MLベースのWebアプリケーションファイアウォール(WAF)向けの、AFLに触発され、Andreas ZellerらのFuzzingBookを基にした ガイド付きミューテーションベースのファザー です。
SQLインジェクションクエリを入力として与えると、ターゲットのWAFをバイパスできる 意味論的に不変な クエリを生成しようとします。WAF-A-MoLEに解空間を探索させることで、ターゲットの分類器がカバーしていない危険な「盲点」を見つけ、製品の堅牢性を評価するためにこのツールを使用できます。

WAF-A-MoLEは最初のペイロードを受け取り、それをペイロード Pool に挿入します。このPoolは、各ペイロードに対するWAFの信頼度スコアで順序付けられた優先度キューを管理します。
各イテレーションでは、ペイロードPoolの先頭が Fuzzer に渡され、利用可能なミューテーション演算子の1つを適用することでランダムに変異されます。
ミューテーション演算子はすべて 意味論を保持 しており、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の堅牢性を強化できることの概念実証です。mlbasedwaf_svc_sqliv3.dump を使用すると、元のKaggleデータセット(SQLiV3)で学習されたWAFをバイパスできます。
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をバイパスします。
ユーザーはパラノイアレベルと、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によるWAF-A-MoLEの拡張版であるwafamole++から最近追加されました。AdaBoostモデルのテストには通常より時間がかかる場合があります(通常2~5分)。
SQLiV5.jsonデータセットで学習されたバリアントもありますが、ほとんどのモデルはデフォルトでWAF-A-MoLEデータセットの元のSQLインジェクションを使用しています。
これらのモデルの一部の学習ルーチンは、元のWAF-A-MoLEデータセット(SQLiV5形式に変更)を使用して、Google Colaboratoryのノートブックで提供されています。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# ペイロードを、各分類器が良性として受け入れるまでに変異させるのにかかった時間を示しています。
x軸は時間(秒、対数スケール)です。 y軸は 信頼度 値、つまり分類器が特定のペイロードがSQLインジェクションであると確信している度合い(パーセンテージ)です。
ペイロードがSQLインジェクションであると「50%確信」していることは、コイン投げと同等であることに注意してください。これが通常の分類しきい値です。信頼度がこれより低い場合、ペイロードは良性として分類されます。

実験はDigitalOcean Standard Dropletsで実行されました。
質問、バグ報告、プルリクエストを歓迎します。
特に、このプロジェクトの拡張に興味がある場合は、以下の貢献を求めています。
| ミューテーション | 例 |
|---|
| ケーススワップ | admin' OR 1=1# ⇒ admin' oR 1=1# |
| 空白置換 | admin' OR 1=1# ⇒ admin'\t\rOR\n1=1# |
| コメント挿入 | admin' OR 1=1# ⇒ admin'/**/OR 1=1# |
| コメント書き換え | admin'/**/OR 1=1# ⇒ admin'/*xyz*/OR 1=1#abc |
| 整数エンコーディング | admin' OR 1=1# ⇒ admin' OR 0x1=(SELECT 1)# |
| 演算子スワップ | admin' OR 1=1# ⇒ admin' OR 1 LIKE 1# |
| 論理的不変式 | admin' OR 1=1# ⇒ admin' OR 1=1 AND 0<1# |
| 数字シャッフリング | admin' OR 1=1# ⇒ admin' OR 2=2# |
| 分類器名 | アルゴリズム |
|---|
| WafBrain | リカレントニューラルネットワーク |
| ML-Based-WAF | 非線形SVM |
| ML-Based-WAF | 確率的勾配降下法 |
| ML-Based-WAF | AdaBoost |
| トークンベース | ナイーブベイズ |
| トークンベース | ランダムフォレスト |
| トークンベース | 線形SVM |
| トークンベース | ガウシアンSVM |
| SQLiGoT - 有向比例 | ガウシアンSVM |
| SQLiGoT - 有向非比例 | ガウシアンSVM |
| SQLiGoT - 無向比例 | ガウシアンSVM |
| SQLiGoT - 無向非比例 | ガウシアンSVM |