mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2025-06-01 19:53:13 +03:00
Major bug fix to properly deal with EXISTS() when forging query or retrieving the query columns.
This commit is contained in:
parent
c2a358561f
commit
3822b494ea
|
@ -341,15 +341,19 @@ class Agent:
|
||||||
@return: query fields (columns) and more details
|
@return: query fields (columns) and more details
|
||||||
@rtype: C{str}
|
@rtype: C{str}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
prefixRegex = "(?:\s+(?:FIRST|SKIP)\s+\d+)*"
|
prefixRegex = "(?:\s+(?:FIRST|SKIP)\s+\d+)*"
|
||||||
fieldsSelectTop = re.search("\ASELECT\s+TOP\s+[\d]+\s+(.+?)\s+FROM", query, re.I)
|
fieldsSelectTop = re.search("\ASELECT\s+TOP\s+[\d]+\s+(.+?)\s+FROM", query, re.I)
|
||||||
fieldsSelectDistinct = re.search("\ASELECT%s\s+DISTINCT\((.+?)\)\s+FROM" % prefixRegex, query, re.I)
|
fieldsSelectDistinct = re.search("\ASELECT%s\s+DISTINCT\((.+?)\)\s+FROM" % prefixRegex, query, re.I)
|
||||||
fieldsSelectCase = re.search("\ASELECT%s\s+(\(CASE WHEN\s+.+\s+END\))" % prefixRegex, query, re.I)
|
fieldsSelectCase = re.search("\ASELECT%s\s+(\(CASE WHEN\s+.+\s+END\))" % prefixRegex, query, re.I)
|
||||||
fieldsSelectFrom = re.search("\ASELECT%s\s+(.+?)\s+FROM\s+" % prefixRegex, query, re.I)
|
fieldsSelectFrom = re.search("\ASELECT%s\s+(.+?)\s+FROM\s+" % prefixRegex, query, re.I)
|
||||||
|
fieldsExists = re.search("EXISTS(.*)", query, re.I)
|
||||||
fieldsSelect = re.search("\ASELECT%s\s+(.*)" % prefixRegex, query, re.I)
|
fieldsSelect = re.search("\ASELECT%s\s+(.*)" % prefixRegex, query, re.I)
|
||||||
fieldsNoSelect = query
|
fieldsNoSelect = query
|
||||||
|
|
||||||
if fieldsSelectTop:
|
if fieldsExists:
|
||||||
|
fieldsToCastStr = fieldsSelect.groups()[0]
|
||||||
|
elif fieldsSelectTop:
|
||||||
fieldsToCastStr = fieldsSelectTop.groups()[0]
|
fieldsToCastStr = fieldsSelectTop.groups()[0]
|
||||||
elif fieldsSelectDistinct:
|
elif fieldsSelectDistinct:
|
||||||
fieldsToCastStr = fieldsSelectDistinct.groups()[0]
|
fieldsToCastStr = fieldsSelectDistinct.groups()[0]
|
||||||
|
@ -368,7 +372,7 @@ class Agent:
|
||||||
fieldsToCastList = fieldsToCastStr.replace(", ", ",")
|
fieldsToCastList = fieldsToCastStr.replace(", ", ",")
|
||||||
fieldsToCastList = fieldsToCastList.split(",")
|
fieldsToCastList = fieldsToCastList.split(",")
|
||||||
|
|
||||||
return fieldsSelectFrom, fieldsSelect, fieldsNoSelect, fieldsSelectTop, fieldsSelectCase, fieldsToCastList, fieldsToCastStr
|
return fieldsSelectFrom, fieldsSelect, fieldsNoSelect, fieldsSelectTop, fieldsSelectCase, fieldsToCastList, fieldsToCastStr, fieldsExists
|
||||||
|
|
||||||
def simpleConcatQuery(self, query1, query2):
|
def simpleConcatQuery(self, query1, query2):
|
||||||
concatenatedQuery = ""
|
concatenatedQuery = ""
|
||||||
|
@ -414,15 +418,18 @@ class Agent:
|
||||||
concatenatedQuery = ""
|
concatenatedQuery = ""
|
||||||
query = query.replace(", ", ",")
|
query = query.replace(", ", ",")
|
||||||
|
|
||||||
fieldsSelectFrom, fieldsSelect, fieldsNoSelect, fieldsSelectTop, fieldsSelectCase, _, fieldsToCastStr = self.getFields(query)
|
fieldsSelectFrom, fieldsSelect, fieldsNoSelect, fieldsSelectTop, fieldsSelectCase, _, fieldsToCastStr, fieldsExists = self.getFields(query)
|
||||||
castedFields = self.nullCastConcatFields(fieldsToCastStr)
|
castedFields = self.nullCastConcatFields(fieldsToCastStr)
|
||||||
concatenatedQuery = query.replace(fieldsToCastStr, castedFields, 1)
|
concatenatedQuery = query.replace(fieldsToCastStr, castedFields, 1)
|
||||||
else:
|
else:
|
||||||
concatenatedQuery = query
|
concatenatedQuery = query
|
||||||
fieldsSelectFrom, fieldsSelect, fieldsNoSelect, fieldsSelectTop, fieldsSelectCase, _, fieldsToCastStr = self.getFields(query)
|
fieldsSelectFrom, fieldsSelect, fieldsNoSelect, fieldsSelectTop, fieldsSelectCase, _, fieldsToCastStr, fieldsExists = self.getFields(query)
|
||||||
|
|
||||||
if getIdentifiedDBMS() == DBMS.MYSQL:
|
if getIdentifiedDBMS() == DBMS.MYSQL:
|
||||||
if fieldsSelectFrom:
|
if fieldsExists:
|
||||||
|
concatenatedQuery = concatenatedQuery.replace("SELECT ", "CONCAT('%s'," % kb.misc.start, 1)
|
||||||
|
concatenatedQuery += ",'%s')" % kb.misc.stop
|
||||||
|
elif fieldsSelectFrom:
|
||||||
concatenatedQuery = concatenatedQuery.replace("SELECT ", "CONCAT('%s'," % kb.misc.start, 1)
|
concatenatedQuery = concatenatedQuery.replace("SELECT ", "CONCAT('%s'," % kb.misc.start, 1)
|
||||||
concatenatedQuery = concatenatedQuery.replace(" FROM ", ",'%s') FROM " % kb.misc.stop, 1)
|
concatenatedQuery = concatenatedQuery.replace(" FROM ", ",'%s') FROM " % kb.misc.stop, 1)
|
||||||
elif fieldsSelect or fieldsSelectCase:
|
elif fieldsSelect or fieldsSelectCase:
|
||||||
|
@ -432,7 +439,10 @@ class Agent:
|
||||||
concatenatedQuery = "CONCAT('%s',%s,'%s')" % (kb.misc.start, concatenatedQuery, kb.misc.stop)
|
concatenatedQuery = "CONCAT('%s',%s,'%s')" % (kb.misc.start, concatenatedQuery, kb.misc.stop)
|
||||||
|
|
||||||
elif getIdentifiedDBMS() in ( DBMS.PGSQL, DBMS.ORACLE, DBMS.SQLITE ):
|
elif getIdentifiedDBMS() in ( DBMS.PGSQL, DBMS.ORACLE, DBMS.SQLITE ):
|
||||||
if fieldsSelectFrom:
|
if fieldsExists:
|
||||||
|
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'||" % kb.misc.start, 1)
|
||||||
|
concatenatedQuery += "||'%s'" % kb.misc.stop
|
||||||
|
elif fieldsSelectFrom:
|
||||||
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'||" % kb.misc.start, 1)
|
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'||" % kb.misc.start, 1)
|
||||||
concatenatedQuery = concatenatedQuery.replace(" FROM ", "||'%s' FROM " % kb.misc.stop, 1)
|
concatenatedQuery = concatenatedQuery.replace(" FROM ", "||'%s' FROM " % kb.misc.stop, 1)
|
||||||
elif fieldsSelect or fieldsSelectCase:
|
elif fieldsSelect or fieldsSelectCase:
|
||||||
|
@ -445,7 +455,10 @@ class Agent:
|
||||||
concatenatedQuery += " FROM DUAL"
|
concatenatedQuery += " FROM DUAL"
|
||||||
|
|
||||||
elif getIdentifiedDBMS() in (DBMS.MSSQL, DBMS.SYBASE):
|
elif getIdentifiedDBMS() in (DBMS.MSSQL, DBMS.SYBASE):
|
||||||
if fieldsSelectTop:
|
if fieldsExists:
|
||||||
|
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'+" % kb.misc.start, 1)
|
||||||
|
concatenatedQuery += "+'%s'" % kb.misc.stop
|
||||||
|
elif fieldsSelectTop:
|
||||||
topNum = re.search("\ASELECT\s+TOP\s+([\d]+)\s+", concatenatedQuery, re.I).group(1)
|
topNum = re.search("\ASELECT\s+TOP\s+([\d]+)\s+", concatenatedQuery, re.I).group(1)
|
||||||
concatenatedQuery = concatenatedQuery.replace("SELECT TOP %s " % topNum, "TOP %s '%s'+" % (topNum, kb.misc.start), 1)
|
concatenatedQuery = concatenatedQuery.replace("SELECT TOP %s " % topNum, "TOP %s '%s'+" % (topNum, kb.misc.start), 1)
|
||||||
concatenatedQuery = concatenatedQuery.replace(" FROM ", "+'%s' FROM " % kb.misc.stop, 1)
|
concatenatedQuery = concatenatedQuery.replace(" FROM ", "+'%s' FROM " % kb.misc.stop, 1)
|
||||||
|
|
|
@ -160,7 +160,7 @@ def __goInferenceProxy(expression, fromUser=False, expected=None, batch=False, r
|
||||||
return __goInference(payload, expression, charsetType, firstChar, lastChar)
|
return __goInference(payload, expression, charsetType, firstChar, lastChar)
|
||||||
|
|
||||||
if kb.dbmsDetected:
|
if kb.dbmsDetected:
|
||||||
_, _, _, _, _, expressionFieldsList, expressionFields = agent.getFields(expression)
|
_, _, _, _, _, expressionFieldsList, expressionFields, _ = agent.getFields(expression)
|
||||||
|
|
||||||
rdbRegExp = re.search("RDB\$GET_CONTEXT\([^)]+\)", expression, re.I)
|
rdbRegExp = re.search("RDB\$GET_CONTEXT\([^)]+\)", expression, re.I)
|
||||||
if rdbRegExp and getIdentifiedDBMS() == DBMS.FIREBIRD:
|
if rdbRegExp and getIdentifiedDBMS() == DBMS.FIREBIRD:
|
||||||
|
|
|
@ -75,12 +75,12 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
|
||||||
lastChar = int(lastChar)
|
lastChar = int(lastChar)
|
||||||
|
|
||||||
if kb.dbmsDetected:
|
if kb.dbmsDetected:
|
||||||
_, _, _, _, _, _, fieldToCastStr = agent.getFields(expression)
|
_, _, _, _, _, _, fieldToCastStr, _ = agent.getFields(expression)
|
||||||
nulledCastedField = agent.nullAndCastField(fieldToCastStr)
|
nulledCastedField = agent.nullAndCastField(fieldToCastStr)
|
||||||
expressionReplaced = expression.replace(fieldToCastStr, nulledCastedField, 1)
|
expressionReplaced = expression.replace(fieldToCastStr, nulledCastedField, 1)
|
||||||
expressionUnescaped = unescaper.unescape(expressionReplaced)
|
expressionUnescaped = unescaper.unescape(expressionReplaced)
|
||||||
else:
|
else:
|
||||||
expressionUnescaped = unescaper.unescape(expression)
|
expressionUnescaped = unescaper.unescape(expression)
|
||||||
|
|
||||||
if length and not isinstance(length, int) and length.isdigit():
|
if length and not isinstance(length, int) and length.isdigit():
|
||||||
length = int(length)
|
length = int(length)
|
||||||
|
|
|
@ -42,7 +42,7 @@ def errorUse(expression):
|
||||||
query = agent.suffixQuery(query)
|
query = agent.suffixQuery(query)
|
||||||
check = "%s(?P<result>.*?)%s" % (kb.misc.start, kb.misc.stop)
|
check = "%s(?P<result>.*?)%s" % (kb.misc.start, kb.misc.stop)
|
||||||
|
|
||||||
_, _, _, _, _, _, fieldToCastStr = agent.getFields(expression)
|
_, _, _, _, _, _, fieldToCastStr, _ = agent.getFields(expression)
|
||||||
nulledCastedField = agent.nullAndCastField(fieldToCastStr)
|
nulledCastedField = agent.nullAndCastField(fieldToCastStr)
|
||||||
|
|
||||||
if getIdentifiedDBMS() == DBMS.MYSQL:
|
if getIdentifiedDBMS() == DBMS.MYSQL:
|
||||||
|
|
|
@ -95,7 +95,7 @@ def unionUse(expression, direct=False, unescape=True, resetCounter=False, unpack
|
||||||
expression = unescaper.unescape(expression)
|
expression = unescaper.unescape(expression)
|
||||||
|
|
||||||
if kb.injection.data[PAYLOAD.TECHNIQUE.UNION].where == 2 and not direct:
|
if kb.injection.data[PAYLOAD.TECHNIQUE.UNION].where == 2 and not direct:
|
||||||
_, _, _, _, _, expressionFieldsList, expressionFields = agent.getFields(origExpr)
|
_, _, _, _, _, expressionFieldsList, expressionFields, _ = agent.getFields(origExpr)
|
||||||
|
|
||||||
# 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
|
||||||
|
|
Loading…
Reference in New Issue
Block a user