mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2025-06-09 15:43:04 +03:00
sqlmap premiere of blind time based query/bisection
This commit is contained in:
parent
ad00fe13c1
commit
b5e45939e3
|
@ -99,9 +99,9 @@ def __goInferenceProxy(expression, fromUser=False, expected=None, batch=False, r
|
||||||
parameter through a bisection algorithm.
|
parameter through a bisection algorithm.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if kb.injection.data[1].vector is not None:
|
if kb.technique and kb.injection.data[kb.technique].vector is not None:
|
||||||
vector = agent.cleanupPayload(kb.injection.data[1].vector)
|
vector = agent.cleanupPayload(kb.injection.data[kb.technique].vector)
|
||||||
kb.pageTemplate = getPageTemplate(kb.injection.data[1].templatePayload, kb.injection.place)
|
kb.pageTemplate = getPageTemplate(kb.injection.data[kb.technique].templatePayload, kb.injection.place)
|
||||||
else:
|
else:
|
||||||
vector = queries[kb.misc.testedDbms].inference.query
|
vector = queries[kb.misc.testedDbms].inference.query
|
||||||
kb.pageTemplate = kb.originalPage
|
kb.pageTemplate = kb.originalPage
|
||||||
|
@ -336,6 +336,72 @@ def __goError(expression, resumeValue=True):
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
def __goTimeBlind(expression, resumeValue=True):
|
||||||
|
"""
|
||||||
|
Retrieve the output of a SQL query taking advantage of an error-based
|
||||||
|
SQL injection vulnerability on the affected parameter.
|
||||||
|
"""
|
||||||
|
|
||||||
|
result = None
|
||||||
|
|
||||||
|
if conf.direct:
|
||||||
|
return direct(expression), None
|
||||||
|
|
||||||
|
condition = (
|
||||||
|
kb.resumedQueries and conf.url in kb.resumedQueries.keys()
|
||||||
|
and expression in kb.resumedQueries[conf.url].keys()
|
||||||
|
)
|
||||||
|
|
||||||
|
if condition and resumeValue:
|
||||||
|
result = resume(expression, None)
|
||||||
|
|
||||||
|
if not result:
|
||||||
|
result = timeBlindUse(expression)
|
||||||
|
dataToSessionFile("[%s][%s][%s][%s][%s]\n" % (conf.url, kb.injection.place, conf.parameters[kb.injection.place], expression, replaceNewlineTabs(result)))
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
def timeBlindUse(expression):
|
||||||
|
"""
|
||||||
|
Retrieve the output of a SQL query taking advantage of an error SQL
|
||||||
|
injection vulnerability on the affected parameter.
|
||||||
|
"""
|
||||||
|
|
||||||
|
output = None
|
||||||
|
import pdb
|
||||||
|
pdb.set_trace()
|
||||||
|
vector = agent.cleanupPayload(kb.injection.data[5].vector)
|
||||||
|
query = unescaper.unescape(vector)
|
||||||
|
query = agent.prefixQuery(query)
|
||||||
|
query = agent.suffixQuery(query)
|
||||||
|
check = "%s(?P<result>.*?)%s" % (kb.misc.start, kb.misc.stop)
|
||||||
|
|
||||||
|
_, _, _, _, _, _, fieldToCastStr = agent.getFields(expression)
|
||||||
|
nulledCastedField = agent.nullAndCastField(fieldToCastStr)
|
||||||
|
|
||||||
|
if kb.dbms == DBMS.MYSQL:
|
||||||
|
nulledCastedField = nulledCastedField.replace("AS CHAR)", "AS CHAR(100))") # fix for that 'Subquery returns more than 1 row'
|
||||||
|
|
||||||
|
expression = expression.replace(fieldToCastStr, nulledCastedField, 1)
|
||||||
|
expression = unescaper.unescape(expression)
|
||||||
|
expression = safeStringFormat(query, expression)
|
||||||
|
|
||||||
|
debugMsg = "query: %s" % expression
|
||||||
|
logger.debug(debugMsg)
|
||||||
|
|
||||||
|
payload = agent.payload(newValue=expression)
|
||||||
|
reqBody, _ = Request.queryPage(payload, content=True)
|
||||||
|
output = extractRegexResult(check, reqBody, re.DOTALL | re.IGNORECASE)
|
||||||
|
|
||||||
|
if output:
|
||||||
|
output = output.replace(kb.misc.space, " ")
|
||||||
|
|
||||||
|
if conf.verbose > 0:
|
||||||
|
infoMsg = "retrieved: %s" % replaceNewlineTabs(output, stdout=True)
|
||||||
|
logger.info(infoMsg)
|
||||||
|
|
||||||
|
return output
|
||||||
|
|
||||||
def __goInband(expression, expected=None, sort=True, resumeValue=True, unpack=True, dump=False):
|
def __goInband(expression, expected=None, sort=True, resumeValue=True, unpack=True, dump=False):
|
||||||
"""
|
"""
|
||||||
Retrieve the output of a SQL query taking advantage of an inband SQL
|
Retrieve the output of a SQL query taking advantage of an inband SQL
|
||||||
|
@ -365,7 +431,7 @@ def __goInband(expression, expected=None, sort=True, resumeValue=True, unpack=Tr
|
||||||
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def getValue(expression, blind=True, inband=True, error=True, fromUser=False, expected=None, batch=False, unpack=True, sort=True, resumeValue=True, charsetType=None, firstChar=None, lastChar=None, dump=False, suppressOutput=False):
|
def getValue(expression, blind=True, inband=True, error=True, time=True, fromUser=False, expected=None, batch=False, unpack=True, sort=True, resumeValue=True, charsetType=None, firstChar=None, lastChar=None, dump=False, suppressOutput=False):
|
||||||
"""
|
"""
|
||||||
Called each time sqlmap inject a SQL query on the SQL injection
|
Called each time sqlmap inject a SQL query on the SQL injection
|
||||||
affected parameter. It can call a function to retrieve the output
|
affected parameter. It can call a function to retrieve the output
|
||||||
|
@ -379,7 +445,7 @@ def getValue(expression, blind=True, inband=True, error=True, fromUser=False, ex
|
||||||
|
|
||||||
if conf.direct:
|
if conf.direct:
|
||||||
value = direct(expression)
|
value = direct(expression)
|
||||||
elif kb.booleanTest is not None or kb.errorTest is not None or kb.unionTest is not None:
|
elif kb.booleanTest is not None or kb.errorTest is not None or kb.unionTest is not None or kb.timeTest is not None:
|
||||||
expression = cleanQuery(expression)
|
expression = cleanQuery(expression)
|
||||||
expression = expandAsteriskForColumns(expression)
|
expression = expandAsteriskForColumns(expression)
|
||||||
value = None
|
value = None
|
||||||
|
@ -412,6 +478,10 @@ def getValue(expression, blind=True, inband=True, error=True, fromUser=False, ex
|
||||||
kb.technique = 1
|
kb.technique = 1
|
||||||
value = __goInferenceProxy(expression, fromUser, expected, batch, resumeValue, unpack, charsetType, firstChar, lastChar)
|
value = __goInferenceProxy(expression, fromUser, expected, batch, resumeValue, unpack, charsetType, firstChar, lastChar)
|
||||||
|
|
||||||
|
if time and kb.timeTest and not value:
|
||||||
|
kb.technique = 5
|
||||||
|
value = __goInferenceProxy(expression, fromUser, expected, batch, resumeValue, unpack, charsetType, firstChar, lastChar)
|
||||||
|
|
||||||
kb.unionNegative = oldParamNegative
|
kb.unionNegative = oldParamNegative
|
||||||
|
|
||||||
if value and isinstance(value, basestring):
|
if value and isinstance(value, basestring):
|
||||||
|
|
|
@ -44,6 +44,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
|
||||||
partialValue = ""
|
partialValue = ""
|
||||||
finalValue = ""
|
finalValue = ""
|
||||||
asciiTbl = getCharset(charsetType)
|
asciiTbl = getCharset(charsetType)
|
||||||
|
timeBasedCompare = (kb.technique == 5)
|
||||||
|
|
||||||
# Set kb.partRun in case "common prediction" feature (a.k.a. "good
|
# Set kb.partRun in case "common prediction" feature (a.k.a. "good
|
||||||
# samaritan") is used
|
# samaritan") is used
|
||||||
|
@ -122,7 +123,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
|
||||||
|
|
||||||
forgedPayload = safeStringFormat(payload.replace('%3E', '%3D'), (expressionUnescaped, idx, posValue))
|
forgedPayload = safeStringFormat(payload.replace('%3E', '%3D'), (expressionUnescaped, idx, posValue))
|
||||||
queriesCount[0] += 1
|
queriesCount[0] += 1
|
||||||
result = Request.queryPage(forgedPayload)
|
result = Request.queryPage(forgedPayload, timeBasedCompare=timeBasedCompare)
|
||||||
|
|
||||||
if result:
|
if result:
|
||||||
return hintValue[idx-1]
|
return hintValue[idx-1]
|
||||||
|
@ -153,7 +154,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
|
||||||
if len(charTbl) == 1:
|
if len(charTbl) == 1:
|
||||||
forgedPayload = safeStringFormat(payload.replace('%3E', '%3D'), (expressionUnescaped, idx, charTbl[0]))
|
forgedPayload = safeStringFormat(payload.replace('%3E', '%3D'), (expressionUnescaped, idx, charTbl[0]))
|
||||||
queriesCount[0] += 1
|
queriesCount[0] += 1
|
||||||
result = Request.queryPage(forgedPayload)
|
result = Request.queryPage(forgedPayload, timeBasedCompare=timeBasedCompare)
|
||||||
|
|
||||||
if result:
|
if result:
|
||||||
return chr(charTbl[0]) if charTbl[0] < 128 else unichr(charTbl[0])
|
return chr(charTbl[0]) if charTbl[0] < 128 else unichr(charTbl[0])
|
||||||
|
@ -174,7 +175,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
|
||||||
forgedPayload = safeStringFormat(payload, (expressionUnescaped, idx, posValue))
|
forgedPayload = safeStringFormat(payload, (expressionUnescaped, idx, posValue))
|
||||||
|
|
||||||
queriesCount[0] += 1
|
queriesCount[0] += 1
|
||||||
result = Request.queryPage(forgedPayload)
|
result = Request.queryPage(forgedPayload, timeBasedCompare=timeBasedCompare)
|
||||||
|
|
||||||
if kb.dbms in (DBMS.SQLITE, DBMS.MAXDB):
|
if kb.dbms in (DBMS.SQLITE, DBMS.MAXDB):
|
||||||
posValue = popValue()
|
posValue = popValue()
|
||||||
|
@ -226,7 +227,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
|
||||||
for retVal in (originalTbl[originalTbl.index(minValue)], originalTbl[originalTbl.index(minValue) + 1]):
|
for retVal in (originalTbl[originalTbl.index(minValue)], originalTbl[originalTbl.index(minValue) + 1]):
|
||||||
forgedPayload = safeStringFormat(payload.replace('%3E', '%3D'), (expressionUnescaped, idx, retVal))
|
forgedPayload = safeStringFormat(payload.replace('%3E', '%3D'), (expressionUnescaped, idx, retVal))
|
||||||
queriesCount[0] += 1
|
queriesCount[0] += 1
|
||||||
result = Request.queryPage(forgedPayload)
|
result = Request.queryPage(forgedPayload, timeBasedCompare=timeBasedCompare)
|
||||||
|
|
||||||
if result:
|
if result:
|
||||||
return chr(retVal) if retVal < 128 else unichr(retVal)
|
return chr(retVal) if retVal < 128 else unichr(retVal)
|
||||||
|
@ -444,7 +445,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
|
||||||
query = agent.prefixQuery(safeStringFormat("AND (%s) = %s", (expressionUnescaped, testValue)))
|
query = agent.prefixQuery(safeStringFormat("AND (%s) = %s", (expressionUnescaped, testValue)))
|
||||||
query = agent.suffixQuery(query)
|
query = agent.suffixQuery(query)
|
||||||
queriesCount[0] += 1
|
queriesCount[0] += 1
|
||||||
result = Request.queryPage(agent.payload(newValue=query))
|
result = Request.queryPage(agent.payload(newValue=query), timeBasedCompare=timeBasedCompare)
|
||||||
|
|
||||||
# Did we have luck?
|
# Did we have luck?
|
||||||
if result:
|
if result:
|
||||||
|
@ -468,7 +469,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
|
||||||
query = agent.prefixQuery(safeStringFormat("AND (%s) = %s", (subquery, testValue)))
|
query = agent.prefixQuery(safeStringFormat("AND (%s) = %s", (subquery, testValue)))
|
||||||
query = agent.suffixQuery(query)
|
query = agent.suffixQuery(query)
|
||||||
queriesCount[0] += 1
|
queriesCount[0] += 1
|
||||||
result = Request.queryPage(agent.payload(newValue=query))
|
result = Request.queryPage(agent.payload(newValue=query), timeBasedCompare=timeBasedCompare)
|
||||||
|
|
||||||
# Did we have luck?
|
# Did we have luck?
|
||||||
if result:
|
if result:
|
||||||
|
|
Loading…
Reference in New Issue
Block a user