mirror of
				https://github.com/sqlmapproject/sqlmap.git
				synced 2025-11-04 01:47:37 +03:00 
			
		
		
		
	Major bug fix.
Minor code refactoring.
This commit is contained in:
		
							parent
							
								
									c0d5daee99
								
							
						
					
					
						commit
						0fc4ebdc1b
					
				| 
						 | 
					@ -72,11 +72,13 @@ def unescapeDbms(payload, injection, dbms):
 | 
				
			||||||
    # provided a DBMS (conf.dbms), unescape the strings between single
 | 
					    # provided a DBMS (conf.dbms), unescape the strings between single
 | 
				
			||||||
    # quotes in the payload
 | 
					    # quotes in the payload
 | 
				
			||||||
    if injection.dbms is not None:
 | 
					    if injection.dbms is not None:
 | 
				
			||||||
        payload = unescape(payload, injection.dbms)
 | 
					        payload = unescape(payload, dbms=injection.dbms)
 | 
				
			||||||
    elif dbms is not None:
 | 
					    elif dbms is not None:
 | 
				
			||||||
        payload = unescape(payload, dbms)
 | 
					        payload = unescape(payload, dbms=dbms)
 | 
				
			||||||
    elif conf.dbms is not None:
 | 
					    elif conf.dbms is not None:
 | 
				
			||||||
        payload = unescape(payload, conf.dbms)
 | 
					        payload = unescape(payload, dbms=conf.dbms)
 | 
				
			||||||
 | 
					    elif getIdentifiedDBMS() is not None:
 | 
				
			||||||
 | 
					        payload = unescape(payload, dbms=getIdentifiedDBMS())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return payload
 | 
					    return payload
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -387,8 +389,7 @@ def checkSqlInjection(place, parameter, value):
 | 
				
			||||||
                                logger.warn(warnMsg)
 | 
					                                logger.warn(warnMsg)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                            configUnion(test.request.char, test.request.columns)
 | 
					                            configUnion(test.request.char, test.request.columns)
 | 
				
			||||||
                            dbmsToUnescape = kb.misc.fpDbms if kb.misc.fpDbms is not None else injection.dbms
 | 
					                            reqPayload, vector = unionTest(comment, place, parameter, value, prefix, suffix)
 | 
				
			||||||
                            reqPayload, vector = unionTest(comment, place, parameter, value, prefix, suffix, dbmsToUnescape)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                            if isinstance(reqPayload, basestring):
 | 
					                            if isinstance(reqPayload, basestring):
 | 
				
			||||||
                                infoMsg = "%s parameter '%s' is '%s' injectable" % (place, parameter, title)
 | 
					                                infoMsg = "%s parameter '%s' is '%s' injectable" % (place, parameter, title)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -422,26 +422,20 @@ class Agent:
 | 
				
			||||||
            fieldsSelectFrom, fieldsSelect, fieldsNoSelect, fieldsSelectTop, fieldsSelectCase, _, fieldsToCastStr = self.getFields(query)
 | 
					            fieldsSelectFrom, fieldsSelect, fieldsNoSelect, fieldsSelectTop, fieldsSelectCase, _, fieldsToCastStr = self.getFields(query)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if getIdentifiedDBMS() == DBMS.MYSQL:
 | 
					        if getIdentifiedDBMS() == DBMS.MYSQL:
 | 
				
			||||||
            if fieldsSelectCase:
 | 
					            if fieldsSelectFrom:
 | 
				
			||||||
                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:
 | 
					            elif (fieldsSelect, fieldsSelectCase):
 | 
				
			||||||
                concatenatedQuery  = concatenatedQuery.replace("SELECT ", "CONCAT('%s'," % kb.misc.start, 1)
 | 
					                concatenatedQuery  = concatenatedQuery.replace("SELECT ", "CONCAT('%s'," % kb.misc.start, 1)
 | 
				
			||||||
                concatenatedQuery += ",'%s')" % kb.misc.stop
 | 
					                concatenatedQuery += ",'%s')" % kb.misc.stop
 | 
				
			||||||
            elif fieldsNoSelect:
 | 
					            elif fieldsNoSelect:
 | 
				
			||||||
                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 fieldsSelectCase:
 | 
					            if fieldsSelectFrom:
 | 
				
			||||||
                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:
 | 
					            elif (fieldsSelect, fieldsSelectCase):
 | 
				
			||||||
                concatenatedQuery  = concatenatedQuery.replace("SELECT ", "'%s'||" % kb.misc.start, 1)
 | 
					                concatenatedQuery  = concatenatedQuery.replace("SELECT ", "'%s'||" % kb.misc.start, 1)
 | 
				
			||||||
                concatenatedQuery += "||'%s'" % kb.misc.stop
 | 
					                concatenatedQuery += "||'%s'" % kb.misc.stop
 | 
				
			||||||
            elif fieldsNoSelect:
 | 
					            elif fieldsNoSelect:
 | 
				
			||||||
| 
						 | 
					@ -455,13 +449,10 @@ class Agent:
 | 
				
			||||||
                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)
 | 
				
			||||||
            elif fieldsSelectCase:
 | 
					 | 
				
			||||||
                concatenatedQuery  = concatenatedQuery.replace("SELECT ", "'%s'+" % kb.misc.start, 1)
 | 
					 | 
				
			||||||
                concatenatedQuery += "+'%s'" % kb.misc.stop
 | 
					 | 
				
			||||||
            elif fieldsSelectFrom:
 | 
					            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:
 | 
					            elif (fieldsSelect, fieldsSelectCase):
 | 
				
			||||||
                concatenatedQuery  = concatenatedQuery.replace("SELECT ", "'%s'+" % kb.misc.start, 1)
 | 
					                concatenatedQuery  = concatenatedQuery.replace("SELECT ", "'%s'+" % kb.misc.start, 1)
 | 
				
			||||||
                concatenatedQuery += "+'%s'" % kb.misc.stop
 | 
					                concatenatedQuery += "+'%s'" % kb.misc.stop
 | 
				
			||||||
            elif fieldsNoSelect:
 | 
					            elif fieldsNoSelect:
 | 
				
			||||||
| 
						 | 
					@ -524,7 +515,7 @@ class Agent:
 | 
				
			||||||
                inbandQuery += ", "
 | 
					                inbandQuery += ", "
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if element == position:
 | 
					            if element == position:
 | 
				
			||||||
                if " FROM " in query and "EXISTS(" not in query and not query.startswith("SELECT ") and "(CASE WHEN (" not in query:
 | 
					                if " FROM " in query and "EXISTS(" not in query and not query.startswith("SELECT "):
 | 
				
			||||||
                    conditionIndex = query.index(" FROM ")
 | 
					                    conditionIndex = query.index(" FROM ")
 | 
				
			||||||
                    inbandQuery += query[:conditionIndex]
 | 
					                    inbandQuery += query[:conditionIndex]
 | 
				
			||||||
                else:
 | 
					                else:
 | 
				
			||||||
| 
						 | 
					@ -532,7 +523,7 @@ class Agent:
 | 
				
			||||||
            else:
 | 
					            else:
 | 
				
			||||||
                inbandQuery += char
 | 
					                inbandQuery += char
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if " FROM " in query and "EXISTS(" not in query and not query.startswith("SELECT ") and "(CASE WHEN (" not in query:
 | 
					        if " FROM " in query and "EXISTS(" not in query and not query.startswith("SELECT "):
 | 
				
			||||||
            conditionIndex = query.index(" FROM ")
 | 
					            conditionIndex = query.index(" FROM ")
 | 
				
			||||||
            inbandQuery += query[conditionIndex:]
 | 
					            inbandQuery += query[conditionIndex:]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -27,7 +27,7 @@ from lib.core.unescaper import unescaper
 | 
				
			||||||
from lib.parse.html import htmlParser
 | 
					from lib.parse.html import htmlParser
 | 
				
			||||||
from lib.request.connect import Connect as Request
 | 
					from lib.request.connect import Connect as Request
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def __unionPosition(comment, place, parameter, value, prefix, suffix, dbms, count, where=1):
 | 
					def __unionPosition(comment, place, parameter, value, prefix, suffix, count, where=1):
 | 
				
			||||||
    validPayload = None
 | 
					    validPayload = None
 | 
				
			||||||
    vector = None
 | 
					    vector = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -38,7 +38,7 @@ def __unionPosition(comment, place, parameter, value, prefix, suffix, dbms, coun
 | 
				
			||||||
        # Prepare expression with delimiters
 | 
					        # Prepare expression with delimiters
 | 
				
			||||||
        randQuery = randomStr()
 | 
					        randQuery = randomStr()
 | 
				
			||||||
        randQueryProcessed = agent.concatQuery("\'%s\'" % randQuery)
 | 
					        randQueryProcessed = agent.concatQuery("\'%s\'" % randQuery)
 | 
				
			||||||
        randQueryUnescaped = unescaper.unescape(randQueryProcessed, dbms=dbms)
 | 
					        randQueryUnescaped = unescaper.unescape(randQueryProcessed)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Forge the inband SQL injection request
 | 
					        # Forge the inband SQL injection request
 | 
				
			||||||
        query = agent.forgeInbandQuery(randQueryUnescaped, position, count, comment, prefix, suffix, conf.uChar)
 | 
					        query = agent.forgeInbandQuery(randQueryUnescaped, position, count, comment, prefix, suffix, conf.uChar)
 | 
				
			||||||
| 
						 | 
					@ -55,7 +55,7 @@ def __unionPosition(comment, place, parameter, value, prefix, suffix, dbms, coun
 | 
				
			||||||
                # Prepare expression with delimiters
 | 
					                # Prepare expression with delimiters
 | 
				
			||||||
                randQuery2 = randomStr()
 | 
					                randQuery2 = randomStr()
 | 
				
			||||||
                randQueryProcessed2 = agent.concatQuery("\'%s\'" % randQuery2)
 | 
					                randQueryProcessed2 = agent.concatQuery("\'%s\'" % randQuery2)
 | 
				
			||||||
                randQueryUnescaped2 = unescaper.unescape(randQueryProcessed2, dbms=dbms)
 | 
					                randQueryUnescaped2 = unescaper.unescape(randQueryProcessed2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                # Confirm that it is a full inband SQL injection
 | 
					                # Confirm that it is a full inband SQL injection
 | 
				
			||||||
                query = agent.forgeInbandQuery(randQueryUnescaped, position, count, comment, prefix, suffix, conf.uChar, multipleUnions=randQueryUnescaped2)
 | 
					                query = agent.forgeInbandQuery(randQueryUnescaped, position, count, comment, prefix, suffix, conf.uChar, multipleUnions=randQueryUnescaped2)
 | 
				
			||||||
| 
						 | 
					@ -71,22 +71,22 @@ def __unionPosition(comment, place, parameter, value, prefix, suffix, dbms, coun
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return validPayload, vector
 | 
					    return validPayload, vector
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def __unionConfirm(comment, place, parameter, value, prefix, suffix, dbms, count):
 | 
					def __unionConfirm(comment, place, parameter, value, prefix, suffix, count):
 | 
				
			||||||
    validPayload = None
 | 
					    validPayload = None
 | 
				
			||||||
    vector = None
 | 
					    vector = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Confirm the inband SQL injection and get the exact column
 | 
					    # Confirm the inband SQL injection and get the exact column
 | 
				
			||||||
    # position which can be used to extract data
 | 
					    # position which can be used to extract data
 | 
				
			||||||
    validPayload, vector = __unionPosition(comment, place, parameter, value, prefix, suffix, dbms, count)
 | 
					    validPayload, vector = __unionPosition(comment, place, parameter, value, prefix, suffix, count)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Assure that the above function found the exploitable full inband
 | 
					    # Assure that the above function found the exploitable full inband
 | 
				
			||||||
    # SQL injection position
 | 
					    # SQL injection position
 | 
				
			||||||
    if not validPayload:
 | 
					    if not validPayload:
 | 
				
			||||||
        validPayload, vector = __unionPosition(comment, place, parameter, value, prefix, suffix, dbms, count, where=2)
 | 
					        validPayload, vector = __unionPosition(comment, place, parameter, value, prefix, suffix, count, where=2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return validPayload, vector
 | 
					    return validPayload, vector
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def __unionTestByCharBruteforce(comment, place, parameter, value, prefix, suffix, dbms):
 | 
					def __unionTestByCharBruteforce(comment, place, parameter, value, prefix, suffix):
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    This method tests if the target url is affected by an inband
 | 
					    This method tests if the target url is affected by an inband
 | 
				
			||||||
    SQL injection vulnerability. The test is done up to 50 columns
 | 
					    SQL injection vulnerability. The test is done up to 50 columns
 | 
				
			||||||
| 
						 | 
					@ -111,7 +111,7 @@ def __unionTestByCharBruteforce(comment, place, parameter, value, prefix, suffix
 | 
				
			||||||
        debugMsg = "testing %s columns (%d%%)" % (status, round(100.0*count/conf.uColsStop))
 | 
					        debugMsg = "testing %s columns (%d%%)" % (status, round(100.0*count/conf.uColsStop))
 | 
				
			||||||
        logger.debug(debugMsg)
 | 
					        logger.debug(debugMsg)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        validPayload, vector = __unionConfirm(comment, place, parameter, value, prefix, suffix, dbms, count)
 | 
					        validPayload, vector = __unionConfirm(comment, place, parameter, value, prefix, suffix, count)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if validPayload:
 | 
					        if validPayload:
 | 
				
			||||||
            break
 | 
					            break
 | 
				
			||||||
| 
						 | 
					@ -120,7 +120,7 @@ def __unionTestByCharBruteforce(comment, place, parameter, value, prefix, suffix
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return validPayload, vector
 | 
					    return validPayload, vector
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def unionTest(comment, place, parameter, value, prefix, suffix, dbms):
 | 
					def unionTest(comment, place, parameter, value, prefix, suffix):
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    This method tests if the target url is affected by an inband
 | 
					    This method tests if the target url is affected by an inband
 | 
				
			||||||
    SQL injection vulnerability. The test is done up to 3*50 times
 | 
					    SQL injection vulnerability. The test is done up to 3*50 times
 | 
				
			||||||
| 
						 | 
					@ -130,7 +130,7 @@ def unionTest(comment, place, parameter, value, prefix, suffix, dbms):
 | 
				
			||||||
        return
 | 
					        return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    kb.technique = PAYLOAD.TECHNIQUE.UNION
 | 
					    kb.technique = PAYLOAD.TECHNIQUE.UNION
 | 
				
			||||||
    validPayload, vector = __unionTestByCharBruteforce(comment, place, parameter, value, prefix, suffix, dbms)
 | 
					    validPayload, vector = __unionTestByCharBruteforce(comment, place, parameter, value, prefix, suffix)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if validPayload:
 | 
					    if validPayload:
 | 
				
			||||||
        validPayload = agent.removePayloadDelimiters(validPayload, False)
 | 
					        validPayload = agent.removePayloadDelimiters(validPayload, False)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -67,7 +67,7 @@ def unionUse(expression, direct=False, unescape=True, resetCounter=False, unpack
 | 
				
			||||||
        # entry per time
 | 
					        # entry per time
 | 
				
			||||||
        # NOTE: I assume that only queries that get data from a table can
 | 
					        # NOTE: I assume that only queries that get data from a table can
 | 
				
			||||||
        # return multiple entries
 | 
					        # return multiple entries
 | 
				
			||||||
        if " FROM " in expression and "EXISTS(" not in expression:
 | 
					        if " FROM " in expression.upper() and " FROM DUAL" not in expression.upper() and "EXISTS(" not in expression.upper():
 | 
				
			||||||
            limitRegExp = re.search(queries[getIdentifiedDBMS()].limitregexp.query, expression, re.I)
 | 
					            limitRegExp = re.search(queries[getIdentifiedDBMS()].limitregexp.query, expression, re.I)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if limitRegExp:
 | 
					            if limitRegExp:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user