
ML 기반 웹 애플리케이션 방화벽을 위한 유도 돌연변이 기반 퍼저
ML 기반 웹 애플리케이션 방화벽(Web Application Firewall, WAF)을 위한 가이드 변이 기반 퍼저로, AFL에서 영감을 받았으며 Andreas Zeller 등의 FuzzingBook을 기반으로 합니다.
입력된 SQL 인젝션 쿼리가 주어지면, 대상 WAF를 우회할 수 있는 의미론적으로 동일한 쿼리를 생성하려고 시도합니다. 이 도구를 사용하여 WAF-A-MoLE이 솔루션 공간을 탐색하여 대상 분류기가 놓친 위험한 "사각지대"를 찾도록 함으로써 제품의 견고성을 평가할 수 있습니다.

WAF-A-MoLE은 초기 페이로드를 받아 페이로드 **풀(Pool)**에 삽입합니다. 이 풀은 각 페이로드에 대한 WAF 신뢰도 점수로 정렬된 우선순위 큐를 관리합니다.
각 반복(iteration) 동안, 페이로드 풀의 헤드는 **퍼저(Fuzzer)**로 전달되어 사용 가능한 변이 연산자 중 하나를 무작위로 적용하여 변이(mutate)됩니다.
모든 변이 연산자는 의미론을 보존하며 SQL 언어의 높은 표현력(이 버전에서는 MySQL)을 활용합니다.
다음은 현재 버전의 WAF-A-MoLE에서 사용 가능한 변이 연산자입니다.
WAF-A-MoLE은 "WAF-A-MoLE: Evading Web Application Firewalls through Adversarial Machine Learning"에서 제시된 방법론을 구현합니다. 사전 인쇄본은 arXiv에서도 찾을 수 있습니다.
인용을 원하시면 다음 (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
자체 WAF의 견고성을 평가하거나 일부 예제 분류기를 대상으로 WAF-A-MoLE을 시험해 볼 수 있습니다. 첫 번째 경우, Model 클래스를 확인하십시오. 커스텀 모델은 이 클래스를 구현해야 WAF-A-MoLE에서 평가할 수 있습니다. 이미 sci-kit learn 및 keras 분류기를 위한 래퍼를 제공하며, 필요에 따라 특징 추출 단계에 맞게 확장할 수 있습니다.
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.
wafamole/models/custom/example_models에 사전 훈련된 모델 몇 개를 제공하여 재미있게 실험해 볼 수 있습니다. 사용된 분류기는 아래 표에 나와 있습니다.
ML 기반 WAF 외에도, WAF-A-MoLE은 규칙 기반 WAF도 지원합니다. 특히, pymodsecurity 프로젝트를 기반으로 한 OWASP Core Rule Set (CRS)이 장착된 ModSecurity WAF용 래퍼를 제공합니다.
admin' OR 1=1#과 동등한 쿼리를 사용하여 사전 훈련된 WAF-Brain 분류기를 우회합니다.
wafamole evade --model-type waf-brain wafamole/models/custom/example_models/waf-brain.h5 "admin' OR 1=1#"
admin' OR 1=1#과 동등한 쿼리를 사용하여 사전 훈련된 ML-Based-WAF SVM 분류기를 우회합니다.
wafamole evade --model-type mlbasedwaf wafamole/models/custom/example_models/mlbasedwaf_svc.dump "admin' OR 1=1#"
admin' OR 1=1#과 동등한 쿼리를 사용하여 사전 훈련된 ML-Based-WAF SVM 분류기를 우회합니다. SQLiV5는 Kaggle에서 가져온 데이터셋에 WAF-A-MoLE 자체에서 생성된 일련의 쿼리를 확장한 것으로, WAF-A-MoLE 쿼리가 재훈련을 통해 WAF의 견고성을 향상시킬 수 있다는 개념 증명입니다. 원본 Kaggle 데이터셋(SQLiV3)으로 훈련된 WAF를 우회하려면 mlbasedwaf_svc_sqliv3.dump를 사용하십시오.
wafamole evade --model-type mlbasedwaf wafamole/models/custom/example_models/mlbasedwaf_svc_sqliv5.dump "admin' OR 1=1#"
admin' OR 1=1#과 동등한 쿼리를 사용하여 사전 훈련된 ML-Based-WAF SGD 분류기를 우회합니다.
wafamole evade --model-type mlbasedwaf wafamole/models/custom/example_models/mlbasedwaf_sgd.dump "admin' OR 1=1#"
admin' OR 1=1#과 동등한 쿼리를 사용하여 사전 훈련된 ML-Based-WAF AdaBoost 분류기를 우회합니다 (다른 모델보다 시간이 오래 걸리며, 약 2~5분 정도 소요).
wafamole evade --model-type mlbasedwaf wafamole/models/custom/example_models/mlbasedwaf_ada.dump "admin' OR 1=1#"
admin' OR 1=1#과 동등한 쿼리를 사용하여 사전 훈련된 토큰 기반 나이브 베이즈 분류기를 우회합니다.
wafamole evade --model-type token wafamole/models/custom/example_models/naive_bayes_trained.dump "admin' OR 1=1#"
admin' OR 1=1#과 동등한 쿼리를 사용하여 사전 훈련된 토큰 기반 랜덤 포레스트 분류기를 우회합니다.
wafamole evade --model-type token wafamole/models/custom/example_models/random_forest_trained.dump "admin' OR 1=1#"
admin' OR 1=1#과 동등한 쿼리를 사용하여 사전 훈련된 토큰 기반 선형 SVM 분류기를 우회합니다.
wafamole evade --model-type token wafamole/models/custom/example_models/lin_svm_trained.dump "admin' OR 1=1#"
admin' OR 1=1#과 동등한 쿼리를 사용하여 사전 훈련된 토큰 기반 가우시안 SVM 분류기를 우회합니다.
wafamole evade --model-type token wafamole/models/custom/example_models/gauss_svm_trained.dump "admin' OR 1=1#"
admin' OR 1=1#과 동등한 쿼리를 사용하여 사전 훈련된 SQLiGOT 분류기를 우회합니다.
DP (방향 비례), UP (무방향 비례), DU (방향 비비례), UU (무방향 비비례)를 사용하십시오.
wafamole evade --model-type DP wafamole/models/custom/example_models/graph_directed_proportional_sqligot "admin' OR 1=1#"
admin' OR 1=1#과 동등한 쿼리를 사용하여 OWASP ModSecurity CRS를 우회합니다.
사용자는 파라노이아 수준(Paranoia Level)과 CRS 규칙이 위치한 경로(예: /etc/coreruleset)도 지정해야 합니다.
wafamole evade --model-type modsecurity_pl[1-4] /etc/coreruleset "admin' OR 1=1#"
SQLiGoT 평가 시작 전 주의사항
이 분류기들은 특징 추출 단계에서 더 복잡한 구조의 벡터를 생성하고, 모든 사전 훈련된 분류기가 강하게 정규화되어 있어 다른 분류기보다 견고합니다. 일부 변종은 우회를 달성하는 페이로드를 생성하는 데 몇 시간이 걸릴 수 있습니다 (벤치마크 섹션 참조).
최신 ML-Based-WAF 모델 참고사항
vladan-stojnic의 ML-Based-WAF를 약간 수정한 버전을 기반으로 한 일부 모델이 최근 nidnogg의 wafamole++라는 WAF-A-MoLE 확장판에서 추가되었습니다. AdaBoost 모델 테스트는 일반보다 시간이 더 오래 걸릴 수 있습니다 (보통 2~5분).
대부분은 기본적으로 WAF-A-MoLE 데이터셋의 원본 SQL 인젝션을 사용하지만, SQLiV5.json 데이터셋으로 훈련된 변종도 있습니다.
Google Colaboratory 노트북이 이러한 모델 중 일부의 훈련 루틴을 위해 제공되며, 원본 WAF-A-MoLE 데이터셋(SQLiV5 형식으로 수정됨)을 사용합니다. SQLiV5.json과 동일한 형식이라면 모든 데이터셋을 사용할 수 있습니다.
먼저 extract_features 및 classify 메서드를 구현하는 커스텀 Model 클래스를 만듭니다.
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
그런 다음 모델에서 객체를 생성하고, 해당 모델 클래스를 사용하는 engine 객체를 인스턴스화합니다.
model = YourCustomModel() #your init
engine = EvasionEngine(model)
result = engine.evaluate(payload, max_rounds, round_size, timeout, threshold)
모든 예제 모델에 대해 WAF-A-MoLE을 평가했습니다.
아래 그래프는 WAF-A-MoLE이 admin' OR 1=1# 페이로드를 각 분류기가 정상(benign)으로 분류할 때까지 변이하는 데 걸린 시간을 보여줍니다.
x 축은 시간(초, 로그 스케일)입니다. y 축은 신뢰도(confidence) 값, 즉 분류기가 주어진 페이로드가 SQL 인젝션일 것이라고 확신하는 정도(백분율)입니다.
페이로드가 SQL 인젝션이라고 "50% 확신"하는 것은 동전 던지기와 동일합니다. 이는 일반적인 분류 임계값입니다. 신뢰도가 더 낮으면 페이로드는 정상으로 분류됩니다.

실험은 DigitalOcean Standard Droplets에서 수행되었습니다.
질문, 버그 신고 및 풀 리퀘스트를 환영합니다.
특히 이 프로젝트를 확장하는 데 관심이 있다면, 다음과 같은 기여를 환영합니다:
| 변이(Mutation) | 예제(Example) |
|---|
| 대소문자 변경 (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# |
| 분류기 이름(Classifier name) | 알고리즘(Algorithm) |
|---|
| WafBrain | 순환 신경망 (Recurrent Neural Network) |
| ML-Based-WAF | 비선형 SVM (Non-Linear SVM) |
| ML-Based-WAF | 확률적 경사 하강법 (Stochastic Gradient Descent) |
| ML-Based-WAF | AdaBoost |
| 토큰 기반 (Token-based) | 나이브 베이즈 (Naive Bayes) |
| 토큰 기반 (Token-based) | 랜덤 포레스트 (Random Forest) |
| 토큰 기반 (Token-based) | 선형 SVM (Linear SVM) |
| 토큰 기반 (Token-based) | 가우시안 SVM (Gaussian SVM) |
| SQLiGoT - 방향 비례 (Directed Proportional) | 가우시안 SVM (Gaussian SVM) |
| SQLiGoT - 방향 비비례 (Directed Unproportional) | 가우시안 SVM (Gaussian SVM) |
| SQLiGoT - 무방향 비례 (Undirected Proportional) | 가우시안 SVM (Gaussian SVM) |
| SQLiGoT - 무방향 비비례 (Undirected Unproportional) | 가우시안 SVM (Gaussian SVM) |