This commit is contained in:
Miroslav Stampar 2010-12-08 22:38:26 +00:00
parent d6077273e0
commit 54f6673609
2 changed files with 49 additions and 44 deletions

View File

@ -367,7 +367,7 @@ def __goInband(expression, expected=None, sort=True, resumeValue=True, unpack=Tr
return data return data
def getValue(expression, blind=True, inband=True, error=True, time=True, fromUser=False, expected=None, batch=False, unpack=True, sort=True, resumeValue=True, charsetType=None, firstChar=None, lastChar=None, dump=False, suppressOutput=False): def getValue(expression, blind=True, inband=True, error=True, time=True, fromUser=False, expected=None, batch=False, unpack=True, sort=True, resumeValue=True, charsetType=None, firstChar=None, lastChar=None, dump=False, suppressOutput=False, expectingNone=False):
""" """
Called each time sqlmap inject a SQL query on the SQL injection Called each time sqlmap inject a SQL query on the SQL injection
affected parameter. It can call a function to retrieve the output affected parameter. It can call a function to retrieve the output
@ -379,54 +379,59 @@ def getValue(expression, blind=True, inband=True, error=True, time=True, fromUse
pushValue(conf.verbose) pushValue(conf.verbose)
conf.verbose = 0 conf.verbose = 0
if conf.direct: try:
value = direct(expression) if conf.direct:
elif kb.booleanTest is not None or kb.errorTest is not None or kb.unionTest is not None or kb.timeTest is not None: value = direct(expression)
expression = cleanQuery(expression) elif kb.booleanTest is not None or kb.errorTest is not None or kb.unionTest is not None or kb.timeTest is not None:
expression = expandAsteriskForColumns(expression) expression = cleanQuery(expression)
value = None expression = expandAsteriskForColumns(expression)
expression = expression.replace("DISTINCT ", "") value = None
found = False
expression = expression.replace("DISTINCT ", "")
if inband and kb.unionTest is not None: if inband and kb.unionTest is not None:
kb.technique = PAYLOAD.TECHNIQUE.UNION kb.technique = PAYLOAD.TECHNIQUE.UNION
value = __goInband(expression, expected, sort, resumeValue, unpack, dump) value = __goInband(expression, expected, sort, resumeValue, unpack, dump)
found = value or (value is None and expectingNone)
if not value: if not found:
warnMsg = "for some reason(s) it was not possible to retrieve " warnMsg = "for some reason(s) it was not possible to retrieve "
warnMsg += "the query output through inband SQL injection " warnMsg += "the query output through inband SQL injection "
warnMsg += "technique, sqlmap is going blind" warnMsg += "technique, sqlmap is going blind"
logger.warn(warnMsg) logger.warn(warnMsg)
oldParamNegative = kb.unionNegative oldParamNegative = kb.unionNegative
kb.unionNegative = False kb.unionNegative = False
if error and kb.errorTest and not value: if error and kb.errorTest and not found:
kb.technique = PAYLOAD.TECHNIQUE.ERROR kb.technique = PAYLOAD.TECHNIQUE.ERROR
value = __goError(expression, resumeValue) value = __goError(expression, resumeValue)
found = value or (value is None and expectingNone)
if blind and kb.booleanTest and not value: if blind and kb.booleanTest and not found:
kb.technique = PAYLOAD.TECHNIQUE.BOOLEAN kb.technique = PAYLOAD.TECHNIQUE.BOOLEAN
value = __goInferenceProxy(expression, fromUser, expected, batch, resumeValue, unpack, charsetType, firstChar, lastChar) value = __goInferenceProxy(expression, fromUser, expected, batch, resumeValue, unpack, charsetType, firstChar, lastChar)
found = value or (value is None and expectingNone)
if time and kb.timeTest and not value: if time and kb.timeTest and not found:
kb.technique = PAYLOAD.TECHNIQUE.TIME kb.technique = PAYLOAD.TECHNIQUE.TIME
while len(kb.responseTimes) < MIN_TIME_RESPONSES: while len(kb.responseTimes) < MIN_TIME_RESPONSES:
_ = Request.queryPage(content=True) _ = Request.queryPage(content=True)
value = __goInferenceProxy(expression, fromUser, expected, batch, resumeValue, unpack, charsetType, firstChar, lastChar) value = __goInferenceProxy(expression, fromUser, expected, batch, resumeValue, unpack, charsetType, firstChar, lastChar)
kb.unionNegative = oldParamNegative kb.unionNegative = oldParamNegative
if value and isinstance(value, basestring): if value and isinstance(value, basestring):
value = value.strip() value = value.strip()
else: else:
errMsg = "none of the injection types identified can be " errMsg = "none of the injection types identified can be "
errMsg += "leveraged to retrieve queries output" errMsg += "leveraged to retrieve queries output"
raise sqlmapNotVulnerableException, errMsg raise sqlmapNotVulnerableException, errMsg
finally:
if suppressOutput: if suppressOutput:
conf.verbose = popValue() conf.verbose = popValue()
return value return value
@ -449,5 +454,5 @@ def goStacked(expression, silent=False):
return payload, page return payload, page
def checkBooleanExpression(expression): def checkBooleanExpression(expression, expectingNone=False):
return getValue(agent.forgeCaseStatement(expression), expected="int", charsetType=1) == "1" return getValue(agent.forgeCaseStatement(expression), expected="int", charsetType=1, expectingNone=expectingNone) == "1"

View File

@ -37,7 +37,7 @@ def tableExists(tableFile):
for table in tables: for table in tables:
if conf.db and '(*)' not in conf.db: if conf.db and '(*)' not in conf.db:
table = "%s.%s" % (conf.db, table) table = "%s.%s" % (conf.db, table)
result = inject.checkBooleanExpression("%s" % safeStringFormat("EXISTS(SELECT %d FROM %s)", (randomInt(1), table))) result = inject.checkBooleanExpression("%s" % safeStringFormat("EXISTS(SELECT %d FROM %s)", (randomInt(1), table)), expectingNone=True)
if result: if result:
clearConsoleLine(True) clearConsoleLine(True)
@ -86,7 +86,7 @@ def columnExists(columnFile):
length = len(columns) length = len(columns)
for column in columns: for column in columns:
result = inject.checkBooleanExpression("%s" % safeStringFormat("EXISTS(SELECT %s FROM %s)", (column, table))) result = inject.checkBooleanExpression("%s" % safeStringFormat("EXISTS(SELECT %s FROM %s)", (column, table)), expectingNone=True)
if result: if result:
clearConsoleLine(True) clearConsoleLine(True)
@ -109,7 +109,7 @@ def columnExists(columnFile):
columns = {} columns = {}
for column in retVal: for column in retVal:
result = inject.checkBooleanExpression("%s" % safeStringFormat("EXISTS(SELECT %s FROM %s WHERE %s>0)", (column, table, column))) result = inject.checkBooleanExpression("%s" % safeStringFormat("EXISTS(SELECT %s FROM %s WHERE %s>0)", (column, table, column)), expectingNone=True)
if result: if result:
columns[column] = 'numeric' columns[column] = 'numeric'