この記事では、AIを作ってみよう:Webセキュリティ(3/4) で作ったAIに可視化の要素を加えてみます。
結果をグラフで見ることができれば、状況がよく分かるようになります。
プログラムをコピペ
前回のプログラムの後ろに絵画するパートを書き加えました。全てをコピペして、「webaccess_grouping_plot.py」というファイル名で保存してください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
import pandas as pd import numpy as np import csv import re import copy from sklearn.cluster import KMeans from sklearn.preprocessing import StandardScaler from sklearn.preprocessing import MinMaxScaler CLUSTERS = 8 INPUT_FILE = 'access_log' CSV_FILE = 'access_log.csv' RESULT_FILE = 'access_log_result.csv' PLT_FILE = 'access_log_plot.jpg' fr = open(INPUT_FILE) fw = open(CSV_FILE, 'w') line = fr.readline() while line: line=line.replace(',','') fline = re.sub(r'^(\S+) (\S+) (\S+) \[([^\]]+)\] "([A-Z]+) ([^ "]+)? HTTP/[0-9.]+" ([0-9]{3}) ([0-9]+|-) "([^\"]*)" "([^\"]*)"', r'\1,\2,\3,\4,\5,\6,\7,\8,\9,\10', line) fw.write(fline) line = fr.readline() fr.close() fw.close() # load csv with header all_data = pd.read_csv(CSV_FILE, header=None) all_data.columns = ['s-ip','s-user','auth-user','date','action','resource','status','bytes','s-url','s-agent'] fit_data = copy.copy(all_data) fit_data.drop(['s-user','auth-user','date','action'], axis=1) # charactors to numbers for i in range(len(all_data)): for col in all_data.columns: astr = all_data[col][i] fit_data[col][i] = astr if str(astr).isdecimal() else sum(int(ord(c)) for c in astr) # AI analysis bunrui = KMeans(n_clusters=CLUSTERS).fit_predict(fit_data) all_data['bunrui'] = bunrui[:] cnt = all_data['bunrui'].value_counts() print(cnt) all_data.to_csv(RESULT_FILE,index=False) ###●↓ここから追記●### # plot import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D COLORS = ['b', 'g', 'c', 'y', 'k', 'b', 'g', 'red', 'c', 'y'] fig = plt.figure(dpi=150) # plot place ax = fig.add_subplot(111,projection='3d') # graph space on place ax.set_xlabel('s-ip') ax.set_ylabel('resource') ax.set_zlabel('bytes') X = fit_data['s-ip'] Y = fit_data['resource'] Z = fit_data['bytes'] for i in range(len(bunrui)): j = bunrui[i] % 10 cl = COLORS[j] plt.scatter(X[i], Y[i], zs=Z[i], s=10, c=cl) plt.savefig(PLT_FILE) plt.show() |
保存できたでしょうか。
追加部分は、matplotlibというライブラリを用いて、グラフを絵画しています。
何の働きがあるかは見たほうが早いので、早速実行してみましょう。
実行
使うログや実行方法は前回と同じaccess_logです。
コマンド実行ウィンドウを開いて、「python webaccess_grouping_plot.py」と打ってください。
~.jpgというファイルができるので開いて見てください。
横軸が「アクセス元IPアドレス」、奥行きが「アクセスされたURL文字列」、縦軸が「Webサーバが返信した通信の大きさ」です。
1つの点が1行のログを表し、色はグループを表しています。
だいたいのログが下のほうに集まっていますね。これらのログは「特徴が似かよっている」と判断します。
これに対して、1つ2つ離れたものがありますね。
特に赤い1点はどれよりも離れていて目立ちます。実はこれが前回示した攻撃ログなんです。攻撃アクセスは、通常のログとは少し違うことが多く、例えばアクセス元がいつもと違う国だったり、通信サイズが異なったりします。(今回は筆者が分かり易い数値にしましたが。)
AIはこのように数値的に近いものをグルーピングするので、我々としてはグループから外れているもの=いつもと違うもの=何か怪しいもの、と解釈すればいいわけです。
可視化するととても分かり易いですね。
AIはこれを3次元でなく多次元で見分けています。人間にはできませんね。
あなたのWebサーバのaccess_logも、このプログラムでそのまま分析できますので、実行してみてください。