Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/vulndb #18492

Open
wants to merge 5 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion w3af/core/controllers/dependency_check/requirements.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
9 changes: 6 additions & 3 deletions w3af/core/controllers/plugins/auth_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -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


Expand Down Expand Up @@ -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)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://github.com/vulndb/data/search?q=10116&unscoped_q=10116

What happens when the ID is not present in the vulndb? Is this error handled somewhere?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's no error. I don't implement here the concept of making vulndb_id required for Vuln instances. I just mentioned the concept in description, because in this PR I prepare the code for this concept. I'll be able to implement it once #18543 is merged.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My point is, when 10116 is passed to the Vuln instance, and then XML plugin tries to write that vuln instance to disk, what happens? Will it crash because 10116 is NOT in the vulndb?

10116 is Holm-specific, that is why I'm asking.


i.set_uri(self._get_main_authentication_url())

Expand Down
2 changes: 1 addition & 1 deletion w3af/core/controllers/sql_tools/blind_sqli_time_delay.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
andresriancho marked this conversation as resolved.
Show resolved Hide resolved

om.out.debug(v.get_desc())

Expand Down
31 changes: 31 additions & 0 deletions w3af/core/data/kb/tests/test_vuln.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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())
8 changes: 4 additions & 4 deletions w3af/core/data/kb/vuln.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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())
Expand All @@ -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.
Expand All @@ -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):
Expand Down
49 changes: 42 additions & 7 deletions w3af/plugins/audit/cors_origin.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be possible for Holm to contribute back to the vulndb? If we do that, all the w3af users would get these detailed descriptions for the vulnerabilities.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I brought up the discussion internally in Holm.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And what was the resolution?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So far there's no decision to contribute to vulndb. Holm holds off

)
v.set_url(forged_req.get_url())
v[METHODS] = allow_methods_set

Expand All @@ -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

Expand All @@ -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()

Expand Down Expand Up @@ -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()

Expand All @@ -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()

Expand Down Expand Up @@ -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()

Expand Down
2 changes: 1 addition & 1 deletion w3af/plugins/audit/csrf.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
4 changes: 2 additions & 2 deletions w3af/plugins/audit/dav.py
Original file line number Diff line number Diff line change
Expand Up @@ -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')
Expand Down Expand Up @@ -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')
Expand Down
3 changes: 2 additions & 1 deletion w3af/plugins/audit/deserialization.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
4 changes: 2 additions & 2 deletions w3af/plugins/audit/eval.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand All @@ -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)

Expand Down
2 changes: 1 addition & 1 deletion w3af/plugins/audit/file_upload.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
2 changes: 1 addition & 1 deletion w3af/plugins/audit/format_string.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
2 changes: 1 addition & 1 deletion w3af/plugins/audit/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
2 changes: 1 addition & 1 deletion w3af/plugins/audit/global_redirect.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
4 changes: 2 additions & 2 deletions w3af/plugins/audit/lfi.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions w3af/plugins/audit/memcachei.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand All @@ -171,4 +171,4 @@ def get_long_desc(self):
it can identify these injection types:

* Batch injection (command injection) - 0x0a/0x0d bytes
"""
"""
2 changes: 1 addition & 1 deletion w3af/plugins/audit/mx_injection.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
4 changes: 2 additions & 2 deletions w3af/plugins/audit/os_commanding.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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()
Expand Down
3 changes: 2 additions & 1 deletion w3af/plugins/audit/phishing_vector.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion w3af/plugins/audit/preg_replace.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion w3af/plugins/audit/redos.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
Loading