Parser of wvs's ( Web Vulnerability Scanner ) exported xml result.
#!/usr/bin/env python
#-*- coding: utf-8 -*-
import bs4
import sys
import logging
logger = logging.getLogger(__file__)
class ParseException(Exception):
def __init__(self, msg='???'):
self.msg = msg
def __str__(self):
return "<ParseException: %s>" % self.msg
class WVSResult(object):
def __init__(self, xml):
try:
self.soup = bs4.BeautifulSoup(xml, "xml")
except:
raise ParseException('Failed to parse xml with bs4')
scan_tag = self.soup.Scan
self.start_url = scan_tag.StartURL.string
self.start_time = scan_tag.StartTime.string
self.finish_time = scan_tag.FinishTime.string
self.scan_time = scan_tag.ScanTime.string
self._reports = []
self._site_files = []
@property
def reports(self):
report_items = self.soup.find_all('ReportItem')
for r in report_items:
id = r.get('id')
name = r.Name.string
details = r.Details.string
affects = r.Affects.string
parameter = r.Parameter.string
severity = r.Severity.string
type = r.Type.string
impact = r.Impact.string
description = r.Description.string
detailed_information = r.DetailedInformation.string
recommendation = r.Recommendation.string
technical_details = {'request': r.TechnicalDetails.Request.string,
'response': r.TechnicalDetails.Response.string
}
report_item = ReportItem(id, name, details, affects, parameter,
severity, type, impact, description,
detailed_information, recommendation,
technical_details)
self._reports.append(report_item)
return self._reports
@property
def site_files(self):
site_files = self.soup.find_all('SiteFile')
for s in site_files:
id = s.get('id')
url = s.FullURL.string
variation_urls = {}
for variation in s.Variations.find_all('Variation'):
variation_url = variation.URL.string
if variation_url is None or not bool(variation_url.strip()):
continue
url_key = hash(variation_url)
if url_key not in variation_urls:
variation_urls[url_key] = variation_url
site_file = SiteFile(id, url, variation_urls.values())
self._site_files.append(site_file)
return self._site_files
class SiteFile(object):
def __init__(self, id, url, variation_urls):
self.id = id
self.url = url
self.variation_urls = variation_urls
def __str__(self):
return '<SiteFile %s (%s)>' % (self.id, self.url)
class ReportItem(object):
def __init__(self, id, name, details, affects, parameter, severity, type,
impact, description, detailed_information, recommendation,
technical_details):
self.id = id
self.name = name
self.details = details
self.affects = affects
self.parameter = parameter
self.severity = severity
self.type = type
self.impact = impact
self.description = description
self.detailed_information = detailed_information
self.recommendation = recommendation
self.technical_details = technical_details
def __str__(self):
return "<ReportItem %s (%s)>" % (self.id, self.name)
class Request(object):
def __init__(self, req_str):
self.req_str = req_str
class Response(object):
def __init__(self, res_str):
self.res_str = res_str
#################################################################
if __name__ == '__main__':
logging.basicConfig(
level=logging.DEBUG if '-v' in sys.argv else logging.WARN,
format='%(asctime)s [%(levelname)s] %(message)s',
datafmt='%Y-%m-%d %H-%M-%S')
with open('export.xml') as f:
xml = f.read()
try:
wvs_result = WVSResult(xml)
except ParseException as e:
logging.info(e.msg)
except:
logging.info("Wrong xml format of wvs's result")
# count = 0
# for r in wvs_result.reports:
# print r.id
# print r.name
# print r.details
# print r.affects
# print r.parameter
# print r.severity
# print r.type
# print r.impact
# print r.description
# print r.detailed_information
# print r.recommendation
# print r.technical_details
# count += 1
# if count == 3:
# break
# count = 0
# for s in wvs_result.site_files:
# print s.id
# print s.url
# for url in s.variation_urls:
# print url
# count += 1
# if count == 3:
# break