サーバのパケットキャプチャを取ってMirai亜種からのスキャン活動をELKで可視化する
こんにちは、にほんももんがです。昨年植えたハニーポット(Cowrie)ですが、今日も今日とてインターネットの片隅で細々と活動しております。可愛らしいなぁと最近始めた水耕栽培のサラダ菜の芽を見つめるような目でログを眺めている日々です。
ところで、Cowrieはssh/telnetの低対話型ハニーポットなので、最近流行しているマルウェアが引っかかることはあまりない*1ようなのですが、IIJ Security Diary: 日本国内における Mirai 亜種の感染状況 (2017年12月)の脚注1に記載があるように、パケットキャプチャをして「初期シーケンスNo=サーバ(ハニポ)のIPアドレスのSYNパケット」を抽出すれば、インターネットの片隅にあるサーバでも世の中のビッグウェーブに乗れるのかもしれないなあと思い立ちやってみました。
気分は完全に田舎のジャスコでは都会から流行が何週間遅れてやってくるのか調査する人って感じです*2。
それでは結論だけ知りたい方は結論に飛んでください。実際に何をしたか知りたい方は引き続きお読みいただければ幸いです。
目次
- 目次
- 環境
- tsharkでパケットキャプチャを取る
- tsharkで該当パケットを抽出する
- logstashでelasticsearchに放り込む
- Kibanaで可視化してダッシュボードを作る
- 結論
- 宣伝
環境
ソフトウェア | バージョン |
---|---|
OS | macOS Higth Sierra 10.13.3 |
tshark(Wireshark) | 2.4.3 |
Elasticsearch | 6.1.3 |
Logstash | 6.1.3 |
Kibana | 6.1.3 |
Kibana | 6.1.3 |
tsharkでパケットキャプチャを取る
まず、サーバのパケットをキャプチャします。今回パケットキャプチャをするのに使ったのはtsharkです。ポイントはtcp.relative_sequence_numbersというオプションをFASLEにすることです。該当パケットの抽出の際に設定すればいいオプションかと思いきや、取得の際に設定する必要があるようです(自信はないのでキャプチャするサーバと同様に分析PCのWiresharkでもこのオプションをFALSEにしておいてください…GUIの設定からでもFALSEにできます)。
キャプチャコマンド例)
$tshark -i ens4 -o tcp.relative_sequence_numbers:FALSE -b filesize:200000 -w ens4-capture -q &
※指定インターフェースやファイルサイズなどは適宜読み替えてください。
キャプチャを始めたら適当にお好みの日数熟成させます。満足行くまでキャプチャ出来たら、キャプチャしたファイルをなんらかの手段で分析用のPCへ移します。
ちなみに私はscpコマンドで雑に手元のPCにダウンロードしてきました。当たり前ですが、この時にまだtsharkを動かしたままだとこのダウンロード作業もキャプチャされるので注意してください。
tsharkで該当パケットを抽出する
次に、ダウンロードしてきたpcapから、tsharkを使って必要な情報だけ抽出します。今回は時間とソースIPくらいでスキャン行為の可視化は十分できるのですが、後ほど利用したい情報はそれ以外にもここで抽出しておいてください。ここでのポイントは、時間として抽出する列をframe.time_epoch
で指定することです。
frame.time
と指定してもFeb 4, 2018 16:53:46.464606074 JST
といったような表記で時間を得られるのでこれでいいかと思いがちなのですが、logstashのdateフィルターが最後の「JST」というタイムゾーン表記に対応していないため*3非常に面倒なことになります。
tsharkを用いた抽出例)
# 時間とソースIP以外も、ソースポートとディスティネーションポートを抽出しておくことにしました $tshark -r <pcapのファイルパス> -Y "tcp.seq == <サーバのIPを10進数で指定>" -T fields -e "frame.time_epoch" -e "ip.src" -e "tcp.srcport" -e "tcp.dstport" > <適当なファイル名.csv>
出力されるcsvのセパレータはデフォルトでタブです。
logstashでelasticsearchに放り込む
抽出したcsv用にlogstashのコンフィグファイルを書いてlogstashを起動し、elasticsearchへデータを放り込みます*4。
ここでのポイントは、csvフィルタのセパレータに\t
でなく
(ハードタブ)を指定することです。\t
指定だとタブ指定になりません*5。まあそもそもtsharkでcsv出力する時点でセパレータをカンマにすればよかった話なんですけど…。
コンフィグ例)
Kibanaで可視化してダッシュボードを作る
ワールドマップ
それではここからは画像のオンパレードです。まずKibanaにアクセスして、メニューの「Management」をクリックし、先ほどLogstashでElasticsearchに放り込んだデータをインデックスパターンに設定して「Next Step」をクリックします。
@timestampを選択して「Create Index Patterns」をクリック。
これでインデックスパターンが作成できました。ここで、「geoip_location」のtypeが「geo_point」になっていることを確認します。これがgeo_pointタイプになっていない場合はデータの取り込みに失敗しているので地図にマッピングはできません。
次に、メニューの「Visualize」を選択し、「+」マークか「Create a visualization」をクリックします。
とりあえずみんな大好きな世界地図へのマッピングがしたいので、「Cordinate Map」を選択します(以前はTile Mapと呼称されていたようですが変更されました)。
先ほど取り込んだデータで作成したインデックスを選択します。
まず、Metrics>Agrregationで「Count」を選択します。次に、Buckets>Aggregationでは「Geohash」を選択します。すると、Fieldの項目が選択できるようになるので、「geoip.location」を選択します。そして最後に右上の「▶︎」マークをクリックします。
マッピングできました。
Option>Map Typeを変更することでヒートマップにもできます。
右上のSaveをクリックして、名前をつけて保存しておきます。あとでダッシュボードを作る時に利用します。
ヒストグラム
スキャン活動を時系列で観測するため、データのヒストグラムを作ります。メニューの「Visualize」を選択し「+」マークから新規作成し、Vertival Barを選択します。
Y-Axis(Y軸)のAggregationはCountのまま、X-Axis(X軸)を追加します。Aggregationを「Date Histogram」にし、Fieldを「@timestamp」にして「▶︎」マークをクリックして反映すると、図のようにヒストグラムができますので、こちらも保存しておきます。もし何も表示されないといったような場合は、データを表示する期間などを調整してみてください。
スキャン元都市ランキング
次は、スキャンのログの数を都市別にカウントし、スキャン活動が多い≒感染端末が多い都市ランキングを作ります。メニューの「Visualize」を選択し、「+」マークから新規作成し、Data Tableを選択します。
MetricsのAggregationはCountのまま、Bucketsで「Split Rows」を選択し、Aggregationを「Term」に、Fieldを「geoip.city_name.keyword」に、Sizeに抽出する数を入力して「▶︎」マークで反映すると、どの都市から何回スキャンが来ているかのランキングを出すことができます。Fieldを「geoip.county_name.keyword」などにすることで国ごとのランキングにすることもできますし、「source_ip.keyword」にすることにより同じホストが何度スキャンして来ているのかのランキングを作ることもできます。
ダッシュボード作成
それでは今まで作成してきたグラフをまとめたダッシュボードを作成します。メニューの「Dashboard」を選択してダッシュボードの新規作成を選びます。
次に右上の「Add」を選択します。
すると下図のように今まで保存して来たグラフが(名前だけで)一覧として出てくるので、それを選択してゆくと下の方にグラフが追加されてゆきます。レイアウトはドラッグ&ドロップなどで自由に変更することができます。
じゃーん!これでダッシュボードが完成しました。ダッシュボードも忘れず 保存しておきましょう。
結論
今まで作って来たダッシュボード上でフィルタgeoip.country_name == Japan
を適用してみた結果が以下です。
5日間パケットキャプチャしているだけでも、自分が思っていたよりも日本国内ホストからのMirai亜種(と思しき)スキャン活動があるなあということがわかりました。インターネットの片隅での細々とした観測(つまりグローバルIPは一つしか保持してないってことです)でもこれだけスキャンされるので、いろんな場所にあるサーバで観測していれば、感染端末の規模感をそれなりの精度で予測できそうです。
ちなみにMiraiからのスキャンをマッピングしていたサービス、Mirai Trackerを公開していた(今は公開されていない)@MalwareTechBlog氏は500台くらいセンサー(観測するサーバ)を用意したと発言している*6ので、そのくらいあると本格的に規模感を把握できるのかもしれません。
宣伝
一連の話をデモを交えて「第3回 ハニーポッター技術交流会」で話す予定です。インフルエンザなどにかからなければ、3度目の正直で今回こそ参加できる予定です。
他の発表者が若者なので緊張しますがよろしくお願いいたします。
*1:ハニポ検出技術によって、丁寧な職人仕事(?)の施されたマルウェアはあまり捕獲できないような印象を受けます。印象でしかないので本当かどうかは保証し兼ねますが…。IoT狙いのコインマイナーとか雑な感じのマルウェアはわりとあっさり捕獲できたりしています。もちろん、最近流行のMirai亜種はスキャン活動をしているボットとは別にマルウェアをダウンロードしてくるサーバがあるので、おそらくボットよりもかなり数が少ないであろうそいつがイソイソとやってこないとマルウェアが設置されないからという理由もあるのでなんとも主張し兼ねますが…とにかく、アンチハニポ検出技術をご存知の方は教えてくださいということでよろしくお願いいたします。
*2:決して田舎のジャスコをdisっているわけではありません。随分お世話になっております。私はイトーヨーカドー派ですがジャスコもサイコーですよね。
*3:対応しているタイムゾーン表記はこちらです:Joda-Time - Java date and time API - Time Zones。JapanはOKなのに何故JSTがダメなのか納得いかない。
*4:Logstashをよく使われている方はご存知かもしれませんが、Windowsの場合ファイルのパスのセパレータに「¥」ではなくて「/」を利用してください。
*5:elasticsearch - logstash tab separator not escaping - Stack Overflow