mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2026-10-12 02:22:55 +00:00
Fixing some of WAF bypass bugs
This commit is contained in:
+4
-1
@@ -423,7 +423,10 @@ def _doSearch():
|
||||
conf.googlePage += 1
|
||||
|
||||
def _setStdinPipeTargets():
|
||||
if conf.url:
|
||||
# Note: an explicit target source takes precedence. Without this, any non-interactive run (CI,
|
||||
# cron, subprocess) would reroute '-m/-l/-r/-g' targets through the STDIN container, losing both
|
||||
# their count and their order
|
||||
if any((conf.url, conf.direct, conf.logFile, conf.bulkFile, conf.requestFile, conf.googleDork, conf.openApiFile)):
|
||||
return
|
||||
|
||||
if isinstance(conf.stdinPipe, _collections.Iterable):
|
||||
|
||||
@@ -20,7 +20,7 @@ from lib.core.enums import OS
|
||||
from thirdparty import six
|
||||
|
||||
# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
|
||||
VERSION = "1.10.8.42"
|
||||
VERSION = "1.10.8.43"
|
||||
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)
|
||||
@@ -88,7 +88,7 @@ WAF_BYPASS_TAMPERS = (
|
||||
)
|
||||
|
||||
# Maximum number of candidate tamper (chains) trialled during automatic WAF-bypass
|
||||
WAF_BYPASS_MAX_TRIALS = 8
|
||||
WAF_BYPASS_MAX_TRIALS = len(WAF_BYPASS_TAMPERS)
|
||||
|
||||
# Browser-like request headers applied alongside the random (non-scanner) User-Agent during
|
||||
# automatic WAF bypass: sqlmap's defaults ('Accept: */*', no 'Accept-Language') are themselves a
|
||||
|
||||
@@ -1215,7 +1215,10 @@ def cmdLineParser(argv=None):
|
||||
if args.dummy:
|
||||
args.url = args.url or DUMMY_URL
|
||||
|
||||
if hasattr(sys.stdin, "fileno") and not any((os.isatty(sys.stdin.fileno()), args.api, args.ignoreStdin, "GITHUB_ACTIONS" in os.environ)):
|
||||
# Note: an explicit target source rules out reading targets from the standard input. Without
|
||||
# this, any non-interactive run (CI, cron, subprocess) would turn '-d/-u/-m/-l/-r/-g' into a
|
||||
# 'multiple targets' run reading from a pipe, which also resets per-target options in between
|
||||
if hasattr(sys.stdin, "fileno") and not any((os.isatty(sys.stdin.fileno()), args.api, args.ignoreStdin, "GITHUB_ACTIONS" in os.environ, args.direct, args.url, args.logFile, args.bulkFile, args.requestFile, args.googleDork, args.configFile, args.openApiFile)):
|
||||
args.stdinPipe = iter(sys.stdin.readline, None)
|
||||
else:
|
||||
args.stdinPipe = None
|
||||
|
||||
@@ -120,7 +120,7 @@ class Fingerprint(GenericFingerprint):
|
||||
fork = FORK.DORIS
|
||||
elif inject.checkBooleanExpression("@@VERSION_COMMENT LIKE '%StarRocks%'"):
|
||||
fork = FORK.STARROCKS
|
||||
elif inject.checkBooleanExpression("GEOGRAPHY_AREA(NULL) IS NULL"): # Note: MemSQL is the only one of the forks without SESSION_USER()
|
||||
elif inject.checkBooleanExpression("GEOGRAPHY_AREA(NULL) IS NULL"): # Note: GEOGRAPHY_AREA() is MemSQL specific
|
||||
fork = FORK.MEMSQL
|
||||
elif inject.checkBooleanExpression("AURORA_VERSION() LIKE '%'"): # Reference: https://aws.amazon.com/premiumsupport/knowledge-center/aurora-version-number/
|
||||
fork = FORK.AURORA
|
||||
|
||||
+26
-3
@@ -7,6 +7,8 @@ See the file 'LICENSE' for copying permission
|
||||
|
||||
import re
|
||||
|
||||
from lib.core.common import Backend
|
||||
from lib.core.enums import DBMS
|
||||
from lib.core.enums import PRIORITY
|
||||
|
||||
__priority__ = PRIORITY.NORMAL
|
||||
@@ -43,7 +45,16 @@ def _unwrapIsnull(query):
|
||||
break
|
||||
|
||||
inner = retVal[match.end():end]
|
||||
separator = inner.rfind(',')
|
||||
separator, depth = -1, 0 # the argument separator is the comma at the top level
|
||||
|
||||
for index, char in enumerate(inner):
|
||||
if char == '(':
|
||||
depth += 1
|
||||
elif char == ')':
|
||||
depth -= 1
|
||||
elif char == ',' and depth == 0:
|
||||
separator = index
|
||||
|
||||
if separator < 1:
|
||||
break
|
||||
|
||||
@@ -75,6 +86,11 @@ def _reshape(payload, opener, tail, build):
|
||||
pos = pos + match.end()
|
||||
continue
|
||||
replacement = build(query, rest)
|
||||
|
||||
if replacement is None: # builder declined, leave this occurrence alone
|
||||
pos = pos + match.end()
|
||||
continue
|
||||
|
||||
retVal = retVal[:start] + replacement + retVal[end + 1 + rest.end():]
|
||||
pos = start + len(replacement)
|
||||
return retVal
|
||||
@@ -134,7 +150,12 @@ def tamper(payload, **kwargs):
|
||||
def _mysqlSet(query, rest):
|
||||
# set-membership form of the same read ('... IN (<ordinals>)', used by the Huffman retrieval).
|
||||
# ORD('') is 0, so a past-the-end position matches the ordinal 0, which is the empty string here
|
||||
position, ordinals = rest.group(1), [int(_) for _ in rest.group(2).split(',')]
|
||||
position = rest.group(1)
|
||||
ordinals = [int(_) for _ in rest.group(2).split(',') if _.strip().isdigit()]
|
||||
|
||||
if not ordinals or any(_ > 255 for _ in ordinals): # a byte comparison cannot represent those
|
||||
return None
|
||||
|
||||
query = _unwrapIsnull(query)
|
||||
members = ",".join("''" if _ == 0 else "0x%02x" % _ for _ in ordinals)
|
||||
return "BINARY RIGHT(LEFT(%s,%s),(%s<=LENGTH(CONVERT(%s USING ascii)))) IN (%s)" % (query, position, position, query, members)
|
||||
@@ -150,7 +171,9 @@ def tamper(payload, **kwargs):
|
||||
comma_tail = r"\s*,\s*(\d+)\s*,\s*1\)\)\s*(>=|<=|>|<|=)\s*(\d+)"
|
||||
set_tail = r"\s*,\s*(\d+)\s*,\s*1\)\)\s+IN\s*\(([\d,\s]+)\)"
|
||||
|
||||
if re.search(r"(?i)IFNULL\(", payload): # also on payloads that are not single-character reads
|
||||
# also on payloads that are not single-character reads. Gated on MySQL, because IFNULL() is used
|
||||
# by H2, HSQLDB, Cubrid and others too, and IF() is not a function there
|
||||
if Backend.getIdentifiedDbms() == DBMS.MYSQL and re.search(r"(?i)IFNULL\(", payload):
|
||||
payload = _unwrapIsnull(payload)
|
||||
|
||||
retVal = _reshape(payload, r"(?i)ORD\(MID\(", set_tail, _mysqlSet)
|
||||
|
||||
Reference in New Issue
Block a user