PhishTank調査を自動化したい - part1

言い訳と動機

今月は仕事がとても忙しかったので、
Microsoftのフィッシングサイトへのアクセスとその後のアクセス試行の調査が出来ていないのですが、
こんな忙しいからこそ手軽に対応したいなあということもあり調査自体の自動化を行いたい。

なにがしたい?

通常であれば、
①フィッシングサイトのURLを取得
からフィッシングサイトへのアクセスをブロックする、アクセスがあったことを検出することが目的になりますが、
私がブログを書き始めたのはアクセスした後の動向を実体験として(ログを)確認することで、
『過去にアクセスしてしまったかもしれない』人を見つけられるかもしれないと思ったからなので、
②フィッシングサイトへのアクセス
③フィッシングサイトへ認証情報(正規の認証情報ではない、IDと環境は自分持ち)を入力
④Azure ADへのサインイン試行の確認
を行う必要があります。

①どうやる?編

①についてはこれまで通りPhishTankから情報を集めます。ツールはなんでもいいのですが、後々のことを考えてMicrosoft AzureのLog Analytics(いまはAzure Monitor?正式名称わからない、以下ログアナ)を使います。
ログアナではKusto Query Language:通称KQLと呼ばれる独自の言語で保管されたテーブルを操作するのですが、
保管されていないテーブルを外部から取得することもできます。そのためにはexternaldataと呼ばれるオペレータを使用します。
https://docs.microsoft.com/en-us/azure/data-explorer/kusto/query/externaldata-operator?pivots=azuremonitor

実行するKQLは以下。

externaldata (phish_id:string, url:string, phish_detail_url:string, submission_time:string, verified:string, verification_time:string, online:string, details:dynamic, target:string)
[@'http://data.phishtank.com/data/online-valid.json']
with (format=multijson)

実行すると以下のようなレコードが手に入ります。
(ポイントはformat=multijson)

画像1

画像2

detailsが配列になっているのでいい感じに展開して配列の中のディクショナリも列と値にバラバラにします。

externaldata (phish_id:string, url:string, phish_detail_url:string, submission_time:string, verified:string, verification_time:string, online:string, details:dynamic, target:string)
[@'http://data.phishtank.com/data/online-valid.json']
with (format=multijson)
//
//以下を追加
| mv-expand details
| evaluate bag_unpack(details)

欲しい情報は(いまのところ)稼働していそうな新しめのMicrosoft向けのフィッシングサイトのURLおよびIPアドレスだけなので、いい感じにフィルタリングします。

externaldata (phish_id:string, url:string, phish_detail_url:string, submission_time:string, verified:string, verification_time:string, online:string, details:dynamic, target:string)
[@'http://data.phishtank.com/data/online-valid.json']
with (format=multijson)
| mv-expand details
| evaluate bag_unpack(details)
//
//以下を追加
| where target == 'Microsoft' //Microsoftに限定
| project url, verified, online, target, ip_address, country, cidr_block, submission_time, verification_time //必要なパラメータのみ出力
| where verified == 'yes' and online == 'yes' //フィッシングサイトとして確認されていて未だオンラインと思われるものに限定

画像3

それっぽい出力が得られましたがどうやら同URLで複数のIPアドレスとNetwork CIDRのレコードがあるようなので、URL単位でまとめてみます。

externaldata (phish_id:string, url:string, phish_detail_url:string, submission_time:string, verified:string, verification_time:string, online:string, details:dynamic, target:string)
[@'http://data.phishtank.com/data/online-valid.json']
with (format=multijson)
| mv-expand details
| evaluate bag_unpack(details)
| where target == 'Microsoft'
| project url, verified, online, target, ip_address, country, cidr_block, submission_time, verification_time
| where verified == 'yes' and online == 'yes'
//
//以下を追加
| extend TimeGenerated = todatetime(submission_time) //報告された日時をTimeGeneratedに名称変更して型変換string→datetime
| summarize arg_max(TimeGenerated, *), make_set(ip_address), make_set(cidr_block) by url //URLごとにIPアドレスとNetwork CIDRをまとめる。他の列は最新のものを使用する
| project-away ip_address, cidr_block //不要なip_address, cidr_blockを除外する

画像4

いい感じに出力が出来ました。このデータを②以降に渡していきますが、それはまたいずれ。
この方法のいいところは、
・データ取得自体にほぼ料金が発生しない
・取得後の処理がしやすい
・KQL自体をURLに格納できるのでブックマークに入れてアクセスするだけ
ことにあります。
例えば今後②以降を手動で実施する場合、フィッシングサイトのURLをコピペしていくことになりますが、
フィッシングサイトのURLは誤操作してしまうと取り返しのつかないことになりかねないため、
事故防止のためにそのままコピーしたくありません。
そのためFQDNとして成立しないようにURLを無害化します。

externaldata (phish_id:string, url:string, phish_detail_url:string, submission_time:string, verified:string, verification_time:string, online:string, details:dynamic, target:string)
[@'http://data.phishtank.com/data/online-valid.json']
with (format=multijson)
| mv-expand details
| evaluate bag_unpack(details)
| where target == 'Microsoft'
| project url, verified, online, target, ip_address, country, cidr_block, submission_time, verification_time
| where verified == 'yes' and online == 'yes'
| extend TimeGenerated = todatetime(submission_time)
| summarize arg_max(TimeGenerated, *), make_set(ip_address), make_set(cidr_block) by url
| project-away ip_address, cidr_block
//
//以下を追加
| extend url = replace(@'http', 'hxxp', replace(@'\.', '[.]', url)) //URL内のドットを大かっこで囲ってプロトコルをhxxpに変更

画像5

さらにクエリを含んだURLを生成することで、URLへアクセスするだけで整理されて無害化された情報にアクセスすることができます。

画像6

蛇足

他にもちょろっと加工するだけでグラフにすることもできるのでブログに書きやすいw

画像7

ちなみに以下はtarget、onlineステータスに関わらず集計した件数。
2/16あたりから報告件数が増えているように見えることがわかる。
ただ注意が必要なのはこの元となっているデータが必ずしも更新された時点で一部削除されていない可能性は否定できない点。

画像8

(PhishTankの仕様をよく理解していないので推測ですが)もしかするとabuseされた段階でデータを消している可能性もあり(アクセスできないものもリストにはあるので消してなさそうな気はしますが)、
過去にいけばいくほど減っているのはそもそもonline状態が無くなっているからかも....?
じゃあonline == 'no'のデータってどれくらいあるかというと、

画像9

え、ない!
じゃあ過去で一番古いデータって...

画像10

おお、2008年ですか...
ということで消されてなさそうなので、やはり2/16から増えてそうだなあということはなんとなくわかりました。

ちなみにログアナからのデータ取得は仕様上送信元IPがばらついてPhishTankへアクセスされるため、ダウンロードリクエスト制限に恐らく引っかかりません。とはいえ自動化する場合は良識をもってアプリケーションキー登録を行いましょう。
参照) https://www.phishtank.com/developer_info.php

この記事が気に入ったらサポートをしてみませんか?