AlienVault Open Threat Exchange is 何?
AlienVaultのOpen Threat eXchange(OTX)は、コミュニティーでIoC(Indicator of Compromise)その他の脅威情報を交換するためのオープンなコミュニティベースのプラットフォームで、アカウント登録をすれば誰でも無料で使用することができる。
AlienVaultは、OTXのプラットフォーム以前から無償で使用できるSIEM的な位置づけのOSSIM、またその商用版のUSM、またオープンソースのホスト型IDS兼ログIDSともいえるOSSECのサポートなど手広いソリューションを提供している。
これを知ったのはOSSECからで、なんだか怖い名前の企業がOSSECの商用サポートしているようだぞというところ、SIEMみたいなものも持っているみたいだぞ、というところで、もちろん使ってみたがかなりスペックを要求されることや、どうもちゃんと動かすには細かい設定のチューニングやメンテナンスが必要のようだ、ということで敬遠していた。
OSSIM、USMを提供しているベンダー、くらいにしか思っていなかったが、脅威情報を交換するプラットフォームOpen Threat Exchangeを提供しはじめた。これが登録ユーザーも増え、活用している人も多いようなので具体的な活用方法を模索していきたいと思う。
AlienVaultについてはWikipediaがわかりやすいかもしれない。 https://en.wikipedia.org/wiki/AlienVault
OTXについてはユーザーガイドがありOTXについて、その中で使われる概念のPulse、アカウントの作成、その他使い方が一通り載っている。英語のドキュメントしか見当たらないので、そのうち日本語訳してうざブログに書いていきたいと思う。
OTXユーザーガイド: https://www.alienvault.com/doc-repo/OTX/user-guides/AlienVault-OTX-User-Guide.pdf
OTXの使い方とか概要
アカウントの作成
上記の通りアカウントの作成方法もあるが特殊な事はないので下記にアクセスしてアカウント作ればいいと思うよ。 https://otx.alienvault.com/
なおアカウントはOTX独自アカウント以外にFacebook、Twitter等のアカウントで利用することもできるのでお好みで。
Pulse
OTXでは、脅威情報(IoC)の登録および取得は「Pulse」というものを通して行う。
脅威情報を提供する側の人は「Pulse」を作成してそこに登録して、 脅威情報を収集したい側の人は「Pulse」から収集する。
なおPulseとはどういう意味かというと「パルス」ということだそうです。
Pulseの中には、IoCが含まれ、この部分が構造化されているので登録や取得が容易になる。 IoCとして登録できるデータの種類は以下のものがある。
- IPv4
- IPv6
- domain
- hostname
- URI
- URL
- filepath
- FileHash-MD5
- FileHash-SHA1
- FileHash-ShA256
- Imphash (import hash)
- PEhash
- CIDR
- mutex
- CVE
それぞれどのような意味なのかは名前でだいたいわかるが詳しく知りたい場合は公式ドキュメント参照。
またPulseへのIoCの登録は、例えばIoCが掲載されているWebページからIoC(IPアドレスなど)を一つずつコピペする必要はなく、例えばURLを入れて「Extract IOCs」とすれば
このように自動的に抽出してくれる。
この仕組み、地味に便利。1エントリずつコピペする必要がない。(正しく抽出できているかどうかのチェックは必要)
基本的にこういう仕組みを使うのにいちいち人手で100%行うのはバカバカしいと考えているので、たとえ精度が少し悪かろうとこういった機能は徹底的に活用、できれば全自動、どうしても必要な場合のみ人が目で見るというステップを入れれば良いと思うのである。
Follow
情報を追いかけたいとき、Followすることができる。TwitterのFollowとさして変わらないかと。 ただ、FollowはユーザーをFollowすることもできるし、Pulseをフォローすることもできる。グループもかな。
FollowのほかにSubscribeということをすることもできるが、使ったことがないのでよくわからない。マニュアルを読むときっとわかるでしょう。
やりたいこと
- 脅威情報をPulseに登録する
- Pulseから脅威情報を入手する
つまり脅威情報を取得するのにOTXのPulseを経由する、ということがしたいだけ。
データソースから脅威情報を直接入手するのと何が違うかというと、データソースが複数あるということや、構造化データではない時もあること、色々なケースが考えられることなどから、PulseへのIoC登録と当該Pulseからの情報の取得を切り分けておくことで、例えばSIEMやIDSなどにおける収集ロジックはいじることなくデータソースの追加や変更が行えてしまうというのがものすごいメリットとなる。
ひとつ難点をいえば「Open」Threat Exchangeなので情報がオープンになる。 お堅いとこだと「そんな得体のしれないサービスの利用は許さぬ!」なんてこともあるかもしれないけど、そんな場合は別の方法を考えるか、懲戒を覚悟でルールを無視するか、バレないようにやるか、自宅でやるのが良いでしょう。
活用例
ここから具体例。
シナリオ
- Malware Corpus Tracker (https://tracker.h3x.eu/about) のPulseを作成する。
- そして、そのPulseを活用すべくイイ感じでダウンロードする
グループやユーザーをFollowすれば複数のPulseを追いかけることはできるのだと思うが今回は1つのPulseを利用する方法でいってみる。
Malware Corpus Tracker(説明は割愛)
1. Pulseをつくる
上記Malware Corpus Trackerでは、自動化むけに1か月、1週間、1日、1時間分のデータをそれぞれ用意してくれている。これをありがたく使わせてもらう。
1day.phpのURLを使う
まず上部メニューから「Create Pulse」をクリック。Pulse作成画面になる。
手でIoCをひとつずつ入力しても良いが、上述の通り指定されたURLからIoCぽいものを取得してくれるので、データソースのURL(今回はMalware Corpus Tracker)を入れて「EXTRACT INDICATORS」をクリックする。
抽出されたIoCが表示されるが、Included IOCsにあるデータのみPulseに登録される。Suggested IOCsのほうに抽出されたデータはおそらく自信がないのでしょう。
Suggested IOCsを選択し、IOCとして登録したいレコードにチェックを入れてAPPLYをクリックする。すべて登録したい場合はタイトル行のところにあるチェックボックスをクリックすれば良い。
そして最下部の「NEXT」をクリック。
次にこのPulseの名前や情報公開範囲を設定する。なお「TLP」については「?」をクリックすると説明のあるUS CERTかどこだかのページが開かれる。JPCERTの早期警戒情報等を見ている人は「アンバー」とかいうとピンとくるでしょう。
Description等は任意なので今回は入れていない。AmberでPRIVATEに。(Amberを選択すると自動でPRIVATEになった)
できたらNEXT。
これで作成完了。Related Pulsesは、同じIOCをもつPulseが参照できるのかな。素晴らしい。
ここで、作成したPulseのURL https://otx.alienvault.com/pulse/XXXXXXXXXXXXXXXXXXXXXXXXXX/のXXXXの部分がこのPulseのIDになるので、控えておきましょう。(あとでも見れるが)
そして、このPulseのページ右上の「Download」からCSVやOpenIOC、STIX等の形式でダウンロードできるが、PulseをPrivateにした場合はログイン状態でないとダウンロードできない(Pulse not foundとなった)ため、APIからのアクセスが必要。APIを使って取得するには以下のようにする。
2. APIでPulseを取得する
メニューから「API」を選ぶと色々な方法が準備されていて、それぞれリンクがあるが、いずれもGithubリポジトリに飛ぶ。今回使用するのはPythonのDirect Connect SDK。
インストール方法や簡単な使い方等は下記リンクをたどれば書いてある。
2-1. OTXv2をpipでインストール
※ここでの環境はAnacondaでインストールしたPython3および周辺ツール・モジュール。
$ pip install OTXv2
Collecting OTXv2
Downloading OTXv2-1.2.tar.gz
Collecting simplejson (from OTXv2)
Downloading simplejson-3.12.0-py3-none-any.whl (51kB)
100% |████████████████████████████████| 61kB 606kB/s
Building wheels for collected packages: OTXv2
Running setup.py bdist_wheel for OTXv2 ... done
Stored in directory: /home/username/.cache/pip/wheels/e5/1d/3f/ceeb09cc8a9773fde86a38d56157e7e3f68fbfb982c7bfc0d4
Successfully built OTXv2
Installing collected packages: simplejson, OTXv2
Successfully installed OTXv2-1.2 simplejson-3.12.0
2-2. OTXv2モジュールを使用してPulse内のIoCを取得
APIキーとPulseのIDが必要なのでメモしておく。
APIキーは、OTXのメニュー「API」から、DirectConnect APIの右上にあるので、これをコピーする。
Pulse IDは、作成したPulseを開き(右上ユーザー名→PROFILEから自分の作成したPulseへ)、URLのhttps://otx.alienvault.com/pulse/XXXXXXXXXX のXXXXXXXXXの箇所にある文字列を取得。
ではPythonで実行してみます。そう、ipythonでね。
普通にPythonスクリプトを書いてももちろん実行できるのでそこは適宜。 In [n]とかOut [n]というところはipythonのプロンプトなのでコードではありませんのでご注意を。
$ ipython3
Python 3.6.1 |Anaconda 4.4.0 (64-bit)| (default, May 11 2017, 13:09:58)
Type "copyright", "credits" or "license" for more information.
IPython 5.3.0 -- An enhanced Interactive Python.
? -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help -> Python's own help system.
object? -> Details about 'object', use 'object??' for extra details.
In [1]: from OTXv2 import OTXv2, IndicatorTypes
In [2]: otx = OTXv2("================= ここにAPIキーを入れる =================")
In [3]: iocs = otx.get_pulse_indicators("==== Pulse ID を入れる ====")
これでiocsが1レコード1ディクショナリのリストになっているので、ループなりして個々のデータを取得できる。 なおレコードあたりのディクショナリのキーは以下の通り。
In [6]: iocs[0].keys()
Out[6]: dict_keys(['indicator', 'description', 'created', 'title', 'slug', 'content', 'pulse_key', 'type', 'id'])
今回作成したPulseのIOCのType名をとってみる。
In [13]: set([ioc["type"] for ioc in iocs])
Out[13]: {'IPv4', 'URL', 'domain', 'hostname'}
このPulseではIPv4、URL、domain、hostnameの4種類があるようだ。
このデータを取り扱う機器やデータセットが必ずしも複数のデータを一括で処理できるとは限らないので、おそらく実際にはIoCタイプごとに取得したい、というようなことになることも多いはず。こんなときは下記のようにすればよい。
ちなみにシンプルに書くためにはリスト内包表記が便利。ループを書かなくて良い。
IoC TypeがIPv4のIoCのみ取得
In [14]: [ioc["indicator"] for ioc in iocs if ioc["type"] == "IPv4"]
Out[14]: ['195.8.66.1']
IoC TypeがdomainのIoCのみ取得
In [15]: [ioc["indicator"] for ioc in iocs if ioc["type"] == "domain"]
Out[15]:
['alucmuhendislik.com',
'atlantarecyclingcenters.com',
'hexacam.com',
'hgssyouth.com',
'miamirecyclecenters.com']
```
IoC TypeがhostnameのIoCのみ取得
In [16]: [ioc["indicator"] for ioc in iocs if ioc["type"] == "hostname"]
Out[16]:
['www.hexacam.com',
'www.miamirecyclecenters.com',
'www.atlantarecyclingcenters.com',
'www.hgssyouth.com',
'www.alucmuhendislik.com']
TypeがURLのIoCのみ取得
In [17]: [ioc["indicator"] for ioc in iocs if ioc["type"] == "URL"]
Out[17]:
['http://www.miamirecyclecenters.com/UYGjkdsc82R/UYGjkdsc82R/UYGjkdsc82R/UYGjkdsc82R/UYGjkdsc82R/UYGjkdsc82R/UYGjkdsc82R/UYGjkdsc82',
'http://alucmuhendislik.com/njhgftrf3/njhgftrf3/njhgftrf3/njhgftrf3/njhgftrf3/njhgftrf',
'http://alucmuhendislik.com/njhgftrf3/njhgftrf3/njhgftrf3/njhgftrf3/njhgftrf3/njhgftrf3/njhgftrf3/njhgftrf3/njhgftrf',
ちなみにたとえば人が触る画面やらに出力するのでクライアントアプリケーションによるリンクを抑制したいよなんていう時にドットを[.]なんて書く時がある。それをやりたいならリスト内包表記でやってしまえばよい。
In [19]: [ioc["indicator"].replace(".", "[.]") for ioc in iocs if ioc["type"] == "hostname"]
Out[19]:
['www[.]hexacam[.]com',
'www[.]miamirecyclecenters[.]com',
'www[.]atlantarecyclingcenters[.]com',
'www[.]hgssyouth[.]com',
'www[.]alucmuhendislik[.]com']
では、IoC Type名.txt というファイルで出力する方法を考えよう。このへんになるとPythonの話でしかないけども。
3行で書けちゃう。
python
In [22]: for typename in set([ioc["type"] for ioc in iocs]):
...: with open("{}.txt".format(typename), "w") as out:
...: out.write("\n".join([ioc["indicator"] for ioc in iocs if ioc["type"] == typename]))
...:
ファイルができている。
$ cat domain.txt
alucmuhendislik.com
atlantarecyclingcenters.com
hexacam.com
hgssyouth.com
今回はPulseの作成~利用までやってみたけど、想像していた通りの簡単さ。
そして実はPulseをPrivateにできるっていうのを知らなかったので新しい発見。(ROMだったので…)
また、一度作成したもののやはり中身を更新していきたい。更新しないと価値が半減。ということで次はAPIを使ってPulse内のデータを更新する処理をやってみたいと思う。
まとめ: 内定辞退率60% 私のやる気は3%