安全矩阵

 找回密码
 立即注册
搜索
查看: 916|回复: 0

[当人工智能遇上安全] 9.基于API序列和深度学习的恶意家族...

[复制链接]

417

主题

417

帖子

2391

积分

金牌会员

Rank: 6Rank: 6

积分
2391
发表于 2023-11-12 14:18:09 | 显示全部楼层 |阅读模式
eastmount 娜璋AI安全之家 2023-11-10 15:42 发表于贵州

《当人工智能遇上安全》系列博客将详细介绍人工智能与安全相关的论文、实践,并分享各种案例,涉及恶意代码检测、恶意请求识别、入侵检测、对抗样本等等。只想更好地帮助初学者,更加成体系的分享新知识。该系列文章会更加聚焦,更加学术,更加深入,也是作者的慢慢成长史。换专业确实挺难的,系统安全也是块硬骨头,但我也试试,看看自己未来四年究竟能将它学到什么程度,漫漫长征路,偏向虎山行。享受过程,一起加油~

前文详细介绍如何学习提取的API序列特征,并构建机器学习算法实现恶意家族分类,这也是安全领域典型的任务或工作。这篇文章将讲解如何构建深度学习模型实现恶意软件家族分类,常见模型包括CNN、BiLSTM、BiGRU,结合注意力机制的CNN+BiLSTM。基础性文章,希望对您有帮助,如果存在错误或不足之处,还请海涵。且看且珍惜!

文章目录:

  • 一.恶意软件分析

    • 1.静态特征
    • 2.动态特征

  • 二.基于CNN的恶意家族检测

    • 1.数据集
    • 2.模型构建
    • 3.实验结果

  • 三.基于BiLSTM的恶意家族检测

    • 1.模型构建
    • 2.实验结果

  • 四.基于BiGRU的恶意家族检测

    • 1.模型构建
    • 2.实验结果

  • 五.基于CNN+BiLSTM和注意力的恶意家族检测

    • 1.模型构建
    • 2.实验结果

  • 六.总结


前文推荐:

作者的github资源:

  • https://github.com/eastmountyxz/AI-Security-Paper


作者作为网络安全的小白,分享一些自学基础教程给大家,主要是在线笔记,希望您们喜欢。同时,更希望您能与我一起操作和进步,后续将深入学习AI安全和系统安全知识并分享相关实验。总之,希望该系列文章对博友有所帮助,写文不易,大神们不喜勿喷,谢谢!如果文章对您有帮助,将是我创作的最大动力,一起加油喔!



一.恶意软件分析

恶意软件或恶意代码分析通常包括静态分析和动态分析。特征种类如果按照恶意代码是否在用户环境或仿真环境中运行,可以划分为静态特征和动态特征。

那么,如何提取恶意软件的静态特征或动态特征呢? 因此,第一部分将简要介绍静态特征和动态特征。

1.静态特征

没有真实运行的特征,通常包括:

  • 字节码
    二进制代码转换成了字节码,比较原始的一种特征,没有进行任何处理
  • IAT表
    PE结构中比较重要的部分,声明了一些函数及所在位置,便于程序执行时导入,表和功能比较相关
  • Android权限表
    如果你的APP声明了一些功能用不到的权限,可能存在恶意目的,如手机信息
  • 可打印字符
    将二进制代码转换为ASCII码,进行相关统计
  • IDA反汇编跳转块
    IDA工具调试时的跳转块,对其进行处理作为序列数据或图数据
  • 常用API函数
  • 恶意软件图像化

静态特征提取方式:


2.动态特征

相当于静态特征更耗时,它要真正去执行代码。通常包括:
– API调用关系:比较明显的特征,调用了哪些API,表述对应的功能
– 控制流图:软件工程中比较常用,机器学习将其表示成向量,从而进行分类
– 数据流图:软件工程中比较常用,机器学习将其表示成向量,从而进行分类

动态特征提取方式:


二.基于CNN的恶意家族检测

前面的系列文章详细介绍如何提取恶意软件的静态和动态特征,包括API序列。接下来将构建深度学习模型学习API序列实现分类。基本流程如下:





1.数据集

整个数据集包括5类恶意家族的样本,每个样本经过先前的CAPE工具成功提取的动态API序列。数据集分布情况如下所示:(建议读者提取自己数据集的样本,包括BIG2015、BODMAS等)

[td]
恶意家族类别数量训练集测试集
AAAAclass1352242110
BBBBclass2335235100
CCCCclass3363243120
DDDDclass4293163130
EEEEclass5548358190

数据集分为训练集和测试集,如下图所示:





数据集中主要包括四个字段,即序号、恶意家族类别、Md5值、API序列或特征。




需要注意,在特征提取过程中涉及大量数据预处理和清洗的工作,读者需要结合实际需求完成。比如提取特征为空值的过滤代码。

  1. #coding:utf-8
  2. #By:Eastmount CSDN 2023-05-31
  3. import csv
  4. import re
  5. import os

  6. csv.field_size_limit(500 * 1024 * 1024)
  7. filename = "AAAA_result.csv"
  8. writename = "AAAA_result_final.csv"
  9. fw = open(writename, mode="w", newline="")
  10. writer = csv.writer(fw)
  11. writer.writerow(['no', 'type', 'md5', 'api'])
  12. with open(filename,encoding='utf-8') as fr:
  13.     reader = csv.reader(fr)
  14.     no = 1
  15.     for row in reader: #['no','type','md5','api']
  16.         tt = row[1]
  17.         md5 = row[2]
  18.         api = row[3]
  19.         #print(no,tt,md5,api)
  20.         #api空值的过滤
  21.         if api=="" or api=="api":
  22.             continue
  23.         else:
  24.             writer.writerow([str(no),tt,md5,api])
  25.             no += 1
  26. fr.close()
复制代码


2.模型构建

该模型的基本步骤如下:

  • 第一步 数据读取
  • 第二步 OneHotEncoder()编码
  • 第三步 使用Tokenizer对词组进行编码
  • 第四步 建立CNN模型并训练
  • 第五步 预测及评估
  • 第六步 验证算法

构建模型如下图所示:




完整代码如下所示:

  1. # -*- coding: utf-8 -*-
  2. # By:Eastmount CSDN 2023-06-27
  3. import pickle
  4. import pandas as pd
  5. import numpy as np
  6. import matplotlib.pyplot as plt
  7. import seaborn as sns
  8. from sklearn import metrics
  9. import tensorflow as tf
  10. from sklearn.preprocessing import LabelEncoder,OneHotEncoder
  11. from keras.models import Model
  12. from keras.layers import LSTM, Activation, Dense, Dropout, Input, Embedding
  13. from keras.layers import Convolution1D, MaxPool1D, Flatten
  14. from keras.optimizers import RMSprop
  15. from keras.layers import Bidirectional
  16. from keras.preprocessing.text import Tokenizer
  17. from keras.preprocessing import sequence
  18. from keras.callbacks import EarlyStopping
  19. from keras.models import load_model
  20. from keras.models import Sequential
  21. from keras.layers.merge import concatenate
  22. import time

  23. """
  24. import os
  25. os.environ["CUDA_DEVICES_ORDER"] = "PCI_BUS_IS"
  26. os.environ["CUDA_VISIBLE_DEVICES"] = "0"
  27. gpu_options = tf.GPUOptions(per_process_gpu_memory_fraction=0.8)
  28. sess = tf.Session(config=tf.ConfigProto(gpu_options=gpu_options))
  29. """

  30. start = time.clock()

  31. #---------------------------------------第一步 数据读取------------------------------------
  32. # 读取测数据集
  33. train_df = pd.read_csv("..\\train_dataset.csv")
  34. val_df = pd.read_csv("..\\val_dataset.csv")
  35. test_df = pd.read_csv("..\\test_dataset.csv")

  36. # 指定数据类型 否则AttributeError: 'float' object has no attribute 'lower' 存在文本为空的现象
  37. # train_df.SentimentText = train_df.SentimentText.astype(str)
  38. print(train_df.head())

  39. # 解决中文显示问题
  40. plt.rcParams['font.sans-serif'] = ['KaiTi']   #指定默认字体 SimHei黑体
  41. plt.rcParams['axes.unicode_minus'] = False    #解决保存图像是负号'

  42. #---------------------------------第二步 OneHotEncoder()编码---------------------------------
  43. # 对数据集的标签数据进行编码  (no apt md5 api)
  44. train_y = train_df.apt
  45. print("Label:")
  46. print(train_y[:10])
  47. val_y = val_df.apt
  48. test_y = test_df.apt
  49. le = LabelEncoder()
  50. train_y = le.fit_transform(train_y).reshape(-1,1)
  51. print("LabelEncoder")
  52. print(train_y[:10])
  53. print(len(train_y))
  54. val_y = le.transform(val_y).reshape(-1,1)
  55. test_y = le.transform(test_y).reshape(-1,1)
  56. Labname = le.classes_
  57. print(Labname)

  58. # 对数据集的标签数据进行one-hot编码
  59. ohe = OneHotEncoder()
  60. train_y = ohe.fit_transform(train_y).toarray()
  61. val_y = ohe.transform(val_y).toarray()
  62. test_y = ohe.transform(test_y).toarray()
  63. print("OneHotEncoder:")
  64. print(train_y[:10])

  65. #-------------------------------第三步 使用Tokenizer对词组进行编码-------------------------------
  66. # 使用Tokenizer对词组进行编码
  67. # 当我们创建了一个Tokenizer对象后,使用该对象的fit_on_texts()函数,以空格去识别每个词
  68. # 可以将输入的文本中的每个词编号,编号是根据词频的,词频越大,编号越小
  69. max_words = 1000
  70. max_len = 200
  71. tok = Tokenizer(num_words=max_words)  #使用的最大词语数为1000
  72. print(train_df.api[:5])
  73. print(type(train_df.api))

  74. # 提取token:api
  75. train_value = train_df.api
  76. train_content = [str(a) for a in train_value.tolist()]
  77. val_value = val_df.api
  78. val_content = [str(a) for a in val_value.tolist()]
  79. test_value = test_df.api
  80. test_content = [str(a) for a in test_value.tolist()]
  81. tok.fit_on_texts(train_content)
  82. print(tok)

  83. # 保存训练好的Tokenizer和导入
  84. # saving
  85. with open('tok.pickle', 'wb') as handle:
  86.     pickle.dump(tok, handle, protocol=pickle.HIGHEST_PROTOCOL)
  87. # loading
  88. with open('tok.pickle', 'rb') as handle:
  89.     tok = pickle.load(handle)

  90. # 使用word_index属性可以看到每次词对应的编码
  91. # 使用word_counts属性可以看到每个词对应的频数
  92. for ii,iterm in enumerate(tok.word_index.items()):
  93.     if ii < 10:
  94.         print(iterm)
  95.     else:
  96.         break
  97. print("===================")  
  98. for ii,iterm in enumerate(tok.word_counts.items()):
  99.     if ii < 10:
  100.         print(iterm)
  101.     else:
  102.         break

  103. # 使用tok.texts_to_sequences()将数据转化为序列
  104. # 使用sequence.pad_sequences()将每个序列调整为相同的长度
  105. # 对每个词编码之后,每句新闻中的每个词就可以用对应的编码表示,即每条新闻可以转变成一个向量了
  106. train_seq = tok.texts_to_sequences(train_content)
  107. val_seq = tok.texts_to_sequences(val_content)
  108. test_seq = tok.texts_to_sequences(test_content)

  109. # 将每个序列调整为相同的长度
  110. train_seq_mat = sequence.pad_sequences(train_seq,maxlen=max_len)
  111. val_seq_mat = sequence.pad_sequences(val_seq,maxlen=max_len)
  112. test_seq_mat = sequence.pad_sequences(test_seq,maxlen=max_len)
  113. print(train_seq_mat.shape)  #(1241, 200)
  114. print(val_seq_mat.shape)    #(459, 200)
  115. print(test_seq_mat.shape)   #(650, 200)
  116. print(train_seq_mat[:2])

  117. #-------------------------------第四步 建立CNN模型并训练-------------------------------
  118. num_labels = 5
  119. inputs = Input(name='inputs',shape=[max_len], dtype='float64')

  120. # 词嵌入(使用预训练的词向量)
  121. layer = Embedding(max_words+1, 256, input_length=max_len, trainable=False)(inputs)

  122. # 词窗大小分别为3,4,5
  123. cnn = Convolution1D(256, 3, padding='same', strides = 1, activation='relu')(layer)
  124. cnn = MaxPool1D(pool_size=3)(cnn)

  125. # 合并三个模型的输出向量
  126. flat = Flatten()(cnn)
  127. drop = Dropout(0.4)(flat)
  128. main_output = Dense(num_labels, activation='softmax')(drop)
  129. model = Model(inputs=inputs, outputs=main_output)
  130. model.summary()
  131. model.compile(loss="categorical_crossentropy",
  132.               optimizer='adam',      #RMSprop()
  133.               metrics=["accuracy"])

  134. # 增加判断 防止再次训练
  135. flag = "train"
  136. if flag == "train":
  137.     print("模型训练")
  138.     # 模型训练
  139.     model_fit = model.fit(train_seq_mat, train_y, batch_size=64, epochs=15,
  140.                           validation_data=(val_seq_mat,val_y),
  141.                           callbacks=[EarlyStopping(monitor='val_loss',min_delta=0.001)]   #当val-loss不再提升时停止训练 0.0001
  142.                          )
  143.    
  144.     # 保存模型
  145.     model.save('cnn_model.h5')  
  146.     del model  # deletes the existing model
  147.    
  148.     # 计算时间
  149.     elapsed = (time.clock() - start)
  150.     print("Time used:", elapsed)
  151.     print(model_fit.history)
  152.    
  153. else:
  154.     print("模型预测")
  155.     # 导入已经训练好的模型
  156.     model = load_model('cnn_model.h5')
  157.    
  158.     #--------------------------------------第五步 预测及评估--------------------------------
  159.     # 对测试集进行预测
  160.     test_pre = model.predict(test_seq_mat)
  161.    
  162.     # 评价预测效果,计算混淆矩阵
  163.     confm = metrics.confusion_matrix(np.argmax(test_y,axis=1),
  164.                                      np.argmax(test_pre,axis=1))
  165.     print(confm)
  166.     print(metrics.classification_report(np.argmax(test_y,axis=1),
  167.                                         np.argmax(test_pre,axis=1),
  168.                                         digits=4))
  169.     print("accuracy", metrics.accuracy_score(np.argmax(test_y, axis=1),
  170.                                              np.argmax(test_pre, axis=1)))
  171.     # 结果存储
  172.     f1 = open("cnn_test_pre.txt", "w")
  173.     for n in np.argmax(test_pre, axis=1):
  174.         f1.write(str(n) + "\n")
  175.     f1.close()

  176.     f2 = open("cnn_test_y.txt", "w")
  177.     for n in np.argmax(test_y, axis=1):
  178.         f2.write(str(n) + "\n")
  179.     f2.close()

  180.     plt.figure(figsize=(8,8))
  181.     sns.heatmap(confm.T, square=True, annot=True,
  182.                 fmt='d', cbar=False, linewidths=.6,
  183.                 cmap="YlGnBu")
  184.     plt.xlabel('True label',size = 14)
  185.     plt.ylabel('Predicted label', size = 14)
  186.     plt.xticks(np.arange(5)+0.5, Labname, size = 12)
  187.     plt.yticks(np.arange(5)+0.5, Labname, size = 12)
  188.     plt.savefig('cnn_result.png')
  189.     plt.show()

  190.     #--------------------------------------第六步 验证算法--------------------------------
  191.     # 使用tok对验证数据集重新预处理
  192.     val_seq = tok.texts_to_sequences(val_content)
  193.     # 将每个序列调整为相同的长度
  194.     val_seq_mat = sequence.pad_sequences(val_seq,maxlen=max_len)
  195.     # 对验证集进行预测
  196.     val_pre = model.predict(val_seq_mat)
  197.     print(metrics.classification_report(np.argmax(val_y,axis=1),
  198.                                         np.argmax(val_pre,axis=1),
  199.                                         digits=4))
  200.     print("accuracy", metrics.accuracy_score(np.argmax(val_y, axis=1),
  201.                                              np.argmax(val_pre, axis=1)))
  202.     # 计算时间
  203.     elapsed = (time.clock() - start)
  204.     print("Time used:", elapsed)
复制代码


3.实验结果

最终运行结果及其生成文件如下图所示:




输出中间过程结果如下所示:

  1.    no  ...                                                api
  2. 0   1  ...  GetSystemInfo;HeapCreate;NtAllocateVirtualMemo...
  3. 1   2  ...  GetSystemInfo;HeapCreate;NtAllocateVirtualMemo...
  4. 2   3  ...  NtQueryValueKey;GetSystemTimeAsFileTime;HeapCr...
  5. 3   4  ...  NtQueryValueKey;NtClose;NtAllocateVirtualMemor...
  6. 4   5  ...  NtOpenFile;NtCreateSection;NtMapViewOfSection;...

  7. [5 rows x 4 columns]
  8. Label:
  9. 0    class1
  10. 1    class1
  11. 2    class1
  12. 3    class1
  13. 4    class1
  14. 5    class1
  15. 6    class1
  16. 7    class1
  17. 8    class1
  18. 9    class1
  19. Name: apt, dtype: object
  20. LabelEncoder
  21. [[0]
  22. [0]
  23. [0]
  24. [0]
  25. [0]
  26. [0]
  27. [0]
  28. [0]
  29. [0]
  30. [0]]
  31. 1241
  32. ['class1' 'class2' 'class3' 'class4' 'class5']
  33. OneHotEncoder:
  34. [[1. 0. 0. 0. 0.]
  35. [1. 0. 0. 0. 0.]
  36. [1. 0. 0. 0. 0.]
  37. [1. 0. 0. 0. 0.]
  38. [1. 0. 0. 0. 0.]
  39. [1. 0. 0. 0. 0.]
  40. [1. 0. 0. 0. 0.]
  41. [1. 0. 0. 0. 0.]
  42. [1. 0. 0. 0. 0.]
  43. [1. 0. 0. 0. 0.]]
  44. 0    GetSystemInfo;HeapCreate;NtAllocateVirtualMemo...
  45. 1    GetSystemInfo;HeapCreate;NtAllocateVirtualMemo...
  46. 2    NtQueryValueKey;GetSystemTimeAsFileTime;HeapCr...
  47. 3    NtQueryValueKey;NtClose;NtAllocateVirtualMemor...
  48. 4    NtOpenFile;NtCreateSection;NtMapViewOfSection;...
  49. Name: api, dtype: object
  50. <class 'pandas.core.series.Series'>
  51. <keras_preprocessing.text.Tokenizer object at 0x0000028E55D36B08>

  52. ('regqueryvalueexw', 1)
  53. ('ntclose', 2)
  54. ('ldrgetprocedureaddress', 3)
  55. ('regopenkeyexw', 4)
  56. ('regclosekey', 5)
  57. ('ntallocatevirtualmemory', 6)
  58. ('sendmessagew', 7)
  59. ('ntwritefile', 8)
  60. ('process32nextw', 9)
  61. ('ntdeviceiocontrolfile', 10)
  62. ===================
  63. ('getsysteminfo', 2651)
  64. ('heapcreate', 2996)
  65. ('ntallocatevirtualmemory', 115547)
  66. ('ntqueryvaluekey', 24120)
  67. ('getsystemtimeasfiletime', 52727)
  68. ('ldrgetdllhandle', 25135)
  69. ('ldrgetprocedureaddress', 199952)
  70. ('memcpy', 9008)
  71. ('setunhandledexceptionfilter', 1504)
  72. ('ntcreatefile', 43260)

  73. (1241, 200)
  74. (459, 200)
  75. (650, 200)
  76. [[  3 135   3   3   2  21   3   3   4   3  96   3   3   4  96   4  96  20
  77.    22  20   3   6   6  23 128 129   3 103  23  56   2 103  23  20   3  23
  78.     3   3   3   3   4   1   5  23  12 131  12  20   3  10   2  10   2  20
  79.     3   4   5  27   3  10   2   6  10   2   3  10   2  10   2   3  10   2
  80.    10   2  10   2  10   2  10   2   3  10   2  10   2  10   2  10   2   3
  81.     3   3  36   4   3  23  20   3   5 207  34   6   6   6  11  11   6  11
  82.     6   6   6   6   6   6   6   6   6  11   6   6  11   6  11   6  11   6
  83.     6  11   6  34   3 141   3 140   3   3 141  34   6   2  21   4  96   4
  84.    96   4  96  23   3   3  12 131  12  10   2  10   2   4   5  27  10   2
  85.     6  10   2  10   2  10   2  10   2  10   2  10   2  10   2  10   2  10
  86.     2  10   2  10   2  10   2  36   4  23   5 207   6   3   3  12 131  12
  87.   132   3]
  88. [ 27   4  27   4  27   4  27   4  27  27   5  27   4  27   4  27  27  27
  89.    27  27  27  27   5  27   4  27   4  27   4  27   4  27   4  27   4  27
  90.     4  27   4  27   4  27   5  52   2  21   4   5   1   1   1   5  21  25
  91.     2  52  12  33  51  28  34  30   2  52   2  21   4   5  27   5  52   6
  92.     6  52   4   1   5   4  52  54   7   7  20  52   7  52   7   7   6   4
  93.     4  24  24  24  24  24  24  24  24  24  24  24  24  24  24  24  24   5
  94.     5   3   7  50  50  50  95  50  50  50  50  50   4   1   5   4   3   3
  95.     3   3   3   7   7   7   3   7   3   7   3  60   3   3   7   7   7   7
  96.    60   3   7   7   7   7   7   7   7   7  52  20   3   3   3  14  14  60
  97.    18  19  18  19   2  21   4   5  18  19  18  19  18  19  18  19   7   7
  98.     7   7   7   7   7   7   7   7   7  52   7   7   7   7   7  60   7   7
  99.     7   7]]
复制代码


模型训练过程如下:
  1. 模型训练
  2. Epoch 1/15

  3. 1/20 [>.............................] - ETA: 5s - loss: 1.5986 - accuracy: 0.2656
  4. 2/20 [==>...........................] - ETA: 1s - loss: 1.6050 - accuracy: 0.2266
  5. 3/20 [===>..........................] - ETA: 1s - loss: 1.5777 - accuracy: 0.2292
  6. 4/20 [=====>........................] - ETA: 2s - loss: 1.5701 - accuracy: 0.2500
  7. 5/20 [======>.......................] - ETA: 2s - loss: 1.5628 - accuracy: 0.2719
  8. 6/20 [========>.....................] - ETA: 3s - loss: 1.5439 - accuracy: 0.3125
  9. 7/20 [=========>....................] - ETA: 3s - loss: 1.5306 - accuracy: 0.3348
  10. 8/20 [===========>..................] - ETA: 3s - loss: 1.5162 - accuracy: 0.3535
  11. 9/20 [============>.................] - ETA: 3s - loss: 1.5020 - accuracy: 0.3698
  12. 10/20 [==============>...............] - ETA: 3s - loss: 1.4827 - accuracy: 0.3969
  13. 11/20 [===============>..............] - ETA: 3s - loss: 1.4759 - accuracy: 0.4020
  14. 12/20 [=================>............] - ETA: 3s - loss: 1.4734 - accuracy: 0.4036
  15. 13/20 [==================>...........] - ETA: 3s - loss: 1.4456 - accuracy: 0.4255
  16. 14/20 [====================>.........] - ETA: 3s - loss: 1.4322 - accuracy: 0.4353
  17. 15/20 [=====================>........] - ETA: 2s - loss: 1.4157 - accuracy: 0.4469
  18. 16/20 [=======================>......] - ETA: 2s - loss: 1.4093 - accuracy: 0.4482
  19. 17/20 [========================>.....] - ETA: 2s - loss: 1.4010 - accuracy: 0.4531
  20. 18/20 [==========================>...] - ETA: 1s - loss: 1.3920 - accuracy: 0.4601
  21. 19/20 [===========================>..] - ETA: 0s - loss: 1.3841 - accuracy: 0.4638
  22. 20/20 [==============================] - ETA: 0s - loss: 1.3763 - accuracy: 0.4674
  23. 20/20 [==============================] - 20s 1s/step - loss: 1.3763 - accuracy: 0.4674 - val_loss: 1.3056 - val_accuracy: 0.4837

  24. Time used: 26.1328806
  25. {'loss': [1.3762551546096802], 'accuracy': [0.467365026473999],
  26. 'val_loss': [1.305567979812622], 'val_accuracy': [0.48366013169288635]}
复制代码


最终预测结果如下所示:

  1. 模型预测
  2. [[ 40  14  11   1  44]
  3. [ 16  57  10   0  17]
  4. [  6  30  61   0  23]
  5. [ 12  20  15  47  36]
  6. [ 11  14  19   0 146]]
  7.               precision    recall  f1-score   support

  8.            0     0.4706    0.3636    0.4103       110
  9.            1     0.4222    0.5700    0.4851       100
  10.            2     0.5259    0.5083    0.5169       120
  11.            3     0.9792    0.3615    0.5281       130
  12.            4     0.5489    0.7684    0.6404       190

  13.     accuracy                         0.5400       650
  14.    macro avg     0.5893    0.5144    0.5162       650
  15. weighted avg     0.5980    0.5400    0.5323       650

  16. accuracy 0.54

  17.               precision    recall  f1-score   support

  18.            0     0.9086    0.4517    0.6034       352
  19.            1     0.5943    0.5888    0.5915       107
  20.            2     0.0000    0.0000    0.0000         0
  21.            3     0.0000    0.0000    0.0000         0
  22.            4     0.0000    0.0000    0.0000         0

  23.     accuracy                         0.4837       459
  24.    macro avg     0.3006    0.2081    0.2390       459
  25. weighted avg     0.8353    0.4837    0.6006       459

  26. accuracy 0.48366013071895425
  27. Time used: 14.170902800000002
复制代码




思考:
然而,整个预测结果效果较差,请读者思考,这是为什么呢?我们能不能通过调参进行优化,又如何改进算法呢?本文仅提供基本思路和代码,更多优化及完善需要读者学会独立解决,加油喔!


三.基于BiLSTM的恶意家族检测1.模型构建

该模型的基本步骤如下:

  • 第一步 数据读取
  • 第二步 OneHotEncoder()编码
  • 第三步 使用Tokenizer对词组进行编码
  • 第四步 建立BiLSTM模型并训练
  • 第五步 预测及评估
  • 第六步 验证算法

构建模型如下图所示:




完整代码如下所示:

  1. # -*- coding: utf-8 -*-
  2. # By:Eastmount CSDN 2023-06-27
  3. import pickle
  4. import pandas as pd
  5. import numpy as np
  6. import matplotlib.pyplot as plt
  7. import seaborn as sns
  8. from sklearn import metrics
  9. import tensorflow as tf
  10. from sklearn.preprocessing import LabelEncoder,OneHotEncoder
  11. from keras.models import Model
  12. from keras.layers import LSTM, Activation, Dense, Dropout, Input, Embedding
  13. from keras.layers import Convolution1D, MaxPool1D, Flatten
  14. from keras.optimizers import RMSprop
  15. from keras.layers import Bidirectional
  16. from keras.preprocessing.text import Tokenizer
  17. from keras.preprocessing import sequence
  18. from keras.callbacks import EarlyStopping
  19. from keras.models import load_model
  20. from keras.models import Sequential
  21. from keras.layers.merge import concatenate
  22. import time

  23. start = time.clock()

  24. #---------------------------------------第一步 数据读取------------------------------------
  25. # 读取测数据集
  26. train_df = pd.read_csv("..\\train_dataset.csv")
  27. val_df = pd.read_csv("..\\val_dataset.csv")
  28. test_df = pd.read_csv("..\\test_dataset.csv")
  29. print(train_df.head())

  30. # 解决中文显示问题
  31. plt.rcParams['font.sans-serif'] = ['KaiTi']
  32. plt.rcParams['axes.unicode_minus'] = False

  33. #---------------------------------第二步 OneHotEncoder()编码---------------------------------
  34. # 对数据集的标签数据进行编码  (no apt md5 api)
  35. train_y = train_df.apt
  36. val_y = val_df.apt
  37. test_y = test_df.apt
  38. le = LabelEncoder()
  39. train_y = le.fit_transform(train_y).reshape(-1,1)
  40. val_y = le.transform(val_y).reshape(-1,1)
  41. test_y = le.transform(test_y).reshape(-1,1)
  42. Labname = le.classes_

  43. # 对数据集的标签数据进行one-hot编码
  44. ohe = OneHotEncoder()
  45. train_y = ohe.fit_transform(train_y).toarray()
  46. val_y = ohe.transform(val_y).toarray()
  47. test_y = ohe.transform(test_y).toarray()

  48. #-------------------------------第三步 使用Tokenizer对词组进行编码-------------------------------
  49. # 使用Tokenizer对词组进行编码
  50. max_words = 2000
  51. max_len = 300
  52. tok = Tokenizer(num_words=max_words)

  53. # 提取token:api
  54. train_value = train_df.api
  55. train_content = [str(a) for a in train_value.tolist()]
  56. val_value = val_df.api
  57. val_content = [str(a) for a in val_value.tolist()]
  58. test_value = test_df.api
  59. test_content = [str(a) for a in test_value.tolist()]
  60. tok.fit_on_texts(train_content)
  61. print(tok)

  62. # 保存训练好的Tokenizer和导入
  63. with open('tok.pickle', 'wb') as handle:
  64.     pickle.dump(tok, handle, protocol=pickle.HIGHEST_PROTOCOL)
  65. with open('tok.pickle', 'rb') as handle:
  66.     tok = pickle.load(handle)

  67. # 使用tok.texts_to_sequences()将数据转化为序列
  68. train_seq = tok.texts_to_sequences(train_content)
  69. val_seq = tok.texts_to_sequences(val_content)
  70. test_seq = tok.texts_to_sequences(test_content)

  71. # 将每个序列调整为相同的长度
  72. train_seq_mat = sequence.pad_sequences(train_seq,maxlen=max_len)
  73. val_seq_mat = sequence.pad_sequences(val_seq,maxlen=max_len)
  74. test_seq_mat = sequence.pad_sequences(test_seq,maxlen=max_len)

  75. #-------------------------------第四步 建立LSTM模型并训练-------------------------------
  76. num_labels = 5
  77. model = Sequential()
  78. model.add(Embedding(max_words+1, 128, input_length=max_len))
  79. #model.add(Bidirectional(LSTM(128, dropout=0.3, recurrent_dropout=0.1)))
  80. model.add(Bidirectional(LSTM(128)))
  81. model.add(Dense(128, activation='relu'))
  82. model.add(Dropout(0.3))
  83. model.add(Dense(num_labels, activation='softmax'))
  84. model.summary()
  85. model.compile(loss="categorical_crossentropy",
  86.               optimizer='adam',
  87.               metrics=["accuracy"])

  88. flag = "train"
  89. if flag == "train":
  90.     print("模型训练")
  91.     # 模型训练
  92.     model_fit = model.fit(train_seq_mat, train_y, batch_size=64, epochs=15,
  93.                           validation_data=(val_seq_mat,val_y),
  94.                           callbacks=[EarlyStopping(monitor='val_loss',min_delta=0.0001)]
  95.                          )
  96.    
  97.     # 保存模型
  98.     model.save('bilstm_model.h5')  
  99.     del model  # deletes the existing model
  100.    
  101.     # 计算时间
  102.     elapsed = (time.clock() - start)
  103.     print("Time used:", elapsed)
  104.     print(model_fit.history)
  105.    
  106. else:
  107.     print("模型预测")
  108.     model = load_model('bilstm_model.h5')
  109.    
  110.     #--------------------------------------第五步 预测及评估--------------------------------
  111.     # 对测试集进行预测
  112.     test_pre = model.predict(test_seq_mat)
  113.     confm = metrics.confusion_matrix(np.argmax(test_y,axis=1),
  114.                                      np.argmax(test_pre,axis=1))
  115.     print(confm)
  116.     print(metrics.classification_report(np.argmax(test_y,axis=1),
  117.                                         np.argmax(test_pre,axis=1),
  118.                                         digits=4))
  119.     print("accuracy", metrics.accuracy_score(np.argmax(test_y, axis=1),
  120.                                              np.argmax(test_pre, axis=1)))
  121.     # 结果存储
  122.     f1 = open("bilstm_test_pre.txt", "w")
  123.     for n in np.argmax(test_pre, axis=1):
  124.         f1.write(str(n) + "\n")
  125.     f1.close()

  126.     f2 = open("bilstm_test_y.txt", "w")
  127.     for n in np.argmax(test_y, axis=1):
  128.         f2.write(str(n) + "\n")
  129.     f2.close()

  130.     plt.figure(figsize=(8,8))
  131.     sns.heatmap(confm.T, square=True, annot=True,
  132.                 fmt='d', cbar=False, linewidths=.6,
  133.                 cmap="YlGnBu")
  134.     plt.xlabel('True label',size = 14)
  135.     plt.ylabel('Predicted label', size = 14)
  136.     plt.xticks(np.arange(5)+0.5, Labname, size = 12)
  137.     plt.yticks(np.arange(5)+0.5, Labname, size = 12)
  138.     plt.savefig('bilstm_result.png')
  139.     plt.show()

  140.     #--------------------------------------第六步 验证算法--------------------------------
  141.     # 使用tok对验证数据集重新预处理
  142.     val_seq = tok.texts_to_sequences(val_content)
  143.     val_seq_mat = sequence.pad_sequences(val_seq,maxlen=max_len)
  144.    
  145.     # 对验证集进行预测
  146.     val_pre = model.predict(val_seq_mat)
  147.     print(metrics.classification_report(np.argmax(val_y,axis=1),
  148.                                         np.argmax(val_pre,axis=1),
  149.                                         digits=4))
  150.     print("accuracy", metrics.accuracy_score(np.argmax(val_y, axis=1),
  151.                                              np.argmax(val_pre, axis=1)))
  152.     # 计算时间
  153.     elapsed = (time.clock() - start)
  154.     print("Time used:", elapsed)
复制代码


2.实验结果

训练输出结果如下图所示:



  1. 模型训练
  2. Epoch 1/15
  3. 1/20 [>.............................] - ETA: 40s - loss: 1.6114 - accuracy: 0.2031
  4. 2/20 [==>...........................] - ETA: 10s - loss: 1.6055 - accuracy: 0.2969
  5. 3/20 [===>..........................] - ETA: 10s - loss: 1.6015 - accuracy: 0.3281
  6. 4/20 [=====>........................] - ETA: 10s - loss: 1.5931 - accuracy: 0.3477
  7. 5/20 [======>.......................] - ETA: 10s - loss: 1.5914 - accuracy: 0.3469
  8. 6/20 [========>.....................] - ETA: 10s - loss: 1.5827 - accuracy: 0.3698
  9. 7/20 [=========>....................] - ETA: 10s - loss: 1.5785 - accuracy: 0.3884
  10. 8/20 [===========>..................] - ETA: 10s - loss: 1.5673 - accuracy: 0.4121
  11. 9/20 [============>.................] - ETA: 9s - loss: 1.5610 - accuracy: 0.4149
  12. 10/20 [==============>...............] - ETA: 9s - loss: 1.5457 - accuracy: 0.4187
  13. 11/20 [===============>..............] - ETA: 8s - loss: 1.5297 - accuracy: 0.4148
  14. 12/20 [=================>............] - ETA: 8s - loss: 1.5338 - accuracy: 0.4128
  15. 13/20 [==================>...........] - ETA: 7s - loss: 1.5214 - accuracy: 0.4279
  16. 14/20 [====================>.........] - ETA: 6s - loss: 1.5176 - accuracy: 0.4286
  17. 15/20 [=====================>........] - ETA: 5s - loss: 1.5100 - accuracy: 0.4271
  18. 16/20 [=======================>......] - ETA: 4s - loss: 1.5065 - accuracy: 0.4258
  19. 17/20 [========================>.....] - ETA: 3s - loss: 1.5021 - accuracy: 0.4237
  20. 18/20 [==========================>...] - ETA: 2s - loss: 1.4921 - accuracy: 0.4288
  21. 19/20 [===========================>..] - ETA: 1s - loss: 1.4822 - accuracy: 0.4334
  22. 20/20 [==============================] - ETA: 0s - loss: 1.4825 - accuracy: 0.4327
  23. 20/20 [==============================] - 33s 2s/step - loss: 1.4825 - accuracy: 0.4327 - val_loss: 1.4187 - val_accuracy: 0.4074

  24. Time used: 38.565846900000004
  25. {'loss': [1.4825222492218018], 'accuracy': [0.4327155649662018],
  26. 'val_loss': [1.4187402725219727], 'val_accuracy': [0.40740740299224854]}
  27. >>>
复制代码


最终预测结果如下所示:

  1. 模型预测
  2. [[36 18 37  1 18]
  3. [14 46 34  0  6]
  4. [ 8 29 73  0 10]
  5. [16 29 14 45 26]
  6. [47 15 33  0 95]]
  7.               precision    recall  f1-score   support

  8.            0     0.2975    0.3273    0.3117       110
  9.            1     0.3358    0.4600    0.3882       100
  10.            2     0.3822    0.6083    0.4695       120
  11.            3     0.9783    0.3462    0.5114       130
  12.            4     0.6129    0.5000    0.5507       190

  13.     accuracy                         0.4538       650
  14.    macro avg     0.5213    0.4484    0.4463       650
  15. weighted avg     0.5474    0.4538    0.4624       650

  16. accuracy 0.45384615384615384

  17.               precision    recall  f1-score   support

  18.            0     0.9189    0.3864    0.5440       352
  19.            1     0.4766    0.4766    0.4766       107
  20.            2     0.0000    0.0000    0.0000         0
  21.            3     0.0000    0.0000    0.0000         0
  22.            4     0.0000    0.0000    0.0000         0

  23.     accuracy                         0.4074       459
  24.    macro avg     0.2791    0.1726    0.2041       459
  25. weighted avg     0.8158    0.4074    0.5283       459

  26. accuracy 0.4074074074074074
  27. Time used: 32.2772881
复制代码




四.基于BiGRU的恶意家族检测1.模型构建

该模型的基本步骤如下:

  • 第一步 数据读取
  • 第二步 OneHotEncoder()编码
  • 第三步 使用Tokenizer对词组进行编码
  • 第四步 建立BiGRU模型并训练
  • 第五步 预测及评估
  • 第六步 验证算法

构建模型如下图所示:



完整代码如下所示:

  1. # -*- coding: utf-8 -*-
  2. # By:Eastmount CSDN 2023-06-27
  3. import pickle
  4. import pandas as pd
  5. import numpy as np
  6. import matplotlib.pyplot as plt
  7. import seaborn as sns
  8. from sklearn import metrics
  9. import tensorflow as tf
  10. from sklearn.preprocessing import LabelEncoder,OneHotEncoder
  11. from keras.models import Model
  12. from keras.layers import GRU, LSTM, Activation, Dense, Dropout, Input, Embedding
  13. from keras.layers import Convolution1D, MaxPool1D, Flatten
  14. from keras.optimizers import RMSprop
  15. from keras.layers import Bidirectional
  16. from keras.preprocessing.text import Tokenizer
  17. from keras.preprocessing import sequence
  18. from keras.callbacks import EarlyStopping
  19. from keras.models import load_model
  20. from keras.models import Sequential
  21. from keras.layers.merge import concatenate
  22. import time

  23. start = time.clock()

  24. #---------------------------------------第一步 数据读取------------------------------------
  25. # 读取测数据集
  26. train_df = pd.read_csv("..\\train_dataset.csv")
  27. val_df = pd.read_csv("..\\val_dataset.csv")
  28. test_df = pd.read_csv("..\\test_dataset.csv")
  29. print(train_df.head())

  30. # 解决中文显示问题
  31. plt.rcParams['font.sans-serif'] = ['KaiTi']
  32. plt.rcParams['axes.unicode_minus'] = False

  33. #---------------------------------第二步 OneHotEncoder()编码---------------------------------
  34. # 对数据集的标签数据进行编码  (no apt md5 api)
  35. train_y = train_df.apt
  36. val_y = val_df.apt
  37. test_y = test_df.apt
  38. le = LabelEncoder()
  39. train_y = le.fit_transform(train_y).reshape(-1,1)
  40. val_y = le.transform(val_y).reshape(-1,1)
  41. test_y = le.transform(test_y).reshape(-1,1)
  42. Labname = le.classes_

  43. # 对数据集的标签数据进行one-hot编码
  44. ohe = OneHotEncoder()
  45. train_y = ohe.fit_transform(train_y).toarray()
  46. val_y = ohe.transform(val_y).toarray()
  47. test_y = ohe.transform(test_y).toarray()

  48. #-------------------------------第三步 使用Tokenizer对词组进行编码-------------------------------
  49. # 使用Tokenizer对词组进行编码
  50. max_words = 2000
  51. max_len = 300
  52. tok = Tokenizer(num_words=max_words)

  53. # 提取token:api
  54. train_value = train_df.api
  55. train_content = [str(a) for a in train_value.tolist()]
  56. val_value = val_df.api
  57. val_content = [str(a) for a in val_value.tolist()]
  58. test_value = test_df.api
  59. test_content = [str(a) for a in test_value.tolist()]
  60. tok.fit_on_texts(train_content)
  61. print(tok)

  62. # 保存训练好的Tokenizer和导入
  63. with open('tok.pickle', 'wb') as handle:
  64.     pickle.dump(tok, handle, protocol=pickle.HIGHEST_PROTOCOL)
  65. with open('tok.pickle', 'rb') as handle:
  66.     tok = pickle.load(handle)

  67. # 使用tok.texts_to_sequences()将数据转化为序列
  68. train_seq = tok.texts_to_sequences(train_content)
  69. val_seq = tok.texts_to_sequences(val_content)
  70. test_seq = tok.texts_to_sequences(test_content)

  71. # 将每个序列调整为相同的长度
  72. train_seq_mat = sequence.pad_sequences(train_seq,maxlen=max_len)
  73. val_seq_mat = sequence.pad_sequences(val_seq,maxlen=max_len)
  74. test_seq_mat = sequence.pad_sequences(test_seq,maxlen=max_len)

  75. #-------------------------------第四步 建立GRU模型并训练-------------------------------
  76. num_labels = 5
  77. model = Sequential()
  78. model.add(Embedding(max_words+1, 256, input_length=max_len))
  79. #model.add(Bidirectional(GRU(128, dropout=0.2, recurrent_dropout=0.1)))
  80. model.add(Bidirectional(GRU(256)))
  81. model.add(Dense(256, activation='relu'))
  82. model.add(Dropout(0.4))
  83. model.add(Dense(num_labels, activation='softmax'))
  84. model.summary()
  85. model.compile(loss="categorical_crossentropy",
  86.               optimizer='adam',
  87.               metrics=["accuracy"])

  88. flag = "train"
  89. if flag == "train":
  90.     print("模型训练")
  91.     # 模型训练
  92.     model_fit = model.fit(train_seq_mat, train_y, batch_size=64, epochs=15,
  93.                           validation_data=(val_seq_mat,val_y),
  94.                           callbacks=[EarlyStopping(monitor='val_loss',min_delta=0.005)]
  95.                          )
  96.    
  97.     # 保存模型
  98.     model.save('gru_model.h5')  
  99.     del model  # deletes the existing model
  100.    
  101.     # 计算时间
  102.     elapsed = (time.clock() - start)
  103.     print("Time used:", elapsed)
  104.     print(model_fit.history)
  105.    
  106. else:
  107.     print("模型预测")
  108.     model = load_model('gru_model.h5')
  109.    
  110.     #--------------------------------------第五步 预测及评估--------------------------------
  111.     # 对测试集进行预测
  112.     test_pre = model.predict(test_seq_mat)
  113.     confm = metrics.confusion_matrix(np.argmax(test_y,axis=1),
  114.                                      np.argmax(test_pre,axis=1))
  115.     print(confm)
  116.     print(metrics.classification_report(np.argmax(test_y,axis=1),
  117.                                         np.argmax(test_pre,axis=1),
  118.                                         digits=4))
  119.     print("accuracy", metrics.accuracy_score(np.argmax(test_y, axis=1),
  120.                                              np.argmax(test_pre, axis=1)))
  121.     # 结果存储
  122.     f1 = open("gru_test_pre.txt", "w")
  123.     for n in np.argmax(test_pre, axis=1):
  124.         f1.write(str(n) + "\n")
  125.     f1.close()

  126.     f2 = open("gru_test_y.txt", "w")
  127.     for n in np.argmax(test_y, axis=1):
  128.         f2.write(str(n) + "\n")
  129.     f2.close()

  130.     plt.figure(figsize=(8,8))
  131.     sns.heatmap(confm.T, square=True, annot=True,
  132.                 fmt='d', cbar=False, linewidths=.6,
  133.                 cmap="YlGnBu")
  134.     plt.xlabel('True label',size = 14)
  135.     plt.ylabel('Predicted label', size = 14)
  136.     plt.xticks(np.arange(5)+0.5, Labname, size = 12)
  137.     plt.yticks(np.arange(5)+0.5, Labname, size = 12)
  138.     plt.savefig('gru_result.png')
  139.     plt.show()

  140.     #--------------------------------------第六步 验证算法--------------------------------
  141.     # 使用tok对验证数据集重新预处理
  142.     val_seq = tok.texts_to_sequences(val_content)
  143.     val_seq_mat = sequence.pad_sequences(val_seq,maxlen=max_len)
  144.    
  145.     # 对验证集进行预测
  146.     val_pre = model.predict(val_seq_mat)
  147.     print(metrics.classification_report(np.argmax(val_y,axis=1),
  148.                                         np.argmax(val_pre,axis=1),
  149.                                         digits=4))
  150.     print("accuracy", metrics.accuracy_score(np.argmax(val_y, axis=1),
  151.                                              np.argmax(val_pre, axis=1)))
  152.     # 计算时间
  153.     elapsed = (time.clock() - start)
  154.     print("Time used:", elapsed)
复制代码


2.实验结果

训练输出结果如下图所示:



  1. 模型训练
  2. Epoch 1/15

  3. 1/20 [>.............................] - ETA: 47s - loss: 1.6123 - accuracy: 0.1875
  4. 2/20 [==>...........................] - ETA: 18s - loss: 1.6025 - accuracy: 0.2656
  5. 3/20 [===>..........................] - ETA: 18s - loss: 1.5904 - accuracy: 0.3333
  6. 4/20 [=====>........................] - ETA: 18s - loss: 1.5728 - accuracy: 0.3867
  7. 5/20 [======>.......................] - ETA: 17s - loss: 1.5639 - accuracy: 0.4094
  8. 6/20 [========>.....................] - ETA: 17s - loss: 1.5488 - accuracy: 0.4375
  9. 7/20 [=========>....................] - ETA: 16s - loss: 1.5375 - accuracy: 0.4397
  10. 8/20 [===========>..................] - ETA: 16s - loss: 1.5232 - accuracy: 0.4434
  11. 9/20 [============>.................] - ETA: 15s - loss: 1.5102 - accuracy: 0.4358
  12. 10/20 [==============>...............] - ETA: 14s - loss: 1.5014 - accuracy: 0.4250
  13. 11/20 [===============>..............] - ETA: 13s - loss: 1.5053 - accuracy: 0.4233
  14. 12/20 [=================>............] - ETA: 12s - loss: 1.5022 - accuracy: 0.4232
  15. 13/20 [==================>...........] - ETA: 11s - loss: 1.4913 - accuracy: 0.4279
  16. 14/20 [====================>.........] - ETA: 9s - loss: 1.4912 - accuracy: 0.4286
  17. 15/20 [=====================>........] - ETA: 8s - loss: 1.4841 - accuracy: 0.4365
  18. 16/20 [=======================>......] - ETA: 7s - loss: 1.4720 - accuracy: 0.4404
  19. 17/20 [========================>.....] - ETA: 5s - loss: 1.4669 - accuracy: 0.4375
  20. 18/20 [==========================>...] - ETA: 3s - loss: 1.4636 - accuracy: 0.4349
  21. 19/20 [===========================>..] - ETA: 1s - loss: 1.4544 - accuracy: 0.4383
  22. 20/20 [==============================] - ETA: 0s - loss: 1.4509 - accuracy: 0.4400
  23. 20/20 [==============================] - 44s 2s/step - loss: 1.4509 - accuracy: 0.4400 - val_loss: 1.3812 - val_accuracy: 0.3660

  24. Time used: 49.7057119
  25. {'loss': [1.4508591890335083], 'accuracy': [0.4399677813053131],
  26. 'val_loss': [1.381193995475769], 'val_accuracy': [0.3660130798816681]}
复制代码


最终预测结果如下所示:

  1. 模型预测
  2. [[ 30   8   9  17  46]
  3. [ 13  50   9  13  15]
  4. [ 10   4  58  29  19]
  5. [ 11   8   8  73  30]
  6. [ 25   3  23  14 125]]
  7.               precision    recall  f1-score   support

  8.            0     0.3371    0.2727    0.3015       110
  9.            1     0.6849    0.5000    0.5780       100
  10.            2     0.5421    0.4833    0.5110       120
  11.            3     0.5000    0.5615    0.5290       130
  12.            4     0.5319    0.6579    0.5882       190

  13.     accuracy                         0.5169       650
  14.    macro avg     0.5192    0.4951    0.5016       650
  15. weighted avg     0.5180    0.5169    0.5120       650

  16. accuracy 0.5169230769230769

  17.               precision    recall  f1-score   support

  18.            0     0.8960    0.3182    0.4696       352
  19.            1     0.7273    0.5234    0.6087       107
  20.            2     0.0000    0.0000    0.0000         0
  21.            3     0.0000    0.0000    0.0000         0
  22.            4     0.0000    0.0000    0.0000         0

  23.     accuracy                         0.3660       459
  24.    macro avg     0.3247    0.1683    0.2157       459
  25. weighted avg     0.8567    0.3660    0.5020       459

  26. accuracy 0.3660130718954248
  27. Time used: 60.106339399999996
复制代码




五.基于CNN+BiLSTM和注意力的恶意家族检测1.模型构建

该模型的基本步骤如下:

  • 第一步 数据读取
  • 第二步 OneHotEncoder()编码
  • 第三步 使用Tokenizer对词组进行编码
  • 第四步 建立Attention机制
  • 第五步 建立Attention+CNN+BiLSTM模型并训练
  • 第六步 预测及评估
  • 第七步 验证算法

构建模型如下图所示:



  1. Model: "model"
  2. __________________________________________________________________________________________________
  3. Layer (type)                    Output Shape         Param #     Connected to                     
  4. ==================================================================================================
  5. inputs (InputLayer)             [(None, 100)]        0                                            
  6. __________________________________________________________________________________________________
  7. embedding (Embedding)           (None, 100, 256)     256256      inputs[0][0]                     
  8. __________________________________________________________________________________________________
  9. conv1d (Conv1D)                 (None, 100, 256)     196864      embedding[0][0]                  
  10. __________________________________________________________________________________________________
  11. conv1d_1 (Conv1D)               (None, 100, 256)     262400      embedding[0][0]                  
  12. __________________________________________________________________________________________________
  13. conv1d_2 (Conv1D)               (None, 100, 256)     327936      embedding[0][0]                  
  14. __________________________________________________________________________________________________
  15. max_pooling1d (MaxPooling1D)    (None, 25, 256)      0           conv1d[0][0]                     
  16. __________________________________________________________________________________________________
  17. max_pooling1d_1 (MaxPooling1D)  (None, 25, 256)      0           conv1d_1[0][0]                  
  18. __________________________________________________________________________________________________
  19. max_pooling1d_2 (MaxPooling1D)  (None, 25, 256)      0           conv1d_2[0][0]                  
  20. __________________________________________________________________________________________________
  21. concatenate (Concatenate)       (None, 25, 768)      0           max_pooling1d[0][0]              
  22.                                                                  max_pooling1d_1[0][0]            
  23.                                                                  max_pooling1d_2[0][0]            
  24. __________________________________________________________________________________________________
  25. bidirectional (Bidirectional)   (None, 25, 256)      918528      concatenate[0][0]               
  26. __________________________________________________________________________________________________
  27. dense (Dense)                   (None, 25, 128)      32896       bidirectional[0][0]              
  28. __________________________________________________________________________________________________
  29. dropout (Dropout)               (None, 25, 128)      0           dense[0][0]                     
  30. __________________________________________________________________________________________________
  31. attention_layer (AttentionLayer (None, 128)          6500        dropout[0][0]                    
  32. __________________________________________________________________________________________________
  33. dense_1 (Dense)                 (None, 5)            645         attention_layer[0][0]            
  34. ==================================================================================================
  35. Total params: 2,002,025
  36. Trainable params: 1,745,769
  37. Non-trainable params: 256,256
复制代码


完整代码如下所示:

  1. # -*- coding: utf-8 -*-
  2. # By:Eastmount CSDN 2023-06-27
  3. import pickle
  4. import pandas as pd
  5. import numpy as np
  6. import matplotlib.pyplot as plt
  7. import seaborn as sns
  8. import tensorflow as tf
  9. from sklearn import metrics
  10. from sklearn.preprocessing import LabelEncoder,OneHotEncoder
  11. from keras.models import Model
  12. from keras.layers import LSTM, GRU, Activation, Dense, Dropout, Input, Embedding
  13. from keras.layers import Convolution1D, MaxPool1D, Flatten
  14. from keras.optimizers import RMSprop
  15. from keras.layers import Bidirectional
  16. from keras.preprocessing.text import Tokenizer
  17. from keras.preprocessing import sequence
  18. from keras.callbacks import EarlyStopping
  19. from keras.models import load_model
  20. from keras.models import Sequential
  21. from keras.layers.merge import concatenate
  22. import time

  23. start = time.clock()

  24. #---------------------------------------第一步 数据读取------------------------------------
  25. # 读取测数据集
  26. train_df = pd.read_csv("..\\train_dataset.csv")
  27. val_df = pd.read_csv("..\\val_dataset.csv")
  28. test_df = pd.read_csv("..\\test_dataset.csv")
  29. print(train_df.head())

  30. # 解决中文显示问题
  31. plt.rcParams['font.sans-serif'] = ['KaiTi']
  32. plt.rcParams['axes.unicode_minus'] = False

  33. #---------------------------------第二步 OneHotEncoder()编码---------------------------------
  34. # 对数据集的标签数据进行编码  (no apt md5 api)
  35. train_y = train_df.apt
  36. val_y = val_df.apt
  37. test_y = test_df.apt
  38. le = LabelEncoder()
  39. train_y = le.fit_transform(train_y).reshape(-1,1)
  40. val_y = le.transform(val_y).reshape(-1,1)
  41. test_y = le.transform(test_y).reshape(-1,1)
  42. Labname = le.classes_

  43. # 对数据集的标签数据进行one-hot编码
  44. ohe = OneHotEncoder()
  45. train_y = ohe.fit_transform(train_y).toarray()
  46. val_y = ohe.transform(val_y).toarray()
  47. test_y = ohe.transform(test_y).toarray()

  48. #-------------------------------第三步 使用Tokenizer对词组进行编码-------------------------------
  49. # 使用Tokenizer对词组进行编码
  50. max_words = 1000
  51. max_len = 100
  52. tok = Tokenizer(num_words=max_words)

  53. # 提取token:api
  54. train_value = train_df.api
  55. train_content = [str(a) for a in train_value.tolist()]
  56. val_value = val_df.api
  57. val_content = [str(a) for a in val_value.tolist()]
  58. test_value = test_df.api
  59. test_content = [str(a) for a in test_value.tolist()]
  60. tok.fit_on_texts(train_content)
  61. print(tok)

  62. # 保存训练好的Tokenizer和导入
  63. with open('tok.pickle', 'wb') as handle:
  64.     pickle.dump(tok, handle, protocol=pickle.HIGHEST_PROTOCOL)
  65. with open('tok.pickle', 'rb') as handle:
  66.     tok = pickle.load(handle)

  67. # 使用tok.texts_to_sequences()将数据转化为序列
  68. train_seq = tok.texts_to_sequences(train_content)
  69. val_seq = tok.texts_to_sequences(val_content)
  70. test_seq = tok.texts_to_sequences(test_content)

  71. # 将每个序列调整为相同的长度
  72. train_seq_mat = sequence.pad_sequences(train_seq,maxlen=max_len)
  73. val_seq_mat = sequence.pad_sequences(val_seq,maxlen=max_len)
  74. test_seq_mat = sequence.pad_sequences(test_seq,maxlen=max_len)

  75. #-------------------------------第四步 建立Attention机制-------------------------------
  76. """
  77. 由于Keras目前还没有现成的Attention层可以直接使用,我们需要自己来构建一个新的层函数。
  78.   Keras自定义的函数主要分为四个部分,分别是:
  79.   init:初始化一些需要的参数
  80.   bulid:具体来定义权重是怎么样的
  81.   call:核心部分,定义向量是如何进行运算的
  82.   compute_output_shape:定义该层输出的大小

  83. 推荐文章 https://blog.csdn.net/huanghaocs/article/details/95752379
  84. 推荐文章 https://zhuanlan.zhihu.com/p/29201491
  85. """
  86. # Hierarchical Model with Attention
  87. from keras import initializers
  88. from keras import constraints
  89. from keras import activations
  90. from keras import regularizers
  91. from keras import backend as K
  92. from keras.engine.topology import Layer

  93. K.clear_session()

  94. class AttentionLayer(Layer):
  95.     def __init__(self, attention_size=None, **kwargs):
  96.         self.attention_size = attention_size
  97.         super(AttentionLayer, self).__init__(**kwargs)
  98.         
  99.     def get_config(self):
  100.         config = super().get_config()
  101.         config['attention_size'] = self.attention_size
  102.         return config
  103.         
  104.     def build(self, input_shape):
  105.         assert len(input_shape) == 3
  106.         
  107.         self.time_steps = input_shape[1]
  108.         hidden_size = input_shape[2]
  109.         if self.attention_size is None:
  110.             self.attention_size = hidden_size
  111.             
  112.         self.W = self.add_weight(name='att_weight', shape=(hidden_size, self.attention_size),
  113.                                 initializer='uniform', trainable=True)
  114.         self.b = self.add_weight(name='att_bias', shape=(self.attention_size,),
  115.                                 initializer='uniform', trainable=True)
  116.         self.V = self.add_weight(name='att_var', shape=(self.attention_size,),
  117.                                 initializer='uniform', trainable=True)
  118.         super(AttentionLayer, self).build(input_shape)

  119.     #解决方法: Attention The graph tensor has name: model/attention_layer/Reshape:0
  120.     #https://blog.csdn.net/weixin_54227557/article/details/129898614
  121.     def call(self, inputs):
  122.         #self.V = K.reshape(self.V, (-1, 1))
  123.         V = K.reshape(self.V, (-1, 1))
  124.         H = K.tanh(K.dot(inputs, self.W) + self.b)
  125.         #score = K.softmax(K.dot(H, self.V), axis=1)
  126.         score = K.softmax(K.dot(H, V), axis=1)
  127.         outputs = K.sum(score * inputs, axis=1)
  128.         return outputs
  129.    
  130.     def compute_output_shape(self, input_shape):
  131.         return input_shape[0], input_shape[2]

  132. #-------------------------------第五步 建立Attention+CNN模型并训练-------------------------------
  133. # 构建TextCNN模型
  134. num_labels = 5
  135. inputs = Input(name='inputs',shape=[max_len], dtype='float64')
  136. layer = Embedding(max_words+1, 256, input_length=max_len, trainable=False)(inputs)
  137. cnn1 = Convolution1D(256, 3, padding='same', strides = 1, activation='relu')(layer)
  138. cnn1 = MaxPool1D(pool_size=4)(cnn1)
  139. cnn2 = Convolution1D(256, 4, padding='same', strides = 1, activation='relu')(layer)
  140. cnn2 = MaxPool1D(pool_size=4)(cnn2)
  141. cnn3 = Convolution1D(256, 5, padding='same', strides = 1, activation='relu')(layer)
  142. cnn3 = MaxPool1D(pool_size=4)(cnn3)

  143. # 合并三个模型的输出向量
  144. cnn = concatenate([cnn1,cnn2,cnn3], axis=-1)

  145. # BiLSTM+Attention
  146. #bilstm = Bidirectional(LSTM(100, dropout=0.2, recurrent_dropout=0.1, return_sequences=True))(cnn)
  147. bilstm = Bidirectional(LSTM(128, return_sequences=True))(cnn)  #参数保持维度3
  148. layer = Dense(128, activation='relu')(bilstm)
  149. layer = Dropout(0.3)(layer)
  150. attention = AttentionLayer(attention_size=50)(layer)

  151. output = Dense(num_labels, activation='softmax')(attention)
  152. model = Model(inputs=inputs, outputs=output)
  153. model.summary()
  154. model.compile(loss="categorical_crossentropy",
  155.               optimizer='adam',
  156.               metrics=["accuracy"])


  157. flag = "test"
  158. if flag == "train":
  159.     print("模型训练")
  160.     # 模型训练
  161.     model_fit = model.fit(train_seq_mat, train_y, batch_size=128, epochs=15,
  162.                           validation_data=(val_seq_mat,val_y),
  163.                           callbacks=[EarlyStopping(monitor='val_loss',min_delta=0.0005)]
  164.                          )

  165.     # 保存模型
  166.     model.save('cnn_bilstm_model.h5')
  167.     del model  # deletes the existing model
  168.    
  169.     #计算时间
  170.     elapsed = (time.clock() - start)
  171.     print("Time used:", elapsed)
  172.     print(model_fit.history)
  173.    
  174. else:
  175.     print("模型预测")
  176.     model = load_model('cnn_bilstm_model.h5', custom_objects={'AttentionLayer': AttentionLayer(50)}, compile=False)

  177.     #--------------------------------------第六步 预测及评估--------------------------------
  178.     # 对测试集进行预测
  179.     test_pre = model.predict(test_seq_mat)
  180.     confm = metrics.confusion_matrix(np.argmax(test_y,axis=1),np.argmax(test_pre,axis=1))
  181.     print(confm)
  182.     print(metrics.classification_report(np.argmax(test_y,axis=1),
  183.                                         np.argmax(test_pre,axis=1),
  184.                                         digits=4))
  185.     print("accuracy",metrics.accuracy_score(np.argmax(test_y,axis=1),
  186.                                  np.argmax(test_pre,axis=1)))
  187.     # 结果存储
  188.     f1 = open("cnn_bilstm_test_pre.txt", "w")
  189.     for n in np.argmax(test_pre, axis=1):
  190.         f1.write(str(n) + "\n")
  191.     f1.close()

  192.     f2 = open("cnn_bilstm_test_y.txt", "w")
  193.     for n in np.argmax(test_y, axis=1):
  194.         f2.write(str(n) + "\n")
  195.     f2.close()

  196.     plt.figure(figsize=(8,8))
  197.     sns.heatmap(confm.T, square=True, annot=True,
  198.                 fmt='d', cbar=False, linewidths=.6,
  199.                 cmap="YlGnBu")
  200.     plt.xlabel('True label',size = 14)
  201.     plt.ylabel('Predicted label', size = 14)
  202.     plt.xticks(np.arange(5)+0.5, Labname, size = 12)
  203.     plt.yticks(np.arange(5)+0.5, Labname, size = 12)
  204.     plt.savefig('cnn_bilstm_result.png')
  205.     plt.show()

  206.     #--------------------------------------第七步 验证算法--------------------------------
  207.     # 使用tok对验证数据集重新预处理,并使用训练好的模型进行预测
  208.     val_seq = tok.texts_to_sequences(val_content)
  209.     val_seq_mat = sequence.pad_sequences(val_seq,maxlen=max_len)
  210.    
  211.     # 对验证集进行预测
  212.     val_pre = model.predict(val_seq_mat)
  213.     print(metrics.classification_report(np.argmax(val_y, axis=1),
  214.                                         np.argmax(val_pre, axis=1),
  215.                                         digits=4))
  216.     print("accuracy", metrics.accuracy_score(np.argmax(val_y, axis=1),
  217.                                              np.argmax(val_pre, axis=1)))
  218.     # 计算时间
  219.     elapsed = (time.clock() - start)
  220.     print("Time used:", elapsed)
复制代码


2.实验结果

训练输出结果如下图所示:



  1. 模型训练
  2. Epoch 1/15

  3. 1/10 [==>...........................] - ETA: 18s - loss: 1.6074 - accuracy: 0.2188
  4. 2/10 [=====>........................] - ETA: 2s - loss: 1.5996 - accuracy: 0.2383
  5. 3/10 [========>.....................] - ETA: 2s - loss: 1.5903 - accuracy: 0.2500
  6. 4/10 [===========>..................] - ETA: 2s - loss: 1.5665 - accuracy: 0.2793
  7. 5/10 [==============>...............] - ETA: 2s - loss: 1.5552 - accuracy: 0.2750
  8. 6/10 [=================>............] - ETA: 1s - loss: 1.5346 - accuracy: 0.2930
  9. 7/10 [====================>.........] - ETA: 1s - loss: 1.5229 - accuracy: 0.3103
  10. 8/10 [=======================>......] - ETA: 1s - loss: 1.5208 - accuracy: 0.3135
  11. 9/10 [==========================>...] - ETA: 0s - loss: 1.5132 - accuracy: 0.3281
  12. 10/10 [==============================] - ETA: 0s - loss: 1.5046 - accuracy: 0.3400
  13. 10/10 [==============================] - 9s 728ms/step - loss: 1.5046 - accuracy: 0.3400 - val_loss: 1.4659 - val_accuracy: 0.5599

  14. Time used: 13.8141568
  15. {'loss': [1.5045626163482666], 'accuracy': [0.34004834294319153],
  16. 'val_loss': [1.4658586978912354], 'val_accuracy': [0.5599128603935242]}
复制代码


最终预测结果如下所示:

  1. 模型预测
  2. [[ 56  13   1   0  40]
  3. [ 31  53   0   0  16]
  4. [ 54  47   3   1  15]
  5. [ 27  14   1  51  37]
  6. [ 39  16   8   2 125]]
  7.               precision    recall  f1-score   support

  8.            0     0.2705    0.5091    0.3533       110
  9.            1     0.3706    0.5300    0.4362       100
  10.            2     0.2308    0.0250    0.0451       120
  11.            3     0.9444    0.3923    0.5543       130
  12.            4     0.5365    0.6579    0.5910       190

  13.     accuracy                         0.4431       650
  14.    macro avg     0.4706    0.4229    0.3960       650
  15. weighted avg     0.4911    0.4431    0.4189       650

  16. accuracy 0.4430769230769231

  17. havior.
  18.               precision    recall  f1-score   support

  19.            0     0.8571    0.5625    0.6792       352
  20.            1     0.6344    0.5514    0.5900       107
  21.            2     0.0000    0.0000    0.0000         0
  22.            4     0.0000    0.0000    0.0000         0

  23.     accuracy                         0.5599       459
  24.    macro avg     0.3729    0.2785    0.3173       459
  25. weighted avg     0.8052    0.5599    0.6584       459

  26. accuracy 0.5599128540305011
  27. Time used: 23.0178675
复制代码




六.总结

写到这里这篇文章就结束,希望对您有所帮助。忙碌的五月、六月,真的很忙,项目本子论文毕业,等忙完后好好写几篇安全博客,感谢支持和陪伴,尤其是家人的鼓励和支持, 继续加油!

  • 一.恶意软件分析
    1.静态特征
    2.动态特征
  • 二.基于CNN的恶意家族检测
    1.数据集
    2.模型构建
    3.实验结果
  • 三.基于BiLSTM的恶意家族检测
    1.模型构建
    2.实验结果
  • 四.基于BiGRU的恶意家族检测
    1.模型构建
    2.实验结果
  • 五.基于CNN+BiLSTM和注意力的恶意家族检测
    1.模型构建
    2.实验结果



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|安全矩阵

GMT+8, 2024-11-28 03:43 , Processed in 0.016524 second(s), 19 queries .

Powered by Discuz! X4.0

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表