
Um fuzzer guiado baseado em mutação para Firewalls de Aplicação Web baseados em ML.
Um fuzzer guiado por mutação para Firewalls de Aplicação Web baseados em ML, inspirado no AFL e baseado no FuzzingBook de Andreas Zeller e outros.
Dado um ataque de injeção SQL de entrada, ele tenta produzir uma consulta semanticamente invariante que consiga contornar o WAF alvo. Você pode usar esta ferramenta para avaliar a robustez do seu produto, deixando o WAF-A-MoLE explorar o espaço de soluções para encontrar "pontos cegos" perigosos não cobertos pelo classificador alvo.

O WAF-A-MoLE pega um payload inicial e o insere no Pool de payloads, que gerencia uma fila de prioridade ordenada pela pontuação de confiança do WAF sobre cada payload.
Durante cada iteração, o cabeça do Pool de payloads é passado para o Fuzzer, onde é mutado aleatoriamente, aplicando um dos operadores de mutação disponíveis.
Os operadores de mutação preservam todos a semântica e aproveitam o alto poder expressivo da linguagem SQL (nesta versão, MySQL).
Abaixo estão os operadores de mutação disponíveis na versão atual do WAF-A-MoLE.
O WAF-A-MoLE implementa a metodologia apresentada em "WAF-A-MoLE: Evading Web Application Firewalls through Adversarial Machine Learning". Uma pré-impressão do nosso artigo também pode ser encontrada no arXiv.
Se quiser citar-nos, utilize a seguinte referência (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
Pode avaliar a robustez do seu próprio WAF, ou testar o WAF-A-MoLE contra alguns classificadores de exemplo. No primeiro caso, consulte a classe Model. O seu modelo personalizado precisa implementar esta classe para ser avaliado pelo WAF-A-MoLE. Já fornecemos wrappers para classificadores do sci-kit learn e keras que podem ser estendidos para se adequar à sua fase de extração de características (se houver).
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.
Fornecemos alguns modelos pré-treinados com os quais pode se divertir, localizados em wafamole/models/custom/example_models. Os classificadores que utilizamos estão listados na tabela abaixo.
Além dos WAFs baseados em ML, o WAF-a-MoLE também suporta WAFs baseados em regras. Especificamente, fornece um wrapper para o WAF ModSecurity equipado com o OWASP Core Rule Set (CRS), baseado no projeto pymodsecurity.
Contorne o classificador WAF-Brain pré-treinado usando um equivalente a admin' OR 1=1#.
wafamole evade --model-type waf-brain wafamole/models/custom/example_models/waf-brain.h5 "admin' OR 1=1#"
Contorne o classificador SVM do ML-Based-WAF pré-treinado usando um equivalente a admin' OR 1=1#.
wafamole evade --model-type mlbasedwaf wafamole/models/custom/example_models/mlbasedwaf_svc.dump "admin' OR 1=1#"
Contorne o classificador SVM do ML-Based-WAF pré-treinado usando um equivalente a admin' OR 1=1#. Note que o SQLiV5 é um conjunto de dados proveniente do Kaggle expandido com uma série de consultas geradas pelo próprio WAF-A-MoLE, como prova de conceito de que as consultas do WAF-A-MoLE podem melhorar a robustez de um WAF com retreinamento. Use mlbasedwaf_svc_sqliv3.dump para contornar o WAF treinado com o conjunto de dados original do Kaggle (SQLiV3).
wafamole evade --model-type mlbasedwaf wafamole/models/custom/example_models/mlbasedwaf_svc_sqliv5.dump "admin' OR 1=1#"
Contorne o classificador SGD do ML-Based-WAF pré-treinado usando um equivalente a admin' OR 1=1#.
wafamole evade --model-type mlbasedwaf wafamole/models/custom/example_models/mlbasedwaf_sgd.dump "admin' OR 1=1#"
Contorne o classificador AdaBoost do ML-Based-WAF pré-treinado usando um equivalente a admin' OR 1=1# (demora mais que outros modelos, cerca de 2 a 5 minutos de execução).
wafamole evade --model-type mlbasedwaf wafamole/models/custom/example_models/mlbasedwaf_ada.dump "admin' OR 1=1#"
Contorne o classificador Naive Bayes baseado em tokens pré-treinado usando um equivalente a admin' OR 1=1#.
wafamole evade --model-type token wafamole/models/custom/example_models/naive_bayes_trained.dump "admin' OR 1=1#"
Contorne o classificador Random Forest baseado em tokens pré-treinado usando um equivalente a admin' OR 1=1#.
wafamole evade --model-type token wafamole/models/custom/example_models/random_forest_trained.dump "admin' OR 1=1#"
Contorne o classificador SVM Linear baseado em tokens pré-treinado usando um equivalente a admin' OR 1=1#.
wafamole evade --model-type token wafamole/models/custom/example_models/lin_svm_trained.dump "admin' OR 1=1#"
Contorne o classificador SVM Gaussiano baseado em tokens pré-treinado usando um equivalente a admin' OR 1=1#.
wafamole evade --model-type token wafamole/models/custom/example_models/gauss_svm_trained.dump "admin' OR 1=1#"
Contorne o classificador SQLiGOT pré-treinado usando um equivalente a admin' OR 1=1#.
Use DP, UP, DU ou UU para (respetivamente) Proporcional Direcionado, Proporcional Não Direcionado, Desproporcional Direcionado e Desproporcional Não Direcionado.
wafamole evade --model-type DP wafamole/models/custom/example_models/graph_directed_proportional_sqligot "admin' OR 1=1#"
Contorne o OWASP ModSecurity CRS usando um equivalente a admin' OR 1=1#.
O utilizador também precisa especificar o Nível de Paranóia bem como o caminho para localizar as regras do CRS (por exemplo, /etc/coreruleset).
wafamole evade --model-type modsecurity_pl[1-4] /etc/coreruleset "admin' OR 1=1#"
ANTES DE INICIAR A AVALIAÇÃO NO SQLiGoT
Estes classificadores são mais robustos que os outros, pois a fase de extração de características produz vetores com estrutura mais complexa, e todos os classificadores pré-treinados foram fortemente regularizados. Pode levar horas para que algumas variantes produzam um payload que atinja a evasão (consulte a secção Benchmark).
Nota sobre modelos ML-Based-WAF mais recentes
Alguns modelos baseados numa versão ligeiramente modificada do ML-Based-WAF de vladan-stojnic foram adicionados recentemente, provenientes de uma extensão do WAF-A-MoLE intitulada wafamole++ por nidnogg. Testar o modelo AdaBoost pode demorar mais do que o habitual (normalmente 2 a 5 minutos).
Existem variantes treinadas com o conjunto de dados SQLiV5.json, enquanto a maioria usa a injeção SQL original do conjunto de dados do WAF-A-MoLE por omissão.
É fornecido um notebook do Google Colaboratory com as rotinas de treino para alguns destes modelos, usando o conjunto de dados original do WAF-A-MoLE (modificado para o formato SQLiV5). Qualquer conjunto de dados pode ser usado desde que esteja no mesmo formato que o SQLiV5.json.
Primeiro, crie uma classe Model personalizada que implemente os métodos extract_features e classify.
class YourCustomModel(Model):
def extract_features(self, value: str):
# TODO: extrair características
feature_vector = your_custom_feature_function(value)
return feature_vector
def classify(self, value):
# TODO: calcular confiança
confidence = your_confidence_eval(value)
return confidence
Depois, crie um objeto a partir do modelo e instancie um objeto engine que use a sua classe de modelo.
model = YourCustomModel() #a sua inicialização
engine = EvasionEngine(model)
result = engine.evaluate(payload, max_rounds, round_size, timeout, threshold)
Avaliámos o WAF-A-MoLE contra todos os nossos modelos de exemplo.
O gráfico abaixo mostra o tempo que o WAF-A-MoLE demorou a mutar o payload admin' OR 1=1# até que fosse aceite por cada classificador como benigno.
No eixo x temos o tempo (em segundos, escala logarítmica). No eixo y temos o valor de confiança, ou seja, o quão certo um classificador está de que um determinado payload é uma injeção SQL (em percentagem).
Note que estar "50% seguro" de que um payload é uma injeção SQL equivale a lançar uma moeda ao ar. Este é o limiar de classificação habitual: se a confiança for inferior, o payload é classificado como benigno.

As experiências foram realizadas em DigitalOcean Standard Droplets.
Perguntas, relatórios de erros e pull requests são bem-vindos.
Em particular, se estiver interessado em expandir este projeto, procuramos as seguintes contribuições:
| Mutação | Exemplo |
|---|
| Troca de Maiúsculas/Minúsculas | admin' OR 1=1# ⇒ admin' oR 1=1# |
| Substituição de Espaços em Branco | admin' OR 1=1# ⇒ admin'\t\rOR\n1=1# |
| Inserção de Comentários | admin' OR 1=1# ⇒ admin'/**/OR 1=1# |
| Reescrita de Comentários | admin'/**/OR 1=1# ⇒ admin'/*xyz*/OR 1=1#abc |
| Codificação de Inteiros | admin' OR 1=1# ⇒ admin' OR 0x1=(SELECT 1)# |
| Troca de Operadores | admin' OR 1=1# ⇒ admin' OR 1 LIKE 1# |
| Invariante Lógico | admin' OR 1=1# ⇒ admin' OR 1=1 AND 0<1# |
| Embaralhamento de Números | admin' OR 1=1# ⇒ admin' OR 2=2# |
| Nome do Classificador | Algoritmo |
|---|
| WafBrain | Rede Neural Recorrente |
| ML-Based-WAF | SVM Não Linear |
| ML-Based-WAF | Gradiente Descendente Estocástico |
| ML-Based-WAF | AdaBoost |
| Baseado em Tokens | Naive Bayes |
| Baseado em Tokens | Random Forest |
| Baseado em Tokens | SVM Linear |
| Baseado em Tokens | SVM Gaussiano |
| SQLiGoT - Proporcional Direcionado | SVM Gaussiano |
| SQLiGoT - Desproporcional Direcionado | SVM Gaussiano |
| SQLiGoT - Proporcional Não Direcionado | SVM Gaussiano |
| SQLiGoT - Desproporcional Não Direcionado | SVM Gaussiano |