Skip to content
KitploitKITPLOIT
ツールブログ
提出
ツールブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

··フィード·お問い合わせ·プライバシー·© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
HTTP3ONSTEROIDS — PoCおよびラボ環境 for CVE-2023-25950: HAProxyのHTTP/3実装における不正なヘッダーフィールドを介したHTTPリクエストスマグリングにより、DoSおよびデータ窃取を可能にします。 | Kitploit
ツール/GitHubGitHub/dhmosfunk/http3onsteroids
脆弱性分析ウェブアプリケーション悪用学習と教育ラボと実践
GitHubdhmosfunk/http3onsteroids

HTTP3ONSTEROIDS

PoCおよびラボ環境 for CVE-2023-25950: HAProxyのHTTP/3実装における不正なヘッダーフィールドを介したHTTPリクエストスマグリングにより、DoSおよびデータ窃取を可能にします。

リポジトリを見る
11221年前未レビュー

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有

目次

  • 脆弱性の説明
    • ソースコードレビュー
  • ラボのセットアップ
    • 問題の特定
  • 参考文献

脆弱性の説明

HAProxyのHTTP/3実装は、不正なHTTPヘッダーフィールド名をブロックできず、この不正なヘッダーを誤って処理するサーバーの前段にデプロイされた場合、HTTPリクエスト/レスポンススマグリング攻撃に悪用される可能性があります。リモートの攻撃者は、正規ユーザーのリクエストを改ざんする可能性があります。その結果、攻撃者は機密情報を取得したり、サービス妨害(DoS)状態を引き起こしたりする可能性があります。

https://jvn.jp/en/jp/JVN38170084/

ソースコードレビュー

CVEの調査を始める前に非常に良い方法は、まず脆弱性の説明を読み、修正用のコミットが利用可能かどうかを確認することです。
私の場合、コミットは利用可能であり、HAProxyの開発者が、HTTP3実装における標準ヘッダーの解析中に、RFC 9114 4.1.2. Malformed Requests and Responses のチェックを含め忘れたことは明らかです。

以下にパッチコミットを示します。

root@kitploit:~
--- a/src/h3.c
+++ b/src/h3.c
@@ -352,7 +352,27 @@ static ssize_t h3_headers_to_htx(struct qcs *qcs, const struct buffer *buf,
        //struct ist scheme = IST_NULL, authority = IST_NULL;
        struct ist authority = IST_NULL;
        int hdr_idx, ret;
-       int cookie = -1, last_cookie = -1;
+       int cookie = -1, last_cookie = -1, i;
+
+       /* RFC 9114 4.1.2. Malformed Requests and Responses
+        *
+        * A malformed request or response is one that is an otherwise valid
+        * sequence of frames but is invalid due to:
+        * - the presence of prohibited fields or pseudo-header fields,
+        * - the absence of mandatory pseudo-header fields,
+        * - invalid values for pseudo-header fields,
+        * - pseudo-header fields after fields,
+        * - an invalid sequence of HTTP messages,
+        * - the inclusion of uppercase field names, or
+        * - the inclusion of invalid characters in field names or values.
+        *
+        * [...]
+        *
+        * Intermediaries that process HTTP requests or responses (i.e., any
+        * intermediary not acting as a tunnel) MUST NOT forward a malformed
+        * request or response. Malformed requests or responses that are
+        * detected MUST be treated as a stream error of type H3_MESSAGE_ERROR.
+        */
 
        TRACE_ENTER(H3_EV_RX_FRAME|H3_EV_RX_HDR, qcs->qcc->conn, qcs);
 
@@ -416,6 +436,14 @@ static ssize_t h3_headers_to_htx(struct qcs *qcs, const struct buffer *buf,
                if (isteq(list[hdr_idx].n, ist("")))
                        break;
 
+               for (i = 0; i < list[hdr_idx].n.len; ++i) {
+                       const char c = list[hdr_idx].n.ptr[i];
+                       if ((uint8_t)(c - 'A') < 'Z' - 'A' || !HTTP_IS_TOKEN(c)) {
+                               TRACE_ERROR("invalid characters in field name", H3_EV_RX_FRAME|H3_EV_RX_HDR, qcs->qcc->conn, qcs);
+                               return -1;
+                       }
+               }
+
                if (isteq(list[hdr_idx].n, ist("cookie"))) {
                        http_cookie_register(list, hdr_idx, &cookie, &last_cookie);
                        continue;

リポジトリ - haproxy-2.7.git/commit

以下に、HAProxy 2.7.0 の標準ヘッダー処理実装において、ヘッダー名のサニタイズが欠如していることを示すコードを示します。

root@kitploit:~
/* 
src/h3.c 
lines: 413 - 428
*/

/* now treat standard headers */
hdr_idx = 0;
while (1) {
    if (isteq(list[hdr_idx].n, ist("")))
        break;
    if (isteq(list[hdr_idx].n, ist("cookie"))) {
        http_cookie_register(list, hdr_idx, & cookie, & last_cookie);
        continue;
    }
    if (!istmatch(list[hdr_idx].n, ist(":")))
        htx_add_header(htx, list[hdr_idx].n, list[hdr_idx].v);
    ++hdr_idx;
}

以下は、ヘッダー名が有効かどうかを確認するために使用されるコードです。

コードは、ヘッダーフィールド名の各文字を反復処理するforループから始まります。ループは i = 0 から i < list[hdr_idx0.n.len] まで実行されます。ここで、list はヘッダー情報を含む配列または構造体であり、hdr_idx はチェック対象の特定のヘッダーを表すインデックスです。
ループ内で、コードはヘッダーフィールド名から現在の文字 c を抽出します。 list[hdr_idx].n.ptr[i] は、ヘッダーフィールド名の i 番目の位置にある文字にアクセスします。
コードの次の部分には if 文があります。これは、現在の文字 c が次の2つの条件のいずれかを満たすかどうかをチェックします:

  • (uint8_t)(c - 'A') < 'Z' - 'A': これは、c から 'A' を引き、結果を uint8_t にキャストすることで、その文字が大文字(A〜Z)かどうかをチェックします。結果が 'Z' と 'A' の差より小さい場合、その文字は大文字です。
  • !HTTP_IS_TOKEN(c): この条件は、その文字が有効なHTTPトークン文字であるかどうかをチェックします。HTTP_IS_TOKEN は、まずヘッダー名にトークンが含まれているかどうかをチェックすることで機能します。トークンとは、HTTPプロトコルで予約された文字ではない文字の並びです。予約文字とは、HTTPプロトコルで特別な意味を持つ文字であり、例としては :、/、?、# などがあります。
root@kitploit:~
/* 
src/h3.c 
lines: 439 - 445
*/
for (i = 0; i < list[hdr_idx].n.len; ++i) {
    const char c = list[hdr_idx].n.ptr[i];
    if ((uint8_t)(c - 'A') < 'Z' - 'A' || !HTTP_IS_TOKEN(c)) {
        TRACE_ERROR("invalid characters in field name", H3_EV_RX_FRAME | H3_EV_RX_HDR, qcs -> qcc -> conn, qcs);
        return -1;
    }
}

ラボのセットアップ

ラボ全体はDocker上で動作しています。以下のコマンドでラボを実行できます:

  1. cd /lab
  2. docker-compose up --build

Dockerビルドの完了には15〜20分かかることに注意してください。
ただし、ラボを実行する前に、いくつかの設定変更を行う必要があります:

/lab/haproxy/conf/haproxy.cfg

root@kitploit:~
...
default_backend api_server

backend api_server
  balance roundrobin
  server api_server [YOUR-LOCAL-IPv4]:8080 # replace with local IPv4

/etc/hosts

root@kitploit:~
[YOUR-LOCAL-IPv4]   foo.com

/lab/docker-compose.yml
引数の値を 'vuln' または 'patched' に変更することで、脆弱性のあるバージョンとパッチ適用済みバージョンのどちらを選択してテストを行うことができます。

root@kitploit:~
...
    args:
        - haproxy_version=patched || vuln
...

最後に、ブラウザに minica.crt 証明書をインポートします。

⚠️ ラボはLinux環境で実行してください。

問題の特定

次のcurlリクエストを送信します:

  • curl --http3 -H "foooooo\r\n: barr" -iL -k https://192.168.1.104/

脆弱性のあるバージョンのレスポンス:

root@kitploit:~
HTTP/3 200 
server: Werkzeug/2.3.6 Python/3.8.17  
date: Sat, 12 Aug 2023 13:10:52 GMT   
content-type: text/html; charset=utf-8
content-length: 76
alt-svc: h3=":443";ma=900;

Host: 192.168.1.104
User-Agent: curl/8.1.2-DEV
Accept: */*
Foooooo\R\N: barr <-- Malformed header

パッチ適用済みバージョンのレスポンス:

root@kitploit:~
curl: (56) HTTP/3 stream 0 reset by server

上記の結果に基づくと、対応するレスポンスは、脆弱性のあるバージョンのHAProxyが**\r\n**プレフィックスをバックエンドサーバーに通過させたのに対し、パッチ適用済みバージョンはクライアントとHAProxyの間の接続を切断したことを示しています。


攻撃者は、バックエンドの動作と、バックエンドサーバーが不正なヘッダーをどのように扱うかに基づいて、HTTPリクエストスマグリング攻撃を実行できます。私の見解では、最も重要な懸念は、攻撃者が前述のCVEを悪用してサービス妨害(DoS)攻撃を実行できる可能性があることです。

参考文献:

https://jvn.jp/en/jp/JVN38170084/
https://github.com/haproxytechblog/haproxy-2.6-http3
https://www.haproxy.com/blog/how-to-enable-quic-load-balancing-on-haproxy
https://git.haproxy.org/
https://github.com/jsha/minica
https://curl.se/docs/http3.html

ツールをダウンロード