2019-03-21 16:00:09 +03:00
|
|
|
#!/usr/bin/env python2
|
2018-08-30 15:54:15 +03:00
|
|
|
|
|
|
|
"""
|
2019-01-05 23:38:52 +03:00
|
|
|
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
2018-08-30 15:54:15 +03:00
|
|
|
See the file 'LICENSE' for copying permission
|
|
|
|
"""
|
|
|
|
|
2019-01-22 03:20:27 +03:00
|
|
|
from __future__ import print_function
|
|
|
|
|
2018-08-30 15:54:15 +03:00
|
|
|
import cookielib
|
|
|
|
import glob
|
|
|
|
import httplib
|
|
|
|
import inspect
|
|
|
|
import os
|
|
|
|
import re
|
2019-01-08 14:58:27 +03:00
|
|
|
import socket
|
|
|
|
import ssl
|
2018-08-30 15:54:15 +03:00
|
|
|
import subprocess
|
|
|
|
import sys
|
|
|
|
import urllib2
|
|
|
|
|
|
|
|
sys.dont_write_bytecode = True
|
|
|
|
|
2019-01-08 14:58:27 +03:00
|
|
|
if hasattr(ssl, "_create_unverified_context"):
|
|
|
|
ssl._create_default_https_context = ssl._create_unverified_context
|
|
|
|
|
2018-08-30 16:18:42 +03:00
|
|
|
NAME, VERSION, AUTHOR = "WAF Detectify", "0.1", "sqlmap developers (@sqlmap)"
|
2018-08-30 15:54:15 +03:00
|
|
|
TIMEOUT = 10
|
2019-01-07 18:23:18 +03:00
|
|
|
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": "identity", "Cache-Control": "max-age=0"}
|
2018-08-30 15:54:15 +03:00
|
|
|
SQLMAP_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", ".."))
|
|
|
|
SCRIPTS_DIR = os.path.join(SQLMAP_DIR, "waf")
|
2018-08-30 16:18:42 +03:00
|
|
|
LEVEL_COLORS = {"o": "\033[00;94m", "x": "\033[00;91m", "!": "\033[00;93m", "i": "\033[00;92m"}
|
2018-08-30 15:54:15 +03:00
|
|
|
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)
|
2018-08-30 16:18:42 +03:00
|
|
|
conn = urllib2.urlopen(req, timeout=TIMEOUT)
|
|
|
|
page = conn.read()
|
|
|
|
headers = conn.info()
|
2019-01-22 02:40:48 +03:00
|
|
|
except Exception as ex:
|
2018-08-30 15:54:15 +03:00
|
|
|
code = getattr(ex, "code", None)
|
|
|
|
page = ex.read() if hasattr(ex, "read") else getattr(ex, "msg", "")
|
2018-08-30 16:50:17 +03:00
|
|
|
headers = ex.info() if hasattr(ex, "info") else {}
|
2018-08-30 15:54:15 +03:00
|
|
|
|
|
|
|
result = CACHE[key] = page, headers, code
|
|
|
|
|
|
|
|
return result
|
|
|
|
|
2018-08-30 16:18:42 +03:00
|
|
|
def colorize(message):
|
2018-08-30 16:21:46 +03:00
|
|
|
if not subprocess.mswindows and sys.stdout.isatty():
|
2018-08-30 16:18:42 +03:00
|
|
|
message = re.sub(r"\[(.)\]", lambda match: "[%s%s\033[00;49m]" % (LEVEL_COLORS[match.group(1)], match.group(1)), message)
|
|
|
|
message = message.replace("@sqlmap", "\033[00;96m@sqlmap\033[00;49m")
|
|
|
|
message = message.replace(NAME, "\033[00;93m%s\033[00;49m" % NAME)
|
|
|
|
|
|
|
|
return message
|
|
|
|
|
2018-08-30 15:54:15 +03:00
|
|
|
def main():
|
|
|
|
global WAF_FUNCTIONS
|
|
|
|
|
2019-01-22 03:20:27 +03:00
|
|
|
print(colorize("%s #v%s\n by: %s\n" % (NAME, VERSION, AUTHOR)))
|
2018-08-30 15:54:15 +03:00
|
|
|
|
|
|
|
if len(sys.argv) < 2:
|
2019-03-04 18:36:19 +03:00
|
|
|
sys.exit(colorize("[x] usage: python %s <hostname>" % os.path.split(__file__)[-1]))
|
2018-08-30 15:54:15 +03:00
|
|
|
|
|
|
|
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"))
|
2019-01-22 04:08:02 +03:00
|
|
|
except ImportError as ex:
|
2019-03-04 18:36:19 +03:00
|
|
|
sys.exit(colorize("[x] cannot import WAF script '%s' (%s)" % (filename[:-3], ex)))
|
2018-08-30 15:54:15 +03:00
|
|
|
|
|
|
|
_ = dict(inspect.getmembers(module))
|
|
|
|
if "detect" not in _:
|
2019-03-04 18:36:19 +03:00
|
|
|
sys.exit(colorize("[x] missing function 'detect(get_page)' in WAF script '%s'" % found))
|
2018-08-30 15:54:15 +03:00
|
|
|
else:
|
|
|
|
WAF_FUNCTIONS.append((_["detect"], _.get("__product__", filename[:-3])))
|
|
|
|
|
|
|
|
WAF_FUNCTIONS = sorted(WAF_FUNCTIONS, key=lambda _: "generic" in _[1].lower())
|
|
|
|
|
2019-01-22 03:20:27 +03:00
|
|
|
print(colorize("[i] checking '%s'..." % sys.argv[1]))
|
2018-08-30 15:54:15 +03:00
|
|
|
|
2019-01-08 14:58:27 +03:00
|
|
|
hostname = sys.argv[1].split("//")[-1].split('/')[0]
|
|
|
|
try:
|
|
|
|
socket.getaddrinfo(hostname, None)
|
|
|
|
except socket.gaierror:
|
2019-01-22 03:20:27 +03:00
|
|
|
print(colorize("[x] host '%s' does not exist" % hostname))
|
2019-03-04 18:36:19 +03:00
|
|
|
sys.exit(1)
|
2019-01-08 14:58:27 +03:00
|
|
|
|
2018-08-30 15:54:15 +03:00
|
|
|
found = False
|
|
|
|
for function, product in WAF_FUNCTIONS:
|
|
|
|
if found and "unknown" in product.lower():
|
|
|
|
continue
|
|
|
|
|
|
|
|
if function(get_page):
|
2019-03-04 18:36:19 +03:00
|
|
|
sys.exit(colorize("[!] WAF/IPS identified as '%s'" % product))
|
2018-08-30 15:54:15 +03:00
|
|
|
|
|
|
|
if not found:
|
2019-01-22 03:20:27 +03:00
|
|
|
print(colorize("[o] nothing found"))
|
2018-08-30 15:54:15 +03:00
|
|
|
|
2019-01-22 03:28:24 +03:00
|
|
|
print()
|
2018-08-30 16:21:46 +03:00
|
|
|
|
2019-03-04 18:36:19 +03:00
|
|
|
sys.exit(int(not found))
|
2018-12-28 22:49:40 +03:00
|
|
|
|
2018-08-30 15:54:15 +03:00
|
|
|
if __name__ == "__main__":
|
|
|
|
main()
|