From 0ea144bf87e313608361ebbe07b333306a89987b Mon Sep 17 00:00:00 2001 From: Quim Montal Date: Wed, 6 Feb 2019 17:00:43 +0100 Subject: [PATCH] Qualysapi fix (#146) * moved qualysapi to branch master-update * fixing bug of qualys scan without vulnerabilities: vulnWhispererQualysVuln[1361] ERROR Could not process scan/1549159480.84792: 'severity' * change to fixed qualysapi branch * fix bug and changed to qualysapi fork master branch * updated submodule to master branch --- deps/qualysapi | 2 +- requirements.txt | 2 +- vulnwhisp/frameworks/qualys_vuln.py | 13 +++++---- vulnwhisp/vulnwhisp.py | 43 +++++++++++++++-------------- 4 files changed, 33 insertions(+), 27 deletions(-) diff --git a/deps/qualysapi b/deps/qualysapi index ba6792e..42c3b43 160000 --- a/deps/qualysapi +++ b/deps/qualysapi @@ -1 +1 @@ -Subproject commit ba6792e7aa86f96b91d499b3235a196d0a2687ab +Subproject commit 42c3b43ac1e6657be32f7a11d211e3157af4143b diff --git a/requirements.txt b/requirements.txt index c6cefef..9ecc043 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,8 +2,8 @@ pandas==0.20.3 setuptools==40.4.3 pytz==2017.2 Requests==2.18.3 -#qualysapi==5.0.4 lxml==4.1.1 +future-fstrings bs4 jira bottle diff --git a/vulnwhisp/frameworks/qualys_vuln.py b/vulnwhisp/frameworks/qualys_vuln.py index 29ed45f..4a193c0 100644 --- a/vulnwhisp/frameworks/qualys_vuln.py +++ b/vulnwhisp/frameworks/qualys_vuln.py @@ -108,12 +108,15 @@ class qualysVulnScan: def process_data(self, scan_id=None): """Downloads a file from Qualys and normalizes it""" - self.logger.info('Downloading scan ID: {}'.format(scan_id)) scan_report = self.qw.get_scan_details(scan_id=scan_id) - keep_columns = ['category', 'cve_id', 'cvss3_base', 'cvss3_temporal', 'cvss_base', 'cvss_temporal', 'dns', 'exploitability', 'fqdn', 'impact', 'ip', 'ip_status', 'netbios', 'os', 'pci_vuln', 'port', 'protocol', 'qid', 'results', 'severity', 'solution', 'ssl', 'threat', 'title', 'type', 'vendor_reference'] - scan_report = scan_report.filter(keep_columns) - scan_report['severity'] = scan_report['severity'].astype(int).astype(str) - scan_report['qid'] = scan_report['qid'].astype(int).astype(str) + if not scan_report.empty: + keep_columns = ['category', 'cve_id', 'cvss3_base', 'cvss3_temporal', 'cvss_base', 'cvss_temporal', 'dns', 'exploitability', 'fqdn', 'impact', 'ip', 'ip_status', 'netbios', 'os', 'pci_vuln', 'port', 'protocol', 'qid', 'results', 'severity', 'solution', 'ssl', 'threat', 'title', 'type', 'vendor_reference'] + scan_report = scan_report.filter(keep_columns) + scan_report['severity'] = scan_report['severity'].astype(int).astype(str) + scan_report['qid'] = scan_report['qid'].astype(int).astype(str) + else: + self.logger.warn('Scan ID {} has no vulnerabilities, skipping.'.format(scan_id)) + return scan_report return scan_report diff --git a/vulnwhisp/vulnwhisp.py b/vulnwhisp/vulnwhisp.py index e7c8e4b..11805a2 100755 --- a/vulnwhisp/vulnwhisp.py +++ b/vulnwhisp/vulnwhisp.py @@ -839,29 +839,32 @@ class vulnWhispererQualysVuln(vulnWhispererBase): else: self.logger.info('Processing report ID: {}'.format(report_id)) vuln_ready = self.qualys_scan.process_data(scan_id=report_id) - vuln_ready['scan_name'] = scan_name - vuln_ready['scan_reference'] = report_id - vuln_ready.rename(columns=self.COLUMN_MAPPING, inplace=True) + if not vuln_ready.empty: + vuln_ready['scan_name'] = scan_name + vuln_ready['scan_reference'] = report_id + vuln_ready.rename(columns=self.COLUMN_MAPPING, inplace=True) - record_meta = ( - scan_name, - scan_reference, - launched_date, - report_name, - time.time(), - vuln_ready.shape[0], - self.CONFIG_SECTION, - report_id, - 1, - ) - self.record_insert(record_meta) + record_meta = ( + scan_name, + scan_reference, + launched_date, + report_name, + time.time(), + vuln_ready.shape[0], + self.CONFIG_SECTION, + report_id, + 1, + ) + self.record_insert(record_meta) - if output_format == 'json': - with open(relative_path_name, 'w') as f: - f.write(vuln_ready.to_json(orient='records', lines=True)) - f.write('\n') + if output_format == 'json': + with open(relative_path_name, 'w') as f: + f.write(vuln_ready.to_json(orient='records', lines=True)) + f.write('\n') - self.logger.info('Report written to {}'.format(report_name)) + self.logger.info('Report written to {}'.format(report_name)) + else: + return False except Exception as e: self.logger.error('Could not process {}: {}'.format(report_id, str(e)))