AWS EC2へのSSHに対する攻撃を分析してみた (2015年4月〜6月)

数ヶ月間、私のお小遣いを貪り続けてきたAWS EC2上のハニーポットですが、さすがに財布へのダメージが蓄積してきたのでいったん停止させました。停止させたもののそれなりにデータを蓄積していたので、さてどうしようかなと思っていたのですが、 先日、長崎で開催された情報処理学会のコンピュータセキュリティシンポジウム2015で聞いた講演の一つに SSHの新しい攻撃方法について触れられていてちょっと気になったので、収集したデータのうちSSHに関しての通信のみちょっと分析してみました。

ハニーポットの構成やデータの収集方法については過去のエントリを参照していただきたいのですが、 今回はAWS Asia Pacific (Tokyo)上でEC2のインスタンス4つを4月頭から6月末まで動かしてデータを取得しました。財布へのダメージも4倍! しかしおかげで複数のIPアドレスで観測した時に生じる差分について知ることができました。

アクセス件数の推移

2015年4月から6月までEC2の4インスタンスで観測したSSHサーバへのアクセス件数

まずはベタに各インスタンスに対するアクセス件数を時間軸で見たものです。A, B, C, Dがそれぞれのインスタンスになりますが、 4つともアクセス件数の傾向にそれほど大きなブレ方はしていないことがわかります。これらのインスタンスが使っているIPアドレスは どこにも広告していないので基本的には全て無差別に打ち込まれている攻撃であると言えます。そのため特定の組織などに対する 攻撃とは異なるかもしれませんが、このようなアクセスは使用しているIPアドレスに関わらず、安定(?)して日々起きていることがわかります。

アクセス先ポート番号の件数

2015年4月から6月までEC2の4インスタンスで観測したSSHサーバに対するアクセス先ポート番号の件数

つづいてアクセス先ポート番号の分布です。4インスタンスの合計値から上位20件をグラフにしてみました。 当然ながらデフォルトポートである22番へのアクセスがダントツですが、それ以外にも様々なポート番号に対して アクセスが来ていることがわかります。ちなみに観測されたポート番号は合計56種類となっており、 505018080 などといったSSHとは全く関係なさそうなポート番号もターゲットとなっていました。

今回利用したハニーポットは特にSSHサーバを偽装するわけではなく、 アクセスしてきた接続元のホストに対してSYN-ACKを返すだけで、あとは勝手に相手が送ってくれたデータをせっせと回収します。 ではなぜ22番ポート以外もSSHだとわかったのか?というとSSHの接続確立時に相手が勝手にバナーとして SSH-2.0-PUTTY のような文字列を送ってきてくれるので、そこからSSHをターゲットにしているということがわかります。 なかにはSSH-2.0-paramiko_1.15.2SSH-2.0-libssh2_1.4.2のように、あからさまにツール使ってますぜと宣伝してくれている やつもいたりします。 しかし先に述べたとおりこちらからは何も情報を渡していないため、相手は攻撃先がSSHサーバであるかどうかを確認などせずに22番以外の ポートに接続をしにきているということがわかります。「ポート番号を変えているからパスワード認証でも大丈夫だよね」とか 「ポートスキャンを止めているからどこがSSHのポート番号かわからないよね」と考えている管理者の方はぜひ設定の見直しをお勧めいたします。

アクセス先IPアドレスと攻撃元IPアドレスの関係

2015年4月から6月までEC2の4インスタンスで観測した攻撃元IPアドレスの件数(アクセス先IPアドレス毎)

それではようやく複数のインスタンスを使ってデータ収集した強みをみたいと思います。 気になることの一つとして「攻撃者はIPアドレスのレンジを舐めるように攻撃しているのでは?」ということだと思います。 実際にSSHにかぎらずport sweep(アドレスレンジに対して特定のポートが空いていないか順番に確認するタイプのスキャン)などでは そういった挙動も見られます。

上の表は各インスタンス(A, B, C, D)で観測されたかどうかと、それぞれで観測されたIPアドレスのユニークな数になります。 観測されたIPアドレスは全部で6,669件ですが、そのうちの約80%にあたる5344件の攻撃元IPアドレスがどれか一つのインスタンスでのみ 観測されているということになります。それぞれのインスタンスはある程度同じレンジにおさまっていたため、 このことから 攻撃者は近接するアドレスに対して何度も出現する可能性が高いとは言えない ということがわかります。 先ほどのポート番号に比べると直接的な対策ができるような類のものではありませんが、例えば自組織で管理されている サーバでSSHの不審なアクセス(Brute forceなど)が発生したさいに他のサーバも利用するブラックリストに追加する、 というような対策はそれほど効果的ではないかもしれません。(もちろん、残り20%は複数インスタンスで観測されているので 無意味ということはありませんが、それでも全インスタンスで観測されたアドレスは約6.5%ほどになっています)

攻撃元IPアドレス毎の接続試行回数

2015年4月から6月までEC2の4インスタンスで観測した攻撃元IPアドレス毎の接続試行回数の分布(n<10)

最後にご紹介するのが1つの攻撃元IPアドレスからやってくるSSHアクセスは何回まで試行されるか?ということをグラフにしたものです。 先述したとおり、このデータ収集はあくまでTCPセッションが確立したとみせかけてデータを送信させるだけという仕様になっているため、 本当にBrute force attackのようなパスワード試行された回数をカウントしているわけではありません。 しかし、通信状態の問題などでうまく接続できないなどのケースが考えられるため、相手がどれくらいしつこかったのかということを 知る指標にできるかと思います。

このグラフでは1つのインスタンスでのみ観測された5344件のIPアドレスに対してそれぞれのアドレスは何度接続試行したのかを ヒストグラムで表したものとなります。一番左のバーが1回だけの試行だった攻撃元IPアドレスのかたまりになるのですが、 これを見るとほとんどの攻撃元IPアドレスが試行1回目でダメそうだったらその時点で諦めているということがわかります。 このグラフは試行10回までの分布しか表示していませんが、10回以上試行してきたIPアドレスは16件だけでした。 全体的に非常に諦めがよい、ということを読み取ることができます。

しかし、ここで最初にふれた情報処理学会のコンピュータセキュリティシンポジウム2015の話に戻ってくるのですが、 富士通研究所の齊藤さんが発表された「SSHログインセンサによるSTBF(Brute Force attacks with Single Trials)の観測」において 一つのIPアドレスからパスワード試行が1回だけ実施されて、次は別のIPアドレスから試行されて、というのを繰り返すBrute force攻撃が確認されたという 事例が報告されていました。これは、一つのホストからパスワード試行を繰り返すと防御側に目立って接続拒否されたり、 共有されているブラックリストに掲載されてしまい他の環境に対しても攻撃ができなるなることを攻撃者が警戒した結果、 ボットネットのように悪性ホストを大量に所有(またはレンタル)している攻撃者が目立たないように1回だけパスワード試行をして去る、という 一撃離脱型の攻撃が連続して発生しているということだと考えられます。 この攻撃に対してはIPアドレスを基準としたパスワード試行回数制限による対策がほぼ無効化されてしまうということが言えます。

実際にこの攻撃がどのくらい世の中に蔓延しているかについては発表者の方も今後調査を継続していくとおっしゃられていましたが、 ここで紹介した分析からもそのような種類の攻撃が発生している可能性を示唆する結果となりました。 AWSでのインスタンスに限りませんが、SSHでリモートアクセスをしているホストについては 今一度設定の見直しなどをしたほうがよいかもしれません。

まもなく日本語版がでるHearthstoneとその制作会社であるBlizzardとは

battle.netより

もうまもなくアメリカのBlizzard社が作成している Hearthstoneというゲームの日本語版がリリースされる。一部のファンが騒いでいるのを目にした人もいるかもしれない。言ってしまえばたかだかいち洋ゲーの日本語化にすぎないのだが、私自身がこのゲームを好きなこともあり、なぜ一部で注目されているかということについてちょっと説明してみたい。

そもそもBlizzard社とは

正式名称Blizzard Entertainment社。おそらく日本ではかなり知名度が低いと思われるが、まさに世界トップのゲーム制作会社の一つであることは間違いない。家庭向けインターネット黎明期からオンラインゲームを作り続けており、いまなおヒット作を生み出し続けている。そして世界中で非常に多くのユーザがこの会社のゲームを楽しんでいる。彼らはゲーム制作に非常にこだわりを持っており、明らかにゲームシステムができているのに発売まで数年かけたり(おそらくゲームバランスの調整をしていると見られる)、発売前に制作を中止したりする徹底ぶりである。

代表的な作品をいくつか紹介したいと思う。

Diablo(ディアブロ)シリーズ

battle.netより

おそらく現時点ではこれが日本で最も有名なBlizzardのゲームだと思われる。2015年時点でDiablo3までが発売されている。ゲームスタイルは複数人でネット越しに集まってやるモンハンといえば想像しやすいかもしれない。やりこみ要素やゲームバランスが優れており、1990年台後半にヒットしたDiablo2は廃人を続出させていた。また、Diablo3についてはスクエア・エニックスが委託によって日本語版をPS4で発売している。

Starcraft(スタークラフト)シリーズ

battle.netより

リアルタイムでマップ上の資源を回収し、兵士や兵器を準備し、対戦相手を攻略するRTS(リアルタイム・ストラテジー)というジャンルのゲーム。日本ではAge of Empireの方が有名で、最近ではスマホゲームのClash of Clansやリトルノアがこれに属する…らしい。Starcraftは特に韓国で人気が高く、プロリーグが存在し韓国の大手企業がそれぞれスポンサーとしてついている。世界大会も多く開かれており、賞金総額が数千万円単位なこともざらである。

Warcraft / World of Warcraft シリーズ

battle.netより

WarcraftはStarcraftと同じRTSのゲームになる。こちらは最後の拡張が2003年に発売した後は開発は続けられていないが、この世界観を引き継いだ World of Warcraft は世界最大規模のMMORPGとなっている。月額課金制であるこのゲームは、最近は最新拡張の適用から約1年たっていることもあり課金者数が500万人ほどだが、2014年の「ファイナルファンタジーXI」「ドラゴンクエストX」「ファイナルファンタジーXIV」の合計課金者数が約100万人とのことなので、これと比較するとその規模が想像できるのではと思う。(ちなみに最新拡張の開始時は課金者数が1000万人ほどだった)

では Hearthstone とは

battle.netより

先述のWarcraftシリーズの世界観を引き継ぐオンラインカードゲームである。Magic the Gathering (マジック・ザ・ギャザリング、MtG) に代表されるトレーディングカードゲームの一種である。ゲーム中で取得・あるいは購入したカードで自分がつかうカードのセット(デッキ)を作成する。カードにはミニオン(戦うキャラクター)やスペルなどがあり、これらを組み合わせた30枚のカードのデッキを用いて1対1の勝負をする。

自分はほとんど他のTCGをやったことがないのだが、以下の点が良いと思っている。

  • 単純にプレーヤー数が多い。公式発表では3000万人ほどのプレーヤーがいるとのこと。とりあえず自分がこれまでプレイしてきて、対戦相手のマッチングに1分以上かかったことはない。
  • プレイヤー数が多いため攻略や考察などが豊富である(ただし、現状ほぼ英語)
  • 操作性に優れている。たとえば不要なカードを他のカードを作るための材料にできるのだが、ダブったカードを自動的に選んでボタン一つで全て処理してくれる。また特にタブレットやスマフォだと操作が直感的で分かりやすい。
  • 実際のお金を払って追加カードを購入できるが、課金すればするほど有利になったり、レアなカードをもとめて何十万と課金することはない。デッキの作り方によるが、自分の経験では多くて1万円ほどで、それ以上課金しても大幅に有利になるということはない。これはレアなカードの出現率の問題だけでなく、不要なカードを材料に(もちろんそれなりの量は必要だが)自分の好きなカードを作れるというシステムがあるためである。

見放されていた国、日本

さて、ではこのゲームの日本語化がどうして注目されているかというと、日本という国はながらくBlizzardから見放されていたという現実がある。日本の会社に委託してローカライズされるというケース(例えばDiablo3)はあったが、Blizzardが自ら日本語化するということはこれまでなかった。

これはアジア圏に対して冷たかったかというと、Starcraftの人気の関係で韓国はかなり優遇されていたし、World of Warcraftでは中国語にローカライズもされている。これはBlizzardは主にPCでプレイするゲームを作っていたが、長らく日本ではコンシューマ機がゲーム市場を独占していて参入が難しかったのではないかと勝手に想像している。また”JRPG”と揶揄されいたりするように、日本人のゲーム感覚が若干他の国とずれいているというのは否めず、敬遠されてきたのではないかと考えている。

だからこそ今回の日本語化は嬉しい

冒頭で書いたとおり、Blizzardのゲームは本当に面白いものが多い。ゲームバランスがとても良く出来ており、どのゲームでもこれだけやれば勝てるというようなものはないし(あったらすぐ調整される)自分の腕を上げれば確実に強くなる。Hearthstoneはデッキを作って戦うためそれなりにカードを揃える必要はあるが、カードの強さだけではある程度のところですぐに行き詰まってしまうようになっている。そのため、勝つためには戦略を考えたり研究したりしなければならない。

正直なところ、こういったプレイスタイルがどこまで日本のユーザに受け入れられるかはわからないし、いわゆる日本のスマフォゲームが売りにしている要素(例えばいわゆる萌え要素とか)がほぼ皆無というのも不安を煽る。ただ、自分で戦略を考え、相手の動きを読んで、勝つというのはとても気持ちのいいものなので、ぜひ多くの人に体験してもらえればと思う。

さらにはこれをきっかけに、他のBlizzardのゲームももっと日本で流行ればいいなというのがささやかな願いである。

6ヶ月間のハニーポットログの可視化(分析結果)

前回記事 6ヶ月間のハニーポットログの可視化(構築及び視覚化手法) の続きです。 前提となるデータの収集環境や可視化手法などについては前回記事にありますので、そちらをご参照ください。 今回は可視化をしてみたことで明らかになった、個人的に興味深い事例をいくつかご紹介します。

Shellshock脆弱性

"QNAP NASのShellshock脆弱性を狙ったとみられる攻撃のパターン1"

"QNAP NASのShellshock脆弱性を狙ったとみられる攻撃のパターン1"

6ヶ月間のハニーポットログの可視化(構築及び視覚化手法)

毎月、飲み会1〜2回分くらいのお金を吸い続けさせながら運用している個人的なハニーポットですが、 データをためるだけためて塩漬けにするのもなんなので、過去6ヶ月分(2014年10月〜2015年3月)の データを可視化および公開しました。公開されているデータは http://pktviz.org/lurker から参照できます。 この記事ではデータの収集方法や可視化・分析方法、興味深かった分析結果について解説したいと思います。

データ収集方法

攻撃データの収集はAmazon EC2上のインスタンスを利用し、自作のハニーポットソフトウェアLurkerを動かして インターネット上からサーバのような常時稼働しているタイプのホストに対する攻撃を収集しました。 PCなど個人で使うようなホストへの攻撃はインターネットから直接的なアクセスではなく Drive by Download攻撃(悪意のあるWebサイトを閲覧した時に攻撃を受けるタイプ)やEメールを利用した攻撃に トレンドが移り久しいですが、公開サーバへの攻撃は日々継続しています。 今回は収集期間(2014年10月〜2015年3月)の間に1つのIPアドレスに対して24,844件のアクセスを受けました。

"ハニーポットの構造"

上の図がハニーポットの設計になります。青色のオブジェクトがハニーポット運用のために用意したもの、 赤が外部からの攻撃者になります。 ハニーポットの動作は非常にシンプルでTCPのSYNパケットに対して偽のSYN ACKパケットを応答し、 あとはデータを含むパケットが送られてきたらそれを記録してDBへ送るだけというものです。 ご存じの方も多いかと思いますが、TCPの通信は

  1. 通信を開始したいホストがSYNパケットを送る
  2. 通信を受けるホストがSYN ACKパケットを返す
  3. 通信開始側のホストがACKパケットを送る
  4. ここまできて両方のホストの準備が整った(Establihsed)ものと判断してデータの送受信がはじまる

という流れで開始します。ここでこのLurkerは送られてきたあらゆるTCP SYNパケットに対して ひたすら偽装したSYN ACKパケットだけを応答し、あとは何もせず放置しておきます。 そうするとSYNパケットを送ってきた攻撃側は勝手にEstablishedの状態になったと判断して、 攻撃データを送ってきてくれるので、あとは送られてきたデータを記録するだけです1。 データはログとしてfluentdに投げているので、あとはプラグインと設定次第で格納するDBは選びたい放題です。 特に深い理由はなく、自分がちょっと慣れているからという理由だけでMongoDBを使っています。 今回はこのDBから6ヶ月分のデータをとりだして、別途データを分析したものを公開しています2

データの可視化

前述したとおり、可視化されたデータは http://pktviz.org/lurker から参照できます。

今回の分析のポイントとして、攻撃のペイロード(実際に送信されたTCPのデータセグメント部分)の 類似性にもとづいて事前にデータをクラスタリングしました。 送信されてくるデータは完全に重複するものも数多くあるのですが、それ以上に攻撃者が使っているツールがわずかに違ったり、 あるいは攻撃に使っているパラメータが少し違うだけというようなものが多く観測されました。 もちろん、攻撃対象となるサービスのプロトコルに依存する部分もありますが、 下の図のようなクラスタリングを実施した結果、同じプロトコルでも複数の特徴が見える結果となりました。 類似度はペイロード同士の最長共通部分などを基準にし、24,844件のデータを569のクラスタにまとめることができました。

"攻撃データのクラスタリング例"

それぞれのクラスタはSampleという単位で扱っており、それぞれにSample IDが割り当てられています。 (代表値のペイロードからMD5のハッシュ値をわりあてただけです) このクラスタをベースにして、各クラスタの代表ペイロードデータ(Example payload (ascii + hex))、 宛先ポートの割合(Destination Port)、時系列での発生件数(Time Series Chart)をリストで表示しています。 宛先ポートの表示はd3pie、折れ線グラフはd3jsで描画しています。

"一覧表示画面でのSampleのサマリ"

このリストでは代表値の検索ぐらいはできるようにしておいたので、例えば:;といれて検索することで Shellshockっぽいパターンを抽出したり、_searchで検索することでElasticsearchの脆弱性を狙ったと思われる ものを抽出することができます3

またSample ID: xxx...のタイトルの部分をクリックすることで各クラスタの詳細な情報を見ることができます。

詳細の1つとなるのが、1つのクラスタにまとまっている複数のペイロードにどのようなバリエーションがあるのかというものを 可視化したものです。これはペイロードの差分をノードグラフにしてペイロードの分岐を示したものになります。 サムネイルをクリックすると大きい画像を表示しますが、中には数十MBのものもあるので注意して閲覧してもらえればと思います。 例えば下の図で示しているペイロードはQNAP NASのShellshock脆弱性を 狙った攻撃と見られますが、/cgi-bin/authLogin.cgi というパスを指定しているところまでは共通していますが、 攻撃コードとして最初に実行するコマンドが/bin/rm -rf /tmp.io.php/bin/rm -rf /tmp.S0.php/bin/rm -rf /tmp.io.shというようにいくつかのバリエーションがあることがわかります。 グラフ作成アルゴリズムがちょっとやっつけなので、重複するノードがあったりするのはご容赦ください4

"QNAP NASのShellshock脆弱性を狙ったとみられる攻撃のパターン1"

また、下の図も同様の図の一部ですが、上側の部分で途中でデータをダウンロードする先がhttp://stanislaw...http://185...http://lliillii...と少しずつ違っていたり、 下側の部分でデータ設置場所にしようとしているディレクトリも/share/HDB_DATA/home/httpd//home/httpd/cgiとバリエーションがあるのがわかります。 これによって同じ脆弱性やツールを用いた攻撃でも部分的に違ってくるということがわかります。 フルサイズの画像はこちらから参照できます。

"QNAP NASのShellshock脆弱性を狙ったとみられる攻撃のパターン2"

さらに送信元IPアドレスと宛先ポート番号について、それぞれどの時期にどれくらいの攻撃が発生していたのかを示す ヒートマップをそれぞれのクラスタごとに作成しています。時系列的な量的変化を表すのだと折れ線グラフが一般的ですが、 系列(ここでは送信元IPアドレスや宛先ポート番号の種類)の数が20をこえたあたりから折れ線グラフは極端に見づらくなってしまいます。 一度に多くの系列を表示させて時間相関が見やすくなること、そして数の比率より1件でも攻撃があったかどうか、という観点から 時系列ヒートマップで視覚化しました。明るい赤のほうが発生件数が多い時間帯で、マウスオーバーで実際の件数を見ることができます。 これによって、ツールや攻撃手法がどの時期に流行ったかや、攻撃対象となったサービスがどのように変化したかを読み取ることができます。

"送信元IPアドレスと攻撃発生日時のヒートマップ" "宛先ポート番号と攻撃発生日時のヒートマップ"

ちょっと長くなってしまったので、分析結果の紹介は記事を分けたいと思います。


  1. この仕組はもともとFFRIの村上純一さん(@junichi_m)が考案して実装を公開されていましたが、今は公開されていないので勝手に作りました。

  2. もちろんリアルタイムに直近のデータを表示させることもできますが、ハニーポットを特定可能な情報が含まれてしまうため、ここでは過去のデータだけを使っています。なお当該ハニーポットはすでにシャットダウンしています

  3. あと、90 90のように入力すると16進数としてバイナリ値としても検索できるはずです。

  4. というか、こういう複数のシーケンスからきれいな分岐のグラフをO(N log N)ぐらいで作れる簡単なアルゴリズムをご存知の方がいらっしゃいましたらぜひご教示ください。O(N2)ぐらいならいけそうなんですが、いかんせんデータ数が多いものが終わらない。。。

仕様変更をすると良くない3つの理由

なんか釣りっぽいタイトルですが、【翻訳】プログラマを悩ませること Top 10みてちょっと触発されたので。仕様変更自体はやむを得ないものだし、それ自体を否定するわけではないですが、現場に悪影響を及ぼす可能性を多くはらんでいると考えます。仕様変更をする時はよく考えてからGoを出すべきですという話。

1. 無茶な要求がでてくる

「AができるんだからBもできるよね」「ここをちょっとこう直すだけだから」という言説をよく見かけます。 簡単にできる修正ももちろんありますが、そうでないものもたくさんあります。特にソフトウェアのようなものは 裏のロジックも含めた実態がぱっと見わかりにくいものですが、あなたが要求していることは建設済みのビルに対して 「今60階のビルだけど、61階にしてくれない? 1つ増やすだけだから簡単でしょ?」とか 「ちょっと横に1mぐらいずらしてくれないかな」と同じようなことを要求しているかもしれません。

2. 期限やリソースが勝手に決まる

もちろんどんなに無茶と思われる要求でも、多くの期限と大量のリソースを投入すれば実現可能かもしれません。 60Fのビルも莫大な費用をかければ61Fになるかもしれません。(建築関係詳しくないですが) ただ、それに対してどのくらいの期間が必要か、という判断を1と同じような「表向き」に見えている 部分からだけの判断だったりすると、不幸なことになります。単純に間に合う、間に合わないの問題ではなく 新たな問題が発生することによって、全体のクオリティにも影響するかもしれません。 突貫工事の事故でビルそのものが倒壊する恐れもあります。

また、特にソフトウェア開発やSE的案件では人月(人数×時間)で開発や修正に必要なコストが計算されますが、 古の伝承でも指摘されている通り、 人数と時間は置き換えることができません。むしろ人数を増やせば増やすほどコミュニケーションコストがあがって ずぶずぶ泥沼に沈んでいきます。あと、開発する人の熟練度も一様ではありません。 Lv1の戦士が100人いてもLv99のボスを倒すことはできないですし、アマチュア作家を100人集めれば 必ず芥川龍之介の文章ができるわけではありません。

3. モチベーションが下がる

仮に期限やリソースが無限に設定できたとしても、度重なる仕様変更はエンジニアのモチベーションをすり減らしていく場合があります。追加の機能などであればまだいいですが、根本的な設計の変更が必要なものだったりすると、今まで頑張ってやってきたものの大部分が無駄になることもあります。穴をほって同じ場所を埋め戻すのを延々と繰り返すという拷問があるそうですが、それと同じようにいつまで頑張っても達成感が得られないような仕様変更が続くと、「どうせまた無駄になるし」みたいな気持ちになって、どんどん仕事が適当になっていくでしょう。

じゃあ、どうしてほしいか

とにかくエンジニア(ないしは実際に作業をする人)を決定に巻き込むことが重要だと思います。 期限や開発者の状況や、変更にどれくらいのコストが掛かるものなのかを関係者みんなで共有することで、 現実的な変更にすることができるかもしれません。もちろんこれはエンジニア側もなぜ難しいのかを 分かるように説明する必要がありますし、変更の目的を実現できるもっと良い案を出していくこともしなければなりません。 実際には、発注側と開発側のお互いが歩み寄ることが重要だと思います。

ニコニコ動画(GINZA)でマイリスト内の動画を一括選択

自分用メモ

  1. ブラウザをChromeにします
  2. マイリストを表示します
  3. ページ内で右クリック –> 要素の検証
  4. 現れた下のウィンドウで一番左のタブ Console を選択
  5. 以下のJavaScriptを入力してEnter。true と返ってきたら成功

     for(i=0;i<document.getElementsByClassName('checkBoxOuter').length;i++){(document.getElementsByClassName('checkBoxOuter')[i].childNodes[1]).checked = true;}
    

DnsHiveをリリースしました

DnsHiveはパケットキャプチャによってDNS名前解決情報の蓄積とネットワーク監視を同時に実行し、ツールです。tcpdumpコマンドを使ったことがある人に端的に機能を説明すると、以下の様な使い方ができます。

# dnshive -i eth0 | grep google.com
1391871175.057028 TCP 10.0.0.5/63906 -> safebrowsing.google.com.(173.194.126.233)/443 Len:107
1391871175.102049 TCP safebrowsing.google.com.(173.194.126.233)/443 -> 10.0.0.5/63906 Len:66
1391871332.255500 TCP 10.0.0.5/63921 -> www3.l.google.com.(173.194.117.131)/443 Len:78
1391871332.294297 TCP www3.l.google.com.(173.194.117.131)/443 -> 10.0.0.5/63921 Len:74

これによって、特定のドメインとの通信をネットワーク監視することができます。

なぜtcpdumpではできないのか

クライアントPCのブラウザなどから見えているドメイン名とパケットキャプチャソフトから見えるドメイン名は異なる場合がある

有名なパケットキャプチャソフトであるtcpdumpWiresharkでは、取得したパケットを表示する際にIPアドレスからドメイン名を検索する「逆引き」機能が備わっています。この時、IPアドレスとドメイン名が1対1の対称構造になっていれば問い合わせ時と同じドメイン名を取得できますが、近年はDNSの設定が複雑化しており対称構造になっていないことが多々有ります。(こちらもご参照ください)そのため、パケットに含まれるIPアドレスだけでは元々どのドメインと通信をしようとしていたのかを判断するのは難しくなっています。

なぜDnsHiveだとできるのか

DnsHiveの仕組み

DnsHiveの構造

本ツールは監視している通信の中からDNSの応答パケットを読み取り、どのドメイン名とIPアドレスが紐づくかを調べ、記録する機能があります。DNSの応答はAレコード、AAAAレコード、CNAMEについて調べます。あとはパケットの内容を表示したり、ファイル(msgpack形式)やメッセージキュー(ZMQ PUB)で出力する際に、IPアドレスだけではなくドメイン名の情報を検索して、一致するものがあればそれも付随させて出力します。

これによって、ツール内でCNAMEを含むドメイン名とIPアドレスのマッピング情報を持つことができ、プログラムが知りたいときに「正引きの逆をたどる」(「逆引き」ではない)をすることができるようになります。仕組みとしてはとても単純ですが、tcpdumpやwireshark、netflowなどでは基本的にIPアドレスまでしか辿れないため、低レイヤで見た統計・計測情報とその通信がどのような意図で実施されたのかをひもづけるのが難しい、という実情があったように思えます(自分が本職のネットワークオペレータではないので想像ですが)このツールでそういった分析の幅が広がればと考えてます。

制限事項

ツールを使うにあたって、いくつか技術的な制限があります。

  • 基本的には監視してるネットワーク上のDNS通信を分析するため、DNS通信が含まれているトラフィック/データでないと効果を発揮できません
  • DNSの問い合わせ・応答を見るため、あらかじめホスト上にあるキャッシュやホスト上で定義されたホスト名などは知ることができません
  • 現在は取得したIPアドレスとドメイン名のマッピングを上書きしていく仕組みになっているため、同じIPアドレスを返す別のドメイン名が出現した場合は新しく出現したものが優先して表示されます

使い方

githubにレポジトリをおいてあるので、cloneして利用していただければと思います。導入にはdnshiveの他にパケット解析ライブラリのswarmも必要になりますのでそちらも合わせて導入してください。今のところはバイナリなどでの提供はありません。

https://github.com/m-mizutani/dnshive

Visualization of DNS Query and Response

Visualization of DNS Query and Response

Overview

Recently I’m strongly interested in exploratory data analysis and network analysis. Then I created one visualization based on the two techniques by DNS query and response. As you may know, we leverage domain name to look up IP address by querying to DNS server. Traditionally, domain name and IP address are configured symmetrically, however recent web services don’t apply symmetrical settings because of load balancing, virtual private hosting, etc. So, it’s difficult to understand usage of domain name service for the users.

Then, I’m trying to visualize DNS query and response to understand architecture of DNS for the services. I used 24 hours traffic data of my home network to visualize. The number of record is 75,098, and I leveraged my traffic analysis tool and graphviz for visualization.

windows.microsoft.com

At first, one easy case. The yellow node means domain name queried for CNAME (e.g. Browser querying the domain name to DNS server), the red node liked with the yellow node by dotted line is a result of querying CNAME, and the green node means actual IP address. The image shows:

  1. Some program queries IP address of windows.microsoft.com
  2. DNS server tells windows.microsoft.com is origin.windows.microsoft.com.akadns.net
  3. The program queries IP address of origin.windows.microsoft.com.akadns.net
  4. DNS server tells IP address of origin.windows.microsoft.com.akadns.net is 65.52.103.234
  5. The program connects to 65.52.103.234

Please note it’s just rough explanation :–)

ad.yahoo.co.jp

Next one shows querying one domain name and multiple IP address returned. It’s not clear that these IP addresses returned at once, or one by one. But we know well it’s one of techniques to load sharing.

nikkei.co.jp

There is an opposite case. The image shows only one IP address is assigned for multiple domain name. I guess there are separated several services, however they don’t have high load. Then they are aggregated to one server. It’s also well known technique to service deployment.

dropbox.com

OK, let’s see a tough case by now. When I(We?) use Dropbox, domain name clientXX.dropbox.com is queried at first, and they are aggregated to client.dropbox.com, and forwarded to client.v.dropbox.com. Eventually domain name client.v.dropbox.com returns a lot of IP addresses. I imagined the architecture for load balancing in the future, but I’m not sure.

couldfront.net

Next one is more aggressive. The image shows domain names and IP addresses related to cloudfront.net. As you may know, Cloud Front is Contents Delivery Network service provided by AWS. Several sites (nikkei.comtogetter.comalc.co.jpevernote.com) are entry point, however there are a lot of IP addresses and complex links between domain name and IP address. It’s estimated that internal system is cross site architecture, not separated per tenant in infrastructure level.

Google

The image shows domain name related to Google. I could not tell about all of Google’s sophisticated system from only the image, however we can find several Google’s services, such as Yotube, Google-analysis, Google map, etc) on same servers. Then I imagined that many services of Google leverage their common middleware/infrastructure, or the IP addresses are just entry points.

Akamai, The net is vast and infinite

Last one is related to Akamai. It looks their internal system is more complex than other giants such as Google and Amazon. Akamai is one of biggest Contents Delivery Network companies. Yellow node is first querying domain name, and the image shows they have a lot of customer.

akamai-apple島

Additionally, there may be “Apple Island” in Akamai network. It seems independent from other Akamai network that is used by other customers. There are nodes of us-courier.push-apple.com.akadns.net., service1.ess.apple.com.akadns.net. at center point of the image (but other nodes hide them), and they are linked a lot of IP addresses. For example, it’s monitored at my home network that us-courier.push-apple.com.akadns.net. returned 440 IP addresses.

You can find full size image from here here. However please note the image file is 37.5MB PNG, if your PC don’t have enough resources, it would be crashed.

DNS問い合わせの可視化

DNS問い合わせの可視化

全体像

最近、データをまとめたり可視化したりしてその性質を調べる探索的データ分析()にはまっています。と、同時にネットワーク分析にもちょっと手を出しており、その2つの派生物としてドメイン名問い合わせの結果を可視化してみました。

これを読んでいる人にはもはや説明の必要はないと思いますが、一応書いておくと、世の中のwww.google.comやwww.amazon.co.jpのようなドメイン名はサーバの場所を直接示しているわけではなく、「この名前を持っているサーバのIPアドレスはなんですか?」というのをDNSサーバという別のサーバに問い合わせることで目的のサーバのIPアドレスを教えてもらい、その後目的のサーバへ接続します。以前は正引き(ドメイン名からIPアドレスを問い合わせる)と逆引き(IPアドレスからドメイン名を問い合わせる)が対称構造になるように設定するのが主流でしたが、最近は負荷軽減などのテクニックが複雑化し、単純ではない構造になっており利用者からは実態がよくわからなくなっています。

そこでDNSの問い合わせとその結果から何か見えるものがあるのではと思い、試しに可視化してみました。可視化には自宅のネットワークを24時間監視したデータを使いました。問い合わせ応答数(全レコード数)は75,098件、トラフィック分析には自作ツール、可視化はベタにgraphvizです。今どき感をだすためにJavaScriptの描画ライブラリも検討しましたが、arbor.jsとかノード数が数百に達するとあっというまにブラウザが真っ赤になって憤死するので断念しました。

windows.microsoft.comの例

まずは一番わかりやすいケースです。黄色ノードがCNAMEの問い合わせドメイン名(ブラウザなどで最初に問い合わせたドメイン名)、黄色から点線でつながっている赤ノードがCNAMEの問い合わせ結果、そして緑ノードが実際のIPアドレスになります。ここでは、

  1. 何かのプログラムがwindows.microsoft.comのIPアドレスを問い合わせた
  2. windows.microsoft.comの実態はorigin.windows.microsoft.com.akadns.netというホストですよ、と教えられた
  3. さらにorigin.windows.microsoft.com.akadns.netのIPアドレスを問い合わせてみた
  4. origin.windows.microsoft.com.akadns.netのIPアドレスは65.52.103.234ですよ、と教えられた
  5. 何かのプログラムは65.52.103.234に接続する

という一連の流れが起きたと考えられます。(かなりざっくりですがそこはご愛嬌で)

ad.yahoo.co.jpの例

次は一つのドメイン名に対して、複数のIPアドレスが応答されている場合です。ここでは一度にこの応答が返されたのか順次返されたのかまでは追いかけていませんが、複数の宛先サーバを用意することで負荷を分散させるためによく使われている手法かと思います。

nikkei.co.jpの例

逆のケースも有ります。複数のドメイン名に対して一つのIPアドレスだけが割り当てられている場合です。これは複数のサービスがあるものの負荷があまり大きくないので、一つのサーバに役割を兼任させているのではないかと推測されます。

dropbox.comの例

そろそろごつい感じの例も見て行きたいと思います。Dropboxでは問い合わせる際にはclientXX.dropbox.comというドメイン名で最初に問い合わせますが、これが一度client.dropbox.comに集約され、client.v.dropbox.comに向けられた上で、そこから多くのIPアドレスを返してきています。これは後々の事を考えて最初の問い合わせ元を分散させておいたのかな…と妄想しますが、実際のところどうなのかはよくわかりません。あとさりげなくclient-lb.dropbox.comというロードバランサーらしきものも見えてはいます。

couldfront.netの例

徐々に激しくなってきたこちらはcloudfront.net関連です。AmazonがAWSで提供しているコンテンツ配信ネットワークになります。いくつかのサイト(nikkei.comtogetter.comalc.co.jpevernote.com)が入口となっていますが、実態となるIPアドレスはとても数が多く、さらにドメイン名から入り乱れてIPアドレスへつながっていることから、複数サイト間をまたがっている内部構造になっていることが伺えます。

google関連

そろそろ何が起きているのかよくわからなくなってきました。こちらはgoogleに関連したドメイン名(の一部)になっています。これだけでgoogleの海千山千なシステムを読み解くのは難しいですが、少なくともGoogle内部の複数のサービス(youtube、google-analysis、google map)などが同じサーバをまたがっていることがわかります。そのため、多くのサービスは共通のミドルウェアのようなインフラの上に相乗りしている状態か、あるいはこのIPアドレスは全部ロードバランサみたいな、ガワだけ見えている状態なのかもしれません。

akanai関連。ネットは広大だわ

トリを飾るのはインターネット界の裏に君臨するAkamaiです。見よ、この圧倒的なカオス! …というほどでもないかもしれませんが、他のgoogleやamazonといった大規模サイトとくらべても、内部構造が複雑になっていることが伺えます。Akamaiは名前こそあまり表に出てきませんが、多数のWebサイト・サービスのCDN(Contents Delivery Network)を世界最大規模で請け負っている企業です。(詳しい解説はぜひこちらを御覧ください)

黄色いノードが一番最初の問い合わせドメイン名なので、ざっくり言うと黄色いノードの多さにあわせていろいろなサービスが乗っかっているのがわかります。また、どこかのドメイン名に集約されてから一様に分配されるというわけではなく、複数の全く違う入り口から一つのIPアドレスにたどり着いているケースがとても多いようです。これはどのISPを使っているかによって見え方が違うらしいのですが、例えばこの例ではリクルートと思われるドメイン名とLinkedInと思われるドメイン名が一つのIPアドレスに紐付いていました。

akamai-apple島

また、あくまで推測ですが、同じAkamaiでもApple専用の島というものがあるようです。これらは他のWebサービスとは独立した専用のサーバ郡がわりあてられているようです。中心部が完全に潰れていますが、それぞれCNAMEの解決先はus-courier.push-apple.com.akadns.net.service1.ess.apple.com.akadns.net.などとなっており、そこから多数のIPアドレスに分配されています。us-courier.push-apple.com.akadns.net.にいたっては440個のIPアドレスと紐付けられているのを観測しました。

フルサイズの絵はこちらからダウンロードできますが、37.5MBのPNGという貧弱なPCだと泡を吹きそうになるサイズとなっているで、閲覧の際は十分ご注意ください。

参考文献

Swarm: 高速なネットワークトラフィック解析ライブラリ

Swarm: 高速なネットワークトラフィック解析ライブラリ

C++で動作するネットワークトラフィック解析ライブラリを作成しました。(github)提供している機能はプログラミング初心者がlibpcapを使ってパケットの構造を調べるようなコードでやっていることとあまり大差はありませんが、毎回同じようなプロトコル解析処理を個別に作成するのが煩わしかったり、既存のリッチなプロトコル解析ツールだとプログラム解析後のデータ処理が面倒・あるいは性能が出にくいという課題があったりなどの理由から、自分で再利用可能なライブラリとして作成していました。

パケットからプロトコルを解釈し、プログラマが利用しやすい形で結果を提供します。集計・分析もC++のコードで記述できるため、高速な実ネットワークトラフィックのリアルタイム分析も可能です。例えば、ネットワークトラフィックに含まれるDNSの問い合わせのドメイン名を全て出力するには、以下のようなコードで記述することができます。

#include <swarm.h>
#include <iostream>

// コールバック関数を持つswarm::Handlerクラスを継承させる
class DnsHandler : public swarm::Handler { 
  // コールバック関数
  void recv (swarm::ev_id ev, const swarm::Property &p) {
    // DNS問い合わせに含まれるドメイン名を表示
    std::cout << p.param ("dns.qd_name")->repr () << std::endl;
  }
};

int main () {
  // デコーダを作成
  swarm::NetDec * nd = new swarm::NetDec (); 
  // DNSパケットが到着した場合に、DnsHandlerのコールバックを呼び出す設定
  nd->set_handler ("dns.packet", new DnsHandler ()); 

  // ファイルから読み込む場合
  // swarm::NetCap * nc = new swarm::CapPcapFile ("./my-dump.pcap");

  // NIC(eth0)から実トラフィックをキャプチャ
  swarm::NetCap * nc = new swarm::CapPcapDev ("eth0"); 

  // デコーダとパケットキャプチャを接続
  nc->bind_netdec (nd); 
  // 解析処理スタート
  nc->start ();
}

特徴

  • zero-copyベースの解析処理: 到着したパケットデータに対して基本的にメモリコピーをしないことにより、高速な解析処理を実現します。
  • シンプルなAPI: 解析結果の参照では実パケットに含まれる生のバイナリデータにアクセスすることもできますし、それぞれのフィールドを適切な表示形式へ変換してくれる機能も実装されています。また、パケット到着などのイベントによって呼び出されるコールバックだけでなく、タイマーで駆動するコールバックも用意されているため、
  • 拡張性の高い構造: 解析するプロトコル間で依存関係の低い設計になっており、ライブラリに新しいプロトコルを組み込むのが容易になっています。また、ライブラリ外でも自作したプロトコル解析モジュールを自由に組み込むことができます(サンプル

今後のToDo

  • TCPのセッション管理・ペイロード再構築
  • TCP上で動作するプロトコル(HTTP, HTTPS, IRCなど)のサポート
    • マルチスレッドによるトラフィック解析処理の並列化

URL