XSStrikeを読む part1
はじめに
めちゃくちゃイケてて最高なXSStrike の中身を読もうという記事です。
最近カメ並のスピードで最強のXSSスキャナーを目指して開発をしているのですが、 さすがに既存のXSSスキャナーが何をやってるのか把握していないのはまずいだろうということで、 今回は3、4回に分けてXSStrikeのロジックを読んでまとめていこうと思います。
ZAPは過去に読んだのですが、XSStrikeは未読なのでワクワクです。
ちなみに昨年ZAPのXSSルールを読んだ時は、こちらの記事の内容とほぼほぼ一緒でしたのでお勧めです。 OWASP ZAPのXSS(Cross-site scripting)診断は何をしているのか? – Web Application Security Memo
最強のXSSスキャナーを作るのであれば、 Burp, ZAP, Arachni, Nikto などのスキャナーも読む必要があるのでは?と思われるかもしれませんが、 Burpは有償なのでペイロードくらいしか見れないですし、 Arachni はサポート切れですし(かなり読みやすいのでお勧め)、 Nikto は汎用スキャナー且つ Perl なので読む気力が・・・
ということで、XSStrike以外はちゃんと読むきあまりなしです。
では行ってみましょう
ファイル一覧
読んでいくにあたり、 ひとまずファイル一覧を眺めつつ、 main関数から派生していく処理をみていきましょう。 ではまずファイル一覧から
重要ファイル (.py のみ)
- xsstrike.py (main file)
/modes
* bruteforcer.py
* crawl.py
* scan.py
* singleFuzz.py
/core
* arjun.py
* checker.py
* colors.py
* config.py
* dom.py
* encoders.py
* filterChecker.py
* fuzzer.py
* generator.py
* htmlParser.py
* jsContexter.py
* log.py
* photon.py
* prompt.py
* requester.py
* updater.py
* utils.py
* wafDetector.py
* zetanize.py
/plugins
* retireJs.py
その他ファイル
/db
* definitions.json
* wafSinatures.json
コードを読む
main 関数
メイン関数は以下の行から、大きく処理が別れます。 (以下のURLの行よりも前の部分は、パラメータとかデータの初期化とかそういう処理ばかりなので無視)
XSStrike/xsstrike.py at 0ecedc1bba149931e3b32e53422d5b7c089ba9dc · s0md3v/XSStrike · GitHub
main 処理は以下の4つに大きく分岐します。
- singleFuzz()
- bruteforcer()
- scan()
- photon() ( + crawl())
今回の記事では singleFuzz()
をみていきます。
singleFuzz()
シングルファズは文字通り Fuzzing をするもので、 スキャンなどの脆弱性検知までは行われません。
主な目的は FireWall のテストで、 ランダム遅延を行いつつリクエストを送っていくという処理を行います。
ここには --fuzzer
パラメータをONにすると入ってきます。
XSStrike/singleFuzz.py at 0ecedc1bba149931e3b32e53422d5b7c089ba9dc · s0md3v/XSStrike · GitHub
singleFuzz() のフロー
paramData ( e.g.
--data q=123
などのパラメータ) が存在するかで GET, POST どちらかを選択するprotocol(http, https) の決定。 target URLが https だった場合、httpsのリクエストを送って対応しているか確認。 https がだめだったら以後のリクエストは http ベースになる。
wafDetector()
リクエストパラメータ(複数)を forEach みたいな感じでループ。 ループ時に、その index 番目のパラメータの値を
v3dm0s
に変更(あとでペイロードに置換するための足跡)
(インデントが足らないので囲む) https://github.com/s0md3v/XSStrike/blob/0ecedc1bba149931e3b32e53422d5b7c089ba9dc/core/config.py#L66 にあるペイロード(複数)を、対象のリクエストパラメータ(単体)に変えてく感じでループ(以下がその処理) (ペイロードを対象(単体)のパラメータに埋め込んで送り込む所:) 1. ペイロードの文字列数・処理の中で変動する数値をベースに sleep をかける 2. ペイロードをデコードしたあとにエンコードする 3. 前もって置換しておいた `v3dm0s` (ペイロードの置換用の足跡)をペイロードに置換 4. リクエストを送る 1. エラーが起きた時はしばらくsleepしてから再送。 2. 再送で失敗した場合は IP がブロックされたと判断して停止 3. 再送が成功した場合は、sleepが功を奏したとして、 `5.` (次の行)に移動 5. レスポンスにペイロードがないかをレスポンス, ペイロード共に lower してマッチング 6. あった場合は [pass], status code が 2xx 系以外の場合は [block], その他の場合は [filtered] というログレベルで吐き出して終わり。
終わりに
今回は singleFuzz()
の中身を読んだ。
次回は bruteforce()
を読む
補足
以下のファイルには、 XSStrike における重要なペイロードや、 多分今後出てきそうなXSSの有無をチェックするためのタグ一覧などが格納されている。
XSStrike/config.py at master · s0md3v/XSStrike · GitHub
主な内容はいかが格納されてる。
- delay などのプロパティ値
- 特別な { 属性, タグ }
- 普通の { タグ }
- js, tag, handler, space のセパレーターとなる文字列
- event handler
- POP UP を出現させる関数のペイロードパターン (confirm, prompt 各3パターン)
- Filter / WAF を回避する 20パターン
- Fuzz strings to test WAFs
- WAF をテストするためのPayloads 30種
- default request header (UA, Upgrade-Insecure-Request, Accept など)
- パラメータ発見のために利用される総当たり用の一般的なパラメータ名 95種類