oscerd/CVE-2026-40860
GitHub: oscerd/CVE-2026-40860
该项目复现了 Apache Camel JMS 组件中 ObjectMessage 不安全反序列化导致的远程代码执行漏洞(CVE-2026-40860)。
Stars: 0 | Forks: 0
# camel-jms JMS ObjectMessage 不安全的反序列化复现器 (CVE-2026-40860)
本项目演示了 Apache Camel 的 `camel-jms` 组件中的 **Java 反序列化漏洞**
(以及传递依赖的 `camel-sjms`、`camel-sjms2`、`camel-amqp`、`camel-activemq`、`camel-activemq6`),
漏洞编号为 **CVE-2026-40860**。`JmsBinding.extractBodyFromJms()` 在处理传入的 JMS **`ObjectMessage`** 时,会通过 `ObjectMessage.getObject()` 对 payload 进行反序列化,期间**未使用任何 `ObjectInputFilter`**、类白名单或黑名单。因为只要 `mapJmsMessage=true`(默认值)且 Camel 作为 JMS **consumer** 时就会触发此过程,所以如果攻击者能够将精心构造的 `ObjectMessage` 发布到被消费的 queue/topic 中,当 classpath 中存在 gadget chain 时,即可实现**远程代码执行**。
安全公告:https://camel.apache.org/security/CVE-2026-40860.html
## 漏洞概述
| 属性 | 值 |
|----------|-------|
| **组件** | `camel-jms` (+ `camel-sjms`, `camel-sjms2`, `camel-amqp`, `camel-activemq`, `camel-activemq6`) |
| **受影响的类** | `org.apache.camel.component.jms.JmsBinding#extractBodyFromJms` → `jakarta.jms.ObjectMessage#getObject()` |
| **CWE** | CWE-502: Deserialization of Untrusted Data |
| **影响** | 远程代码执行 (RCE) |
| **触发条件** | Camel JMS consumer + `mapJmsMessage=true` (默认值) + 攻击者可入队的 `ObjectMessage` |
| **受影响版本** | 从 3.0.0 到 4.14.7 之前,从 4.15.0 到 4.18.2 之前,从 4.19.0 到 4.20.0 之前 |
| **修复版本** | 4.14.7, 4.18.2, 4.20.0 |
| **JIRA** | CAMEL-23321 |
| **报告者** | Venkatraman Kumar (Securin) |
## 技术细节
```
// JmsBinding.extractBodyFromJms(Exchange, Message) - affected version
if (message instanceof ObjectMessage objectMessage) {
Object payload = objectMessage.getObject(); // <-- deserializes with no ObjectInputFilter
if (payload instanceof DefaultExchangeHolder holder) {
...
}
return payload;
}
```
`getObject()` 会对 message body 执行 JMS provider 的 `ObjectInputStream.readObject()`。Camel 没有添加任何自己的类过滤机制,因此在反序列化过程中,classpath 上的 gadget chain 就会被执行。
### 修复内容(及其局限性)
该修复(4.14.7 / 4.18.2 / 4.20.0)添加了一个默认的 `ObjectInputFilter` 白名单(`java.**;javax.**;org.apache.camel.**;!*`),可通过新增的 `deserializationFilter` endpoint 选项或 JVM 级别的 `-Djdk.serialFilter` 进行自定义。请注意 Camel 官方针对该修复的 commit message:
因此,完整的防护 = **升级 Camel + 限制 provider / JVM filter**。此 PoC 使用了带有 `trustAllPackages=true` 的 ActiveMQ 客户端(一种常见的真实环境设置),以便 provider 对 payload 进行反序列化;在受影响的 Camel 版本中,这长驱直入,毫无阻碍。
## 受害者路由
```
from("jms:queue:evil") // mapJmsMessage defaults to true
.log("Consumed: ${body.class.name}");
```
仅仅**接收**到 `ObjectMessage` 就会触发反序列化 —— 路由的 body 是什么根本无关紧要。
## 仓库结构 —— 攻击者 vs. 受害者
**受害者**是 Camel JMS consumer。**攻击者**是任何可以发布消息到该 queue 的 producer。双方都连接到一个运行在 Docker 中的真实 **Apache ActiveMQ Artemis** broker。
```
CVE-2026-40860/
├── pom.xml # camel-jms 4.18.1 + activemq-client 6.2.4 + commons-collections 3.2.1 (gadget)
├── Dockerfile # runs the app (--add-opens only to build the gadget)
├── docker-compose.yml # Artemis broker (quay.io) + the reproducer app
├── README.md
└── src/main/
├── java/com/example/
│ ├── Application.java
│ ├── JmsConfig.java # OpenWire ConnectionFactory (trustAllPackages=true) + jms component
│ ├── VictimRoute.java # victim: from("jms:queue:evil")
│ ├── Gadget.java # CommonsCollections6 gadget, fires during getObject()
│ └── ExploitController.java # attacker: publishes ObjectMessage(gadget) to the queue
└── resources/
└── application.properties
```
## 前置条件
- Java 17+ 和 Maven 3.8+
- Docker(用于运行 broker 和应用程序)
## 复现步骤
### 步骤 1:构建并启动一切
```
mvn clean package -DskipTests
docker compose up -d --build
```
这将启动一个 Artemis broker (`quay.io/artemiscloud/activemq-artemis-broker`) 和复现器应用程序,
后者会通过 OpenWire 连接到该 broker。
### 步骤 2:触发反序列化 (RCE)
```
curl -s http://localhost:8080/exploit/attack
# -> ObjectMessage 已发布到队列 'evil'。
# camel-jms consumer 调用了 ObjectMessage.getObject() -> 反序列化。
# # >>> RCE 证明 — /tmp/pwned 存在:true
```
### 步骤 3:验证
```
docker exec cve-2026-40860 ls -la /tmp/pwned
```
### 清理
```
docker compose down
```
## 攻击向量
任何从攻击者可发布消息的目标地址读取数据的 Camel JMS **consumer**(`camel-jms`、`camel-sjms`、`camel-sjms2`、`camel-amqp`、`camel-activemq`、`camel-activemq6`)——无论是共享的 broker、具有开放 producer 的 topic、还是由不受信任的上游提供数据的 queue——只要配置了 `mapJmsMessage=true`(默认值)即可被攻击。
## 利用条件
1. 一个配置了 `mapJmsMessage=true`(默认值)的 Camel JMS consumer。
2. 攻击者能够将 `ObjectMessage` 入队到被消费的目标地址中。
3. JMS provider 会反序列化 payload(例如 ActiveMQ 的 `trustAllPackages=true`,或者 provider 没有限制性过滤器)。
4. **classpath 中存在 gadget 库**(此处为 `commons-collections:3.2.1`)。
## 推荐修复方案
升级到 **4.14.7 / 4.18.2 / 4.20.0**,**并且**对端到端的反序列化进行限制:
- 设置 JVM 级别的白名单:`-Djdk.serialFilter=java.**;org.apache.camel.**;!*`(或者使用 endpoint 新增的 `deserializationFilter` 选项)。
- 配置 **JMS provider 自身的**反序列化过滤器(例如 ActiveMQ 的 `trustedPackages`,**切勿**使用 `trustAllPackages=true`)。
## 缓解措施
在升级之前:
1. 优先使用非 `ObjectMessage` 的 payload;如果可以接受原始 message,请设置 `mapJmsMessage=false`。
2. 严格限制 JMS provider 的受信任包;在不受信任的目标地址上绝不使用 `trustAllPackages=true`。
3. 应用 `-Djdk.serialFilter`。
4. 从 classpath 中**移除 gadget 库**(升级/移除 commons-collections 3.x 及类似库)。
## 免责声明
本复现程序仅供**安全研究和授权测试使用**,针对的是**已公开披露并已修复**的漏洞。未经明确许可,请勿将其用于任何系统。
标签:Apache Camel, CISA项目, CVE-2026-40860, Java反序列化, JS文件枚举, RCE, 域名枚举, 漏洞复现, 请求拦截