您好,登錄后才能下訂單哦!
數據來源:http://www.schonlau.net/網頁中的Masquerading User Data。其中包含50個用戶的操作日志,每個日志包含1500條操作命令,前面5000條是正常的操作,后面的10000條日志中隨即包含有異常操作。具體參考《Web安全機器學習入門》
本來想自己寫的,但是網上資料太多,就沒必要寫了。看下其他大佬寫過的就行了:
這兩個看了,基本上就沒啥問題了
Step 1:隨便選擇一個user日志,里面每行代表一個命令。每150個命令弄成一個操作序列,保存在列表之中
def load_user(filename):
most_cmd = []
mini_cmd = []
cmd_list = []
cmd_seq = []
# 獲取操作序列
with open(filename, 'r', encoding="utf-8") as f:
cmd = f.readline()
temp = []
cnt = 0
while(cmd):
cmd_list.append(cmd.strip('\n'))
temp.append(cmd.strip('\n'))
cnt = cnt + 1
if(cnt == 150): # 這里不按照書上的分,我這里按照150個命令為一個序列,剛好和標簽對上號,因為標簽只有100個值
cmd_seq.append(temp)
cnt = 0
temp = []
cmd = f.readline()
Step 2:然后將user日志中所有的命令進行統計,統計出它們最頻繁的50個命令,以及最不頻繁的50個命令
# 獲取最頻繁的前50個命令,獲取最不頻繁的前50個命令
fdist = sorted(FreqDist(cmd_list).items(),key = operator.itemgetter(1), reverse = True) # 按照出現頻率排序
most_cmd = [ item[0] for item in fdist[:50]]
mini_cmd = [ item[0] for item in fdist[-50:]]
Step 3:特征化。在 Step 1 的操作序列上,我們按一個操作系列為單元,①統計其中不重復的命令個數、②最頻繁的10個命令、③最不頻繁的10個命令
user_feature = []
for cmd_list in user_cmd_list:
# 獲取每個序列不重復命令的個數
seq_len = len(set(cmd_list))
# 將每個序列按照出現頻率由高到低的排列命令
fdist = sorted(FreqDist(cmd_list).items(), key=operator.itemgetter(1), reverse=True)
seq_freq = [item[0] for item in fdist]
# 獲取最頻繁和最不頻繁的前10個命令
f2 = seq_freq[:10]
f3 = seq_freq[-10:]
Step 4:因為KNN只能接收數值類型輸入。在 Step 4 中,②和③都是字符串的命令,我們需要將其標量化。標量化的方式:統計最頻繁使用的50個命令和最不頻繁使用的50個命令計算重合程度
# 計算重合度
f2 = len(set(f2) & set(user_max_freq))
f3 = len(set(f3) & set(user_min_freq))
# 合并特征:①每個序列不重復的命令個數;②每個序列最頻繁的前10個命令和user中最頻繁的50個命令重合度;
# ③每個序列最不頻繁的前10個命令和user中最不頻繁的前50個命令重合度;
user_feature.append([seq_len, f2, f3])
from nltk.probability import FreqDist # 統計命令出現頻率
import operator
from sklearn.neighbors import KNeighborsClassifier
import numpy as np
def load_user(filename):
most_cmd = []
mini_cmd = []
cmd_list = []
cmd_seq = []
# 獲取操作序列
with open(filename, 'r', encoding="utf-8") as f:
cmd = f.readline()
temp = []
cnt = 0
while(cmd):
cmd_list.append(cmd.strip('\n'))
temp.append(cmd.strip('\n'))
cnt = cnt + 1
if(cnt == 150): # 這里不按照書上的分,我這里按照150個命令為一個序列,剛好和標簽對上號,因為標簽只有100個值
cmd_seq.append(temp)
cnt = 0
temp = []
cmd = f.readline()
# 獲取最頻繁的前50個命令,獲取最不頻繁的前50個命令
fdist = sorted(FreqDist(cmd_list).items(),key = operator.itemgetter(1), reverse = True) # 按照出現頻率排序
most_cmd = [ item[0] for item in fdist[:50]]
mini_cmd = [ item[0] for item in fdist[-50:]]
return cmd_seq, most_cmd, mini_cmd
def get_user_feature(user_cmd_list, user_max_freq, user_min_freq):
user_feature = []
for cmd_list in user_cmd_list:
# 獲取每個序列不重復命令的個數
seq_len = len(set(cmd_list))
# 將每個序列按照出現頻率由高到低的排列命令
fdist = sorted(FreqDist(cmd_list).items(), key=operator.itemgetter(1), reverse=True)
seq_freq = [item[0] for item in fdist]
# 獲取最頻繁和最不頻繁的前10個命令
f2 = seq_freq[:10]
f3 = seq_freq[-10:]
# 計算重合度
f2 = len(set(f2) & set(user_max_freq))
f3 = len(set(f3) & set(user_min_freq))
# 合并特征:①每個序列不重復的命令個數;②每個序列最頻繁的前10個命令和user中最頻繁的50個命令重合度;③每個序列最不頻繁的前10個命令和user中最不頻繁的前50個命令重合度;
user_feature.append([seq_len, f2, f3])
return user_feature
def get_labels(filename): # 獲取第三列的標簽
labels = []
cnt = 0
with open(filename, 'r', encoding="utf-8") as f:
temp = f.readline().strip('\n')
while(temp):
labels.append(int(temp[4]))
cnt += 1
temp = f.readline().strip('\n')
return labels
if __name__ == "__main__":
user_cmd_list, user_max_freq, user_min_freq = load_user('user.txt')
user_feature = get_user_feature(user_cmd_list, user_max_freq, user_min_freq)
labels = get_labels('labels.txt')
# 切割數據集:訓練集和測試集
x_train = user_feature[0:70]
y_train = labels[0:70]
x_test = user_feature[70:]
y_test = labels[70:]
# 訓練數據
neight = KNeighborsClassifier(n_neighbors=3)
neight.fit(x_train, y_train)
# 預測
y_predict = neight.predict(x_test)
# 計算得分
score = np.mean(y_test == y_predict) * 100
print(score) # 90.0
最終獲得90%的正確率。
①獲取最頻繁的前50個命令,書上的方式獲取的并不是最頻繁的前50個。在這里我改了下代碼。②標簽和數據對不上號,命令共有15000個,標簽只有100個。書上的做法是每100個為一個操作序列,也就是有150個操作序列,然后在標簽出再前面增加了50個標簽。我的代碼是將150個命令作為一個序列,這樣下來剛好合適。
最后推薦下個人博客:https://unihac.github.io/
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。