mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2025-03-14 15:14:31 +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
|
||||
# quotes in the payload
|
||||
if injection.dbms is not None:
|
||||
payload = unescape(payload, injection.dbms)
|
||||
payload = unescape(payload, dbms=injection.dbms)
|
||||
elif dbms is not None:
|
||||
payload = unescape(payload, dbms)
|
||||
payload = unescape(payload, dbms=dbms)
|
||||
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
|
||||
|
||||
|
@ -387,8 +389,7 @@ def checkSqlInjection(place, parameter, value):
|
|||
logger.warn(warnMsg)
|
||||
|
||||
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, dbmsToUnescape)
|
||||
reqPayload, vector = unionTest(comment, place, parameter, value, prefix, suffix)
|
||||
|
||||
if isinstance(reqPayload, basestring):
|
||||
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)
|
||||
|
||||
if getIdentifiedDBMS() == DBMS.MYSQL:
|
||||
if fieldsSelectCase:
|
||||
concatenatedQuery = concatenatedQuery.replace("SELECT ", "CONCAT('%s'," % kb.misc.start, 1)
|
||||
concatenatedQuery += ",'%s')" % kb.misc.stop
|
||||
elif fieldsSelectFrom:
|
||||
if fieldsSelectFrom:
|
||||
concatenatedQuery = concatenatedQuery.replace("SELECT ", "CONCAT('%s'," % kb.misc.start, 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 += ",'%s')" % kb.misc.stop
|
||||
elif fieldsNoSelect:
|
||||
concatenatedQuery = "CONCAT('%s',%s,'%s')" % (kb.misc.start, concatenatedQuery, kb.misc.stop)
|
||||
|
||||
elif getIdentifiedDBMS() in ( DBMS.PGSQL, DBMS.ORACLE, DBMS.SQLITE ):
|
||||
if fieldsSelectCase:
|
||||
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'||" % kb.misc.start, 1)
|
||||
concatenatedQuery += "||'%s'" % kb.misc.stop
|
||||
elif fieldsSelectFrom:
|
||||
if fieldsSelectFrom:
|
||||
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'||" % kb.misc.start, 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 += "||'%s'" % kb.misc.stop
|
||||
elif fieldsNoSelect:
|
||||
|
@ -455,13 +449,10 @@ class Agent:
|
|||
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(" 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:
|
||||
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'+" % kb.misc.start, 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 += "+'%s'" % kb.misc.stop
|
||||
elif fieldsNoSelect:
|
||||
|
@ -524,7 +515,7 @@ class Agent:
|
|||
inbandQuery += ", "
|
||||
|
||||
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 ")
|
||||
inbandQuery += query[:conditionIndex]
|
||||
else:
|
||||
|
@ -532,7 +523,7 @@ class Agent:
|
|||
else:
|
||||
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 ")
|
||||
inbandQuery += query[conditionIndex:]
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ from lib.core.unescaper import unescaper
|
|||
from lib.parse.html import htmlParser
|
||||
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
|
||||
vector = None
|
||||
|
||||
|
@ -38,7 +38,7 @@ def __unionPosition(comment, place, parameter, value, prefix, suffix, dbms, coun
|
|||
# Prepare expression with delimiters
|
||||
randQuery = randomStr()
|
||||
randQueryProcessed = agent.concatQuery("\'%s\'" % randQuery)
|
||||
randQueryUnescaped = unescaper.unescape(randQueryProcessed, dbms=dbms)
|
||||
randQueryUnescaped = unescaper.unescape(randQueryProcessed)
|
||||
|
||||
# Forge the inband SQL injection request
|
||||
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
|
||||
randQuery2 = randomStr()
|
||||
randQueryProcessed2 = agent.concatQuery("\'%s\'" % randQuery2)
|
||||
randQueryUnescaped2 = unescaper.unescape(randQueryProcessed2, dbms=dbms)
|
||||
randQueryUnescaped2 = unescaper.unescape(randQueryProcessed2)
|
||||
|
||||
# Confirm that it is a full inband SQL injection
|
||||
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
|
||||
|
||||
def __unionConfirm(comment, place, parameter, value, prefix, suffix, dbms, count):
|
||||
def __unionConfirm(comment, place, parameter, value, prefix, suffix, count):
|
||||
validPayload = None
|
||||
vector = None
|
||||
|
||||
# Confirm the inband SQL injection and get the exact column
|
||||
# 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
|
||||
# SQL injection position
|
||||
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
|
||||
|
||||
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
|
||||
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))
|
||||
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:
|
||||
break
|
||||
|
@ -120,7 +120,7 @@ def __unionTestByCharBruteforce(comment, place, parameter, value, prefix, suffix
|
|||
|
||||
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
|
||||
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
|
||||
|
||||
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:
|
||||
validPayload = agent.removePayloadDelimiters(validPayload, False)
|
||||
|
|
|
@ -67,7 +67,7 @@ def unionUse(expression, direct=False, unescape=True, resetCounter=False, unpack
|
|||
# entry per time
|
||||
# NOTE: I assume that only queries that get data from a table can
|
||||
# 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)
|
||||
|
||||
if limitRegExp:
|
||||
|
|
Loading…
Reference in New Issue
Block a user