Skip to content

Commit 97187c0

Browse files
author
ekultek
committed
fixes issue #173 crawler will ignore SSL certificates, fixes #174 caches the found firewall into memory, incase we run across it again we don't waste our time trying to discover it, fixes #175 and #176 if there are unicode chars in the value it will not be saved
1 parent 4c496b2 commit 97187c0

File tree

8 files changed

+90
-16
lines changed

8 files changed

+90
-16
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ There are some requirements for this to be run successfully.
9898

9999
### Installation
100100

101-
You can download the latest [tar.gz](https://github.com/ekultek/zeus-scanner/tarball/master), the latest [zip](https://github.com/ekultek/zeus-scanner/zipball/master), or you can find the current stable release [here](https://github.com/Ekultek/Zeus-Scanner/releases/tag/v1.2). Alternatively you can install the latest development version by following the instructions that best match your operating system:
101+
You can download the latest [tar.gz](https://github.com/ekultek/zeus-scanner/tarball/master), the latest [zip](https://github.com/ekultek/zeus-scanner/zipball/master), or you can find the current stable release [here](https://github.com/Ekultek/Zeus-Scanner/releases/tag/v1.3). Alternatively you can install the latest development version by following the instructions that best match your operating system:
102102

103103
**_NOTE: (optional but highly advised)_** add sqlmap and nmap to your environment PATH by moving them to `/usr/bin` or by adding them to the PATH via terminal
104104

etc/checksum/md5sum.md5

+6-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
a48339bbd1bbcd2e27650fd930ebfa4c ./zeus.py
1+
e4ea2d20dd1e0ec58e68159689e2cb74 ./zeus.py
22
4b32db388e8acda35570c734d27c950c ./etc/scripts/launch_sqlmap.sh
33
6ad5f22ec4a6f8324bfb1b01ab6d51ec ./etc/scripts/cleanup.sh
44
74d7bee13890a9dd279bb857591647ce ./etc/scripts/reinstall.sh
@@ -55,6 +55,7 @@ bf5285dc059c761e1719bc734ae8504f ./lib/firewall/varnish.py
5555
cb45428e92485b759ff5cb46a0be9c73 ./lib/firewall/yunsuo.py
5656
bbd8b4c6100070d420d48dc7dfc297eb ./lib/firewall/webknight.py
5757
95b908a21c0ff456ae59df4c6c189c54 ./lib/firewall/wallarm.py
58+
8fc8d62377bebbfa7ca4d70a79eab115 ./lib/firewall/bigip.py
5859
6ea65a0160c21e144e92334acc2e3667 ./lib/firewall/anquanbao.py
5960
7f4e3ba2f459926fc77bcddc17b933aa ./lib/firewall/generic.py
6061
cf236a16c7869282f55dd4c5ad6347a5 ./lib/attacks/gist_lookup/__init__.py
@@ -68,15 +69,16 @@ d2846e039fefee741db24dd64f7bd50e ./lib/attacks/admin_panel_finder/__init__.py
6869
b5cd5e913cc62112776153bdf0f60fa4 ./lib/attacks/xss_scan/__init__.py
6970
63c45495ec1ed2e98946bef514d8805e ./lib/attacks/nmap_scan/__init__.py
7071
216999fa0e84866d5c1d96d5676034e4 ./lib/attacks/nmap_scan/nmap_opts.py
71-
7267f30f11ed3d096e222da949da5bea ./lib/header_check/__init__.py
72+
b6f5f8e43c1e480329b66e193bd91751 ./lib/header_check/__init__.py
7273
9a2bb0d52f64e12d5a63ce83874ea74a ./lib/core/common.py
7374
1faa2b5dfad6eb538bbfe42942d2a9da ./lib/core/errors.py
7475
d41d8cd98f00b204e9800998ecf8427e ./lib/core/__init__.py
75-
bf158550d8f51f4841fd1b003cb71c55 ./lib/core/settings.py
76+
4a87e14ed7a070ae15b1ed7ac7ceaecc ./lib/core/settings.py
77+
4b507b34677b414b8338475fea2c012a ./lib/core/cache.py
7678
9a02e5b913d210350545ac26510a63c9 ./var/search/__init__.py
7779
8402f23a2586b6f684fb1c3c04c4386f ./var/search/selenium_search.py
7880
63ba132381a0cc2d7629852bd5e4aa17 ./var/search/pgp_search.py
7981
d41d8cd98f00b204e9800998ecf8427e ./var/__init__.py
8082
d41d8cd98f00b204e9800998ecf8427e ./var/auto_issue/__init__.py
8183
0c11c16126baf789388a661bbbefb149 ./var/auto_issue/github.py
82-
df0c4467256fb6fb7ab6c40209e4ab6d ./var/blackwidow/__init__.py
84+
7608a7a8195d6d66ebae7664f25639fd ./var/blackwidow/__init__.py

lib/core/cache.py

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
from functools import wraps
2+
3+
import lib.core.settings
4+
5+
6+
def cache(func):
7+
"""
8+
if we come across the same URL more then once, it will be cached into memory
9+
so that we don't have to test it again
10+
"""
11+
__cache = {}
12+
13+
@wraps(func)
14+
def func_wrapper(*args, **kwargs):
15+
if args in __cache:
16+
lib.core.settings.logger.warning(lib.core.settings.set_color(
17+
"cached detection has shown that the target URL WAF/IPS/IDS is '{}'...".format(
18+
__cache[args]
19+
), level=35
20+
))
21+
return __cache[args]
22+
else:
23+
__to_cache = func(*args, **kwargs)
24+
__cache[args] = __to_cache
25+
return __to_cache
26+
27+
return func_wrapper

lib/core/settings.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
ISSUE_LINK = "https://github.com/ekultek/zeus-scanner/issues"
4747

4848
# current version <major.minor.commit.patch ID>
49-
VERSION = "1.2.41.{}".format(PATCH_ID)
49+
VERSION = "1.3".format(PATCH_ID)
5050

5151
# colors to output depending on the version
5252
VERSION_TYPE_COLORS = {"dev": 33, "stable": 92, "other": 30}

lib/firewall/bigip.py

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import re
2+
3+
from lib.core.common import HTTP_HEADER
4+
5+
6+
__item__ = "BIG-IP Application Security Manager (F5 Networks)"
7+
8+
9+
def detect(content, **kwargs):
10+
headers = kwargs.get("headers", None)
11+
detection_schema = (
12+
re.compile(r"\ATS\w{4,}=", re.I), re.compile(r"BIGip|BipServer", re.I),
13+
re.compile(r"\AF5\Z", re.I)
14+
)
15+
for detection in detection_schema:
16+
if detection.search(headers.get(HTTP_HEADER.SERVER, "")) is not None:
17+
return True
18+
if detection.search(headers.get(HTTP_HEADER.SET_COOKIE, "")) is not None:
19+
return True

lib/header_check/__init__.py

+33-8
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
import os
22
import re
33
import importlib
4+
import unicodedata
45

56
import requests
67
from xml.dom import minidom
78
from requests.exceptions import ConnectionError
89

910
from var.auto_issue.github import request_issue_creation
11+
from lib.core.cache import cache
1012
from lib.core.common import (
1113
write_to_log_file,
1214
shutdown,
@@ -32,6 +34,7 @@
3234
)
3335

3436

37+
@cache
3538
def detect_protection(url, **kwargs):
3639
verbose = kwargs.get("verbose", False)
3740
agent = kwargs.get("agent", None)
@@ -68,12 +71,13 @@ def detect_protection(url, **kwargs):
6871

6972
html, status, headers = protection_check_req.content, protection_check_req.status_code, protection_check_req.headers
7073

71-
for dbms in DBMS_ERRORS: # make sure there are no DBMS errors in the HTML
74+
# make sure there are no DBMS errors in the HTML
75+
for dbms in DBMS_ERRORS:
7276
for regex in DBMS_ERRORS[dbms]:
7377
if re.compile(regex).search(html) is not None:
74-
logger.info(set_color(
78+
logger.warning(set_color(
7579
"it appears that the WAF/IDS/IPS check threw a DBMS error and may be vulnerable "
76-
"to SQL injection attacks. it appears the backend DBMS is '{}'...".format(dbms), level=25
80+
"to SQL injection attacks. it appears the backend DBMS is '{}'...".format(dbms), level=30
7781
))
7882
return None
7983

@@ -94,7 +98,7 @@ def detect_protection(url, **kwargs):
9498
if len(retval) >= 2:
9599
try:
96100
del retval[retval.index("Generic (Unknown)")]
97-
except:
101+
except (Exception, IndexError):
98102
logger.warning(set_color(
99103
"multiple firewalls identified ({}), displaying most likely...".format(
100104
", ".join(retval)
@@ -105,9 +109,11 @@ def detect_protection(url, **kwargs):
105109
logger.warning(set_color(
106110
"discovered firewall is unknown to Zeus, saving fingerprint to file. "
107111
"if you know the details or the context of the firewall please create "
108-
"an issue with the fingerprint, or a pull request with the script...", level=30
112+
"an issue ({}) with the fingerprint, or a pull request with the script...".format(
113+
ISSUE_LINK
114+
), level=30
109115
))
110-
fingerprint = "<!---\nStatus: {}\nHeaders: {}\n--->\n{}".format(
116+
fingerprint = "<!---\nHTTP 1.1\nStatus Code: {}\nHTTP Headers: {}\n--->\n{}".format(
111117
status, headers, html
112118
)
113119
write_to_log_file(fingerprint, UNKNOWN_FIREWALL_FINGERPRINT_PATH, UNKNOWN_FIREWALL_FILENAME)
@@ -143,12 +149,14 @@ def load_xml_data(path, start_node="header", search_node="name"):
143149

144150
def load_headers(url, **kwargs):
145151
"""
146-
load the URL headers
152+
load the HTTP headers
147153
"""
148154
agent = kwargs.get("agent", None)
149155
proxy = kwargs.get("proxy", None)
150156
xforward = kwargs.get("xforward", False)
151157

158+
literal_match = re.compile(r"\\(\X(\d+)?\w+)?", re.I)
159+
152160
if proxy is not None:
153161
proxy = proxy_string_to_dict(proxy)
154162
if not xforward:
@@ -182,7 +190,23 @@ def load_headers(url, **kwargs):
182190
[c for c in req.cookies.itervalues()], COOKIE_LOG_PATH,
183191
COOKIE_FILENAME.format(replace_http(url))
184192
)
185-
return req.headers
193+
retval = {}
194+
do_not_use = []
195+
http_headers = req.headers
196+
for header in http_headers:
197+
try:
198+
# test to see if there are any unicode errors in the string
199+
retval[header] = unicodedata.normalize("NFKD", u"{}".format(http_headers[header])).encode("ascii", errors="ignore")
200+
# just to be safe, we're going to put all the possible Unicode errors into a tuple
201+
except (UnicodeEncodeError, UnicodeDecodeError, UnicodeError, UnicodeTranslateError, UnicodeWarning):
202+
# if there are, we're going to append them to a `do_not_use` list
203+
do_not_use.append(header)
204+
retval.clear()
205+
for head in http_headers:
206+
# if the header is in the list, we skip it
207+
if head not in do_not_use:
208+
retval[head] = http_headers[head]
209+
return retval
186210

187211

188212
def compare_headers(found_headers, comparable_headers):
@@ -222,6 +246,7 @@ def main_header_check(url, **kwargs):
222246
"checking if target URL is protected by some kind of WAF/IPS/IDS..."
223247
))
224248
identified = detect_protection(url, proxy=proxy, agent=agent, verbose=verbose, xforward=xforward)
249+
225250
if identified is None:
226251
logger.info(set_color(
227252
"no WAF/IDS/IPS has been identified on target URL...", level=25

var/blackwidow/__init__.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ def test_connection(self):
5151
make sure the connection is good before you continue
5252
"""
5353
try:
54-
attempt = requests.get(self.url, params=self.headers, proxies=self.proxy)
54+
# verify=False will take care of SSLErrors
55+
attempt = requests.get(self.url, params=self.headers, proxies=self.proxy, verify=False)
5556
if attempt.status_code == 200:
5657
return ("ok", None)
5758
return ("fail", attempt.status_code)

zeus.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ def __run_attacks_main(**kwargs):
285285
), level=25
286286
))
287287
logger.info(set_color(
288-
"checking URL headers..."
288+
"checking for HTTP headers..."
289289
))
290290
main_header_check(
291291
url, verbose=opt.runInVerbose, agent=agent_to_use,

0 commit comments

Comments
 (0)