渗透测试自动化报告脚本-----Nessus报告自动化解析--1-html解析

news2024/12/27 15:02:31

本专栏内容主要用于渗透测试工程师应对在工作中的自动化操作难题,高效摸鱼专用

解决问题

1、对Nessus导出的html报告进行自动化的提取操作,包括IP地址,漏洞个数,漏洞等级,漏洞描述,CVE编号等

2、由于Nessus导出的报告内容只有英文,因此对导出的信息进行自动化在线翻译

3、对导出的信息进行自动化处理,形成word文档报告表格

4、支持对单个报告大量漏洞数量的快速处理

TIP:由于不同方式导出的报告html格式可能不同,该脚本可能暂时只支持以下导出格式,但是其解析思路是通用的,各位大佬可以根据其思路自行开发

 以下是我对上述导出报告的html文件的规律分析,也是我对于各个元素的定位参考

根据分析脚本的思路就已经非常明确了:

1、使用Xpath定位到第一个IP位置:/html/body/div[1]/div[3]/div[1]

2、通过相对位置分别定位到其他描述,漏洞个数就是div+1,开始时间,结束时间div+3,系统信息div+5,第一个漏洞名称div+7,第n个漏洞名称就是div+(n-1)3+7,第n个漏洞描述是div+(n-1)3+8

3、对于漏洞的信息,进行修正,漏洞描述,漏洞详情,相关链接,漏洞等级等项,每一个占据2个div,缺失或者增加进行修正即可

4、对于第n个IP的信息,则与之前的IP漏洞个数有关,其相对位置为+7+(高中低信息总个数*3)tip:这里的个数不能直接使用定位到的即div[2]中的个数,和报告中的不相符合,Nessus可能会将漏洞进行合并

源代码如下:

from lxml import etree
import re
class ALocation:
     ''''
     该类中包含有所有的定位函数,其功能主要就是从html文件中定位出所有我们需要的信息
     '''
     def __init__(self,path,BaseLocation):
          self.BaseLocation=BaseLocation          #每个IP名称的div位置,即相对基地址
          self.target_IP=""                       #用于保存该基地址下对应的IP地址
          self.Critical_number=0                  #div[2]中展示的紧急漏洞的个数
          self.High_number=0                      #div[2]中展示高危漏洞的个数
          self.midium_number=0                    #div[2]中展示中危漏洞的个数
          self.low_number=0                       #div[2]中展示低危漏洞的个数
          self.vul_Critical_list=[]               #div+(n-1)*3+7定位到的紧急漏洞列表
          self.vul_Advance_list=[]                #div+(n-1)*3+7定位到的高危漏洞列表
          self.vul_midium_list=[]                 #div+(n-1)*3+7定位到的中危漏洞列表
          self.vul_low_list=[]                    #div+(n-1)*3+7定位到的低危漏洞列表
          self.Vul_Sum=[]                         #定位到漏洞描述
          self.vul_descrition=[]                  #定位到的详情,tip:由于漏洞描述的篇幅较大,尽可能减少一次性的保存,单个保读取更加节约内存,所以该函数需要的是通过漏洞名定位到其描述的方法
          self.Information=[]                     #信息列表
          self.parser=etree.HTMLParser(encoding="utf-8")
          self.XmlTree=etree.parse(path,parser=self.parser)
          self.BaseXpath='/html/body/div[1]/div[3]/'
     def LocalToIP(self):
          #定位以该基地址为起点的IP地址,其格式为一个IP字符串
          IP=self.XmlTree.xpath(self.BaseXpath+'div['+str(self.BaseLocation)+']/text()')
          self.target_IP=IP[0]
          return self.target_IP
     def LocalToCritical(self):
          #定位该基地址中的紧急漏洞的个数,但是其个数可能会与报告中不同
          Critical=self.XmlTree.xpath(self.BaseXpath+'div['+str(int(self.BaseLocation)+1)+']/table/tbody/tr[1]/td[1]/div/text()')
          self.Critical_number=int(Critical[0])
          return self.Critical_number
     def LocalToAdvance(self):
          #定位该基地址中高危漏洞的个数,但是其个数可能会与报告中不同
          Advance=self.XmlTree.xpath(self.BaseXpath+'div['+str(int(self.BaseLocation)+1)+']/table/tbody/tr[1]/td[2]/div/text()')
          self.High_number=int(Advance[0])
          return self.High_number
     def LocalToMidiun(self):
          #定位该基地址中中危漏洞的个数,但是其个数可能会与报告中不同
          medium=self.XmlTree.xpath(self.BaseXpath+'div['+str(int(self.BaseLocation)+1)+']/table/tbody/tr[1]/td[3]/div/text()')
          self.midium_number=int(medium[0])
          return self.midium_number
     def LocalToLow(self):
        #定位低危漏洞的个数,但是其个数可能会与报告中不同
        Low=self.XmlTree.xpath(self.BaseXpath+'div['+str(int(self.BaseLocation)+1)+']/table/tbody/tr[1]/td[4]/div/text()')
        self.low_number=int(Low[0])
        #print(self.low_number)
        return self.low_number
     #本来还需要定位信息个数,但是由于这里的信息数目个数不在报告之内,所以舍去
     def LocalToVul(self):
          i=self.BaseLocation+7
          #定位该基地址下所有的漏洞名称,即div+7+(n-1)*3,根据颜色来判断漏洞等级,为了避免透露扫描器特征,将漏洞编号剔除,保留漏洞名称
          vul=self.XmlTree.xpath(self.BaseXpath+'div['+str(i)+']/@style')
          while(vul!=[]):
               vul=self.XmlTree.xpath(self.BaseXpath+'div['+str(i)+']/@style')
               if '#91243E' in str(vul):
                    data=self.XmlTree.xpath(self.BaseXpath+'div['+str(i)+']/text()')
                    data[0]=data[0].split("-",1)[1]
                    self.vul_Critical_list.append(data[0])
               if '#DD4B50' in str(vul):
                    data=self.XmlTree.xpath(self.BaseXpath+'div['+str(i)+']/text()')
                    data[0]=data[0].split("-",1)[1]
                    self.vul_Advance_list.append(data[0])
               if '#F18C43' in str(vul):
                    data=self.XmlTree.xpath(self.BaseXpath+'div['+str(i)+']/text()')
                    data[0]=data[0].split("-",1)[1]
                    self.vul_midium_list.append(data[0])
               if '#F8C851' in str(vul):
                    data=self.XmlTree.xpath(self.BaseXpath+'div['+str(i)+']/text()')
                    data[0]=data[0].split("-",1)[1]
                    self.vul_low_list.append(data[0])
               if '#67ACE1' in str(vul):
                    data=self.XmlTree.xpath(self.BaseXpath+'div['+str(i)+']/text()')
                    data[0]=data[0].split("-",1)[1]
                    self.Information.append(data[0])
               i=i+3
               vul=self.XmlTree.xpath(self.BaseXpath+'div['+str(i)+']/@style')
     def get_vul_index(self,name):
          #通过漏洞的名称来获取该漏洞位于该IP地址的相对位置编号,基于此判断漏洞的div地址
          for i in self.vul_Critical_list:
               if name==i:
                    return self.vul_Critical_list.index(i)
          for i in self.vul_Advance_list:
               if name==i:
                    return len(self.vul_Critical_list)+self.vul_Advance_list.index(i) 
               #此处不能使用之前定位的漏洞数量,因为报告中会进行合并
          for i in self.vul_midium_list:
               if name==i:
                    return len(self.vul_Critical_list)+len(self.vul_Advance_list)+self.vul_midium_list.index(i)
          for i in self.vul_low_list:
               if name==i:
                    return len(self.vul_Critical_list)+len(self.vul_Advance_list)+len(self.vul_midium_list)+self.vul_low_list.index(i)
     def Check_Base(self,name,condition):
          #对漏洞信息里的div位置进行修正
          index=self.get_vul_index(name)
          i=self.BaseLocation+8
          div=0
          contents=self.XmlTree.xpath(self.BaseXpath+'div['+str(i+index*3)+']')
          for e in contents:
               dis=e.xpath('string(.)')
               if condition==0:#定位解决方案的时候使用
                    if  "See Also" not in dis:
                         div=div-1
               if condition==1:#定位CVE编码的时候使用
                    if 'CVSS v3.0 Base Score' in dis:
                         div=div+1
                    if 'CVSS v2.0 Base Score' in dis:
                         div=div+1
                    if 'CVSS v3.0 Temporal Score' in dis:
                         div=div+1
                    if 'CVSS v2.0 Temporal Score' in dis:
                         div=div+1
                    if "STIG Severity" in dis:
                         div=div+1
                    if  "See Also" not in dis:
                         div=div-1
               if condition==2:#定位插件输出的时候使用
                    if 'CVSS v3.0 Base Score' in dis:
                         div=div+1
                    if 'CVSS v2.0 Base Score' in dis:
                         div=div+1
                    if 'CVSS v3.0 Temporal Score' in dis:
                         div=div+1
                    if 'CVSS v2.0 Temporal Score' in dis:
                         div=div+1
                    if "STIG Severity" in dis:
                         div=div+1
                    if  "See Also" not in dis:
                         div=div-1
                    if "References" not in dis:
                         div=div-1
                    if "Exploitable With" in dis:
                         div=div+1
          return div
     def LocalToDir(self,name):
          #通过漏洞名称定位到漏洞描述
          index=self.get_vul_index(name)
          i=self.BaseLocation+8
          dis=self.XmlTree.xpath(self.BaseXpath+'div['+str(i+index*3)+']/div[2]/text()')
          return dis
     def LocalToPluginsOut(self,name):
          #通过漏洞名称定位到报告中的插件输出部分
          i=self.BaseLocation+8
          index=self.get_vul_index(name)
          plug_out=[]
          number=self.Check_Base(name,2)*2+17
          Pl=self.XmlTree.xpath(self.BaseXpath+'div['+str(i+index*3)+']/div['+str(number)+']/text()')
          while(Pl):
               plug_out.append(Pl)
               number=number+3
               Pl=self.XmlTree.xpath(self.BaseXpath+'div['+str(i+index*3)+']/div['+str(number)+']/text()')
          return plug_out
     
     def LocalToCVE(self,name):
        #根据漏洞名称定位其cve编号
        begin=self.BaseLocation+8
        cve_list=[]
        index=0
        index=self.get_url_Index(name)
        number=self.Check_Base(name,1)*2+12
        Pl=self.XmlTree.xpath(self.BaseXpath+'div['+str(begin+index*3)+']/div['+str(number)+']/table/tbody/tr[1]/td[2]/a/text()')
        j=1
        while(Pl):
            Pl=self.XmlTree.xpath(self.BaseXpath+'div['+str(begin+index*3)+']/div['+str(number)+']/table/tbody/tr['+str(j)+']/td[2]/a/text()')
            if 'CVE' in str(Pl):
                cve_list.append(Pl)
            j=j+1
        return cve_list
     def LocalToSolution(self,name):
          #通过漏洞名称定位漏洞解决方案
          index=self.get_vul_index(name)
          number=self.Check_Base(name,0)*2+8
          i=self.BaseLocation+8
          Pl=self.XmlTree.xpath(self.BaseXpath+'div['+str(i+index*3)+']/div['+str(number)+']/text()')
          return Pl
class Totall:
     #该结构体主要是通过之前IP漏洞信息,定位到下一个漏洞信息,每个漏洞或者信息在报告中占据3个div
     def __init__(self,path):
          self.path=path         #目标html地址
          self.wordtask=[]       #列表中的每一个元素,代表一个IP地址以及其对应的漏洞信息
          self.BeginBaseLocation=1 #即第一个IP的基地址
     def get_list(self):
          one=ALocation(self.path,self.BeginBaseLocation)
          IP=one.LocalToIP()
          pattern =re.compile(r'(([1-9]?\d|1\d\d|2[0-4]\d|25[0-5])\.){3}([1-9]?\d|1\d\d|2[0-4]\d|25[0-5])')
          "因为报告中还有其他信息,通过正则判断定位到的是否为IP地址"
          result=pattern.findall(IP)
          one.LocalToVul()
          if result!=[]:
               self.wordtask.append(one)
          while(result!=[]):
               totallen=len(one.vul_Advance_list)+len(one.vul_Critical_list)+len(one.vul_midium_list)+len(one.vul_low_list)+len(one.Information)
               self.BeginBaseLocation=self.BeginBaseLocation+7+totallen*3
               one=ALocation(self.path,self.BeginBaseLocation)
               IP=one.LocalToIP(self)
               one.LocalToVul(self.BeginBaseLocation)
               result=pattern.findall(IP)
               if result!=[]:
                    self.wordtask.append(one)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/693328.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

配置文件的优先级及maven打包和参数(port)的修改

1、配置文件的优先级 SpringBoot中支持五种配置格式:优先级:命令行参数(–xxxxxx) > java系统属性(-Dxxx xxx) > application.properties > application.yml > application.yaml 虽然springboot支持多种格式配置文件,但是在项目开发时&…

智能仓储货架的电子标签解决方案

近年来,电商和新零售行业的迅猛增长催生了仓储管理场景和运营模式的变革。企业不断寻求“低成本”和“更可靠”的解决方案,加快了仓储管理从粗放型向精细化转变的步伐。仓储管理的技术变革从机械化走向自动化,仓储数智化成为主流趋势。在这个…

chatgpt赋能python:Python语言冒泡排序-深入了解

Python语言冒泡排序 - 深入了解 冒泡排序是一种基本的排序算法,也是学习排序算法的入门算法之一。在Python中,我们可以很容易地实现冒泡排序。 冒泡排序的原理 冒泡排序的原理很简单,大概分为以下几个步骤: 比较相邻的元素&am…

Jnpf低代码开发平台

一、写在前面 低代码开发平台,一个号称能在几分钟的时间里开发出一套公司内部都可使用的应用系统开发工具。 很多人或许都隐隐听说过低代码,因为低代码不仅远名国外,国内的腾讯、阿里、华为、网易、百度等科技巨头也纷纷入局,足以…

蓝桥杯专题-试题版-【打印十字图】【剪格子】【错误票据】【翻硬币】

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例点击跳转>软考全系列点击跳转>蓝桥系列 👉关于作者 专注于Android/Unity和各种游…

【软考网络管理员】2023年软考网管初级常见知识考点(29)-进程管理与存储管理

涉及知识点 进程管理,进程状态,死锁问题,存储管理,页面置换算法,软考网络管理员常考知识点,软考网络管理员网络安全,网络管理员考点汇总。 原创于:CSDN博主-《拄杖盲学轻声码》&…

高速电路设计系列分享-熟悉JESD204B(中)

目录 概要 整体架构流程 技术名词解释 技术细节 1.数据链路层 小结 概要 提示:这里可以添加技术概要 随着高速ADC跨入GSPS范围,与FPGA(定制ASIC)进行数据传输的首选接口协JESD204B。为了捕捉频率范围更高的RF频谱,需要宽带RFADC。在其推动下…

elasticsearch 明明有index但是查不出来

最近用python去query elastricsearch的data,但是我再kibana明明看到有,但是就是查不出来 因为涉及公司隐私,就不截图直接举例子了,我在 discover里面看到的是某条数据的index是 xxx-sss-a-b,但是我写query是xxx-sss-a-…

Spring Boot中的@EnableAutoConfiguration注解

Spring Boot中的EnableAutoConfiguration注解 介绍 Spring Boot是一个非常流行的Java框架,它可以快速创建基于Spring的应用程序。Spring Boot提供了许多自动配置功能,使得开发者可以非常容易地创建一个可运行的应用程序。其中,EnableAutoCo…

macOS Sonoma 14beta 2 With OpenCore 0.9.3 and winPE双引导黑苹果镜像

镜像特点 完全由黑果魏叔官方制作,针对各种机型进行默认配置,让黑苹果安装不再困难。系统镜像设置为双引导分区,全面去除clover引导分区(如有需要,可以自行直接替换opencore分区文件为clover引导文件)备注…

【江西省研究生数学建模竞赛】题目之一 蒸汽发生器倒U型管内液体流动 详细的数学模型及参考文献

【江西省研究生数学建模竞赛】题目之一 蒸汽发生器倒U型管内液体流动 1 题目 2023年江西省研究生数学建模竞赛题目之一 荧汽发生器倒U型管内液体流动 PACTEL压水堆整体测试设备在2009年建造,用于带有垂直倒U型管莱汽发生器的压水堆热液压相关的安全性研究&#x…

MobaXterm 的安装-迅为STM32MP157开发板

MobaXterm 是远端电脑的终极工具箱,作为一个单窗口程序,为程序员,网站管理员,IT 管理员以及更多需要处理远端任务的用户提供了很多实用的功能。MobaXterm 为 windows 桌面提供了所有重要的远端网络工具(SSH, X11, RDP, VNC, FTP, …

Spring Boot中的事务隔离级别

Spring Boot中的事务隔离级别 介绍 Spring Boot是一个流行的Java框架,它提供了许多方便的注解和工具,使得数据库操作变得更加容易。其中,事务隔离级别是Spring Boot中一个非常重要的概念,它可以帮助开发者控制数据库操作的并发性…

postman接口测试之发送post请求

目录 前言: 一、新建目录文件夹 二、新建请求(api接口) 三、添加请求方法、url、及参数 四、发送post请求并且查看请求结果 前言: Postman是一种广泛使用的API开发和测试工具,可以帮助测试人员快速创建请求并检查…

进程与进程间通信

一、什么是进程? 进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配的基本单位,是操作系统结构的基础。进程实体由程序段、数据段以及进程控制块 (PCB) 组成。…

java项目之旅游资源网站ssm源码

风定落花生,歌声逐流水,大家好我是风歌,混迹在java圈的辛苦码农。今天要和大家聊的是一款基于ssm的旅游资源网站。项目源码以及部署相关请联系风歌,文末附上联系信息 。 旅游资源网站源码下载地址: https://download…

【MOOC 测验】第4章 网络层

1‌、下列关于路由算法描述错误的是( ) A. 链路状态算法是一种全局路由算法,每个路由器需要维护全局状态信息B. OSPF 是一种域内路由协议,核心是基于 Dijkstra 最低费用路径算法C. RIP 是一种域内路由算法,核心是基…

手搓GPT系列之 - 通过理解LSTM的反向传播过程,理解LSTM解决梯度消失的原理 - 逐条解释LSTM创始论文全部推导公式,配超多图帮助理解(中篇)

近期因俗事缠身,《通过理解LSTM的反向传播过程,理解LSTM解决梯度消失的原理 - 逐条解释LSTM创始论文全部推导公式,配超多图帮助理解》的中下篇鸽了实在太久有些不好意思了。为了避免烂尾,还是抽时间补上(上篇在此&…

孚盟云 SQL注入漏洞

漏洞说明 孚盟与阿里强强联手将最受青睐的经典C系列产品打造成全新的孚盟云产品,让用户可以用云模式实现信息化管理,让用户的异地办公更加流畅,大大降低中小企业在信息化上成本,用最小的投入享受大型企业级别的信息化服务&#x…

22-UMAP-Towards Fair Multi-Stakeholder Recommender Systems

KY:datasets, neural networks, gaze detection, text tagging AB:RSs通常建立在大型(可能是非常稀疏的)数据集上,因此妨碍了非常复杂去偏技术的使用。我们的方法引入了一个公平函数(fairness functional&a…