thinkphp5.1.x反序列化利用链

思路

// 析构方法入手
__destruct() --> removeFiles() --> files_exists($filename)

// 可控参数
new windows()->filename

// 绝对路径
D:\phpstudy\PHPTutorial\WWW\v5.1.37\thinkphp\library\think\process\pipes\Windows.php

file_exists()函数将参数当作字符串处理,可以触发类的__toString()魔术方法

// 寻找__toString()的调用链
__toString() --> toJson()--> toArray()

//寻找  $可控变量->方法(参数可控) 的点
$relation->visible($name);

// 可控参数
$name --> ($this->append as $key => $name)
$relation--> getAttr($key) --> getData($name) --> array_key_exists($name, $this->data) --> $this->data[$name]

// 绝对路径
D:\phpstudy\PHPTutorial\WWW\v5.1.37\thinkphp\library\think\model\concern\Conversion.php
下的$this->append 
D:\phpstudy\PHPTutorial\WWW\v5.1.37\thinkphp\library\think\model\concern\Attribute.php
下的
$this->$data

// 注意,他们均为代码复用的trait,需要寻找复用了他们的类来进行利用

寻找没有visible方法的类,并且实现了__call()方法,这个方法的实现一般带着call_user_func_array

__call()-->call_user_func_array($this->hook[$method], $args)

//可控变量
$this->hook

// 绝对路径
D:\phpstudy\PHPTutorial\WWW\v5.1.37\thinkphp\library\think\Request.php

// $args为数组,且第一个参数为类实例,难以利用
array_unshift($args, $this)

故寻找Requests.php中其他可以利用的函数,filter功能经常被利用,想办法利用call_user_func()方法

filterValue(&$value, $key, $filters) --> call_user_func($filter, $value)
-->input($data = [], $name = '', $default = null, $filter = '') --> array_walk_recursive($data, [$this, 'filterValue'], $filter)  
--> param($name = '', $default = null, $filter = '') 
--> isAjax($ajax = false) 
--> $this->param($this->config['var_ajax'])

$this->config['var_ajax']可控, 由于param()中$name可控,所以input()函数中的$name也可控,刚好input()函数中$data参数也可控(为$_GET数组)
$data = $this->getData($data, $name) --> $data = $data[$val]

// 可控参数
$this->hook
$this->config['var_ajax']
$this -> $filter
$this -> $data($_GET数组)

// 绝对路径
 D:\phpstudy\PHPTutorial\WWW\v5.1.37\thinkphp\library\think\Request.php

最终的反序列利用链
在这里插入图片描述

在默认模块中构造利用点
在这里插入图片描述

POC

https://github.com/Dido1960/thinkphp/tree/master/v5.1.37/poc

参考文章

挖掘暗藏ThinkPHP中的反序列利用链
Thinkphp 反序列化利用链深入分析

发表评论

电子邮件地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据