diff --git a/.gitignore b/.gitignore index 9ea526d9f710326c7b98267b30624635e1090305..1e788cb1852089d59aae33e59d76809676604c59 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ wiser-wcs-reports/.idea/* wiser-wcs-reports/env/* wiser-wcs-reports/example_nmap_output/* +wiser-wcs-reports/__pycache__/* diff --git a/run-cscan.sh b/run-cscan.sh index 86d8999a588da1c960442e846752f5197fe3449b..e2f50595b21cf21be0673a31d781eee796b9cc5d 100644 --- a/run-cscan.sh +++ b/run-cscan.sh @@ -20,7 +20,7 @@ if [ $RESULT -ne 0 ]; then fi cd /service/wiser-wcs-reports -python3 wiser-wcs.py | tail -n 1 > /root/out/genscan-out.json +python3 main.py | tail -n 1 > /root/out/genscan-out.json # outputting the scan result cat /root/out/genscan-out.json diff --git a/wiser-wcs-reports/__init__.py b/wiser-wcs-reports/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/wiser-wcs-reports/main.py b/wiser-wcs-reports/main.py new file mode 100644 index 0000000000000000000000000000000000000000..e446e39dec42a63455de78fe0715c6426d6920ab --- /dev/null +++ b/wiser-wcs-reports/main.py @@ -0,0 +1,72 @@ +from xmljson import badgerfish +from xml.etree.ElementTree import fromstring +from os import listdir +from os.path import isfile, join +import configparser +import json +import w3af +import zap + + +class Options(object): + """ + Dummy class + """ + pass + + +def parse_config_file(filename): + """ + Parse the config file. + + :param filename: the config file + :return: + """ + config = configparser.ConfigParser() + config.read(filename) + return config + + +def reports_json(dir): + """ + Iterate through directory. + :param dir: + :return: + """ + onlyfiles = [f for f in listdir(dir) if f.endswith(".xml") and isfile(join(dir,f))] + reports = dict() + for f in onlyfiles: + inputstream = open(join(dir,f)) + input = inputstream.read() + out = badgerfish.data(fromstring(input)) + reports[f] = out + return reports + + +def list_vulnerabilities(reports): + """ + List all vulnerabilities based on the reports given. + :return: + """ + vulnerabilities = list() + for report in reports.values(): + report_dict = report + if "OWASPZAPReport" in report_dict: + vulnerabilities.extend(zap.WiserZapReport(report_dict['OWASPZAPReport']).get_report()) + if "w3af-run" in report_dict: + vulnerabilities.extend(w3af.WiserW3afReport(report_dict['w3af-run']).get_report()) + return vulnerabilities + +if __name__ == "__main__": + config = parse_config_file('wiser-wcs.cfg') + reports = reports_json(config['cscan_config']['cscan_output']) + print("printing vulnerabilities: ") + vulnerabilities = list_vulnerabilities(reports) + vulnerabilities_list = list() + for vulnerability in vulnerabilities: + print(vulnerability) + vulnerabilities_list.append(vulnerability.__dict__) + + vulnerabilities_json = json.dumps({ "reports": vulnerabilities_list}) + print("printing vulnerabilities JSON: ") + print(vulnerabilities_json) diff --git a/wiser-wcs-reports/nmap.py b/wiser-wcs-reports/nmap.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/wiser-wcs-reports/w3af.py b/wiser-wcs-reports/w3af.py new file mode 100644 index 0000000000000000000000000000000000000000..19dce3833aa55990fe1f006995de5b3535bfdc47 --- /dev/null +++ b/wiser-wcs-reports/w3af.py @@ -0,0 +1,65 @@ +from wiser import WiserReport, WiserVulnerability +import re +from collections import OrderedDict + + +class WiserW3afVulnerability(WiserVulnerability): + + def __init__(self, alert): + super().__init__() + self.parse_report(alert) + + def parse_report(self, alert): + self.short_desc = alert['@name'] + self.desc = alert['description']['$'] + if 'references' in alert: + if 'reference' in alert['references']: + if isinstance(alert['references']['reference'], OrderedDict): + self.reference = alert['references']['reference']['@url'] + if alert['references']['reference'] is list: + self.reference = alert['references']['reference'][0]['@url'] + self.risk_level = alert['@severity'] + if 'long-description' in alert: + self.solution = alert['long-description']['$'] + if '@id' in alert: + if 'references' in alert: + if 'reference' in alert['references']: + if '@title' in alert['references']['reference']: + if alert['references']['reference']['@title'] == 'WASC': + self.wascid = re.sub('[\[\]]', '', alert['@id']) + self.source_pentest="W3af" + self.set_wiser_risk_level() + + def set_wiser_risk_level(self): + if self.risk_level == "Information": + self.w_risk_level = 25 + if self.risk_level == "Low": + self.w_risk_level = 50 + if self.risk_level == "Medium": + self.w_risk_level = 75 + if self.risk_level == "High": + self.w_risk_level = 100 + + +class WiserW3afReport(WiserReport): + + def __init__(self, report): + super().__init__() + self.parse_report(report) + + def parse_report(self, report_dict): + """ + Parses W3af report + :param report: + :return: + """ + self.report = list() + if 'vulnerability' in report_dict: + if type(report_dict['vulnerability'])==list: + for alert in report_dict['vulnerability']: + vulnerability = WiserW3afVulnerability(alert) + self.report.append(vulnerability) + else: + alert = report_dict['vulnerability'] + vulnerability = WiserW3afVulnerability(alert) + self.report.append(vulnerability) diff --git a/wiser-wcs-reports/wiser-wcs.py b/wiser-wcs-reports/wiser-wcs.py deleted file mode 100644 index f5027ebcb82e3e9214a52412d7f1e46bac7066b1..0000000000000000000000000000000000000000 --- a/wiser-wcs-reports/wiser-wcs.py +++ /dev/null @@ -1,266 +0,0 @@ -from xmljson import badgerfish -from xml.etree.ElementTree import fromstring -from os import listdir -from os.path import isfile, join -from collections import OrderedDict -import configparser -import json -import re - - -class Options(object): - """ - Dummy class - """ - pass - - -class IterMixin(object): - def __iter__(self): - for attr, value in self.__dict__.iteritems(): - yield attr, value - - -class WiserVulnerability(IterMixin): - """ - Super class of WISER vulnerabilities. - """ - - """ short description of the vulnerability """ - short_desc = dict() - """ long description """ - desc = dict() - """ reference url """ - reference = dict() - """ how to solve """ - solution = dict() - """ risk level """ - risk_level = dict() - """ WISER risk level """ - w_risk_level = dict() - """id of the vuln """ - wascid = dict() - """ Source pen_test """ - source_pentest = dict() - - def __init__(self): - pass - - def parse_from_alert(self, alert_dict, type): - pass - - def parse_report(self, report_dict): - pass - - """ - Sets WISER risk level to the Vulnerability. - """ - def set_wiser_risk_level(self): - pass - - def __str__(self): - return json.dumps(self.__dict__) - - -class WiserReport(IterMixin): - - report = list() - report_json = dict() - - def __init__(self): - pass - - def parse_report(self, report_dict): - pass - - """ Gets the report from the parsed list of vulnerabilities. - """ - def get_report(self): - return self.report - - -class WiserZapVulnerability(WiserVulnerability): - - def __init__(self, alert): - super().__init__() - self.parse_report(alert) - - @staticmethod - def _pretty(text): - return re.sub('(</?p>)+', '\n', text).strip() - - def parse_report(self, alert): - self.short_desc = self._pretty(alert['alert']['$']) - self.desc = self._pretty(alert['desc']['$']) - self.reference = self._pretty(alert['reference']['$']) - self.risk_level = self._pretty(alert['riskdesc']['$']) - self.solution = self._pretty(alert['solution']['$']) - if 'wascid' in alert: - self.wascid = alert['wascid']['$'] - self.source_pentest="OWASP ZAP" - self.set_wiser_risk_level() - - def set_wiser_risk_level(self): - if self.risk_level == "Low (Low)": - self.w_risk_level = 10 - if self.risk_level == "Low (Medium)": - self.w_risk_level = 20 - if self.risk_level == "Low (High)": - self.w_risk_level = 50 - if self.risk_level == "Medium (Low)": - self.w_risk_level = 20 - if self.risk_level == "Medium (Medium)": - self.w_risk_level = 50 - if self.risk_level == "Medium (High)": - self.w_risk_level = 80 - if self.risk_level == "High (Low)": - self.w_risk_level = 50 - if self.risk_level == "High (Medium)": - self.w_risk_level = 80 - if self.risk_level == "High (High)": - self.w_risk_level = 100 - - -class WiserW3afVulnerability(WiserVulnerability): - - def __init__(self, alert): - super().__init__() - self.parse_report(alert) - - def parse_report(self, alert): - self.short_desc = alert['@name'] - self.desc = alert['description']['$'] - if 'references' in alert: - if 'reference' in alert['references']: - if isinstance(alert['references']['reference'], OrderedDict): - self.reference = alert['references']['reference']['@url'] - if alert['references']['reference'] is list: - self.reference = alert['references']['reference'][0]['@url'] - self.risk_level = alert['@severity'] - if 'long-description' in alert: - self.solution = alert['long-description']['$'] - if '@id' in alert: - if 'references' in alert: - if 'reference' in alert['references']: - if '@title' in alert['references']['reference']: - if alert['references']['reference']['@title'] == 'WASC': - self.wascid = re.sub('[\[\]]', '', alert['@id']) - self.source_pentest="W3af" - self.set_wiser_risk_level() - - def set_wiser_risk_level(self): - if self.risk_level == "Information": - self.w_risk_level = 25 - if self.risk_level == "Low": - self.w_risk_level = 50 - if self.risk_level == "Medium": - self.w_risk_level = 75 - if self.risk_level == "High": - self.w_risk_level = 100 - - -class WiserZapReport(WiserReport): - - def __init__(self, report): - super().__init__() - self.parse_report(report) - - def parse_report(self, report_dict): - """ - Parses OWASP ZAP report - :param report: - :return: - """ - self.report = list() - if 'site' in report_dict: - if 'alerts' in report_dict['site'] and report_dict['site']['alerts'] is not None: - if 'alertitem' in report_dict['site']['alerts']: - if type(report_dict['site']['alerts']['alertitem'])==list: - for i in range(0, len(report_dict['site']['alerts']['alertitem'])): - alert = report_dict['site']['alerts']['alertitem'][i] - vulnerability = WiserZapVulnerability(alert) - self.report.append(vulnerability) - else: - alert = report_dict['site']['alerts']['alertitem'] - vulnerability = WiserZapVulnerability(alert) - self.report.append(vulnerability) - -class WiserW3afReport(WiserReport): - - def __init__(self, report): - super().__init__() - self.parse_report(report) - - def parse_report(self, report_dict): - """ - Parses W3af report - :param report: - :return: - """ - self.report = list() - if 'vulnerability' in report_dict: - if type(report_dict['vulnerability'])==list: - for alert in report_dict['vulnerability']: - vulnerability = WiserW3afVulnerability(alert) - self.report.append(vulnerability) - else: - alert = report_dict['vulnerability'] - vulnerability = WiserW3afVulnerability(alert) - self.report.append(vulnerability) - - -def parse_config_file(filename): - """ - Parse the config file. - - :param filename: the config file - :return: - """ - config = configparser.ConfigParser() - config.read(filename) - return config - - -def reports_json(dir): - """ - Iterate through directory. - :param dir: - :return: - """ - onlyfiles = [f for f in listdir(dir) if isfile(join(dir,f))] - reports = dict() - for f in onlyfiles: - inputstream = open(join(dir,f)) - input = inputstream.read() - out = badgerfish.data(fromstring(input)) - reports[f] = out - return reports - - -def list_vulnerabilities(reports): - """ - List all vulnerabilities based on the reports given. - :return: - """ - vulnerabilities = list() - for report in reports.values(): - report_dict = report - if "OWASPZAPReport" in report_dict: - vulnerabilities.extend(WiserZapReport(report_dict['OWASPZAPReport']).get_report()) - if "w3af-run" in report_dict: - vulnerabilities.extend(WiserW3afReport(report_dict['w3af-run']).get_report()) - return vulnerabilities - -if __name__ == "__main__": - config = parse_config_file('wiser-wcs.cfg') - reports = reports_json(config['cscan_config']['cscan_output']) - print("printing vulnerabilities: ") - vulnerabilities = list_vulnerabilities(reports) - vulnerabilities_list = list() - for vulnerability in vulnerabilities: - print(vulnerability) - vulnerabilities_list.append(vulnerability.__dict__) - - vulnerabilities_json = json.dumps({ "reports": vulnerabilities_list}) - print("printing vulnerabilities JSON: ") - print(vulnerabilities_json) diff --git a/wiser-wcs-reports/wiser.py b/wiser-wcs-reports/wiser.py new file mode 100644 index 0000000000000000000000000000000000000000..597ef1978fb8302ec2498b13897cc650c3a0587f --- /dev/null +++ b/wiser-wcs-reports/wiser.py @@ -0,0 +1,65 @@ +import json + + +class IterMixin(object): + def __iter__(self): + for attr, value in self.__dict__.iteritems(): + yield attr, value + + +class WiserVulnerability(IterMixin): + """ + Super class of WISER vulnerabilities. + """ + + """ short description of the vulnerability """ + short_desc = dict() + """ long description """ + desc = dict() + """ reference url """ + reference = dict() + """ how to solve """ + solution = dict() + """ risk level """ + risk_level = dict() + """ WISER risk level """ + w_risk_level = dict() + """id of the vuln """ + wascid = dict() + """ Source pen_test """ + source_pentest = dict() + + def __init__(self): + pass + + def parse_from_alert(self, alert_dict, type): + pass + + def parse_report(self, report_dict): + pass + + """ + Sets WISER risk level to the Vulnerability. + """ + def set_wiser_risk_level(self): + pass + + def __str__(self): + return json.dumps(self.__dict__) + + +class WiserReport(IterMixin): + + report = list() + report_json = dict() + + def __init__(self): + pass + + def parse_report(self, report_dict): + pass + + """ Gets the report from the parsed list of vulnerabilities. + """ + def get_report(self): + return self.report \ No newline at end of file diff --git a/wiser-wcs-reports/zap.py b/wiser-wcs-reports/zap.py new file mode 100644 index 0000000000000000000000000000000000000000..32e23f126061cdf391939f02a682c54233c729d6 --- /dev/null +++ b/wiser-wcs-reports/zap.py @@ -0,0 +1,71 @@ +from wiser import WiserReport, WiserVulnerability +import re + + +class WiserZapVulnerability(WiserVulnerability): + + def __init__(self, alert): + super().__init__() + self.parse_report(alert) + + @staticmethod + def _pretty(text): + return re.sub('(</?p>)+', '\n', text).strip() + + def parse_report(self, alert): + self.short_desc = self._pretty(alert['alert']['$']) + self.desc = self._pretty(alert['desc']['$']) + self.reference = self._pretty(alert['reference']['$']) + self.risk_level = self._pretty(alert['riskdesc']['$']) + self.solution = self._pretty(alert['solution']['$']) + if 'wascid' in alert: + self.wascid = alert['wascid']['$'] + self.source_pentest="OWASP ZAP" + self.set_wiser_risk_level() + + def set_wiser_risk_level(self): + if self.risk_level == "Low (Low)": + self.w_risk_level = 10 + if self.risk_level == "Low (Medium)": + self.w_risk_level = 20 + if self.risk_level == "Low (High)": + self.w_risk_level = 50 + if self.risk_level == "Medium (Low)": + self.w_risk_level = 20 + if self.risk_level == "Medium (Medium)": + self.w_risk_level = 50 + if self.risk_level == "Medium (High)": + self.w_risk_level = 80 + if self.risk_level == "High (Low)": + self.w_risk_level = 50 + if self.risk_level == "High (Medium)": + self.w_risk_level = 80 + if self.risk_level == "High (High)": + self.w_risk_level = 100 + + +class WiserZapReport(WiserReport): + + def __init__(self, report): + super().__init__() + self.parse_report(report) + + def parse_report(self, report_dict): + """ + Parses OWASP ZAP report + :param report: + :return: + """ + self.report = list() + if 'site' in report_dict: + if 'alerts' in report_dict['site'] and report_dict['site']['alerts'] is not None: + if 'alertitem' in report_dict['site']['alerts']: + if type(report_dict['site']['alerts']['alertitem'])==list: + for i in range(0, len(report_dict['site']['alerts']['alertitem'])): + alert = report_dict['site']['alerts']['alertitem'][i] + vulnerability = WiserZapVulnerability(alert) + self.report.append(vulnerability) + else: + alert = report_dict['site']['alerts']['alertitem'] + vulnerability = WiserZapVulnerability(alert) + self.report.append(vulnerability)