mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2025-02-19 21:10:36 +03:00
Major bug fix to make partial UNION query sql injection work properly
also on Microsoft SQL Server
This commit is contained in:
parent
064029cb2d
commit
1f7810e46a
|
@ -81,6 +81,14 @@ class Agent:
|
||||||
return retValue
|
return retValue
|
||||||
|
|
||||||
|
|
||||||
|
def fullPayload(self, query):
|
||||||
|
query = self.prefixQuery(query)
|
||||||
|
query = self.postfixQuery(query)
|
||||||
|
payload = self.payload(newValue=query)
|
||||||
|
|
||||||
|
return payload
|
||||||
|
|
||||||
|
|
||||||
def prefixQuery(self, string):
|
def prefixQuery(self, string):
|
||||||
"""
|
"""
|
||||||
This method defines how the input string has to be escaped
|
This method defines how the input string has to be escaped
|
||||||
|
@ -396,32 +404,32 @@ class Agent:
|
||||||
inbandQuery += ", "
|
inbandQuery += ", "
|
||||||
|
|
||||||
if element == exprPosition:
|
if element == exprPosition:
|
||||||
if " FROM " in query and not query.startswith("SELECT ") and not "(SELECT " in query:
|
if " FROM " in query and not query.startswith("SELECT "):
|
||||||
conditionIndex = query.rindex(" FROM ")
|
conditionIndex = query.index(" FROM ")
|
||||||
inbandQuery += "%s" % query[:conditionIndex]
|
inbandQuery += query[:conditionIndex]
|
||||||
else:
|
else:
|
||||||
inbandQuery += "%s" % query
|
inbandQuery += query
|
||||||
else:
|
else:
|
||||||
inbandQuery += "NULL"
|
inbandQuery += "NULL"
|
||||||
|
|
||||||
if " FROM " in query and not query.startswith("SELECT ") and not "(SELECT " in query:
|
if " FROM " in query and not query.startswith("SELECT "):
|
||||||
conditionIndex = query.rindex(" FROM ")
|
conditionIndex = query.index(" FROM ")
|
||||||
inbandQuery += "%s" % query[conditionIndex:]
|
inbandQuery += query[conditionIndex:]
|
||||||
|
|
||||||
|
if " ORDER BY " in inbandQuery and "(SELECT " in inbandQuery:
|
||||||
|
orderIndex = inbandQuery.index(" ORDER BY ")
|
||||||
|
inbandQuery += inbandQuery[orderIndex:].replace(")", "")
|
||||||
|
|
||||||
if kb.dbms == "Oracle":
|
if kb.dbms == "Oracle":
|
||||||
if " FROM " not in inbandQuery:
|
if " FROM " not in inbandQuery:
|
||||||
inbandQuery += " FROM DUAL"
|
inbandQuery += " FROM DUAL"
|
||||||
|
|
||||||
if " ORDER BY " in inbandQuery:
|
|
||||||
orderIndex = inbandQuery.index(" ORDER BY ")
|
|
||||||
inbandQuery = inbandQuery[:orderIndex]
|
|
||||||
|
|
||||||
inbandQuery = self.postfixQuery(inbandQuery, kb.unionComment)
|
inbandQuery = self.postfixQuery(inbandQuery, kb.unionComment)
|
||||||
|
|
||||||
return inbandQuery
|
return inbandQuery
|
||||||
|
|
||||||
|
|
||||||
def limitQuery(self, num, query, fieldsList=None):
|
def limitQuery(self, num, query, field):
|
||||||
"""
|
"""
|
||||||
Take in input a query string and return its limited query string.
|
Take in input a query string and return its limited query string.
|
||||||
|
|
||||||
|
@ -436,8 +444,8 @@ class Agent:
|
||||||
@param query: query to be processed
|
@param query: query to be processed
|
||||||
@type query: C{str}
|
@type query: C{str}
|
||||||
|
|
||||||
@param fieldsList: list of fields within the query
|
@param field: field within the query
|
||||||
@type fieldsList: C{list}
|
@type field: C{list}
|
||||||
|
|
||||||
@return: limited query string
|
@return: limited query string
|
||||||
@rtype: C{str}
|
@rtype: C{str}
|
||||||
|
@ -453,13 +461,12 @@ class Agent:
|
||||||
limitStr = queries[kb.dbms].limit % (num, 1)
|
limitStr = queries[kb.dbms].limit % (num, 1)
|
||||||
limitedQuery += " %s" % limitStr
|
limitedQuery += " %s" % limitStr
|
||||||
|
|
||||||
# TODO: fix for Partial UNION query SQL injection technique both
|
# TODO: fix Partial UNION query SQL injection technique for Oracle
|
||||||
# Oracle and Microsoft SQL Server
|
|
||||||
elif kb.dbms == "Oracle":
|
elif kb.dbms == "Oracle":
|
||||||
if query.startswith("SELECT "):
|
if query.startswith("SELECT "):
|
||||||
limitedQuery = "%s FROM (%s, %s" % (untilFrom, untilFrom, limitStr)
|
limitedQuery = "%s FROM (%s, %s" % (untilFrom, untilFrom, limitStr)
|
||||||
else:
|
else:
|
||||||
limitedQuery = "%s FROM (SELECT %s, %s" % (untilFrom, ", ".join(field for field in fieldsList), limitStr)
|
limitedQuery = "%s FROM (SELECT %s, %s" % (untilFrom, field, limitStr)
|
||||||
limitedQuery = limitedQuery % fromFrom
|
limitedQuery = limitedQuery % fromFrom
|
||||||
limitedQuery += "=%d" % (num + 1)
|
limitedQuery += "=%d" % (num + 1)
|
||||||
|
|
||||||
|
@ -469,9 +476,9 @@ class Agent:
|
||||||
limitedQuery = limitedQuery[:untilOrderChar]
|
limitedQuery = limitedQuery[:untilOrderChar]
|
||||||
|
|
||||||
limitedQuery = limitedQuery.replace("SELECT ", (limitStr % 1), 1)
|
limitedQuery = limitedQuery.replace("SELECT ", (limitStr % 1), 1)
|
||||||
limitedQuery = "%s WHERE %s " % (limitedQuery, fieldsList[0])
|
limitedQuery = "%s WHERE %s " % (limitedQuery, field)
|
||||||
limitedQuery += "NOT IN (%s" % (limitStr % num)
|
limitedQuery += "NOT IN (%s" % (limitStr % num)
|
||||||
limitedQuery += "%s %s)" % (fieldsList[0], fromFrom)
|
limitedQuery += "%s %s)" % (field, fromFrom)
|
||||||
|
|
||||||
return limitedQuery
|
return limitedQuery
|
||||||
|
|
||||||
|
|
|
@ -70,13 +70,23 @@ def __goInference(payload, expression):
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
def __goInferenceFields(expression, expressionFields, expressionFieldsList, payload, expected=None):
|
def __goInferenceFields(expression, expressionFields, expressionFieldsList, payload, expected=None, num=None):
|
||||||
outputs = []
|
outputs = []
|
||||||
|
origExpr = None
|
||||||
|
|
||||||
for field in expressionFieldsList:
|
for field in expressionFieldsList:
|
||||||
output = None
|
output = None
|
||||||
|
|
||||||
|
if isinstance(num, int):
|
||||||
|
origExpr = expression
|
||||||
|
expression = agent.limitQuery(num, expression, field)
|
||||||
|
|
||||||
expressionReplaced = expression.replace(expressionFields, field, 1)
|
expressionReplaced = expression.replace(expressionFields, field, 1)
|
||||||
|
|
||||||
|
if " ORDER BY " in expressionReplaced and "(SELECT " in expressionReplaced:
|
||||||
|
orderIndex = expressionReplaced.index(" ORDER BY ")
|
||||||
|
expressionReplaced += expressionReplaced[orderIndex:].replace(")", "")
|
||||||
|
|
||||||
output = resume(expressionReplaced, payload)
|
output = resume(expressionReplaced, payload)
|
||||||
|
|
||||||
if not output or ( expected == "int" and not output.isdigit() ):
|
if not output or ( expected == "int" and not output.isdigit() ):
|
||||||
|
@ -87,6 +97,9 @@ def __goInferenceFields(expression, expressionFields, expressionFieldsList, payl
|
||||||
|
|
||||||
output = __goInference(payload, expressionReplaced)
|
output = __goInference(payload, expressionReplaced)
|
||||||
|
|
||||||
|
if isinstance(num, int):
|
||||||
|
expression = origExpr
|
||||||
|
|
||||||
outputs.append(output)
|
outputs.append(output)
|
||||||
|
|
||||||
return outputs
|
return outputs
|
||||||
|
@ -252,9 +265,7 @@ def __goInferenceProxy(expression, fromUser=False, expected=None):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
for num in xrange(startLimit, stopLimit):
|
for num in xrange(startLimit, stopLimit):
|
||||||
limitedExpr = agent.limitQuery(num, expression, expressionFieldsList)
|
output = __goInferenceFields(expression, expressionFields, expressionFieldsList, payload, expected, num)
|
||||||
|
|
||||||
output = __goInferenceFields(limitedExpr, expressionFields, expressionFieldsList, payload, expected)
|
|
||||||
outputs.append(output)
|
outputs.append(output)
|
||||||
|
|
||||||
return outputs
|
return outputs
|
||||||
|
|
|
@ -261,7 +261,14 @@ def unionUse(expression, direct=False, unescape=True, resetCounter=False):
|
||||||
return
|
return
|
||||||
|
|
||||||
for num in xrange(startLimit, stopLimit):
|
for num in xrange(startLimit, stopLimit):
|
||||||
limitedExpr = agent.limitQuery(num, expression, expressionFieldsList)
|
orderBy = re.search(" ORDER BY ([\w\_]+)", expression, re.I)
|
||||||
|
|
||||||
|
if orderBy:
|
||||||
|
field = orderBy.group(1)
|
||||||
|
else:
|
||||||
|
field = expressionFieldsList[0]
|
||||||
|
|
||||||
|
limitedExpr = agent.limitQuery(num, expression, field)
|
||||||
output = unionUse(limitedExpr, direct=True, unescape=False)
|
output = unionUse(limitedExpr, direct=True, unescape=False)
|
||||||
|
|
||||||
if output:
|
if output:
|
||||||
|
|
Loading…
Reference in New Issue
Block a user