mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2024-11-28 20:43:49 +03:00
Major bug fix so that when the expected value of a query (count variable)
is an integer and for some reason the resumed value from session file is a string or a binary file, the query is executed again and and its new output saved to the session file
This commit is contained in:
parent
03b90e0a3f
commit
206191d164
|
@ -71,7 +71,7 @@ def __goInference(payload, expression):
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
def __goInferenceFields(expression, expressionFields, expressionFieldsList, payload):
|
def __goInferenceFields(expression, expressionFields, expressionFieldsList, payload, expected=None):
|
||||||
outputs = []
|
outputs = []
|
||||||
|
|
||||||
for field in expressionFieldsList:
|
for field in expressionFieldsList:
|
||||||
|
@ -80,7 +80,12 @@ def __goInferenceFields(expression, expressionFields, expressionFieldsList, payl
|
||||||
expressionReplaced = expression.replace(expressionFields, field, 1)
|
expressionReplaced = expression.replace(expressionFields, field, 1)
|
||||||
output = resume(expressionReplaced, payload)
|
output = resume(expressionReplaced, payload)
|
||||||
|
|
||||||
if not output:
|
if not output or ( expected == "int" and not output.isdigit() ):
|
||||||
|
if output:
|
||||||
|
warnMsg = "expected value type %s, resumed '%s', " % (expected, output)
|
||||||
|
warnMsg += "sqlmap is going to retrieve the value again"
|
||||||
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
output = __goInference(payload, expressionReplaced)
|
output = __goInference(payload, expressionReplaced)
|
||||||
|
|
||||||
outputs.append(output)
|
outputs.append(output)
|
||||||
|
@ -88,7 +93,7 @@ def __goInferenceFields(expression, expressionFields, expressionFieldsList, payl
|
||||||
return outputs
|
return outputs
|
||||||
|
|
||||||
|
|
||||||
def __goInferenceProxy(expression, fromUser=False):
|
def __goInferenceProxy(expression, fromUser=False, expected=None):
|
||||||
"""
|
"""
|
||||||
Retrieve the output of a SQL query characted by character taking
|
Retrieve the output of a SQL query characted by character taking
|
||||||
advantage of an blind SQL injection vulnerability on the affected
|
advantage of an blind SQL injection vulnerability on the affected
|
||||||
|
@ -108,7 +113,7 @@ def __goInferenceProxy(expression, fromUser=False):
|
||||||
|
|
||||||
output = resume(expression, payload)
|
output = resume(expression, payload)
|
||||||
|
|
||||||
if output:
|
if output and ( expected == None or ( expected == "int" and output.isdigit() ) ):
|
||||||
return output
|
return output
|
||||||
|
|
||||||
if kb.dbmsDetected:
|
if kb.dbmsDetected:
|
||||||
|
@ -179,7 +184,7 @@ def __goInferenceProxy(expression, fromUser=False):
|
||||||
count = resume(countedExpression, payload)
|
count = resume(countedExpression, payload)
|
||||||
|
|
||||||
if not stopLimit:
|
if not stopLimit:
|
||||||
if not count:
|
if not count or not count.isdigit():
|
||||||
count = __goInference(payload, countedExpression)
|
count = __goInference(payload, countedExpression)
|
||||||
|
|
||||||
if count.isdigit() and int(count) > 0:
|
if count.isdigit() and int(count) > 0:
|
||||||
|
@ -268,7 +273,7 @@ def __goInferenceProxy(expression, fromUser=False):
|
||||||
limitedExpr += "NOT IN (%s" % (limitStr % num)
|
limitedExpr += "NOT IN (%s" % (limitStr % num)
|
||||||
limitedExpr += "%s %s)" % (expressionFieldsList[0], fromFrom)
|
limitedExpr += "%s %s)" % (expressionFieldsList[0], fromFrom)
|
||||||
|
|
||||||
output = __goInferenceFields(limitedExpr, expressionFields, expressionFieldsList, payload)
|
output = __goInferenceFields(limitedExpr, expressionFields, expressionFieldsList, payload, expected)
|
||||||
outputs.append(output)
|
outputs.append(output)
|
||||||
|
|
||||||
return outputs
|
return outputs
|
||||||
|
@ -276,7 +281,7 @@ def __goInferenceProxy(expression, fromUser=False):
|
||||||
elif kb.dbms == "Oracle" and expression.startswith("SELECT ") and " FROM " not in expression:
|
elif kb.dbms == "Oracle" and expression.startswith("SELECT ") and " FROM " not in expression:
|
||||||
expression = "%s FROM DUAL" % expression
|
expression = "%s FROM DUAL" % expression
|
||||||
|
|
||||||
outputs = __goInferenceFields(expression, expressionFields, expressionFieldsList, payload)
|
outputs = __goInferenceFields(expression, expressionFields, expressionFieldsList, payload, expected)
|
||||||
|
|
||||||
returnValue = ", ".join([output for output in outputs])
|
returnValue = ", ".join([output for output in outputs])
|
||||||
else:
|
else:
|
||||||
|
@ -285,7 +290,7 @@ def __goInferenceProxy(expression, fromUser=False):
|
||||||
return returnValue
|
return returnValue
|
||||||
|
|
||||||
|
|
||||||
def __goInband(expression):
|
def __goInband(expression, expected=None):
|
||||||
"""
|
"""
|
||||||
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.
|
||||||
|
@ -304,7 +309,7 @@ def __goInband(expression):
|
||||||
if condition:
|
if condition:
|
||||||
output = resume(expression, None)
|
output = resume(expression, None)
|
||||||
|
|
||||||
if not output:
|
if not output or ( expected == "int" and not output.isdigit() ):
|
||||||
partial = True
|
partial = True
|
||||||
|
|
||||||
if not output:
|
if not output:
|
||||||
|
@ -355,7 +360,7 @@ def __goInband(expression):
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
def getValue(expression, blind=True, inband=True, fromUser=False):
|
def getValue(expression, blind=True, inband=True, fromUser=False, expected=None):
|
||||||
"""
|
"""
|
||||||
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
|
||||||
|
@ -368,9 +373,9 @@ def getValue(expression, blind=True, inband=True, fromUser=False):
|
||||||
value = None
|
value = None
|
||||||
|
|
||||||
if inband and conf.unionUse and kb.dbms:
|
if inband and conf.unionUse and kb.dbms:
|
||||||
value = __goInband(expression)
|
value = __goInband(expression, expected)
|
||||||
|
|
||||||
if blind and not value:
|
if blind and not value:
|
||||||
value = __goInferenceProxy(expression, fromUser)
|
value = __goInferenceProxy(expression, fromUser, expected)
|
||||||
|
|
||||||
return value
|
return value
|
||||||
|
|
|
@ -135,9 +135,9 @@ class Enumeration:
|
||||||
query = rootQuery["blind"]["count2"]
|
query = rootQuery["blind"]["count2"]
|
||||||
else:
|
else:
|
||||||
query = rootQuery["blind"]["count"]
|
query = rootQuery["blind"]["count"]
|
||||||
count = inject.getValue(query, inband=False)
|
count = inject.getValue(query, inband=False, expected="int")
|
||||||
|
|
||||||
if not len(count) or count == "0":
|
if not count.isdigit() or not len(count) or count == "0":
|
||||||
errMsg = "unable to retrieve the number of database users"
|
errMsg = "unable to retrieve the number of database users"
|
||||||
raise sqlmapNoneDataException, errMsg
|
raise sqlmapNoneDataException, errMsg
|
||||||
|
|
||||||
|
@ -228,9 +228,9 @@ class Enumeration:
|
||||||
query = rootQuery["blind"]["count2"] % user
|
query = rootQuery["blind"]["count2"] % user
|
||||||
else:
|
else:
|
||||||
query = rootQuery["blind"]["count"] % user
|
query = rootQuery["blind"]["count"] % user
|
||||||
count = inject.getValue(query, inband=False)
|
count = inject.getValue(query, inband=False, expected="int")
|
||||||
|
|
||||||
if not len(count) or count == "0":
|
if not count.isdigit() or not len(count) or count == "0":
|
||||||
warnMsg = "unable to retrieve the number of password "
|
warnMsg = "unable to retrieve the number of password "
|
||||||
warnMsg += "hashes for user '%s'" % user
|
warnMsg += "hashes for user '%s'" % user
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
@ -458,9 +458,9 @@ class Enumeration:
|
||||||
query = rootQuery["blind"]["count"] % (conditionChar, queryUser)
|
query = rootQuery["blind"]["count"] % (conditionChar, queryUser)
|
||||||
else:
|
else:
|
||||||
query = rootQuery["blind"]["count"] % queryUser
|
query = rootQuery["blind"]["count"] % queryUser
|
||||||
count = inject.getValue(query, inband=False)
|
count = inject.getValue(query, inband=False, expected="int")
|
||||||
|
|
||||||
if not len(count) or count == "0":
|
if not count.isdigit() or not len(count) or count == "0":
|
||||||
warnMsg = "unable to retrieve the number of "
|
warnMsg = "unable to retrieve the number of "
|
||||||
warnMsg += "privileges for user '%s'" % user
|
warnMsg += "privileges for user '%s'" % user
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
@ -572,9 +572,9 @@ class Enumeration:
|
||||||
query = rootQuery["blind"]["count2"]
|
query = rootQuery["blind"]["count2"]
|
||||||
else:
|
else:
|
||||||
query = rootQuery["blind"]["count"]
|
query = rootQuery["blind"]["count"]
|
||||||
count = inject.getValue(query, inband=False)
|
count = inject.getValue(query, inband=False, expected="int")
|
||||||
|
|
||||||
if not len(count) or count == "0":
|
if not count.isdigit() or not len(count) or count == "0":
|
||||||
errMsg = "unable to retrieve the number of databases"
|
errMsg = "unable to retrieve the number of databases"
|
||||||
raise sqlmapNoneDataException, errMsg
|
raise sqlmapNoneDataException, errMsg
|
||||||
|
|
||||||
|
@ -662,9 +662,9 @@ class Enumeration:
|
||||||
logger.info(logMsg)
|
logger.info(logMsg)
|
||||||
|
|
||||||
query = rootQuery["blind"]["count"] % db
|
query = rootQuery["blind"]["count"] % db
|
||||||
count = inject.getValue(query, inband=False)
|
count = inject.getValue(query, inband=False, expected="int")
|
||||||
|
|
||||||
if not len(count) or count == "0":
|
if not count.isdigit() or not len(count) or count == "0":
|
||||||
warnMsg = "unable to retrieve the number of "
|
warnMsg = "unable to retrieve the number of "
|
||||||
warnMsg += "tables for database '%s'" % db
|
warnMsg += "tables for database '%s'" % db
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
@ -756,9 +756,9 @@ class Enumeration:
|
||||||
elif kb.dbms == "Microsoft SQL Server":
|
elif kb.dbms == "Microsoft SQL Server":
|
||||||
query = rootQuery["blind"]["count"] % (conf.db, conf.db, conf.tbl)
|
query = rootQuery["blind"]["count"] % (conf.db, conf.db, conf.tbl)
|
||||||
|
|
||||||
count = inject.getValue(query, inband=False)
|
count = inject.getValue(query, inband=False, expected="int")
|
||||||
|
|
||||||
if not len(count) or count == "0":
|
if not count.isdigit() or not len(count) or count == "0":
|
||||||
errMsg = "unable to retrieve the number of columns "
|
errMsg = "unable to retrieve the number of columns "
|
||||||
errMsg += "for table '%s' " % conf.tbl
|
errMsg += "for table '%s' " % conf.tbl
|
||||||
errMsg += "on database '%s'" % conf.db
|
errMsg += "on database '%s'" % conf.db
|
||||||
|
@ -905,9 +905,9 @@ class Enumeration:
|
||||||
query = rootQuery["blind"]["count"] % conf.tbl.upper()
|
query = rootQuery["blind"]["count"] % conf.tbl.upper()
|
||||||
else:
|
else:
|
||||||
query = rootQuery["blind"]["count"] % (conf.db, conf.tbl)
|
query = rootQuery["blind"]["count"] % (conf.db, conf.tbl)
|
||||||
count = inject.getValue(query, inband=False)
|
count = inject.getValue(query, inband=False, expected="int")
|
||||||
|
|
||||||
if not len(count) or count == "0":
|
if not count.isdigit() or not len(count) or count == "0":
|
||||||
errMsg = "unable to retrieve the number of "
|
errMsg = "unable to retrieve the number of "
|
||||||
if conf.col:
|
if conf.col:
|
||||||
errMsg += "columns '%s' " % colString
|
errMsg += "columns '%s' " % colString
|
||||||
|
|
Loading…
Reference in New Issue
Block a user