5.6 示例:使用K近邻算法检测WebShell

完整演示代码请见本书GitHub上的5-5.py。

1.数据搜集和数据清洗

使用ADFA-LD数据集中WebShell相关数据,ADFA-LD数据集中记录下了系统调用序列,比如(系统调用A、系统调用B、系统调用C),然后使用数字标识每一个系统调用,这样就转换成了系统调用序列(1,2,3),这时(1,2,3)就转换成了一个序列向量,如图5-7所示。ADFA-LD数据集的详细介绍请阅读第3章相关内容。

图5-7 ADFA-LD数据集将系统调用的顺序抽象成序列向量

加载ADFA-LD中的正常样本数据:


def load_adfa_training_files(rootdir):
x=[]
y=[]
list = os.listdir(rootdir)
for i in range(0, len(list)):
    path = os.path.join(rootdir, list[i])
    if os.path.isfile(path):
        x.append(load_one_flle(path))
        y.append(0)
return x,y

定义遍历目录下文件的函数:


def dirlist(path, allfile):
filelist = os.listdir(path)
for filename in filelist:
    filepath = os.path.join(path, filename)
    if os.path.isdir(filepath):
        dirlist(filepath, allfile)
    else:
        allfile.append(filepath)
return allfile

从攻击数据集中筛选和WebShell相关的数据:


def load_adfa_webshell_files(rootdir):
x=[]
y=[]
allfile=dirlist(rootdir,[])
for file in allfile:
    if re.match(
r" ../data/ADFA-LD/Attack_Data_Master/Web_Shell_\d+/UAD-W*",
file):
        x.append(load_one_flle(file))
        y.append(1)
return x,y

2.特征化

由于ADFA-LD数据集都记录了函数调用序列,每个文件包含的函数调用序列的个数都不一致,可以参考第3章中的词集模型进行特征化。


    x1,y1=load_adfa_training_files("../data/ADFA-LD/Training_Data_Master/")
x2,y2= load_adfa_webshell_files("../data/ADFA-LD/Attack_Data_Master/"
x=x1+x2
y=y1+y2
vectorizer = CountVectorizer(min_df=1)
x=vectorizer.fit_transform(x)
x=x.toarray()

3.训练样本

实例化KNN算法,其中邻居个数设置为3:


clf = KNeighborsClassifier(n_neighbors=3)

4.效果验证

我们使用十折交叉验证。


print  cross_validation.cross_val_score(clf, x, y, n_jobs=-1,cv=10)

测试结果如下,准确率约为95%。


[ 0.97916667  0.9375      0.97916667  0.93684211  0.95789474  0.84210526
  0.96842105  0.97894737  0.9787234   0.9787234 ]