
攻撃的セキュリティ研究者 + AI vs. 新しいn-day: 金曜日の夜にCVE-2026-53435の初の公開PoCを構築。内部に生の8h20mのログ。
初の公開概念実証 CVE-2026-53435 に対するもので、アドバイザリのみが存在し、PoC がどこにも公開されていない時点で作成されました。 あいまいな一行アドバイザリから、金曜の夜に 約8.5時間 かけて再構築されました。エクスプロイトを手書きするのではなく、AI を誘導しながら、行き詰まり、方向転換、検証を経て、動作するチェーンができるまで進められました。

PoC がコントローラ上の
/etc/passwdに到達 — 任意ファイル読み取りを確認。
| CVE | CVE-2026-53435 (Jenkins SECURITY-3707) |
| Class | 安全でないデシリアライゼーション (config.xml による ClassFilter バイパス) |
| Impact (this PoC) | 認証済みのコントローラ上での任意ファイル読み取り |
| Affected | Jenkins weekly ≤ 2.567, LTS ≤ 2.555.2 |
| Fixed | Jenkins weekly 2.568, LTS 2.555.3 |
| Advisory | https://www.jenkins.io/security/advisory/2026-06-10/ (公開日 2026-06-10) |
| Status at time of writing | 公開 PoC は存在しませんでした (GitHub PoC リポジトリ: 0) |
これは、単なる成果物ではなく、プロセスを示す実験です。
長年、攻撃的研究者の成果は単一の完成されたエクスプロイトでした — その生成に費やされた8時間の誤った方向転換は消え去っていました。このリポジトリはその誤った方向転換を残します。人間とAIが、アドバイザリから動作するPoCまで、新しいn-dayを協力して進めた、軽く編集された完全なトランスクリプトを付録として含めています。
その主張は、意図的に「AIがやった」というものではありません。8時間は、そうではないという証拠です。AIは決してワンショットでチェーンを完成させませんでした。作業を支えたのはドメイン専門知識でした — アドバイザリがデシリアライゼーションシンクを隠していることを知っていること、Jenkins コアタイプをプラグインではなく調べるべきことを知っていること、パッチ前のDescribableListが要素型を強制しないことを知っていること、そして主張を信じるのではなく検証する方法を知っていることです。研究者の価値は消えませんでした。エクスプロイトをタイピングすることから、方向づけ、枝刈り、検証へと移行したのです。
その変化こそが記録に値するものです。
Jenkins はカスタム ClassFilter でデシリアライゼーションを保護しており、Jenkins コアまたはプラグインで定義された型のみを許可します。CVE-2026-53435 は、これでは不十分であるというものです:config.xml を POST できる攻撃者は、Jenkins に任意のコア/プラグイン型を、それが予期していないコンテキストにデシリアライズさせ、その後 Stapler ルーティングを介して HTTP でそのオブジェクトにアクセスできます。
この PoC は hudson.Plugin$DummyImpl (Jenkins コアタイプであるため、場所のホワイトリストを通過します) を ListView の <properties> リストに埋め込みます — これは DescribableList<ViewProperty> であり、パッチ前は要素型を強制しません。埋め込まれたオブジェクトは baseResourceURL=file:/ を持ちます。それに HTTP リクエストをルーティングすることで、コントローラのファイルシステムから直接ファイルを提供します。
汎用的な ysoserial チェーンはここでは機能しません — ガジェットはフィルタを生き残るために Jenkins/プラグイン常駐型でなければなりません。その制約がすべてです。
所有するシステム、またはテストする明示的な許可を得たシステムに対してのみ使用してください。
エクスプロイトは、同一設定の2つのコンテナ — 脆弱な 2.555.2 とパッチ済みの 2.555.3 — に対して実行され、これが無関係なファイル読み取りプリミティブではなく、この CVE を利用していることを確認しました:
パッチ済みビルドはリクエストを受け入れますが、修正はデシリアライゼーション時に埋め込まれた型を拒否するため、プロパティリストは空で返され、ルーティング先がありません。失敗はアドバイザリが説明するまさにそのメカニズムに当たります — これこそがこれを CVE-2026-53435 の真の PoC にするものです。
python3 exploit_cve_2026_53435_v2.py <base_url> <user> <pass> <remote_file> [view_name]
# example (against your own lab):
python3 exploit_cve_2026_53435_v2.py http://127.0.0.1:8080 <user> <pass> /etc/passwd
base_url — ターゲットの http://host:port (プレーン HTTP; インスタンスが実際に TLS を終端しない限り https を前置しないでください)。config.xml を POST する権限 (View/Configure) と Overall/Read を持つアカウントが必要です。docker compose -f lab/docker-compose.yml up -d
# vulnerable: http://127.0.0.1:8080 (Jenkins LTS 2.555.2)
# patched: http://127.0.0.1:8081 (Jenkins LTS 2.555.3, negative control)
ラボは Groovy 初期化を介してローカルのみのユーザーデータベースをプロビジョニングするため、外部 IdP なしで認証された低権限パスを実行できます。
2026-06-12 (Fri) 15:00 → 23:23 ≈ 8h 20m
15:00–15:12 Lab built (docker: vuln 2.555.2 / patched 2.555.3) + first recon
15:12–21:00 Deserialization sink & gadget analysis
(Commons-Collections bypass attempts failed → pivot
from properties to actions and back)
21:00–22:30 ClassFilter analysis + gadget re-hunt, restricted to core types
22:30–23:00 Working PoC (v1 → v2) + differential verification (vuln vs patched)
これらの時間のほとんどは分析であり、タイピングではありませんでした。エクスプロイト自体は最後の約30分でまとまりました — 正しいシンクとガジェットが判明した後です。
Claude Code (Anthropic) を使用して構築され、著者が対話的に操作しました:
完全で軽く編集された動作トランスクリプトは transcript/ にあります — 行き詰まりも含めて生のまま保持されています。(トーンを和らげ、ローカルネットワークの詳細を隠すためにのみ編集されました。技術的なものは削除されていません。)
許可されたセキュリティテスト、研究、教育のみを対象としています。著者および貢献者は誤用に対する責任を負いません。対象の脆弱性はパッチされています — Jenkins LTS 2.555.3 / weekly 2.568 以降に更新してください。
| 2.555.2 (vulnerable) | 2.555.3 (patched) |
|---|
createView | HTTP 200 | HTTP 200 |
保存された <properties> | <hudson.Plugin_-DummyImpl/> — 生存 | <properties/> — 除去 |
トリガー → /etc/passwd | root:x:0:0:... — 読み取り | 空 — ブロック |