mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2024-11-25 19:13:48 +03:00
OR based inference works for the first time in history and fingerprint of 4 major DBMSes is now injection based (instead of AND)
This commit is contained in:
parent
e4b51dd549
commit
d77ddbee47
|
@ -263,14 +263,12 @@ def checkSqlInjection(place, parameter, value):
|
|||
# test's <where> tag
|
||||
if where == 1:
|
||||
origValue = value
|
||||
kb.pageTemplate = kb.originalPage
|
||||
elif where == 2:
|
||||
origValue = "-%s" % randomInt()
|
||||
|
||||
# Save original page template and replace with current one
|
||||
# Use different page template than the original one
|
||||
# as we are changing parameters value, which will result
|
||||
# most definitely with a different "page template" used by the
|
||||
# comparison engine
|
||||
pushValue(kb.pageTemplate)
|
||||
# most definitely with a different content
|
||||
kb.pageTemplate, _ = Request.queryPage(agent.payload(place, parameter, value, origValue), place, content=True)
|
||||
elif where == 3:
|
||||
origValue = ""
|
||||
|
@ -362,10 +360,6 @@ def checkSqlInjection(place, parameter, value):
|
|||
# Restore old value of socket timeout
|
||||
socket.setdefaulttimeout(popValue())
|
||||
|
||||
# Restore page template
|
||||
if where == 2:
|
||||
kb.pageTemplate = popValue()
|
||||
|
||||
# If the injection test was successful feed the injection
|
||||
# object with the test's details
|
||||
if injectable is True:
|
||||
|
@ -395,6 +389,7 @@ def checkSqlInjection(place, parameter, value):
|
|||
injection.data[stype].where = where
|
||||
injection.data[stype].vector = vector
|
||||
injection.data[stype].comment = comment
|
||||
injection.data[stype].pageTemplate = kb.pageTemplate
|
||||
|
||||
if "details" in test:
|
||||
for detailKey, detailValue in test.details.items():
|
||||
|
@ -562,7 +557,7 @@ def checkStability():
|
|||
infoMsg = "testing if the url is stable, wait a few seconds"
|
||||
logger.info(infoMsg)
|
||||
|
||||
firstPage = kb.pageTemplate # set inside checkConnection()
|
||||
firstPage = kb.originalPage # set inside checkConnection()
|
||||
time.sleep(1)
|
||||
secondPage, _ = Request.queryPage(content=True)
|
||||
|
||||
|
@ -758,7 +753,7 @@ def checkConnection(suppressOutput=False):
|
|||
start = time.time()
|
||||
page, _ = Request.queryPage(content=True)
|
||||
kb.responseTime = time.time() - start
|
||||
kb.pageTemplate = page
|
||||
kb.originalPage = kb.pageTemplate = page
|
||||
except sqlmapConnectionException, errMsg:
|
||||
errMsg = getUnicode(errMsg)
|
||||
raise sqlmapConnectionException, errMsg
|
||||
|
|
|
@ -209,13 +209,17 @@ class Agent:
|
|||
|
||||
payload = payload.replace("[ORIGVALUE]", origvalue)
|
||||
|
||||
if kb.dbms is not None:
|
||||
inferenceQuery = queries[kb.dbms].inference.query
|
||||
payload = payload.replace("[INFERENCE]", inferenceQuery)
|
||||
elif "[INFERENCE]" in payload:
|
||||
errMsg = "invalid usage of inference payload without knowledge "
|
||||
errMsg += "of underlying DBMS"
|
||||
raise sqlmapNoneDataException, errMsg
|
||||
if "[INFERENCE]" in payload:
|
||||
if kb.dbms is not None:
|
||||
inferenceQuery = queries[kb.dbms].inference.query
|
||||
payload = payload.replace("[INFERENCE]", inferenceQuery)
|
||||
elif kb.misc.testedDbms is not None:
|
||||
inferenceQuery = queries[kb.misc.testedDbms].inference.query
|
||||
payload = payload.replace("[INFERENCE]", inferenceQuery)
|
||||
else:
|
||||
errMsg = "invalid usage of inference payload without knowledge "
|
||||
errMsg += "of underlying DBMS"
|
||||
raise sqlmapNoneDataException, errMsg
|
||||
|
||||
return payload
|
||||
|
||||
|
@ -659,7 +663,7 @@ class Agent:
|
|||
@rtype: C{str}
|
||||
"""
|
||||
|
||||
return queries[kb.dbms].case.query % expression
|
||||
return queries[kb.dbms if kb.dbms else kb.misc.testedDbms].case.query % expression
|
||||
|
||||
def addPayloadDelimiters(self, inpStr):
|
||||
"""
|
||||
|
|
|
@ -1159,6 +1159,7 @@ def __setKnowledgeBaseAttributes():
|
|||
|
||||
kb.nullConnection = None
|
||||
kb.pageTemplate = None
|
||||
kb.originalPage = None
|
||||
|
||||
# Back-end DBMS underlying operating system fingerprint via banner (-b)
|
||||
# parsing
|
||||
|
|
|
@ -100,8 +100,10 @@ def __goInferenceProxy(expression, fromUser=False, expected=None, batch=False, r
|
|||
|
||||
if kb.injection.data[1].vector is not None:
|
||||
vector = agent.cleanupPayload(kb.injection.data[1].vector)
|
||||
kb.pageTemplate = kb.injection.data[1].pageTemplate
|
||||
else:
|
||||
vector = queries[kb.misc.testedDbms].inference.query
|
||||
kb.pageTemplate = kb.originalPage
|
||||
|
||||
query = agent.prefixQuery(vector)
|
||||
query = agent.suffixQuery(query)
|
||||
|
@ -441,3 +443,6 @@ def goStacked(expression, silent=False):
|
|||
page, _ = Request.queryPage(payload, content=True, silent=silent)
|
||||
|
||||
return payload, page
|
||||
|
||||
def checkBooleanExpression(expression):
|
||||
return getValue(agent.forgeCaseStatement(expression), expected="int", charsetType=1) == "1"
|
||||
|
|
|
@ -92,8 +92,7 @@ class Fingerprint(GenericFingerprint):
|
|||
result = True
|
||||
else:
|
||||
randInt = randomInt()
|
||||
payload = agent.fullPayload("AND BINARY_CHECKSUM(%d)=BINARY_CHECKSUM(%d)" % (randInt, randInt))
|
||||
result = Request.queryPage(payload)
|
||||
result = inject.checkBooleanExpression("BINARY_CHECKSUM(%d)=BINARY_CHECKSUM(%d)" % (randInt, randInt))
|
||||
|
||||
if result:
|
||||
infoMsg = "confirming Microsoft SQL Server"
|
||||
|
@ -101,13 +100,12 @@ class Fingerprint(GenericFingerprint):
|
|||
|
||||
for version in (0, 5, 8):
|
||||
randInt = randomInt()
|
||||
query = "AND %d=(SELECT (CASE WHEN (( SUBSTRING((@@VERSION), 22, 1)=2 AND SUBSTRING((@@VERSION), 25, 1)=%d ) OR ( SUBSTRING((@@VERSION), 23, 1)=2 AND SUBSTRING((@@VERSION), 26, 1)=%d )) THEN %d ELSE %d END))" % (randInt, version, version, randInt, (randInt + 1))
|
||||
check = "%d=(SELECT (CASE WHEN (( SUBSTRING((@@VERSION), 22, 1)=2 AND SUBSTRING((@@VERSION), 25, 1)=%d ) OR ( SUBSTRING((@@VERSION), 23, 1)=2 AND SUBSTRING((@@VERSION), 26, 1)=%d )) THEN %d ELSE %d END))" % (randInt, version, version, randInt, (randInt + 1))
|
||||
|
||||
if conf.direct:
|
||||
query = query.replace("AND ", "SELECT 1 WHERE ", 1)
|
||||
check = "SELECT 1 WHERE " + check
|
||||
|
||||
payload = agent.fullPayload(query)
|
||||
result = Request.queryPage(payload)
|
||||
result = inject.checkBooleanExpression(check)
|
||||
|
||||
if result:
|
||||
if version == 8:
|
||||
|
@ -126,9 +124,8 @@ class Fingerprint(GenericFingerprint):
|
|||
break
|
||||
|
||||
else:
|
||||
query = "AND %d=(SELECT (CASE WHEN (SUBSTRING((@@VERSION), 22, 1)=7) THEN %d ELSE %d END))" % (randInt, randInt, (randInt + 1))
|
||||
payload = agent.fullPayload(query)
|
||||
result = Request.queryPage(payload)
|
||||
check = "%d=(SELECT (CASE WHEN (SUBSTRING((@@VERSION), 22, 1)=7) THEN %d ELSE %d END))" % (randInt, randInt, (randInt + 1))
|
||||
result = inject.checkBooleanExpression(check)
|
||||
|
||||
if result:
|
||||
kb.dbmsVersion = ["7.0"]
|
||||
|
|
|
@ -163,15 +163,13 @@ class Fingerprint(GenericFingerprint):
|
|||
logger.info(infoMsg)
|
||||
|
||||
randInt = getUnicode(randomInt(1))
|
||||
payload = agent.fullPayload("AND CONNECTION_ID()=CONNECTION_ID()")
|
||||
result = Request.queryPage(payload)
|
||||
result = inject.checkBooleanExpression("CONNECTION_ID()=CONNECTION_ID()")
|
||||
|
||||
if result:
|
||||
infoMsg = "confirming MySQL"
|
||||
logger.info(infoMsg)
|
||||
|
||||
payload = agent.fullPayload("AND ISNULL(1/0)" if kb.injection.place != PLACE.URI else "AND ISNULL(1 DIV 0)")
|
||||
result = Request.queryPage(payload)
|
||||
result = inject.checkBooleanExpression("ISNULL(1/0)" if kb.injection.place != PLACE.URI else "ISNULL(1 DIV 0)")
|
||||
|
||||
if not result:
|
||||
warnMsg = "the back-end DBMS is not MySQL"
|
||||
|
|
|
@ -80,8 +80,7 @@ class Fingerprint(GenericFingerprint):
|
|||
if conf.direct:
|
||||
result = True
|
||||
else:
|
||||
payload = agent.fullPayload("AND ROWNUM=ROWNUM")
|
||||
result = Request.queryPage(payload)
|
||||
result = inject.checkBooleanExpression("ROWNUM=ROWNUM")
|
||||
|
||||
if result:
|
||||
logMsg = "confirming Oracle"
|
||||
|
@ -92,8 +91,7 @@ class Fingerprint(GenericFingerprint):
|
|||
if conf.direct:
|
||||
result = True
|
||||
else:
|
||||
payload = agent.fullPayload("AND LENGTH(SYSDATE)=LENGTH(SYSDATE)")
|
||||
result = Request.queryPage(payload)
|
||||
result = inject.checkBooleanExpression("LENGTH(SYSDATE)=LENGTH(SYSDATE)")
|
||||
|
||||
if not result:
|
||||
warnMsg = "the back-end DBMS is not Oracle"
|
||||
|
|
|
@ -86,15 +86,13 @@ class Fingerprint(GenericFingerprint):
|
|||
|
||||
randInt = getUnicode(randomInt(1))
|
||||
|
||||
payload = agent.fullPayload("AND %s::int=%s" % (randInt, randInt))
|
||||
result = Request.queryPage(payload)
|
||||
result = inject.checkBooleanExpression("%s::int=%s" % (randInt, randInt))
|
||||
|
||||
if result:
|
||||
infoMsg = "confirming PostgreSQL"
|
||||
logger.info(infoMsg)
|
||||
|
||||
payload = agent.fullPayload("AND COALESCE(%s, NULL)=%s" % (randInt, randInt))
|
||||
result = Request.queryPage(payload)
|
||||
result = inject.checkBooleanExpression("COALESCE(%s, NULL)=%s" % (randInt, randInt))
|
||||
|
||||
if not result:
|
||||
warnMsg = "the back-end DBMS is not PostgreSQL"
|
||||
|
|
Loading…
Reference in New Issue
Block a user