题目:漏洞分析与预测
具体要求:在cnnvd、cnvd、nvd等漏洞库收集漏洞信息数据,根据漏洞信息对下个月的漏洞信息进行预测。
- 下个月每周的漏洞数量
- 下个月的漏洞分布比例(低、中、高、超高)
- 下个月的漏洞修复比例、 下个月每周的漏洞数量
- 以上都需进行可视化显示
具体思路
- 首先,我们需要获取漏洞信息,我能想到的有三种方法,
- 第一通过Python爬虫获取漏洞信息,但是后来发现各大漏洞库都有很严格的反爬虫技术,所以果断放弃第一种,
- 第二种通过浏览各大网站手动统计,但是后来发现信息量太过庞大,果断放弃(如果不能提高效率,放弃)
- 第三种是后来发现cnvd网站可以个人用户注册,里面有已经统计好的xml文档,下载分析就可以使用了
- 第二,我们拿到数据,通过创建xml文档的dom对象来获取其中的数据,(此处可以参考其它博文或者百度)
- 第三,分析过程也是一些简单的逻辑判断,(代码中注释很多,基本可以看懂)
- 最后,画图依然选择matplotlib库
Python代码实现
第一种方式:通过下载.xml文档获取信息
import xml.dom.minidom
import matplotlib as mpl
import matplotlib.pyplot as plt
myfont = mpl.font_manager.FontProperties(fname=
("C:\Windows\Fonts\simhei.ttf"))
def getData():
'''
:return:返回8月份漏洞信息,包括时间及危险程度
'''
se = []
Time = []
for i in range(1, 5):
dom = xml.dom.minidom.parse('%d.xml' % i)
root = dom.documentElement
serverity = root.getElementsByTagName('serverity')
time = root.getElementsByTagName('openTime')
for j in range(len(serverity)):
se.append(serverity[j].firstChild.data)
for j in range(len(time)):
m = time[j].firstChild.data
m = m.split('-')
s = m[2] # m[1][1:] + '.' +
Time.append(int(s))
return se, Time
def ChangeForm(serverity):
index = 0
for i in serverity:
if i == '高':
serverity[index] = 'High'
elif i == '中':
serverity[index] = 'Middle'
else:
serverity[index] = 'Low'
index += 1
return serverity
def GetGraph(serverity, time):
plt.figure()
plt.subplot(1, 2, 1)
plt.hist(serverity, color='g', alpha=0.5)
plt.xticks()
plt.xlabel(u'严重程度', fontproperties=myfont)
plt.ylabel(u'漏洞数目', fontproperties=myfont)
plt.title(u'8月漏洞严重程度与数量', fontproperties=myfont)
plt.grid()
plt.subplot(1, 2, 2)
plt.hist(time, color='r', alpha=0.5)
plt.xlabel(u'发布日期', fontproperties=myfont)
plt.ylabel(u'漏洞数目', fontproperties=myfont)
plt.title(u'8月漏洞数量与发布日期', fontproperties=myfont)
plt.grid()
plt.show()
def main():
serverity, time = getData()
serverity = ChangeForm(serverity)
GetGraph(serverity, time)
if __name__ == '__main__':
main()
第二种方式:通过收集信息存放于Excel表格,然后通过代码分析
python 代码实现
import xlrd
import numpy as np
import matplotlib.pyplot as pl
# 列表计算平均数
def averagenum(num):
nsum = 0
for i in range(len(num)):
nsum += num[i]
return nsum / len(num)
def read_excel_num():
"""
读取Excel文件获取漏洞数量
:return: 每一行的数据
"""
# print(os.getcwd())
# 打开excel文件
# week为漏洞数量
workbook = xlrd.open_workbook('predict.xlsx')
number = workbook.sheet_by_name("week")
row_num_number = number.nrows
data_number = {}
for i in range(1, row_num_number):
# 获得漏洞数量第i行的数据
row_data0 = number.row_values(i)
print(row_data0)
data_number[row_data0[0]] = row_data0[1]
print(data_number)
return data_number
def read_excel_rank():
"""
读取Excel文件获取漏洞比例
:return: 平均数列表
"""
# 打开excel文件
workbook = xlrd.open_workbook('predict.xlsx')
rank = workbook.sheet_by_name("rank")
# 获取漏洞比例表格行数
row_num_rank = rank.nrows
low_list = []
middle_list = []
high_list = []
super_high = []
for i in range(1, row_num_rank):
# 获取漏洞严重程度第i行的数据
row_data1 = rank.row_values(i)
print(row_data1)
low_list.append(row_data1[1])
middle_list.append(row_data1[2])
high_list.append(row_data1[3])
super_high.append(row_data1[4])
low_avr = averagenum(low_list)
middle_avr = averagenum(middle_list)
high_avr = averagenum(high_list)
super_high_avr = averagenum(super_high)
avr_list = [low_avr, middle_avr, high_avr, super_high_avr]
return avr_list
def qudian_yuce():
"""
求平均数得到下个月四周的漏洞发生量
:return: 平均数列表
"""
avr_list = []
data = read_excel_num()
for i in data:
if i == 5:
break
else:
avr_list.append((data[i] + data[i + 4]) // 2)
return avr_list
def main1():
avr = qudian_yuce()
for i in range(1, 5):
print("下月第 %s 周漏洞数量:%s" % (i, avr[i - 1]))
X1 = [1, 2, 3, 4]
pl.plot(X1, avr)
pl.xticks(X1)
pl.xlabel('week')
pl.ylabel('number')
pl.title('Volume projections')
pl.show()
print()
def main2():
avr_list = read_excel_rank()
X2 = ['low', 'middle', 'high', 'superHigh']
pl.plot(X2, avr_list)
pl.xticks(X2)
pl.xlabel("severity")
pl.ylabel("number/%")
pl.title("Severity projections")
pl.show()
print("下月漏洞比例预测:",avr_list)
if __name__ == '__main__':
main1()
main2()
运行结果



