From 9e892e93f3c758b4106d87378cfdecfab2388a87 Mon Sep 17 00:00:00 2001 From: Miroslav Stampar Date: Thu, 30 Aug 2018 14:54:15 +0200 Subject: [PATCH] Created a WAF Detectify utility --- extra/wafdetectify/__init__.py | 8 +++ extra/wafdetectify/wafdetectify.py | 107 +++++++++++++++++++++++++++++ lib/core/settings.py | 2 +- txt/checksum.md5 | 4 +- 4 files changed, 119 insertions(+), 2 deletions(-) create mode 100644 extra/wafdetectify/__init__.py create mode 100644 extra/wafdetectify/wafdetectify.py diff --git a/extra/wafdetectify/__init__.py b/extra/wafdetectify/__init__.py new file mode 100644 index 000000000..7181b22a1 --- /dev/null +++ b/extra/wafdetectify/__init__.py @@ -0,0 +1,8 @@ +#!/usr/bin/env python + +""" +Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) +See the file 'LICENSE' for copying permission +""" + +pass diff --git a/extra/wafdetectify/wafdetectify.py b/extra/wafdetectify/wafdetectify.py new file mode 100644 index 000000000..5192e1520 --- /dev/null +++ b/extra/wafdetectify/wafdetectify.py @@ -0,0 +1,107 @@ +#!/usr/bin/env python + +""" +Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) +See the file 'LICENSE' for copying permission +""" + +import cookielib +import glob +import httplib +import inspect +import os +import re +import subprocess +import sys +import urllib +import urllib2 +import urlparse + +sys.dont_write_bytecode = True + +NAME, VERSION, AUTHOR = "WAF Detectify", "0.1", "Miroslav Stampar (@stamparm)" +TIMEOUT = 10 +HEADERS = {"User-Agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:61.0) Gecko/20100101 Firefox/61.0", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "en-US,en;q=0.5", "Accept-Encoding": "gzip, deflate", "Cache-Control": "max-age=0"} +SQLMAP_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..")) +SCRIPTS_DIR = os.path.join(SQLMAP_DIR, "waf") +CACHE = {} +WAF_FUNCTIONS = [] + +def get_page(get=None, url=None, host=None, data=None): + key = (get, url, host, data) + + if key in CACHE: + return CACHE[key] + + page, headers, code = None, {}, httplib.OK + + url = url or ("%s%s%s" % (sys.argv[1], '?' if '?' not in sys.argv[1] else '&', get) if get else sys.argv[1]) + if not url.startswith("http"): + url = "http://%s" % url + + try: + req = urllib2.Request("".join(url[_].replace(' ', "%20") if _ > url.find('?') else url[_] for _ in xrange(len(url))), data, HEADERS) + page = urllib2.urlopen(req, timeout=TIMEOUT).read() + except Exception, ex: + code = getattr(ex, "code", None) + page = ex.read() if hasattr(ex, "read") else getattr(ex, "msg", "") + + result = CACHE[key] = page, headers, code + + return result + +def main(): + global WAF_FUNCTIONS + + print "%s #v%s\n by: %s\n" % (NAME, VERSION, AUTHOR) + + if len(sys.argv) < 2: + exit("[x] usage: python %s " % os.path.split(__file__)[-1]) + + cookie_jar = cookielib.CookieJar() + opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookie_jar)) + urllib2.install_opener(opener) + + sys.path.insert(0, SQLMAP_DIR) + + for found in glob.glob(os.path.join(SCRIPTS_DIR, "*.py")): + dirname, filename = os.path.split(found) + dirname = os.path.abspath(dirname) + + if filename == "__init__.py": + continue + + if dirname not in sys.path: + sys.path.insert(0, dirname) + + try: + if filename[:-3] in sys.modules: + del sys.modules[filename[:-3]] + module = __import__(filename[:-3].encode(sys.getfilesystemencoding() or "utf8")) + except ImportError, msg: + exit("[x] cannot import WAF script '%s' (%s)" % (filename[:-3], msg)) + + _ = dict(inspect.getmembers(module)) + if "detect" not in _: + exit("[x] missing function 'detect(get_page)' in WAF script '%s'" % found) + else: + WAF_FUNCTIONS.append((_["detect"], _.get("__product__", filename[:-3]))) + + WAF_FUNCTIONS = sorted(WAF_FUNCTIONS, key=lambda _: "generic" in _[1].lower()) + + print "[i] %d (sqlmap's) WAF scripts loaded" % len(WAF_FUNCTIONS) + + found = False + for function, product in WAF_FUNCTIONS: + if found and "unknown" in product.lower(): + continue + + if function(get_page): + print "[!] WAF/IPS/IDS identified as '%s'" % product + found = True + + if not found: + print "[o] nothing found" + +if __name__ == "__main__": + main() diff --git a/lib/core/settings.py b/lib/core/settings.py index 1af9fd1e0..42c97278d 100644 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -19,7 +19,7 @@ from lib.core.enums import DBMS_DIRECTORY_NAME from lib.core.enums import OS # sqlmap version (...) -VERSION = "1.2.8.23" +VERSION = "1.2.8.24" TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable" TYPE_COLORS = {"dev": 33, "stable": 90, "pip": 34} VERSION_STRING = "sqlmap/%s#%s" % ('.'.join(VERSION.split('.')[:-1]) if VERSION.count('.') > 2 and VERSION.split('.')[-1] == '0' else VERSION, TYPE) diff --git a/txt/checksum.md5 b/txt/checksum.md5 index 0dbc59dc8..96d13ebbf 100644 --- a/txt/checksum.md5 +++ b/txt/checksum.md5 @@ -21,6 +21,8 @@ e4805169a081b834ca51a60a150c7247 extra/shutils/newlines.py 1056d1112ba5130868178cb495d22b1d extra/shutils/regressiontest.py 1e5532ede194ac9c083891c2f02bca93 extra/sqlharvest/__init__.py b3e60ea4e18a65c48515d04aab28ff68 extra/sqlharvest/sqlharvest.py +1e5532ede194ac9c083891c2f02bca93 extra/wafdetectify/__init__.py +cf646f49087ff56d752dc831d2245a51 extra/wafdetectify/wafdetectify.py 3459c562a6abb9b4bdcc36925f751f3e lib/controller/action.py 7493c782345a60f6c00c9281d51a494e lib/controller/checks.py c414cecdb0472c92cf50ed5b01e4438c lib/controller/controller.py @@ -48,7 +50,7 @@ c8c386d644d57c659d74542f5f57f632 lib/core/patch.py 0c3eef46bdbf87e29a3f95f90240d192 lib/core/replication.py a7db43859b61569b601b97f187dd31c5 lib/core/revision.py fcb74fcc9577523524659ec49e2e964b lib/core/session.py -b52affaeb83ecf36e15e75bd439df284 lib/core/settings.py +4ecbe8858ce030877cb3e00f437ac87a lib/core/settings.py dd68a9d02fccb4fa1428b20e15b0db5d lib/core/shell.py a7edc9250d13af36ac0108f259859c19 lib/core/subprocessng.py 815d1cf27f0f8738d81531e73149867d lib/core/target.py