[HITCON 2017]SSRFme

打开环境后给了一串代码

117.136.0.16 <?php
    if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
        $http_x_headers = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
        $_SERVER['REMOTE_ADDR'] = $http_x_headers[0];
    }

    echo $_SERVER["REMOTE_ADDR"];

    $sandbox = "sandbox/" . md5("orange" . $_SERVER["REMOTE_ADDR"]);
    @mkdir($sandbox);
    @chdir($sandbox);

    $data = shell_exec("GET " . escapeshellarg($_GET["url"]));
    $info = pathinfo($_GET["filename"]);
    $dir  = str_replace(".", "", basename($info["dirname"]));
    @mkdir($dir);
    @chdir($dir);
    @file_put_contents(basename($info["basename"]), $data);
    highlight_file(__FILE__);

简单的代码审计一下,第一个if为了是确保$_SERVER['REMOTE_ADDR']里面获得的是真实ip,而不是代理ip,接着创建了一个文件,文件的路径是sandbox/(orange加ip值)的md5加密,然后切换到了这个文件路径。不难理解shell_exec是执行shell代码的意思,escapeshellarg可以百度,可这个GET并没有看懂。

GET是perl(一种语言)里面的语法,在shell里是可以执行的,当GET后面加文件路径的时候,意为读取该文件或目录的内容。而GET也可以进行命令执行,因为GET底层实现使用的是perl里面的open函数,而open函数可以执行命令,所以我们可以用GET来执行命令。要让GET执行命令,当GET使用file协议的时候就会调用到perl的open函数,这就是我们要利用的点。

pathinfo就是以数组的形式返回文件路径的信息

  • [dirname] //路径名
  • [basename] //文件名
  • [extension] //扩展名

basename() 函数返回路径中的文件名部分。

比如$_GET["filename"]=/123/321,经过$info["dirname"]后等于/123,在经过basename后等于123,然后再此目录下创建一个123文件,进入到文件里,把$data的内容写入到文件里。

那意思就是url我可以传入一个想要读取的文件路径,然后shell_exec执行(GET 文件路径),最后会把执行的结果写入我传入的filename里面,然后我就可以去读取filename里面的内容,去查看结果了。方法明确后,开始构造payload

先看看根目录/ 

?url=/&filename=coconut

然后去查看文件(注意md5加密要用小写,因为大写打不开。。。)

可以看到有个flag和readflag,因为之前遇到过,猜想基本都是直接读flag打不开,读readflag是个二进制的,所以readflag应该是个程序,要执行它让它去读flag。

 果然是这样的,因为传入/readflag后GET只是打开文件,把文件内容写到了coconut里面,所以是乱码。

注意:

Perl的open函数会执行给open函数所传递的文件名参数中的系统命令,但是前提是这个文件名是需要存在的。这道题因为文件名是可以控制的,所以就先生成一个以读取flag命令命名的文件。因为perl里的GET函数底层就是调用了open处理,而首先得满足前面的文件存在, 才会继续到open语句, 所以在执行命令前得保证有相应的同名文件。

这里又要用到让GET去执行程序,构造payload

?url=&filename=|/readflag           //要有个管道符,我也不知道为啥,可能open函数命令执行的时候就需要吧0.0有大佬请指教~

?url=file:|/readflag&filename=coconut

最后得到flag

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值