はじめに
XSS対策の記事はよくあるけど、
いざ侵入テストを作るために気をつけるべきことといった記事はあまりないよなと思い今回記事にしてみました。(自分も知りたかった。)
正直XSSとか調査して教えてくれたらいくら払います的なことがされているサイトや会社あるので見つけるのは相当難しいのかもしれませんが、
結構自分なりにどうすれば侵入テストである程度発見できるか考えられたと思ったので記事にしてみました!
こんな時はこれだと検知出来ないよねなどあればコメント等で教えていただけるとかなり嬉しいです!
よろしくお願いいたします!自分もさらに検知できる方法等あれば記事追加していく所存です!
世の中には、
『OWASP ZAP』といった侵入テストツールや、
『XSS Locator (Polygot)』といった便利なXSS検査用の文字列があります。
XSS Locator (Polygot)の文字列 ※リンク先と同じものです。
javascript:/*--></title></style></textarea></script></xmp><svg/onload='+/"/+/onmouseover=1/+/[*/[]/+alert(1)//'>
ありますね、、 ←共感は自分でシステムです!(◍•ᴗ•◍)
ですが、
これでどこまで検知出来る?
そもそもどういう風にテストをするべき?
検査する時気をつけるべきことはないの?
どのようにXSSの侵入テストを作ればよりXSSを検知出来るの?
等々色々思うことあるかと思います!
そんな色々なことを思ったので実際にやってみた結果、
自分でXSSの侵入テストを作成する時にこういうことを気をつけて作成するといいのかなと思ったこと等々書いていきたいと思います!
よろしくお願いします!
あと、自分で作成した侵入テスト全ての検査でjs実行発火で確認できるのが理想なのですが、
それは難しいと思う箇所あるのでそういった場合は、
この文字入れて普通ならこういう挙動になるのにならない怪しいで検知したことにできるとしているとします!(サンプルで作成したものは実際の攻撃コードで発火で確認はしています。これはテストを作る際にのお話です。)
あと基本は『侵入テスト』の前に『エスケープ』されているか『スキームのチェック』されているか等のチェックが先になるかと思っています!
↑いらすとやさんの画像かわいいです!
では早速!
注意:あくまで自分なりに色々お試ししたというものです。絶対にこうだ!というわけではないということご了承ください。
最終的に言いたいことは以下箇所にあります。それまではなぜそう思ったかの説明的な感じです。
あとお試し用のgithubのリンクです! 『※sample-a1』的なやつは以下のコードの中のフォルダ名言ってます!
『OWASP ZAP』 VS 『XSS Locator (Polygot)』
まず色々な脆弱性があるページで、
『OWASP ZAP』 と 『XSS Locator (Polygot)』ならどれぐらい検知出来るか調べてみました!
※これは色々なサイトから拾ってきたものやPolygotの文字列見て想定して作ったもの色々あります。
以下の表見てもらうと色々なことがわかります。
・軽いXSSは両方ともある程度検知できる。
・『OWASP ZAP』はスキームチェックする時しない時ある? ※sample-a9
・どちらも正規表現での脆弱性の検知は基本出来ない。
・どちらもエラー箇所等での脆弱性の検知は基本出来ない。
・基本的に『OWASP ZAP』の方が検知出来ていない。
・ 『XSS Locator (Polygot)』は検知の仕方とか入力を間違えると検知出来ない場合も出てくる。(後程詳しく)
※ちなみにですが、owaspzapの攻撃コードで問題なく問題検知出来るか実際に全てのページで自分で確認しています。(OWASPZAPで引っかかったから検知としているのではなくさらに自分で確認して検知出来るか確認したという感じです。)!
※この表で出しているものは攻撃コードでjs発火全てします。
※お試ししたgithubのリンクです。
正常時入る想定の値の例 | OWASP ZAP | XSS Locator (Polygot) | |
---|---|---|---|
<title>中のエスケープもれ ※sample-a1 |
1 | 検知出来た | 検知出来た |
<style>中のエスケープもれ ※sample-a2 | red | 検知出来た | 検知出来た |
<textarea>中のエスケープもれ ※sample-a3 | 初めての投稿です! | 検知出来た | 検知出来た |
<script>中のエスケープもれ ※sample-a4 | sss | 検知出来た | 検知出来た |
<xmp>中のエスケープもれ ※sample-a5 | sample | 検知出来た | 検知出来た |
<pre>中のエスケープもれ ※sample-a6 | sample | 検知出来た | 検知出来た |
エスケープ不十分 ※sample-a7 『"』と『'』のエスケープされないもの |
red | 検知出来た | 検知出来た |
エスケープ不十分 ※sample-a8 『"』と『'』のエスケープされないもの |
"color: red" | 検知出来ず | 検知出来た (""で囲って入力必須) |
urlスキームチェック漏れ ※sample-a9 | https://sachiko-kame.github.io/ | 検知出来ず | 検知出来た |
php文字列出力をHTMLのコメントで囲った箇所のエスケープもれ ※sample-b1 | sample | 検知出来た | 検知出来た |
不適切なエスケープ箇所 ※sample-b2 phpの出力をjsのエスケープ関数で囲っている |
sample | 検知出来た | 検知出来た |
for文内のエスケープ漏れ ※sample-b3 | 良い天気ですね#出来事#天気#aaa | 検知出来た | 検知出来た (#の後ろに入力必須) |
for文内のエスケープ漏れ ※sample-b4 scriptの文字だけ弾く処理入れたもの |
良い天気ですね#出来事#天気#aaa | 検知出来た | 検知出来た (#の後ろに入力必須) |
正規表現にユーザーの入力を入れられチェック不十分(phpコード内) ※sample-b5 基本正規表現をユーザー入力で作成しない |
https://sachiko-kame.github.io#abc | 検知出来ず | 検知出来ず |
正規表現にユーザーの入力を入れられチェック不十分(jsコード内) ※sample-b6 基本正規表現をユーザー入力で作成しない |
https://sachiko-kame.github.io#abc | 検知出来ず | 検知出来ず |
正規表現にユーザーの入力を一部入れられチェック不十分(phpコード内) ※sample-b7 基本正規表現をユーザー入力で作成しない |
http://192.168.99.100:86/sample-b7/?name=sachiko | 検知出来ず | 検知出来ず |
正規表現にユーザーの入力を一部入れられチェック不十分(jsコード内) ※sample-b8 基本正規表現をユーザー入力で作成しない |
http://192.168.99.100:86/sample-b8/?name=sachiko | 検知出来ず | 検知出来ず |
styleのクラス記述箇所にプレフィックス入れた後エスケープ漏れ ※sample-b9 | php | 検知出来ず | 検知出来た (マウスオーバーしてチェック必須) |
trycatchのエラー出力文言のエスケープ漏れ ※sample-c1 | sample | 検知出来ず | 検知出来ず |
iframeのurlスキームチェック漏れ ※sample-c2 | https://sachiko-kame.github.io/ | 検知出来た | 検知出来た |
『XSS Locator (Polygot)』の検査の様子。手順は以下です!
①まず問題ないテキストで問題ないこと確認。(攻撃コードでちゃんと攻撃発火するためにまず問題ないを確認)
②サンプル用に作った攻撃コードで攻撃がちゃんと出来ているか確認。
③XSS Locator (Polygot)の文字列で攻撃して攻撃検知できるか確認。
owasp_zapの検知画像とか貼ってて見にくいのはご了承ください。
owaspzapの動画は今回省略させて頂きますやり方は以下のものわかりやすかったのでリンク貼っておきます!
https://chigusa-web.com/blog/owasp-zap-install/
『XSS Locator (Polygot)』は検知の仕方とか入力を間違えると検知出来ない場合も出てくる??
本題に入る前に自分が気をつけようと思ったことについて話させて頂こうと思います!
よろしくお願いします!
当たり前かもなのですが、
- ユーザーが自由に入力出来る箇所に 『XSS Locator (Polygot)』の値を入れるべき。
- ユーザーが自由に入力出来る箇所にシステムが指定した文字を入れるよう指示とかあればシステムが指示した文字+ 『XSS Locator (Polygot)』を入れるべき。
(説明わかりづらくすみません、後程動画も用意しましたのでそちらもみていただけると嬉しいです。)
まず最初の方ですが例えばurlの『#(ハッシュ)』以降に好きな文字を入れる場合、 『XSS Locator (Polygot)』の値も『#(ハッシュ)』以降に入れないといけないということ。
※パス以降に好きな文字とか入れられるシステムならその時は 『XSS Locator (Polygot)』の値をパス以降に入れるとかシステムにあった方法で検査すべきということです。と言ってますができるなら全ての可能性考えて全てテストが理想ではあると思ってます。(パラメーター、ハッシュ後の値、フォーム入力あればフォームにも、パスに入れられる可能性なくてもパスにも念のため的な)
○
https://sachiko-kame.github.io#<<Polygotの値>>
× ※以下は論外そもそもURL全部にPolygotの値の値入れるとかアクセスもされませんからね、
<<Polygotの値>>
×(出来たら本当はこれもしたいのはあるのですが、)
https://sachiko-kame.github.io/<<Polygotの値>>
次のユーザーが自由に入力出来る箇所にシステムが指定した文字を入れるよう指示とかあればシステムが指示した文字+ 『XSS Locator (Polygot)』を入れるべきなのですが、
例えばユーザに入力してもらうものをこういう風に入力してください的なもの言っていた場合、
例えば入力値を『"』で囲ってくださいとか、前に『aa』をつけて入力してくださいみたいに指定した場合、 『XSS Locator (Polygot)』の値はそれをした箇所に入れるべきということです。※できるならそれしないパターンも必要かとは思っています。
『"』で囲って入力してくださいと指定している場合、
○
"<<Polygotの値>>"
×(出来たら本当はこれもしたいのはあるのですが、)
<<Polygotの値>>
自分の説明だとわかりにくいかと思うので実際に動画を用意しました!
『ユーザーが自由に入力出来る箇所に 『XSS Locator (Polygot)』の値を入れるべき』の参考動画
『ユーザーが自由に入力出来る箇所にシステムが指定した文字を入れるよう指示とかあればシステムが指示した文字+ 『XSS Locator (Polygot)』を入れるべき』の参考動画
XSSの侵入テストを自分で作成する時気をつけるべきと思ったことまとめ編
-
検査はWAFなど入れない状態で行う。
※WAFがあるとWAFで弾かれて攻撃検知出来なかった的な場合もありそうなので。 -
基本的に攻撃コードは 『XSS Locator (Polygot)』と
|.|
を使う。
※上記の表でわかる通りこれである程度は検知出来るので攻撃コードはこれが適切かなという感じです。※|.|
については少し後で再度説明しています。 -
まずはシステムの正常パターンを出す。 ex) 〇〇をした場合〇〇という挙動になる。
※逆にこの挙動にならない怪しいを探すため。正規表現系の脆弱性はこういう感じで探さないと難しいかと思い。
例
・フォームに〇〇と打つとこの場所に〇〇と表示される。
・フォームにredと打つとこの場所が赤くなる。
・フォームにsampleと打つとここにURL#sampleとなりクリックしたら適切な箇所が表示される。
-
ユーザーが自由に入力できる箇所を洗い出す。※参考: sample-b3
※ここに攻撃コードを入れて検査するため。 -
ユーザーが自由に入力できる箇所 + システムがお願いしていることあればそれも洗い出す。『"』で囲ってください的なもの。※参考: sample-a8
※ここに攻撃コードを入れて検査するため。 -
(自力で)脆弱診断するとき、クッリクやフォーカス当ててみるを行い正常の挙動と違わないかを確認する。 ※参考: sample-a7
※イベントハンドラやsrcにjsが仕込まれている時を想定
例
・何もしないでjs発火しない確認。
・フォーム当ててjs発火しない確認。
・クリックしてjs発火しない確認。
・正常時の挙動と想定した挙動になっているか確認。
※イベントハンドラ色々は以下のサイトが見やすかったので貼っておきます。
https://phpjavascriptroom.com/?t=js&p=event
以下のようにするとイベントハンドラの内容クリックやカーソル当てた時に『"』で囲ったものを実行するといった感じです。
<input イベントハンドラ="jsのファンクションや実際のjsコード" />
-
エラー時の時も発火しないか確認する。※参考: sample-c1
※ここはエラーが起きる時に攻撃コードを仕込んで確認するといった感じですね。
※基本的に『<<エラーが起こる文字列>><<Polygot>>』で入力して確認する感じになるかと思っています。 -
正規表現の可能性も考えて必ず違う挙動をするような文字を仕込んで意図した挙動にならない場合怪しいとする。
※絶対バグるような文字入れて検知してやるぞこのやろ〜という感じです!
例としては以下のようなものです。
|.|
これもある程度パターン持って確認出来たらイイかもです。又はの意味の『|』で囲っているので高確率でバグりそうかと思っています。
実際やってみた挙動を以下の表に表してみました。
検査したパターン | 実際に打った又は入力したもの | 正常ならどういう挙動になってた | バグってどんな挙動になった |
---|---|---|---|
sample-b5 | https://sachiko-kame.github.io#|.| | クリックできるURLが https://sachiko-kame.github.ioとなる |
クリックできるURLが http://192.168.99.100:86/sample-b5/?name=https%3A%2F%2Fsachiko-kame.github.io%23%7C.%7C 先頭のURLがそもそも違う、、 |
sample-b6 | https://sachiko-kame.github.io#|.| | クリックできるURLが https://sachiko-kame.github.ioとなる |
クリックできるURLが http://192.168.99.100:86/sample-b6/ 先頭のURLがそもそも違う、、 |
sample-b7 | http://192.168.99.100:86/sample-b7/?|.|=|.| | 画像のURLが https://sachiko-kame.github.io/images/sachiko.pngとなる |
|.||.||.||.|がある程度表示されていた |
sample-b8 | http://192.168.99.100:86/sample-b8/?|.|=|.| | 画像のURLが https://sachiko-kame.github.io/images/sachiko.pngとなる |
|.||.||.||.|がある程度表示されていた |
- 意図したタグが入っていないかの確認(◍•ᴗ•。◍) ここまでしないと完全に見つけられなさそうです、、 ※sample-c1
確認動画。※ここに入っているタグを直に打つとスクリプト発火する感じです、、
- おまけとして長文入力している箇所で許可しているタグあったらそこにイベントハンドラ入力して全て発火しないかの確認も出来たらより良いのかも?とか考えています。ここはおまけとして書きました。
実際テスト作るならこんな感じかな?を作成してみた!(おまけ)
こちらおまけで今後改善の余地はあるかと思っていますがこんな感じに作成すればイイかなを作成してみたになります!
※異常の場合は異常起こす文字の後にポリゴットの文字を入力する感じです。
行うこと | +a行うこと | 想定結果 |
---|---|---|
〇〇の箇所にXXXを入力する(正常) | 何もしない | アラート等表示されないこと、〇〇の箇所のURLがXXであること。 |
〇〇の箇所にXXXを入力する(正常) | 表示された文字クリック | アラート等表示されないこと、〇〇の箇所のURLがXXであること。 |
〇〇の箇所にXXXを入力する(正常) | 表示された箇所カーソルあてる | アラート等表示されないこと、〇〇の箇所のURLがXXであること。 |
〇〇の箇所にXXXを入力する(異常) | 何もしない | アラート等表示されないこと、〇〇の箇所のURLがXXであること。 |
〇〇の箇所にXXXを入力する(異常) | 表示された文字クリック | アラート等表示されないこと、〇〇の箇所のURLがXXであること。 |
〇〇の箇所にXXXを入力する(異常) | 表示された箇所カーソルあてる | アラート等表示されないこと、〇〇の箇所のURLがXXであること。 |
〇〇の箇所に"XXX"を入力する(正常) | 何もしない | アラート等表示されないこと、〇〇の箇所のURLがXXであること。 |
〇〇の箇所に"XXX"を入力する(正常) | 表示された文字クリック | アラート等表示されないこと、〇〇の箇所のURLがXXであること。 |
〇〇の箇所に"XXX"を入力する(正常) | 表示された箇所カーソルあてる | アラート等表示されないこと、〇〇の箇所のURLがXXであること。 |
〇〇の箇所に"XXX"を入力する(異常) | 何もしない | アラート等表示されないこと、〇〇の箇所のURLがXXであること。 |
〇〇の箇所に"XXX"を入力する(異常) | 表示された文字クリック | アラート等表示されないこと、〇〇の箇所のURLがXXであること。 |
〇〇の箇所"XXX"を入力する(異常) | 表示された箇所カーソルあてる | アラート等表示されないこと、〇〇の箇所のURLがXXであること。 |
このほかに意図したタグ入れられていないかの確認も大事かと。
最後に
実際これらのパターン出すと膨大な量になるかとは思いますが、
どうしても外部のライブラリ使って表示等する場合はある程度しておいたほうがより安全かなとは思います!
あと『OWASPZAP』が『XSS Locator (Polygot)』より検知出来ていないことにびっくりしました!(◍•ᴗ•◍)と言ってもOWASPは自動にやってくれたり他のもの検知してくれたりと良い点はあると思ってはいます。
逆にただの文字列でここまで検知出来るのはなんか嬉しかったです。
あとエラー出たらとか最初考えていたのですが、あまりここは検知に有効ではなかったかもと今回のことで確認出来たお気持ちです!
あとほかにowaspzap以外のツールで確認した場合の結果等もあったら知りたいです。特に自分では手が届かない何十万のツールとか
あと、結局見つけ出す箇所はエスケープされていない箇所、スキームチェックされていない箇所正規表現ユーザー入力で使っている箇所とかなのを心に留めておくとなんか良いような気もしています。
あとここら辺も想定しておいた方がいいよ等あったらご教授よろしくお願いいたします!
あと、
最後まで読んで頂きありがとうございました!!
お試しコード場所は以下