基于python 爬取绿盟漏扫html报告

简介:

文章基于pythonBeautifulSoup 爬虫模块爬取绿盟科技漏洞扫描器NOSFUCS的htmll漏洞报告,整理有用数据于excel表上
文末给出扫描器输出报告的html前端页面以及网页源代码,助于分析脚本代码。


collections是Python内建的一个集合模块,提供了许多有用的集合类。

使用dict时,Key是无序的。在对dict做迭代时,我们无法确定Key的顺序。如果要保持Key的顺序,可以用OrderedDict

https://www.cnblogs.com/frydsh/archive/2012/07/10/2585370.html

zip函数接受任意多个(包括0个和1个)序列作为参数,返回一个tuple列表。

Python3.5中,open()不同模式如r、r+ 、w+、w、a、a+有何不同?

r 只能读 
r+ 可读可写 不会创建不存在的文件 从顶部开始写 会覆盖之前此位置的内容 
w+ 可读可写 如果文件存在 则覆盖整个文件不存在则创建 
w 只能写 覆盖整个文件 不存在则创建 
a 只能写 从文件底部添加内容 不存在则创建 
a+ 可读可写 从文件顶部读取内容 从文件底部添加内容 不存在则创建


# author LDF
# date 2018-02-14
try:
    from bs4 import BeautifulSoup
except:
    print('pip3 install beautifulsoup4')
from collections import OrderedDict
import re, os

columns_head = ('漏洞等级', '主机IP', '端口', '协议', '服务', '漏洞名称')
columns_tail = ('详细描述', '解决办法')
columns_tail_default_list = tuple(zip(columns_tail, [''] * len(columns_tail))) #构成有2元素,方便后续做字典?
ip_re = re.compile(r'(?s)IP地址(?:.*?)(.*?)')


def scan_vulns(detail_table):
    clear_re = re.compile(r'\S+')   # 匹配非空白行
    vulns_detail_map = dict()
    for tr in detail_table.findAll('tr', {'class':"solution"}):
        table_id = tr.get('id')
        infos = OrderedDict(columns_tail_default_list)
        for item in tr.findAll('tr'):
            key = item.th.get_text()
            value = item.td.get_text().strip().replace(',', ',') #去除首尾空格,英文','改中文','
            if key in infos:
                if key in ('详细描述', '解决办法'):
                    value = ''.join(clear_re.findall(value)) #删除首尾空格
                infos[key] = value
        vulns_detail_map[table_id] = ','.join(infos.values())
    return vulns_detail_map  # 一个table_id,俩个以逗号隔开的值


def scan(filename):
    try:
        with open(filename, encoding='utf8') as f:
            data = f.read()
        bsObj = BeautifulSoup(data, 'html.parser') ##== bsObj = BeautifulSoup(open('filename.html'))
        vuln_list = bsObj.find('table', {'id':"vuln_list", 'class':"report_table"}).tbody
        vuln_detail = bsObj.find('div', {'id':'vul_detail'})
        vuln_detail_map = scan_vulns(vuln_detail) # 取出网页漏洞描述中的‘详细描述’‘和解决办法’项
        with open('report.csv', 'a') as f:
            ip = ip_re.search(data).group(1)
            for tr in vuln_list.findAll('tr'):
                items = tr.contents
                port = items[1].get_text()
                protocol = items[3].get_text()
                server = items[5].get_text()
                for span in items[7].findAll('span'):
                    vuln_name = span.get_text()
                    level = span.get('class')[0].split('_')[-1]
                    table_id = span.get('onclick').split('\'')[-2]
                    record = (level, ip, port, protocol, server, vuln_name, vuln_detail_map[table_id])
                    f.write(','.join(record) + '\n')
    except Exception as e:
        print(filename, e)

def _dealSum(filenames):
    a = open('report.csv', 'r+')
    b = open('Newreport.csv', 'w')
    for i in a:
        try:
            if '漏洞等级,主机IP,端口,协议,服务,漏洞名称,详细描述,解决办法' in i:
                b.write(i.replace('\n','')+',IP\n')
            else:
                b.write(i.replace('\n', ','+filenames.pop()+'\n'))
        except:
            b.write(i)
    while filenames:
        b.write(",,,,,,,,{}".format(filenames.pop() + '\n'))
        # f1.write(i.replace('\n', 'ii\n'))


def main():
    filenames = []
    with open('report.csv', 'w') as f:
        f.write(','.join(columns_head + columns_tail)+'\n') # 写入数据,并以逗号隔开
    f.close()
    for filename in os.listdir():
        if filename.endswith('.html'):
            filenames.append(filename.rsplit('.', 1)[0]) #先用split('.')方法将字符串以"."开割形成一个字符串数组,然后再通过索引[0]取出所得数组中的第1个元素的值,split方法从左至右处理字符串,而rsplit方法从右至左处理字符串:
            scan(filename)
    _dealSum(filenames)

if __name__ == '__main__':
    main()
    os.remove('./report.csv')




    ##脚本灵感来源:
    #https://www.cnblogs.com/QG-whz/p/4792315.html  http://www.jb51.net/article/57293.htm
    #https://www.jianshu.com/p/5c239bcd05a3
#https://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/001411031239400f7181f65f33a4623bc42276a605debf6000

基于python 爬取绿盟漏扫html报告_第1张图片


1.主机概况
主机风险 非常安全(1.0分)
IP地址 120.197.233.114
系统版本 V6.0R02F03SP06
插件版本 V6.0R02F01.0902
扫描起始时间 2018-02-07 15:42:21
扫描结束时间 2018-02-07 15:59:13
漏洞扫描检查模板 自动匹配扫描
漏洞风险评估分 1.0分
主机风险评估分 1.0分
2.漏洞信息
2.1 漏洞概况
漏洞类别:高危险[0]  中危险[0]  低风险[1]
端口 协议 服务 漏洞 NF已防护
-- ICMP --
  • 允许Traceroute探测
    路由跟踪列表:
    120.197.234.138
    120.197.234.130
    120.197.232.34
    120.197.233.114
  • -
2.2 漏洞详情
允许Traceroute探测
3.配置合规信息
检查项类别: 合规 [0]   不合规 [0]
4.状态合规信息
5.其他信息
5.1 操作系统类型
操作系统名字 版本号
6.参考标准
6.1 单一漏洞风险等级评定标准
危险程度 危险值区域 危险程度说明
7 <= 漏洞风险值 <= 10 攻击者可以远程执行任意命令或者代码,或对系统进行远程拒绝服务攻击。
4 <= 漏洞风险值 < 7 攻击者可以远程创建、修改、删除文件或数据,或对普通服务进行拒绝服务攻击。
0 <= 漏洞风险值 < 4 攻击者可以获取某些系统、服务的信息,或读取系统文件和数据。

说明:

  1. 漏洞的风险值兼容CVSS评分标准。
6.2 单一配置检查项等级评定标准
危险程度 危险值区域 危险程度说明
7 <= 检查项风险值 <= 10 不当的配置导致攻击者可以通过其他方式获得管理员权限、或者只有管理员权限才能加固的配置。
4 <= 检查项风险值 < 7 不当的配置导致攻击者可以对主机进行破坏或者收集主机的信息、或者遭受攻击后,重要事件没有记录。
0 <= 检查项风险值 < 4 不当地配置对主机安全不会造成太大的影响。
6.3 主机风险等级评定标准
主机风险等级 主机风险值区域
非常危险 7.0 <= 主机风险值 <= 10.0
比较危险 5.0 <= 主机风险值 < 7.0
比较安全 2.0 <= 主机风险值 < 5.0
非常安全 0.0 <= 主机风险值 < 2.0

说明:

  1. 按照远程安全评估系统的主机风险评估模型计算主机风险值。根据得到的主机风险值参考“主机风险等级评定标准”标识主机风险等等级。
  2. 将主机风险等级按照风险值的高低进行排序,得到非常危险、比较危险、比较安全、非常安全四种主机风险等级。
  3. 用户可以根据自己的需要修订主机风险等级中的主机风险值范围。


你可能感兴趣的:(Python脚本)