> > Black Hat ASIA Arsenal 2019の登壇

Black Hat ASIA Arsenal 2019の登壇

2019.04.10
プロフェッショナルサービス事業部
桝屋 雅文
米山 俊嗣
高江洲 勲
title1

 2019年3月28日(木)から3月29日(金)にかけてシンガポールのMarina Bay Sandsで開催されたBlack Hat 2019 Arsenalに、セキュリティテストツール「GyoiThon」のプレゼンターとして参加してきました。

 本Blogでは、筆者らが出展したツール「GyoiThon」の概要と、今後同イベントへの参加を検討されている読者の参考になるよう、出展時の様子や工夫した点等を紹介します。

Black Hat ASIA 2019のエントランス


1. はじめに

 Black Hat Arsenalとは、Briefingsと並行して開催される「先進的なセキュリティに関するツールの展示会」であり、厳しい事前審査をクリアしたツールのみが出展可能です。聞くところによると、採択率は数%~十数%の狭き門のようです。今回も世界各国から約30のツールが出展されていました。

 ちなみに、弊社のArsenal出展は、Black Hat ASIA 2016,2018、Black Hat USA 2018、Black Hat EURO 2018に続き5回目となります。もはや常連といっても過言ではない参加数です(笑)
※各回の参加ブログはこちらからご参照ください。

Arsenalのスケジュールボード


2. GyoiThonの概要

 今回筆者らは、2018年のBlack Hat ASIA Arsenalに出展したGyoiThonのアップグレード版を出展しました。


- 旧型GyoiThonの概要

 GyoiThonをご存じでない方も多いかと思いますので、従来のGyoiThonの概要を説明します。

 GyoiThonとは、Webサーバに特化したペネトレーションテストツールであり、現在は情報収集(OSINT)に重きを置いています。GyoiThonの最大の特徴は、ターゲットWebサーバの稼働に殆ど影響を与えずに、(正常アクセスの範囲内で)サーバ上で稼働している製品(OS, Framework, CMS等)を特定できる点にあります。そして、特定した製品のCVE番号を列挙することが可能です(オプション次第では、Metasploitを介したExploitの実行や、コンテンツ探索等も可能です)。

 このようにGyoiThonを使用することで、手軽にWebサーバの脆弱性有無も確認することが可能となります。


- アップグレード機能:シグネチャの自動生成

 上述したように、Webサーバの脆弱性有無を確認するためには、稼働している製品を特定することが必須となります。GyoiThonでは製品を特定するためにシグネチャを使用しています。しかし、従来のGyoiThonは、シグネチャをエンジニアが時間をかけて手動で作成しなければならないという課題がありました。これにより、対応可能な製品を増やしたい場合は、エンジニアが対象製品の特徴を分析し、一つひとつシグネチャを作成するという、気の遠くなるような作業を行う必要がありました。

 そこで新型GyoiThonでは、シグネチャの自動生成機能を実装しました。これは、「GyoiThonが特定する製品の多くはOSSであり、ソースコード(パッケージ)が公開されている」ことに着目し、パッケージ展開後にWebサイト上で公開される可能性の高いPathやファイルPath独自の手法で特定してシグネチャ化します。

 これにより、GyoiThonに特定させたい製品のパッケージファイルをインポートするだけで、自動的にシグネチャを生成することが可能となりました。筆者らの知る限り、このように全自動でシグネチャを生成するツールは他に聞いたことがありません。

 以下、もう少し具体的に、シグネチャ自動生成機能の概要を説明していきます。


2.1. シグネチャの自動生成

 突然ですが質問です。
 以下は「とあるCMS」で構築したWebサイトのHTTPレスポンスを示しています。
 このレスポンスを見て、あなたはCMSの種類を特定できるでしょうか?

<link rel="shortcut icon" href="/core/misc/favicon.ico" type="image/vnd.microsoft.icon" />
<link rel="canonical" href="/node/1" />
<link rel="shortlink" href="/node/1" />
<link rel="revision" href="/node/1" />
…snip…
<title>Gyoithon page | Gyoithon page</title>
<link rel="stylesheet" href="/sites/default/files/css/css_tkeOEWfM6OFUIhuI7-a5HCSwE3rIQepiuKNt5Zr
7WWg.css?pom0j6" media="all" />
<link rel="stylesheet" href="/sites/default/files/css/css_jOw317331T1b8jqEXN7KFhd_2yK9S_1cOWw6eHq
kdv0.css?pom0j6" media="all" />

とあるCMSで構築したWebサイトのHTTPレスポンス


 おそらく、特定できなかったと思います。
 実は、このサイトは「Drupal 8.6.3」で構築されています。新型GyoiThonであれば、正しくDrupalであることを特定することができます。

 通常、Drupalで構築されたWebサイトには、以下のような定番のヘッダやタグがHTTPレスポンスに含まれていることがあります。これらのヘッダ・タグには「Drupal, drupal」等の製品名を示す文字列が含まれているため(赤字部分)、普通の人間や従来の脆弱性スキャナーであっても容易にDrupalを特定することができます。

X-Drupal-Dynamic-Cache: MISS
X-Generator: Drupal 8 (http://drupal.org)
<meta name="Generator" content="Drupal 8 (https://www.drupal.org)" />
<script src="/core/misc/drupalSettingsLoader.js?v=8.3.1"></script>
<script src="/core/misc/drupal.init.js?v=8.3.1"></script>

定番のDrupalの特徴(一例)


 一方、先ほどのHTTPレスポンスには、上記のような定番の特徴は含まれていません。では、GyoiThonはこのレスポンスの何を見てDrupalと判断しているのでしょうか。

 以下に赤字で示した文字列が、新型GyoiThonが判断の根拠にしたDrupalの特徴です。

<link rel="shortcut icon" href="/core/misc/favicon.ico" type="image/vnd.microsoft.icon" />
<link rel="canonical" href="/node/1" />
<link rel="shortlink" href="/node/1" />
<link rel="revision" href="/node/1" />
…snip…
<title>Gyoithon page | Gyoithon page</title>
<link rel="stylesheet" href="/sites/default/files/css/css_tkeOEWfM6OFUIhuI7-a5HCSwE3rIQepiuKNt5Zr
7WWg.css?pom0j6" media="all" />
<link rel="stylesheet" href="/sites/default/files/css/css_jOw317331T1b8jqEXN7KFhd_2yK9S_1cOWw6eHq
kdv0.css?pom0j6" media="all" />

GyoiThonが判断の根拠にしたDrupalの特徴(赤字)


 一見すると、どのレスポンスにも含まれていそうな特徴のない文字列に見えます。しかし、筆者らが独自開発した手法を使うと、上記の赤字文字列は「Drupalの特徴」であると判断することができます(詳細は後述します)。

 もう一つ例を示します。以下は、Joomla!で構築したWebサイトのHTTPレスポンスを示しています。Drupalの例と同じように、レスポンスにはJoomla!を示す文字列は存在しません。しかし、GyoiThonは赤字部分の特徴を基に、「Joomla!」であることを特定することができます。

<title>Gyoithon page</title>
<link href="/templates/protostar/favicon.ico" rel="shortcut icon" type="image/vnd.microsoft.icon" />
<link href="/templates/protostar/css/style.css?f673d87b56120dcab0477660bf1c2384" rel="stylesheet" />
…snip…
<script src="/media/jui/js/jquery.min.js?f673d87b56120dcab0477660bf1c2384"></script>
<script src="/media/system/js/caption.js?f673d87b56120dcab0477660bf1c2384"></script>
<script src="/media/jui/js/bootstrap.min.js?f673d87b56120dcab0477660bf1c2384"></script>
<script src="/templates/protostar/js/template.js?f673d87b56120dcab0477660bf1c2384"></script>

Joomla! で構築したWebサイト


 このように、GyoiThonはHTTPレスポンス上に表れる各製品の公開ディレクトリPathに現れる特徴を基に製品を特定していきます。新型GyoiThonでは、このような各製品の公開ディレクトリPathを見つけるためのシグネチャを全自動で生成することができます。

 以下、シグネチャの生成フローを解説していきます。


2.2. 処理フロー

 本ブログでは、「Joomla! 3.9.4」のシグネチャ生成を例にして、シグネチャ自動生成手順を解説していきます。

 GyoiThonは、以下の3ステップでシグネチャを自動生成します。

シグネチャの自動生成処理フロー


Step1. 製品パッケージの取得と解凍

パッケージの取得から解凍までの流れ


- 1. パッケージのダウンロード

 シグネチャ化したい製品のパッケージ(通常は圧縮されている)を公式Webサイト等からダウンロードします。

- 2. ファイル名の変更

 圧縮ファイルの名前を「Joomla@3.9.4@-Stable-Full_Package.zip」のように、「@」区切りで「製品名」「バージョン」「その他」の3項目に分ける形にリネームします。
 ※製品名とバージョンは、最終的には以下のようにシグネチャファイル内に取り込まれます。

CMS@joomla@Joomla@3.9.4@(/media/index.html)
CMS@joomla@Joomla@3.9.4@(/media/jui/js/jquery.min.js)
CMS@joomla@Joomla@3.9.4@(/media/jui/js/template.js)

最終的に作成されるシグネチャファイルの一例

- 3. パッケージの展開

 リネームした圧縮ファイルを以下のようにGyoiThonにインポートします。
 ※ここまでの工程は、ユーザが手動で行います。

root@kali:~/GyoiThon# python3 gyoithon.py -d --category=CMS --vendor=joomla --package=Joomla@3.9.4@-Stable-Full_Package.zip

シグネチャ生成時のコマンド(オプション詳細はGitHubをご参照ください)


 すると、自動的に圧縮ファイルが展開され、製品に含まれるPathやファイルPathがディレクトリに展開されます。この後、GyoiThonによるシグネチャの自動生成処理が始まります。


Step2. 公開/非公開ディレクトリの判定

- ディレクトリ構造のグラフ化

 GyoiThonは、ディレクトリ内のPathの階層構造や各Path上に存在するファイル名・拡張子を調査します。そして、各Pathの親子関係を表した有向グラフを作成します。この処理にはPythonライブラリのNetworkXを利用しています。

 以下は、Joomla!3.9.4のディレクトリ構造をグラフ化した様子を示しています。

Joomla! のディレクトリ構造をグラフ化した様子


 各Pathにはユニークなインデックス(以下、ノード番号)が割り当てられ、Pathの親子関係は矢印(->)で表されます。また、各ノードは属性としてPath上に存在するファイル群を保持します。

 このグラフを解説用に分かり易く表したものが以下になります。

Node Index Directory Path Files (Attribute)
0 /Joomla-3.9.4/ web.config.txt, LISENCE.txt
1 /Joomla-3.9.4/administrator/ index.php
2 /Joomla-3.9.4/administrator/cache/ index.html
…snip… …snip… …snip…
1434 /Joomla-3.9.4/media/ index.html
1435 /Joomla-3.9.4/media/jui/ - (ファイル無し)
1436 /Joomla-3.9.4/media/jui/js/ template.js, jquery.min.js

Joomla! のディレクトリ構造


 ノード番号「0」は、全ディレクトリの親、つまりルートディレクトリを表します。そして、ノード番号「1」は、ルートディレクトリ直下のディレクトリを表します。この時、ノード「0」とノード「1」は親子関係となります(親:0、子:1)。
 この要領で、全ディレクトリの親子関係を定義していきます。なお、各ノード(ディレクトリ)にはファイルが配置されている場合がありますので、各ノードの属性としてファイル名を持たせるようにします。


- ディレクトリ構造のグラフ化

 各ノードの評価値(スコア)を計算します。
 スコアは、公開される可能性の高いPathほど高い値となるように計算されます。

 筆者らはこの計算を行うために、各ノードの属性に含まれるファイルの拡張子を使用することにしました。以下は、スコア計算に使用するスコアテーブルの一例です。

Extension Score
.txt 0.2
.combine 1.0
.c 0.0
.config 0.2
.css 1.0
…snip… …snip…
.html 0.8
.ico 1.0
.ini 0.2
.jpg 1.0
.js 1.0
.php 0.2

スコアテーブル


 本テーブルは、主要な拡張子とスコアを対応付けたものとなっています。スコアは「0.0~1.0」の値域を持っており、「0.0」に近いほど(パッケージ展開後に)非公開となる可能性が高い拡張子と見なされます(インストール時のみに使用されるファイルや、製品の内部処理に使用されるファイル等)。一方、「1.0」に近いほど公開される可能性が高い拡張子と見なされます(JavaScriptや画像、CSS等のリソースファイル等)。

 例えば、「.c」や「.config」は、通常は公開されないファイルと考えられるため、スコアは低く設定します。一方、「.css」や「.js」は、通常は公開を意図しているファイルであるため、スコアは高く設定します。

 このように、各ファイルの公開可能性に基づいて各拡張子のスコアを決定しています。
 ※筆者らの経験に基づいて各拡張子のスコアを定義していますが、GyoiThonの利用者が自由に再定義することも可能です。

 スコアテーブルを用いて各ノードのスコアを計算した結果は以下のとおりです。

Node Index Directory Path Score
0 /Joomla-3.9.4/ 0.2
1 /Joomla-3.9.4/administrator/ 0.2
2 /Joomla-3.9.4/administrator/cache/ 0.8
…snip… …snip… …snip…
1434 /Joomla-3.9.4/media/ 0.8
1435 /Joomla-3.9.4/media/jui/ 0.0
1436 /Joomla-3.9.4/media/jui/js/ 1.0

各ノードのスコアリング結果


 ノード「0」は、「web.config.txt」と「LISENCE.txt」のファイルを持っているため、スコアは0.2(.txt = 0.2)となります。一方、ノード「1436」は、「template.js」と「jquery.min.js」のファイルを持っているため、スコアは1.0(.js = 1.0)となります。なお、複数のスコアが異なるファイルを持っているノードは、各ファイルスコアの中央値をノードのスコアとします(外れ値の影響を抑えるため)。


- ディレクトリの公開/非公開判定

 各ノードのスコアに応じて、公開および非公開の判定を行います。
 筆者らは、ノードのスコアが閾値を超えていた場合は公開(Public)、閾値を下回っていた場合は非公開(Private)としています。すると、各ノードは以下のようになります。
 ※閾値は予め定義する必要があります。本例では「0.7」としていますが、GyoiThonの利用者が自由に変更することも可能です。

Node Index Directory Path Status
0 /Joomla-3.9.4/ Private
1 /Joomla-3.9.4/administrator/ Private
2 /Joomla-3.9.4/administrator/cache/ Public
…snip… …snip… …snip…
1434 /Joomla-3.9.4/media/ Public
1435 /Joomla-3.9.4/media/jui/ Private
1436 /Joomla-3.9.4/media/jui/js/ Public

各ノードの公開/非公開判定結果


 この結果、ノード「2」「1434」「1436」は公開ディレクトリ、それ以外は非公開ディレクトリと判定され、ノード「2」「1434」「1436」がシグネチャ候補となります。


- “オセロ”処理の実行

 ここで、ノード「1435」に注目してください。
 このノードはファイルを持っていないためにスコアが「0.0」になっており、その結果、非公開(Private)に判定されています。しかし、本ノードの親ノード「1434」と、子ノード「1436」は公開となっています。すなわち、ノード「1435」は、公開ノードの間に位置していることになります。

 筆者らは、「公開ノードの間に位置しているノードは公開される可能性が高い」と仮定し、このようなノードを(オセロのように)非公開から公開にひっくり返す処理を行っています。この結果、ノード「1435」は公開ディレクトリして判定され、シグネチャ候補となります。

Node Index Directory Path Status
0 /Joomla-3.9.4/ Private
1 /Joomla-3.9.4/administrator/ Private
2 /Joomla-3.9.4/administrator/cache/ Public
…snip… …snip… …snip…
1434 /Joomla-3.9.4/media/ Public
1435 /Joomla-3.9.4/media/jui/ Public
1436 /Joomla-3.9.4/media/jui/js/ Public

オセロ処理の実行結果


オセロ処理の実行イメージ


Step3. シグネチャ/学習データの生成

- 不要なPathの切り落とし

 Step2までの処理を行うことで、対象パッケージ内の公開ディレクトリPath(シグネチャ候補)が出揃います。ここで、下表の赤字部分に注目してください。

Node Index Directory Path
2 /Joomla-3.9.4/administrator/cache/
1434 /Joomla-3.9.4/media/
1435 /Joomla-3.9.4/media/jui/
1436 /Joomla-3.9.4/media/jui/js/

公開ディレクトリPathに非公開の部分Pathが含まれている様子


 公開ディレクトリPathに含まれる「/Joomla-3.9.4/administrator」や「/Joomla-3.9.4」といった部分Pathは、Step2において非公開ディレクトリと判定されたPathです。よって、これらの部分Pathは公開領域として設定されることはないことを意味します。

 そこで、これらの部分Pathを公開ディレクトリPathから切り落とします。
 すると、公開ディレクトリPathは以下のようになります。

Node Index Directory Path
2 /cache/
1434 /media/
1435 /media/jui/
1436 /media/jui/js/

非公開の部分Pathを切り落とした結果


- シグネチャの作成

 次に、各公開ディレクトリPathと同ディレクトリ上に配置されているファイルを組み合わせて、シグネチャを作成します。

Directory Path Files
/cache/ index.html
/media/ index.html
/media/jui/ -
/media/jui/js/ template.js, jquery.min.js

公開ディレクトリPathとファイル


 すると、以下のようなシグネチャが出揃います。

Sig No Signature
1 /cache/
2 /cache/index.html
3 /media/
4 /media/index.html
5 /media/jui/
6 /media/jui/js/
7 /media/jui/js/template.js
8 /media/jui/js/jquery.min.js

自動生成されたシグネチャ


 先に例示したJoomla! で構築したWebサイトのHTTPレスポンスを新たに作成したシグネチャで解析すると、以下のように2つの箇所で文字列が一致します。このように、生成したシグネチャを使うことで、Joomla! であることを特定することができます

<title>Gyoithon page</title>
<link href="/templates/protostar/favicon.ico" rel="shortcut icon" type="image/vnd.microsoft.icon" />
<link href="/templates/protostar/css/style.css?f673d87b56120dcab0477660bf1c2384" rel="stylesheet" />
…snip…
<script src="/media/jui/js/jquery.min.js?f673d87b56120dcab0477660bf1c2384"></script>
<script src="/media/system/js/caption.js?f673d87b56120dcab0477660bf1c2384"></script>
<script src="/media/jui/js/bootstrap.min.js?f673d87b56120dcab0477660bf1c2384"></script>
<script src="/templates/protostar/js/template.js?f673d87b56120dcab0477660bf1c2384"></script>

Joomla! で構築したWebサイト


- シグネチャの重複排除

 ところで、上記の例で示したシグネチャの内、「/cache/」や「/media/」等はよくあるディレクトリ名になっているため、他製品のパッケージを基に作成したシグネチャにも含まれる可能性があります。仮に同じシグネチャが複数製品(Joomla! とDrupal等)に跨っていた場合、1つのHTTPレスポンスにてJoomla! とDrupalのように複数製品を誤って検知してしまいます。

 そこで、複数製品でシグネチャが重複していた場合は、「同シグネチャは製品固有の特徴ではない」と判断し、シグネチャから削除するようにしています。様々な製品/バージョンをGyoiThonにインポートしていくことで、製品の特徴付けに寄与しないシグネチャは削除されていき、最終的には各製品を強く特徴付けるシグネチャのみが残るようにしています。

以上が、Black Hat ASIA 2019 Arsenal向けにアップグレードしたGyoiThonの新機能概要となります。


3. 事前準備

 Arsenalは、「如何に訪問者を退屈させずに場を盛り上げるか」が重視されます。退屈なプレゼンをしていると、出展ブースに人が集まらず寂しい思いをします(今回もそのようなブースがありました)。そこで筆者らは、効果的にツールの魅力をアピールするために、以下のアイテムを用意しました。

GyoiThonシャツ(非売品)


 筆者らは上記のシャツを着用しながら「プレゼン→デモ動画→QAタイム」の流れをコアタイム内でひたすら行いました。また、メインプレゼンター以外のメンバーは、人垣から外れた訪問者に対して配布資料を手渡し、必要に応じて個別にプレゼンを行いました。

 さらに、多くの訪問者に関心を持って貰うため、事前にGitHubにてソースコードを公開し、また、以下のようにTwitterを活用した宣伝も行いました。

GyoiThon公式アカウントによる宣伝


出展メンバーによる宣伝


Arsenalで繋がった友人による宣伝(一部加工)


4. 出展の様子

 事前準備の効果もあり、発表開始時間となるやいなや、筆者らのブースは非常に多くの訪問者で溢れかえり、その勢いは発表時間終了まで絶え間なく続くものでした!

発表の様子1


発表の様子2


発表の様子3


 今回のデモでは、見た目が同じだが3つの異なるCMSで構築されたWebサーバを用意し、「このWebサーバでは何のCMSが利用されているか分かりますか?」等と訪問者へ実際のデモ環境を見せながら質問し、会話を多くすることで、よりインタラクティブな発表となるようにしました。皆さん真剣に考えつつ、「これは分からない!」「難しい!」と答える方が圧倒的に多く、GyoiThonだと特定できることを実演すると「クールだな!」と感心いただけました。

 最終的には、約100分間で約350名の方に訪問いただき、大盛況と言える結果となりました。また、GitHubには、Arsenal終了直後に多くのStar(「いいね」のようなもの)が付きました。このことから、ツールの魅力が訪問者によく伝わり、多くの関心が得られたと思っています。


5. おわりに

 Arsenalはプレゼンターと訪問者の距離が非常に近いです。そのため、訪問者は単にツールのデモを観たり説明を聞いたりするだけではなく、気軽にプレゼンターと会話・議論することができます。

 今回はツール仕様の他、実際にツールを動かすための具体的な動作環境等に関する細やかな質問やアドバイスが寄せられました。また、多くの方から「クールなツールだ!興味があるから使ってみるよ!」との感想を頂いた他、訪問者とガッチリと握手や肩を組んで一体感が生まれる場面も多々ありました。

 また、他のArsenalプレゼンターや運営メンバーとの交流もあり、非常に有意義なものとなりました。

Arsenalプレゼンターの集合写真(運営者のtwitterから引用)


 筆者らプレゼンター側としては、自分たちが有益だと思い立ち開発したツールに対して、世界各国の技術者・研究者らからダイレクトな反応を得られる点がツール出展の最大の魅力だと考えています。今回も多くの訪問者から様々な質問・意見・アイデアを貰いました。

 今回出展したGyoiThonはまだまだ改良の余地を残しています。今後もアップグレードを繰り返していきながら、今後開催される他のカンファレンスにも積極的に出展していきたいと考えています。

以上