Minor bug fix to consider --start and --stop also in partial UNION query SQL injection

This commit is contained in:
Bernardo Damele 2010-04-30 15:48:40 +00:00
parent 4d46f997a7
commit 90d9900371
3 changed files with 21 additions and 23 deletions

View File

@ -314,7 +314,7 @@ def __goInferenceProxy(expression, fromUser=False, expected=None, batch=False, r
return returnValue return returnValue
def __goInband(expression, expected=None, sort=True, resumeValue=True, unpack=True): def __goInband(expression, expected=None, sort=True, resumeValue=True, unpack=True, dump=False):
""" """
Retrieve the output of a SQL query taking advantage of an inband SQL Retrieve the output of a SQL query taking advantage of an inband SQL
injection vulnerability on the affected parameter. injection vulnerability on the affected parameter.
@ -336,14 +336,14 @@ def __goInband(expression, expected=None, sort=True, resumeValue=True, unpack=Tr
partial = True partial = True
if not output: if not output:
output = unionUse(expression, resetCounter=True, unpack=unpack) output = unionUse(expression, resetCounter=True, unpack=unpack, dump=dump)
if output: if output:
data = parseUnionPage(output, expression, partial, condition, sort) data = parseUnionPage(output, expression, partial, condition, sort)
return data return data
def getValue(expression, blind=True, inband=True, fromUser=False, expected=None, batch=False, unpack=True, sort=True, resumeValue=True, charsetType=None, firstChar=None, lastChar=None): def getValue(expression, blind=True, inband=True, fromUser=False, expected=None, batch=False, unpack=True, sort=True, resumeValue=True, charsetType=None, firstChar=None, lastChar=None, dump=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
@ -361,7 +361,7 @@ def getValue(expression, blind=True, inband=True, fromUser=False, expected=None,
expression = expression.replace("DISTINCT ", "") expression = expression.replace("DISTINCT ", "")
if inband and kb.unionPosition: if inband and kb.unionPosition:
value = __goInband(expression, expected, sort, resumeValue, unpack) value = __goInband(expression, expected, sort, resumeValue, unpack, dump)
if not value: if not value:
warnMsg = "for some reasons it was not possible to retrieve " warnMsg = "for some reasons it was not possible to retrieve "

View File

@ -39,7 +39,7 @@ from lib.utils.resume import resume
reqCount = 0 reqCount = 0
def unionUse(expression, direct=False, unescape=True, resetCounter=False, nullChar="NULL", unpack=True): def unionUse(expression, direct=False, unescape=True, resetCounter=False, nullChar="NULL", unpack=True, dump=False):
""" """
This function tests for an inband SQL injection on the target This function tests for an inband SQL injection on the target
url then call its subsidiary function to effectively perform an url then call its subsidiary function to effectively perform an
@ -73,13 +73,6 @@ def unionUse(expression, direct=False, unescape=True, resetCounter=False, nullCh
if ( kb.unionNegative or kb.unionFalseCond ) and not direct: if ( kb.unionNegative or kb.unionFalseCond ) and not direct:
_, _, _, _, _, expressionFieldsList, expressionFields = agent.getFields(origExpr) _, _, _, _, _, expressionFieldsList, expressionFields = agent.getFields(origExpr)
if len(expressionFieldsList) > 1:
infoMsg = "the SQL query provided has more than a field. "
infoMsg += "sqlmap will now unpack it into distinct queries "
infoMsg += "to be able to retrieve the output even if we "
infoMsg += "are in front of a partial inband sql injection"
logger.info(infoMsg)
# We have to check if the SQL query might return multiple entries # We have to check if the SQL query might return multiple entries
# and in such case forge the SQL limiting the query output one # and in such case forge the SQL limiting the query output one
# entry per time # entry per time
@ -130,6 +123,11 @@ def unionUse(expression, direct=False, unescape=True, resetCounter=False, nullCh
elif kb.dbms == "Microsoft SQL Server": elif kb.dbms == "Microsoft SQL Server":
stopLimit += startLimit stopLimit += startLimit
elif dump:
if conf.limitStart:
startLimit = conf.limitStart
if conf.limitStop:
stopLimit = conf.limitStop
if not stopLimit or stopLimit <= 1: if not stopLimit or stopLimit <= 1:
if kb.dbms == "Oracle" and expression.endswith("FROM DUAL"): if kb.dbms == "Oracle" and expression.endswith("FROM DUAL"):
@ -194,10 +192,14 @@ def unionUse(expression, direct=False, unescape=True, resetCounter=False, nullCh
field = None field = None
limitedExpr = agent.limitQuery(num, expression, field) limitedExpr = agent.limitQuery(num, expression, field)
output = unionUse(limitedExpr, direct=True, unescape=False) output = resume(limitedExpr, None)
if not output:
output = unionUse(limitedExpr, direct=True, unescape=False)
if output: if output:
value += output value += output
parseUnionPage(output, limitedExpr)
return value return value

View File

@ -1331,7 +1331,7 @@ class Enumeration:
query = rootQuery["inband"]["query"] % (colString, conf.tbl) query = rootQuery["inband"]["query"] % (colString, conf.tbl)
else: else:
query = rootQuery["inband"]["query"] % (colString, conf.db, conf.tbl) query = rootQuery["inband"]["query"] % (colString, conf.db, conf.tbl)
entries = inject.getValue(query, blind=False) entries = inject.getValue(query, blind=False, dump=True)
if entries: if entries:
if isinstance(entries, str): if isinstance(entries, str):
@ -1432,19 +1432,15 @@ class Enumeration:
else: else:
length = lengths[column] length = lengths[column]
kb.data.dumpedTable[column] = { kb.data.dumpedTable[column] = { "length": length,
"length": length, "values": columnEntries }
"values": columnEntries,
}
entriesCount = len(columnEntries) entriesCount = len(columnEntries)
if kb.data.dumpedTable: if kb.data.dumpedTable:
kb.data.dumpedTable["__infos__"] = { kb.data.dumpedTable["__infos__"] = { "count": entriesCount,
"count": entriesCount, "table": conf.tbl,
"table": conf.tbl, "db": conf.db }
"db": conf.db
}
else: else:
warnMsg = "unable to retrieve the entries of " warnMsg = "unable to retrieve the entries of "
if conf.col: if conf.col: