首先需要实现反序列化,找到传参数的位置。
影响thinkphp 5.1.37——5.1.41
测试可以自己实现一个函数
<?php
namespace app\index\controller;
class Index{
public function index(){
@unserialize($_GET['hack']);
return 'thinkPHP5';
}
}
为了实现反序列化自动执行的魔法函数,要找到一个析构函数,thinkphp\library\think\process\pipes\Windows.php中有一个
public function __destruct()
{
$this->close();
$this->removeFiles(); //跟进
}
继续跟进removeFiles()
private function removeFiles()
{
foreach ($this->files as $filename) {
if (file_exists($filename)) { //跟进
@unlink($filename);
}
}
$this->files = [];
}
file_exists会将$filename当作字符串进行处理,触发任意类的__toString()
这时候需要找到一个__toString函数能继续向下执行的类,全局搜索
找到thinkphp\library\think\model\concern\Conversion.php 第242行可以继续执行
public function __toString()
{
return $this->toJson(); //跟进
}
这里会执行toJson方法,继续跟进toArray
public function toJson($options = JSON_UNESCAPED_UNICODE)
{
return json_encode($this->toArray(), $options); //跟进toArray()
}
public function toArray() //131行
{
...
if (!empty($this->append)) { //184行
foreach ($this->append as $key => $name) {
if (is_array($name)) {
// 追加关联对象属性
$relation = $this->