Fix coding style

This commit is contained in:
Florian Wininger 2021-04-29 11:19:37 +02:00
parent a8cfb259e9
commit 1bf3ae6d94
25 changed files with 128 additions and 114 deletions

View File

@ -3,6 +3,10 @@
# Specify a configuration file.
#rcfile=
# Add files or directories matching the regex patterns to the blacklist. The
# regex matches against base names, not paths.
ignore-patterns=jsparser3.py
[MESSAGES CONTROL]
# Only show warnings with the listed confidence levels. Leave empty to show
@ -24,19 +28,27 @@ confidence=
# --enable=similarities". If you want to run only the classes checker, but have
# no Warning level messages displayed, use"--disable=all --enable=classes
# --disable=W"
disable=too-few-public-methods,too-many-instance-attributes,too-many-arguments,
too-many-locals,logging-format-interpolation,not-an-iterable,too-many-public-methods,
missing-function-docstring,missing-class-docstring,missing-module-docstring
disable=too-few-public-methods,too-many-instance-attributes,too-many-arguments,import-error,
logging-format-interpolation,not-an-iterable,too-many-public-methods,fixme,
missing-function-docstring,missing-class-docstring,missing-module-docstring,invalid-name
[FORMAT]
# Maximum number of characters on a single line.
max-line-length=120
max-nested-blocks=10
max-locals=25
max-branches=40
max-statements=100
[SIMILARITIES]
# Minimum lines number of a similarity.
min-similarity-lines=16
min-similarity-lines=43
# Ignore comments when computing similarities.
ignore-comments=yes

View File

@ -78,7 +78,7 @@ if a script is vulnerable.""",
author_email="nicolas.surribas@gmail.com",
license="GPLv2",
platforms=["Any"],
packages=find_packages(exclude=["tests","tests.*"]),
packages=find_packages(exclude=["tests", "tests.*"]),
data_files=doc_and_conf_files,
include_package_data=True,
scripts=[

View File

@ -591,14 +591,14 @@ if __name__ == "__main__":
print(flags)
print('')
print("#"*50)
print("#" * 50)
print('')
for evil_request, param_name, payload, flags in mutator.mutate(res2):
print(evil_request)
print('')
print("#"*50)
print("#" * 50)
print('')
def iterator():
@ -610,7 +610,7 @@ if __name__ == "__main__":
print(evil_request)
print('')
print("#"*50)
print("#" * 50)
print('')
mutator = Mutator(payloads=random_string_with_flags, qs_inject=True, max_queries_per_pattern=16)

View File

@ -91,7 +91,7 @@ class mod_brute_login_form(Attack):
def must_attack(self, request: Request):
# We leverage the fact that the crawler will fill password entries with a known placeholder
if "Letm3in_" not in (request.encoded_data + request.encoded_params):
if "Letm3in_" not in request.encoded_data + request.encoded_params:
return False
# We may want to remove this but if not available fallback to target URL
@ -172,7 +172,7 @@ class mod_brute_login_form(Attack):
)
self.log_red("---")
self.log_red(vuln_message),
self.log_red(vuln_message)
self.log_red(Messages.MSG_EVIL_REQUEST)
self.log_red(evil_request.http_repr())
self.log_red("---")

View File

@ -43,7 +43,7 @@ class mod_crlf(Attack):
def attack(self, request: Request):
page = request.path
for mutated_request, parameter, payload, flags in self.mutator.mutate(request):
for mutated_request, parameter, _payload, _flags in self.mutator.mutate(request):
if self.verbose == 2:
print("[¨] {0}".format(mutated_request.url))

View File

@ -46,7 +46,7 @@ class mod_csrf(Attack):
"authenticity_token", "_token", "csrf_token", "csrfname", "csrftoken", "anticsrf",
"__requestverificationtoken", "token", "csrf", "_csrf_token", "xsrf_token",
"_csrf", "csrf-token", "xsrf-token", "_wpnonce"
]
]
TOKEN_HEADER_STRINGS = [
"csrf-token", "x-csrf-token", "xsrf-token", "x-xsrf-token", "csrfp-token",

View File

@ -11,6 +11,7 @@ from wapitiCore.definitions.fingerprint import NAME as TECHNO_DETECTED
MSG_TECHNO_VERSIONED = _("{0} {1} detected")
MSG_NO_DRUPAL = _("No Drupal Detected")
class mod_drupal_enum(Attack):
"""Detect Drupal version."""
name = "drupal_enum"
@ -18,6 +19,7 @@ class mod_drupal_enum(Attack):
PAYLOADS_FILE_THEMES = "wordpress_themes.txt"
versions = []
def __init__(self, crawler, persister, logger, attack_options):
Attack.__init__(self, crawler, persister, logger, attack_options)
self.finished = False
@ -30,7 +32,7 @@ class mod_drupal_enum(Attack):
def detect_version(self, url):
vers = {}
data = self.get_hash()
for uri in data :
for uri in data:
req = Request('{}{}'.format(url, uri))
rep = self.crawler.get(req)
if rep.status != 200:
@ -39,22 +41,21 @@ class mod_drupal_enum(Attack):
cont = rep.content.encode()
hash_content = hashlib.sha256(cont).hexdigest()
if uri in data :
if hash_content in data[uri] :
if uri in data:
if hash_content in data[uri]:
vers[uri] = data[uri][hash_content]
if vers :
self.versions = set.intersection(*[set(versions) for versions in vers.values()])
if vers:
self.versions = set.intersection(*[set(versions) for versions in vers.values()])
def check_drupal(self, url):
check_list = ['sites/', 'core/misc/drupal.js', 'misc/drupal.js', 'misc/test/error/404/ispresent.html']
for item in check_list :
for item in check_list:
req = Request('{}{}'.format(url, item))
rep = self.crawler.get(req)
if rep.status != 404:
return True
return False
def must_attack(self, request: Request):
if self.finished:
return False
@ -66,44 +67,44 @@ class mod_drupal_enum(Attack):
def attack(self, request: Request):
self.finished = True
request_to_root = Request(request.url)
response = self.crawler.send(request_to_root, follow_redirects=True)
self.crawler.send(request_to_root, follow_redirects=True)
if self.check_drupal(request_to_root.url):
self.detect_version(request_to_root.url)
if self.versions :
if self.versions:
self.versions = sorted(self.versions, key=lambda x: [i for i in x.split('.')])
drupal_detected = {
"name": "Drupal",
"versions": self.versions,
"categories": ["CMS Drupal"]
}
"name": "Drupal",
"versions": self.versions,
"categories": ["CMS Drupal"]
}
self.log_blue(
MSG_TECHNO_VERSIONED,
"Drupal",
self.versions
)
MSG_TECHNO_VERSIONED,
"Drupal",
self.versions
)
self.add_addition(
category = TECHNO_DETECTED,
level = LOW_LEVEL,
request = request_to_root,
info = json.dumps(drupal_detected)
)
else :
category=TECHNO_DETECTED,
level=LOW_LEVEL,
request=request_to_root,
info=json.dumps(drupal_detected)
)
else:
drupal_detected = {
"name": "Drupal",
"versions": [""],
"categories": ["CMS Drupal"]
}
"name": "Drupal",
"versions": [""],
"categories": ["CMS Drupal"]
}
self.log_blue(
MSG_TECHNO_VERSIONED,
"Drupal",
[]
MSG_TECHNO_VERSIONED,
"Drupal",
[]
)
self.add_addition(
category = TECHNO_DETECTED,
level = LOW_LEVEL,
request = request_to_root,
info = json.dumps(drupal_detected)
category=TECHNO_DETECTED,
level=LOW_LEVEL,
request=request_to_root,
info=json.dumps(drupal_detected)
)
else :
else:
self.log_blue(MSG_NO_DRUPAL)

View File

@ -24,7 +24,7 @@ import re
from requests.exceptions import ReadTimeout, RequestException
from wapitiCore.attack.attack import Attack, PayloadReader
from wapitiCore.language.vulnerability import Messages, MEDIUM_LEVEL, HIGH_LEVEL,CRITICAL_LEVEL, _
from wapitiCore.language.vulnerability import Messages, MEDIUM_LEVEL, HIGH_LEVEL, CRITICAL_LEVEL, _
from wapitiCore.definitions.file import NAME
from wapitiCore.net.web import Request

View File

@ -43,8 +43,8 @@ class mod_http_headers(Attack):
def is_set(self, response: Page, header_name, check_list):
if header_name not in response.headers:
return False
else:
return any(element in response.headers[header_name].lower() for element in check_list)
return any(element in response.headers[header_name].lower() for element in check_list)
def must_attack(self, request: Request):
if self.finished:

View File

@ -215,7 +215,7 @@ class mod_permanentxss(Attack):
skip=self.options.get("skipped_parameters")
)
for evil_request, xss_param, xss_payload, xss_flags in attack_mutator.mutate(injection_request):
for evil_request, xss_param, _xss_payload, xss_flags in attack_mutator.mutate(injection_request):
if self.verbose == 2:
print("[¨] {0}".format(evil_request))
@ -364,12 +364,12 @@ class mod_permanentxss(Attack):
if case_sensitive:
if match_type == "exact" and expected_value == tag.string.strip():
return True
elif match_type == "starts_with" and tag.string.strip().startswith(expected_value):
if match_type == "starts_with" and tag.string.strip().startswith(expected_value):
return True
else:
if match_type == "exact" and expected_value.lower() == tag.string.strip().lower():
return True
elif match_type == "starts_with" and \
if match_type == "starts_with" and \
tag.string.strip().lower().startswith(expected_value.lower()):
return True
else:
@ -378,12 +378,12 @@ class mod_permanentxss(Attack):
if case_sensitive:
if match_type == "exact" and tag[attribute] == expected_value:
return True
elif match_type == "starts_with" and tag[attribute].startswith(expected_value):
if match_type == "starts_with" and tag[attribute].startswith(expected_value):
return True
else:
if match_type == "exact" and tag[attribute].lower() == expected_value.lower():
return True
elif match_type == "starts_with" and \
if match_type == "starts_with" and \
expected_value.lower().startswith(tag[attribute].lower()):
return True
break

View File

@ -46,7 +46,7 @@ class mod_shellshock(Attack):
hex_string = hexlify(self.rand_string.encode())
bash_string = ""
for i in range(0, 64, 2):
bash_string += "\\x" + hex_string[i:i+2].decode()
bash_string += "\\x" + hex_string[i:i + 2].decode()
cmd = "echo; echo; echo -e '{0}';".format(bash_string)

View File

@ -495,9 +495,9 @@ class mod_sql(Attack):
continue
comparison = (
response.status == good_status and
response.redirection_url == good_redirect and
response.text_only_md5 == good_hash
response.status == good_status and
response.redirection_url == good_redirect and
response.text_only_md5 == good_hash
)
test_results.append(comparison == (flags.section == "True"))

View File

@ -174,7 +174,7 @@ class mod_ssrf(Attack):
def attack(self, request: Request):
# Let's just send payloads, we don't care of the response as what we want to know is if the target
# contacted the endpoint.
for mutated_request, parameter, payload, flags in self.mutator.mutate(request):
for mutated_request, _parameter, _payload, _flags in self.mutator.mutate(request):
if self.verbose == 2:
print("[¨] {0}".format(mutated_request))

View File

@ -49,7 +49,7 @@ class mod_timesql(Attack):
current_parameter = None
vulnerable_parameter = False
for mutated_request, parameter, payload, flags in self.mutator.mutate(request):
for mutated_request, parameter, _payload, _flags in self.mutator.mutate(request):
if current_parameter != parameter:
# Forget what we know about current parameter
current_parameter = parameter

View File

@ -10,6 +10,7 @@ from wapitiCore.definitions.fingerprint import NAME as TECHNO_DETECTED
MSG_TECHNO_VERSIONED = _("{0} {1} detected")
MSG_NO_WP = _("No WordPress Detected")
class mod_wp_enum(Attack):
"""Detect WordPress Plugins with version."""
name = "wp_enum"
@ -20,7 +21,6 @@ class mod_wp_enum(Attack):
Attack.__init__(self, crawler, persister, logger, attack_options)
self.finished = False
def get_plugin(self):
with open(path_join(self.DATA_DIR, self.PAYLOADS_FILE_PLUGINS), errors="ignore") as plugin_list:
for line in plugin_list:
@ -41,11 +41,11 @@ class mod_wp_enum(Attack):
rep = self.crawler.get(req)
if rep.status == 200:
version = re.search(r'tag:\s*([\d.]+)', rep.content)
#This check was added to detect invalid format of "Readme.txt" who can cause a crashe
if version :
# This check was added to detect invalid format of "Readme.txt" who can cause a crashe
if version:
version = version.group(1)
else :
print ("Readme.txt is not in a valid format")
else:
print("Readme.txt is not in a valid format")
version = ""
plugin_detected = {
"name": plugin,
@ -58,10 +58,10 @@ class mod_wp_enum(Attack):
version
)
self.add_addition(
category = TECHNO_DETECTED,
level = LOW_LEVEL,
request = req,
info = json.dumps(plugin_detected)
category=TECHNO_DETECTED,
level=LOW_LEVEL,
request=req,
info=json.dumps(plugin_detected)
)
elif rep.status == 403:
plugin_detected = {
@ -75,10 +75,10 @@ class mod_wp_enum(Attack):
[""]
)
self.add_addition(
category = TECHNO_DETECTED,
level = LOW_LEVEL,
request = req,
info = json.dumps(plugin_detected)
category=TECHNO_DETECTED,
level=LOW_LEVEL,
request=req,
info=json.dumps(plugin_detected)
)
def detect_theme(self, url):
@ -87,11 +87,10 @@ class mod_wp_enum(Attack):
rep = self.crawler.get(req)
if rep.status == 200:
version = re.search(r'tag:\s*([\d.]+)', rep.content)
#This check was added to detect invalid format of "Readme.txt" who can cause a crashe
if version :
# This check was added to detect invalid format of "Readme.txt" who can cause a crashe
if version:
version = version.group(1)
else :
#print ("Readme.txt is not in a valid format")
else:
version = ""
theme_detected = {
"name": theme,
@ -104,10 +103,10 @@ class mod_wp_enum(Attack):
version
)
self.add_addition(
category = TECHNO_DETECTED,
level = LOW_LEVEL,
request = req,
info = json.dumps(theme_detected)
category=TECHNO_DETECTED,
level=LOW_LEVEL,
request=req,
info=json.dumps(theme_detected)
)
elif rep.status == 403:
theme_detected = {
@ -121,13 +120,13 @@ class mod_wp_enum(Attack):
[""]
)
self.add_addition(
category = TECHNO_DETECTED,
level = LOW_LEVEL,
request = req,
info = json.dumps(theme_detected)
category=TECHNO_DETECTED,
level=LOW_LEVEL,
request=req,
info=json.dumps(theme_detected)
)
def check_wordpress(self, response :object):
def check_wordpress(self, response: object):
if re.findall('WordPress.*', response.content):
return True
return False

View File

@ -185,7 +185,8 @@ class mod_xss(Attack):
# stop trying payloads and jump to the next parameter
break
elif response.status == 500 and not saw_internal_error:
if response.status == 500 and not saw_internal_error:
if xss_param == "QUERY_STRING":
anom_msg = Messages.MSG_QS_500
else:
@ -239,12 +240,12 @@ class mod_xss(Attack):
if case_sensitive:
if match_type == "exact" and expected_value == tag.string.strip():
return True
elif match_type == "starts_with" and tag.string.strip().startswith(expected_value):
if match_type == "starts_with" and tag.string.strip().startswith(expected_value):
return True
else:
if match_type == "exact" and expected_value.lower() == tag.string.strip().lower():
return True
elif match_type == "starts_with" and \
if match_type == "starts_with" and \
tag.string.strip().lower().startswith(expected_value.lower()):
return True
else:
@ -253,12 +254,12 @@ class mod_xss(Attack):
if case_sensitive:
if match_type == "exact" and tag[attribute] == expected_value:
return True
elif match_type == "starts_with" and tag[attribute].startswith(expected_value):
if match_type == "starts_with" and tag[attribute].startswith(expected_value):
return True
else:
if match_type == "exact" and tag[attribute].lower() == expected_value.lower():
return True
elif match_type == "starts_with" and \
if match_type == "starts_with" and \
expected_value.lower().startswith(tag[attribute].lower()):
return True
break

View File

@ -203,7 +203,7 @@ class mod_xxe(Attack):
vulnerable_parameter = True
continue
elif response.status == 500 and not saw_internal_error:
if response.status == 500 and not saw_internal_error:
saw_internal_error = True
if parameter == "QUERY_STRING":
anom_msg = Messages.MSG_QS_500
@ -268,7 +268,7 @@ class mod_xxe(Attack):
current_parameter = None
vulnerable_parameter = False
for mutated_request, parameter, payload, flags in mutator.mutate(original_request):
for mutated_request, parameter, _payload, flags in mutator.mutate(original_request):
if current_parameter != parameter:
# Forget what we know about current parameter
current_parameter = parameter
@ -379,7 +379,7 @@ class mod_xxe(Attack):
"</xml>"
)
for payload, flags in self.payloads:
for payload, _flags in self.payloads:
if "{}.dtd".format(payload_name) in payload:
payload = payload.replace("[PATH_ID]", str(original_request.path_id))
payload = payload.replace("[PARAM_AS_HEX]", "72617720626f6479")

View File

@ -25,6 +25,7 @@ MEDIUM_LEVEL = "2"
LOW_LEVEL = "1"
INFO_LEVEL = "0"
class Messages:
MSG_EVIL_URL = _(" Evil url: {0}")
MSG_PARAM_INJECT = _("{0} in {1} via injection in the parameter {2}")

View File

@ -448,7 +448,11 @@ class Wapiti:
with open(traceback_file, "w") as traceback_fd:
print_tb(exception_traceback, file=traceback_fd)
print("{}: {}".format(exception.__class__.__name__, exception), file=traceback_fd)
print("Occurred in {} on {}".format(attack_module.name, self.target_url), file=traceback_fd)
print(
"Occurred in {} on {}".format(
attack_module.name,
self.target_url),
file=traceback_fd)
print("{}. Requests {}. OS {}".format(WAPITI_VERSION, requests.__version__, sys.platform))
try:
@ -1252,7 +1256,6 @@ def wapiti_main():
print(_("Attack process interrupted. Scan will be resumed next time "
"unless you specify \"--flush-attacks\" or \"--flush-session\"."))
print('')
pass
except OperationalError:
print(_("[!] Can't store information in persister. SQLite database must have been locked by another process"))
print(_("[!] You should unlock and launch Wapiti again."))

View File

@ -395,8 +395,8 @@ class Page:
# a hack for auto-generated Apache directory index
if query_string in [
"C=D;O=A", "C=D;O=D", "C=M;O=A", "C=M;O=D",
"C=N;O=A", "C=N;O=D", "C=S;O=A", "C=S;O=D"
"C=D;O=A", "C=D;O=D", "C=M;O=A", "C=M;O=D",
"C=N;O=A", "C=N;O=D", "C=S;O=A", "C=S;O=D"
]:
query_string = ""

View File

@ -17,8 +17,6 @@
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
import struct
from yaswfp import swfparser
from bs4 import BeautifulSoup
@ -86,7 +84,6 @@ def new_read_u30(stream):
def read_abc(data):
name_len = data.find(b'\0')
minor, major = struct.unpack("HH", data[name_len + 1: name_len + 5])
i = name_len + 5
read_value, read_size = read_u30(data[i:])

View File

@ -339,8 +339,8 @@ class Request:
def parameters_count(self):
if isinstance(self._post_params, list):
return len(self.get_params) + len(self._post_params) + len(self._file_params)
else:
return len(self.get_params) + len(self._file_params)
return len(self.get_params) + len(self._file_params)
@staticmethod
def _encoded_keys(params):
@ -356,6 +356,7 @@ class Request:
buff += "\n\tdata: {}".format(self.encoded_data.replace("\n", "\n\t"))
if self._file_params:
buff += "\n\tfiles: {}".format(self.encoded_files)
return buff
def http_repr(self, left_margin=" "):

View File

@ -323,9 +323,9 @@ def apply_attrval_context(context, payloads, code):
# we must deal differently with self-closing tags
# see https://developer.mozilla.org/en-US/docs/Glossary/empty_element for reference
if context["tag"].lower() in [
"area", "base", "br", "col", "embed", "hr", "img", "input", "keygen", "link", "meta", "param",
"source", "track", "wbr",
"frame" # Not in Mozilla list but I guess it is because it is deprecated
"area", "base", "br", "col", "embed", "hr", "img", "input", "keygen", "link", "meta", "param",
"source", "track", "wbr",
"frame" # Not in Mozilla list but I guess it is because it is deprecated
]:
# We don't even need a slash to mark the end of the tag
js_code += ">"

View File

@ -24,12 +24,12 @@ from .txtreportgenerator import TXTReportGenerator
from .xmlreportgenerator import XMLReportGenerator
GENERATORS = {
"csv": CSVReportGenerator,
"html": HTMLReportGenerator,
"json": JSONReportGenerator,
"txt": TXTReportGenerator,
"xml": XMLReportGenerator
}
"csv": CSVReportGenerator,
"html": HTMLReportGenerator,
"json": JSONReportGenerator,
"txt": TXTReportGenerator,
"xml": XMLReportGenerator
}
def get_report_generator_instance(report_format: str = "html"):

View File

@ -23,7 +23,6 @@ from wapitiCore.report.reportgenerator import ReportGenerator
NB_COLUMNS = 80
# TODO: should use more the python format mini-language
# http://docs.python.org/2/library/string.html#format-specification-mini-language