mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2025-12-10 09:49:06 +00:00
Major enhancement to support Partial UNION query SQL injection technique too.
Minor code cleanup.
This commit is contained in:
@@ -53,12 +53,11 @@ class Agent:
|
||||
injection statement to request
|
||||
"""
|
||||
|
||||
negValue = ""
|
||||
retValue = ""
|
||||
|
||||
if negative == True or conf.paramNegative == True:
|
||||
negValue = "-"
|
||||
else:
|
||||
negValue = ""
|
||||
|
||||
# After identifing the injectable parameter
|
||||
if kb.injPlace == "User-Agent":
|
||||
@@ -231,6 +230,22 @@ class Agent:
|
||||
|
||||
|
||||
def getFields(self, query):
|
||||
"""
|
||||
Take in input a query string and return its fields (columns) and
|
||||
more details.
|
||||
|
||||
Example:
|
||||
|
||||
Input: SELECT user, password FROM mysql.user
|
||||
Output: user,password
|
||||
|
||||
@param query: query to be processed
|
||||
@type query: C{str}
|
||||
|
||||
@return: query fields (columns) and more details
|
||||
@rtype: C{str}
|
||||
"""
|
||||
|
||||
fieldsSelectTop = re.search("\ASELECT\s+TOP\s+[\d]+\s+(.+?)\s+FROM", query, re.I)
|
||||
fieldsSelectDistinct = re.search("\ASELECT\s+DISTINCT\((.+?)\)\s+FROM", query, re.I)
|
||||
fieldsSelectFrom = re.search("\ASELECT\s+(.+?)\s+FROM\s+", query, re.I)
|
||||
@@ -395,5 +410,55 @@ class Agent:
|
||||
return inbandQuery
|
||||
|
||||
|
||||
def limitQuery(self, num, query, fieldsList=None):
|
||||
"""
|
||||
Take in input a query string and return its limited query string.
|
||||
|
||||
Example:
|
||||
|
||||
Input: SELECT user FROM mysql.users
|
||||
Output: SELECT user FROM mysql.users LIMIT <num>, 1
|
||||
|
||||
@param num: limit number
|
||||
@type num: C{int}
|
||||
|
||||
@param query: query to be processed
|
||||
@type query: C{str}
|
||||
|
||||
@param fieldsList: list of fields within the query
|
||||
@type fieldsList: C{list}
|
||||
|
||||
@return: limited query string
|
||||
@rtype: C{str}
|
||||
"""
|
||||
|
||||
limitedQuery = query
|
||||
limitStr = queries[kb.dbms].limit
|
||||
fromIndex = limitedQuery.index(" FROM ")
|
||||
untilFrom = limitedQuery[:fromIndex]
|
||||
fromFrom = limitedQuery[fromIndex+1:]
|
||||
|
||||
if kb.dbms in ( "MySQL", "PostgreSQL" ):
|
||||
limitStr = queries[kb.dbms].limit % (num, 1)
|
||||
limitedQuery += " %s" % limitStr
|
||||
|
||||
elif kb.dbms == "Oracle":
|
||||
limitedQuery = "%s FROM (%s, %s" % (untilFrom, untilFrom, limitStr)
|
||||
limitedQuery = limitedQuery % fromFrom
|
||||
limitedQuery += "=%d" % (num + 1)
|
||||
|
||||
elif kb.dbms == "Microsoft SQL Server":
|
||||
if re.search(" ORDER BY ", limitedQuery, re.I):
|
||||
untilOrderChar = limitedQuery.index(" ORDER BY ")
|
||||
limitedQuery = limitedQuery[:untilOrderChar]
|
||||
|
||||
limitedQuery = limitedQuery.replace("SELECT ", (limitStr % 1), 1)
|
||||
limitedQuery = "%s WHERE %s " % (limitedQuery, fieldsList[0])
|
||||
limitedQuery += "NOT IN (%s" % (limitStr % num)
|
||||
limitedQuery += "%s %s)" % (fieldsList[0], fromFrom)
|
||||
|
||||
return limitedQuery
|
||||
|
||||
|
||||
# SQL agent
|
||||
agent = Agent()
|
||||
|
||||
@@ -500,6 +500,7 @@ def cleanQuery(query):
|
||||
upperQuery = upperQuery.replace(" order by ", " ORDER BY ")
|
||||
upperQuery = upperQuery.replace(" group by ", " GROUP BY ")
|
||||
upperQuery = upperQuery.replace(" union all ", " UNION ALL ")
|
||||
upperQuery = upperQuery.replace(" rownum ", " ROWNUM ")
|
||||
|
||||
return upperQuery
|
||||
|
||||
@@ -624,3 +625,53 @@ def getRange(count, dump=False, plusOne=False):
|
||||
indexRange = range(limitStart - 1, limitStop)
|
||||
|
||||
return indexRange
|
||||
|
||||
|
||||
def parseUnionPage(output, expression, partial=False, condition=None):
|
||||
data = []
|
||||
|
||||
outCond1 = ( output.startswith(temp.start) and output.endswith(temp.stop) )
|
||||
outCond2 = ( output.startswith("__START__") and output.endswith("__STOP__") )
|
||||
|
||||
if outCond1 or outCond2:
|
||||
if outCond1:
|
||||
regExpr = '%s(.*?)%s' % (temp.start, temp.stop)
|
||||
elif outCond2:
|
||||
regExpr = '__START__(.*?)__STOP__'
|
||||
|
||||
output = re.findall(regExpr, output, re.S)
|
||||
|
||||
if condition == None:
|
||||
condition = (
|
||||
kb.resumedQueries and conf.url in kb.resumedQueries.keys()
|
||||
and expression in kb.resumedQueries[conf.url].keys()
|
||||
)
|
||||
|
||||
if partial or not condition:
|
||||
logOutput = "".join(["__START__%s__STOP__" % replaceNewlineTabs(value) for value in output])
|
||||
dataToSessionFile("[%s][%s][%s][%s][%s]\n" % (conf.url, kb.injPlace, conf.parameters[kb.injPlace], expression, logOutput))
|
||||
|
||||
output = set(output)
|
||||
|
||||
for entry in output:
|
||||
info = []
|
||||
|
||||
if "__DEL__" in entry:
|
||||
entry = entry.split("__DEL__")
|
||||
else:
|
||||
entry = entry.split(temp.delimiter)
|
||||
|
||||
if len(entry) == 1:
|
||||
data.append(entry[0])
|
||||
else:
|
||||
for value in entry:
|
||||
info.append(value)
|
||||
|
||||
data.append(info)
|
||||
else:
|
||||
data = output
|
||||
|
||||
if len(data) == 1 and isinstance(data[0], str):
|
||||
data = data[0]
|
||||
|
||||
return data
|
||||
|
||||
Reference in New Issue
Block a user