IIJのインシデント調査システム

熊坂駿吾氏(以下、熊坂):IIJの熊坂から、社内で作成しているインシデント調査システムに関して紹介いたします。「インシデント調査システムが内製すぎる件」というところで、IIJの中で作成しているCHAGE(チャゲ)を紹介します。

まず私は2015年にIIJに新卒入社しまして、2018年度からSOCで業務を行っています。アナリスト的なことは詳しくやっていなくて、どちらかというとアナリストたちが業務を行うための環境の整備をしています。

具体的には、Windowsのメンテナンスをしたり、社内で使うツールの開発だったり、縁の下の力持ちと呼んでもらえたらうれしいな、という立場で活動しています。本日はその中の、社内で作っているツール「CHAGE」を紹介します。

OSINTを支援するシステム「CHAGE」

まず「CHAGEとは」というところなんですが、OSINTを支援するシステムです。OSINTについて、検索してみると「公開情報を紐づけて、表現されていない事実を導き出す調査手法」と説明があるんですが、これだとちょっとよくわからなかったので、簡単にまとめてみました。

例えば、とある人が「☆☆ってなんですか?」とBさんに聞くと、Bさんが「☆☆は〇〇です」と1つの情報だけを返してきます。ただ、これだけだと、Bさんが本当のことを言っているのか嘘のことを言っているのか、あるいは他に何か隠されたことがあるんじゃないかなどが判断できません。なので、Bさんだけではなくて、Yさん、Gさんにも情報を聞きます。

このとき、BさんとYさんとGさんで言っている情報がバラバラで関係がないように感じます。しかし、それらの共通するところを紐づけていくことで、BさんYさんGさんの誰もが言っていない☆☆は△△、☆☆は□□と、“表現されていない事実”を導き出せます。

僕より少し上の世代の方ですと、たぶん「マジカルバナナ」みたいなものをイメージしてもらえばわかりやすいかと思うんです。簡単に言うと、連想ゲームをやっているだけなんですね。この連想ゲームをしていくことで、誰も言っていない情報を導き出せる調査手法を「OSINT」と言います。

ツリー表示にしてアナリストが使いやすいように

CHAGEでは、世界中の情報をOSINTで調査はできなくて、ドメインやIPアドレスのような、インターネットで活用するものを主に調査しています。それらを使うと何がうれしいのかというと、例えば事前に次の攻撃元を予想できちゃいます。

CHAGEにIPアドレスの情報を入れると、それらに紐づく情報をどんどん検索してくれます。この結果、IPアドレスAをただ調べただけだと、ドメインAという情報しかわかりませんが、CHAGEに入れることによって、まったく関係のないドメインBを導き出せます。

このCHAGEを使うことによって、IIJのSOCのアナリストは、次のステップとして、攻撃元IPアドレスAに関連するドメインBにも目を光らせておくことができます。ただこの表示は、1,000件ぐらい続くとすごく見づらいものになってくるんですよ。なので、CHAGEはただ情報を調べることを支援するだけではなくて、情報を見やすくすることも手伝っています。

どういうことかというと、ツリー表示にしているんですね。左側が、先ほどの順番にたどって行く例と同じ表になっているんですが、その表に関連する情報を1つの丸にまとめてツリー表示にできます。これによって、情報量がどんどん増えたとしても、アナリストがツリーを見て、攻撃について判断できます。

先ほどのIPアドレスAに関する調査をツリーにすると、このようなイメージになります。IPアドレスAが一番左にあって、それにドメインAが関連づいていて、それらから関係する担当者の氏名や代表の電話番号、また関係していくドメインBをどんどん追いかけていくのが、視覚的に簡単にわかりやすく出てきます。

数十万件の調査が20秒程度でできる

詳しい方だとちょっと気づいちゃうかもしれないんですが、「これはdigだったりとかwhoisを組み合わせただけではないでしょうか?」……ーというところ。そう思っている方がいたら、本当にそのとおりなんですよ。ただし、数十万件を20秒程度で行ってくれているツールです。もし僕が(手動で)やるんだったら、20秒だったらたぶん4件、がんばったら5件ぐらいはいけるかと思うんです。詳しい人とかだと10件とかいけるんですかね?

でも残念ながら、数十万件を20秒でできる人はなかなかいないんじゃないでしょうか。CHAGEでは、人ではなかなかできない時間で、数十万件の調査を行えます。実際に今細かくいろいろ出していますが、これが、CHAGEが実際に調査してきた数十万件を表したものです。

この画面でCHAGEを見れるんですが、残念ながら、人がこれをずっと眺めて情報を精査していくのはとても大変なことです。なので、実際にアナリストが見ている画面は、もうちょっと情報を非表示などにして、いる情報・いらない情報、あとは重要な情報を整理しています。

Google検索に比べて遅い理由

ところでみなさん、この数十万件を20秒程度というのは遅いと感じた方はいますかね? 実はみなさん、もっと速いシステムをふだん使っているんですよ。Googleなんですけどね。Googleで「IIJ」と調べたときの速度は、だいたい2.5千万件を0.36秒ぐらいでやっているんですよ。10万件あたりで直すと0.0014秒ぐらいです。

CHAGEと比較をしてみると、検索エンジンでは10万件を0.0014秒でやっていますが、CHAGEは10秒程度かかってしまうんですよ。ただ、ごめんなさい。これでCHAGEが遅いと思わないでください。CHAGEは、検索エンジンと仕組みが大きく違います。

ざっくり説明すると、検索エンジンはデータベースという情報を溜めておくところが存在して、事前にインターネットから情報を収集しておきます。検索エンジンで何かを調べたときは、事前に収集したところからの情報を返しているので、10万件あたり0.0014秒ぐらいの速度を出してくれています。

CHAGEの場合はどうなのかというところなんですが、出てくるものは同じようなかたちです。CHAGEがあって、データを溜めておくところがあって、情報収集元のインターネットが存在する。ただCHAGEは事前にインターネットから情報を集めることがとても難しいです。なぜなら、CHAGEで調べる攻撃は未知のものだったり、どこかでまとまっていない情報である可能性が高いからです。

なので、残念ながらCHAGEでは事前に情報を集めることができず、CHAGEに検索を入れるたびにインターネットから情報を集めています。実際としてはこんなひどいことにならないように、CHAGEに情報をキャッシュできるようにもしているのですが、残念ながら先ほど伝えたとおり、調べる情報は未知なものが多いので、キャッシュが返ってくる可能性もとても低い状態になってしまっています。

検索エンジンと比べるとこの部分がすごいハンデなんですよ。このハンデがどれくらいかというところで、僕のMacBookで実際Googleに検索を行ってみました。名前解決を行った時間ですね。だいたい1件あたり0.196秒ぐらい。これを10万件分数えると1.9万秒、時間に直すと5.2時間ぐらいになるんです。

先ほどハンデがあると言った部分、これは1件ずつ順番にやっては5.2時間ぐらいかかってしまうタスク量になっています。CHAGEにはこの5.2時間をどうにかして10秒で終わらせる技術が詰まっているすばらしい仕組みになっています。Googleよりはだいぶ遅いですけど、それはCHAGEが集めているデータは早く集められないという特性を持っているので、あれだけの時間差が生まれています。

5.2時間をどうやって10秒で終わらせているか

じゃあ5.2時間をどうやって10秒で終わらせているかという話なんですが、これはとても簡単なお話です。例えば、5.2時間かかる夏休みの宿題が「あと3時間後に提出だよ」となったときに、子ども1人でやっても終わらない。さてどうするか。じゃあお兄ちゃんに手伝ってもらって、3時間以内で終わらせるようにしましょう。お兄ちゃんと2人でやると、5.2時間あったものが2.6時間になります。

でも実は宿題の提出があと1時間でした。「どうしよう。ママ! パパ! 助けて!」となったときには、じゃあママとパパにも手伝ってもらって、5時間かかる宿題を1時間2分で終わらましょう。この“終わらなそうならみんなでがんばってやる”というのがコンピューターの世界にも存在します。コンピューターの世界では、この方式を並列処理と言ったりします。

CHAGEでも、同じ話を使っています。5時間分の仕事があるんだったら、この仕事を並列で実行していこう。だいたい2,000並列ぐらいだすると9.5秒ぐらいで終わるので、10万件あたり10秒で返すというところが見えてきます。2,000並列ぐらいCHAGEでできたら、終わりそうな話に見えてくるんですよ。

情報同士の関係性を築いていくと遅くなる

ただ、世の中そんなに甘くなかったです。CHAGEは関係する情報を見つけながらどんどん検索していくので、検索中に情報同士の関係性を築いていく必要が出てきます。いきなり関係のない情報をポンと検索することはできなくて、左から順番にこの情報に関係するもの、この情報に関係するものとたどっていく必要があります。

なのでIPアドレスAを検索し終わったらドメインAを検索できて、ドメインAの検索が終わったら次の担当者氏名や代表電話番号に関係する情報を検索できるような分け方になってきます。最初の検索元を0層として考えると、次が1層、その次が2層、どんどん層が深くなっていくようなイメージです。

この例の場合、0層で検索できる対象が1件だけになってきます。1層で検索できる対象は2件、2層で検索できる対象は4件。これは関係性を築くために順番に検索する必要があるので、残念ながら層が分かれていると、同時に検索できないんですよ。なので例えば2層の場合、最大4並列しかできない事実がわかってきます。

こうなってくると、さっきの「2,000並列ぐらいできたら10秒ぐらいで終わるね」という話がなかなか難しそうな感じがしてきます。例えば1層で2,000件返してくれるような検索結果であれば、10秒ぐらいで終わるかもしれないんですが、1層で2件しか返してこない、2層で4件しか返してこない。こんなツリーになってしまうと、検索の時間が10時間になったりとか、どんどん長くかかってしまう可能性が考えられます。

検索内容によって検索の時間が変わってしまうようなシステムは、残念ながらSOCの本番で使っていけるようなシステムとして採用できません。その他にもCHAGEがツリーをより高速に検索するための問題はさまざまです。残念ながらこれらの問題をすべて解決してくれるような既成のリレーショナルデータベースシステムがどこにも見当たらなかったんですよ。

ではDBも内製だ

じゃあどうするかというところで、「よろしい。ではDBも内製だ」ということになりました。CHAGEではデータベースにASKS Frameworkというものを開発して、問い合わせをたくさんできる仕組みを提供しています。

この問い合わせをたくさんできる仕組みを用いることで、先ほどの並列が4件しかできない問題を2,000件できるようにして、10秒でデータを返せるようにできたりとか、またその他の工夫によって、関係するデータをより効率的に返せるような仕組みを用意しています。今日ASKSのことに関して細かくいろいろお伝えしたいんですが、残念ながら時間が限られているので、CHAGEとASKSの続きはWebページでみなさんに紹介したいと思います。

IIJ Engineers Blogで、CHAGEに関して情報をまとめているので、みなさんぜひこちらもご覧ください。

ところでみなさん、「続きはWebで」という表現を最近聞かないと思いませんかね? これは今までの情報媒体はインターネットが主体ではなかったというのがあるんですが、最近はインターネットが主体になって、CMはそこに導く手段であるという立ち位置に変わってきたから、続きがWebじゃなくて主体がWebになってきたという話で、「続きはWebで」を言わなくなってきているらしいです。

なのでナウいヤング風(笑)にお伝えしますと、「IIJ CHAGEで、検索 検索!!」というところです。ぜひGoogleで「IIJ CHAGE」を調べてみてください。よろしくお願いします。以上です。