Compare commits

...

30 Commits
1.2.7 ... 1.2.8

Author SHA1 Message Date
Miroslav Stampar
af89137f2c Update of WAF scripts 2018-08-05 14:19:27 +02:00
Miroslav Stampar
1f9bf587b5 Implementation for an Issue #3108 2018-07-31 02:18:33 +02:00
Miroslav Stampar
f0e4c20004 First commit related to the #3108 2018-07-31 01:17:11 +02:00
Miroslav Stampar
cef416559a Minor update 2018-07-31 00:20:52 +02:00
Miroslav Stampar
ce47b6c76e Minor patch 2018-07-27 01:39:04 +02:00
Miroslav Stampar
39108bc100 Trivial refactoring of unused variables 2018-07-27 00:59:24 +02:00
Miroslav Stampar
f63ceaa0c1 Minor refactoring 2018-07-27 00:53:14 +02:00
Miroslav Stampar
1e60378fb2 Minor refactoring 2018-07-27 00:30:30 +02:00
Miroslav Stampar
22c7bc54b4 Minor patch 2018-07-27 00:01:23 +02:00
Miroslav Stampar
5f1bae86b0 Fixes #3194 2018-07-19 18:00:56 +02:00
Miroslav Stampar
a0cbf6991d Minor style update 2018-07-18 17:00:34 +02:00
Miroslav Stampar
9f2bc00426 Minor patch 2018-07-18 16:30:59 +02:00
Miroslav Stampar
6bb486c1bf Potential patch for #3192 2018-07-18 15:34:38 +02:00
Miroslav Stampar
741ce9e3f0 Trivial update (just to reset checksums) 2018-07-15 16:08:01 +02:00
Anastasios Stasinopoulos
a479655097 Minor patch (--purge instead of --purge-output) (#3188) 2018-07-15 11:28:34 +02:00
Miroslav Stampar
4846d85ccd Pre-fetching latest revision number in case of update 2018-07-11 19:30:14 +02:00
Miroslav Stampar
3c439c3929 Known cause of majority of false-positives (Issue #3176) 2018-07-11 16:12:57 +02:00
Miroslav Stampar
5cc36a5736 Revert of last commit (Fixes #3179) 2018-07-10 15:54:06 +02:00
Miroslav Stampar
29dcdd3bef Potential patch for #3178 2018-07-10 15:35:07 +02:00
Miroslav Stampar
53eadb0af8 Fixes #3173 2018-07-09 12:22:51 +02:00
Miroslav Stampar
7b705b94e3 Fixes #3171 2018-07-09 12:20:18 +02:00
Miroslav Stampar
558484644a Minor refactoring 2018-07-06 16:22:19 +02:00
Miroslav Stampar
e84142b6a9 Fixes #3172 2018-07-06 16:18:04 +02:00
Miroslav Stampar
b44551230e Fixes #3165 2018-07-05 15:13:51 +02:00
Miroslav Stampar
4ecf6eee05 Minor style update 2018-07-05 14:21:32 +02:00
Miroslav Stampar
57be1856a6 Where things could go kaboom (changing terminal coloring) 2018-07-05 14:01:43 +02:00
Miroslav Stampar
a424e4ab59 Fixes #3168 2018-07-02 13:09:25 +02:00
Miroslav Stampar
4660b816d5 Minor patch (fallback for masking of sensitive data) 2018-07-02 11:54:12 +02:00
Miroslav Stampar
f92e1ebc40 Another trivial style update 2018-07-02 11:47:47 +02:00
Miroslav Stampar
48cd0421a6 Trivial style update 2018-07-02 11:41:36 +02:00
80 changed files with 406 additions and 336 deletions

View File

@@ -868,11 +868,11 @@ def boldifyMessage(message):
retVal = message retVal = message
if any(_ in message for _ in BOLD_PATTERNS): if any(_ in message for _ in BOLD_PATTERNS):
retVal = setColor(message, True) retVal = setColor(message, bold=True)
return retVal return retVal
def setColor(message, bold=False): def setColor(message, color=None, bold=False):
retVal = message retVal = message
level = extractRegexResult(r"\[(?P<result>%s)\]" % '|'.join(_[0] for _ in getPublicTypeMembers(LOGGING_LEVELS)), message) or kb.get("stickyLevel") level = extractRegexResult(r"\[(?P<result>%s)\]" % '|'.join(_[0] for _ in getPublicTypeMembers(LOGGING_LEVELS)), message) or kb.get("stickyLevel")
@@ -880,15 +880,11 @@ def setColor(message, bold=False):
level = unicodeencode(level) level = unicodeencode(level)
if message and getattr(LOGGER_HANDLER, "is_tty", False): # colorizing handler if message and getattr(LOGGER_HANDLER, "is_tty", False): # colorizing handler
if bold: if bold or color:
retVal = colored(message, color=None, on_color=None, attrs=("bold",)) retVal = colored(message, color=color, on_color=None, attrs=("bold",) if bold else None)
elif level: elif level:
level = getattr(logging, level, None) if isinstance(level, basestring) else level level = getattr(logging, level, None) if isinstance(level, basestring) else level
_ = LOGGER_HANDLER.level_map.get(level) retVal = LOGGER_HANDLER.colorize(message, level)
if _:
background, foreground, bold = _
retVal = colored(message, color=foreground, on_color="on_%s" % background if background else None, attrs=("bold",) if bold else None)
kb.stickyLevel = level if message and message[-1] != "\n" else None kb.stickyLevel = level if message and message[-1] != "\n" else None
return retVal return retVal
@@ -929,7 +925,7 @@ def dataToStdout(data, forceOutput=False, bold=False, content_type=None, status=
if conf.get("api"): if conf.get("api"):
sys.stdout.write(message, status, content_type) sys.stdout.write(message, status, content_type)
else: else:
sys.stdout.write(setColor(message, bold)) sys.stdout.write(setColor(message, bold=bold))
sys.stdout.flush() sys.stdout.flush()
except IOError: except IOError:
@@ -1301,7 +1297,7 @@ def setPaths(rootPath):
paths.PGSQL_XML = os.path.join(paths.SQLMAP_XML_BANNER_PATH, "postgresql.xml") paths.PGSQL_XML = os.path.join(paths.SQLMAP_XML_BANNER_PATH, "postgresql.xml")
for path in paths.values(): for path in paths.values():
if any(path.endswith(_) for _ in (".txt", ".xml", ".zip")): if any(path.endswith(_) for _ in (".md5", ".txt", ".xml", ".zip")):
checkFile(path) checkFile(path)
def weAreFrozen(): def weAreFrozen():
@@ -1321,8 +1317,6 @@ def parseTargetDirect():
if not conf.direct: if not conf.direct:
return return
conf.direct = conf.direct.encode(UNICODE_ENCODING) # some DBMS connectors (e.g. pymssql) don't like Unicode with non-US letters
details = None details = None
remote = False remote = False
@@ -1433,7 +1427,7 @@ def parseTargetUrl():
errMsg += "on this platform" errMsg += "on this platform"
raise SqlmapGenericException(errMsg) raise SqlmapGenericException(errMsg)
if not re.search(r"^http[s]*://", conf.url, re.I) and not re.search(r"^ws[s]*://", conf.url, re.I): if not re.search(r"^https?://", conf.url, re.I) and not re.search(r"^wss?://", conf.url, re.I):
if re.search(r":443\b", conf.url): if re.search(r":443\b", conf.url):
conf.url = "https://%s" % conf.url conf.url = "https://%s" % conf.url
else: else:
@@ -1534,14 +1528,14 @@ def expandAsteriskForColumns(expression):
the SQL query string (expression) the SQL query string (expression)
""" """
asterisk = re.search(r"(?i)\ASELECT(\s+TOP\s+[\d]+)?\s+\*\s+FROM\s+`?([^`\s()]+)", expression) match = re.search(r"(?i)\ASELECT(\s+TOP\s+[\d]+)?\s+\*\s+FROM\s+`?([^`\s()]+)", expression)
if asterisk: if match:
infoMsg = "you did not provide the fields in your query. " infoMsg = "you did not provide the fields in your query. "
infoMsg += "sqlmap will retrieve the column names itself" infoMsg += "sqlmap will retrieve the column names itself"
logger.info(infoMsg) logger.info(infoMsg)
_ = asterisk.group(2).replace("..", '.').replace(".dbo.", '.') _ = match.group(2).replace("..", '.').replace(".dbo.", '.')
db, conf.tbl = _.split('.', 1) if '.' in _ else (None, _) db, conf.tbl = _.split('.', 1) if '.' in _ else (None, _)
if db is None: if db is None:
@@ -3351,6 +3345,22 @@ def unhandledExceptionMessage():
return errMsg return errMsg
def getLatestRevision():
"""
Retrieves latest revision from the offical repository
"""
retVal = None
req = urllib2.Request(url="https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/lib/core/settings.py")
try:
content = urllib2.urlopen(req).read()
retVal = extractRegexResult(r"VERSION\s*=\s*[\"'](?P<result>[\d.]+)", content)
except:
pass
return retVal
def createGithubIssue(errMsg, excMsg): def createGithubIssue(errMsg, excMsg):
""" """
Automatically create a Github issue with unhandled exception information Automatically create a Github issue with unhandled exception information
@@ -3444,8 +3454,7 @@ def maskSensitiveData(msg):
retVal = retVal.replace(value, '*' * len(value)) retVal = retVal.replace(value, '*' * len(value))
# Just in case (for problematic parameters regarding user encoding) # Just in case (for problematic parameters regarding user encoding)
match = re.search(r"(?i)[ -]-(u|url|data|cookie)( |=)(.*?)( -?-[a-z]|\Z)", retVal) for match in re.finditer(r"(?i)[ -]-(u|url|data|cookie)( |=)(.*?)(?= -?-[a-z]|\Z)", retVal):
if match:
retVal = retVal.replace(match.group(3), '*' * len(match.group(3))) retVal = retVal.replace(match.group(3), '*' * len(match.group(3)))
if getpass.getuser(): if getpass.getuser():
@@ -3753,7 +3762,7 @@ def expandMnemonics(mnemonics, parser, args):
logger.debug(debugMsg) logger.debug(debugMsg)
else: else:
found = sorted(options.keys(), key=lambda x: len(x))[0] found = sorted(options.keys(), key=lambda x: len(x))[0]
warnMsg = "detected ambiguity (mnemonic '%s' can be resolved to: %s). " % (name, ", ".join("'%s'" % key for key in options.keys())) warnMsg = "detected ambiguity (mnemonic '%s' can be resolved to any of: %s). " % (name, ", ".join("'%s'" % key for key in options.keys()))
warnMsg += "Resolved to shortest of those ('%s')" % found warnMsg += "Resolved to shortest of those ('%s')" % found
logger.warn(warnMsg) logger.warn(warnMsg)
@@ -4275,9 +4284,11 @@ def extractExpectedValue(value, expected):
value = value.strip().lower() value = value.strip().lower()
if value in ("true", "false"): if value in ("true", "false"):
value = value == "true" value = value == "true"
elif value in ('t', 'f'):
value = value == 't'
elif value in ("1", "-1"): elif value in ("1", "-1"):
value = True value = True
elif value == "0": elif value == '0':
value = False value = False
else: else:
value = None value = None
@@ -4691,3 +4702,13 @@ def safeVariableNaming(value):
def unsafeVariableNaming(value): def unsafeVariableNaming(value):
return re.sub(r"%s([0-9a-f]{2})" % SAFE_VARIABLE_MARKER, lambda match: match.group(1).decode("hex"), value) return re.sub(r"%s([0-9a-f]{2})" % SAFE_VARIABLE_MARKER, lambda match: match.group(1).decode("hex"), value)
def firstNotNone(*args):
retVal = None
for _ in args:
if _ is not None:
retVal = _
break
return retVal

View File

@@ -54,6 +54,7 @@ from lib.core.common import resetCookieJar
from lib.core.common import runningAsAdmin from lib.core.common import runningAsAdmin
from lib.core.common import safeExpandUser from lib.core.common import safeExpandUser
from lib.core.common import saveConfig from lib.core.common import saveConfig
from lib.core.common import setColor
from lib.core.common import setOptimize from lib.core.common import setOptimize
from lib.core.common import setPaths from lib.core.common import setPaths
from lib.core.common import singleTimeWarnMessage from lib.core.common import singleTimeWarnMessage
@@ -699,6 +700,22 @@ def _setDBMS():
break break
def _listTamperingFunctions():
"""
Lists available tamper functions
"""
if conf.listTampers:
infoMsg = "listing available tamper scripts\n"
logger.info(infoMsg)
for script in sorted(glob.glob(os.path.join(paths.SQLMAP_TAMPER_PATH, "*.py"))):
content = openFile(script, "rb").read()
match = re.search(r'(?s)__priority__.+"""(.+)"""', content)
if match:
comment = match.group(1).strip()
dataToStdout("* %s - %s\n" % (setColor(os.path.basename(script), "yellow"), re.sub(r" *\n *", " ", comment.split("\n\n")[0].strip())))
def _setTamperingFunctions(): def _setTamperingFunctions():
""" """
Loads tampering functions from given script(s) Loads tampering functions from given script(s)
@@ -2459,6 +2476,7 @@ def init():
_setDNSServer() _setDNSServer()
_adjustLoggingFormatter() _adjustLoggingFormatter()
_setMultipleTargets() _setMultipleTargets()
_listTamperingFunctions()
_setTamperingFunctions() _setTamperingFunctions()
_setWafFunctions() _setWafFunctions()
_setTrafficOutputFP() _setTrafficOutputFP()

View File

@@ -227,6 +227,7 @@ optDict = {
"disableColoring": "boolean", "disableColoring": "boolean",
"googlePage": "integer", "googlePage": "integer",
"identifyWaf": "boolean", "identifyWaf": "boolean",
"listTampers": "boolean",
"mobile": "boolean", "mobile": "boolean",
"offline": "boolean", "offline": "boolean",
"purge": "boolean", "purge": "boolean",

View File

@@ -19,7 +19,7 @@ from lib.core.enums import DBMS_DIRECTORY_NAME
from lib.core.enums import OS from lib.core.enums import OS
# sqlmap version (<major>.<minor>.<month>.<monthly commit>) # sqlmap version (<major>.<minor>.<month>.<monthly commit>)
VERSION = "1.2.7.0" VERSION = "1.2.8.0"
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

@@ -671,6 +671,8 @@ def _createTargetDirs():
conf.outputPath = tempDir conf.outputPath = tempDir
conf.outputPath = getUnicode(conf.outputPath)
try: try:
with codecs.open(os.path.join(conf.outputPath, "target.txt"), "w+", UNICODE_ENCODING) as f: with codecs.open(os.path.join(conf.outputPath, "target.txt"), "w+", UNICODE_ENCODING) as f:
f.write(kb.originalUrls.get(conf.url) or conf.url or conf.hostname) f.write(kb.originalUrls.get(conf.url) or conf.url or conf.hostname)

View File

@@ -168,6 +168,7 @@ def runThreads(numThreads, threadFunction, cleanupFunction=None, forwardExceptio
except (KeyboardInterrupt, SqlmapUserQuitException), ex: except (KeyboardInterrupt, SqlmapUserQuitException), ex:
print print
kb.prependFlag = False
kb.threadContinue = False kb.threadContinue = False
kb.threadException = True kb.threadException = True

View File

@@ -17,6 +17,7 @@ import zipfile
from lib.core.common import dataToStdout from lib.core.common import dataToStdout
from lib.core.common import getSafeExString from lib.core.common import getSafeExString
from lib.core.common import getLatestRevision
from lib.core.common import pollProcess from lib.core.common import pollProcess
from lib.core.common import readInput from lib.core.common import readInput
from lib.core.data import conf from lib.core.data import conf
@@ -25,6 +26,7 @@ from lib.core.data import paths
from lib.core.revision import getRevisionNumber from lib.core.revision import getRevisionNumber
from lib.core.settings import GIT_REPOSITORY from lib.core.settings import GIT_REPOSITORY
from lib.core.settings import IS_WIN from lib.core.settings import IS_WIN
from lib.core.settings import VERSION
from lib.core.settings import ZIPBALL_PAGE from lib.core.settings import ZIPBALL_PAGE
from lib.core.settings import UNICODE_ENCODING from lib.core.settings import UNICODE_ENCODING
@@ -39,6 +41,10 @@ def update():
warnMsg += "from GitHub (e.g. 'git clone --depth 1 %s sqlmap')" % GIT_REPOSITORY warnMsg += "from GitHub (e.g. 'git clone --depth 1 %s sqlmap')" % GIT_REPOSITORY
logger.warn(warnMsg) logger.warn(warnMsg)
if VERSION == getLatestRevision():
logger.info("already at the latest revision '%s'" % getRevisionNumber())
return
message = "do you want to try to fetch the latest 'zipball' from repository and extract it (experimental) ? [y/N]" message = "do you want to try to fetch the latest 'zipball' from repository and extract it (experimental) ? [y/N]"
if readInput(message, default='N', boolean=True): if readInput(message, default='N', boolean=True):
directory = os.path.abspath(paths.SQLMAP_ROOT_PATH) directory = os.path.abspath(paths.SQLMAP_ROOT_PATH)

View File

@@ -637,6 +637,9 @@ def cmdLineParser(argv=None):
miscellaneous.add_option("--identify-waf", dest="identifyWaf", action="store_true", miscellaneous.add_option("--identify-waf", dest="identifyWaf", action="store_true",
help="Make a thorough testing for a WAF/IPS/IDS protection") help="Make a thorough testing for a WAF/IPS/IDS protection")
miscellaneous.add_option("--list-tampers", dest="listTampers", action="store_true",
help="Display list of available tamper scripts")
miscellaneous.add_option("--mobile", dest="mobile", action="store_true", miscellaneous.add_option("--mobile", dest="mobile", action="store_true",
help="Imitate smartphone through HTTP User-Agent header") help="Imitate smartphone through HTTP User-Agent header")
@@ -874,9 +877,9 @@ def cmdLineParser(argv=None):
if args.dummy: if args.dummy:
args.url = args.url or DUMMY_URL args.url = args.url or DUMMY_URL
if not any((args.direct, args.url, args.logFile, args.bulkFile, args.googleDork, args.configFile, args.requestFile, args.updateAll, args.smokeTest, args.liveTest, args.wizard, args.dependencies, args.purge, args.sitemapUrl)): if not any((args.direct, args.url, args.logFile, args.bulkFile, args.googleDork, args.configFile, args.requestFile, args.updateAll, args.smokeTest, args.liveTest, args.wizard, args.dependencies, args.purge, args.sitemapUrl, args.listTampers)):
errMsg = "missing a mandatory option (-d, -u, -l, -m, -r, -g, -c, -x, --wizard, --update, --purge-output or --dependencies), " errMsg = "missing a mandatory option (-d, -u, -l, -m, -r, -g, -c, -x, --list-tampers, --wizard, --update, --purge or --dependencies). "
errMsg += "use -h for basic or -hh for advanced help\n" errMsg += "Use -h for basic and -hh for advanced help\n"
parser.error(errMsg) parser.error(errMsg)
return args return args

View File

@@ -136,7 +136,7 @@ class XP_cmdshell:
for line in lines: for line in lines:
echoedLine = "echo %s " % line echoedLine = "echo %s " % line
echoedLine += ">> \"%s\%s\"" % (tmpPath, randDestFile) echoedLine += ">> \"%s\\%s\"" % (tmpPath, randDestFile)
echoedLines.append(echoedLine) echoedLines.append(echoedLine)
for echoedLine in echoedLines: for echoedLine in echoedLines:

View File

@@ -472,7 +472,6 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
currentCharIndex = threadData.shared.index[0] currentCharIndex = threadData.shared.index[0]
if kb.threadContinue: if kb.threadContinue:
start = time.time()
val = getChar(currentCharIndex, asciiTbl, not(charsetType is None and conf.charset)) val = getChar(currentCharIndex, asciiTbl, not(charsetType is None and conf.charset))
if val is None: if val is None:
val = INFERENCE_UNKNOWN_CHAR val = INFERENCE_UNKNOWN_CHAR
@@ -485,7 +484,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
if kb.threadContinue: if kb.threadContinue:
if showEta: if showEta:
progress.progress(calculateDeltaSeconds(start), threadData.shared.index[0]) progress.progress(threadData.shared.index[0])
elif conf.verbose >= 1: elif conf.verbose >= 1:
startCharIndex = 0 startCharIndex = 0
endCharIndex = 0 endCharIndex = 0
@@ -553,7 +552,6 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
while True: while True:
index += 1 index += 1
start = time.time()
# Common prediction feature (a.k.a. "good samaritan") # Common prediction feature (a.k.a. "good samaritan")
# NOTE: to be used only when multi-threading is not set for # NOTE: to be used only when multi-threading is not set for
@@ -578,7 +576,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
# Did we have luck? # Did we have luck?
if result: if result:
if showEta: if showEta:
progress.progress(calculateDeltaSeconds(start), len(commonValue)) progress.progress(len(commonValue))
elif conf.verbose in (1, 2) or conf.api: elif conf.verbose in (1, 2) or conf.api:
dataToStdout(filterControlChars(commonValue[index - 1:])) dataToStdout(filterControlChars(commonValue[index - 1:]))
@@ -628,7 +626,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
threadData.shared.value = partialValue = partialValue + val threadData.shared.value = partialValue = partialValue + val
if showEta: if showEta:
progress.progress(calculateDeltaSeconds(start), index) progress.progress(index)
elif conf.verbose in (1, 2) or conf.api: elif conf.verbose in (1, 2) or conf.api:
dataToStdout(filterControlChars(val)) dataToStdout(filterControlChars(val))

View File

@@ -16,6 +16,7 @@ from lib.core.common import calculateDeltaSeconds
from lib.core.common import dataToStdout from lib.core.common import dataToStdout
from lib.core.common import decodeHexValue from lib.core.common import decodeHexValue
from lib.core.common import extractRegexResult from lib.core.common import extractRegexResult
from lib.core.common import firstNotNone
from lib.core.common import getConsoleWidth from lib.core.common import getConsoleWidth
from lib.core.common import getPartRun from lib.core.common import getPartRun
from lib.core.common import getUnicode from lib.core.common import getUnicode
@@ -102,7 +103,7 @@ def _oneShotErrorUse(expression, field=None, chunkTest=False):
try: try:
while True: while True:
check = r"(?si)%s(?P<result>.*?)%s" % (kb.chars.start, kb.chars.stop) check = r"(?si)%s(?P<result>.*?)%s" % (kb.chars.start, kb.chars.stop)
trimcheck = r"(?si)%s(?P<result>[^<\n]*)" % kb.chars.start trimCheck = r"(?si)%s(?P<result>[^<\n]*)" % kb.chars.start
if field: if field:
nulledCastedField = agent.nullAndCastField(field) nulledCastedField = agent.nullAndCastField(field)
@@ -133,22 +134,21 @@ def _oneShotErrorUse(expression, field=None, chunkTest=False):
# Parse the returned page to get the exact error-based # Parse the returned page to get the exact error-based
# SQL injection output # SQL injection output
output = reduce(lambda x, y: x if x is not None else y, ( output = firstNotNone(
extractRegexResult(check, page), extractRegexResult(check, page),
extractRegexResult(check, threadData.lastHTTPError[2] if wasLastResponseHTTPError() else None), extractRegexResult(check, threadData.lastHTTPError[2] if wasLastResponseHTTPError() else None),
extractRegexResult(check, listToStrValue((headers[header] for header in headers if header.lower() != HTTP_HEADER.URI.lower()) if headers else None)), extractRegexResult(check, listToStrValue((headers[header] for header in headers if header.lower() != HTTP_HEADER.URI.lower()) if headers else None)),
extractRegexResult(check, threadData.lastRedirectMsg[1] if threadData.lastRedirectMsg and threadData.lastRedirectMsg[0] == threadData.lastRequestUID else None)), extractRegexResult(check, threadData.lastRedirectMsg[1] if threadData.lastRedirectMsg and threadData.lastRedirectMsg[0] == threadData.lastRequestUID else None)
None
) )
if output is not None: if output is not None:
output = getUnicode(output) output = getUnicode(output)
else: else:
trimmed = ( trimmed = firstNotNone(
extractRegexResult(trimcheck, page) or extractRegexResult(trimCheck, page),
extractRegexResult(trimcheck, threadData.lastHTTPError[2] if wasLastResponseHTTPError() else None) or extractRegexResult(trimCheck, threadData.lastHTTPError[2] if wasLastResponseHTTPError() else None),
extractRegexResult(trimcheck, listToStrValue((headers[header] for header in headers if header.lower() != HTTP_HEADER.URI.lower()) if headers else None)) or extractRegexResult(trimCheck, listToStrValue((headers[header] for header in headers if header.lower() != HTTP_HEADER.URI.lower()) if headers else None)),
extractRegexResult(trimcheck, threadData.lastRedirectMsg[1] if threadData.lastRedirectMsg and threadData.lastRedirectMsg[0] == threadData.lastRequestUID else None) extractRegexResult(trimCheck, threadData.lastRedirectMsg[1] if threadData.lastRedirectMsg and threadData.lastRedirectMsg[0] == threadData.lastRequestUID else None)
) )
if trimmed: if trimmed:
@@ -163,7 +163,7 @@ def _oneShotErrorUse(expression, field=None, chunkTest=False):
output = extractRegexResult(check, trimmed, re.IGNORECASE) output = extractRegexResult(check, trimmed, re.IGNORECASE)
if not output: if not output:
check = "(?P<result>[^\s<>'\"]+)" check = r"(?P<result>[^\s<>'\"]+)"
output = extractRegexResult(check, trimmed, re.IGNORECASE) output = extractRegexResult(check, trimmed, re.IGNORECASE)
else: else:
output = output.rstrip() output = output.rstrip()
@@ -402,7 +402,6 @@ def errorUse(expression, dump=False):
while kb.threadContinue: while kb.threadContinue:
with kb.locks.limit: with kb.locks.limit:
try: try:
valueStart = time.time()
threadData.shared.counter += 1 threadData.shared.counter += 1
num = threadData.shared.limits.next() num = threadData.shared.limits.next()
except StopIteration: except StopIteration:
@@ -419,7 +418,7 @@ def errorUse(expression, dump=False):
with kb.locks.value: with kb.locks.value:
index = None index = None
if threadData.shared.showEta: if threadData.shared.showEta:
threadData.shared.progress.progress(time.time() - valueStart, threadData.shared.counter) threadData.shared.progress.progress(threadData.shared.counter)
for index in xrange(1 + len(threadData.shared.buffered)): for index in xrange(1 + len(threadData.shared.buffered)):
if index < len(threadData.shared.buffered) and threadData.shared.buffered[index][0] >= num: if index < len(threadData.shared.buffered) and threadData.shared.buffered[index][0] >= num:
break break

View File

@@ -19,6 +19,7 @@ from lib.core.common import calculateDeltaSeconds
from lib.core.common import clearConsoleLine from lib.core.common import clearConsoleLine
from lib.core.common import dataToStdout from lib.core.common import dataToStdout
from lib.core.common import extractRegexResult from lib.core.common import extractRegexResult
from lib.core.common import firstNotNone
from lib.core.common import flattenValue from lib.core.common import flattenValue
from lib.core.common import getConsoleWidth from lib.core.common import getConsoleWidth
from lib.core.common import getPartRun from lib.core.common import getPartRun
@@ -90,7 +91,10 @@ def _oneShotUnionUse(expression, unpack=True, limited=False):
# Parse the returned page to get the exact UNION-based # Parse the returned page to get the exact UNION-based
# SQL injection output # SQL injection output
def _(regex): def _(regex):
return reduce(lambda x, y: x if x is not None else y, (extractRegexResult(regex, removeReflectiveValues(page, payload), re.DOTALL | re.IGNORECASE), extractRegexResult(regex, removeReflectiveValues(listToStrValue((_ for _ in headers.headers if not _.startswith(HTTP_HEADER.URI)) if headers else None), payload, True), re.DOTALL | re.IGNORECASE)), None) return firstNotNone(
extractRegexResult(regex, removeReflectiveValues(page, payload), re.DOTALL | re.IGNORECASE),
extractRegexResult(regex, removeReflectiveValues(listToStrValue((_ for _ in headers.headers if not _.startswith(HTTP_HEADER.URI)) if headers else None), payload, True), re.DOTALL | re.IGNORECASE)
)
# Automatically patching last char trimming cases # Automatically patching last char trimming cases
if kb.chars.stop not in (page or "") and kb.chars.stop[:-1] in (page or ""): if kb.chars.stop not in (page or "") and kb.chars.stop[:-1] in (page or ""):
@@ -308,7 +312,6 @@ def unionUse(expression, unpack=True, dump=False):
while kb.threadContinue: while kb.threadContinue:
with kb.locks.limit: with kb.locks.limit:
try: try:
valueStart = time.time()
threadData.shared.counter += 1 threadData.shared.counter += 1
num = threadData.shared.limits.next() num = threadData.shared.limits.next()
except StopIteration: except StopIteration:
@@ -333,7 +336,7 @@ def unionUse(expression, unpack=True, dump=False):
items = parseUnionPage(output) items = parseUnionPage(output)
if threadData.shared.showEta: if threadData.shared.showEta:
threadData.shared.progress.progress(time.time() - valueStart, threadData.shared.counter) threadData.shared.progress.progress(threadData.shared.counter)
if isListLike(items): if isListLike(items):
# in case that we requested N columns and we get M!=N then we have to filter a bit # in case that we requested N columns and we get M!=N then we have to filter a bit
if len(items) > 1 and len(expressionFieldsList) > 1: if len(items) > 1 and len(expressionFieldsList) > 1:
@@ -355,7 +358,7 @@ def unionUse(expression, unpack=True, dump=False):
else: else:
index = None index = None
if threadData.shared.showEta: if threadData.shared.showEta:
threadData.shared.progress.progress(time.time() - valueStart, threadData.shared.counter) threadData.shared.progress.progress(threadData.shared.counter)
for index in xrange(1 + len(threadData.shared.buffered)): for index in xrange(1 + len(threadData.shared.buffered)):
if index < len(threadData.shared.buffered) and threadData.shared.buffered[index][0] >= num: if index < len(threadData.shared.buffered) and threadData.shared.buffered[index][0] >= num:
break break

View File

@@ -7,7 +7,7 @@ See the file 'LICENSE' for copying permission
try: try:
from crypt import crypt from crypt import crypt
except ImportError: except: # removed ImportError because of https://github.com/sqlmapproject/sqlmap/issues/3171
from thirdparty.fcrypt.fcrypt import crypt from thirdparty.fcrypt.fcrypt import crypt
_multiprocessing = None _multiprocessing = None

View File

@@ -5,6 +5,8 @@ Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
import time
from lib.core.common import getUnicode from lib.core.common import getUnicode
from lib.core.common import dataToStdout from lib.core.common import dataToStdout
from lib.core.data import conf from lib.core.data import conf
@@ -17,13 +19,12 @@ class ProgressBar(object):
def __init__(self, minValue=0, maxValue=10, totalWidth=None): def __init__(self, minValue=0, maxValue=10, totalWidth=None):
self._progBar = "[]" self._progBar = "[]"
self._oldProgBar = ""
self._min = int(minValue) self._min = int(minValue)
self._max = int(maxValue) self._max = int(maxValue)
self._span = max(self._max - self._min, 0.001) self._span = max(self._max - self._min, 0.001)
self._width = totalWidth if totalWidth else conf.progressWidth self._width = totalWidth if totalWidth else conf.progressWidth
self._amount = 0 self._amount = 0
self._times = [] self._start = None
self.update() self.update()
def _convertSeconds(self, value): def _convertSeconds(self, value):
@@ -52,7 +53,7 @@ class ProgressBar(object):
percentDone = min(100, int(percentDone)) percentDone = min(100, int(percentDone))
# Figure out how many hash bars the percentage should be # Figure out how many hash bars the percentage should be
allFull = self._width - len("100%% [] %s/%s ETA 00:00" % (self._max, self._max)) allFull = self._width - len("100%% [] %s/%s (ETA 00:00)" % (self._max, self._max))
numHashes = (percentDone / 100.0) * allFull numHashes = (percentDone / 100.0) * allFull
numHashes = int(round(numHashes)) numHashes = int(round(numHashes))
@@ -68,19 +69,18 @@ class ProgressBar(object):
percentString = getUnicode(percentDone) + "%" percentString = getUnicode(percentDone) + "%"
self._progBar = "%s %s" % (percentString, self._progBar) self._progBar = "%s %s" % (percentString, self._progBar)
def progress(self, deltaTime, newAmount): def progress(self, newAmount):
""" """
This method saves item delta time and shows updated progress bar with calculated eta This method saves item delta time and shows updated progress bar with calculated eta
""" """
if len(self._times) <= ((self._max * 3) / 100) or newAmount > self._max: if self._start is None or newAmount > self._max:
self._start = time.time()
eta = None eta = None
else: else:
midTime = sum(self._times) / len(self._times) delta = time.time() - self._start
midTimeWithLatest = (midTime + deltaTime) / 2 eta = (self._max - self._min) * (1.0 * delta / newAmount) - delta
eta = midTimeWithLatest * (self._max - newAmount)
self._times.append(deltaTime)
self.update(newAmount) self.update(newAmount)
self.draw(eta) self.draw(eta)
@@ -89,9 +89,7 @@ class ProgressBar(object):
This method draws the progress bar if it has changed This method draws the progress bar if it has changed
""" """
if self._progBar != self._oldProgBar: dataToStdout("\r%s %d/%d%s" % (self._progBar, self._amount, self._max, (" (ETA %s)" % (self._convertSeconds(int(eta)) if eta is not None else "??:??"))))
self._oldProgBar = self._progBar
dataToStdout("\r%s %d/%d%s" % (self._progBar, self._amount, self._max, (" ETA %s" % self._convertSeconds(int(eta))) if eta is not None else ""))
if self._amount >= self._max: if self._amount >= self._max:
if not conf.liveTest: if not conf.liveTest:
dataToStdout("\r%s\r" % (" " * self._width)) dataToStdout("\r%s\r" % (" " * self._width))

View File

@@ -67,11 +67,11 @@ class Filesystem(GenericFilesystem):
chunkName = randomStr(lowercase=True) chunkName = randomStr(lowercase=True)
fileScrLines = self._dataToScr(fileContent, chunkName) fileScrLines = self._dataToScr(fileContent, chunkName)
logger.debug("uploading debug script to %s\%s, please wait.." % (tmpPath, randScr)) logger.debug("uploading debug script to %s\\%s, please wait.." % (tmpPath, randScr))
self.xpCmdshellWriteFile(fileScrLines, tmpPath, randScr) self.xpCmdshellWriteFile(fileScrLines, tmpPath, randScr)
logger.debug("generating chunk file %s\%s from debug script %s" % (tmpPath, chunkName, randScr)) logger.debug("generating chunk file %s\\%s from debug script %s" % (tmpPath, chunkName, randScr))
commands = ( commands = (
"cd \"%s\"" % tmpPath, "cd \"%s\"" % tmpPath,
@@ -174,10 +174,10 @@ class Filesystem(GenericFilesystem):
encodedFileContent = base64encode(wFileContent) encodedFileContent = base64encode(wFileContent)
encodedBase64File = "tmpf%s.txt" % randomStr(lowercase=True) encodedBase64File = "tmpf%s.txt" % randomStr(lowercase=True)
encodedBase64FilePath = "%s\%s" % (tmpPath, encodedBase64File) encodedBase64FilePath = "%s\\%s" % (tmpPath, encodedBase64File)
randPSScript = "tmpps%s.ps1" % randomStr(lowercase=True) randPSScript = "tmpps%s.ps1" % randomStr(lowercase=True)
randPSScriptPath = "%s\%s" % (tmpPath, randPSScript) randPSScriptPath = "%s\\%s" % (tmpPath, randPSScript)
wFileSize = len(encodedFileContent) wFileSize = len(encodedFileContent)
chunkMaxSize = 1024 chunkMaxSize = 1024
@@ -212,15 +212,15 @@ class Filesystem(GenericFilesystem):
logger.info(infoMsg) logger.info(infoMsg)
dFileName = ntpath.basename(dFile) dFileName = ntpath.basename(dFile)
sFile = "%s\%s" % (tmpPath, dFileName) sFile = "%s\\%s" % (tmpPath, dFileName)
wFileSize = os.path.getsize(wFile) wFileSize = os.path.getsize(wFile)
debugSize = 0xFF00 debugSize = 0xFF00
if wFileSize < debugSize: if wFileSize < debugSize:
chunkName = self._updateDestChunk(wFileContent, tmpPath) chunkName = self._updateDestChunk(wFileContent, tmpPath)
debugMsg = "renaming chunk file %s\%s to %s " % (tmpPath, chunkName, fileType) debugMsg = "renaming chunk file %s\\%s to %s " % (tmpPath, chunkName, fileType)
debugMsg += "file %s\%s and moving it to %s" % (tmpPath, dFileName, dFile) debugMsg += "file %s\\%s and moving it to %s" % (tmpPath, dFileName, dFile)
logger.debug(debugMsg) logger.debug(debugMsg)
commands = ( commands = (
@@ -248,7 +248,7 @@ class Filesystem(GenericFilesystem):
debugMsg = "appending chunk " debugMsg = "appending chunk "
copyCmd = "copy /B /Y %s+%s %s" % (dFileName, chunkName, dFileName) copyCmd = "copy /B /Y %s+%s %s" % (dFileName, chunkName, dFileName)
debugMsg += "%s\%s to %s file %s\%s" % (tmpPath, chunkName, fileType, tmpPath, dFileName) debugMsg += "%s\\%s to %s file %s\\%s" % (tmpPath, chunkName, fileType, tmpPath, dFileName)
logger.debug(debugMsg) logger.debug(debugMsg)
commands = ( commands = (
@@ -275,7 +275,7 @@ class Filesystem(GenericFilesystem):
randVbs = "tmps%s.vbs" % randomStr(lowercase=True) randVbs = "tmps%s.vbs" % randomStr(lowercase=True)
randFile = "tmpf%s.txt" % randomStr(lowercase=True) randFile = "tmpf%s.txt" % randomStr(lowercase=True)
randFilePath = "%s\%s" % (tmpPath, randFile) randFilePath = "%s\\%s" % (tmpPath, randFile)
vbs = """Dim inputFilePath, outputFilePath vbs = """Dim inputFilePath, outputFilePath
inputFilePath = "%s" inputFilePath = "%s"
@@ -338,7 +338,7 @@ class Filesystem(GenericFilesystem):
self.xpCmdshellWriteFile(encodedFileContent, tmpPath, randFile) self.xpCmdshellWriteFile(encodedFileContent, tmpPath, randFile)
logger.debug("uploading a visual basic decoder stub %s\%s, please wait.." % (tmpPath, randVbs)) logger.debug("uploading a visual basic decoder stub %s\\%s, please wait.." % (tmpPath, randVbs))
self.xpCmdshellWriteFile(vbs, tmpPath, randVbs) self.xpCmdshellWriteFile(vbs, tmpPath, randVbs)
@@ -359,7 +359,7 @@ class Filesystem(GenericFilesystem):
chunkMaxSize = 500 chunkMaxSize = 500
randFile = "tmpf%s.txt" % randomStr(lowercase=True) randFile = "tmpf%s.txt" % randomStr(lowercase=True)
randFilePath = "%s\%s" % (tmpPath, randFile) randFilePath = "%s\\%s" % (tmpPath, randFile)
encodedFileContent = base64encode(wFileContent) encodedFileContent = base64encode(wFileContent)

View File

@@ -100,9 +100,9 @@ class Fingerprint(GenericFingerprint):
if inject.checkBooleanExpression("XMLTABLE(NULL) IS NULL"): if inject.checkBooleanExpression("XMLTABLE(NULL) IS NULL"):
Backend.setVersion(">= 10.0") Backend.setVersion(">= 10.0")
elif inject.checkBooleanExpression("SIND(0)=0"): elif inject.checkBooleanExpression("SIND(0)=0"):
Backend.setVersion(">= 9.6.0", "< 10.0") Backend.setVersionList([">= 9.6.0", "< 10.0"])
elif inject.checkBooleanExpression("TO_JSONB(1) IS NOT NULL"): elif inject.checkBooleanExpression("TO_JSONB(1) IS NOT NULL"):
Backend.setVersion(">= 9.5.0", "< 9.6.0") Backend.setVersionList([">= 9.5.0", "< 9.6.0"])
elif inject.checkBooleanExpression("JSON_TYPEOF(NULL) IS NULL"): elif inject.checkBooleanExpression("JSON_TYPEOF(NULL) IS NULL"):
Backend.setVersionList([">= 9.4.0", "< 9.5.0"]) Backend.setVersionList([">= 9.4.0", "< 9.5.0"])
elif inject.checkBooleanExpression("ARRAY_REPLACE(NULL,1,1) IS NULL"): elif inject.checkBooleanExpression("ARRAY_REPLACE(NULL,1,1) IS NULL"):

View File

@@ -372,7 +372,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
else: else:
regVal = conf.regVal regVal = conf.regVal
infoMsg = "reading Windows registry path '%s\%s' " % (regKey, regVal) infoMsg = "reading Windows registry path '%s\\%s' " % (regKey, regVal)
logger.info(infoMsg) logger.info(infoMsg)
return self.readRegKey(regKey, regVal, True) return self.readRegKey(regKey, regVal, True)
@@ -417,7 +417,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
else: else:
regType = conf.regType regType = conf.regType
infoMsg = "adding Windows registry path '%s\%s' " % (regKey, regVal) infoMsg = "adding Windows registry path '%s\\%s' " % (regKey, regVal)
infoMsg += "with data '%s'. " % regData infoMsg += "with data '%s'. " % regData
infoMsg += "This will work only if the user running the database " infoMsg += "This will work only if the user running the database "
infoMsg += "process has privileges to modify the Windows registry." infoMsg += "process has privileges to modify the Windows registry."
@@ -449,12 +449,12 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
regVal = conf.regVal regVal = conf.regVal
message = "are you sure that you want to delete the Windows " message = "are you sure that you want to delete the Windows "
message += "registry path '%s\%s? [y/N] " % (regKey, regVal) message += "registry path '%s\\%s? [y/N] " % (regKey, regVal)
if not readInput(message, default='N', boolean=True): if not readInput(message, default='N', boolean=True):
return return
infoMsg = "deleting Windows registry path '%s\%s'. " % (regKey, regVal) infoMsg = "deleting Windows registry path '%s\\%s'. " % (regKey, regVal)
infoMsg += "This will work only if the user running the database " infoMsg += "This will work only if the user running the database "
infoMsg += "process has privileges to modify the Windows registry." infoMsg += "process has privileges to modify the Windows registry."
logger.info(infoMsg) logger.info(infoMsg)

View File

@@ -778,6 +778,10 @@ googlePage = 1
# Valid: True or False # Valid: True or False
identifyWaf = False identifyWaf = False
# Display list of available tamper scripts
# Valid: True or False
listTampers = False
# Imitate smartphone through HTTP User-Agent header. # Imitate smartphone through HTTP User-Agent header.
# Valid: True or False # Valid: True or False
mobile = False mobile = False

View File

@@ -273,6 +273,12 @@ def main():
logger.error(errMsg) logger.error(errMsg)
raise SystemExit raise SystemExit
elif all(_ in excMsg for _ in ("scramble_caching_sha2", "TypeError")):
errMsg = "please downgrade the 'PyMySQL' package (=< 0.8.1) "
errMsg += "(Reference: https://github.com/PyMySQL/PyMySQL/issues/700)"
logger.error(errMsg)
raise SystemExit
elif "must be pinned buffer, not bytearray" in excMsg: elif "must be pinned buffer, not bytearray" in excMsg:
errMsg = "error occurred at Python interpreter which " errMsg = "error occurred at Python interpreter which "
errMsg += "is fixed in 2.7.x. Please update accordingly " errMsg += "is fixed in 2.7.x. Please update accordingly "
@@ -325,7 +331,11 @@ def main():
file_ = match.group(1) file_ = match.group(1)
file_ = os.path.relpath(file_, os.path.dirname(__file__)) file_ = os.path.relpath(file_, os.path.dirname(__file__))
file_ = file_.replace("\\", '/') file_ = file_.replace("\\", '/')
file_ = re.sub(r"\.\./", '/', file_).lstrip('/') if "../" in file_:
file_ = re.sub(r"(\.\./)+", '/', file_)
else:
file_ = file_.lstrip('/')
file_ = re.sub(r"/{2,}", '/', file_)
excMsg = excMsg.replace(match.group(1), file_) excMsg = excMsg.replace(match.group(1), file_)
errMsg = maskSensitiveData(errMsg) errMsg = maskSensitiveData(errMsg)

View File

@@ -18,6 +18,9 @@ def tamper(payload, **kwargs):
""" """
Replaces each (MySQL) 0x<hex> encoded string with equivalent CONCAT(CHAR(),...) counterpart Replaces each (MySQL) 0x<hex> encoded string with equivalent CONCAT(CHAR(),...) counterpart
Requirement:
* MySQL
Tested against: Tested against:
* MySQL 4, 5.0 and 5.5 * MySQL 4, 5.0 and 5.5

View File

@@ -14,7 +14,7 @@ def dependencies():
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Replaces apostrophe character with its UTF-8 full width counterpart Replaces apostrophe character (') with its UTF-8 full width counterpart (e.g. ' -> %EF%BC%87)
References: References:
* http://www.utf8-chartable.de/unicode-utf8-table.pl?start=65280&number=128 * http://www.utf8-chartable.de/unicode-utf8-table.pl?start=65280&number=128

View File

@@ -14,7 +14,7 @@ def dependencies():
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Replaces apostrophe character with its illegal double unicode counterpart Replaces apostrophe character (') with its illegal double unicode counterpart (e.g. ' -> %00%27)
>>> tamper("1 AND '1'='1") >>> tamper("1 AND '1'='1")
'1 AND %00%271%00%27=%00%271' '1 AND %00%271%00%27=%00%271'

View File

@@ -18,7 +18,7 @@ def dependencies():
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Appends encoded NULL byte character at the end of payload Appends (Access) NULL byte character (%00) at the end of payload
Requirement: Requirement:
* Microsoft Access * Microsoft Access

View File

@@ -17,7 +17,7 @@ def dependencies():
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Base64 all characters in a given payload Base64-encodes all characters in a given payload
>>> tamper("1' AND SLEEP(5)#") >>> tamper("1' AND SLEEP(5)#")
'MScgQU5EIFNMRUVQKDUpIw==' 'MScgQU5EIFNMRUVQKDUpIw=='

View File

@@ -16,8 +16,7 @@ def dependencies():
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Replaces greater than operator ('>') with 'NOT BETWEEN 0 AND #' Replaces greater than operator ('>') with 'NOT BETWEEN 0 AND #' and equals operator ('=') with 'BETWEEN # AND #'
Replaces equals operator ('=') with 'BETWEEN # AND #'
Tested against: Tested against:
* Microsoft SQL Server 2005 * Microsoft SQL Server 2005

View File

@@ -17,8 +17,7 @@ def dependencies():
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Replaces space character after SQL statement with a valid random blank character. Replaces space character after SQL statement with a valid random blank character. Afterwards replace character '=' with operator LIKE
Afterwards replace character '=' with operator LIKE
Requirement: Requirement:
* Blue Coat SGOS with WAF activated as documented in * Blue Coat SGOS with WAF activated as documented in

View File

@@ -16,13 +16,10 @@ def dependencies():
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Double url-encodes all characters in a given payload (not processing Double URL-encodes all characters in a given payload (not processing already encoded) (e.g. SELECT -> %2553%2545%254C%2545%2543%2554)
already encoded)
Notes: Notes:
* Useful to bypass some weak web application firewalls that do not * Useful to bypass some weak web application firewalls that do not double URL-decode the request before processing it through their ruleset
double url-decode the request before processing it through their
ruleset
>>> tamper('SELECT FIELD FROM%20TABLE') >>> tamper('SELECT FIELD FROM%20TABLE')
'%2553%2545%254C%2545%2543%2554%2520%2546%2549%2545%254C%2544%2520%2546%2552%254F%254D%2520%2554%2541%2542%254C%2545' '%2553%2545%254C%2545%2543%2554%2520%2546%2549%2545%254C%2544%2520%2546%2552%254F%254D%2520%2554%2541%2542%254C%2545'

View File

@@ -16,8 +16,7 @@ def dependencies():
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Url-encodes all characters in a given payload (not processing already URL-encodes all characters in a given payload (not processing already encoded) (e.g. SELECT -> %53%45%4C%45%43%54)
encoded)
Tested against: Tested against:
* Microsoft SQL Server 2005 * Microsoft SQL Server 2005
@@ -26,10 +25,8 @@ def tamper(payload, **kwargs):
* PostgreSQL 8.3, 8.4, 9.0 * PostgreSQL 8.3, 8.4, 9.0
Notes: Notes:
* Useful to bypass very weak web application firewalls that do not * Useful to bypass very weak web application firewalls that do not url-decode the request before processing it through their ruleset
url-decode the request before processing it through their ruleset * The web server will anyway pass the url-decoded version behind, hence it should work against any DBMS
* The web server will anyway pass the url-decoded version behind,
hence it should work against any DBMS
>>> tamper('SELECT FIELD FROM%20TABLE') >>> tamper('SELECT FIELD FROM%20TABLE')
'%53%45%4C%45%43%54%20%46%49%45%4C%44%20%46%52%4F%4D%20%54%41%42%4C%45' '%53%45%4C%45%43%54%20%46%49%45%4C%44%20%46%52%4F%4D%20%54%41%42%4C%45'

View File

@@ -18,8 +18,7 @@ def dependencies():
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Unicode-url-encodes non-encoded characters in a given payload (not Unicode-URL-encodes all characters in a given payload (not processing already encoded) (e.g. SELECT -> %u0053%u0045%u004C%u0045%u0043%u0054)
processing already encoded)
Requirement: Requirement:
* ASP * ASP
@@ -32,9 +31,7 @@ def tamper(payload, **kwargs):
* PostgreSQL 9.0.3 * PostgreSQL 9.0.3
Notes: Notes:
* Useful to bypass weak web application firewalls that do not * Useful to bypass weak web application firewalls that do not unicode URL-decode the request before processing it through their ruleset
unicode url-decode the request before processing it through their
ruleset
>>> tamper('SELECT FIELD%20FROM TABLE') >>> tamper('SELECT FIELD%20FROM TABLE')
'%u0053%u0045%u004C%u0045%u0043%u0054%u0020%u0046%u0049%u0045%u004C%u0044%u0020%u0046%u0052%u004F%u004D%u0020%u0054%u0041%u0042%u004C%u0045' '%u0053%u0045%u004C%u0045%u0043%u0054%u0020%u0046%u0049%u0045%u004C%u0044%u0020%u0046%u0052%u004F%u004D%u0020%u0054%u0041%u0042%u004C%u0045'

View File

@@ -13,8 +13,7 @@ __priority__ = PRIORITY.NORMAL
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Unicode-escapes non-encoded characters in a given payload (not Unicode-escapes non-encoded characters in a given payload (not processing already encoded) (e.g. SELECT -> \u0053\u0045\u004C\u0045\u0043\u0054)
processing already encoded)
Notes: Notes:
* Useful to bypass weak filtering and/or WAFs in JSON contexes * Useful to bypass weak filtering and/or WAFs in JSON contexes

View File

@@ -19,7 +19,7 @@ def dependencies():
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Replaces instances like 'LIMIT M, N' with 'LIMIT N OFFSET M' Replaces (MySQL) instances like 'LIMIT M, N' with 'LIMIT N OFFSET M' counterpart
Requirement: Requirement:
* MySQL * MySQL

View File

@@ -19,7 +19,7 @@ def dependencies():
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Replaces instances like 'MID(A, B, C)' with 'MID(A FROM B FOR C)' Replaces (MySQL) instances like 'MID(A, B, C)' with 'MID(A FROM B FOR C)' counterpart
Requirement: Requirement:
* MySQL * MySQL

View File

@@ -16,7 +16,7 @@ def dependencies():
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Prepends (inline) comment before parentheses Prepends (inline) comment before parentheses (e.g. ( -> /**/()
Tested against: Tested against:
* Microsoft SQL Server * Microsoft SQL Server

View File

@@ -18,7 +18,7 @@ def dependencies():
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Replaces instances like 'CONCAT(A, B)' with 'CONCAT_WS(MID(CHAR(0), 0, 0), A, B)' Replaces (MySQL) instances like 'CONCAT(A, B)' with 'CONCAT_WS(MID(CHAR(0), 0, 0), A, B)' counterpart
Requirement: Requirement:
* MySQL * MySQL

View File

@@ -19,7 +19,7 @@ def dependencies():
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Replaces all occurrences of operator equal ('=') with operator 'LIKE' Replaces all occurrences of operator equal ('=') with 'LIKE' counterpart
Tested against: Tested against:
* Microsoft SQL Server 2005 * Microsoft SQL Server 2005

View File

@@ -14,7 +14,7 @@ def dependencies():
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Slash escape quotes (' and ") Slash escape single and double quotes (e.g. ' -> \')
>>> tamper('1" AND SLEEP(5)#') >>> tamper('1" AND SLEEP(5)#')
'1\\\\" AND SLEEP(5)#' '1\\\\" AND SLEEP(5)#'

View File

@@ -21,7 +21,7 @@ def dependencies():
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Adds versioned MySQL comment before each keyword Adds (MySQL) versioned comment before each keyword
Requirement: Requirement:
* MySQL < 5.1 * MySQL < 5.1

View File

@@ -16,7 +16,7 @@ def dependencies():
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
HTML encode (using code points) all non-alphanumeric characters HTML encode (using code points) all non-alphanumeric characters (e.g. ' -> &#39;)
>>> tamper("1' AND SLEEP(5)#") >>> tamper("1' AND SLEEP(5)#")
'1&#39;&#32;AND&#32;SLEEP&#40;5&#41;&#35;' '1&#39;&#32;AND&#32;SLEEP&#40;5&#41;&#35;'

View File

@@ -14,7 +14,7 @@ def dependencies():
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Replaces instances like 'IFNULL(A, B)' with 'CASE WHEN ISNULL(A) THEN (B) ELSE (A) END' Replaces instances like 'IFNULL(A, B)' with 'CASE WHEN ISNULL(A) THEN (B) ELSE (A) END' counterpart
Requirement: Requirement:
* MySQL * MySQL

View File

@@ -14,7 +14,7 @@ def dependencies():
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Replaces instances like 'IFNULL(A, B)' with 'IF(ISNULL(A), B, A)' Replaces instances like 'IFNULL(A, B)' with 'IF(ISNULL(A), B, A)' counterpart
Requirement: Requirement:
* MySQL * MySQL

View File

@@ -13,7 +13,7 @@ __priority__ = PRIORITY.NORMAL
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Add a comment to the end of all occurrences of (blacklisted) "information_schema" identifier Add an inline comment (/**/) to the end of all occurrences of (MySQL) "information_schema" identifier
>>> tamper('SELECT table_name FROM INFORMATION_SCHEMA.TABLES') >>> tamper('SELECT table_name FROM INFORMATION_SCHEMA.TABLES')
'SELECT table_name FROM INFORMATION_SCHEMA/**/.TABLES' 'SELECT table_name FROM INFORMATION_SCHEMA/**/.TABLES'

View File

@@ -17,7 +17,7 @@ def dependencies():
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Replaces each keyword character with lower case value Replaces each keyword character with lower case value (e.g. SELECT -> select)
Tested against: Tested against:
* Microsoft SQL Server 2005 * Microsoft SQL Server 2005

View File

@@ -19,7 +19,7 @@ def dependencies():
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Embraces complete query with versioned comment Embraces complete query with (MySQL) versioned comment
Requirement: Requirement:
* MySQL * MySQL

View File

@@ -18,7 +18,7 @@ def dependencies():
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Embraces complete query with zero-versioned comment Embraces complete query with (MySQL) zero-versioned comment
Requirement: Requirement:
* MySQL * MySQL

View File

@@ -18,7 +18,7 @@ def dependencies():
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Adds multiple spaces around SQL keywords Adds multiple spaces (' ') around SQL keywords
Notes: Notes:
* Useful to bypass very weak and bespoke web application firewalls * Useful to bypass very weak and bespoke web application firewalls

View File

@@ -15,8 +15,7 @@ __priority__ = PRIORITY.NORMAL
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Replaces predefined SQL keywords with representations Replaces predefined SQL keywords with representations suitable for replacement filters (e.g. SELECT -> SELSELECTECT)
suitable for replacement (e.g. .replace("SELECT", "")) filters
Notes: Notes:
* Useful to bypass very weak custom filters * Useful to bypass very weak custom filters

View File

@@ -16,10 +16,11 @@ def dependencies():
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Converts all (non-alphanum) characters in a given payload (not processing already encoded) Converts all (non-alphanum) characters in a given payload to overlong UTF8 (not processing already encoded) (e.g. ' -> %C0%A7)
Reference: https://www.acunetix.com/vulnerabilities/unicode-transformation-issues/ Reference:
Reference: https://www.thecodingforums.com/threads/newbie-question-about-character-encoding-what-does-0xc0-0x8a-have-in-common-with-0xe0-0x80-0x8a.170201/ * https://www.acunetix.com/vulnerabilities/unicode-transformation-issues/
* https://www.thecodingforums.com/threads/newbie-question-about-character-encoding-what-does-0xc0-0x8a-have-in-common-with-0xe0-0x80-0x8a.170201/
>>> tamper('SELECT FIELD FROM TABLE WHERE 2>1') >>> tamper('SELECT FIELD FROM TABLE WHERE 2>1')
'SELECT%C0%A0FIELD%C0%A0FROM%C0%A0TABLE%C0%A0WHERE%C0%A02%C0%BE1' 'SELECT%C0%A0FIELD%C0%A0FROM%C0%A0TABLE%C0%A0WHERE%C0%A02%C0%BE1'

View File

@@ -16,10 +16,11 @@ def dependencies():
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Converts all characters in a given payload (not processing already encoded) Converts all characters in a given payload to overlong UTF8 (not processing already encoded) (e.g. SELECT -> %C1%93%C1%85%C1%8C%C1%85%C1%83%C1%94)
Reference: https://www.acunetix.com/vulnerabilities/unicode-transformation-issues/ Reference:
Reference: https://www.thecodingforums.com/threads/newbie-question-about-character-encoding-what-does-0xc0-0x8a-have-in-common-with-0xe0-0x80-0x8a.170201/ * https://www.acunetix.com/vulnerabilities/unicode-transformation-issues/
* https://www.thecodingforums.com/threads/newbie-question-about-character-encoding-what-does-0xc0-0x8a-have-in-common-with-0xe0-0x80-0x8a.170201/
>>> tamper('SELECT FIELD FROM TABLE WHERE 2>1') >>> tamper('SELECT FIELD FROM TABLE WHERE 2>1')
'%C1%93%C1%85%C1%8C%C1%85%C1%83%C1%94%C0%A0%C1%86%C1%89%C1%85%C1%8C%C1%84%C0%A0%C1%86%C1%92%C1%8F%C1%8D%C0%A0%C1%94%C1%81%C1%82%C1%8C%C1%85%C0%A0%C1%97%C1%88%C1%85%C1%92%C1%85%C0%A0%C0%B2%C0%BE%C0%B1' '%C1%93%C1%85%C1%8C%C1%85%C1%83%C1%94%C0%A0%C1%86%C1%89%C1%85%C1%8C%C1%84%C0%A0%C1%86%C1%92%C1%8F%C1%8D%C0%A0%C1%94%C1%81%C1%82%C1%8C%C1%85%C0%A0%C1%97%C1%88%C1%85%C1%92%C1%85%C0%A0%C0%B2%C0%BE%C0%B1'

View File

@@ -18,7 +18,7 @@ def dependencies():
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Adds a percentage sign ('%') infront of each character Adds a percentage sign ('%') infront of each character (e.g. SELECT -> %S%E%L%E%C%T)
Requirement: Requirement:
* ASP * ASP

View File

@@ -20,7 +20,7 @@ def dependencies():
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Replaces plus ('+') character with function CONCAT() Replaces plus operator ('+') with (MsSQL) function CONCAT() counterpart
Tested against: Tested against:
* Microsoft SQL Server 2012 * Microsoft SQL Server 2012

View File

@@ -20,7 +20,7 @@ def dependencies():
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Replaces plus ('+') character with ODBC function {fn CONCAT()} Replaces plus operator ('+') with (MsSQL) ODBC function {fn CONCAT()} counterpart
Tested against: Tested against:
* Microsoft SQL Server 2008 * Microsoft SQL Server 2008

View File

@@ -18,7 +18,7 @@ def dependencies():
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Replaces each keyword character with random case value Replaces each keyword character with random case value (e.g. SELECT -> SEleCt)
Tested against: Tested against:
* Microsoft SQL Server 2005 * Microsoft SQL Server 2005

View File

@@ -15,7 +15,7 @@ __priority__ = PRIORITY.LOW
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Add random comments to SQL keywords Add random inline comments inside SQL keywords (e.g. SELECT -> S/**/E/**/LECT)
>>> import random >>> import random
>>> random.seed(0) >>> random.seed(0)

View File

@@ -14,11 +14,10 @@ def dependencies():
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Appends special crafted string Appends special crafted string for bypassing Imperva SecureSphere WAF
Notes: Reference:
* Useful for bypassing Imperva SecureSphere WAF * http://seclists.org/fulldisclosure/2011/May/163
* Reference: http://seclists.org/fulldisclosure/2011/May/163
>>> tamper('1 AND 1=1') >>> tamper('1 AND 1=1')
"1 AND 1=1 and '0having'='0having'" "1 AND 1=1 and '0having'='0having'"

View File

@@ -11,7 +11,7 @@ __priority__ = PRIORITY.HIGH
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Appends 'sp_password' to the end of the payload for automatic obfuscation from DBMS logs Appends (MsSQL) function 'sp_password' to the end of the payload for automatic obfuscation from DBMS logs
Requirement: Requirement:
* MSSQL * MSSQL

View File

@@ -14,8 +14,7 @@ __priority__ = PRIORITY.LOW
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Replaces space character (' ') with a dash comment ('--') followed by Replaces space character (' ') with a dash comment ('--') followed by a random string and a new line ('\n')
a random string and a new line ('\n')
Requirement: Requirement:
* MSSQL * MSSQL

View File

@@ -20,8 +20,7 @@ def dependencies():
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Replaces space character (' ') with a pound character ('#') followed by Replaces (MySQL) instances of space character (' ') with a pound character ('#') followed by a random string and a new line ('\n')
a random string and a new line ('\n')
Requirement: Requirement:
* MySQL * MySQL

View File

@@ -14,7 +14,7 @@ def dependencies():
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Replaces space character (' ') with comments '/**_**/' Replaces (MySQL) instances of space character (' ') with comments '/**_**/'
Tested against: Tested against:
* MySQL 5.0 and 5.5 * MySQL 5.0 and 5.5

View File

@@ -23,8 +23,7 @@ def dependencies():
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Replaces space character (' ') with a pound character ('#') followed by Replaces (MySQL) instances of space character (' ') with a pound character ('#') followed by a random string and a new line ('\n')
a random string and a new line ('\n')
Requirement: Requirement:
* MySQL >= 5.1.13 * MySQL >= 5.1.13

View File

@@ -19,8 +19,7 @@ def dependencies():
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Replaces space character (' ') with a random blank character from a Replaces (MsSQL) instances of space character (' ') with a random blank character from a valid set of alternate characters
valid set of alternate characters
Requirement: Requirement:
* Microsoft SQL Server * Microsoft SQL Server

View File

@@ -11,8 +11,7 @@ __priority__ = PRIORITY.LOW
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Replaces space character (' ') with a pound character ('#') followed by Replaces space character (' ') with a pound character ('#') followed by a new line ('\n')
a new line ('\n')
Requirement: Requirement:
* MSSQL * MSSQL

View File

@@ -19,8 +19,7 @@ def dependencies():
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Replaces space character (' ') with a random blank character from a Replaces (MySQL) instances of space character (' ') with a random blank character from a valid set of alternate characters
valid set of alternate characters
Requirement: Requirement:
* MySQL * MySQL

View File

@@ -18,15 +18,12 @@ def dependencies():
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Replaces space character (' ') with a dash comment ('--') followed by Replaces space character (' ') with a dash comment ('--') followed by a new line ('\n')
a new line ('\n')
Requirement: Requirement:
* MySQL * MySQL
* MSSQL * MSSQL
Tested against:
Notes: Notes:
* Useful to bypass several web application firewalls. * Useful to bypass several web application firewalls.

View File

@@ -17,8 +17,7 @@ def tamper(payload, **kwargs):
Replaces space character (' ') with plus ('+') Replaces space character (' ') with plus ('+')
Notes: Notes:
* Is this any useful? The plus get's url-encoded by sqlmap engine * Is this any useful? The plus get's url-encoded by sqlmap engine invalidating the query afterwards
invalidating the query afterwards
* This tamper script works against all databases * This tamper script works against all databases
>>> tamper('SELECT id FROM users') >>> tamper('SELECT id FROM users')

View File

@@ -16,8 +16,7 @@ def dependencies():
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Replaces space character (' ') with a random blank character from a Replaces space character (' ') with a random blank character from a valid set of alternate characters
valid set of alternate characters
Tested against: Tested against:
* Microsoft SQL Server 2005 * Microsoft SQL Server 2005

View File

@@ -14,7 +14,7 @@ def dependencies():
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Replaces UNION ALL SELECT with UNION SELECT Replaces instances of UNION ALL SELECT with UNION SELECT counterpart
>>> tamper('-1 UNION ALL SELECT') >>> tamper('-1 UNION ALL SELECT')
'-1 UNION SELECT' '-1 UNION SELECT'

View File

@@ -16,8 +16,7 @@ def dependencies():
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Replaces quote character (') with a multi-byte combo %bf%27 together with Replaces quote character (') with a multi-byte combo %BF%27 together with generic comment at the end (to make it work)
generic comment at the end (to make it work)
Notes: Notes:
* Useful for bypassing magic_quotes/addslashes feature * Useful for bypassing magic_quotes/addslashes feature

View File

@@ -17,7 +17,7 @@ def dependencies():
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Replaces each keyword character with upper case value Replaces each keyword character with upper case value (e.g. select -> SELECT)
Tested against: Tested against:
* Microsoft SQL Server 2005 * Microsoft SQL Server 2005

View File

@@ -14,12 +14,12 @@ def dependencies():
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Append a HTTP header 'X-originating-IP' to bypass Appends a HTTP header 'X-originating-IP' to bypass Varnish Firewall
WAF Protection of Varnish Firewall
Reference:
* http://h30499.www3.hp.com/t5/Fortify-Application-Security/Bypassing-web-application-firewalls-using-HTTP-headers/ba-p/6418366
Notes: Notes:
Reference: http://h30499.www3.hp.com/t5/Fortify-Application-Security/Bypassing-web-application-firewalls-using-HTTP-headers/ba-p/6418366
Examples: Examples:
>> X-forwarded-for: TARGET_CACHESERVER_IP (184.189.250.X) >> X-forwarded-for: TARGET_CACHESERVER_IP (184.189.250.X)
>> X-remote-IP: TARGET_PROXY_IP (184.189.250.X) >> X-remote-IP: TARGET_PROXY_IP (184.189.250.X)

View File

@@ -20,7 +20,7 @@ def dependencies():
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Encloses each non-function keyword with versioned MySQL comment Encloses each non-function keyword with (MySQL) versioned comment
Requirement: Requirement:
* MySQL * MySQL

View File

@@ -21,7 +21,7 @@ def dependencies():
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Encloses each keyword with versioned MySQL comment Encloses each keyword with (MySQL) versioned comment
Requirement: Requirement:
* MySQL >= 5.1.13 * MySQL >= 5.1.13

View File

@@ -20,8 +20,7 @@ def randomIP():
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Append a fake HTTP header 'X-Forwarded-For' to bypass Append a fake HTTP header 'X-Forwarded-For'
WAF (usually application based) protection
""" """
headers = kwargs.get("headers", {}) headers = kwargs.get("headers", {})

View File

@@ -1,6 +1,8 @@
# #
# Copyright (C) 2010-2012 Vinay Sajip. All rights reserved. Licensed under the new BSD license. # Copyright (C) 2010-2012 Vinay Sajip. All rights reserved. Licensed under the new BSD license.
# (Note: 2018 modifications by @stamparm)
# #
import logging import logging
import os import os
import re import re
@@ -43,6 +45,7 @@ class ColorizingStreamHandler(logging.StreamHandler):
} }
csi = '\x1b[' csi = '\x1b['
reset = '\x1b[0m' reset = '\x1b[0m'
bold = "\x1b[1m"
disable_coloring = False disable_coloring = False
@property @property
@@ -127,9 +130,9 @@ class ColorizingStreamHandler(logging.StreamHandler):
ctypes.windll.kernel32.SetConsoleTextAttribute(h, color) ctypes.windll.kernel32.SetConsoleTextAttribute(h, color)
def colorize(self, message, record): def colorize(self, message, levelno):
if record.levelno in self.level_map and self.is_tty: if levelno in self.level_map and self.is_tty:
bg, fg, bold = self.level_map[record.levelno] bg, fg, bold = self.level_map[levelno]
params = [] params = []
if bg in self.color_map: if bg in self.color_map:
@@ -142,17 +145,60 @@ class ColorizingStreamHandler(logging.StreamHandler):
params.append('1') params.append('1')
if params and message: if params and message:
if message.lstrip() != message: match = re.search(r"\A(\s+)", message)
prefix = re.search(r"\s+", message).group(0) prefix = match.group(1) if match else ""
message = message[len(prefix):]
else:
prefix = ""
message = "%s%s" % (prefix, ''.join((self.csi, ';'.join(params), match = re.search(r"\[([A-Z ]+)\]", message) # log level
'm', message, self.reset))) if match:
level = match.group(1)
if message.startswith(self.bold):
message = message.replace(self.bold, "")
reset = self.reset + self.bold
params.append('1')
else:
reset = self.reset
message = message.replace(level, ''.join((self.csi, ';'.join(params), 'm', level, reset)), 1)
match = re.search(r"\A\s*\[([\d:]+)\]", message) # time
if match:
time = match.group(1)
if not message.endswith(self.reset):
reset = self.reset
elif self.bold in message: # bold
reset = self.reset + self.bold
else:
reset = self.reset
message = message.replace(time, ''.join((self.csi, str(self.color_map["cyan"] + 30), 'm', time, reset)), 1)
match = re.search(r"\[(#\d+)\]", message) # counter
if match:
counter = match.group(1)
if not message.endswith(self.reset):
reset = self.reset
elif self.bold in message: # bold
reset = self.reset + self.bold
else:
reset = self.reset
message = message.replace(counter, ''.join((self.csi, str(self.color_map["yellow"] + 30), 'm', counter, reset)), 1)
match = re.search(r"'([^']+)'", message) # single-quoted
if level != "PAYLOAD" and match:
string = match.group(1)
if not message.endswith(self.reset):
reset = self.reset
elif self.bold in message: # bold
reset = self.reset + self.bold
else:
reset = self.reset
message = message.replace(string, ''.join((self.csi, str(self.color_map["white"] + 30), 'm', string, reset)), 1)
else:
message = ''.join((self.csi, ';'.join(params), 'm', message, self.reset))
if prefix:
message = "%s%s" % (prefix, message)
return message return message
def format(self, record): def format(self, record):
message = logging.StreamHandler.format(self, record) message = logging.StreamHandler.format(self, record)
return self.colorize(message, record) return self.colorize(message, record.levelno)

View File

@@ -28,7 +28,7 @@ c7443613a0a2505b1faec931cee2a6ef lib/controller/handler.py
1e5532ede194ac9c083891c2f02bca93 lib/controller/__init__.py 1e5532ede194ac9c083891c2f02bca93 lib/controller/__init__.py
0adf547455a76dc71e6a599e52da1ed9 lib/core/agent.py 0adf547455a76dc71e6a599e52da1ed9 lib/core/agent.py
fd8f239e259afaf5f24bcf34a0ad187f lib/core/bigarray.py fd8f239e259afaf5f24bcf34a0ad187f lib/core/bigarray.py
acec51826b280ad96dedbb56515e3988 lib/core/common.py ee1b800e860263b877a2b292a3e4becd lib/core/common.py
0d082da16c388b3445e656e0760fb582 lib/core/convert.py 0d082da16c388b3445e656e0760fb582 lib/core/convert.py
9f87391b6a3395f7f50830b391264f27 lib/core/data.py 9f87391b6a3395f7f50830b391264f27 lib/core/data.py
72016ea5c994a711a262fd64572a0fcd lib/core/datatype.py 72016ea5c994a711a262fd64572a0fcd lib/core/datatype.py
@@ -40,26 +40,26 @@ ab3f4f3e3019add5f4a2e28f7e8748a4 lib/core/enums.py
cada93357a7321655927fc9625b3bfec lib/core/exception.py cada93357a7321655927fc9625b3bfec lib/core/exception.py
1e5532ede194ac9c083891c2f02bca93 lib/core/__init__.py 1e5532ede194ac9c083891c2f02bca93 lib/core/__init__.py
458a194764805cd8312c14ecd4be4d1e lib/core/log.py 458a194764805cd8312c14ecd4be4d1e lib/core/log.py
13c0a490b5a928b64236b4a15e578267 lib/core/optiondict.py 05f72baa2db4073bb0273d7fc1df13eb lib/core/optiondict.py
c82dee0f62e729213b92f5ec85f74b70 lib/core/option.py 8e759d4c8711a5980d4bdc2d044a4fd4 lib/core/option.py
c8c386d644d57c659d74542f5f57f632 lib/core/patch.py c8c386d644d57c659d74542f5f57f632 lib/core/patch.py
6783160150b4711d02c56ee2beadffdb lib/core/profiling.py 6783160150b4711d02c56ee2beadffdb lib/core/profiling.py
6f654e1715571eff68a0f8af3d62dcf8 lib/core/readlineng.py 6f654e1715571eff68a0f8af3d62dcf8 lib/core/readlineng.py
0c3eef46bdbf87e29a3f95f90240d192 lib/core/replication.py 0c3eef46bdbf87e29a3f95f90240d192 lib/core/replication.py
a7db43859b61569b601b97f187dd31c5 lib/core/revision.py a7db43859b61569b601b97f187dd31c5 lib/core/revision.py
fcb74fcc9577523524659ec49e2e964b lib/core/session.py fcb74fcc9577523524659ec49e2e964b lib/core/session.py
9e328a8f6e8e76c8d78779a8041d47c7 lib/core/settings.py 355a1680a1f53013390849ca50322c0e lib/core/settings.py
dd68a9d02fccb4fa1428b20e15b0db5d lib/core/shell.py dd68a9d02fccb4fa1428b20e15b0db5d lib/core/shell.py
a7edc9250d13af36ac0108f259859c19 lib/core/subprocessng.py a7edc9250d13af36ac0108f259859c19 lib/core/subprocessng.py
95f04c1c1d8c3998d86e1bdf0e12771c lib/core/target.py 12bed9603b6fba3e5ffda11d584bc449 lib/core/target.py
72d499ca8d792e90a1ebfb2ad2341a51 lib/core/testing.py 72d499ca8d792e90a1ebfb2ad2341a51 lib/core/testing.py
de9922a29c71a235cb95a916ff925db2 lib/core/threads.py e896992e4db26605ab1e73615b1f9434 lib/core/threads.py
c40758411bb0bd68764d78e0bb72bd0f lib/core/unescaper.py c40758411bb0bd68764d78e0bb72bd0f lib/core/unescaper.py
9d395b143be295a143eb5c9b926f3569 lib/core/update.py b35636650cfe721f5cc47fb91737c061 lib/core/update.py
e772deb63270375e685fa5a7b775c382 lib/core/wordlist.py e772deb63270375e685fa5a7b775c382 lib/core/wordlist.py
1e5532ede194ac9c083891c2f02bca93 lib/__init__.py 1e5532ede194ac9c083891c2f02bca93 lib/__init__.py
7620f1f4b8791e13c7184c06b5421754 lib/parse/banner.py 7620f1f4b8791e13c7184c06b5421754 lib/parse/banner.py
3dd11b8be62e15a9d54cf5f08c603ffc lib/parse/cmdline.py babf5c48bc6a3797fc459706af4465cd lib/parse/cmdline.py
fb2e2f05dde98caeac6ccf3e67192177 lib/parse/configfile.py fb2e2f05dde98caeac6ccf3e67192177 lib/parse/configfile.py
3794ff139869f5ae8e81cfdbe5714f56 lib/parse/handler.py 3794ff139869f5ae8e81cfdbe5714f56 lib/parse/handler.py
6bab53ea9d75bc9bb8169d3e8f3f149f lib/parse/headers.py 6bab53ea9d75bc9bb8169d3e8f3f149f lib/parse/headers.py
@@ -88,18 +88,18 @@ acc1db3667bf910b809eb279b60595eb lib/takeover/icmpsh.py
fb9e34d558293b5d6b9727f440712886 lib/takeover/registry.py fb9e34d558293b5d6b9727f440712886 lib/takeover/registry.py
48575dde7bb867b7937769f569a98309 lib/takeover/udf.py 48575dde7bb867b7937769f569a98309 lib/takeover/udf.py
f6f835e4190a55e42d13c1e7ca3f728f lib/takeover/web.py f6f835e4190a55e42d13c1e7ca3f728f lib/takeover/web.py
f1decf0a987bd3a4bc757212cbe6a6c8 lib/takeover/xp_cmdshell.py debc36a3ff80ba915aeeee69b21a8ddc lib/takeover/xp_cmdshell.py
4a7f231e597f754e9fcd116d13ad1a4d lib/techniques/blind/inference.py 0e9d37cbeabd1bbbfe2c53f01bbb6a6e lib/techniques/blind/inference.py
1e5532ede194ac9c083891c2f02bca93 lib/techniques/blind/__init__.py 1e5532ede194ac9c083891c2f02bca93 lib/techniques/blind/__init__.py
1e5532ede194ac9c083891c2f02bca93 lib/techniques/dns/__init__.py 1e5532ede194ac9c083891c2f02bca93 lib/techniques/dns/__init__.py
799faf9008527d2e9da9d923e50f685a lib/techniques/dns/test.py 799faf9008527d2e9da9d923e50f685a lib/techniques/dns/test.py
48a24f48da791e67309003fd5e8428cb lib/techniques/dns/use.py 48a24f48da791e67309003fd5e8428cb lib/techniques/dns/use.py
1e5532ede194ac9c083891c2f02bca93 lib/techniques/error/__init__.py 1e5532ede194ac9c083891c2f02bca93 lib/techniques/error/__init__.py
f5fb02487edaf9adaa81d54324c84f8f lib/techniques/error/use.py 6007347548e85383705eaa4b863448a2 lib/techniques/error/use.py
1e5532ede194ac9c083891c2f02bca93 lib/techniques/__init__.py 1e5532ede194ac9c083891c2f02bca93 lib/techniques/__init__.py
1e5532ede194ac9c083891c2f02bca93 lib/techniques/union/__init__.py 1e5532ede194ac9c083891c2f02bca93 lib/techniques/union/__init__.py
94d7a22bb6725a91e84ba2cd9973e96d lib/techniques/union/test.py 94d7a22bb6725a91e84ba2cd9973e96d lib/techniques/union/test.py
11ecf2effbe9f40b361843d546c3c521 lib/techniques/union/use.py 7361338240ecd9d01d1d10ec76bce069 lib/techniques/union/use.py
77ff35587af9e3dfde63b8327e230f9a lib/utils/api.py 77ff35587af9e3dfde63b8327e230f9a lib/utils/api.py
37dfb641358669f62c2acedff241348b lib/utils/brute.py 37dfb641358669f62c2acedff241348b lib/utils/brute.py
31b1e7eb489eac837db6a2bc1dcb7da7 lib/utils/crawler.py 31b1e7eb489eac837db6a2bc1dcb7da7 lib/utils/crawler.py
@@ -107,11 +107,11 @@ de9620f03231d8329ee8434884b6bacd lib/utils/deps.py
f7af65aa47329d021e2b2cc8521b42a4 lib/utils/getch.py f7af65aa47329d021e2b2cc8521b42a4 lib/utils/getch.py
7af29f61302c8693cd6436d4b69e22d3 lib/utils/har.py 7af29f61302c8693cd6436d4b69e22d3 lib/utils/har.py
062e4e8fc43ac54305a75ddd0d482f81 lib/utils/hashdb.py 062e4e8fc43ac54305a75ddd0d482f81 lib/utils/hashdb.py
cc1cfe36057f1d9bbdcba1bcc03359f9 lib/utils/hash.py 4d5b2262ad495301706a4cf4c565abec lib/utils/hash.py
011d2dbf589e0faa0deca61a651239cc lib/utils/htmlentities.py 011d2dbf589e0faa0deca61a651239cc lib/utils/htmlentities.py
1e5532ede194ac9c083891c2f02bca93 lib/utils/__init__.py 1e5532ede194ac9c083891c2f02bca93 lib/utils/__init__.py
010d8327239d33af4ce9f25683cfc012 lib/utils/pivotdumptable.py 010d8327239d33af4ce9f25683cfc012 lib/utils/pivotdumptable.py
5cb78b0e60fd7fd84502d62cf85d2064 lib/utils/progress.py 683c3bd05b6164f56a57ed495c162684 lib/utils/progress.py
0ec5cec9d93d5ffd1eaeda6e942ecadf lib/utils/purge.py 0ec5cec9d93d5ffd1eaeda6e942ecadf lib/utils/purge.py
2c5a655c8e94cbe2664ee497752ac1f2 lib/utils/search.py 2c5a655c8e94cbe2664ee497752ac1f2 lib/utils/search.py
571884f530796534f03c49cf3f380a4c lib/utils/sqlalchemy.py 571884f530796534f03c49cf3f380a4c lib/utils/sqlalchemy.py
@@ -163,7 +163,7 @@ e7d44671ae26c0bcd5fe8448be070bbd plugins/dbms/maxdb/syntax.py
bf7842bb291e2297c3c8d1023eb3e550 plugins/dbms/maxdb/takeover.py bf7842bb291e2297c3c8d1023eb3e550 plugins/dbms/maxdb/takeover.py
decc645344bb93aca504a71ba2e4cad4 plugins/dbms/mssqlserver/connector.py decc645344bb93aca504a71ba2e4cad4 plugins/dbms/mssqlserver/connector.py
f1f1541a54faf67440179fa521f99849 plugins/dbms/mssqlserver/enumeration.py f1f1541a54faf67440179fa521f99849 plugins/dbms/mssqlserver/enumeration.py
177e1d55d28ed3190bc0079b8126c6be plugins/dbms/mssqlserver/filesystem.py 65911fdc86fa6322e72319e6488a0bb8 plugins/dbms/mssqlserver/filesystem.py
08914da79141713bd69a25c3cc7f06a8 plugins/dbms/mssqlserver/fingerprint.py 08914da79141713bd69a25c3cc7f06a8 plugins/dbms/mssqlserver/fingerprint.py
f25c50a95e5390ecd32be5a011637349 plugins/dbms/mssqlserver/__init__.py f25c50a95e5390ecd32be5a011637349 plugins/dbms/mssqlserver/__init__.py
612be1929108e7b4512a49a4a3837bbc plugins/dbms/mssqlserver/syntax.py 612be1929108e7b4512a49a4a3837bbc plugins/dbms/mssqlserver/syntax.py
@@ -185,7 +185,7 @@ bcdbd9c04d7d5a911e0e31abe1a24f0f plugins/dbms/oracle/takeover.py
f99c23db4ee6a6b8c0edbf684d360ad3 plugins/dbms/postgresql/connector.py f99c23db4ee6a6b8c0edbf684d360ad3 plugins/dbms/postgresql/connector.py
7cdb821884e5f15084d1bea7f8a50574 plugins/dbms/postgresql/enumeration.py 7cdb821884e5f15084d1bea7f8a50574 plugins/dbms/postgresql/enumeration.py
c8bb829d45752b98e6a03817b92e0fe5 plugins/dbms/postgresql/filesystem.py c8bb829d45752b98e6a03817b92e0fe5 plugins/dbms/postgresql/filesystem.py
29560cf78211888802c6e5c8681e7d71 plugins/dbms/postgresql/fingerprint.py d30806e39996e6d273f0af888f5710a4 plugins/dbms/postgresql/fingerprint.py
470860d3e85d11a67f2220bffaa415e7 plugins/dbms/postgresql/__init__.py 470860d3e85d11a67f2220bffaa415e7 plugins/dbms/postgresql/__init__.py
20e6f48f496348be45f3402ebc265dbb plugins/dbms/postgresql/syntax.py 20e6f48f496348be45f3402ebc265dbb plugins/dbms/postgresql/syntax.py
1287acf330da86a93c8e64aff46e3b65 plugins/dbms/postgresql/takeover.py 1287acf330da86a93c8e64aff46e3b65 plugins/dbms/postgresql/takeover.py
@@ -214,7 +214,7 @@ f5d5419efddfe04648ea5e953c650793 plugins/generic/fingerprint.py
f7874230e5661910d5fd21544c7d1022 plugins/generic/misc.py f7874230e5661910d5fd21544c7d1022 plugins/generic/misc.py
b1d2a7f3170f9b69e71335aa47f9b08b plugins/generic/search.py b1d2a7f3170f9b69e71335aa47f9b08b plugins/generic/search.py
a70cc0ada4b0cc9e7df23cb6d48a4a0c plugins/generic/syntax.py a70cc0ada4b0cc9e7df23cb6d48a4a0c plugins/generic/syntax.py
e522c294676ede15bee751107e9bb449 plugins/generic/takeover.py 4adc07051b727f1525cf0a2d619221f8 plugins/generic/takeover.py
4419b13a4b78d7e9e4a2632302344a1a plugins/generic/users.py 4419b13a4b78d7e9e4a2632302344a1a plugins/generic/users.py
1e5532ede194ac9c083891c2f02bca93 plugins/__init__.py 1e5532ede194ac9c083891c2f02bca93 plugins/__init__.py
5dc693e22f5d020c5c568d7325bd4226 shell/backdoors/backdoor.asp_ 5dc693e22f5d020c5c568d7325bd4226 shell/backdoors/backdoor.asp_
@@ -226,66 +226,66 @@ ec2ba8c757ac96425dcd2b97970edd3a shell/stagers/stager.asp_
0c48ddb1feb7e38a951ef05a0d48e032 shell/stagers/stager.jsp_ 0c48ddb1feb7e38a951ef05a0d48e032 shell/stagers/stager.jsp_
2f9e459a4cf6a58680978cdce5ff7971 shell/stagers/stager.php_ 2f9e459a4cf6a58680978cdce5ff7971 shell/stagers/stager.php_
4eaeef94314956e4517e5310a28d579a sqlmapapi.py 4eaeef94314956e4517e5310a28d579a sqlmapapi.py
b6e9d67cafb85ff2c3fde165fc577a8d sqlmap.py a35b5b83c12841fdf3925190c9d24299 sqlmap.py
1a1e3a78ded58b240c9dbb1b17996acf tamper/0x2char.py 523dab9e1093eb59264c6beb366b255a tamper/0x2char.py
4c3b8a7daa4bff52e01d4168be0eedbe tamper/apostrophemask.py 3a1697585ae4e7bf315e9dda97d6f321 tamper/apostrophemask.py
4115a55b8aba464723d645b7d3156b6e tamper/apostrophenullencode.py d7a119a74be9b385ee3884fb5e6af041 tamper/apostrophenullencode.py
d7e9a979eff4d7315d804a181e66fc93 tamper/appendnullbyte.py a14420ef43cdeb8fbc091116d31d31f1 tamper/appendnullbyte.py
0298d81e9dfac7ff18a5236c0f1d84b6 tamper/base64encode.py cfe19908ec32e3f2e113e759705f986b tamper/base64encode.py
9a3da4aa7b220448aa3ecbb92f68330f tamper/between.py e77a89b2af931a1820f6ba4b86d19cd4 tamper/between.py
e1d2329adc6ca89828a2eaec2951806c tamper/bluecoat.py 9df0a1810a27b92eec1375d19a95b7ef tamper/bluecoat.py
e3cdf13caedb4682bee3ff8fac103606 tamper/chardoubleencode.py 8c174b8925f4f075010b04d85c02a169 tamper/chardoubleencode.py
3b2f68476fbcf8223199e8dd4ec14b64 tamper/charencode.py 45174c61533f464806f4454be6a3f2d6 tamper/charencode.py
b502023ac6c48e49e652ba524b8e18cc tamper/charunicodeencode.py 0aadf3e93dd72a9b94cb6532b3343dd1 tamper/charunicodeencode.py
2c2b38974dc773568de7e7d771d7042c tamper/charunicodeescape.py 014f352771f0c1fb9e0f5397c5a03dc3 tamper/charunicodeescape.py
6a395de07b60f47d9474ace0a98c160f tamper/commalesslimit.py 6c618b9310ed5c8de93c927e920b1d31 tamper/commalesslimit.py
211bb8fa36a6ecb42b719c951c362851 tamper/commalessmid.py 50f6532870d2e109bf46468e8d3ded49 tamper/commalessmid.py
6082358eb328d1cdd4587e73c95bbefc tamper/commentbeforeparentheses.py 4951fec0a1af043e4b9c0728882d3452 tamper/commentbeforeparentheses.py
334e4a2485b3a1bbc1734823b93ea694 tamper/concat2concatws.py 376dc1203bfcd88380d902d36e7e0c5a tamper/concat2concatws.py
dcdc433fe946f1b9005bcd427a951dd6 tamper/equaltolike.py 6c882baf74213f401841968c04ce5e42 tamper/equaltolike.py
06df880df5d8749963f5562f60fd1637 tamper/escapequotes.py 22ab48f5b8ca449ac651637016be4369 tamper/escapequotes.py
4393cc5220d2e39c5c9c5a9af4e2635d tamper/greatest.py 4393cc5220d2e39c5c9c5a9af4e2635d tamper/greatest.py
25ec62158d3e289bda8a04c8b65686ba tamper/halfversionedmorekeywords.py 6124bc647bfa04f2b16ff8cad98382d4 tamper/halfversionedmorekeywords.py
9d8c350cbb90d4b21ec9c9db184a213a tamper/htmlencode.py ef0639557a79e57b06296c4bc223ebef tamper/htmlencode.py
3f79551baf811ff70b2ba8795a2064be tamper/ifnull2casewhenisnull.py 42f232d776065e325e862867c522c523 tamper/ifnull2casewhenisnull.py
e2c2b6a67546b36983a72f129a817ec0 tamper/ifnull2ifisnull.py 6e3ab1cf4ccf5524dcb60e390f920b60 tamper/ifnull2ifisnull.py
21665e68ef9f91b2395e81d2f341412d tamper/informationschemacomment.py 3ed2c6299c7c94776306535ff6090ab3 tamper/informationschemacomment.py
1e5532ede194ac9c083891c2f02bca93 tamper/__init__.py 1e5532ede194ac9c083891c2f02bca93 tamper/__init__.py
2dc49bcd6c55f4e2322b07fa92685356 tamper/least.py 2dc49bcd6c55f4e2322b07fa92685356 tamper/least.py
1834b5409c449d2ea1b70a5038fed9eb tamper/lowercase.py 40d1ea0796fd91cb3cdd602e36daed15 tamper/lowercase.py
de4c83d33968a0cbf00cdfd8d35deddc tamper/modsecurityversioned.py 1c4d622d1c2c77fc3db1f8b3849467ee tamper/modsecurityversioned.py
39981d5d6cb84aca950458739102bb07 tamper/modsecurityzeroversioned.py f177a624c2cd3431c433769c6eb995e7 tamper/modsecurityzeroversioned.py
5ee5147612ebe4769a67a8e2305d62f7 tamper/multiplespaces.py 91b63afdb96b1d51c12a14cbd425d310 tamper/multiplespaces.py
be757e4c9a6fb36af7b9a8c444fddb05 tamper/nonrecursivereplacement.py efd1917c6ccc632f044084a30e0e0f98 tamper/nonrecursivereplacement.py
e298e486c06bb39d81f10d61a5c4ceec tamper/overlongutf8more.py dcf3458f9010ca41bc4b56804f15792c tamper/overlongutf8more.py
b9f698556f8333d9fa6eadaab44a77ab tamper/overlongutf8.py a3a3cef042b864c4226b63f89548f939 tamper/overlongutf8.py
bc0363e4fc04240c9f7b81e4ecce0714 tamper/percentage.py 89f8753a0ef65d2bb860c8864e9e935a tamper/percentage.py
91272e566ceb4644254cd6abd613db21 tamper/plus2concat.py a47aafcbc1de2deb85160e29de46f748 tamper/plus2concat.py
265314f4b3b921f4c0d470ddaa6506e4 tamper/plus2fnconcat.py 759b86cf3bb1d7871dc6489538253f94 tamper/plus2fnconcat.py
e94a1c7e4dc7450ac224436269d823bb tamper/randomcase.py 078494e1217400b485ef653108d32699 tamper/randomcase.py
6368a971a80b1acbbbc6b76616bd96b9 tamper/randomcomments.py 28626e4b8c673228dcfe4f1627a9e08b tamper/randomcomments.py
48228322d40d97016b05e408c5234634 tamper/securesphere.py 938bfac6e55a8823e4a66cd29166d980 tamper/securesphere.py
cac8a56f8cc6c14524ee392daa5ae2fd tamper/space2comment.py cac8a56f8cc6c14524ee392daa5ae2fd tamper/space2comment.py
62d4d07b640d9d54d26ba33a77de9474 tamper/space2dash.py 4e6da2aca962b6110652e5f83dce5cd7 tamper/space2dash.py
ab91c20f71973b1a9a5fecfb9f2a1d1f tamper/space2hash.py 7cdbae483262f66ef5d77521c59d9621 tamper/space2hash.py
18f827afce8322adfa0c6dfbb4a59379 tamper/space2morecomment.py f3fed47a4fccb2b482f1f01559b8f55a tamper/space2morecomment.py
59e61a9dd1f1e6b79fde026ed771cac4 tamper/space2morehash.py fc3d9896cac8f4a97efd39673fadca7b tamper/space2morehash.py
ad45e799126d2d563b3958f714d2e7c6 tamper/space2mssqlblank.py b55ed15af74ffefc4dc303646c7c6482 tamper/space2mssqlblank.py
74334d72bffb99b0ac092f87f4da2675 tamper/space2mssqlhash.py 64e3d97e22f7e0870e88a87fd2f64243 tamper/space2mssqlhash.py
fd1bff6caefe5007444f7a0fabbc8ce9 tamper/space2mysqlblank.py 3ef95855a38bbc0f031ae3a992dcbf52 tamper/space2mysqlblank.py
48a1f013657186e336d249adefbdbc7b tamper/space2mysqldash.py 8a4737f853354ac9c3788278589a772a tamper/space2mysqldash.py
36958b2a5f5915de8b7cc157a64b267a tamper/space2plus.py 72a547bc3bf32dba0d1c3093988df8af tamper/space2plus.py
6ce135f89259c379d84c85e538300091 tamper/space2randomblank.py a74cd6375c5d5d253e2e7014b00ecd33 tamper/space2randomblank.py
95c91853034d9e276a6570e4d01b5f74 tamper/sp_password.py 93fc10b57586936cef05e88227c84ad0 tamper/sp_password.py
041cb567dff6bb6e7389e12ab3fb84c6 tamper/symboliclogical.py 041cb567dff6bb6e7389e12ab3fb84c6 tamper/symboliclogical.py
6459c62914ae643799667de8bd283c97 tamper/unionalltounion.py 6679c4ffb7322315a738dcfa68c6fb7c tamper/unionalltounion.py
3b8182b8caef857b9af397e47d0c9938 tamper/unmagicquotes.py 51d20b5cb5a50fc2e44d39087f865d23 tamper/unmagicquotes.py
371afb396f0bb18d97147c5db83354f4 tamper/uppercase.py cc212839f55692d422beef3a8e22a8d4 tamper/uppercase.py
557ce5bf5ae9b7ab26f2c6b57312f41a tamper/varnish.py f2b9eac52d346315f5705f71beeda791 tamper/varnish.py
929a2586dbb7b758a454eb09e13e5a73 tamper/versionedkeywords.py 0e40966a51d1eb5d42a2159d2015a8a4 tamper/versionedkeywords.py
3aff4d344ebd4f38e033e73b63f84447 tamper/versionedmorekeywords.py 0fba004bf1be6edbefbda89f23f4e518 tamper/versionedmorekeywords.py
ed1acafbac707bfa71c72f76b81c1bdd tamper/xforwardedfor.py de532c4e3160039335010c499129d54f tamper/xforwardedfor.py
368165b45dadcdff4422bc010700832a thirdparty/ansistrm/ansistrm.py b25b47ddeeb62e5857fd5ad17fd454b5 thirdparty/ansistrm/ansistrm.py
d41d8cd98f00b204e9800998ecf8427e thirdparty/ansistrm/__init__.py d41d8cd98f00b204e9800998ecf8427e thirdparty/ansistrm/__init__.py
8e775c25bc9e84891ad6fcb4f0005c23 thirdparty/beautifulsoup/beautifulsoup.py 8e775c25bc9e84891ad6fcb4f0005c23 thirdparty/beautifulsoup/beautifulsoup.py
cb2e1fe7c404dff41a2ae9132828f532 thirdparty/beautifulsoup/__init__.py cb2e1fe7c404dff41a2ae9132828f532 thirdparty/beautifulsoup/__init__.py
@@ -402,11 +402,12 @@ ef722d062564def381b1f96f5faadee3 waf/baidu.py
41e399dbfe7b904d5aacfb37d85e1fbf waf/blockdos.py 41e399dbfe7b904d5aacfb37d85e1fbf waf/blockdos.py
2f3bbf43be94d4e9ffe9f80e8483d62f waf/ciscoacexml.py 2f3bbf43be94d4e9ffe9f80e8483d62f waf/ciscoacexml.py
ba84f296cb52f5e78a0670b98d7763fa waf/cloudbric.py ba84f296cb52f5e78a0670b98d7763fa waf/cloudbric.py
21b8203fdaaaac3cb7c84fa4dc0627f6 waf/cloudflare.py feda0f2a5172325f39e8e3e38c45f73d waf/cloudflare.py
b16b1c15532103346d5e2f5b8bd1ed36 waf/cloudfront.py b16b1c15532103346d5e2f5b8bd1ed36 waf/cloudfront.py
ac96f34c254951d301973617064eb1b5 waf/comodo.py ac96f34c254951d301973617064eb1b5 waf/comodo.py
56d58c982c2cf775e0f8dc6767f336fd waf/datapower.py 56d58c982c2cf775e0f8dc6767f336fd waf/datapower.py
1538b661e35843074f4599be93b3fae9 waf/denyall.py 1538b661e35843074f4599be93b3fae9 waf/denyall.py
0182d23b34cf903537f77f4ec4b144bf waf/distil.py
aade02eb8f6a4a214a53db0fd0f2aae6 waf/dosarrest.py aade02eb8f6a4a214a53db0fd0f2aae6 waf/dosarrest.py
357cbc0a17a44e4f64062b799c718e0b waf/dotdefender.py 357cbc0a17a44e4f64062b799c718e0b waf/dotdefender.py
7ec3f2a90914b501100685aa66aadf02 waf/edgecast.py 7ec3f2a90914b501100685aa66aadf02 waf/edgecast.py
@@ -414,7 +415,7 @@ aade02eb8f6a4a214a53db0fd0f2aae6 waf/dosarrest.py
a2ce6cde682f78e1fd561dc40611877e waf/fortiweb.py a2ce6cde682f78e1fd561dc40611877e waf/fortiweb.py
eb56ac34775cc3c5f721ec967d04b283 waf/generic.py eb56ac34775cc3c5f721ec967d04b283 waf/generic.py
1c70655551b8296ceeb19292a342e620 waf/hyperguard.py 1c70655551b8296ceeb19292a342e620 waf/hyperguard.py
525483047474e6f15d9898b525bdafd3 waf/incapsula.py 2a52c09e4ce1f2a5976ce53b415ef496 waf/incapsula.py
1e5532ede194ac9c083891c2f02bca93 waf/__init__.py 1e5532ede194ac9c083891c2f02bca93 waf/__init__.py
30ae98958fb35061d9a4145cc74c0489 waf/isaserver.py 30ae98958fb35061d9a4145cc74c0489 waf/isaserver.py
5a5c9452b9779bf39c208ebe26c98fdb waf/jiasule.py 5a5c9452b9779bf39c208ebe26c98fdb waf/jiasule.py
@@ -430,6 +431,7 @@ ad7fe23004f8e0d02534c7baa877add3 waf/paloalto.py
856e34d47fedfe96039a6a7807f9605a waf/profense.py 856e34d47fedfe96039a6a7807f9605a waf/profense.py
166eb53544536e3e86223d513b8b688d waf/proventia.py 166eb53544536e3e86223d513b8b688d waf/proventia.py
78a40eca7ddd14c4eaf911de7748b487 waf/radware.py 78a40eca7ddd14c4eaf911de7748b487 waf/radware.py
67864bf5e5a38cb27b5daf3581282f9e waf/reblaze.py
f5d53758d2008195609557112ce8e895 waf/requestvalidationmode.py f5d53758d2008195609557112ce8e895 waf/requestvalidationmode.py
acb82b21f4032ceb510a58142add02ab waf/safe3.py acb82b21f4032ceb510a58142add02ab waf/safe3.py
67cdf508e7b1f69ddf622a87e0e5e4e8 waf/safedog.py 67cdf508e7b1f69ddf622a87e0e5e4e8 waf/safedog.py
@@ -439,7 +441,7 @@ d1b67820442199181815ec3fce27e582 waf/secureiis.py
b088cf83c1a681d143e7eaea43f52b80 waf/sonicwall.py b088cf83c1a681d143e7eaea43f52b80 waf/sonicwall.py
4c412bc70007e6108d109e2911f2cefe waf/sophos.py 4c412bc70007e6108d109e2911f2cefe waf/sophos.py
0e244e097a648158948dc8bb2351c781 waf/stingray.py 0e244e097a648158948dc8bb2351c781 waf/stingray.py
d5a5cef222f0e27f47bec3c4228e255e waf/sucuri.py 9da254a2dfe22539c90bc1db0643489e waf/sucuri.py
46224e3fa4b819da227c50fd45155823 waf/tencent.py 46224e3fa4b819da227c50fd45155823 waf/tencent.py
dffa9cebad777308714aaf83b71635b4 waf/teros.py dffa9cebad777308714aaf83b71635b4 waf/teros.py
b37210459a13de40bf07722c4d032c33 waf/trafficshield.py b37210459a13de40bf07722c4d032c33 waf/trafficshield.py
@@ -465,7 +467,7 @@ d48c971769c6131e35bd52d2315a8d58 xml/banner/servlet-engine.xml
d989813ee377252bca2103cea524c06b xml/banner/sharepoint.xml d989813ee377252bca2103cea524c06b xml/banner/sharepoint.xml
350605448f049cd982554123a75f11e1 xml/banner/x-aspnet-version.xml 350605448f049cd982554123a75f11e1 xml/banner/x-aspnet-version.xml
817078783e1edaa492773d3b34d8eef0 xml/banner/x-powered-by.xml 817078783e1edaa492773d3b34d8eef0 xml/banner/x-powered-by.xml
fb93505ef0ab3b4a20900f3e5625260d xml/boundaries.xml 201b8bb7888f500294a9831bb47ce7a7 xml/boundaries.xml
0d0d4bd0e06c99dd8eb4f92acc25caf3 xml/errors.xml 0d0d4bd0e06c99dd8eb4f92acc25caf3 xml/errors.xml
a279656ea3fcb85c727249b02f828383 xml/livetests.xml a279656ea3fcb85c727249b02f828383 xml/livetests.xml
3318571fac8df058f19ea85780606643 xml/payloads/boolean_blind.xml 3318571fac8df058f19ea85780606643 xml/payloads/boolean_blind.xml

View File

@@ -17,7 +17,7 @@ def detect(get_page):
for vector in WAF_ATTACK_VECTORS: for vector in WAF_ATTACK_VECTORS:
page, headers, code = get_page(get=vector) page, headers, code = get_page(get=vector)
retval = re.search(r"cloudflare-nginx", headers.get(HTTP_HEADER.SERVER, ""), re.I) is not None retval = re.search(r"cloudflare", headers.get(HTTP_HEADER.SERVER, ""), re.I) is not None
if code >= 400: if code >= 400:
retval |= re.search(r"\A__cfduid=", headers.get(HTTP_HEADER.SET_COOKIE, ""), re.I) is not None retval |= re.search(r"\A__cfduid=", headers.get(HTTP_HEADER.SET_COOKIE, ""), re.I) is not None

24
waf/distil.py Normal file
View File

@@ -0,0 +1,24 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
import re
from lib.core.enums import HTTP_HEADER
from lib.core.settings import WAF_ATTACK_VECTORS
__product__ = "Distil Web Application Firewall Security (Distil Networks)"
def detect(get_page):
retval = False
for vector in WAF_ATTACK_VECTORS:
_, headers, _ = get_page(get=vector)
retval = headers.get("x-distil-cs") is not None
if retval:
break
return retval

View File

@@ -20,6 +20,7 @@ def detect(get_page):
retval = re.search(r"incap_ses|visid_incap", headers.get(HTTP_HEADER.SET_COOKIE, ""), re.I) is not None retval = re.search(r"incap_ses|visid_incap", headers.get(HTTP_HEADER.SET_COOKIE, ""), re.I) is not None
retval |= re.search(r"Incapsula", headers.get("X-CDN", ""), re.I) is not None retval |= re.search(r"Incapsula", headers.get("X-CDN", ""), re.I) is not None
retval |= "Incapsula incident ID" in (page or "") retval |= "Incapsula incident ID" in (page or "")
retval |= headers.get("X-Iinfo") is not None
if retval: if retval:
break break

25
waf/reblaze.py Normal file
View File

@@ -0,0 +1,25 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
import re
from lib.core.enums import HTTP_HEADER
from lib.core.settings import WAF_ATTACK_VECTORS
__product__ = "Reblaze Web Application Firewall (Reblaze)"
def detect(get_page):
retval = False
for vector in WAF_ATTACK_VECTORS:
_, headers, _ = get_page(get=vector)
retval = re.search(r"\Arbzid=", headers.get(HTTP_HEADER.SET_COOKIE, ""), re.I) is not None
retval |= re.search(r"Reblaze Secure Web Gateway", headers.get(HTTP_HEADER.SERVER, ""), re.I) is not None
if retval:
break
return retval

View File

@@ -21,6 +21,8 @@ def detect(get_page):
retval |= "Access Denied - Sucuri Website Firewall" in (page or "") retval |= "Access Denied - Sucuri Website Firewall" in (page or "")
retval |= "Sucuri WebSite Firewall - CloudProxy - Access Denied" in (page or "") retval |= "Sucuri WebSite Firewall - CloudProxy - Access Denied" in (page or "")
retval |= re.search(r"Questions\?.+cloudproxy@sucuri\.net", (page or "")) is not None retval |= re.search(r"Questions\?.+cloudproxy@sucuri\.net", (page or "")) is not None
retval |= headers.get("X-Sucuri-ID") is not None
retval |= headers.get("X-Sucuri-Cache") is not None
if retval: if retval:
break break

View File

@@ -293,78 +293,6 @@ Formats:
<suffix> AND "[RANDSTR]" LIKE "[RANDSTR]</suffix> <suffix> AND "[RANDSTR]" LIKE "[RANDSTR]</suffix>
</boundary> </boundary>
<boundary>
<level>2</level>
<clause>1</clause>
<where>1,2</where>
<ptype>2</ptype>
<prefix>%')</prefix>
<suffix> AND ('%'='</suffix>
</boundary>
<boundary>
<level>3</level>
<clause>1</clause>
<where>1,2</where>
<ptype>2</ptype>
<prefix>%'))</prefix>
<suffix> AND (('%'='</suffix>
</boundary>
<boundary>
<level>4</level>
<clause>1</clause>
<where>1,2</where>
<ptype>2</ptype>
<prefix>%')))</prefix>
<suffix> AND ((('%'='</suffix>
</boundary>
<boundary>
<level>1</level>
<clause>1</clause>
<where>1,2</where>
<ptype>2</ptype>
<prefix>%'</prefix>
<suffix> AND '%'='</suffix>
</boundary>
<boundary>
<level>4</level>
<clause>1</clause>
<where>1,2</where>
<ptype>2</ptype>
<prefix>%")</prefix>
<suffix> AND ("%"="</suffix>
</boundary>
<boundary>
<level>5</level>
<clause>1</clause>
<where>1,2</where>
<ptype>2</ptype>
<prefix>%"))</prefix>
<suffix> AND (("%"="</suffix>
</boundary>
<boundary>
<level>5</level>
<clause>1</clause>
<where>1,2</where>
<ptype>2</ptype>
<prefix>%")))</prefix>
<suffix> AND ((("%"="</suffix>
</boundary>
<boundary>
<level>3</level>
<clause>1</clause>
<where>1,2</where>
<ptype>2</ptype>
<prefix>%"</prefix>
<suffix> AND "%"="</suffix>
</boundary>
<boundary> <boundary>
<level>1</level> <level>1</level>
<clause>1</clause> <clause>1</clause>