diff --git a/w3af/core/controllers/dependency_check/requirements.py b/w3af/core/controllers/dependency_check/requirements.py index 5ed8c0c4ec..fcda1565c6 100644 --- a/w3af/core/controllers/dependency_check/requirements.py +++ b/w3af/core/controllers/dependency_check/requirements.py @@ -50,7 +50,7 @@ PIPDependency('Halberd', 'halberd', '0.2.4'), PIPDependency('darts.lib.utils', 'darts.util.lru', '0.5'), PIPDependency('jinja2', 'Jinja2', '2.10'), - PIPDependency('vulndb', 'vulndb', '0.1.1'), + PIPDependency('vulndb', 'vulndb', '0.1.3'), PIPDependency('markdown', 'markdown', '2.6.1'), # This was used for testing, but now it's required for diff --git a/w3af/core/controllers/plugins/auth_plugin.py b/w3af/core/controllers/plugins/auth_plugin.py index 90dae889c9..98bf4e001d 100644 --- a/w3af/core/controllers/plugins/auth_plugin.py +++ b/w3af/core/controllers/plugins/auth_plugin.py @@ -26,8 +26,9 @@ import w3af.core.data.kb.config as cf from w3af.core.controllers.plugins.plugin import Plugin -from w3af.core.data.kb.info import Info +from w3af.core.data.constants import severity from w3af.core.data.fuzzer.utils import rand_alnum +from w3af.core.data.kb.vuln import Vuln from w3af.core.data.url.helpers import is_no_content_response @@ -278,10 +279,12 @@ def _log_info_to_kb(self, title, message, include_log_messages=True): '%s') desc = msg_fmt % args - i = Info(title, + i = Vuln(title, desc, + severity.INFORMATION, self._http_response_ids, - self.get_name()) + self.get_name(), + vulndb_id=10116) i.set_uri(self._get_main_authentication_url()) diff --git a/w3af/core/controllers/sql_tools/blind_sqli_time_delay.py b/w3af/core/controllers/sql_tools/blind_sqli_time_delay.py index 2955996f48..6bcba39eea 100644 --- a/w3af/core/controllers/sql_tools/blind_sqli_time_delay.py +++ b/w3af/core/controllers/sql_tools/blind_sqli_time_delay.py @@ -130,7 +130,7 @@ def is_injectable(self, mutant, delay_obj): v = Vuln.from_mutant('Blind SQL injection vulnerability', desc, severity.HIGH, response_ids, 'blind_sqli', - mutant) + mutant, vulndb_id=46) om.out.debug(v.get_desc()) diff --git a/w3af/core/data/kb/tests/test_vuln.py b/w3af/core/data/kb/tests/test_vuln.py index 0e7d559556..8649ecebb1 100644 --- a/w3af/core/data/kb/tests/test_vuln.py +++ b/w3af/core/data/kb/tests/test_vuln.py @@ -23,6 +23,7 @@ from nose.plugins.attrib import attr +from w3af.core.data.constants.vulns import VULNS from w3af.core.data.kb.vuln import Vuln from w3af.core.data.parsers.doc.url import URL from w3af.core.data.request.fuzzable_request import FuzzableRequest @@ -90,3 +91,33 @@ def test_from_mutant(self): self.assertEqual(inst.get_method(), mutant.get_method()) self.assertEqual(inst.get_dc(), mutant.get_dc()) self.assertEqual(inst.get_token_name(), mutant.get_token().get_name()) + + def test_from_mutant_can_match_vulndb_id(self): + url = URL('http://moth/?a=1&b=2') + payloads = ['abc', 'def'] + + freq = FuzzableRequest(url) + fuzzer_config = {} + + created_mutants = QSMutant.create_mutants( + freq, + payloads, + [], + False, + fuzzer_config + ) + mutant = created_mutants[0] + + inst = Vuln.from_mutant( + 'Blind SQL injection vulnerability', + 'desc' * 30, + 'High', + 1, + 'plugin_name', + mutant + ) + self.assertEqual( + inst.get_vulndb_id(), + VULNS.get('Blind SQL injection vulnerability'), + ) + self.assertIsNotNone(inst.get_vulndb_id()) diff --git a/w3af/core/data/kb/vuln.py b/w3af/core/data/kb/vuln.py index 4df133094f..34f8635c40 100644 --- a/w3af/core/data/kb/vuln.py +++ b/w3af/core/data/kb/vuln.py @@ -52,7 +52,7 @@ def __init__(self, name, desc, severity, response_ids, plugin_name, self.set_severity(severity) @classmethod - def from_mutant(cls, name, desc, severity, response_ids, plugin_name, mutant): + def from_mutant(cls, name, desc, severity, response_ids, plugin_name, mutant, vulndb_id=None): """ TODO: I wanted to use super(Vuln, cls).from_mutant here but I was unable to make it work. Refactoring required to avoid code duplication @@ -64,7 +64,7 @@ def from_mutant(cls, name, desc, severity, response_ids, plugin_name, mutant): if not isinstance(mutant, Mutant): raise TypeError('Mutant expected in from_mutant.') - inst = cls(name, desc, severity, response_ids, plugin_name) + inst = cls(name, desc, severity, response_ids, plugin_name, vulndb_id=vulndb_id) inst.set_uri(mutant.get_uri()) inst.set_method(mutant.get_method()) @@ -73,7 +73,7 @@ def from_mutant(cls, name, desc, severity, response_ids, plugin_name, mutant): return inst @classmethod - def from_fr(cls, name, desc, severity, response_ids, plugin_name, freq): + def from_fr(cls, name, desc, severity, response_ids, plugin_name, freq, vulndb_id=None): """ :return: A vuln instance with the proper data set based on the values taken from the fuzzable request. @@ -84,7 +84,7 @@ def from_fr(cls, name, desc, severity, response_ids, plugin_name, freq): mutant = EmptyMutant(freq) return Vuln.from_mutant(name, desc, severity, response_ids, plugin_name, - mutant) + mutant, vulndb_id=vulndb_id) @classmethod def from_vuln(cls, other_vuln): diff --git a/w3af/plugins/audit/cors_origin.py b/w3af/plugins/audit/cors_origin.py index 4aebded3e9..72cb6371a5 100644 --- a/w3af/plugins/audit/cors_origin.py +++ b/w3af/plugins/audit/cors_origin.py @@ -167,7 +167,14 @@ def _allow_methods(self, forged_req, url, origin, response, msg %= (url, ACCESS_CONTROL_ALLOW_METHODS, allow_methods, ', '.join(report_sensitive)) - v = Vuln(name, msg, severity.LOW, response.get_id(), self.get_name()) + v = Vuln( + name, + msg, + severity.LOW, + response.get_id(), + self.get_name(), + vulndb_id=10010, + ) v.set_url(forged_req.get_url()) v[METHODS] = allow_methods_set @@ -184,7 +191,14 @@ def _allow_methods(self, forged_req, url, origin, response, msg %= (url, ACCESS_CONTROL_ALLOW_METHODS, allow_methods, ', '.join(report_strange)) - v = Vuln(name, msg, severity.LOW, response.get_id(), self.get_name()) + v = Vuln( + name, + msg, + severity.LOW, + response.get_id(), + self.get_name(), + vulndb_id=10011, + ) v.set_url(forged_req.get_url()) v[METHODS] = allow_methods_set @@ -205,8 +219,14 @@ def _universal_allow(self, forged_req, url, origin, response, ' and leaves the application open to Cross-domain attacks.' msg %= (forged_req.get_url(), ACCESS_CONTROL_ALLOW_ORIGIN) - v = Vuln('Access-Control-Allow-Origin set to "*"', msg, - severity.LOW, response.get_id(), self.get_name()) + v = Vuln( + 'Access-Control-Allow-Origin set to "*"', + msg, + severity.LOW, + response.get_id(), + self.get_name(), + vulndb_id=10012, + ) v.set_url(forged_req.get_url()) v[DOMAIN] = forged_req.get_url().get_domain() @@ -249,7 +269,14 @@ def _origin_echo(self, forged_req, url, origin, response, ACCESS_CONTROL_ALLOW_ORIGIN, ACCESS_CONTROL_ALLOW_CREDENTIALS) - v = Vuln(name, msg, sev, response.get_id(), self.get_name()) + v = Vuln( + name, + msg, + sev, + response.get_id(), + self.get_name(), + vulndb_id=10013, + ) v.set_url(forged_req.get_url()) v[DOMAIN] = forged_req.get_url().get_domain() @@ -266,7 +293,14 @@ def _origin_echo(self, forged_req, url, origin, response, msg = msg % (forged_req.get_url(), ACCESS_CONTROL_ALLOW_ORIGIN) - v = Vuln(name, msg, sev, response.get_id(), self.get_name()) + v = Vuln( + name, + msg, + sev, + response.get_id(), + self.get_name(), + vulndb_id=10014, + ) v.set_url(forged_req.get_url()) v[DOMAIN] = forged_req.get_url().get_domain() @@ -306,7 +340,8 @@ def _universal_origin_allow_creds(self, forged_req, url, origin, response, ACCESS_CONTROL_ALLOW_CREDENTIALS) v = Vuln('Incorrect withCredentials implementation', msg, - severity.INFORMATION, response.get_id(), self.get_name()) + severity.INFORMATION, response.get_id(), self.get_name(), + vulndb_id=10015) v.set_url(forged_req.get_url()) v[DOMAIN] = forged_req.get_url().get_domain() diff --git a/w3af/plugins/audit/csrf.py b/w3af/plugins/audit/csrf.py index 642e1170c2..a35512a8ae 100644 --- a/w3af/plugins/audit/csrf.py +++ b/w3af/plugins/audit/csrf.py @@ -101,7 +101,7 @@ def audit(self, freq, orig_response, debugging_id): msg = 'Cross Site Request Forgery has been found at: %s' % freq.get_url() v = Vuln.from_fr('CSRF vulnerability', msg, severity.MEDIUM, - orig_response.id, self.get_name(), freq) + orig_response.id, self.get_name(), freq, vulndb_id=13) self.kb_append_uniq(self, 'csrf', v) diff --git a/w3af/plugins/audit/dav.py b/w3af/plugins/audit/dav.py index 932d18dfcc..937aeb8a39 100644 --- a/w3af/plugins/audit/dav.py +++ b/w3af/plugins/audit/dav.py @@ -101,7 +101,7 @@ def _SEARCH(self, domain_path): 'directory: "%s".' % domain_path) v = Vuln('Insecure DAV configuration', msg, severity.MEDIUM, - res.id, self.get_name()) + res.id, self.get_name(), vulndb_id=10081) v.set_url(res.get_url()) v.set_method('SEARCH') @@ -131,7 +131,7 @@ def _PROPFIND(self, domain_path): ' directory: "%s".' % domain_path) v = Vuln('Insecure DAV configuration', msg, severity.MEDIUM, - res.id, self.get_name()) + res.id, self.get_name(), vulndb_id=10081) v.set_url(res.get_url()) v.set_method('PROPFIND') diff --git a/w3af/plugins/audit/deserialization.py b/w3af/plugins/audit/deserialization.py index daa02268c9..9d95b49ca7 100644 --- a/w3af/plugins/audit/deserialization.py +++ b/w3af/plugins/audit/deserialization.py @@ -200,7 +200,8 @@ def _find_delay_in_mutant(self, (mutant, delay_obj), debugging_id=None): severity.HIGH, [r.id for r in responses], self.get_name(), - mutant) + mutant, + vulndb_id=10113) self.kb_append_uniq(self, 'deserialization', v) diff --git a/w3af/plugins/audit/eval.py b/w3af/plugins/audit/eval.py index 7c1a66a13f..255b209c92 100644 --- a/w3af/plugins/audit/eval.py +++ b/w3af/plugins/audit/eval.py @@ -167,7 +167,7 @@ def _find_delay_in_mutant(self, (mutant, delay_obj, debugging_id)): v = Vuln.from_mutant('eval() input injection vulnerability', desc, severity.HIGH, response_ids, - self.get_name(), mutant) + self.get_name(), mutant, vulndb_id=6) self.kb_append_uniq(self, 'eval', v) @@ -186,7 +186,7 @@ def _analyze_echo(self, mutant, response): v = Vuln.from_mutant('eval() input injection vulnerability', desc, severity.HIGH, response.id, - self.get_name(), mutant) + self.get_name(), mutant, vulndb_id=6) self.kb_append_uniq(self, 'eval', v) diff --git a/w3af/plugins/audit/file_upload.py b/w3af/plugins/audit/file_upload.py index 199052dbd8..d2824118f5 100644 --- a/w3af/plugins/audit/file_upload.py +++ b/w3af/plugins/audit/file_upload.py @@ -307,7 +307,7 @@ def _confirm_file_upload(self, path, mutant, http_response, debugging_id): severity.HIGH, [http_response.id, response.id], self.get_name(), - mutant) + mutant, vulndb_id=65) v['file_dest'] = response.get_url() v['file_vars'] = mutant.get_file_vars() diff --git a/w3af/plugins/audit/format_string.py b/w3af/plugins/audit/format_string.py index c81f58a6ab..65d3a039ce 100644 --- a/w3af/plugins/audit/format_string.py +++ b/w3af/plugins/audit/format_string.py @@ -83,7 +83,7 @@ def _analyze_result(self, mutant, response): v = Vuln.from_mutant('Format string vulnerability', desc, severity.MEDIUM, response.id, - self.get_name(), mutant) + self.get_name(), mutant, vulndb_id=10003) v.add_to_highlight(error) diff --git a/w3af/plugins/audit/generic.py b/w3af/plugins/audit/generic.py index d8258d58ac..bb1c1087f5 100644 --- a/w3af/plugins/audit/generic.py +++ b/w3af/plugins/audit/generic.py @@ -260,7 +260,7 @@ def end(self): v = Vuln.from_mutant('Unhandled error in web application', desc, severity.LOW, id_list, self.get_name(), - mutant) + mutant, vulndb_id=73) self.kb_append_uniq(self, 'generic', v) diff --git a/w3af/plugins/audit/global_redirect.py b/w3af/plugins/audit/global_redirect.py index 09cc72cd9d..0e39ac058e 100644 --- a/w3af/plugins/audit/global_redirect.py +++ b/w3af/plugins/audit/global_redirect.py @@ -170,7 +170,7 @@ def _analyze_result(self, mutant, response): desc = 'Global redirect was found at: ' + mutant.found_at() v = Vuln.from_mutant('Insecure redirection', desc, severity.MEDIUM, - response.id, self.get_name(), mutant) + response.id, self.get_name(), mutant, vulndb_id=50) self.kb_append_uniq(self, 'global_redirect', v) diff --git a/w3af/plugins/audit/lfi.py b/w3af/plugins/audit/lfi.py index 33d60642c1..ab1ed48944 100644 --- a/w3af/plugins/audit/lfi.py +++ b/w3af/plugins/audit/lfi.py @@ -179,7 +179,7 @@ def _analyze_result(self, mutant, response): v = Vuln.from_mutant('Local file inclusion vulnerability', desc, severity.MEDIUM, response.id, - self.get_name(), mutant) + self.get_name(), mutant, vulndb_id=17) v['file_pattern'] = file_pattern_match @@ -216,7 +216,7 @@ def _analyze_result(self, mutant, response): v = Vuln.from_mutant('Local file inclusion vulnerability', desc, severity.MEDIUM, response.id, - self.get_name(), mutant) + self.get_name(), mutant, vulndb_id=17) # # Set which part of the source code to match diff --git a/w3af/plugins/audit/memcachei.py b/w3af/plugins/audit/memcachei.py index 93959c2943..550486f4e3 100644 --- a/w3af/plugins/audit/memcachei.py +++ b/w3af/plugins/audit/memcachei.py @@ -147,7 +147,7 @@ def _analyze_echo(self, mutant, debugging_id=None, original_response=None): v = Vuln.from_mutant('Memcache injection vulnerability', desc, severity.HIGH, response_ids, 'memcachei', - mutant) + mutant, vulndb_id=10008) self.kb_append_uniq(self, 'memcachei', v) @@ -171,4 +171,4 @@ def get_long_desc(self): it can identify these injection types: * Batch injection (command injection) - 0x0a/0x0d bytes - """ \ No newline at end of file + """ diff --git a/w3af/plugins/audit/mx_injection.py b/w3af/plugins/audit/mx_injection.py index 68ec855e20..512ecd6d2c 100644 --- a/w3af/plugins/audit/mx_injection.py +++ b/w3af/plugins/audit/mx_injection.py @@ -90,7 +90,7 @@ def _analyze_result(self, mutant, response): v = Vuln.from_mutant('MX injection vulnerability', desc, severity.MEDIUM, response.id, - self.get_name(), mutant) + self.get_name(), mutant, vulndb_id=10002) v.add_to_highlight(mx_error) self.kb_append_uniq(self, 'mx_injection', v) diff --git a/w3af/plugins/audit/os_commanding.py b/w3af/plugins/audit/os_commanding.py index 755409e69c..4eb791da2f 100644 --- a/w3af/plugins/audit/os_commanding.py +++ b/w3af/plugins/audit/os_commanding.py @@ -126,7 +126,7 @@ def _analyze_echo(self, mutant, response): # Create the vuln obj v = Vuln.from_mutant('OS commanding vulnerability', desc, severity.HIGH, response.id, - self.get_name(), mutant) + self.get_name(), mutant, vulndb_id=36) v['os'] = sent_os v['separator'] = sent_separator @@ -201,7 +201,7 @@ def _find_delay_in_mutant(self, (mutant, delay_obj, debugging_id)): v = Vuln.from_mutant('OS commanding vulnerability', desc, severity.HIGH, [r.id for r in responses], - self.get_name(), mutant) + self.get_name(), mutant, vulndb_id=36) v['os'] = delay_obj.get_OS() v['separator'] = delay_obj.get_separator() diff --git a/w3af/plugins/audit/phishing_vector.py b/w3af/plugins/audit/phishing_vector.py index 4b0519748e..c1dd1f162f 100644 --- a/w3af/plugins/audit/phishing_vector.py +++ b/w3af/plugins/audit/phishing_vector.py @@ -116,7 +116,8 @@ def _analyze_result(self, mutant, response): desc %= mutant.found_at() v = Vuln.from_mutant('Phishing vector', desc, severity.LOW, - response.id, self.get_name(), mutant) + response.id, self.get_name(), mutant, + vulndb_id=74) v.add_to_highlight(src_attr) self.kb_append_uniq(self, 'phishing_vector', v) diff --git a/w3af/plugins/audit/preg_replace.py b/w3af/plugins/audit/preg_replace.py index 536fdfb401..82185922df 100644 --- a/w3af/plugins/audit/preg_replace.py +++ b/w3af/plugins/audit/preg_replace.py @@ -78,7 +78,7 @@ def _analyze_result(self, mutant, response): v = Vuln.from_mutant('Unsafe preg_replace usage', desc, severity.HIGH, response.id, - self.get_name(), mutant) + self.get_name(), mutant, vulndb_id=10018) v.add_to_highlight(preg_error_string) self.kb_append_uniq(self, 'preg_replace', v) diff --git a/w3af/plugins/audit/redos.py b/w3af/plugins/audit/redos.py index 4d5146d6f6..b41a1d69ec 100644 --- a/w3af/plugins/audit/redos.py +++ b/w3af/plugins/audit/redos.py @@ -82,7 +82,7 @@ def _find_delay_in_mutant(self, (mutant, delay_obj, debugging_id)): v = Vuln.from_mutant('ReDoS vulnerability', desc, severity.MEDIUM, response_ids, - self.get_name(), mutant) + self.get_name(), mutant, 10009) self.kb_append_uniq(self, 'redos', v) diff --git a/w3af/plugins/audit/response_splitting.py b/w3af/plugins/audit/response_splitting.py index cc8c8104b0..9f1cfecd16 100644 --- a/w3af/plugins/audit/response_splitting.py +++ b/w3af/plugins/audit/response_splitting.py @@ -80,7 +80,7 @@ def _analyze_result(self, mutant, response): desc = 'Response splitting was found at: %s' % mutant.found_at() v = Vuln.from_mutant('Response splitting vulnerability', desc, severity.MEDIUM, response.id, - self.get_name(), mutant) + self.get_name(), mutant, vulndb_id=41) self.kb_append_uniq(self, 'response_splitting', v) @@ -96,9 +96,15 @@ def _report_php_errors(self, mutant, response): ' testing for response splitting: "%s".') args = (mutant.get_token_name(), mutant.get_url(), error) desc %= args - i = Info.from_mutant('Parameter modifies response headers', - desc, response.id, self.get_name(), - mutant) + i = Vuln.from_mutant( + 'Parameter modifies response headers', + desc, + severity.LOW, + response.id, + self.get_name(), + mutant, + vulndb_id=10078, + ) self.kb_append_uniq(self, 'response_splitting', i) break diff --git a/w3af/plugins/audit/rfi.py b/w3af/plugins/audit/rfi.py index 81339ad17f..75994403ec 100644 --- a/w3af/plugins/audit/rfi.py +++ b/w3af/plugins/audit/rfi.py @@ -334,7 +334,7 @@ def _analyze_result(self, rfi_data, mutant, response): v = Vuln.from_mutant('Remote code execution', desc, severity.HIGH, response.id, self.get_name(), - mutant) + mutant, vulndb_id=42) self._vulns.append(v) @@ -348,7 +348,7 @@ def _analyze_result(self, rfi_data, mutant, response): v = Vuln.from_mutant('Remote file inclusion', desc, severity.MEDIUM, response.id, self.get_name(), - mutant) + mutant, vulndb_id=42) self._vulns.append(v) @@ -365,7 +365,7 @@ def _analyze_result(self, rfi_data, mutant, response): v = Vuln.from_mutant('Potential remote file inclusion', desc, severity.LOW, response.id, - self.get_name(), mutant) + self.get_name(), mutant, vulndb_id=42) v.add_to_highlight(error) self._vulns.append(v) diff --git a/w3af/plugins/audit/shell_shock.py b/w3af/plugins/audit/shell_shock.py index 8e0354f0e4..a958c111c4 100644 --- a/w3af/plugins/audit/shell_shock.py +++ b/w3af/plugins/audit/shell_shock.py @@ -107,7 +107,7 @@ def _with_header_echo_injection(self, freq, debugging_id): v = Vuln.from_mutant(u'Shell shock vulnerability', desc, severity.HIGH, [response.id], - self.get_name(), mutant) + self.get_name(), mutant, vulndb_id=68) self.kb_append_uniq(self, 'shell_shock', v) return True @@ -170,7 +170,7 @@ def _find_delay_in_mutant(self, (mutant, delay_obj, debugging_id)): v = Vuln.from_mutant(u'Shell shock vulnerability', desc, severity.HIGH, [r.id for r in responses], - self.get_name(), mutant) + self.get_name(), mutant, vulndb_id=68) self.kb_append_uniq(self, 'shell_shock', v) return True @@ -183,4 +183,4 @@ def get_long_desc(self): This plugin detects shell shock vulnerabilities. See: CVE-2014-6271 - """ \ No newline at end of file + """ diff --git a/w3af/plugins/audit/sqli.py b/w3af/plugins/audit/sqli.py index 6c1d7b7f30..d0ac3c2d1f 100644 --- a/w3af/plugins/audit/sqli.py +++ b/w3af/plugins/audit/sqli.py @@ -199,7 +199,8 @@ def _analyze_result(self, mutant, response): desc %= dbms_type, mutant.found_at() v = Vuln.from_mutant('SQL injection', desc, severity.HIGH, - response.id, self.get_name(), mutant) + response.id, self.get_name(), mutant, + vulndb_id=45) v.add_to_highlight(sql_error_string) v['error'] = sql_error_string diff --git a/w3af/plugins/audit/ssi.py b/w3af/plugins/audit/ssi.py index 3d6510f353..b5f38e4b60 100644 --- a/w3af/plugins/audit/ssi.py +++ b/w3af/plugins/audit/ssi.py @@ -135,7 +135,7 @@ def _analyze_result(self, mutant, response): v = Vuln.from_mutant('Server side include vulnerability', desc, severity.HIGH, response.id, - self.get_name(), mutant) + self.get_name(), mutant, vulndb_id=10016) v.add_to_highlight(expected_result) self.kb_append_uniq(self, 'ssi', v) @@ -219,7 +219,7 @@ def _analyze_persistent(self, freq, response): v = Vuln.from_mutant('Persistent server side include vulnerability', desc, severity.HIGH, response.id, - self.get_name(), mutant) + self.get_name(), mutant, vulndb_id=10017) v.add_to_highlight(matched_expected_result) self.kb_append(self, 'ssi', v) diff --git a/w3af/plugins/audit/ssl_certificate.py b/w3af/plugins/audit/ssl_certificate.py index ef1154f1e8..1261da9729 100644 --- a/w3af/plugins/audit/ssl_certificate.py +++ b/w3af/plugins/audit/ssl_certificate.py @@ -135,7 +135,8 @@ def on_success(domain, port, ssl_sock, result): desc, severity.LOW, 1, - self.get_name()) + self.get_name(), + vulndb_id=10079) v.set_url(self._url_from_parts(domain, port)) self.kb_append(self, 'ssl_v2', v) @@ -333,7 +334,7 @@ def _handle_certificate_validation_error(self, cve, domain, port): desc %= args v = Vuln('Invalid SSL certificate', desc, - severity.LOW, 1, self.get_name()) + severity.LOW, 1, self.get_name(), vulndb_id=10080) v.set_url(self._url_from_parts(domain, port)) self.kb_append(self, 'invalid_ssl_cert', v) diff --git a/w3af/plugins/audit/un_ssl.py b/w3af/plugins/audit/un_ssl.py index 8cc0af79f9..366062efc7 100644 --- a/w3af/plugins/audit/un_ssl.py +++ b/w3af/plugins/audit/un_ssl.py @@ -122,7 +122,7 @@ def audit(self, freq, orig_response, debugging_id): v = Vuln.from_fr('Secure content over insecure channel', desc, severity.MEDIUM, response_ids, - self.get_name(), freq) + self.get_name(), freq, vulndb_id=10001) self.kb_append(self, 'un_ssl', v) diff --git a/w3af/plugins/audit/websocket_hijacking.py b/w3af/plugins/audit/websocket_hijacking.py index 81d9efee92..ac5a96f4ed 100644 --- a/w3af/plugins/audit/websocket_hijacking.py +++ b/w3af/plugins/audit/websocket_hijacking.py @@ -124,7 +124,8 @@ def check_is_open_web_socket(self, web_socket_url, web_socket_version): msg %= web_socket_url v = Vuln.from_fr('Open WebSocket', msg, severity.LOW, - upgrade_response.id, self.get_name(), upgrade_request) + upgrade_response.id, self.get_name(), upgrade_request, + vulndb_id=10004) self.kb_append_uniq(self, 'websocket_hijacking', v) return True @@ -173,7 +174,7 @@ def check_is_restricted_by_origin_with_match_bug(self, web_socket_url, v = Vuln.from_fr('Insecure WebSocket Origin filter', msg, severity.MEDIUM, upgrade_response.id, - self.get_name(), upgrade_request) + self.get_name(), upgrade_request, vulndb_id=10005) self.kb_append_uniq(self, 'websocket_hijacking', v) return True @@ -219,7 +220,7 @@ def check_is_restricted_by_origin(self, web_socket_url, web_socket_version): v = Vuln.from_fr('Origin restricted WebSocket', msg, severity.LOW, upgrade_response.id, self.get_name(), - upgrade_request) + upgrade_request, vulndb_id=10006) self.kb_append_uniq(self, 'websocket_hijacking', v) return True @@ -264,7 +265,7 @@ def check_need_basic_auth_origin_not_restricted(self, web_socket_url, v = Vuln.from_fr('Websockets CSRF vulnerability', msg, severity.HIGH, upgrade_response.id, - self.get_name(), upgrade_request) + self.get_name(), upgrade_request, vulndb_id=10007) self.kb_append_uniq(self, 'websocket_hijacking', v) return True @@ -307,7 +308,7 @@ def check_need_cookie_origin_not_restricted(self, web_socket_url, v = Vuln.from_fr('Websockets CSRF vulnerability', msg, severity.HIGH, upgrade_response.id, - self.get_name(), upgrade_request) + self.get_name(), upgrade_request, vulndb_id=10007) self.kb_append_uniq(self, 'websocket_hijacking', v) return True diff --git a/w3af/plugins/audit/xss.py b/w3af/plugins/audit/xss.py index 7cb81fa55f..9544d7cc32 100644 --- a/w3af/plugins/audit/xss.py +++ b/w3af/plugins/audit/xss.py @@ -138,7 +138,7 @@ def _report_vuln(self, mutant, response, mod_value): v = Vuln.from_mutant('Cross site scripting vulnerability', desc, vuln_severity, response.id, self.get_name(), - mutant) + mutant, vulndb_id=55) v.add_to_highlight(mod_value) self.kb_append_uniq(self, 'xss', v) @@ -337,7 +337,7 @@ def _report_persistent_vuln(self, mutant, response, mutant_response_id, v = Vuln.from_mutant(name, desc, vuln_severity, response_ids, self.get_name(), - mutant) + mutant, vulndb_id=56) v['persistent'] = True v['write_payload'] = mutant diff --git a/w3af/plugins/audit/xst.py b/w3af/plugins/audit/xst.py index 862d5c6ebb..94e1d959de 100644 --- a/w3af/plugins/audit/xst.py +++ b/w3af/plugins/audit/xst.py @@ -81,7 +81,7 @@ def audit(self, freq, orig_response, debugging_id): v = Vuln.from_fr('Cross site tracing vulnerability', desc, severity.LOW, response.id, self.get_name(), - freq) + freq, vulndb_id=63) om.out.vulnerability(v.get_desc(), severity=v.get_severity()) self.kb_append(self, 'xst', v) diff --git a/w3af/plugins/audit/xxe.py b/w3af/plugins/audit/xxe.py index 766296ca9f..231c79ac9e 100644 --- a/w3af/plugins/audit/xxe.py +++ b/w3af/plugins/audit/xxe.py @@ -321,7 +321,8 @@ def _analyze_result(self, mutant, response): desc %= mutant.found_at() v = Vuln.from_mutant('XML External Entity', desc, severity.HIGH, - response.id, self.get_name(), mutant) + response.id, self.get_name(), mutant, + vulndb_id=10064) v.add_to_highlight(pattern_match) diff --git a/w3af/plugins/bruteforce/basic_auth.py b/w3af/plugins/bruteforce/basic_auth.py index 87f4a547a8..d2e9d5fb0b 100644 --- a/w3af/plugins/bruteforce/basic_auth.py +++ b/w3af/plugins/bruteforce/basic_auth.py @@ -127,7 +127,7 @@ def _brute_worker(self, url, combination, debugging_id): ' A valid user and password combination is: %s/%s .') desc %= (url, user, password_for_report) v = Vuln('Guessable credentials', desc, - severity.HIGH, response.id, self.get_name()) + severity.HIGH, response.id, self.get_name(), vulndb_id=10114) v.set_url(url) v['user'] = user diff --git a/w3af/plugins/bruteforce/form_auth.py b/w3af/plugins/bruteforce/form_auth.py index c947eef28f..c95dc13050 100644 --- a/w3af/plugins/bruteforce/form_auth.py +++ b/w3af/plugins/bruteforce/form_auth.py @@ -474,7 +474,7 @@ def _brute_worker(self, mutant, login_failed_result_list, combination, session, desc %= (freq_url, password_for_report) v = Vuln.from_mutant('Guessable credentials', desc, severity.HIGH, - resp.id, self.get_name(), mutant) + resp.id, self.get_name(), mutant, 10115) v['user'] = user v['pass'] = password v['response'] = resp diff --git a/w3af/plugins/crawl/dot_listing.py b/w3af/plugins/crawl/dot_listing.py index 804356a04b..03b2fc43f8 100644 --- a/w3af/plugins/crawl/dot_listing.py +++ b/w3af/plugins/crawl/dot_listing.py @@ -100,7 +100,7 @@ def _check_and_analyze(self, domain_path): desc %= (response.get_url()) v = Vuln('.listing file found', desc, severity.LOW, response.id, - self.get_name()) + self.get_name(), vulndb_id=10024) v.set_url(response.get_url()) kb.kb.append(self, 'dot_listing', v) @@ -123,7 +123,7 @@ def _check_and_analyze(self, domain_path): ', '.join(real_groups)) v = Vuln('Operating system username and group leak', desc, - severity.LOW, response.id, self.get_name()) + severity.LOW, response.id, self.get_name(), 10025) v.set_url(response.get_url()) kb.kb.append(self, 'dot_listing', v) diff --git a/w3af/plugins/crawl/open_api.py b/w3af/plugins/crawl/open_api.py index 4ebd57c4bf..5f01ce1566 100644 --- a/w3af/plugins/crawl/open_api.py +++ b/w3af/plugins/crawl/open_api.py @@ -24,6 +24,8 @@ import w3af.core.controllers.output_manager as om import w3af.core.data.kb.knowledge_base as kb import w3af.core.data.kb.config as cf +from w3af.core.data.constants import severity +from w3af.core.data.kb.vuln import Vuln from w3af.core.data.options.opt_factory import opt_factory from w3af.core.data.parsers.doc.url import URL @@ -269,10 +271,12 @@ def _report_to_kb_if_needed(self, http_response, parser): desc %= (http_response.get_url(), '\n - '.join(parser.get_parsing_errors())) - i = Info('Failed to parse Open API specification', + i = Vuln('Failed to parse Open API specification', desc, + severity.INFORMATION, http_response.id, - self.get_name()) + self.get_name(), + vulndb_id=10117) i.set_url(http_response.get_url()) kb.kb.append(self, 'open_api', i) diff --git a/w3af/plugins/crawl/phpinfo.py b/w3af/plugins/crawl/phpinfo.py index e38c3392fe..b707736df6 100644 --- a/w3af/plugins/crawl/phpinfo.py +++ b/w3af/plugins/crawl/phpinfo.py @@ -206,7 +206,7 @@ def _check_and_analyze(self, domain_path, php_info_filename): desc %= (response.get_url(), php_version.group(2), sysinfo.group(1)) v = Vuln('phpinfo() file found', desc, severity.MEDIUM, - response.id, self.get_name()) + response.id, self.get_name(), 10027) v.set_url(response.get_url()) kb.kb.append(self, 'phpinfo', v) diff --git a/w3af/plugins/crawl/phpinfo_analysis/analysis.py b/w3af/plugins/crawl/phpinfo_analysis/analysis.py index a890c65bd8..342630185b 100644 --- a/w3af/plugins/crawl/phpinfo_analysis/analysis.py +++ b/w3af/plugins/crawl/phpinfo_analysis/analysis.py @@ -40,7 +40,7 @@ def register_globals(response): if rg == 'On': desc = 'The phpinfo()::register_globals is on.' v = Vuln('PHP register_globals: On', desc, - severity.MEDIUM, response.id, 'phpinfo') + severity.MEDIUM, response.id, 'phpinfo', vulndb_id=10028) v.set_url(response.get_url()) kb.kb.append('phpinfo', 'phpinfo', v) @@ -48,7 +48,14 @@ def register_globals(response): else: rg_name = 'PHP register_globals: Off' rg_desc = 'The phpinfo()::register_globals is off.' - i = Info(rg_name, rg_desc, response.id, 'phpinfo') + i = Vuln( + rg_name, + rg_desc, + severity.INFORMATION, + response.id, + 'phpinfo', + vulndb_id=10085, + ) i.set_url(response.get_url()) kb.kb.append('phpinfo', 'phpinfo', i) @@ -64,7 +71,7 @@ def allow_url_fopen(response): desc = 'The phpinfo()::allow_url_fopen is enabled.' v = Vuln('PHP allow_url_fopen: On', desc, - severity.MEDIUM, response.id, 'phpinfo') + severity.MEDIUM, response.id, 'phpinfo', 10029) v.set_url(response.get_url()) kb.kb.append('phpinfo', 'phpinfo', v) @@ -80,7 +87,7 @@ def allow_url_include(response): desc = 'The phpinfo()::allow_url_include is enabled.' v = Vuln('PHP allow_url_include: On', desc, - severity.MEDIUM, response.id, 'phpinfo') + severity.MEDIUM, response.id, 'phpinfo', vulndb_id=10030) v.set_url(response.get_url()) kb.kb.append('phpinfo', 'phpinfo', v) @@ -96,7 +103,7 @@ def display_errors(response): desc = 'The phpinfo()::display_errors is enabled.' v = Vuln('PHP display_errors: On', desc, - severity.MEDIUM, response.id, 'phpinfo') + severity.MEDIUM, response.id, 'phpinfo', vulndb_id=10031) v.set_url(response.get_url()) kb.kb.append('phpinfo', 'phpinfo', v) @@ -112,7 +119,7 @@ def expose_php(response): desc = 'The phpinfo()::expose_php is enabled.' v = Vuln('PHP expose_php: On', desc, - severity.MEDIUM, response.id, 'phpinfo') + severity.MEDIUM, response.id, 'phpinfo', vulndb_id=10032) v.set_url(response.get_url()) kb.kb.append('phpinfo', 'phpinfo', v) @@ -143,7 +150,7 @@ def lowest_privilege_test(response): desc %= (lpt_uname, lpt_uid, lpt_gid) v = Vuln('PHP running with privileged user', desc, - severity.MEDIUM, response.id, 'phpinfo') + severity.MEDIUM, response.id, 'phpinfo', 10033) v.set_url(response.get_url()) kb.kb.append('phpinfo', 'phpinfo', v) @@ -181,7 +188,7 @@ def disable_functions(response): desc %= (', '.join(dfe),) v = Vuln('PHP disable_functions weakness', desc, - severity.MEDIUM, response.id, 'phpinfo') + severity.MEDIUM, response.id, 'phpinfo', vulndb_id=10034) v.set_url(response.get_url()) kb.kb.append('phpinfo', 'phpinfo', v) @@ -224,7 +231,7 @@ def curl_file_support(response): ' functions to bypass safe_mode and open_basedir' ' restrictions.') v = Vuln('PHP curl_file_support:not_fixed', desc, - severity.MEDIUM, response.id, 'phpinfo') + severity.MEDIUM, response.id, 'phpinfo', vulndb_id=10035) v.set_url(response.get_url()) kb.kb.append('phpinfo', 'phpinfo', v) @@ -244,7 +251,7 @@ def cgi_force_redirect(response): desc = 'The phpinfo()::CGI::force_redirect is disabled.' v = Vuln('PHP cgi_force_redirect: Off', desc, - severity.MEDIUM, response.id, 'phpinfo') + severity.MEDIUM, response.id, 'phpinfo', vulndb_id=10036) v.set_url(response.get_url()) kb.kb.append('phpinfo', 'phpinfo', v) @@ -260,7 +267,7 @@ def session_cookie_httponly(response): desc = 'The phpinfo()::session.cookie_httponly is off.' v = Vuln('PHP session.cookie_httponly: Off', desc, - severity.MEDIUM, response.id, 'phpinfo') + severity.MEDIUM, response.id, 'phpinfo', vulndb_id=10037) v.set_url(response.get_url()) kb.kb.append('phpinfo', 'phpinfo', v) @@ -277,7 +284,7 @@ def session_save_path(response): desc = ('The phpinfo()::session.save_path may be set to a world-' 'readable directory.') v = Vuln('Word readable PHP session_save_path', desc, - severity.LOW, response.id, 'phpinfo') + severity.LOW, response.id, 'phpinfo', vulndb_id=10038) v.set_url(response.get_url()) kb.kb.append('phpinfo', 'phpinfo', v) @@ -294,7 +301,7 @@ def session_use_trans(response): desc = ('The phpinfo()::session.use_trans is enabled. This makes' ' session hijacking easier.') v = Vuln('PHP session_use_trans: On', desc, - severity.MEDIUM, response.id, 'phpinfo') + severity.MEDIUM, response.id, 'phpinfo', vulndb_id=10039) v.set_url(response.get_url()) kb.kb.append('phpinfo', 'phpinfo', v) @@ -312,7 +319,7 @@ def default_charset(response): ' makes PHP scripts vulnerable to various charset' ' encoding XSS.') v = Vuln('PHP default_charset: Off', desc, - severity.MEDIUM, response.id, 'phpinfo') + severity.MEDIUM, response.id, 'phpinfo', vulndb_id=10040) v.set_url(response.get_url()) kb.kb.append('phpinfo', 'phpinfo', v) @@ -330,7 +337,7 @@ def enable_dl(response): if rg == 'On': desc = 'The phpinfo()::enable_dl is on.' v = Vuln('PHP enable_dl: On', desc, - severity.MEDIUM, response.id, 'phpinfo') + severity.MEDIUM, response.id, 'phpinfo', vulndb_id=10041) v.set_url(response.get_url()) kb.kb.append('phpinfo', 'phpinfo', v) @@ -338,7 +345,14 @@ def enable_dl(response): else: ed_name = 'PHP enable_dl: Off' ed_desc = 'The phpinfo()::enable_dl is off.' - i = Info(ed_name, ed_desc, response.id, 'phpinfo') + i = Vuln( + ed_name, + ed_desc, + severity.INFORMATION, + response.id, + 'phpinfo', + vulndb_id=10093, + ) i.set_url(response.get_url()) kb.kb.append('phpinfo', 'phpinfo', i) @@ -363,7 +377,7 @@ def memory_limit(response): desc %= (memory_limit_mo.group(1),) v = Vuln('PHP high memory limit', desc, - severity.MEDIUM, response.id, 'phpinfo') + severity.MEDIUM, response.id, 'phpinfo', vulndb_id=10042) v.set_url(response.get_url()) kb.kb.append('phpinfo', 'phpinfo', v) @@ -389,7 +403,7 @@ def post_max_size(response): desc %= (post_max_size_mo.group(1),) v = Vuln('PHP high POST max size', desc, - severity.LOW, response.id, 'phpinfo') + severity.LOW, response.id, 'phpinfo', vulndb_id=10043) v.set_url(response.get_url()) kb.kb.append('phpinfo', 'phpinfo', v) @@ -415,7 +429,7 @@ def upload_max_filesize(response): desc %= (upload_max_filesize_mo.group(1),) v = Vuln('PHP upload_max_filesize:high', desc, - severity.LOW, response.id, 'phpinfo') + severity.LOW, response.id, 'phpinfo', vulndb_id=10044) v.set_url(response.get_url()) kb.kb.append('phpinfo', 'phpinfo', v) @@ -431,7 +445,7 @@ def upload_tmp_dir(response): desc = 'The phpinfo()::upload_tmp_dir may be set to world-readable directory.' v = Vuln('PHP upload_tmp_dir is world readable', desc, - severity.LOW, response.id, 'phpinfo') + severity.LOW, response.id, 'phpinfo', vulndb_id=10045) v.set_url(response.get_url()) kb.kb.append('phpinfo', 'phpinfo', v) @@ -446,7 +460,14 @@ def file_uploads(response): return desc = 'The phpinfo()::file_uploads is enabled.' - i = Info('PHP file_uploads: On', desc, response.id, 'phpinfo') + i = Vuln( + 'PHP file_uploads: On', + desc, + severity.LOW, + response.id, + 'phpinfo', + vulndb_id=10086, + ) i.set_url(response.get_url()) kb.kb.append('phpinfo', 'phpinfo', i) @@ -464,13 +485,13 @@ def magic_quotes_gpc(response): if mqg == 'On': desc = 'The phpinfo()::magic_quotes_gpc is on.' - i = Info('PHP magic_quotes_gpc: On', desc, response.id, - 'phpinfo') + i = Vuln('PHP magic_quotes_gpc: On', desc, severity.LOW, response.id, + 'phpinfo', vulndb_id=10087) else: desc = 'The phpinfo()::magic_quotes_gpc is off.' - i = Info('PHP magic_quotes_gpc: Off', desc, response.id, - 'phpinfo') + i = Vuln('PHP magic_quotes_gpc: Off', desc, severity.LOW, response.id, + 'phpinfo', vulndb_id=10088) i.set_url(response.get_url()) kb.kb.append('phpinfo', 'phpinfo', i) @@ -488,14 +509,14 @@ def open_basedir(response): if obd == 'no value': desc = 'The phpinfo()::open_basedir is not set.' - i = Info('PHP open_basedir:disabled', desc, response.id, - 'phpinfo') + i = Vuln('PHP open_basedir:disabled', desc, response.id, severity.LOW, + 'phpinfo', vulndb_id=10089) else: desc = 'The phpinfo()::open_basedir is set to %s.' desc %= open_basedir_mo.group(1) - i = Info('PHP open_basedir:enabled', desc, response.id, - 'phpinfo') + i = Vuln('PHP open_basedir:enabled', desc, severity.LOW, response.id, + 'phpinfo', vulndb_id=10090) i.set_url(response.get_url()) kb.kb.append('phpinfo', 'phpinfo', i) @@ -512,12 +533,12 @@ def session_hash_function(response): if session_hash_function_mo.group(1) == 0 \ or session_hash_function_mo.group(1) != 'no': desc = 'The phpinfo()::session.hash_function uses the insecure md5 algorithm.' - i = Info('PHP session.hash_function:md5', desc, response.id, - 'phpinfo') + i = Vuln('PHP session.hash_function:md5', desc, severity.LOW, response.id, + 'phpinfo', vulndb_id=10091) else: desc = 'The phpinfo()::session.hash_function uses the insecure sha algorithm.' - i = Info('PHP session.hash_function:sha', desc, response.id, - 'phpinfo') + i = Vuln('PHP session.hash_function:sha', desc, severity.LOW, response.id, + 'phpinfo', vulndb_id=10092) i.set_url(response.get_url()) diff --git a/w3af/plugins/crawl/ria_enumerator.py b/w3af/plugins/crawl/ria_enumerator.py index df0f34a888..79fcbd90bf 100644 --- a/w3af/plugins/crawl/ria_enumerator.py +++ b/w3af/plugins/crawl/ria_enumerator.py @@ -121,8 +121,8 @@ def _analyze_gears_manifest(self, url, response, file_name): ' information that may get cached on the client.') desc %= url - i = Info('Gears manifest resource', desc, response.id, - self.get_name()) + i = Vuln('Gears manifest resource', desc, severity.LOW, response.id, + self.get_name(), vulndb_id=10082) i.set_url(url) kb.kb.append(self, url, i) @@ -149,8 +149,14 @@ def _analyze_crossdomain_clientaccesspolicy(self, url, response, file_name): desc = 'The "%s" file at: "%s" is not a valid XML.' desc %= (file_name, response.get_url()) - i = Info('Invalid RIA settings file', desc, response.id, - self.get_name()) + i = Vuln( + 'Invalid RIA settings file', + desc, + severity.LOW, + response.id, + self.get_name(), + vulndb_id=10083, + ) i.set_url(response.get_url()) kb.kb.append(self, 'info', i) @@ -170,7 +176,7 @@ def _analyze_crossdomain_clientaccesspolicy(self, url, response, file_name): desc %= (file_name, response.get_url()) v = Vuln('Insecure RIA settings', desc, severity.LOW, - response.id, self.get_name()) + response.id, self.get_name(), vulndb_id=10026) v.set_url(response.get_url()) v.set_method('GET') @@ -186,8 +192,8 @@ def _analyze_crossdomain_clientaccesspolicy(self, url, response, file_name): ' access from "%s".' desc %= (file_name, response.get_url(), url) - i = Info('Cross-domain allow ACL', desc, response.id, - self.get_name()) + i = Vuln('Cross-domain allow ACL', desc, severity.LOW, response.id, + self.get_name(), vulndb_id=10084) i.set_url(response.get_url()) i.set_method('GET') diff --git a/w3af/plugins/crawl/robots_txt.py b/w3af/plugins/crawl/robots_txt.py index 445b72286a..3f701df2ca 100644 --- a/w3af/plugins/crawl/robots_txt.py +++ b/w3af/plugins/crawl/robots_txt.py @@ -26,7 +26,8 @@ from w3af.core.controllers.exceptions import RunOnce from w3af.core.controllers.misc.decorators import runonce from w3af.core.controllers.core_helpers.fingerprint_404 import is_404 -from w3af.core.data.kb.info import Info +from w3af.core.data.constants import severity +from w3af.core.data.kb.vuln import Vuln class robots_txt(CrawlPlugin): @@ -71,7 +72,14 @@ def crawl(self, fuzzable_request, debugging_id): ' analysis queue.') desc %= robots_url - i = Info('robots.txt file', desc, http_response.id, self.get_name()) + i = Vuln( + 'robots.txt file', + desc, + severity.LOW, + http_response.id, + self.get_name(), + vulndb_id=10073, + ) i.set_url(robots_url) kb.kb.append(self, 'robots.txt', i) diff --git a/w3af/plugins/grep/analyze_cookies.py b/w3af/plugins/grep/analyze_cookies.py index 2784ef2049..f264c75f09 100644 --- a/w3af/plugins/grep/analyze_cookies.py +++ b/w3af/plugins/grep/analyze_cookies.py @@ -118,7 +118,14 @@ def _collect_cookies(self, request, response, cookie_object, desc = 'The URL: "%s" sent the cookie: "%s".' desc = desc % (response.get_url(), cstr) - i = CookieInfo('Cookie', desc, response.id, self.get_name()) + i = CookieVuln( + 'Cookie', + desc, + severity.INFORMATION, + response.id, + self.get_name(), + vulndb_id=10110, + ) i.set_url(response.get_url()) i.set_cookie_object(cookie_object) @@ -158,7 +165,14 @@ def _parse_cookie(self, request, response, cookie_header_value): ' incorrect format: "%s" that does NOT respect the RFC.' desc = desc % cookie_header_value - i = CookieInfo('Invalid cookie', desc, response.id, self.get_name()) + i = CookieVuln( + 'Invalid cookie', + desc, + severity.INFORMATION, + response.id, + self.get_name(), + vulndb_id=10111, + ) i.set_url(response.get_url()) i.set_cookie_string(cookie_header_value) @@ -208,7 +222,7 @@ def _http_only(self, request, response, cookie_obj, desc = desc % response.get_url() v = CookieVuln('Cookie without HttpOnly', desc, vuln_severity, - response.id, self.get_name()) + response.id, self.get_name(), vulndb_id=22) v.set_url(response.get_url()) v.set_cookie_object(cookie_obj) @@ -252,7 +266,7 @@ def _ssl_cookie_via_http(self, request, response): v = CookieVuln('Secure cookies over insecure channel', desc, severity.HIGH, response.id, - self.get_name()) + self.get_name(), vulndb_id=10046) v.set_url(response.get_url()) v.set_cookie_object(info.get_cookie_object()) @@ -290,8 +304,14 @@ def _match_cookie_fingerprint(self, request, response, cookie_obj): ' The remote platform is: "%s".' desc = desc % (response.get_url(), system_name) - i = CookieInfo('Identified cookie', desc, response.id, - self.get_name()) + i = CookieVuln( + 'Identified cookie', + desc, + severity.INFORMATION, + response.id, + self.get_name(), + vulndb_id=10112, + ) i.set_cookie_object(cookie_obj) i.set_url(response.get_url()) i['httpd'] = system_name @@ -332,7 +352,7 @@ def _secure_over_http(self, request, response, cookie_obj, desc = desc % response.get_url() v = CookieVuln('Secure cookie over HTTP', desc, severity.HIGH, - response.id, self.get_name()) + response.id, self.get_name(), vulndb_id=10047) v.set_url(response.get_url()) v.set_cookie_object(cookie_obj) @@ -359,7 +379,8 @@ def _not_secure_over_https(self, request, response, cookie_obj, desc = desc % response.get_url() v = CookieVuln('Secure flag missing in HTTPS cookie', desc, - severity.MEDIUM, response.id, self.get_name()) + severity.MEDIUM, response.id, self.get_name(), + vulndb_id=25) v.set_url(response.get_url()) v.set_cookie_object(cookie_obj) diff --git a/w3af/plugins/grep/cross_domain_js.py b/w3af/plugins/grep/cross_domain_js.py index a645a96343..ccf4cf0f24 100644 --- a/w3af/plugins/grep/cross_domain_js.py +++ b/w3af/plugins/grep/cross_domain_js.py @@ -26,8 +26,9 @@ from w3af import ROOT_PATH from w3af.core.controllers.plugins.grep_plugin import GrepPlugin -from w3af.core.data.kb.info import Info +from w3af.core.data.constants import severity from w3af.core.data.kb.info_set import InfoSet +from w3af.core.data.kb.vuln import Vuln from w3af.core.data.options.opt_factory import opt_factory from w3af.core.data.options.option_types import INPUT_FILE from w3af.core.data.options.option_list import OptionList @@ -114,8 +115,8 @@ def _analyze_domain(self, response, script_full_url, script_tag): desc %= (smart_str_ignore(response_url), smart_str_ignore(script_domain)) - i = Info('Cross-domain javascript source', desc, - response.id, self.get_name()) + i = Vuln('Cross-domain javascript source', desc, severity.INFORMATION, + response.id, self.get_name(), vulndb_id=10107) i.set_url(response_url) i.add_to_highlight(to_highlight) i[CrossDomainInfoSet.ITAG] = script_domain diff --git a/w3af/plugins/grep/html_comments.py b/w3af/plugins/grep/html_comments.py index 0dec17e5a5..ee695a6b49 100644 --- a/w3af/plugins/grep/html_comments.py +++ b/w3af/plugins/grep/html_comments.py @@ -27,6 +27,8 @@ import w3af.core.controllers.output_manager as om import w3af.core.data.parsers.parser_cache as parser_cache import w3af.core.data.kb.knowledge_base as kb +from w3af.core.data.constants import severity +from w3af.core.data.kb.vuln import Vuln from w3af.core.data.quick_match.multi_in import MultiIn from w3af.core.data.db.disk_dict import DiskDict @@ -110,11 +112,13 @@ def _interesting_word(self, comment, request, response): ' This could be interesting.') desc %= (word, response.get_url()) - i = Info.from_fr('Interesting HTML comment', + i = Vuln.from_fr('Interesting HTML comment', desc, + severity.INFORMATION, response.id, self.get_name(), - request) + request, + vulndb_id=10105) i.add_to_highlight(word) i[HTMLCommentHidesHTMLInfoSet.ITAG] = comment @@ -154,11 +158,13 @@ def _html_in_comment(self, comment, request, response): ' This could be interesting.') desc %= (comment, response.get_url()) - i = Info.from_fr('HTML comment contains HTML code', + i = Vuln.from_fr('HTML comment contains HTML code', desc, + severity.INFORMATION, response.id, self.get_name(), - request) + request, + vulndb_id=10106) i.set_uri(response.get_uri()) i.add_to_highlight(html_in_comment.group(0)) i[HTMLCommentHidesHTMLInfoSet.ITAG] = comment diff --git a/w3af/plugins/grep/http_auth_detect.py b/w3af/plugins/grep/http_auth_detect.py index 00c1f6751a..757ffd180c 100644 --- a/w3af/plugins/grep/http_auth_detect.py +++ b/w3af/plugins/grep/http_auth_detect.py @@ -82,7 +82,7 @@ def _find_auth_uri(self, response): ' the URI.') desc %= response.get_uri() v = Vuln('Basic HTTP credentials', desc, severity.HIGH, - response.id, self.get_name()) + response.id, self.get_name(), vulndb_id=10049) v.set_url(response.get_url()) v.add_to_highlight(response.get_uri().url_string) @@ -113,7 +113,8 @@ def _find_auth_uri(self, response): desc %= (response.get_url(), url) v = Vuln('Basic HTTP credentials', desc, - severity.HIGH, response.id, self.get_name()) + severity.HIGH, response.id, self.get_name(), + vulndb_id=10049) v.set_url(response.get_url()) v.add_to_highlight(url.url_string) @@ -144,8 +145,14 @@ def _report_no_realm(self, response): ' 401) but the www-authenticate header is not present.' ' This requires human verification.') desc %= response.get_url() - i = Info('Authentication without www-authenticate header', desc, - response.id, self.get_name()) + i = Vuln( + 'Authentication without www-authenticate header', + desc, + severity.LOW, + response.id, + self.get_name(), + vulndb_id=10076, + ) i.set_url(response.get_url()) kb.kb.append(self, 'non_rfc_auth', i) @@ -180,11 +187,13 @@ def _analyze_401(self, response): if 'ntlm' in realm.lower(): v = Vuln('NTLM authentication', desc, - vuln_severity, response.id, self.get_name()) + vuln_severity, response.id, self.get_name(), + vulndb_id=10050) else: v = Vuln('HTTP Basic authentication', desc, - vuln_severity, response.id, self.get_name()) + vuln_severity, response.id, self.get_name(), + vulndb_id=10051) v.set_url(response.get_url()) v['message'] = realm diff --git a/w3af/plugins/grep/path_disclosure.py b/w3af/plugins/grep/path_disclosure.py index bb038ce0a6..95138d909d 100644 --- a/w3af/plugins/grep/path_disclosure.py +++ b/w3af/plugins/grep/path_disclosure.py @@ -107,7 +107,7 @@ def find_path_disclosure(self, request, response): desc %= (response.get_url(), match) v = Vuln('Path disclosure vulnerability', desc, severity.LOW, - response.id, self.get_name()) + response.id, self.get_name(), vulndb_id=10023) v.add_to_highlight(match) v.set_url(real_url) v['path'] = match diff --git a/w3af/plugins/grep/ssn.py b/w3af/plugins/grep/ssn.py index dca1ee0150..b3f41d20ea 100644 --- a/w3af/plugins/grep/ssn.py +++ b/w3af/plugins/grep/ssn.py @@ -72,7 +72,7 @@ def grep(self, request, response): ' Number: "%s".') desc %= (uri, validated_ssn) v = Vuln('US Social Security Number disclosure', desc, - severity.LOW, response.id, self.get_name()) + severity.LOW, response.id, self.get_name(), vulndb_id=10053) v.set_uri(uri) v.add_to_highlight(found_ssn) diff --git a/w3af/plugins/grep/strange_headers.py b/w3af/plugins/grep/strange_headers.py index 2e82643a7d..f78b759a92 100644 --- a/w3af/plugins/grep/strange_headers.py +++ b/w3af/plugins/grep/strange_headers.py @@ -22,12 +22,14 @@ import w3af.core.data.kb.knowledge_base as kb from w3af.core.controllers.plugins.grep_plugin import GrepPlugin -from w3af.core.data.kb.info import Info +from w3af.core.data.constants import severity from w3af.core.data.kb.info_set import InfoSet # Remember that this headers are only the ones SENT BY THE SERVER TO THE # CLIENT. Headers must be uppercase in order to compare them +from w3af.core.data.kb.vuln import Vuln + COMMON_HEADERS = {'ACCEPT-RANGES', 'AGE', 'ALLOW', @@ -120,7 +122,14 @@ def grep(self, request, response): ' requires manual analysis.') desc %= (header_name, hvalue) - i = Info('Strange header', desc, response.id, self.get_name()) + i = Vuln( + 'Strange header', + desc, + severity.INFORMATION, + response.id, + self.get_name(), + vulndb_id=10108, + ) i.add_to_highlight(hvalue, header_name) i.set_url(response.get_url()) i[StrangeHeaderInfoSet.ITAG] = header_name @@ -151,8 +160,8 @@ def _content_location_not_300(self, request, response): desc %= (response.get_url(), header_value, response.get_code()) - i = Info('Content-Location HTTP header anomaly', desc, - response.id, self.get_name()) + i = Vuln('Content-Location HTTP header anomaly', desc, severity.INFORMATION, + response.id, self.get_name(), vulndb_id=10109) i.set_url(response.get_url()) i.add_to_highlight('content-location') diff --git a/w3af/plugins/grep/strange_parameters.py b/w3af/plugins/grep/strange_parameters.py index 23df2eb127..ce8fd5a92b 100644 --- a/w3af/plugins/grep/strange_parameters.py +++ b/w3af/plugins/grep/strange_parameters.py @@ -29,7 +29,6 @@ from w3af.core.controllers.exceptions import BaseFrameworkException from w3af.core.data.misc.encoding import smart_str_ignore from w3af.core.data.bloomfilter.scalable_bloom import ScalableBloomFilter -from w3af.core.data.kb.info import Info from w3af.core.data.kb.vuln import Vuln @@ -105,13 +104,13 @@ def _analyze_strange(self, request, response, ref, token_name, token_value): args = tuple(smart_str_ignore(i) for i in args) desc %= args - i = Info('Uncommon query string parameter', desc, response.id, - self.get_name()) - i['parameter_value'] = token_value - i.add_to_highlight(token_value) - i.set_uri(ref) + v = Vuln('Uncommon query string parameter', desc, severity.LOW, response.id, + self.get_name(), vulndb_id=10019) + v['parameter_value'] = token_value + v.add_to_highlight(token_value) + v.set_uri(ref) - self.kb_append(self, 'strange_parameters', i) + self.kb_append(self, 'strange_parameters', v) return True def _analyze_SQL(self, request, response, ref, token_name, token_value): @@ -131,7 +130,7 @@ def _analyze_SQL(self, request, response, ref, token_name, token_value): desc %= (response.get_uri(), token_name, token_value) v = Vuln('Parameter has SQL sentence', desc, severity.LOW, - response.id, self.get_name()) + response.id, self.get_name(), vulndb_id=10075) v['parameter_value'] = token_value v.add_to_highlight(token_value) v.set_uri(ref) diff --git a/w3af/plugins/grep/symfony.py b/w3af/plugins/grep/symfony.py index 3bdf41dcb6..1b5cebea9d 100644 --- a/w3af/plugins/grep/symfony.py +++ b/w3af/plugins/grep/symfony.py @@ -22,8 +22,9 @@ import re import w3af.core.data.parsers.parser_cache as parser_cache +from w3af.core.data.constants import severity -from w3af.core.data.kb.info import Info +from w3af.core.data.kb.vuln import Vuln from w3af.core.data.options.opt_factory import opt_factory from w3af.core.data.options.option_list import OptionList from w3af.core.controllers.plugins.grep_plugin import GrepPlugin @@ -70,8 +71,14 @@ def grep(self, request, response): ' and contains a form that has CSRF protection disabled.') desc %= response.get_url() - i = Info('Symfony Framework with CSRF protection disabled', - desc, response.id, self.get_name()) + i = Vuln( + 'Symfony Framework with CSRF protection disabled', + desc, + severity.MEDIUM, + response.id, + self.get_name(), + vulndb_id=10071, + ) i.set_url(response.get_url()) self.kb_append_uniq(self, 'symfony', i, 'URL') diff --git a/w3af/plugins/infrastructure/allowed_methods.py b/w3af/plugins/infrastructure/allowed_methods.py index f116e4a9a5..13fe6ec8b6 100644 --- a/w3af/plugins/infrastructure/allowed_methods.py +++ b/w3af/plugins/infrastructure/allowed_methods.py @@ -27,6 +27,8 @@ from w3af.core.controllers.exceptions import RunOnce from w3af.core.controllers.misc.group_by_min_key import group_by_min_key from w3af.core.controllers.exceptions import HTTPRequestException +from w3af.core.data.constants import severity +from w3af.core.data.kb.vuln import Vuln from w3af.core.data.options.opt_factory import opt_factory from w3af.core.data.options.option_list import OptionList from w3af.core.data.bloomfilter.scalable_bloom import ScalableBloomFilter @@ -241,8 +243,14 @@ def _can_bruteforce(self, url): ' defaulted to GET instead of returning a "Not Implemented"' ' response.') response_ids = [arg_response.get_id(), get_response.get_id()] - i = Info('Non existent methods default to GET', - desc, response_ids, self.get_name()) + i = Vuln( + 'Non existent methods default to GET', + desc, + severity.INFORMATION, + response_ids, + self.get_name(), + vulndb_id=10095, + ) i.set_url(url) kb.kb.append(self, 'custom-configuration', i) @@ -301,7 +309,14 @@ def _analyze_methods(self, url, _allowed_methods, id_list): ' include DAV methods and should be disabled: %s') desc = desc % (url, ', '.join(_allowed_methods)) - i = Info('DAV methods enabled', desc, id_list, self.get_name()) + i = Vuln( + 'DAV methods enabled', + desc, + severity.INFORMATION, + id_list, + self.get_name(), + vulndb_id=10096, + ) i.set_url(url) i['methods'] = _allowed_methods diff --git a/w3af/plugins/infrastructure/dns_wildcard.py b/w3af/plugins/infrastructure/dns_wildcard.py index 4479a89590..37366cce5b 100644 --- a/w3af/plugins/infrastructure/dns_wildcard.py +++ b/w3af/plugins/infrastructure/dns_wildcard.py @@ -29,6 +29,8 @@ from w3af.core.controllers.exceptions import BaseFrameworkException, RunOnce from w3af.core.controllers.misc.decorators import runonce from w3af.core.controllers.misc.fuzzy_string_cmp import fuzzy_not_equal, fuzzy_equal +from w3af.core.data.constants import severity +from w3af.core.data.kb.vuln import Vuln from w3af.core.data.url.helpers import is_no_content_response from w3af.core.data.dc.headers import Headers from w3af.core.data.kb.info import Info @@ -103,10 +105,12 @@ def _test_ip_address(self, original_response, domain): args = (modified_response.get_uri(), original_response.get_uri()) desc %= args - i = Info('Default virtual host', + i = Vuln('Default virtual host', desc, + severity.INFORMATION, modified_response.id, - self.get_name()) + self.get_name(), + vulndb_id=10101) i.set_url(modified_response.get_url()) kb.kb.append(self, 'dns_wildcard', i) @@ -133,10 +137,12 @@ def _test_dns(self, original_response, dns_wildcard_url): ' of "%s" differ from the contents of "%s".') desc %= (dns_wildcard_url, original_response.get_url()) - i = Info('No DNS wildcard', + i = Vuln('No DNS wildcard', desc, + severity.INFORMATION, [original_response.id, modified_response.id], - self.get_name()) + self.get_name(), + vulndb_id=10102) i.set_url(dns_wildcard_url) kb.kb.append(self, 'dns_wildcard', i) diff --git a/w3af/plugins/infrastructure/dot_net_errors.py b/w3af/plugins/infrastructure/dot_net_errors.py index 7c5db0c477..ce8180cf70 100644 --- a/w3af/plugins/infrastructure/dot_net_errors.py +++ b/w3af/plugins/infrastructure/dot_net_errors.py @@ -120,7 +120,8 @@ def _send_and_check(self, url): desc, severity.LOW, response.id, - self.get_name()) + self.get_name(), + vulndb_id=10074) kb.kb.append(self, 'dot_net_errors', v) diff --git a/w3af/plugins/infrastructure/find_vhosts.py b/w3af/plugins/infrastructure/find_vhosts.py index b2477cdeb8..23bef6dba6 100644 --- a/w3af/plugins/infrastructure/find_vhosts.py +++ b/w3af/plugins/infrastructure/find_vhosts.py @@ -37,7 +37,6 @@ from w3af.core.data.bloomfilter.scalable_bloom import ScalableBloomFilter from w3af.core.data.dc.headers import Headers from w3af.core.data.kb.vuln import Vuln -from w3af.core.data.kb.info import Info class find_vhosts(InfrastructurePlugin): @@ -128,8 +127,8 @@ def _get_dead_domains(self, fuzzable_request): u' This can be a broken link, or an internal domain name.') desc %= (fuzzable_request.get_url(), domain) - i = Info(u'Internal hostname in HTML link', desc, - original_response.id, self.get_name()) + i = Vuln(u'Internal hostname in HTML link', desc, severity.INFORMATION, + original_response.id, self.get_name(), vulndb_id=10055) i.set_url(fuzzable_request.get_url()) kb.kb.append(self, 'find_vhosts', i) @@ -168,7 +167,8 @@ def _check_potential_vhosts(self, fuzzable_request, vhosts): ids.extend([r.id for r in non_existent_responses]) v = Vuln.from_fr('Virtual host identified', desc, severity.LOW, - ids, self.get_name(), fuzzable_request) + ids, self.get_name(), fuzzable_request, + vulndb_id=10054) kb.kb.append(self, 'find_vhosts', v) om.out.information(v.get_desc()) diff --git a/w3af/plugins/infrastructure/halberd.py b/w3af/plugins/infrastructure/halberd.py index dbf384cb93..7540210843 100644 --- a/w3af/plugins/infrastructure/halberd.py +++ b/w3af/plugins/infrastructure/halberd.py @@ -35,8 +35,9 @@ from w3af.core.controllers.plugins.infrastructure_plugin import InfrastructurePlugin from w3af.core.controllers.exceptions import RunOnce from w3af.core.controllers.misc.decorators import runonce +from w3af.core.data.constants import severity +from w3af.core.data.kb.vuln import Vuln from w3af.plugins.infrastructure.halberd_helpers.strategy import CustomScanStrategy -from w3af.core.data.kb.info import Info class halberd(InfrastructurePlugin): @@ -128,8 +129,14 @@ def _report(self, scantask, report_file): # This is added so other w3af plugins can read the halberd results. # If needed by other plugins, I could fill up the info object with # more data about the different headers, time, etc... - i = Info('HTTP load balancer detected', halberd_report, 1, - self.get_name()) + i = Vuln( + 'HTTP load balancer detected', + halberd_report, + severity.INFORMATION, + 1, + self.get_name(), + vulndb_id=10072, + ) i['server_number'] = len(clues) kb.kb.append(self, 'halberd', i) diff --git a/w3af/plugins/infrastructure/hmap.py b/w3af/plugins/infrastructure/hmap.py index ad1ffa55e7..bd7a27086b 100644 --- a/w3af/plugins/infrastructure/hmap.py +++ b/w3af/plugins/infrastructure/hmap.py @@ -26,9 +26,10 @@ from w3af.core.controllers.exceptions import RunOnce, BaseFrameworkException from w3af.core.controllers.misc.decorators import runonce from w3af.core.controllers.plugins.infrastructure_plugin import InfrastructurePlugin +from w3af.core.data.constants import severity +from w3af.core.data.kb.vuln import Vuln from w3af.core.data.options.opt_factory import opt_factory from w3af.core.data.options.option_list import OptionList -from w3af.core.data.kb.info import Info class hmap(InfrastructurePlugin): @@ -87,7 +88,14 @@ def discover(self, fuzzable_request, debugging_id): desc = 'The most accurate fingerprint for this HTTP server is: "%s".' desc %= server - i = Info('Webserver fingerprint', desc, 1, self.get_name()) + i = Vuln( + 'Webserver fingerprint', + desc, + severity.INFORMATION, + 1, + self.get_name(), + vulndb_id=10094, + ) i['server'] = server om.out.information(i.get_desc()) diff --git a/w3af/plugins/infrastructure/server_header.py b/w3af/plugins/infrastructure/server_header.py index 9b95285e77..04731a2726 100644 --- a/w3af/plugins/infrastructure/server_header.py +++ b/w3af/plugins/infrastructure/server_header.py @@ -25,6 +25,8 @@ import w3af.core.data.kb.knowledge_base as kb from w3af.core.controllers.plugins.infrastructure_plugin import InfrastructurePlugin +from w3af.core.data.constants import severity +from w3af.core.data.kb.vuln import Vuln from w3af.core.data.url.helpers import is_no_content_response from w3af.core.data.kb.info import Info @@ -89,7 +91,14 @@ def _check_server_header(self, fuzzable_request, response): desc = 'The server header for the remote web server is: "%s".' desc %= server - i = Info('Server header', desc, response.id, self.get_name()) + i = Vuln( + 'Server header', + desc, + severity.INFORMATION, + response.id, + self.get_name(), + vulndb_id=10098, + ) i['server'] = server i.add_to_highlight(header_name + ':') @@ -105,8 +114,8 @@ def _check_server_header(self, fuzzable_request, response): # strange ! desc = ('The remote HTTP Server omitted the "server" header in' ' its response.') - i = Info('Omitted server header', desc, response.id, - self.get_name()) + i = Vuln('Omitted server header', desc, severity.INFORMATION, response.id, + self.get_name(), vulndb_id=10099) om.out.information(i.get_desc()) @@ -135,7 +144,14 @@ def _check_x_power(self, fuzzable_request, response): desc = 'The %s header for the target HTTP server is "%s".' desc %= (header_name, powered_by) - i = Info('Powered-by header', desc, response.id, self.get_name()) + i = Vuln( + 'Powered-by header', + desc, + severity.INFORMATION, + response.id, + self.get_name(), + vulndb_id=10100, + ) i['powered_by'] = powered_by i.add_to_highlight(header_name + ':') diff --git a/w3af/plugins/infrastructure/shared_hosting.py b/w3af/plugins/infrastructure/shared_hosting.py index 8a837114a9..a19c394f9d 100644 --- a/w3af/plugins/infrastructure/shared_hosting.py +++ b/w3af/plugins/infrastructure/shared_hosting.py @@ -141,7 +141,8 @@ def _analyze_ips(self, ip_address_list, fuzzable_request): kb.kb.raw_write(self, 'domains', domain_list) v = Vuln.from_fr('Shared hosting', desc, severity.MEDIUM, 1, - self.get_name(), fuzzable_request) + self.get_name(), fuzzable_request, + vulndb_id=10103) v['also_in_hosting'] = results diff --git a/w3af/plugins/output/xml_file.py b/w3af/plugins/output/xml_file.py index 06cbc6a4f4..d67aa5c323 100644 --- a/w3af/plugins/output/xml_file.py +++ b/w3af/plugins/output/xml_file.py @@ -768,6 +768,7 @@ def to_string(self): context = dotdict({}) context.id_list = info.get_id() + context.vulndb_id = info.get_vulndb_id() context.http_method = info.get_method() context.name = info.get_name() context.plugin_name = info.get_plugin_name() diff --git a/w3af/plugins/output/xml_file/finding.tpl b/w3af/plugins/output/xml_file/finding.tpl index c82c3e2411..4332a2615c 100644 --- a/w3af/plugins/output/xml_file/finding.tpl +++ b/w3af/plugins/output/xml_file/finding.tpl @@ -1,4 +1,4 @@ - + {{ description | escape_text }} {% if long_description %}