Added new switch --union-char to be able to provide the character used in union-test and exploit (default is still NULL, but can be any)

This commit is contained in:
Bernardo Damele 2010-11-19 14:56:20 +00:00
parent c6545f5c9f
commit ad17e9ed2a
8 changed files with 33 additions and 12 deletions

View File

@ -246,7 +246,7 @@ Anastasios Monachos <anastasiosm@gmail.com>
Alejo Murillo Moya <alex@65535.com> Alejo Murillo Moya <alex@65535.com>
for reporting a minor bug for reporting a minor bug
for suggesting a feature for suggesting a few features
Roberto Nemirovsky <roberto.paes@gmail.com> Roberto Nemirovsky <roberto.paes@gmail.com>
for pointing me out some enhancements for pointing me out some enhancements

View File

@ -425,7 +425,7 @@ class Agent:
return concatenatedQuery return concatenatedQuery
def forgeInbandQuery(self, query, exprPosition=None, nullChar="NULL", count=None, comment=None): def forgeInbandQuery(self, query, exprPosition=None, nullChar=None, count=None, comment=None):
""" """
Take in input an query (pseudo query) string and return its Take in input an query (pseudo query) string and return its
processed UNION ALL SELECT query. processed UNION ALL SELECT query.
@ -456,6 +456,9 @@ class Agent:
@rtype: C{str} @rtype: C{str}
""" """
if nullChar is None:
nullChar = conf.uChar
if count is None: if count is None:
count = kb.unionCount count = kb.unionCount

View File

@ -487,7 +487,14 @@ def __setWriteFile():
conf.wFileType = getFileType(conf.wFile) conf.wFileType = getFileType(conf.wFile)
def __setUnionTech(): def __setUnion():
if isinstance(conf.uChar, basestring) and conf.uChar != "NULL" and not conf.uChar.isdigit():
if not conf.uChar.startswith("'") or not conf.uChar.endswith("'"):
debugMsg = "setting the UNION query SQL injection character to '%s'" % conf.uChar
logger.debug(debugMsg)
conf.uChar = "'%s'" % conf.uChar
if conf.uTech is None: if conf.uTech is None:
conf.uTech = "NULL" conf.uTech = "NULL"
@ -1341,7 +1348,7 @@ def init(inputOptions=advancedDict()):
__setHTTPAuthentication() __setHTTPAuthentication()
__setHTTPProxy() __setHTTPProxy()
__setSafeUrl() __setSafeUrl()
__setUnionTech() __setUnion()
__setGoogleDorking() __setGoogleDorking()
__urllib2Opener() __urllib2Opener()
__findPageForms() __findPageForms()

View File

@ -79,7 +79,8 @@ optDict = {
"timeSec": "integer", "timeSec": "integer",
"unionTest": "boolean", "unionTest": "boolean",
"uTech": "string", "uTech": "string",
"uCols": "integer" "uCols": "integer",
"uChar": "string"
}, },
"Fingerprint": { "Fingerprint": {

View File

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

View File

@ -90,21 +90,21 @@ def __unionConfirm(count=None, comment=None):
return validPayload return validPayload
def __unionTestByNULLBruteforce(comment): def __unionTestByCharBruteforce(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
""" """
query = agent.prefixQuery("UNION ALL SELECT NULL") query = agent.prefixQuery("UNION ALL SELECT %s" % conf.uChar)
for count in range(1, conf.uCols+1): for count in range(1, conf.uCols+1):
if kb.dbms == DBMS.ORACLE and query.endswith(" FROM DUAL"): if kb.dbms == DBMS.ORACLE and query.endswith(" FROM DUAL"):
query = query[:-len(" FROM DUAL")] query = query[:-len(" FROM DUAL")]
if count: if count:
query += ", NULL" query += ", %s" % conf.uChar
if kb.dbms == DBMS.ORACLE: if kb.dbms == DBMS.ORACLE:
query += " FROM DUAL" query += " FROM DUAL"
@ -151,8 +151,10 @@ def unionTest():
if conf.uTech == "orderby": if conf.uTech == "orderby":
technique = "ORDER BY clause bruteforcing" technique = "ORDER BY clause bruteforcing"
else: elif conf.uChar == "NULL":
technique = "NULL bruteforcing" technique = "NULL bruteforcing"
else:
technique = "char (%s) bruteforcing" % conf.uChar
infoMsg = "testing inband sql injection on parameter " infoMsg = "testing inband sql injection on parameter "
infoMsg += "'%s' with %s technique" % (kb.injParameter, technique) infoMsg += "'%s' with %s technique" % (kb.injParameter, technique)
@ -164,7 +166,7 @@ def unionTest():
if conf.uTech == "orderby": if conf.uTech == "orderby":
validPayload = __unionTestByOrderBy(comment) validPayload = __unionTestByOrderBy(comment)
else: else:
validPayload = __unionTestByNULLBruteforce(comment) validPayload = __unionTestByCharBruteforce(comment)
if validPayload: if validPayload:
setUnion(comment=comment) setUnion(comment=comment)

View File

@ -26,7 +26,7 @@ from lib.utils.resume import resume
reqCount = 0 reqCount = 0
def unionUse(expression, direct=False, unescape=True, resetCounter=False, nullChar="NULL", unpack=True, dump=False): def unionUse(expression, direct=False, unescape=True, resetCounter=False, nullChar=None, unpack=True, dump=False):
""" """
This function tests for an inband SQL injection on the target This function tests for an inband SQL injection on the target
url then call its subsidiary function to effectively perform an url then call its subsidiary function to effectively perform an

View File

@ -265,6 +265,11 @@ uTech = NULL
# Default: 20 # Default: 20
uCols = 20 uCols = 20
# Character to use to bruteforce number of columns
# Valid: string
# Default: NULL
uChar = NULL
[Fingerprint] [Fingerprint]