mirror of
				https://github.com/sqlmapproject/sqlmap.git
				synced 2025-10-31 16:07:55 +03:00 
			
		
		
		
	Major bug fix to make it work properly with MSSQL custom limited (SELECT
TOP ...) queries with both inferential blind and Full UNION query injection
This commit is contained in:
		
							parent
							
								
									2cc3bb2f6a
								
							
						
					
					
						commit
						9c42a883be
					
				|  | @ -285,7 +285,7 @@ class Agent: | |||
|         if query.startswith("SELECT ") and "(SELECT " in query: | ||||
|             fieldsSelectFrom = None | ||||
| 
 | ||||
|         return fieldsSelectFrom, fieldsSelect, fieldsNoSelect, fieldsToCastList, fieldsToCastStr | ||||
|         return fieldsSelectFrom, fieldsSelect, fieldsNoSelect, fieldsSelectTop, fieldsToCastList, fieldsToCastStr | ||||
| 
 | ||||
| 
 | ||||
|     def concatQuery(self, query): | ||||
|  | @ -317,7 +317,7 @@ class Agent: | |||
|         concatQuery = "" | ||||
|         query       = query.replace(", ", ",") | ||||
| 
 | ||||
|         fieldsSelectFrom, fieldsSelect, fieldsNoSelect, _, fieldsToCastStr = self.getFields(query) | ||||
|         fieldsSelectFrom, fieldsSelect, fieldsNoSelect, fieldsSelectTop, _, fieldsToCastStr = self.getFields(query) | ||||
|         castedFields = self.nullCastConcatFields(fieldsToCastStr) | ||||
|         concatQuery  = query.replace(fieldsToCastStr, castedFields, 1) | ||||
| 
 | ||||
|  | @ -348,7 +348,11 @@ class Agent: | |||
|                     concatQuery += " FROM DUAL" | ||||
| 
 | ||||
|         elif kb.dbms == "Microsoft SQL Server": | ||||
|             if fieldsSelectFrom: | ||||
|             if fieldsSelectTop: | ||||
|                 topNum = re.search("\ASELECT\s+TOP\s+([\d]+)\s+", concatQuery, re.I).group(1) | ||||
|                 concatQuery = concatQuery.replace("SELECT TOP %s " % topNum, "TOP %s '%s'+" % (topNum, temp.start), 1) | ||||
|                 concatQuery = concatQuery.replace(" FROM ", "+'%s' FROM " % temp.stop, 1) | ||||
|             elif fieldsSelectFrom: | ||||
|                 concatQuery = concatQuery.replace("SELECT ", "'%s'+" % temp.start, 1) | ||||
|                 concatQuery = concatQuery.replace(" FROM ", "+'%s' FROM " % temp.stop, 1) | ||||
|             elif fieldsSelect: | ||||
|  | @ -393,6 +397,11 @@ class Agent: | |||
| 
 | ||||
|         inbandQuery = self.prefixQuery(" UNION ALL SELECT ") | ||||
| 
 | ||||
|         if query.startswith("TOP"): | ||||
|             topNum       = re.search("\ATOP\s+([\d]+)\s+", query, re.I).group(1) | ||||
|             query        = query[len("TOP %s " % topNum):] | ||||
|             inbandQuery += "TOP %s " % topNum | ||||
| 
 | ||||
|         if not exprPosition: | ||||
|             exprPosition = kb.unionPosition | ||||
| 
 | ||||
|  | @ -472,10 +481,17 @@ class Agent: | |||
|             if " ORDER BY " in limitedQuery: | ||||
|                 limitedQuery = limitedQuery[:limitedQuery.index(" ORDER BY ")] | ||||
| 
 | ||||
|             if not limitedQuery.startswith("SELECT TOP "): | ||||
|                 limitedQuery  = limitedQuery.replace("SELECT ", (limitStr % 1), 1) | ||||
|                 limitedQuery  = "%s WHERE %s " % (limitedQuery, field) | ||||
|                 limitedQuery += "NOT IN (%s" % (limitStr % num) | ||||
|                 limitedQuery += "%s %s)" % (field, fromFrom) | ||||
|             else: | ||||
|                 topNums         = re.search("\ASELECT\s+TOP\s+([\d]+)\s+.+?\s+FROM\s+.+?\s+WHERE\s+.+?\s+NOT\s+IN\s+\(SELECT\s+TOP\s+([\d]+)\s+", limitedQuery, re.I).groups() | ||||
|                 quantityTopNums = topNums[0] | ||||
|                 limitedQuery    = limitedQuery.replace("SELECT TOP %s" % quantityTopNums, "SELECT TOP 1", 1) | ||||
|                 startTopNums    = topNums[1] | ||||
|                 limitedQuery    = limitedQuery.replace(" (SELECT TOP %s" % startTopNums, " (SELECT TOP %d" % num) | ||||
| 
 | ||||
|         return limitedQuery | ||||
| 
 | ||||
|  |  | |||
|  | @ -30,7 +30,7 @@ import sys | |||
| 
 | ||||
| 
 | ||||
| # sqlmap version and site | ||||
| VERSION            = "0.6.4-rc3" | ||||
| VERSION            = "0.6.4-rc4" | ||||
| VERSION_STRING     = "sqlmap/%s" % VERSION | ||||
| SITE               = "http://sqlmap.sourceforge.net" | ||||
| 
 | ||||
|  | @ -73,6 +73,7 @@ MATCH_RATIO       = 0.9 | |||
| SQL_STATEMENTS    = { | ||||
|                       "SQL SELECT statement":  ( | ||||
|                              "select ", | ||||
|                              "select top ", | ||||
|                              " from ", | ||||
|                              " from dual", | ||||
|                              " where ", | ||||
|  |  | |||
|  | @ -131,7 +131,7 @@ def __goInferenceProxy(expression, fromUser=False, expected=None): | |||
|         return output | ||||
| 
 | ||||
|     if kb.dbmsDetected: | ||||
|         _, _, _, expressionFieldsList, expressionFields = agent.getFields(expression) | ||||
|         _, _, _, _, expressionFieldsList, expressionFields = agent.getFields(expression) | ||||
| 
 | ||||
|         if len(expressionFieldsList) > 1: | ||||
|             infoMsg  = "the SQL query provided has more than a field. " | ||||
|  | @ -159,7 +159,17 @@ def __goInferenceProxy(expression, fromUser=False, expected=None): | |||
|                     stopLimit = limitRegExp.group(int(limitGroupStop)) | ||||
|                     limitCond = int(stopLimit) > 1 | ||||
| 
 | ||||
|                 elif kb.dbms in ( "Oracle", "Microsoft SQL Server" ): | ||||
|                 elif kb.dbms == "Microsoft SQL Server": | ||||
|                     limitGroupStart = queries[kb.dbms].limitgroupstart | ||||
|                     limitGroupStop  = queries[kb.dbms].limitgroupstop | ||||
| 
 | ||||
|                     if limitGroupStart.isdigit(): | ||||
|                         startLimit = int(limitRegExp.group(int(limitGroupStart))) | ||||
| 
 | ||||
|                     stopLimit = limitRegExp.group(int(limitGroupStop)) | ||||
|                     limitCond = int(stopLimit) > 1 | ||||
| 
 | ||||
|                 elif kb.dbms == "Oracle": | ||||
|                     limitCond = False | ||||
|             else: | ||||
|                 limitCond = True | ||||
|  | @ -178,6 +188,9 @@ def __goInferenceProxy(expression, fromUser=False, expected=None): | |||
|                         untilLimitChar = expression.index(queries[kb.dbms].limitstring) | ||||
|                         expression = expression[:untilLimitChar] | ||||
| 
 | ||||
|                     elif kb.dbms == "Microsoft SQL Server": | ||||
|                         stopLimit += startLimit | ||||
| 
 | ||||
|                 if not stopLimit or stopLimit <= 1: | ||||
|                     if kb.dbms == "Oracle" and expression.endswith("FROM DUAL"): | ||||
|                         test = "n" | ||||
|  |  | |||
|  | @ -54,7 +54,7 @@ def bisection(payload, expression, length=None): | |||
|     finalValue      = "" | ||||
| 
 | ||||
|     if kb.dbmsDetected: | ||||
|         _, _, _, _, fieldToCastStr = agent.getFields(expression) | ||||
|         _, _, _, _, _, fieldToCastStr = agent.getFields(expression) | ||||
|         nulledCastedField             = agent.nullAndCastField(fieldToCastStr) | ||||
|         expressionReplaced            = expression.replace(fieldToCastStr, nulledCastedField, 1) | ||||
|         expressionUnescaped           = unescaper.unescape(expressionReplaced) | ||||
|  |  | |||
|  | @ -159,7 +159,7 @@ def unionUse(expression, direct=False, unescape=True, resetCounter=False): | |||
|                 conf.paramNegative = True | ||||
| 
 | ||||
|     if conf.paramNegative == True and direct == False: | ||||
|         _, _, _, expressionFieldsList, expressionFields = agent.getFields(origExpr) | ||||
|         _, _, _, _, expressionFieldsList, expressionFields = agent.getFields(origExpr) | ||||
| 
 | ||||
|         if len(expressionFieldsList) > 1: | ||||
|             infoMsg  = "the SQL query provided has more than a field. " | ||||
|  | @ -187,7 +187,17 @@ def unionUse(expression, direct=False, unescape=True, resetCounter=False): | |||
|                     stopLimit = limitRegExp.group(int(limitGroupStop)) | ||||
|                     limitCond = int(stopLimit) > 1 | ||||
| 
 | ||||
|                 elif kb.dbms in ( "Oracle", "Microsoft SQL Server" ): | ||||
|                 elif kb.dbms == "Microsoft SQL Server": | ||||
|                     limitGroupStart = queries[kb.dbms].limitgroupstart | ||||
|                     limitGroupStop  = queries[kb.dbms].limitgroupstop | ||||
| 
 | ||||
|                     if limitGroupStart.isdigit(): | ||||
|                         startLimit = int(limitRegExp.group(int(limitGroupStart))) | ||||
| 
 | ||||
|                     stopLimit = limitRegExp.group(int(limitGroupStop)) | ||||
|                     limitCond = int(stopLimit) > 1 | ||||
| 
 | ||||
|                 elif kb.dbms == "Oracle": | ||||
|                     limitCond = False | ||||
|             else: | ||||
|                 limitCond = True | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	Block a user