
Un fuzzer guiado basado en mutaciones para cortafuegos de aplicaciones web basados en ML.
Un fuzzer guiado basado en mutaciones para Cortafuegos de Aplicaciones Web basados en ML, inspirado en AFL y basado en el FuzzingBook de Andreas Zeller y otros.
Dada una consulta de inyección SQL de entrada, intenta producir una consulta semánticamente invariante que sea capaz de eludir el WAF objetivo. Puedes usar esta herramienta para evaluar la robustez de tu producto permitiendo que WAF-A-MoLE explore el espacio de soluciones para encontrar "puntos ciegos" peligrosos no cubiertos por el clasificador objetivo.

WAF-A-MoLE toma un payload inicial y lo inserta en el Pool de payloads, que gestiona una cola de prioridad ordenada por la puntuación de confianza del WAF sobre cada payload.
Durante cada iteración, la cabeza del Pool de payloads se pasa al Fuzzer, donde se muta aleatoriamente, aplicando uno de los operadores de mutación disponibles.
Todos los operadores de mutación preservan la semántica y aprovechan el alto poder expresivo del lenguaje SQL (en esta versión, MySQL).
A continuación se muestran los operadores de mutación disponibles en la versión actual de WAF-A-MoLE.
WAF-A-MoLE implementa la metodología presentada en "WAF-A-MoLE: Evading Web Application Firewalls through Adversarial Machine Learning". También se puede encontrar una preimpresión de nuestro artículo en arXiv.
Si quieres citarnos, por favor usa la siguiente referencia (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
Puedes evaluar la robustez de tu propio WAF, o probar WAF-A-MoLE contra algunos clasificadores de ejemplo. En el primer caso, echa un vistazo a la clase Model. Tu modelo personalizado necesita implementar esta clase para ser evaluado por WAF-A-MoLE. Ya proporcionamos wrappers para clasificadores de sci-kit learn y keras que pueden extenderse para adaptarse a tu fase de extracción de características (si la hay).
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.
Proporcionamos algunos modelos preentrenados con los que puedes divertirte, ubicados en wafamole/models/custom/example_models. Los clasificadores que usamos se enumeran en la siguiente tabla.
Además de los WAF basados en ML, WAF-A-MoLE también soporta WAF basados en reglas. Específicamente, proporciona un wrapper para el WAF ModSecurity equipado con el OWASP Core Rule Set (CRS), basado en el proyecto pymodsecurity.
Bypass del clasificador WAF-Brain preentrenado usando un equivalente de admin' OR 1=1#.
wafamole evade --model-type waf-brain wafamole/models/custom/example_models/waf-brain.h5 "admin' OR 1=1#"
Bypass del clasificador SVM ML-Based-WAF preentrenado usando un equivalente de admin' OR 1=1#.
wafamole evade --model-type mlbasedwaf wafamole/models/custom/example_models/mlbasedwaf_svc.dump "admin' OR 1=1#"
Bypass del clasificador SVM ML-Based-WAF preentrenado usando un equivalente de admin' OR 1=1#. Nota: SQLiV5 es un conjunto de datos obtenido de Kaggle expandido con una serie de consultas generadas por el propio WAF-A-MoLE, como prueba de concepto de que las consultas de WAF-A-MoLE pueden mejorar la robustez de un WAF mediante reentrenamiento. Usa mlbasedwaf_svc_sqliv3.dump para evadir el WAF entrenado con el conjunto de datos original de Kaggle (SQLiV3).
wafamole evade --model-type mlbasedwaf wafamole/models/custom/example_models/mlbasedwaf_svc_sqliv5.dump "admin' OR 1=1#"
Bypass del clasificador SGD ML-Based-WAF preentrenado usando un equivalente de admin' OR 1=1#.
wafamole evade --model-type mlbasedwaf wafamole/models/custom/example_models/mlbasedwaf_sgd.dump "admin' OR 1=1#"
Bypass del clasificador AdaBoost ML-Based-WAF preentrenado usando un equivalente de admin' OR 1=1# (toma más tiempo que otros modelos, alrededor de 2 a 5 minutos de ejecución).
wafamole evade --model-type mlbasedwaf wafamole/models/custom/example_models/mlbasedwaf_ada.dump "admin' OR 1=1#"
Bypass del clasificador Naive Bayes basado en tokens preentrenado usando un equivalente de admin' OR 1=1#.
wafamole evade --model-type token wafamole/models/custom/example_models/naive_bayes_trained.dump "admin' OR 1=1#"
Bypass del clasificador Bosque Aleatorio basado en tokens preentrenado usando un equivalente de admin' OR 1=1#.
wafamole evade --model-type token wafamole/models/custom/example_models/random_forest_trained.dump "admin' OR 1=1#"
Bypass del clasificador SVM Lineal basado en tokens preentrenado usando un equivalente de admin' OR 1=1#.
wafamole evade --model-type token wafamole/models/custom/example_models/lin_svm_trained.dump "admin' OR 1=1#"
Bypass del clasificador SVM Gaussiana basado en tokens preentrenado usando un equivalente de admin' OR 1=1#.
wafamole evade --model-type token wafamole/models/custom/example_models/gauss_svm_trained.dump "admin' OR 1=1#"
Bypass del clasificador SQLiGOT preentrenado usando un equivalente de admin' OR 1=1#.
Usa DP, UP, DU o UU para (respectivamente) Dirigido Proporcional, No Dirigido Proporcional, Dirigido No Proporcional y No Dirigido No Proporcional.
wafamole evade --model-type DP wafamole/models/custom/example_models/graph_directed_proportional_sqligot "admin' OR 1=1#"
Bypass del OWASP ModSecurity CRS usando un equivalente de admin' OR 1=1#.
El usuario también debe especificar el Nivel de Paranoia así como la ruta para localizar las reglas CRS (por ejemplo, /etc/coreruleset).
wafamole evade --model-type modsecurity_pl[1-4] /etc/coreruleset "admin' OR 1=1#"
ANTES DE EJECUTAR LA EVALUACIÓN EN SQLiGoT
Estos clasificadores son más robustos que los demás, ya que la fase de extracción de características produce vectores con una estructura más compleja, y todos los clasificadores preentrenados han sido fuertemente regularizados. Puede llevar horas para que algunas variantes produzcan un payload que logre la evasión (ver sección de Evaluación de rendimiento).
Nota sobre modelos ML-Based-WAF más recientes
Recientemente se han añadido algunos modelos basados en una versión ligeramente modificada del ML-Based-WAF de vladan-stojnic, provenientes de una extensión de WAF-A-MoLE titulada wafamole++ por nidnogg. Probar el modelo AdaBoost puede tomar más tiempo de lo habitual (generalmente de 2 a 5 minutos).
Existen variantes entrenadas con el conjunto de datos SQLiV5.json, mientras que la mayoría utiliza por defecto la inyección SQL original del conjunto de datos de WAF-A-MoLE.
Se proporciona un notebook de Google Colaboratory con las rutinas de entrenamiento para algunos de estos modelos, utilizando el conjunto de datos original de WAF-A-MoLE (modificado al formato SQLiV5). Se puede usar cualquier conjunto de datos siempre que tenga el mismo formato que SQLiV5.json.
Primero, crea una clase Model personalizada que implemente los métodos extract_features y 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
Luego, crea un objeto a partir del modelo e instancia un objeto engine que use tu clase de modelo.
model = YourCustomModel() #your init
engine = EvasionEngine(model)
result = engine.evaluate(payload, max_rounds, round_size, timeout, threshold)
Evaluamos WAF-A-MoLE contra todos nuestros modelos de ejemplo.
El gráfico a continuación muestra el tiempo que le tomó a WAF-A-MoLE mutar el payload admin' OR 1=1# hasta que fue aceptado como benigno por cada clasificador.
En el eje x tenemos el tiempo (en segundos, escala logarítmica). En el eje y tenemos el valor de confianza, es decir, qué tan seguro está un clasificador de que un payload dado es una inyección SQL (en porcentaje).
Observa que estar "50% seguro" de que un payload es una inyección SQL es equivalente a lanzar una moneda. Este es el umbral de clasificación habitual: si la confianza es menor, el payload se clasifica como benigno.

Los experimentos se realizaron en DigitalOcean Standard Droplets.
Preguntas, informes de errores y pull requests son bienvenidos.
En particular, si estás interesado en expandir este proyecto, buscamos las siguientes contribuciones:
| Mutación | Ejemplo |
|---|
| Intercambio de mayúsculas/minúsculas | admin' OR 1=1# ⇒ admin' oR 1=1# |
| Sustitución de espacios en blanco | admin' OR 1=1# ⇒ admin'\t\rOR\n1=1# |
| Inyección de comentarios | admin' OR 1=1# ⇒ admin'/**/OR 1=1# |
| Reescritura de comentarios | admin'/**/OR 1=1# ⇒ admin'/*xyz*/OR 1=1#abc |
| Codificación de enteros | admin' OR 1=1# ⇒ admin' OR 0x1=(SELECT 1)# |
| Intercambio de operadores | admin' OR 1=1# ⇒ admin' OR 1 LIKE 1# |
| Invariante lógica | admin' OR 1=1# ⇒ admin' OR 1=1 AND 0<1# |
| Barajado de números | admin' OR 1=1# ⇒ admin' OR 2=2# |
| Nombre del clasificador | Algoritmo |
|---|
| WafBrain | Red Neuronal Recurrente |
| ML-Based-WAF | SVM No Lineal |
| ML-Based-WAF | Descenso de Gradiente Estocástico |
| ML-Based-WAF | AdaBoost |
| Basado en tokens | Naive Bayes |
| Basado en tokens | Bosque Aleatorio |
| Basado en tokens | SVM Lineal |
| Basado en tokens | SVM Gaussiana |
| SQLiGoT - Dirigido Proporcional | SVM Gaussiana |
| SQLiGoT - Dirigido No Proporcional | SVM Gaussiana |
| SQLiGoT - No Dirigido Proporcional | SVM Gaussiana |
| SQLiGoT - No Dirigido No Proporcional | SVM Gaussiana |