Further integration of identYwaf

This commit is contained in:
Miroslav Stampar 2019-05-24 13:54:10 +02:00
parent 0c79504ff1
commit ad01aa7449
7 changed files with 33 additions and 47 deletions

View File

@ -108,7 +108,6 @@ from lib.request.templates import getPageTemplate
from lib.techniques.union.test import unionTest from lib.techniques.union.test import unionTest
from lib.techniques.union.use import configUnion from lib.techniques.union.use import configUnion
from thirdparty import six from thirdparty import six
from thirdparty.identywaf import identYwaf
from thirdparty.six.moves import http_client as _http_client from thirdparty.six.moves import http_client as _http_client
def checkSqlInjection(place, parameter, value): def checkSqlInjection(place, parameter, value):
@ -1403,49 +1402,22 @@ def checkWaf():
kb.resendPostOnRedirect = popValue() kb.resendPostOnRedirect = popValue()
kb.redirectChoice = popValue() kb.redirectChoice = popValue()
# TODO: today
if retVal: if retVal:
pass if not kb.identifiedWafs:
# identYwaf warnMsg = "heuristics detected that the target "
#if conf.timeout == defaults.timeout: warnMsg += "is protected by some kind of WAF/IPS"
#logger.warning("dropping timeout to %d seconds (i.e. '--timeout=%d')" % (IDS_WAF_CHECK_TIMEOUT, IDS_WAF_CHECK_TIMEOUT)) logger.critical(warnMsg)
#conf.timeout = IDS_WAF_CHECK_TIMEOUT
# identYwaf message = "are you sure that you want to "
message += "continue with further target testing? [y/N] "
choice = readInput(message, default='N', boolean=True)
#def _(*args, **kwargs): if not conf.tamper:
#page, headers, code = None, None, None warnMsg = "please consider usage of tamper scripts (option '--tamper')"
#try: singleTimeWarnMessage(warnMsg)
#pushValue(kb.redirectChoice)
#pushValue(kb.resendPostOnRedirect)
#kb.redirectChoice = REDIRECTION.YES if not choice:
#kb.resendPostOnRedirect = True raise SqlmapUserQuitException
#if kwargs.get("get"):
#kwargs["get"] = urlencode(kwargs["get"])
#kwargs["raise404"] = False
#kwargs["silent"] = True
#kwargs["finalCode"] = True
#page, headers, code = Request.getPage(*args, **kwargs)
#except Exception:
#pass
#finally:
#kb.resendPostOnRedirect = popValue()
#kb.redirectChoice = popValue()
#message = "are you sure that you want to "
#message += "continue with further target testing? [y/N] "
#choice = readInput(message, default='N', boolean=True)
#if not conf.tamper:
#warnMsg = "please consider usage of tamper scripts (option '--tamper')"
#singleTimeWarnMessage(warnMsg)
#if not choice:
#raise SqlmapUserQuitException
hashDBWrite(HASHDB_KEYS.CHECK_WAF_RESULT, retVal, True) hashDBWrite(HASHDB_KEYS.CHECK_WAF_RESULT, retVal, True)

View File

@ -290,6 +290,7 @@ DEPRECATED_OPTIONS = {
"--purge-output": "use '--purge' instead", "--purge-output": "use '--purge' instead",
"--check-payload": None, "--check-payload": None,
"--check-waf": None, "--check-waf": None,
"--identify-waf": None,
"--pickled-options": "use '--api -c ...' instead", "--pickled-options": "use '--api -c ...' instead",
} }

View File

@ -1890,6 +1890,7 @@ def _setKnowledgeBaseAttributes(flushAll=True):
kb.ignoreCasted = None kb.ignoreCasted = None
kb.ignoreNotFound = False kb.ignoreNotFound = False
kb.ignoreTimeout = False kb.ignoreTimeout = False
kb.identifiedWafs = set()
kb.injection = InjectionDict() kb.injection = InjectionDict()
kb.injections = [] kb.injections = []
kb.laggingChecked = False kb.laggingChecked = False
@ -1970,7 +1971,6 @@ def _setKnowledgeBaseAttributes(flushAll=True):
kb.tableExistsChoice = None kb.tableExistsChoice = None
kb.uChar = NULL kb.uChar = NULL
kb.unionDuplicates = False kb.unionDuplicates = False
kb.wafSpecificResponse = None
kb.wizardMode = False kb.wizardMode = False
kb.xpCmdshellAvailable = False kb.xpCmdshellAvailable = False

View File

@ -18,7 +18,7 @@ from lib.core.enums import OS
from thirdparty.six import unichr as _unichr from thirdparty.six import unichr as _unichr
# sqlmap version (<major>.<minor>.<month>.<monthly commit>) # sqlmap version (<major>.<minor>.<month>.<monthly commit>)
VERSION = "1.3.5.131" VERSION = "1.3.5.132"
TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable" TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable"
TYPE_COLORS = {"dev": 33, "stable": 90, "pip": 34} 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) VERSION_STRING = "sqlmap/%s#%s" % ('.'.join(VERSION.split('.')[:-1]) if VERSION.count('.') > 2 and VERSION.split('.')[-1] == '0' else VERSION, TYPE)

View File

@ -51,8 +51,10 @@ from lib.parse.html import htmlParser
from lib.utils.htmlentities import htmlEntities from lib.utils.htmlentities import htmlEntities
from thirdparty import six from thirdparty import six
from thirdparty.chardet import detect from thirdparty.chardet import detect
from thirdparty.identywaf import identYwaf
from thirdparty.odict import OrderedDict from thirdparty.odict import OrderedDict
from thirdparty.six import unichr as _unichr from thirdparty.six import unichr as _unichr
from thirdparty.six.moves import http_client as _http_client
def forgeHeaders(items=None, base=None): def forgeHeaders(items=None, base=None):
""" """
@ -365,7 +367,7 @@ def decodePage(page, contentEncoding, contentType):
return page return page
def processResponse(page, responseHeaders, status=None): def processResponse(page, responseHeaders, code=None, status=None):
kb.processResponseCounter += 1 kb.processResponseCounter += 1
page = page or "" page = page or ""
@ -383,6 +385,16 @@ def processResponse(page, responseHeaders, status=None):
if msg: if msg:
logger.warning("parsed DBMS error message: '%s'" % msg.rstrip('.')) logger.warning("parsed DBMS error message: '%s'" % msg.rstrip('.'))
rawResponse = "%s %s %s\n%s\n%s" % (_http_client.HTTPConnection._http_vsn_str, code or "", status or "", "".join(responseHeaders.headers), page)
identYwaf.non_blind.clear()
if identYwaf.non_blind_check(rawResponse, silent=True):
for waf in identYwaf.non_blind:
if waf not in kb.identifiedWafs:
kb.identifiedWafs.add(waf)
errMsg = "WAF/IPS identified as '%s'" % identYwaf.format_name(waf)
singleTimeLogMessage(errMsg, logging.CRITICAL)
if kb.originalPage is None: if kb.originalPage is None:
for regex in (EVENTVALIDATION_REGEX, VIEWSTATE_REGEX): for regex in (EVENTVALIDATION_REGEX, VIEWSTATE_REGEX):
match = re.search(regex, page) match = re.search(regex, page)

View File

@ -795,7 +795,7 @@ class Connect(object):
socket.setdefaulttimeout(conf.timeout) socket.setdefaulttimeout(conf.timeout)
processResponse(page, responseHeaders, status) processResponse(page, responseHeaders, code, status)
if not skipLogTraffic: if not skipLogTraffic:
if conn and getattr(conn, "redurl", None): if conn and getattr(conn, "redurl", None):

View File

@ -66,7 +66,7 @@ else:
sys.stdout = codecs.getwriter(locale.getpreferredencoding())(sys.stdout) sys.stdout = codecs.getwriter(locale.getpreferredencoding())(sys.stdout)
NAME = "identYwaf" NAME = "identYwaf"
VERSION = "1.0.108" VERSION = "1.0.110"
BANNER = """ BANNER = """
` __ __ ` ` __ __ `
____ ___ ___ ____ ______ `| T T` __ __ ____ _____ ____ ___ ___ ____ ______ `| T T` __ __ ____ _____
@ -396,7 +396,7 @@ def init():
def format_name(waf): def format_name(waf):
return "%s%s" % (DATA_JSON["wafs"][waf]["name"], (" (%s)" % DATA_JSON["wafs"][waf]["company"]) if DATA_JSON["wafs"][waf]["name"] != DATA_JSON["wafs"][waf]["company"] else "") return "%s%s" % (DATA_JSON["wafs"][waf]["name"], (" (%s)" % DATA_JSON["wafs"][waf]["company"]) if DATA_JSON["wafs"][waf]["name"] != DATA_JSON["wafs"][waf]["company"] else "")
def non_blind_check(raw): def non_blind_check(raw, silent=False):
retval = False retval = False
match = re.search(WAF_RECOGNITION_REGEX, raw or "") match = re.search(WAF_RECOGNITION_REGEX, raw or "")
if match: if match:
@ -405,7 +405,8 @@ def non_blind_check(raw):
if match.group(_): if match.group(_):
waf = re.sub(r"\Awaf_", "", _) waf = re.sub(r"\Awaf_", "", _)
non_blind.add(waf) non_blind.add(waf)
single_print(colorize("[+] non-blind match: '%s'%s" % (format_name(waf), 20 * ' '))) if not silent:
single_print(colorize("[+] non-blind match: '%s'%s" % (format_name(waf), 20 * ' ')))
return retval return retval
def run(): def run():