
Grammatikbasierter HTTP/1-Fuzzer mit Mutationsfähigkeit
T-Reqs (Two Requests) ist ein grammatikbasierter HTTP-Fuzzer, der im Rahmen des Papers mit dem Titel "T-Reqs: HTTP Request Smuggling with Differential Fuzzing" entwickelt wurde und auf der ACM CCS 2021 vorgestellt wurde.
BibTeX des Papers:
@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 dient zum Fuzzing von HTTP-Servern, indem mutierte HTTP-Anfragen der Versionen 1.1 und früher gesendet werden. Es besteht aus drei Hauptkomponenten: 1) Eingabegenerierung, 2) Mutieren der generierten Eingaben und 3) Ausliefern an die Zielserver.
Eine CFG-Grammatik, die in den Fuzzer eingespeist wird, dient zur Generierung von HTTP-Anfragen. Da die unten gezeigte Beispielgrammatik auf das Fuzzing der Anfragezeile zugeschnitten ist, werden jede Komponente der Anfragezeile und mögliche Werte für jede explizit angegeben. Dies ermöglicht es uns, gültige Anfragen mit verschiedenen Formen der Anfragezeile zu generieren und jede Komponente der Anfragezeile aus Mutationsperspektive als separate Einheit zu behandeln.
'<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'],
Jede Komponente kann auf zwei Arten markiert werden: zeichenmutable und baummutable (siehe die Beispielkonfiguration). Wenn eine Komponente zeichenmutable ist, kann ein zufälliges Zeichen an einer zufälligen Position gelöscht, ersetzt oder eingefügt werden. Im unten gezeigten Beispiel (linke Seite) wird das letzte Zeichen in der Protokollversion (1) gelöscht, der dritte Buchstabe im Methodennamen (S) durch R ersetzt und ein Schrägstrich am Anfang der URI eingefügt. Wenn eine Komponente hingegen baummutable ist, kann eine zufällige Komponente an einer zufälligen Position unter dieser Komponente gelöscht, ersetzt oder eingefügt werden. Das folgende Beispiel (rechte Seite) zeigt drei Baum-Mutationen, die auf die Anfragezeilenkomponente angewendet wurden: 1) method wird durch protocol ersetzt, 2) ein zusätzlicher URI wird nach dem aktuellen URI eingefügt, und 3) das vorhandene proto wird gelöscht.

Der Fuzzer sollte über die Benutzereinstellungen bezüglich der Generierung und Mutation von Eingaben informiert werden. Genauer gesagt sollten die Eingabegrammatik, die mutierbaren Komponenten, Mutationspräferenzen und andere Dinge in der Konfigurationsdatei angegeben werden (siehe eine Beispiel-Konfiguration).
Um die in jeder Iteration generierten und mutierten Eingaben reproduzieren zu können, wird eine Seed-Nummer verwendet. Tatsächlich dient diese Seed-Nummer als Startwert für die Zufallszahlengenerierung während der Erstellung und Mutation einer Eingabe. Abhängig davon, wie diese Seeds in den Fuzzer eingegeben werden, läuft er in einem von zwei Modi: Einzelmodus und Batch-Modus. Im Einzelmodus werden Eingaben basierend auf den vom Benutzer angegebenen Seeds generiert und mutiert. Im folgenden Befehl wird ein einzelner Seed (z.B. 505) angegeben. Alternativ könnte eine Liste von Seeds mit der Option -f angegeben werden (siehe Hilfeseite für weitere Informationen).
python3 main.py -i -c config -s 505
Im Batch-Modus (der Standard ist) beginnt er dagegen mit Null als Seed-Wert und erhöht ihn in jeder Iteration, bis die Endzahl erreicht ist. Die Anfangs- und Endzahlen können angepasst werden.
python3 main.py -c config
Wir stellen auch ein Dockerfile zur Verfügung, damit Sie den t-reqs-Code ausführen können. Sie können die folgenden Befehle ausführen, um zu beginnen:
# 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-Request-Smuggling beruht auf unterschiedlichen Body-Parsing-Verhalten zwischen Servern, bei denen ein Server den Transfer-Encoding-Header verwendet, während der andere den Content-Length-Header bevorzugt, um die Grenzen eines Anforderungskörpers zu bestimmen, oder ein Server einen Anforderungskörper ignoriert, während der andere ihn verarbeitet.
Um das Body-Parsing von Servern als Reaktion auf verschiedene Mutationen in verschiedenen Formen einer HTTP-Anfrage zu analysieren, müssen wir auf diesen Servern einen Feedback-Mechanismus installieren, der uns über das Body-Parsing-Verhalten informiert. Eine Möglichkeit, einen Feedback-Mechanismus auf einem Server zu installieren, besteht darin, den Server im Reverse-Proxy-Modus auszuführen und Anfragen an ein als Dienst laufendes 'Feedback-Provider'-Skript weiterzuleiten. Dieser Dienst misst die Länge des Körpers in empfangenen Anfragen und speichert sie, um sie später mit anderen Servern zu vergleichen.
Ein Beispielskript für einen 'feedback provider' ist in diesem Repository verfügbar. Dieses Skript sendet die Körperlängeninformationen jedoch in einer Antwort zurück, unter der Annahme, dass diese Informationen auf der Client-Seite gespeichert werden.
T-Reqs ist unter der MIT-Lizenz lizenziert.