前編:Elasticsearchの機械学習分析による類似ドメイン検知
2022年08月08日 月曜日
CONTENTS
Elasticsearchの機械学習機能
今回はElasticsearchの教師あり機械学習(ML)機能とそれを使った類似ドメイン検知についてご紹介します。
Elasticsearchは無償(一部機能を除く)で利用できるデータ分析・可視化ツールです。一般的にはログやテキストデータの保存や検索、可視化などで使われることが多いでしょう。そのElasticsearchでML機能が使えることはご存知でしょうか。
ElasticsearchのML機能は、2016年に Elastic社がPrelert社を買収したことで、バージョン6.1から追加されました。有償なのですが、試用ライセンスで30日間試すことが可能です。今回も試用ライセンスで検証しています。
MLには教師なし型と教師あり型があります。Elasticsearchでは当初は教師なし型のみでしたが、教師あり型が後から追加されました。なお Elasticsearchでは教師なし型のML機能を異常検知(Anomaly Detections)、教師あり型をデータフレーム分析(Dataframe Analysis)と呼びます。
また、教師なし型の分析手法にも大きく2つあり、時系列分析(Time Series Analysis)と、集合分析(Population Analysis)があります。時系列分析はその名の通り時間軸の比較で異常を検知するものです。一方、集合分析はその時点において、特定の要素が他とくらべてどうか、つまり集合としての異常を検知します。
一方のデータフレーム分析の方ですが、分析手法は3つあり、外れ値検出(Outlier)、回帰(Regression)、分類(Classificaton)です。これらは昔からある呼び方なので説明は不要だと思います。
以下の図はこれらを整理したものです。
今回行う教師あり型のデータフレーム分析(分類)の手順は、教師データの作成、学習、テスト、モデル作成という、scikit-learnなどを使った一般的な手順と大きな違いはありません。
一方、異常検知は少し独特ですが、こちらの方がログなどの時系列データを扱うことの多い Elasticsearchの特徴にマッチしているとおもいます。この教師なし型の時系列分析、集合分析、どちらも非常に面白い機能なので、また機会があれば紹介します。
類似ドメイン検知とは
皆さんは iij.ad.jp や microsoft.com、debian.org などのような、いわゆるドメイン名が、全世界で何件ぐらいレジストリに登録されているかご存知でしょうか。
Verisign社のレポート Domain Name Industry Brief (DNIB) によると、2021年末時点で約3億4100万件のドメイン名が登録されているそうです。
なお、2012年末時点では2億5200万件とのことなので、9年で約9000万件が新たに登録されたことになります。1日あたりなんと 27000件です。
しかし、これらの中にはフィッシングなどのサイバー攻撃や転売などが目的で登録されるものも多数あります。例えば、金融機関を狙ったフィッシングサイトなどで本物そっくりのドメイン名を使う、などは昔からよくある手口です。
また不正利用とは言えないまでも、自社と似たドメイン名が、関係ない他社や個人に取得されていると、どのような使われ方をされるのか気になりますね。
このような、ある特定のドメインに似たドメインを類似ドメインと呼びますが、類似ドメインが誰かに登録されたことを早期に発見できれば、使われ方をウォッチすることもできますし、不正利用されそうな場合に対策が打ちやすくなるでしょう。
類似ドメイン登録検知の仕組み
まず考える必要があるのは、どのような教師データを用意するかです。今回の場合、様々なドメインのリストを用意し、基準となるドメインに似ている、似ていないのフラグを立てていきます。対象が iij.ad.jp だとすると、例えばこんな感じです。
domain, flag, 特徴量1, 特徴量2, 特徴量3..... iij.ad.jp, Y, 0, 0, 1 iii.ad.jp, Y, 2, 0, 0 iij.co.jp, Y, 1, 0, 1 microsoft.com, N, 0, 0, 2 debian.org, N, 0, 0, 0 ・ ・ ・
Nは類似ドメインではない、Yは類似ドメインであるという意味で、特徴量は機械学習に学習させる特徴(ベクトル)です。これらをたくさん学習させることで、類似ドメインの特徴を機械が覚えていきます。
ところで類似ドメイン、つまりドメインが似ているとはどういうことでしょうか。例えば example.jp について考えてみます。
example.co.jp は example.jp の類似ドメインでしょうか。これは似てますね。example.com はどうでしょうか。example は同じなので似てると言ってもいいでしょう。
では exampplee.jp は? Aさんは似ていると言い、Bさんは似てないと言うかもしれません。似ている、似ていないは感覚の問題で、厳密な定義は無いからです。結局、類似ドメインかどうかの判断は主観によるところも大きいということです。
かと言ってこれを、exampleの eが2文字で xとaとmとpとlが一文字づつ、exaという並びが先頭にあって、、などと細かく定義していくのであれば、MLを使う意味がなくなります。単にプログラム化すればいいからです。
MLはそうではなく、ベクトルによって位置がなんとなく近い、なにか似ているという、ある種、人間が持つ感覚を機械に持たせ、判断させることだと言えます。つまり教師データには作成者の感覚が大なり小なり反映されるということです。そして、それを学習した機械が作成者に似た感覚を持つようになる、、、そう考えると面白いですね。
教師データの作成
さきほどベクトルが出てきましたが、教師データにはベクトルを測るために特徴量が必要です。類似ドメイン検知用に教師データを作る場合、どのような特徴量があればいいでしょうか。
ドメイン名は、a-zまでのアルファベットと0-9の数字、ドットおよびハイフンで構成されます(今回は日本語ドメインなどは除きます)。よって、最も単純な考え方は、各文字の出現した回数をカウントすることです。たとえば、iij.ad.jp であれば、iとjとドットが2、aとdとpが1、その他の文字や記号は出現しないので0です。
その場合の教師データは以下のような形式になります。1行目はヘッダです。ShellやPythonなどを使えば簡単に作成できると思います。
domain,flag,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,n0,n1,n2,n3,n4,n5,n6,n7,n8,n9,haifun,dot iij.ad.jp, Y,1,0,0,1,0,0,0,0,2,2,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2 iii.ad.jp, Y,1,0,0,1,0,0,0,0,3,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2 iij.co.jp, Y,0,0,1,0,0,0,0,0,2,2,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2 microsoft.com, N,0,0,2,0,0,1,0,0,1,0,0,0,2,0,3,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 debian.org, N,1,1,0,1,1,0,1,0,1,0,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
特徴量が 26+10+2で38種類。つまりベクトルでいうと、38次元ベクトルの教師データです。これをたくさん並べたものを機械に学習させると、同じような文字が使われているドメインをベクトルが近いと判断し、判別できるようになるというわけです。
256次元ベクトルの教師データ
ただし、この教師データには一つ問題があります。この方法では、単純に文字や記号が何回出現したかしか見ていません。つまり、文字がどのように並んでいても、文字の出現数が同じなら似ていると判断します。たとえば、iij.ad.jp と daiji.jp を似ていると判断してしまいます。よって検知精度を上げるには文字の出現数だけでなく、文字の並びを情報として持つ必要があります。
では文字の並びをどうやって判断するか。いろいろやり方はあると思いますが、単純な方法は、2文字の並びを特徴量とすることです。つまり、
aa,ab,ac,ad,ae,af,……………..
のように、ドメイン名を構成する全ての文字と記号の組み合わせを特徴量として持たせます。それらが何回出現したかによって、文字の並びまで考慮した判別ができるはずです。
ただしこの方法も、問題とまでは言えませんが、課題があります。特徴量の数が増えすぎてしまうことです。38種類同士のすべての組み合わせを持つと、38×38で 1444次元もの特徴量になります。特徴量が無駄に多すぎるといろいろと問題なので、もう少し減らしたいところです。
そこでもう少しスマートで効率的な方法として今回採用したのが、以下で公開されている、文字をアスキーコード化して半分ずらすやり方です。これにより、よりすくない特徴量、つまり00からffの256次元で全ての並びを学習させることができます。
Classification of URL bitstreams using bag of bytes
詳細は上記の論文や弊社IIRを参照頂きたいのですが、イメージとしては、文字の後半分と次の文字の前半分をつないで、一つの特徴量にするという感じです。そうすることで、文字の並びをカウントできます。
この方法で作成した教師データは以下のような形式になります。1行目はヘッダです。
domain,flag,00,01,02,03,04,05,06,07,08,09,0a,0b,0c,0d,0e,0f,10,11,12,13,14,15,16,17,18,19,1a,1b,1c,1d,1e,1f,20,21,22,23,24,25,26,27,28,29,2a,2b,2c,2d,2e,2f,30,31,32,33,34,35,36,37,38,39,3a,3b,3c,3d,3e,3f,40,41,42,43,44,45,46,47,48,49,4a,4b,4c,4d,4e,4f,50,51,52,53,54,55,56,57,58,59,5a,5b,5c,5d,5e,5f,60,61,62,63,64,65,66,67,68,69,6a,6b,6c,6d,6e,6f,70,71,72,73,74,75,76,77,78,79,7a,7b,7c,7d,7e,7f,80,81,82,83,84,85,86,87,88,89,8a,8b,8c,8d,8e,8f,90,91,92,93,94,95,96,97,98,99,9a,9b,9c,9d,9e,9f,a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,aa,ab,ac,ad,ae,af,b0,b1,b2,b3,b4,b5,b6,b7,b8,b9,ba,bb,bc,bd,be,bf,c0,c1,c2,c3,c4,c5,c6,c7,c8,c9,ca,cb,cc,cd,ce,cf,d0,d1,d2,d3,d4,d5,d6,d7,d8,d9,da,db,dc,dd,de,df,e0,e1,e2,e3,e4,e5,e6,e7,e8,e9,ea,eb,ec,ed,ee,ef,f0,f1,f2,f3,f4,f5,f6,f7,f8,f9,fa,fb,fc,fd,fe,ff iij.ad.jp, Y,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,2,2,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 iii.ad.jp, Y,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,3,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 iij.co.jp, Y,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,2,2,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0 microsoft.com, N,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,2,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,1,1,0,1,0,0,0,2,0,3,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,1,0,0,0,0,0,0,0,0 debian.org, N,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,1,0,1,1,0,1,0,1,0,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0
学習に使用するドメイン名は実在のドメインでも架空のものでも、どちらでもかまいません。
上はあくまでサンプルなので、どのようなドメイン名を教師データに使えばよいか、色々と試してみる必要があります。数もいくつ必要とかは一概には言えませんが、数十種類あれば精度の高いモデルを作ることができました。こちらも色々試してみてください。
長くなりましたので今回はここまでとします。次回は、作成した教師データを使って実際にElasticsearchを使って機械学習分析を行っていきます。