ThinkPHP 6.0反序列化利用链学习


安装环境

直接按照github上ThinkPHP官方提供的方式安装 mac下:

我还是直接在sublime中运行think文件进行调试 注意这里在think中unserialize(urldecode("xxx"));的代码位置 如果放在(new App())->console->run();后运行会有点问题:因为run()中有exit() (这里不可注释,因为需要(new App())->initialize();来初始化,否则Model.phpdb()中的self::$db一直为NULL) 以下提供3种解决办法:

利用链

6.0和之前的区别在于6.0.x版本取消了Windows类,也就是删除了最开始的__destruct() 不过__toString()之后的链(动态调用的链,包含*route.php也已失效)仍然存在 所以要找到一个新起始触发点,来触发__toString()

”通常最好的反序列化起始点为__destruct()__wakeup(),因为这两个函数的调用在反序列化过程中都会自动调用,所以我们先来找此类函数。这里我找了vendor/topthink/think-orm/src/Model.php__destruct()函数。“ 随着大佬的脚步,到vendor/topthink/think-orm/src/Model.php瞅一瞅 $this->lazySave可控,跟到save() 这里要保证$this->trigger('BeforeWrite')$this->isEmpty()不为false,默认前者为true 后面这个是判断了$this->data有无值,可控 接着看到函数updateData() 出发点在这个截图的最下方也就是$allowFields = $this->checkAllowFields(); 不过要保证执行到这一步,需要构造前面不return,要保证$data不能为空 checkData()函数啥都没干,$this->getChangedData() 可构造$this->force,即可进入checkAllowFields() 跟到$this->db() 发现有字符串拼接且参数可控,可以触发__toString()了(注意还要满足$this->connectionmysql)

 

POC

参考链接

1.thinkphp v6.0.x 反序列化利用链挖掘