第一天开通博客,以此来对学习过程中的心得加以记录,个人对机器学习在网络安全中的应用颇为感兴趣,尝试使用tensorflow实现sql注入、xss等攻击的识别。记录一下过程。
tensorflow是google开源深度学习框架,因其卓越的表现迅速成为深度学习领域的主流工具。
首先是数据集的准备,安全渗透类的数据集并不是很多,搜索了很久后终于找到一个可用的,git地址:https://github.com/foospidy/payloads。样本格式:
sql注入:admin") or ("1"="1
admin") or ("1"="1"--
xss:
使用卷积神经网络识别攻击的思想是将攻击报文转换成44x44的图像矩阵,然后做图像识别。将样本字符串转换成1936维度的向量,如“ admin") or ("1"="1 ”转换为[1,1,0,0,0,0,1,1,1,0,0,1,0,0,1,1,0,1,1,0,1,1,1,0,1,0,0,1,1,1,0
,1,1,1,0,0,1,0,0,0,1,0,0,1,0,1,0,0,1,0,1,0,0,0,0,0,1,1,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,0,0,0,0,1,0,1,0,0,0,0,1,0,0,
0,1,0,0,1,1,0,0,0,1,0,1,0,0,0,1,0,0,1,1,1,1,0,1,0,1,0,0,0,1,0,0,1,1,0,0,0,1,0,0,0,0,0...0,0],通过该方法生成训练样本与测试样本矩阵train_X,train_Y,test_X,test_Y。其中train_X为训练样本,train_Y为训练样本分类,test_X为测试样本,test_Y为测试样本分类。
此例中,我们使用两个卷基层,第一个卷基层设置一个卷积核,第二个卷基层设置两个卷积核,每层包含一组通道,经过池化层与dropout层处理后与softmax层链接,最后得到概率输出。首先定义卷积函数与池化函数:
def conv2d(x, W):
return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')
tf.nn.conv2d是tensorflow提供的二维卷积函数,W为卷积参数,如[5, 5, 2,3],5X5表示卷积核的尺寸,2为通道个数,3表示卷积核数量,padding为边界处理方式。
def max_pool_2x2(x):
return tf.nn.max_pool(x, ksize=[1, 2, 2, 1],strides=[1, 2, 2, 1], padding='SAME')
该池化函数的作用是将2X2的像素块转换为1X1的像素。池化的最终目的是将局部的特征进行聚合操作,从而降低模型的复杂度,减少与隐含层之间的链接数量。定义第一层参数,将1936维向量转换成44X44维图像矩阵:
x = tf.placeholder(tf.float32, [None, 1936])
y_ = tf.placeholder(tf.float32, [None, 3])
x_image = tf.reshape(x, [-1,44,44,1])
第一层卷积核与偏置定义:
W_conv1 = weight_variable([5, 5, 1, 1])
b_conv1 = bias_variable([1])
执行隐含层激活函数relu:
h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1)
执行池化函数:
h_pool1 = max_pool_2x2(h_conv1)
同理,构建第二层卷基层,与第一层的区别是卷积核数量为2,即:W_conv2 = weight_variable([5, 5, 1, 2]),经过第二层激活函数后得到:
h_pool2 = max_pool_2x2(h_conv2)
接下来构建一个包含1024个隐含节点的隐含层与h_pool2链接,定义:
W_fc1 = weight_variable([11 * 11 * 2, 1024])
b_fc1 = bias_variable([1024])
由于经过两层卷积操作后,44X44维的图像变成11X11,第二层卷积使用两个卷基层,所以,W_fc1 为[11 * 11 * 2, 1024],接下来执行隐含层激活函数:
h_pool2_flat = tf.reshape(h_pool2, [-1, 11*11*2])
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)
调用dropout函数随机丢掉样本部分像素点,以此来解决过度拟合的问题:
h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)
调用softmax函数分类:
W_fc2 = weight_variable([1024, 3])
b_fc2 = bias_variable([3])
y_conv=tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2) + b_fc2)
调用loss function来描述模型的分类精度:
cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(y_conv), reduction_indices=[1]))
使用梯度下降算法优化分类器:
train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
至此,使用卷积神经网络识别web攻击的模型已经构建完成,下面使用样本开始训练:
step = 1
group = 100
while step < ((len(train_X))/group):
batch_x = train_X[step*group:step*group+group]
batch_y = train_Y[step*group:step*group+group]
train_step.run(feed_dict={x: batch_x, y_: batch_y, keep_prob: 0.75})
step = step +1
每次取样本中100组数据进行循环训练,训练完成后需要使用测试集对训练结果加以测试,定义:
correct_prediction = tf.equal(tf.argmax(y_conv,1), tf.argmax(y_,1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
其中,y_conv为预测分类结果,y_为真是结果,然后去平均值。测试调用:
accuracy.eval(feed_dict={x: test_X, y_: test_Y, keep_prob: 1.0})
以上即为测试使用卷积神经网络识别web攻击的全部过程,算法相关代码参考tensorflow官网api文档,使用该测试集准确率稳定在90%左右,精度还有待大幅提高,后期需要增大样本数,提高样本质量,并且不断对参数调优,以达到更好的识别率。欢迎交流学习,批评指正。