本サイトは、快適にご利用いただくためにクッキー(Cookie)を使用しております。
Cookieの使用に同意いただける場合は「同意する」ボタンを押してください。
なお本サイトのCookie使用については、「個人情報保護方針」をご覧ください。

最新情報

2017.06.27

Webセキュリティエンジニアのためのレコメンドエンジン -初級編-

 「レコメンド」と聞くと、オンラインショップで自分の嗜好に合った商品を推薦する仕組みを思い浮かべる方が多いと思います。このレコメンドという手法は様々なシステムに組み込まれており、例えば音楽配信サービスにおける楽曲の推薦、不動産紹介サービスにおける不動産情報の推薦等、広く実用されています。


 今回は、レコメンドの手法をセキュリティ分野に拡張し、Webアプリケーションの脆弱性を精査するための検査文字列を人間にレコメンドする検証システム「PyRecommender」を開発しましたので、そのロジック説明とデモをお見せします。


 なお、本システムでは、過去の膨大な脆弱性検査結果を基に、脆弱性の様々な発現パターンをベクトル化し、機械学習を用いて学習しています。そして、新たに脆弱性の可能性のある挙動を検知した場合、学習結果に基づいて最適な検査文字列をレコメンドする仕組みになっています。


システム概要


Figure1
Figure 1 システム概要

 Figure 1はPyRecommenderの概要図です。システムは大きく二つのサブシステムから構成されます。一つは、Webアプリの挙動を観察して脆弱性の発現パターンの特徴ベクトルを生成するInvestigator。もう一つは、Investigatorが生成した特徴ベクトルを基に、脆弱性の検査文字列をレコメンドするRecommenderです。Recommenderは内部にレコメンドエンジンを持っていますが、このエンジンの実現に学習済みの機械学習モデルを使用しています。この二つのサブシステムが連携して動作することで、Webアプリの脆弱性を精査するための検査文字列を人間にレコメンドすることができるようになります。


 ここで、Webアプリの脆弱性と一口で言っても多種多様ですが、今回は反射型のXSS(Reflected Cross site scripting:以下、XSS)を例にして説明していきます。


Note: 検証システムのソースコード及び学習データは「検証用コード」に掲載しています。ご興味のある方は、ご自身の管理下にあるシステムに対し、ご自身の責任の下でご自由にお使いください。


Investigator

 Investigatorは検査対象のWebアプリをクローリングし、レスポンスに値が反射されるパラメータを列挙します。そして、各パラメータ値の出力箇所及び使用可能な記号・スクリプト文字列を調査し、これをベクトル化します。


 例えば、対象のWebアプリがFigure 2の挙動を示した場合、InvestigatorはFigure 3のように調査結果を纏め、その特徴をベクトル化します。


[request]
GET /?x=test"'`<>alert();prompt();confirm();alert``;<script>Msgbox(); HTTP/1.1
-------------------------------------------------------------------------------------
[response]
<div class=test`<>alert();prompt();confirm();alert``;Msgbox();  >123</div>
Figure 2 調査の様子(“や<script>等が使用できないことが分かる)

  Investigation result Vector
Output places
HTML tag : div
attribute: class
quotation: None
10
5
0
Available symbols and script strings
“        : Fail
‘        : Fail
`        : Pass
<        : Pass
>        : Pass
alert(); : Pass
prompt();: Pass
confirm(): Pass
alert``; : Pass
<script> : Fail
Msgbox();: Pass
1
1
0
0
0
0
0
0
0
1
0
Figure 3 調査結果

 ここで、調査結果をベクトル化する際は、以下のような事前に定義した変換テーブルを使用しています。


Figure4
Figure 4 変換テーブルの一例

Note: 今回は検証を単純化するために、クローリング対象は「<a href=’xxx’>」でアクセス可能なページとし、対象のパラメータはクエリパラメータのみとしています。

 以上の仕組みでベクトル化したWebアプリの挙動の特徴をRecommenderに連携します。


 このように、Investigatorの役割は、パラメータ値の出力個所及び使用可能な記号・スクリプト文字列を調査し、特徴ベクトルに変換するのみとなります。今回は検証用にInvestigatorを作成しましたが、お手元の脆弱性スキャナまたはクローラーに同様に機能が備わっている場合は、これを代用しても問題はありません。



Recommender

 RecommenderはInvestigatorが生成した特徴ベクトルを入力に取り、精査に最適な検査文字列を出力(レコメンド)します。


 なお、レコメンドエンジンの実現には、機械学習アルゴリズムの一つである多層パーセプトロン(以下、MLP)を使用しています(Figure 5)。


Figure5
Figure 5 MLPの利用イメージ

 MLPは水色のノードから特徴ベクトルを受け取り、赤いノードから特徴ベクトルに対応する検査文字列を確率順に出力します。Figure 6はとあるレコメンドの例を示しています。


[inputted feature vector]
3,2,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0
---------------------------------------------------------
[recommended result]
0.99562198 : "></iframe><script>alert();</script>
0.00195420 : "><script>alert();</script>
0.00151912 : 'javascript:alert();
Figure 6 レコメンド例

 この例では、Recommenderは確度99.5%で「"></iframe><script>alert();</script>」をレコメンドしていることを意味しています。


 ちなみに、MLPは教師あり学習モデルのため、事前に学習させる必要があります。すなわち、学習データとして様々な脆弱性の発現パターンを用意する必要があります。今回は、WAVSEPのXSSケースを手動で精査して収集した、約1,300パターンのデータをMLPの学習に使用しています。


Note: 学習データは(Figure 3と同じく)値の出力箇所及び使用可能な記号・スクリプト文字列と、その際に発火した検査文字列(答え)のセットで構成されます。また、ベクトル化にはFigure 4と同じテーブルを使用しています。
今回使用した学習データはこちらから参照可能です。


デモンストレーション

 今回はWebseclabを対象にしてPyRecommenderのデモを行ってみます。

 デモの様子は以下の通りです。



Movie 1 デモ動画(PyRecommender vs Webseclab)

 WebseclabのトップURLからクローリングし(00:12 – 00:16)、下記URL及びパラメータでXSSの可能性を検知しています(00:17-00:19)。そして、各検知箇所に対する検査文字列をレコメンドしています(00:20-00:24)。Figure 7はXSSの可能性を検知した箇所と、それらに対してレコメンドされた検査文字列の一覧を表しています。


No URL(Path) Param レコメンドされた検査文字列
1 /xss/reflect/textare
a1
in
0.9993: </textarea><img src=x onerror=alert();>
0.0004: <script>alert();</script>
0.0001: </textarea><img src=x onerror=prompt();>
2 /xss/reflect/onmouse
over_div_unquoted
in
0.9832:  onmousemove=alert();
0.0101: " onmousemove=alert();",
0.0030: "><script>alert();</script>
3 /xss/reflect/onmouse
over_unquoted
In
0.8097: "><frame src="javascript:alert()">
0.1887:  onmousemove=alert();
0.0005: <img src=x onerror=alert();>
Figure 7 レコメンド結果(一例)

 基本的にレコメンドされた検査文字列の内、最も確率の高い文字列を使用することで、XSSを発火させることができます。しかし、No3のように学習データに含まれないパターンの場合では、1番手の検査文字列はHTML構文の規則に合致しないため発火せず、2番手の検査文字列で発火しています。レコメンドの確度は低くなるものの、学習していないパターンでも上手く発火する検査文字列をレコメンドすることもあります。


 以下、レコメンドされた検査文字列を用いて精査した様子を幾つか見ていきましょう。なお、結果を見やすくするために、敢えてURLエンコードはしていません。


No1:http://xxx/xss/reflect/textarea1?in=foo1

[request (default)]
GET /xss/reflect/textarea1?in=foo1 HTTP/1.1
-------------------------------------------------------------------------------------
[response]
<textarea name="in" rows="5" cols="60">foo1</textarea>
Figure 8 正常時のレスポンス(抜粋)

[request (use recommended inspection string)]
GET /xss/reflect/textarea1?in=foo1</textarea><img src=x onerror=alert();> HTTP/1.1
-------------------------------------------------------------------------------------
[response]
<textarea name="in" rows="5" cols="60">foo1</textarea><img src=x onerror=alert();></text
area>
Figure 9 レコメンド文字列で精査した結果(発火)

No3:http://xxx/xss/reflect/onmouseover_unquoted?in=changeme5

[request]
GET /xss/reflect/onmouseover_unquoted?in=changeme5 HTTP/1.1
-----------------------------------------------------------------------
[response]
Homepage: <input value=changeme5 name="in" size="40"><BR>
Figure 10 正常時のレスポンス(抜粋)

[request (use recommended inspection string)]
GET /xss/reflect/onmouseover_unquoted?in=changeme5 onmousemove=alert();  HTTP/1.1
-------------------------------------------------------------------------
[response]
Homepage: <input value=changeme5 onmousemove=alert();  name="in" size="40"><BR>
Figure 11 レコメンド文字列で精査した結果(発火)

 以上のように、レコメンドされた何れかの検査文字列を用いて、正しくスクリプトを動作させることができました。


 このように、Webアプリの挙動を特徴ベクトル化するInvestigatorと、事前に様々な脆弱性の発現パターンを学習したRecommenderが連携することで、正しく脆弱性の精査が行えることが分かりました。


 なお、学習していない脆弱性の発現パターンの場合は、パターンによっては確率的に尤も近しい(正しい)検査文字列をレコメンドすることもありますが、全く発火しない(役に立たない)検査文字列をレコメンドすることもあります。このような場合は、人間が手動で精査して学習データを追加し、Recommenderを再学習させることで、次回以降はより高い精度でレコメンドすることが可能となります。つまり、Recommenderは使い込むことで徐々に賢くなっていきます。



Movie 2 学習の様子


まとめ

 今回の検証を纏めます。


  1. 機械学習を活用することで、脆弱性の検査文字列をレコメンド可能
  2. 学習していないパターンでも、正しい検査文字列をレコメンドする「場合」もある
  3. 様々な脆弱性の発現パターンを学習させることで、レコメンド精度を向上可能

 なお、今回使用した学習データは、WAVSEPに含まれる単純なケースであり、また手動で作成したためデータ数には限界がありました。これを克服するためには、バグバウンティや脆弱性検査業務で大量に生み出されるリアルな検査結果を自動的にベクトル化し、学習データとして活用する仕組みが必要になると考えています。


 最後に、本記事は「初級編」としていますが、次回は中級編と銘打ち、レコメンドのロバスト性能を上げる仕組みについて寄稿する予定です。具体的には、MLPの代わりにConvolutional Neural Networkを使用し、少ない学習データでもレコメンド精度を維持・向上させることができるのか検証します。



検証用コード

https://github.com/13o-bbr-bbq/machine_learning_security/tree/master/Recommender


以上



<本ページに関するサービスの詳細>
https://www.mbsd.jp/solutions/assessment/


高江洲 勲 の他のブログ記事を読む

プロフェッショナルサービス事業部
高江洲 勲

おすすめ記事