Fixed previous bug in getErrorParsedDBMSes() call in detection phase.

Added minor support to escape quotes in UNION payloads during detection phase.
This commit is contained in:
Bernardo Damele 2011-01-11 23:47:32 +00:00
parent aa49aa579f
commit 5c7c3c76c3
5 changed files with 27 additions and 25 deletions

View File

@ -149,14 +149,15 @@ def checkSqlInjection(place, parameter, value):
continue
# NOTE: Leave this commented for the time being
#if getErrorParsedDBMSes() and dbms not in getErrorParsedDBMSes() and kb.skipTests is None:
# msg = "parsed error message(s) showed that the "
# msg += "back-end DBMS could be '%s'. " % getErrorParsedDBMSesFormatted()
# msg += "Do you want to skip test payloads specific for other DBMSes? [Y/n]"
# kb.skipTests = conf.realTest or readInput(msg, default="Y") not in ("n", "N")
if getErrorParsedDBMSes() and dbms not in getErrorParsedDBMSes() and kb.skipOthersDbms is None:
msg = "parsed error message(s) showed that the "
msg += "back-end DBMS could be '%s'. " % getErrorParsedDBMSesFormatted()
msg += "Do you want to skip test payloads specific for other DBMSes? [Y/n]"
if kb.skipTests:
if conf.realTest or readInput(msg, default="Y") in ("y", "Y"):
kb.skipOthersDbms = getErrorParsedDBMSes()
if kb.skipOthersDbms and dbms not in kb.skipOthersDbms:
debugMsg = "skipping test '%s' because " % title
debugMsg += "the parsed error message(s) showed "
debugMsg += "that the back-end DBMS could be "
@ -378,7 +379,8 @@ def checkSqlInjection(place, parameter, value):
elif method == PAYLOAD.METHOD.UNION:
configUnion(test.request.char, test.request.columns)
reqPayload, unionVector = unionTest(comment, place, parameter, value, prefix, suffix)
dbmsToUnescape = dbms if dbms is not None else injection.dbms
reqPayload, unionVector = unionTest(comment, place, parameter, value, prefix, suffix, dbmsToUnescape)
if isinstance(reqPayload, basestring):
infoMsg = "%s parameter '%s' is '%s' injectable" % (place, parameter, title)

View File

@ -1159,7 +1159,7 @@ def __setKnowledgeBaseAttributes(flushAll=True):
kb.responseTimes = []
kb.resumedQueries = {}
kb.retriesCount = 0
kb.skipTests = None
kb.skipOthersDbms = None
kb.suppressSession = False
kb.technique = None
kb.testMode = False

View File

@ -11,9 +11,13 @@ from lib.core.data import kb
from lib.core.datatype import advancedDict
class Unescaper(advancedDict):
def unescape(self, expression, quote=True):
def unescape(self, expression, quote=True, dbms=None):
if hasattr(kb, "dbms") and kb.dbms is not None:
return self[kb.dbms if kb.dbms else kb.misc.testedDbms](expression, quote=quote)
return self[kb.dbms](expression, quote=quote)
elif hasattr(kb.misc, "testedDbms") and kb.misc.testedDbms is not None:
return self[kb.misc.testedDbms](expression, quote=quote)
if dbms is not None:
return self[dbms](expression, quote=quote)
elif hasattr(kb.misc, "testedDbms") and kb.misc.testedDbms is not None:
return self[kb.misc.testedDbms](expression, quote=quote)
else:

View File

@ -26,7 +26,7 @@ from lib.core.unescaper import unescaper
from lib.parse.html import htmlParser
from lib.request.connect import Connect as Request
def __unionPosition(comment, place, parameter, value, prefix, suffix, count, where=1):
def __unionPosition(comment, place, parameter, value, prefix, suffix, dbms, count, where=1):
validPayload = None
unionVector = None
@ -40,7 +40,7 @@ def __unionPosition(comment, place, parameter, value, prefix, suffix, count, whe
# Prepare expression with delimiters
randQuery = randomStr()
randQueryProcessed = agent.concatQuery("\'%s\'" % randQuery)
randQueryUnescaped = unescaper.unescape(randQueryProcessed)
randQueryUnescaped = unescaper.unescape(randQueryProcessed, dbms=dbms)
# Forge the inband SQL injection request
query = agent.forgeInbandQuery(randQueryUnescaped, exprPosition, count=count, comment=comment, prefix=prefix, suffix=suffix)
@ -58,7 +58,7 @@ def __unionPosition(comment, place, parameter, value, prefix, suffix, count, whe
# Prepare expression with delimiters
randQuery2 = randomStr()
randQueryProcessed2 = agent.concatQuery("\'%s\'" % randQuery2)
randQueryUnescaped2 = unescaper.unescape(randQueryProcessed2)
randQueryUnescaped2 = unescaper.unescape(randQueryProcessed2, dbms=dbms)
# Confirm that it is a full inband SQL injection
query = agent.forgeInbandQuery(randQueryUnescaped, exprPosition, count=count, comment=comment, prefix=prefix, suffix=suffix, multipleUnions=randQueryUnescaped2)
@ -74,19 +74,19 @@ def __unionPosition(comment, place, parameter, value, prefix, suffix, count, whe
return validPayload, unionVector
def __unionConfirm(comment, place, parameter, value, prefix, suffix, count):
def __unionConfirm(comment, place, parameter, value, prefix, suffix, dbms, count):
validPayload = None
unionVector = None
# Confirm the inband SQL injection and get the exact column
# position which can be used to extract data
if not isinstance(kb.unionPosition, int):
validPayload, unionVector = __unionPosition(comment, place, parameter, value, prefix, suffix, count)
validPayload, unionVector = __unionPosition(comment, place, parameter, value, prefix, suffix, dbms, count)
# Assure that the above function found the exploitable full inband
# SQL injection position
if not isinstance(kb.unionPosition, int):
validPayload, unionVector = __unionPosition(comment, place, parameter, value, prefix, suffix, count, where=2)
validPayload, unionVector = __unionPosition(comment, place, parameter, value, prefix, suffix, dbms, count, where=2)
# Assure that the above function found the exploitable partial
# (single entry) inband SQL injection position with negative
@ -98,7 +98,7 @@ def __unionConfirm(comment, place, parameter, value, prefix, suffix, count):
return validPayload, unionVector
def __unionTestByCharBruteforce(comment, place, parameter, value, prefix, suffix):
def __unionTestByCharBruteforce(comment, place, parameter, value, prefix, suffix, dbms):
"""
This method tests if the target url is affected by an inband
SQL injection vulnerability. The test is done up to 50 columns
@ -123,7 +123,7 @@ def __unionTestByCharBruteforce(comment, place, parameter, value, prefix, suffix
debugMsg = "testing number of columns: %s" % status
logger.debug(debugMsg)
validPayload, unionVector = __unionConfirm(comment, place, parameter, value, prefix, suffix, count)
validPayload, unionVector = __unionConfirm(comment, place, parameter, value, prefix, suffix, dbms, count)
if validPayload:
setUnion(count=count)
@ -133,7 +133,7 @@ def __unionTestByCharBruteforce(comment, place, parameter, value, prefix, suffix
return validPayload, unionVector
def unionTest(comment, place, parameter, value, prefix, suffix):
def unionTest(comment, place, parameter, value, prefix, suffix, dbms):
"""
This method tests if the target url is affected by an inband
SQL injection vulnerability. The test is done up to 3*50 times
@ -144,7 +144,7 @@ def unionTest(comment, place, parameter, value, prefix, suffix):
oldTechnique = kb.technique
kb.technique = PAYLOAD.TECHNIQUE.UNION
validPayload, unionVector = __unionTestByCharBruteforce(comment, place, parameter, value, prefix, suffix)
validPayload, unionVector = __unionTestByCharBruteforce(comment, place, parameter, value, prefix, suffix, dbms)
if validPayload:
validPayload = agent.removePayloadDelimiters(validPayload, False)

View File

@ -25,7 +25,6 @@ from lib.core.enums import DBMS
from lib.core.enums import PAYLOAD
from lib.core.unescaper import unescaper
from lib.request.connect import Connect as Request
from lib.techniques.inband.union.test import unionTest
from lib.utils.resume import resume
reqCount = 0
@ -52,9 +51,6 @@ def unionUse(expression, direct=False, unescape=True, resetCounter=False, nullCh
if resetCounter:
reqCount = 0
if not kb.unionTest:
unionTest()
if not kb.unionCount:
return