T-Reqs(Two Requests)は、論文「T-Reqs: HTTP Request Smuggling with Differential Fuzzing」の一部として書かれた文法ベースのHTTPファザーであり、この論文はACM CCS 2021で発表されました。
BibTeX of the paper:
@inproceedings{ccs2021treqs,
title={T-Reqs: HTTP Request Smuggling with Differential Fuzzing},
author={Jabiyev, Bahruz and Sprecher, Steven and Onarlioglu, Kaan and Kirda, Engin},
booktitle={Proceedings of the 2021 ACM SIGSAC Conference on Computer and Communications Security},
pages={1805--1820},
year={2021}
}
T-Reqsは、バージョン1.1以前の変異したHTTPリクエストを送信することで、HTTPサーバーをファジングするためのものです。主に3つのコンポーネントがあります:1)入力の生成、2)生成された入力の変異、3)ターゲットサーバーへの配信。
ファザーに供給されるCFG文法を使用して、HTTPリクエストを生成します。以下に示す例の文法はリクエストラインのファジングに特化しており、すべてのリクエストラインコンポーネントとそれぞれの可能な値が明示的に指定されています。これにより、様々な形式のリクエストラインを持つ有効なリクエストを生成できるだけでなく、変異の観点から各リクエストラインコンポーネントを個別の単位として扱うことができます。
'<start>':
['<request>'],
'<request>':
['<request-line><base><the-rest>'],
'<request-line>':
['<method-name><space><uri><space><protocol><separator><version><newline>'],
'<method-name>':
['GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'CONNECT', 'OPTIONS', 'TRACE', 'PATCH'],
'<space>':
[' '],
'<uri>':
['/_URI_'],
'<protocol>':
['HTTP'],
'<separator>':
['/'],
'<version>':
['0.9', '1.0', '1.1'],
'<newline>':
['\r\n'],
'<base>':
['Host: _HOST_\r\nConnection:close\r\nX-Request-ID: _REQUEST_ID_\r\n'],
'<the-rest>':
['Content-Length: 5\r\n\r\nBBBBBBBBBB'],
各コンポーネントは、文字列可変とツリー可変の2つの方法でマークできます(設定例を参照)。コンポーネントが文字列可変の場合、ランダムな位置でランダムな文字が削除、置換、または挿入されます。以下の例(左側)では、プロトコルバージョンの最後の文字(1)が削除され、メソッド名の3文字目(S)がRに置換され、URIの先頭にスラッシュが挿入されています。一方、コンポーネントがツリー可変の場合、そのコンポーネントの下のランダムな位置でランダムなコンポーネントが削除、置換、または挿入されます。以下の例(右側)は、リクエストラインコンポーネントに適用された3つのツリー変異を示しています:1)methodがprotocolに置換、2)現在のURIの後に追加のURIが挿入、3)既存のprotoが削除。

ファザーには、入力の生成と変異に関するユーザーの設定を通知する必要があります。具体的には、入力文法、可変コンポーネント、変異の設定などを設定ファイルで指定する必要があります(設定例を参照)。
各イテレーションで生成・変異された入力を再現できるように、シード番号が使用されます。実際、このシード番号は、入力の形成と変異中の乱数生成のシードとして機能します。これらのシードがどのようにファザーに供給されるかに応じて、個別モードと一括モードの2つのモードのいずれかで実行されます。個別モードでは、ユーザーが指定したシードに基づいて入力が生成・変異されます。以下のコマンドでは、単一のシード(例:505)が指定されています。別の方法として、-f オプションを使用してシードのリストを指定することもできます(詳細はヘルプページを参照)。
python3 main.py -i -c config -s 505
一方、一括モード(デフォルト)では、シード値として0から始まり、終了番号に達するまで各イテレーションでインクリメントされます。開始番号と終了番号はカスタマイズ可能です。
python3 main.py -c config
t-reqsコードを実行できるように、Dockerfileも提供しています。以下のコマンドを実行して始めてください。
# run the command below under the directory which has the Dockerfile
docker build -t test/treqs .
# create a container after you built the image using the command above
docker run -ti test/treqs bash
# run the commands below in the started docker shell
cd t-reqs/
python3 code/main.py -c config -n -i -s90
HTTPリクエストスマグリングは、一方のサーバーがリクエストボディの境界を決定するためにTransfer-Encodingヘッダーを使用し、もう一方がContent-Lengthヘッダーを優先する場合、または一方のサーバーがリクエストボディを無視し、もう一方がそれを処理する場合のサーバー間の異なるボディ解析動作に依存します。
さまざまな形式のHTTPリクエストに対するさまざまな変異に応じたサーバーのボディ解析を分析するには、ボディ解析の動作を通知するフィードバックメカニズムをそれらのサーバーにインストールする必要があります。サーバーにフィードバックメカニズムをインストールする一つの方法は、サーバーをリバースプロキシモードで実行し、リクエストをサービスとして実行されている「フィードバックプロバイダー」スクリプトに転送することです。このサービスは、受信したリクエストのボディ長を測定し、後で他のサーバーと比較するために保存します。
このリポジトリには、フィードバックプロバイダーのスクリプト例が用意されています。ただし、このスクリプトは、クライアント側に保存されることを前提として、レスポンスでボディ長情報を返送します。
T-ReqsはMITライセンスの下でライセンスされています。