基于上述三种特征提取思路,选择效果最佳的分词方式训练MLP模型,可以训练得到一个函数和参数组合,能满足对已知攻击类型的完全识别。但由于该MLP模型的特征提取发哪个是,部分依赖规则,造成理论上永远存在漏拦和误判。因为对识别目标来说样本永远是不充分的,需要人工不断的Review,发现新的攻击方式,调整特征提取方式,调整参数,重训练…这条路貌似永远没有尽头。
1. 为什么选择LSTM
回顾下上述的Web攻击请求,安全专家一眼便能识别攻击,而机器学习模型需要我们人工来告诉它一系列有区分度的特征,并使用样本数据结合特征,让ML模型模拟出一个函数得到一个是与非的输出。
安全专家看到一个url请求,会根据自身脑海中的“经验记忆”来对url请求进行理解,url请求结构是否正常,是否包含Web攻击关键词,每个片段有什么含义…这些都基于对url请求每个字符上下文的理解。传统的神经网络做不到这一点,然而循环神经网络可以做到这一点,它允许信息持续存在。
刚好利用LSTM对前后文理解优势,利用url请求的前后字符判断是否为Web攻击。这个好处是可以省去特征工程这一繁杂的过程。
正是这种对url请求特征的理解方式,让它具备了一定对未知攻击的识别能力。针对未知攻击变形来说,分词的MLP模型能理解cat,但对变形的 c’a’t则无法理解,因为分词会把它分割开来。而LSTM模型把每个字符当作一个特征,且字符间有上下文联系,无论cat 、c’a't 或 c”’a”’t 、””c’a’t””,在经过嵌入层的转换后,拥有近似的特征向量表达,对模型来说都是近似一回事。
2. 特征向量化和模型训练
这里仅对参数值请求的参数值进行训练。
- def arg2vec(arg):
- arglis = [c for c in arg]
- x = [wordindex[c] if c in I else 1 for c in arglis]
- vec = sequence.pad_sequences([x], maxlenmaxlen=maxlen)
- return np.array(vec).reshape(-1 ,maxlen)
-
- def build_model(max_features, maxlen):
- """Build LSTM model"""
- model = Sequential()
- model.add(Embedding(max_features, 32, input_length=maxlen))
- model.add(LSTM(16))
- model.add(Dropout(0.5))
- model.add(Dense(1))
- model.add(Activation('sigmoid'))
- # model.compile(loss='binary_crossentropy,mean_squared_error',
- # optimizer='Adam,rmsprop')
- model.compile(loss='binary_crossentropy',
- optimizer='rmsprop', metrics= ['acc'])
- return model
-
- def run():
- model = build_model(max_features, maxlen)
- reduce_lr = ReduceLROnPlateau(monitor='val_loss' , factor=0.2, patience= 4 , mode='auto', epsilon = 0.0001 )
- model.fit(X, y, batch_size=512, epochs= 20, validation_split=0.1, callbacks = [reduce_lr])
- return model
-
- if __name__=="__main__":
- startTime = time.time()
- filename = sys.argv[1]
- data = pd.read_csv(filename)
- I = ['v', 'i', '%', '}' , 'r', '^', 'a' , 'c', 'y', '.' , '_', '|', 'h' , 'w', 'd', 'g' , '{', '!', '$' , '[', ' ', '"' , ';', 't ' , '>', '<', ' ', 'l' , 'n', ' r', '(', '=', ':', 'n' , '~', '`', '&', 'x', "'" , '+', 'k', ']', ')', 'f' , 'u', '', '0', 'q', '#' , 'm', '@', '*', 'e', 'z' , '?', 't' , 's', 'b' , 'p' , 'o' , '-', 'j' , '/',',' ]
- wordindex = {k:v+2 for v, k in enumerate (I)}
- max_features = len(wordindex) + 2 # 增加未知态(包含中文)和填充态
- maxlen = 128
- X = np.array([arg2vec(x) for x in data['args']]).reshape(- 1 ,128)
- y = data['lable']
- model = run()
- logger.info("模型存储!")
- modelname = 'model/lstm' + time.strftime('%y_%m_%d' ) + '.h5'
- model.save(modelname)
(编辑:PHP编程网 - 黄冈站长网)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|