From 2d88e64404ef4d5bbd7a2b0f4804ce505411ddb8 Mon Sep 17 00:00:00 2001 From: ekultek Date: Mon, 20 Nov 2017 20:00:45 -0600 Subject: [PATCH] created 7 new WAF scripts for firewall detection (issue #142) --- etc/checksum/md5sum.md5 | 11 +++++++++-- lib/core/common.py | 1 + lib/firewall/aws.py | 17 +++++++---------- lib/firewall/sonicwall.py | 24 ++++++++++++++++++++++++ lib/firewall/stringray.py | 19 +++++++++++++++++++ lib/firewall/varnish.py | 24 ++++++++++++++++++++++++ lib/firewall/wallarm.py | 16 ++++++++++++++++ lib/firewall/webknight.py | 22 ++++++++++++++++++++++ lib/firewall/yundun.py | 19 +++++++++++++++++++ lib/firewall/yunsuo.py | 19 +++++++++++++++++++ 10 files changed, 160 insertions(+), 12 deletions(-) create mode 100644 lib/firewall/sonicwall.py create mode 100644 lib/firewall/stringray.py create mode 100644 lib/firewall/varnish.py create mode 100644 lib/firewall/wallarm.py create mode 100644 lib/firewall/webknight.py create mode 100644 lib/firewall/yundun.py create mode 100644 lib/firewall/yunsuo.py diff --git a/etc/checksum/md5sum.md5 b/etc/checksum/md5sum.md5 index 0736abd..079a884 100644 --- a/etc/checksum/md5sum.md5 +++ b/etc/checksum/md5sum.md5 @@ -37,7 +37,7 @@ d41d8cd98f00b204e9800998ecf8427e ./lib/__init__.py 2bfc3884ae96cc2443ebf94359b380c0 ./lib/firewall/cloudfront.py d41d8cd98f00b204e9800998ecf8427e ./lib/firewall/__init__.py 24342e7de0c51595d593cef74d80d3a0 ./lib/firewall/sucuri.py -9c3ec0cce44c4246b97b431e37e3dcc2 ./lib/firewall/aws.py +7bc1ef02ddc94ec678a4ea14835e9af0 ./lib/firewall/aws.py 1f303641d59686d544f2986ff74c6b31 ./lib/firewall/webseal.py e4eef006dd909c222b1b9f48826c3ef5 ./lib/firewall/pk.py 6b370050b40d8c1d2221424f756c7842 ./lib/firewall/paloalto.py @@ -47,6 +47,13 @@ c3f01fc8ff7dfe7759f63bf16b00f127 ./lib/firewall/wordfence.py 6ccf3a1df5aa6429cd3365b7b8ded8f4 ./lib/firewall/powerful.py 54815706261c32b57fbbdc99244b5cdd ./lib/firewall/modsecurity.py fde5445df5d77d245656adea96673cfa ./lib/firewall/squid.py +1105bb1a4236f884548c6a013a51945e ./lib/firewall/sonicwall.py +9070b43428bd17fd5faf86995cb559a2 ./lib/firewall/stringray.py +0c9cae75883a59d1a224e27339803dbe ./lib/firewall/varnish.py +8c4a95660ca3c142f3658a2df1146171 ./lib/firewall/yundun.py +608ea8be34f9ec4c92c4e22eb0c5b39c ./lib/firewall/yunsuo.py +75da205112928437d8b3f451af16e7b8 ./lib/firewall/webknight.py +95b908a21c0ff456ae59df4c6c189c54 ./lib/firewall/wallarm.py 6ea65a0160c21e144e92334acc2e3667 ./lib/firewall/anquanbao.py ad238be8225c2791d82d4c7582afe820 ./lib/firewall/generic.py 4f359db78f12132482f78a7426ea82df ./lib/attacks/gist_lookup/__init__.py @@ -61,7 +68,7 @@ a27929dffdf979f59675ad21ff5f77a6 ./lib/attacks/xss_scan/__init__.py fa40d9681c7c3024bd50ad12ef231d6d ./lib/attacks/nmap_scan/__init__.py 216999fa0e84866d5c1d96d5676034e4 ./lib/attacks/nmap_scan/nmap_opts.py 1477efbe270c386057b0170faee4335f ./lib/header_check/__init__.py -10f45e11e9702c173ab019b3b0f004b5 ./lib/core/common.py +833a08e289a14935e476742ec3a27e81 ./lib/core/common.py 1faa2b5dfad6eb538bbfe42942d2a9da ./lib/core/errors.py d41d8cd98f00b204e9800998ecf8427e ./lib/core/__init__.py 48a84b7da7d66b77f27e2ebc5270a30a ./lib/core/settings.py diff --git a/lib/core/common.py b/lib/core/common.py index 479ab59..fdcffda 100644 --- a/lib/core/common.py +++ b/lib/core/common.py @@ -38,6 +38,7 @@ class HTTP_HEADER: URI = "URI" USER_AGENT = "User-Agent" VIA = "Via" + X_CACHE = "X-Cache" X_POWERED_BY = "X-Powered-By" X_DATA_ORIGIN = "X-Data-Origin" X_FRAME_OPT = "X-Frame-Options" diff --git a/lib/firewall/aws.py b/lib/firewall/aws.py index 18dc1e5..7b4014d 100644 --- a/lib/firewall/aws.py +++ b/lib/firewall/aws.py @@ -9,17 +9,14 @@ def detect(content, **kwargs): content = str(content) detection_schema = ( re.compile(r"[0-9a-zA-Z]{16,25}<.RequestId>", re.I), - re.compile(r"AccessDenied<.Code>", re.I) + re.compile(r"AccessDenied<.Code>", re.I), + re.compile(r"\bAWS", re.I), + re.compile(r"x.amz.id.\d+", re.I), + re.compile(r"x.amz.request.id", re.I) ) - for detection in detection_schema: - if detection.search(content) is not None: - return True if headers is not None: - headers = str(headers) - detection_schema = ( - re.compile(r"x.amz.id.\d+", re.I), - re.compile(r"x.amz.request.id", re.I) - ) for detection in detection_schema: - if detection.search(headers) is not None: + if detection.search(content) is not None: + return True + elif detection.search(str(headers)) is not None: return True diff --git a/lib/firewall/sonicwall.py b/lib/firewall/sonicwall.py new file mode 100644 index 0000000..38f679a --- /dev/null +++ b/lib/firewall/sonicwall.py @@ -0,0 +1,24 @@ +import re + +from lib.core.common import HTTP_HEADER + + +__item__ = "SonicWALL Firewall (Dell)" + + +def detect(content, **kwargs): + content = str(content) + headers = kwargs.get("headers", None) + detection_schema = ( + re.compile(r"This.request.is.blocked.by.the.SonicWALL", re.I), + re.compile(r"Dell.SonicWALL", re.I), + re.compile(r"\bDell\b", re.I), + re.compile(r"Web.Site.Blocked.+\bnsa.banner", re.I), + re.compile(r"SonicWALL", re.I), + re.compile(r"<.+>policy.this.site.is.blocked<.+.>", re.I) + ) + for detection in detection_schema: + if detection.search(content) is not None: + return True + elif detection.search(headers.get(HTTP_HEADER.SERVER)) is not None: + return True diff --git a/lib/firewall/stringray.py b/lib/firewall/stringray.py new file mode 100644 index 0000000..a00261a --- /dev/null +++ b/lib/firewall/stringray.py @@ -0,0 +1,19 @@ +import re + +from lib.core.common import HTTP_HEADER + + +__item__ = "Stingray Application Firewall (Riverbed / Brocade)" + + +def detect(content, **kwargs): + headers = kwargs.get("headers", None) + status = kwargs.get("status", None) + status_schema = (403, 500) + detection_schema = ( + re.compile(r"\AX-Mapping-", re.I), + ) + for detection in detection_schema: + if detection.search(headers.get(HTTP_HEADER.SET_COOKIE, "")) is not None: + if status in status_schema: + return True diff --git a/lib/firewall/varnish.py b/lib/firewall/varnish.py new file mode 100644 index 0000000..692b874 --- /dev/null +++ b/lib/firewall/varnish.py @@ -0,0 +1,24 @@ +import re + +from lib.core.common import HTTP_HEADER + + +__item__ = "Varnish FireWall (OWASP)" + + +def detect(content, **kwargs): + content = str(content) + headers = kwargs.get("headers", None) + status = kwargs.get("status", None) + detection_schema = ( + re.compile(r"\bXID: \d+", re.I), + re.compile(r"varnish\Z", re.I), + re.compile(r"varnish"), re.I + ) + for detection in detection_schema: + if detection.search(content) is not None and status == 404: + return True + elif detection.search(headers.get(HTTP_HEADER.VIA)) is not None: + return True + elif detection.search(headers.get(HTTP_HEADER.SERVER)) is not None: + return True diff --git a/lib/firewall/wallarm.py b/lib/firewall/wallarm.py new file mode 100644 index 0000000..8ca0316 --- /dev/null +++ b/lib/firewall/wallarm.py @@ -0,0 +1,16 @@ +import re + +from lib.core.common import HTTP_HEADER + + +__item__ = "Wallarm Web Application Firewall (Wallarm)" + + +def detect(content, **kwargs): + headers = kwargs.get("headers", None) + detection_schema = ( + re.compile(r"nginx-wallarm", re.I), + ) + for detection in detection_schema: + if detection.search(headers.get(HTTP_HEADER.SERVER, "")) is not None: + return True diff --git a/lib/firewall/webknight.py b/lib/firewall/webknight.py new file mode 100644 index 0000000..2259b1f --- /dev/null +++ b/lib/firewall/webknight.py @@ -0,0 +1,22 @@ +import re + +from lib.core.common import HTTP_HEADER + + +__item__ = "WebKnight Application Firewall (AQTRONIX)" + + +def detect(content, **kwargs): + headers = kwargs.get("headers", None) + status = kwargs.get("status", None) + detection_schema = ( + re.compile(r"webknight", re.I), + re.compile(r"WebKnight", re.I) + ) + if status is not None: + if status == 999: + return True + if headers is not None: + for detection in detection_schema: + if detection.search(headers.get(HTTP_HEADER.SERVER)) is not None: + return True diff --git a/lib/firewall/yundun.py b/lib/firewall/yundun.py new file mode 100644 index 0000000..798e089 --- /dev/null +++ b/lib/firewall/yundun.py @@ -0,0 +1,19 @@ +import re + +from lib.core.common import HTTP_HEADER + + +__item__ = "Yundun Web Application Firewall (Yundun)" + + +def detect(content, **kwargs): + headers = kwargs.get("headers", None) + detection_schema = ( + re.compile(r"YUNDUN", re.I), + ) + if headers is not None: + for detection in detection_schema: + if detection.search(headers.get(HTTP_HEADER.X_CACHE)) is not None: + return True + if detection.search(headers.get(HTTP_HEADER.SERVER)) is not None: + return True diff --git a/lib/firewall/yunsuo.py b/lib/firewall/yunsuo.py new file mode 100644 index 0000000..988c6ce --- /dev/null +++ b/lib/firewall/yunsuo.py @@ -0,0 +1,19 @@ +import re + +from lib.core.common import HTTP_HEADER + + +__item__ = "Yunsuo Web Application Firewall (Yunsuo)" + + +def detect(content, **kwargs): + headers = kwargs.get("headers", None) + content = str(content) + detection_schema = ( + re.compile(r"