php审计之pop链挖掘
pop链简介
它是一种给定的属性编程,常用于调用链的方法。在题目中的代码里找到主动调用的指令,并且这些指令集成成一条有指令的能达到不利攻击效果的代码,就是弹出链(个人)在链中。
魔术方法
__wakeup() //使用unserialize时触发
__sleep() //使用serialize时触发
__destruct() //对象被销毁时触发
__call() //在对象上下文中调用不可访问的方法时触发
__callStatic() //在静态上下文中调用不可访问的方法时触发
__get() //用于从不可访问的属性读取数据
__set() //用于将数据写入不可访问的属性
__isset() //在不可访问的属性上调用isset()或empty()触发
__unset() //在不可访问的属性上使用unset()时触发
__toString() //把类当作字符串使用时触发,file_exists()判断也会触发
__invoke() //当脚本尝试将对象调用为函数时触发
__call
与__callstatic
#
现实情况下__call
的利用居多,该魔术方法触发的条件是在对象上下文中调用不可访问的方法时触发。
调用流程如下:
$this->a() ==> 当前类a方法 ==> 父类a方法 ==> 当前类__call方法 ==> 父类__call方法
如果触发__call
方法,那么a,即方法名,会作为__call
的方法的第一个参数,而参数列表会作为__call
的方法第二个参数。
来看到代码
function __destruct(){
$this->a->b();
}
这里有2个利用路径,一个是$this->a
中构造一个存在方法的实例化类,另一种方式是找一个不存在b方法并且存在__call
方法的类,当b不存在时,即自动调用__call
。
__callstatic
方法只有在调用到静态方法的时候才能触发
__get
与__set
#
不存在该类变量或者不可访问时,则会调用对应的__get
方法
$this->a ==> 当前类a变量 ==> 父类a变量 ==> 当前类__get方法 ==> 父类__get方法
__get
代码案例
function __destruct(){
echo $this->a;
}
调用不存在变量a,即会自动触发__get
方法,
数据写入不可访问的变量或不存在的变量即调用__set
function __destruct(){
$this->a = 1;
}
__toString
把类当作字符串使用时触发
$this->_adapterName = $adapterName;
$adapterName = 'xxx' . $adapterName;
pop链构造思路
此前构思的自动化挖掘POP链的功能已经被其他师傅实现了,在此就不班门弄斧了,直接拿现成的来用。
按照个人理解反序列化入口点一般为`__wakeup`、 `__destruct`、 `__construct`等
思路其实就是寻找`__destruct`方法,作为入口点,然后寻找一个回调函数作为末端。而中间需要寻找各种中间链,将其串联起来。串联的方法基本上就是一些魔术方法和一些自定义的方法。
Ezpop
class Modifier {
protected $var;
public function append($value){
include($value);
}
public function __invoke(){
$this->append($this->var);
}
}
class Show{