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