笔记里直接复制出来的
1 composer直接获取框架代码
➜ composer create-project --prefer-dist topthink/think tp5137
➜ cd tp5137
➜ vim composer.json # 把"topthink/framework": "5.1.*"改成"topthink/framework": "5.1.37"
➜ composer update
2 反序列化的利用点
- 有一个内容完全可控的反序列化点,例如: unserialize(可控变量)
- 存在文件上传、文件名完全可控、使用了文件操作函数,例如: file_exists('phar://恶意文件')
3 反序列化链
3.0 存在反序列化的点,寻找有__desctruct方法的类,在对象析构时会自动执行其中的代码
3.1 在 think\process\pipes\Windows 类的 __destruct 方法中调用了$this->removeFiles();
3.2 在$this->removeFiles() 中调用了file_exists($filename)
3.3 file_exists()需要字符串类型参数,在执行file_exists($filename)时会触发类的__toString()
3.4 全局搜索__toString(),寻找可利用的__toString(),找到think\model\concern\Conversion
__toString 内调用了$this->toJson(),toJson()内调用了json_encode($this->toArray(), $options);
3.5 Conversion类内,在$this->toArray()中,存在$relation->visible($name),$relation 和 $name来自$this,可控
3.6 寻找有visible方法和__call方法的类,找到了think\Request 类,其中有__call,会执行array_unishift($args, $this);
call_user_func_array($this->hook[$method], $args);
同时 think\Request 类的 input 方法经常是链中一个非常棒的 Gadget ,相当于 call_user_func($filter,$data) ,但是由于array_unishift在参数数组开头插入了一个对象,需要找一个调用input方法,并且第一个参数可控的函数传入Request对象
3.7 找到$this->param 调用了input方法,找到isAjax 和 isPjax 方法调用了$this->param 并且第一个参数可控,构造完成