从CVE-2023-43291到数据库权限:一次emlog渗透测试的完整思考路径
那天下午,我在本地环境搭建了emlog pro 2.1.15的测试实例。这个轻量级CMS系统看似简单,但当我注意到cache.php文件中可疑的反序列化操作时,直觉告诉我这里可能存在突破口。接下来的72小时里,我经历了一系列令人着迷的技术探索——从字符串逃逸构造到字符集编码陷阱,最终意外地在数据库备份中找到了突破口。这不是一个简单的POC复现,而是一场充满意外和思考的实战之旅。
1. 漏洞入口的发现与验证
在审计emlog的代码结构时,/include/lib/cache.php文件引起了我的注意。这个负责缓存处理的组件,竟然直接对用户输入的序列化数据进行反序列化操作。更危险的是,系统没有对反序列化的类进行任何白名单限制。
关键风险点分析:
- 未过滤的
unserialize()调用 - 缺乏操作日志记录
- 默认开启的缓存功能
验证漏洞存在性的最小化测试代码:
$payload = 'a:2:{i:0;O:4:"test":1:{s:4:"name";s:5:"admin";}i:1;N;}'; file_put_contents('/path/to/cache/data.cache', $payload);当访问触发缓存读取的页面时,如果系统抛出类未定义的警告,就证实了反序列化漏洞的存在。但真正的挑战在于:如何将这个看似局限的反序列化点转化为有实际危害的攻击?
2. 从反序列化到SQL注入的链条构建
emlog的数据库操作类有一个特点:它会在对象销毁时自动执行某些清理操作。通过精心构造的序列化字符串,我们可以利用这个特性注入恶意SQL语句。
字符串逃逸的关键技巧:
- 首先创建一个正常文章,alias字段设置为逃逸起始标记
- 第二篇文章的alias包含恶意SQL代码
- 利用反序列化时的字符串长度计算差异,使系统错误解析SQL语句
典型的Payload结构:
";s:[长度]:"[SQL注入代码]";s:1:"Y实际操作中,我发现必须精确计算序列化字符串中的长度值。一个实用的调试方法是先在本地环境测试不同长度值的效果,记录下成功的组合:
| 长度值 | 效果 |
|---|---|
| 87 | 基础注入 |
| 93 | 扩展字段 |
| 81 | 精简版 |
3. 身份验证绕过的意外收获
在反复测试过程中,我意外发现系统对身份验证的处理存在逻辑缺陷。当连续多次请求失败后,系统会临时关闭某些安全检查。这不是设计上的后门,而是错误处理逻辑不严谨导致的副作用。
绕过步骤:
- 先发送5次错误格式的请求
- 在第6次请求时携带有效但过期的token
- 系统会返回包含新token的错误页面
这个发现让我意识到:真正的渗透测试不能只盯着已知漏洞,系统在各种异常状态下的行为同样值得关注。
4. 字符集陷阱与非常规解决方案
当注入尝试进行到关键阶段时,我遇到了令人抓狂的错误:
Illegal mix of collations for operation 'UNION'这个问题源于emlog使用了非标准的字符集配置。经过多次尝试,我发现了几种可能的解决方案:
- 强制转换字符集:
CONVERT(column_name USING utf8mb4)- 使用二进制比较:
WHERE BINARY column_name = 'value'- 修改连接配置(需要一定权限):
SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci正当我深陷字符集问题的泥潭时,一个偶然的发现改变了整个方向——系统管理后台提供了完整的数据库备份功能,而且备份文件竟然包含所有表结构和数据。
5. 数据库备份中的新突破口
通过下载的SQL备份文件,我不仅找到了flag的存储位置,还发现了几个有趣的安全隐患:
- 备份文件包含完整的用户凭证(虽然被哈希处理)
- 系统配置中暴露了绝对路径
- 存在测试用的临时表
最关键的发现是在备份文件的注释部分,管理员留下了上传文件类型配置的记录。默认情况下,系统禁止上传.php文件,但这个限制在恢复备份时没有被正确重置。
利用步骤:
- 编辑备份文件,添加合法的文件上传记录
- 在记录中插入webshell代码
- 通过后台的恢复功能上传修改后的备份
这个迂回的getshell方式让我深刻体会到:在渗透测试中,最直接的路径不一定是最有效的。有时候,那些被忽视的"管理便利功能"反而会成为整个防御体系的阿喀琉斯之踵。
6. 防御措施与安全建议
完成这次测试后,我总结了几个关键防御点,这些建议同样适用于其他CMS系统:
必须实施的加固措施:
- 禁用不必要的序列化操作
- 对数据库操作实施严格的参数化查询
- 备份功能增加权限检查和内容过滤
推荐的安全配置:
location ~* \.php$ { # 禁止直接访问缓存文件 if ($request_uri ~* "/cache/") { return 403; } }这次对emlog的渗透过程充满了意外和惊喜。从最初的反序列化漏洞到最终的数据库权限获取,几乎每一步都需要调整策略、克服意料之外的障碍。这也再次证明:在安全领域,保持开放的思维和持续的学习态度,比掌握任何特定技术都更重要。