Merge branch 'master' of github.com:sqlmapproject/sqlmap

This commit is contained in:
Miroslav Stampar 2012-12-19 14:29:08 +01:00
commit 23153e8088
8 changed files with 211 additions and 686 deletions

View File

@ -675,6 +675,71 @@ class Agent(object):
return unionQuery
def limitCondition(self, expression, dump=False):
startLimit = 0
stopLimit = None
limitCond = True
limitRegExp = re.search(queries[Backend.getIdentifiedDbms()].limitregexp.query, expression, re.I)
limitRegExp2 = re.search(queries[Backend.getIdentifiedDbms()].limitregexp.query2, expression, re.I)
topLimit = re.search("TOP\s+([\d]+)\s+", expression, re.I)
if (limitRegExp or limitRegExp2) or (Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE) and topLimit):
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.SQLITE):
limitGroupStart = queries[Backend.getIdentifiedDbms()].limitgroupstart.query
limitGroupStop = queries[Backend.getIdentifiedDbms()].limitgroupstop.query
if limitGroupStart.isdigit():
if limitRegExp:
startLimit = int(limitRegExp.group(int(limitGroupStart)))
stopLimit = limitRegExp.group(int(limitGroupStop))
elif limitRegExp2:
startLimit = 0
stopLimit = limitRegExp2.group(int(limitGroupStart))
limitCond = int(stopLimit) > 1
elif Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE):
if limitRegExp:
limitGroupStart = queries[Backend.getIdentifiedDbms()].limitgroupstart.query
limitGroupStop = queries[Backend.getIdentifiedDbms()].limitgroupstop.query
if limitGroupStart.isdigit():
startLimit = int(limitRegExp.group(int(limitGroupStart)))
stopLimit = limitRegExp.group(int(limitGroupStop))
limitCond = int(stopLimit) > 1
elif topLimit:
startLimit = 0
stopLimit = int(topLimit.group(1))
limitCond = int(stopLimit) > 1
elif Backend.isDbms(DBMS.ORACLE):
limitCond = False
# We assume that only queries NOT containing a "LIMIT #, 1"
# (or equivalent depending on the back-end DBMS) can return
# multiple entries
if limitCond:
if (limitRegExp or limitRegExp2) and stopLimit is not None:
stopLimit = int(stopLimit)
# From now on we need only the expression until the " LIMIT "
# (or equivalent, depending on the back-end DBMS) word
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.SQLITE):
stopLimit += startLimit
_ = expression.index(queries[Backend.getIdentifiedDbms()].limitstring.query)
expression = expression[:_]
elif Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE):
stopLimit += startLimit
elif dump:
if conf.limitStart:
startLimit = conf.limitStart - 1
if conf.limitStop:
stopLimit = conf.limitStop
return expression, limitCond, topLimit, startLimit, stopLimit
def limitQuery(self, num, query, field=None, uniqueField=None):
"""
Take in input a query string and return its limited query string.

View File

@ -661,6 +661,9 @@ def filePathToString(filePath):
return strRepl
def singleTimeDebugMessage(message):
singleTimeLogMessage(message, logging.DEBUG)
def singleTimeWarnMessage(message):
singleTimeLogMessage(message, logging.WARN)

View File

@ -129,7 +129,7 @@ def liveTest():
if case.hasAttribute("name"):
name = case.getAttribute("name")
if conf.runCase and ((conf.runCase.isdigit() and conf.runCase != count) or not re.search(conf.runCase, name, re.DOTALL)):
if conf.runCase and ((conf.runCase.isdigit() and conf.runCase != count) or not re.search(conf.runCase, name, re.DOTALL | re.I)):
continue
if case.getElementsByTagName("switches"):
@ -206,7 +206,7 @@ def runCase(switches=None, parse=None):
retVal = False
if parse and retVal:
ifile = open(conf.dumper.getOutputFile(), 'r')
ifile = open(conf.dumper.getOutputFile(), "rb")
content = ifile.read()
ifile.close()
for item in parse:

View File

@ -139,8 +139,6 @@ def _goInferenceProxy(expression, fromUser=False, batch=False, unpack=True, char
startLimit = 0
stopLimit = None
outputs = BigArray()
untilLimitChar = None
untilOrderChar = None
if not unpack:
return _goInference(payload, expression, charsetType, firstChar, lastChar, dump)
@ -160,69 +158,18 @@ def _goInferenceProxy(expression, fromUser=False, batch=False, unpack=True, char
# If we have been here from SQL query/shell we have to check if
# the SQL query might return multiple entries and in such case
# forge the SQL limiting the query output one entry per time
# NOTE: I assume that only queries that get data from a table
# forge the SQL limiting the query output one entry at a time
# NOTE: we assume that only queries that get data from a table
# can return multiple entries
if fromUser and " FROM " in expression.upper() and ((Backend.getIdentifiedDbms() \
not in FROM_DUMMY_TABLE) or (Backend.getIdentifiedDbms() in FROM_DUMMY_TABLE and not \
expression.upper().endswith(FROM_DUMMY_TABLE[Backend.getIdentifiedDbms()]))) \
and not re.search(SQL_SCALAR_REGEX, expression, re.I):
expression, limitCond, topLimit, startLimit, stopLimit = agent.limitCondition(expression)
limitCond = True
limitRegExp = re.search(queries[Backend.getIdentifiedDbms()].limitregexp.query, expression, re.I)
limitRegExp2 = re.search(queries[Backend.getIdentifiedDbms()].limitregexp.query2, expression, re.I)
topLimit = re.search("TOP\s+([\d]+)\s+", expression, re.I)
if (limitRegExp or limitRegExp2) or (Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE) and topLimit):
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.SQLITE):
limitGroupStart = queries[Backend.getIdentifiedDbms()].limitgroupstart.query
limitGroupStop = queries[Backend.getIdentifiedDbms()].limitgroupstop.query
if limitGroupStart.isdigit():
if limitRegExp2:
startLimit = 0
stopLimit = limitRegExp2.group(int(limitGroupStart))
else:
startLimit = int(limitRegExp.group(int(limitGroupStart)))
stopLimit = limitRegExp.group(int(limitGroupStop))
limitCond = int(stopLimit) > 1
elif Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE):
if limitRegExp:
limitGroupStart = queries[Backend.getIdentifiedDbms()].limitgroupstart.query
limitGroupStop = queries[Backend.getIdentifiedDbms()].limitgroupstop.query
if limitGroupStart.isdigit():
startLimit = int(limitRegExp.group(int(limitGroupStart)))
stopLimit = limitRegExp.group(int(limitGroupStop))
limitCond = int(stopLimit) > 1
elif topLimit:
startLimit = 0
stopLimit = int(topLimit.group(1))
limitCond = int(stopLimit) > 1
elif Backend.isDbms(DBMS.ORACLE):
limitCond = False
# We assume that only queries NOT containing a "LIMIT #, 1"
# (or equivalent depending on the back-end DBMS) can return
# multiple entries
if limitCond:
if (limitRegExp or limitRegExp2) and stopLimit is not None:
stopLimit = int(stopLimit)
# From now on we need only the expression until the " LIMIT "
# (or equivalent, depending on the back-end DBMS) word
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.SQLITE):
stopLimit += startLimit
untilLimitChar = expression.index(queries[Backend.getIdentifiedDbms()].limitstring.query)
expression = expression[:untilLimitChar]
elif Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE):
stopLimit += startLimit
test = True
if not stopLimit or stopLimit <= 1:
if Backend.getIdentifiedDbms() in FROM_DUMMY_TABLE and expression.upper().endswith(FROM_DUMMY_TABLE[Backend.getIdentifiedDbms()]):
test = False
@ -232,9 +179,9 @@ def _goInferenceProxy(expression, fromUser=False, batch=False, unpack=True, char
countFirstField = queries[Backend.getIdentifiedDbms()].count.query % expressionFieldsList[0]
countedExpression = expression.replace(expressionFields, countFirstField, 1)
if re.search(" ORDER BY ", expression, re.I):
untilOrderChar = countedExpression.index(" ORDER BY ")
countedExpression = countedExpression[:untilOrderChar]
if " ORDER BY " in expression.upper():
_ = countedExpression.upper().rindex(" ORDER BY ")
countedExpression = countedExpression[:_]
if not stopLimit:
count = _goInference(payload, countedExpression, charsetType=CHARSET_TYPE.DIGITS, firstChar=firstChar, lastChar=lastChar)

View File

@ -238,14 +238,13 @@ def errorUse(expression, dump=False):
stopLimit = None
output = None
outputs = None
untilLimitChar = None
_, _, _, _, _, expressionFieldsList, expressionFields, _ = agent.getFields(expression)
# We have to check if the SQL query might return multiple entries
# and in such case forge the SQL limiting the query output one
# entry per time
# NOTE: I assume that only queries that get data from a table can
# entry at a time
# NOTE: we assume that only queries that get data from a table can
# return multiple entries
if (dump and (conf.limitStart or conf.limitStop)) or (" FROM " in \
expression.upper() and ((Backend.getIdentifiedDbms() not in FROM_DUMMY_TABLE) \
@ -253,70 +252,13 @@ def errorUse(expression, dump=False):
expression.upper().endswith(FROM_DUMMY_TABLE[Backend.getIdentifiedDbms()]))) \
and ("(CASE" not in expression.upper() or ("(CASE" in expression.upper() and "WHEN use" in expression))) \
and not re.search(SQL_SCALAR_REGEX, expression, re.I):
expression, limitCond, topLimit, startLimit, stopLimit = agent.limitCondition(expression, dump)
limitCond = True
limitRegExp = re.search(queries[Backend.getIdentifiedDbms()].limitregexp.query, expression, re.I)
limitRegExp2 = re.search(queries[Backend.getIdentifiedDbms()].limitregexp.query2, expression, re.I)
topLimit = re.search("TOP\s+([\d]+)\s+", expression, re.I)
if (limitRegExp or limitRegExp2) or (Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE) and topLimit):
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.SQLITE):
limitGroupStart = queries[Backend.getIdentifiedDbms()].limitgroupstart.query
limitGroupStop = queries[Backend.getIdentifiedDbms()].limitgroupstop.query
if limitGroupStart.isdigit():
if limitRegExp2:
startLimit = 0
stopLimit = limitRegExp2.group(int(limitGroupStart))
else:
startLimit = int(limitRegExp.group(int(limitGroupStart)))
stopLimit = limitRegExp.group(int(limitGroupStop))
limitCond = int(stopLimit) > 1
elif Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE):
if limitRegExp:
limitGroupStart = queries[Backend.getIdentifiedDbms()].limitgroupstart.query
limitGroupStop = queries[Backend.getIdentifiedDbms()].limitgroupstop.query
if limitGroupStart.isdigit():
startLimit = int(limitRegExp.group(int(limitGroupStart)))
stopLimit = limitRegExp.group(int(limitGroupStop))
limitCond = int(stopLimit) > 1
elif topLimit:
startLimit = 0
stopLimit = int(topLimit.group(1))
limitCond = int(stopLimit) > 1
elif Backend.isDbms(DBMS.ORACLE):
limitCond = False
# I assume that only queries NOT containing a "LIMIT #, 1"
# (or equivalent depending on the back-end DBMS) can return
# multiple entries
if limitCond:
if (limitRegExp or limitRegExp2) and stopLimit is not None:
stopLimit = int(stopLimit)
# From now on we need only the expression until the " LIMIT "
# (or equivalent, depending on the back-end DBMS) word
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.SQLITE):
stopLimit += startLimit
untilLimitChar = expression.index(queries[Backend.getIdentifiedDbms()].limitstring.query)
expression = expression[:untilLimitChar]
elif Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE):
stopLimit += startLimit
elif dump:
if conf.limitStart:
startLimit = conf.limitStart - 1
if conf.limitStop:
stopLimit = conf.limitStop
# Count the number of SQL query entries output
countedExpression = expression.replace(expressionFields, queries[Backend.getIdentifiedDbms()].count.query % ('*' if len(expressionFieldsList) > 1 else expressionFields), 1)
if " ORDER BY " in expression:
if " ORDER BY " in expression.upper():
_ = countedExpression.upper().rindex(" ORDER BY ")
countedExpression = countedExpression[:_]

View File

@ -29,6 +29,7 @@ from lib.core.common import isNumPosStrValue
from lib.core.common import listToStrValue
from lib.core.common import parseUnionPage
from lib.core.common import removeReflectiveValues
from lib.core.common import singleTimeDebugMessage
from lib.core.common import singleTimeWarnMessage
from lib.core.common import wasLastRequestDBMSError
from lib.core.convert import htmlunescape
@ -160,13 +161,16 @@ def unionUse(expression, unpack=True, dump=False):
_, _, _, _, _, expressionFieldsList, expressionFields, _ = agent.getFields(origExpr)
if expressionFieldsList and len(expressionFieldsList) > 1 and "ORDER BY" in expression.upper():
# No need for it in multicolumn dumps (one row is retrieved per request) and just slowing down on large table dumps
expression = expression[:expression.upper().rindex(" ORDER BY ")]
# Removed ORDER BY clause because UNION does not play well with it
expression = re.sub("\s*ORDER BY\s+[\w,]+", "", expression, re.I)
debugMsg = "stripping ORDER BY clause from statement because "
debugMsg += "it does not play well with UNION query SQL injection"
singleTimeDebugMessage(debugMsg)
# We have to check if the SQL query might return multiple entries
# and in such case forge the SQL limiting the query output one
# entry per time
# NOTE: I assume that only queries that get data from a table can
# if the technique is partial UNION query and in such case forge the
# SQL limiting the query output one entry at a time
# NOTE: we assume that only queries that get data from a table can
# return multiple entries
if (kb.injection.data[PAYLOAD.TECHNIQUE.UNION].where == PAYLOAD.WHERE.NEGATIVE or \
(dump and (conf.limitStart or conf.limitStop))) and \
@ -174,66 +178,9 @@ def unionUse(expression, unpack=True, dump=False):
not in FROM_DUMMY_TABLE) or (Backend.getIdentifiedDbms() in FROM_DUMMY_TABLE \
and not expression.upper().endswith(FROM_DUMMY_TABLE[Backend.getIdentifiedDbms()]))) \
and not re.search(SQL_SCALAR_REGEX, expression, re.I):
expression, limitCond, topLimit, startLimit, stopLimit = agent.limitCondition(expression, dump)
limitCond = True
limitRegExp = re.search(queries[Backend.getIdentifiedDbms()].limitregexp.query, expression, re.I)
limitRegExp2 = re.search(queries[Backend.getIdentifiedDbms()].limitregexp.query2, expression, re.I)
topLimit = re.search("TOP\s+([\d]+)\s+", expression, re.I)
if (limitRegExp or limitRegExp2) or (Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE) and topLimit):
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.SQLITE):
limitGroupStart = queries[Backend.getIdentifiedDbms()].limitgroupstart.query
limitGroupStop = queries[Backend.getIdentifiedDbms()].limitgroupstop.query
if limitGroupStart.isdigit():
if limitRegExp2:
startLimit = 0
stopLimit = limitRegExp2.group(int(limitGroupStart))
else:
startLimit = int(limitRegExp.group(int(limitGroupStart)))
stopLimit = limitRegExp.group(int(limitGroupStop))
limitCond = int(stopLimit) > 1
elif Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE):
if limitRegExp:
limitGroupStart = queries[Backend.getIdentifiedDbms()].limitgroupstart.query
limitGroupStop = queries[Backend.getIdentifiedDbms()].limitgroupstop.query
if limitGroupStart.isdigit():
startLimit = int(limitRegExp.group(int(limitGroupStart)))
stopLimit = limitRegExp.group(int(limitGroupStop))
limitCond = int(stopLimit) > 1
elif topLimit:
startLimit = 0
stopLimit = int(topLimit.group(1))
limitCond = int(stopLimit) > 1
elif Backend.isDbms(DBMS.ORACLE):
limitCond = False
# I assume that only queries NOT containing a "LIMIT #, 1"
# (or equivalent depending on the back-end DBMS) can return
# multiple entries
if limitCond:
if (limitRegExp or limitRegExp2) and stopLimit is not None:
stopLimit = int(stopLimit)
# From now on we need only the expression until the " LIMIT "
# (or equivalent, depending on the back-end DBMS) word
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.SQLITE):
stopLimit += startLimit
untilLimitChar = expression.index(queries[Backend.getIdentifiedDbms()].limitstring.query)
expression = expression[:untilLimitChar]
elif Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE):
stopLimit += startLimit
elif dump:
if conf.limitStart:
startLimit = conf.limitStart - 1
if conf.limitStop:
stopLimit = conf.limitStop
# Count the number of SQL query entries output
countedExpression = expression.replace(expressionFields, queries[Backend.getIdentifiedDbms()].count.query % ('*' if len(expressionFieldsList) > 1 else expressionFields), 1)
@ -362,7 +309,6 @@ def unionUse(expression, unpack=True, dump=False):
kb.suppressResumeInfo = False
if not value and not abortedFlag:
expression = re.sub("\s*ORDER BY\s+[\w,]+", "", expression, re.I) # full union doesn't play well with ORDER BY
value = _oneShotUnionUse(expression, unpack)
duration = calculateDeltaSeconds(start)

View File

@ -106,7 +106,7 @@ def from_buffer(buffer, mime=False):
try:
libmagic = None
# Let's try to find magic or magic1
dll = ctypes.util.find_library('magic') or ctypes.util.find_library('magic1')
@ -198,7 +198,8 @@ magic_check.argtypes = [magic_t, c_char_p]
magic_compile = libmagic.magic_compile
magic_compile.restype = c_int
magic_compile.argtypes = [magic_t, c_char_p]
except ImportError:
pass
MAGIC_NONE = 0x000000 # No flags

View File

@ -44,7 +44,7 @@
<item value="r'database management system users privileges:.+debian-sys-maint.+\(administrator\).+root.+\(administrator\).+privilege: SUPER'"/>
<item value="r'database management system users roles:.+debian-sys-maint.+\[.+root.+\[.+role: SUPER'"/>
<item value="r'available databases \[.+information_schema.+mysql.+owasp10.+testdb'"/>
<item value="r'Database: testdb.+1 table.+users'"/>
<item value="r'Database: testdb.+3 tables.+users'"/>
<item value="r'Database: testdb.+Table: users.+3 columns.+surname.+varchar\(1000\)'"/>
<item value="r'Database: testdb.+Table.+Entries.+users.+5'"/>
<item value="r'Database: testdb.+Table: users.+5 entries.+luther.+nameisnull.+'"/>
@ -87,7 +87,7 @@
<item value="r'database management system users privileges:.+debian-sys-maint.+\(administrator\).+root.+\(administrator\).+privilege: SUPER'"/>
<item value="r'database management system users roles:.+debian-sys-maint.+\[.+root.+\[.+role: SUPER'"/>
<item value="r'available databases \[.+information_schema.+mysql.+owasp10.+testdb'"/>
<item value="r'Database: testdb.+1 table.+users'"/>
<item value="r'Database: testdb.+3 tables.+users'"/>
<item value="r'Database: testdb.+Table: users.+3 columns.+surname.+varchar\(1000\)'"/>
<item value="r'Database: testdb.+Table.+Entries.+users.+5'"/>
<item value="r'Database: testdb.+Table: users.+5 entries.+luther.+nameisnull.+'"/>
@ -130,7 +130,7 @@
<item value="r'database management system users privileges:.+debian-sys-maint.+\(administrator\).+root.+\(administrator\).+privilege: SUPER'"/>
<item value="r'database management system users roles:.+debian-sys-maint.+\[.+root.+\[.+role: SUPER'"/>
<item value="r'available databases \[.+information_schema.+mysql.+owasp10.+testdb'"/>
<item value="r'Database: testdb.+1 table.+users'"/>
<item value="r'Database: testdb.+3 tables.+users'"/>
<item value="r'Database: testdb.+Table: users.+3 columns.+surname.+varchar\(1000\)'"/>
<item value="r'Database: testdb.+Table.+Entries.+users.+5'"/>
<item value="r'Database: testdb.+Table: users.+5 entries.+luther.+nameisnull.+'"/>
@ -173,7 +173,7 @@
<item value="r'database management system users privileges:.+debian-sys-maint.+\(administrator\).+root.+\(administrator\).+privilege: SUPER'"/>
<item value="r'database management system users roles:.+debian-sys-maint.+\[.+root.+\[.+role: SUPER'"/>
<item value="r'available databases \[.+information_schema.+mysql.+owasp10.+testdb'"/>
<item value="r'Database: testdb.+1 table.+users'"/>
<item value="r'Database: testdb.+3 tables.+users'"/>
<item value="r'Database: testdb.+Table: users.+3 columns.+surname.+varchar\(1000\)'"/>
<item value="r'Database: testdb.+Table.+Entries.+users.+5'"/>
<item value="r'Database: testdb.+Table: users.+5 entries.+luther.+nameisnull.+'"/>
@ -190,18 +190,6 @@
<getCurrentDb value="True"/>
<getHostname value="True"/>
<isDba value="True"/>
<getUsers value="True"/>
<getPasswordHashes value="True"/>
<getPrivileges value="True"/>
<getRoles value="True"/>
<getDbs value="True"/>
<getTables value="True"/>
<getColumns value="True"/>
<getCount value="True"/>
<dumpTable value="True"/>
<db value="testdb"/>
<tbl value="users"/>
<excludeSysDbs value="True"/>
</switches>
<parse>
<item value="Title: MySQL &gt; 5.0.11 AND time-based blind"/>
@ -211,15 +199,6 @@
<item value="current database: 'testdb'"/>
<item value="hostname: 'debian"/>
<item value="current user is DBA: True"/>
<item value="r'database management system users \[.+'debian-sys-maint'@'localhost'.+'root'@''"/>
<item value="r'database management system users password hashes:.+root \[.+password hash: \*00E247AC5F9AF26AE0194B41E1E769DEE1429A29.+clear-text password: testpass'"/>
<item value="r'database management system users privileges:.+debian-sys-maint.+\(administrator\).+root.+\(administrator\).+privilege: SUPER'"/>
<item value="r'database management system users roles:.+debian-sys-maint.+\[.+root.+\[.+role: SUPER'"/>
<item value="r'available databases \[.+information_schema.+mysql.+owasp10.+testdb'"/>
<item value="r'Database: testdb.+1 table.+users'"/>
<item value="r'Database: testdb.+Table: users.+3 columns.+surname.+varchar\(1000\)'"/>
<item value="r'Database: testdb.+Table.+Entries.+users.+5'"/>
<item value="r'Database: testdb.+Table: users.+5 entries.+luther.+nameisnull.+'"/>
</parse>
</case>
<case name="MySQL inline queries multi-threaded enumeration - all entries">
@ -259,7 +238,7 @@
<item value="r'database management system users privileges:.+debian-sys-maint.+\(administrator\).+root.+\(administrator\).+privilege: SUPER'"/>
<item value="r'database management system users roles:.+debian-sys-maint.+\[.+root.+\[.+role: SUPER'"/>
<item value="r'available databases \[.+information_schema.+mysql.+owasp10.+testdb'"/>
<item value="r'Database: testdb.+1 table.+users'"/>
<item value="r'Database: testdb.+3 tables.+users'"/>
<item value="r'Database: testdb.+Table: users.+3 columns.+surname.+varchar\(1000\)'"/>
<item value="r'Database: testdb.+Table.+Entries.+users.+5'"/>
<item value="r'Database: testdb.+Table: users.+5 entries.+luther.+nameisnull.+'"/>
@ -304,11 +283,14 @@
<item value="r'Database: testdb.+Table: users.+3 entries.+fluffy.+bunny.+wu.+ming'"/>
</parse>
</case>
<!-- TODO: this fails because of issue #304 -->
<case name="MySQL boolean-based multi-threaded custom enumeration - substring">
<switches>
<url value="http://debiandev/sqlmap/mysql/get_int.php?id=1"/>
<!-- TODO: this fails because of issue #305 -->
<!--
<threads value="4"/>
-->
<threads value="1"/>
<tech value="B"/>
<dumpTable value="True"/>
<db value="testdb"/>
@ -366,7 +348,7 @@
<tech value="B"/>
<search value="True"/>
<db value="testdb"/>
<tbl value="a,e,i"/>
<tbl value="foo,se,bar"/>
</switches>
<parse>
<item value="r'Database: testdb.+1 table.+users'"/>
@ -380,7 +362,7 @@
<tech value="E"/>
<search value="True"/>
<db value="testdb"/>
<tbl value="a,e,i"/>
<tbl value="foo,se,bar"/>
</switches>
<parse>
<item value="r'Database: testdb.+1 table.+users'"/>
@ -394,7 +376,7 @@
<tech value="U"/>
<search value="True"/>
<db value="testdb"/>
<tbl value="a,e,i"/>
<tbl value="foo,se,bar"/>
</switches>
<parse>
<item value="r'Database: testdb.+1 table.+users'"/>
@ -653,400 +635,39 @@
<item value="r'SELECT \* FROM users LIMIT 0, 2 \[2\].+1, luther, blissett.+2, fluffy, bunny'"/>
</parse>
</case>
<case name="MySQL boolean-based multi-threaded custom ordered SQL query enumeration">
<switches>
<url value="http://debiandev/sqlmap/mysql/get_int.php?id=1"/>
<threads value="4"/>
<tech value="B"/>
<query value="SELECT * FROM users ORDER BY name"/>
</switches>
<parse>
<item value="r'SELECT \* FROM users ORDER BY name \[5\].+2, fluffy, bunny.+1, luther, blissett.+3, wu, ming'"/>
</parse>
</case>
<case name="MySQL error-based multi-threaded custom ordered SQL query enumeration">
<switches>
<url value="http://debiandev/sqlmap/mysql/get_int.php?id=1"/>
<threads value="4"/>
<tech value="E"/>
<query value="SELECT * FROM users ORDER BY name"/>
</switches>
<parse>
<item value="r'SELECT \* FROM users ORDER BY name \[5\].+2, fluffy, bunny.+1, luther, blissett.+3, wu, ming'"/>
</parse>
</case>
<case name="MySQL UNION query multi-threaded custom ordered SQL query enumeration">
<switches>
<url value="http://debiandev/sqlmap/mysql/get_int.php?id=1"/>
<threads value="4"/>
<tech value="U"/>
<query value="SELECT * FROM users ORDER BY name"/>
</switches>
<parse>
<!-- NOTE: it is not sorted on purpose because UNION does not play well with ORDER BY and it is stripped -->
<item value="r'SELECT \* FROM users ORDER BY name \[5\].+1, luther, blissett.+2, fluffy, bunny.+3, wu, ming'"/>
</parse>
</case>
<!-- End of user's provided statement enumeration switches -->
<!-- Old test cases -->
<case name="MySQL (--technique=E --is-dba --banner --current-user --current-db --dbs --tables -D testdb -T users --columns --dump)">
<switches>
<url value="http://debiandev/sqlmap/mysql/get_int.php?id=1"/>
<isDba value="True"/>
<tech value="E"/>
<getBanner value="True"/>
<getCurrentUser value="True"/>
<getCurrentDb value="True"/>
<getDbs value="True"/>
<getTables value="True"/>
<db value="testdb"/>
<tbl value="users"/>
<getColumns value="True"/>
<dumpTable value="True"/>
</switches>
<parse>
<item value="current user is DBA: True"/>
<item value="banner: '5.1.63-0+squeeze2'"/>
<item value="current user: 'root@localhost'"/>
<item value="current database: 'testdb'"/>
<item value="r'information_schema.+mysql.+owasp10.+testdb'"/>
<item value="r'1 table.+users'"/>
<item value="r'3 columns.+surname.+varchar\(1000\)'"/>
<item value="r'5 entries.+nameisnull.+'"/>
</parse>
</case>
<case name="MySQL (--technique=U --is-dba --banner --current-user --current-db --dbs --tables -D testdb -T users --columns --dump)">
<switches>
<url value="http://debiandev/sqlmap/mysql/get_int.php?id=1"/>
<isDba value="True"/>
<tech value="U"/>
<getBanner value="True"/>
<getCurrentUser value="True"/>
<getCurrentDb value="True"/>
<getDbs value="True"/>
<getTables value="True"/>
<db value="testdb"/>
<tbl value="users"/>
<getColumns value="True"/>
<dumpTable value="True"/>
</switches>
<parse>
<item value="current user is DBA: True"/>
<item value="banner: '5.1.63-0+squeeze1'"/>
<item value="current user: 'root@localhost'"/>
<item value="current database: 'testdb'"/>
<item value="r'information_schema.+mysql.+owasp10.+testdb'"/>
<item value="r'1 table.+users'"/>
<item value="r'3 columns.+surname.+varchar\(1000\)'"/>
<item value="r'5 entries.+nameisnull.+'"/>
</parse>
</case>
<case name="MySQL partial union (--technique=U --is-dba --banner --current-user --current-db --dbs --tables -D testdb -T users --columns --dump)">
<switches>
<url value="http://debiandev/sqlmap/mysql/get_int_partialunion.php?id=1"/>
<isDba value="True"/>
<tech value="U"/>
<getBanner value="True"/>
<getCurrentUser value="True"/>
<getCurrentDb value="True"/>
<getDbs value="True"/>
<getTables value="True"/>
<db value="testdb"/>
<tbl value="users"/>
<getColumns value="True"/>
<dumpTable value="True"/>
</switches>
<parse>
<item value="current user is DBA: True"/>
<item value="banner: '5.1.63-0+squeeze1'"/>
<item value="current user: 'root@localhost'"/>
<item value="current database: 'testdb'"/>
<item value="r'information_schema.+mysql.+owasp10.+testdb'"/>
<item value="r'1 table.+users'"/>
<item value="r'3 columns.+surname.+varchar\(1000\)'"/>
<item value="r'5 entries.+nameisnull.+'"/>
</parse>
</case>
<case name="Postgres (--technique=B --is-dba --banner --current-user --current-db --dbs --tables -D testdb -T users --columns --dump --threads=4)">
<switches>
<url value="http://debiandev/sqlmap/pgsql/get_int.php?id=1"/>
<isDba value="True"/>
<tech value="B"/>
<getBanner value="True"/>
<getCurrentUser value="True"/>
<getCurrentDb value="True"/>
<getDbs value="True"/>
<getTables value="True"/>
<db value="testdb"/>
<tbl value="users"/>
<getColumns value="True"/>
<dumpTable value="True"/>
<threads value="4"/>
</switches>
<parse>
<item value="current user is DBA: True"/>
<item value="PostgreSQL 8.3.9 on i486-pc-linux-gnu, compiled by GCC gcc-4.3.real (Debian 4.3.2-1.1) 4.3.2"/>
<item value="current user: 'testuser'"/>
<item value="current database: 'testdb'"/>
<item value="r'postgres.+template0.+template1.+testdb'"/>
<item value="r'1 table.+users'"/>
<item value="r'3 columns.+username.+bpchar'"/>
<item value="r'4 entries.+nameisnull'"/>
</parse>
</case>
<case name="Postgres (--technique=E --is-dba --banner --current-user --current-db --dbs --tables -D testdb -T users --columns --dump)">
<switches>
<url value="http://debiandev/sqlmap/pgsql/get_int.php?id=1"/>
<isDba value="True"/>
<tech value="E"/>
<getBanner value="True"/>
<getCurrentUser value="True"/>
<getCurrentDb value="True"/>
<getDbs value="True"/>
<getTables value="True"/>
<db value="testdb"/>
<tbl value="users"/>
<getColumns value="True"/>
<dumpTable value="True"/>
</switches>
<parse>
<item value="current user is DBA: True"/>
<item value="PostgreSQL 8.3.9 on i486-pc-linux-gnu, compiled by GCC gcc-4.3.real (Debian 4.3.2-1.1) 4.3.2"/>
<item value="current user: 'testuser'"/>
<item value="current database: 'testdb'"/>
<item value="r'postgres.+template0.+template1.+testdb'"/>
<item value="r'1 table.+users'"/>
<item value="r'3 columns.+username.+bpchar'"/>
<item value="r'4 entries.+nameisnull'"/>
</parse>
</case>
<case name="Postgres (--technique=U --is-dba --banner --current-user --current-db --dbs --tables -D testdb -T users --columns --dump)">
<switches>
<url value="http://debiandev/sqlmap/pgsql/get_int.php?id=1"/>
<isDba value="True"/>
<tech value="U"/>
<getBanner value="True"/>
<getCurrentUser value="True"/>
<getCurrentDb value="True"/>
<getDbs value="True"/>
<getTables value="True"/>
<db value="testdb"/>
<tbl value="users"/>
<getColumns value="True"/>
<dumpTable value="True"/>
</switches>
<parse>
<item value="current user is DBA: True"/>
<item value="PostgreSQL 8.3.9 on i486-pc-linux-gnu, compiled by GCC gcc-4.3.real (Debian 4.3.2-1.1) 4.3.2"/>
<item value="current user: 'testuser'"/>
<item value="current database: 'testdb'"/>
<item value="r'postgres.+template0.+template1.+testdb'"/>
<item value="r'1 table.+users'"/>
<item value="r'3 columns.+username.+bpchar'"/>
<item value="r'4 entries.+nameisnull'"/>
</parse>
</case>
<case name="Postgres partial union (--technique=U --is-dba --banner --current-user --current-db --dbs --tables -D testdb -T users --columns --dump)">
<switches>
<url value="http://debiandev/sqlmap/pgsql/get_int_partialunion.php?id=1"/>
<isDba value="True"/>
<tech value="U"/>
<getBanner value="True"/>
<getCurrentUser value="True"/>
<getCurrentDb value="True"/>
<getDbs value="True"/>
<getTables value="True"/>
<db value="testdb"/>
<tbl value="users"/>
<getColumns value="True"/>
<dumpTable value="True"/>
</switches>
<parse>
<item value="current user is DBA: True"/>
<item value="PostgreSQL 8.3.9 on i486-pc-linux-gnu, compiled by GCC gcc-4.3.real (Debian 4.3.2-1.1) 4.3.2"/>
<item value="current user: 'testuser'"/>
<item value="current database: 'testdb'"/>
<item value="r'postgres.+template0.+template1.+testdb'"/>
<item value="r'1 table.+users'"/>
<item value="r'3 columns.+username.+bpchar'"/>
<item value="r'4 entries.+nameisnull'"/>
</parse>
</case>
<case name="Oracle (--technique=B --is-dba --banner --current-user --current-db --dbs --tables -D SCOTT -T users --columns --dump --threads=4)">
<switches>
<url value="http://debiandev/sqlmap/oracle/get_int.php?id=1"/>
<isDba value="True"/>
<tech value="B"/>
<getBanner value="True"/>
<getCurrentUser value="True"/>
<getCurrentDb value="True"/>
<getDbs value="True"/>
<getTables value="True"/>
<db value="SCOTT"/>
<tbl value="users"/>
<getColumns value="True"/>
<dumpTable value="True"/>
<threads value="4"/>
</switches>
<parse>
<item value="current user is DBA: True"/>
<item value="banner: 'Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod'"/>
<item value="current user: 'SYS'"/>
<item value="'TESTDB.REGRESS.RDBMS.DEV.US.ORACLE.COM'"/>
<item value="r'available databases.+15.+CTXSYS.+DBSNMP.+SCOTT.+SYS.+SYSMAN'"/>
<item value="r'5 tables.+BONUS.+DEPT.+EMP.+SALGRADE.+USERS'"/>
<item value="r'3 columns.+SURNAME.+VARCHAR'"/>
<item value="r'4 entries.+nameisnull'"/>
</parse>
</case>
<case name="Oracle (--technique=E --is-dba --banner --current-user --current-db --dbs --tables -D SCOTT -T users --columns --dump)">
<switches>
<url value="http://debiandev/sqlmap/oracle/get_int.php?id=1"/>
<isDba value="True"/>
<tech value="E"/>
<getBanner value="True"/>
<getCurrentUser value="True"/>
<getCurrentDb value="True"/>
<getDbs value="True"/>
<getTables value="True"/>
<db value="SCOTT"/>
<tbl value="users"/>
<getColumns value="True"/>
<dumpTable value="True"/>
</switches>
<parse>
<item value="current user is DBA: True"/>
<item value="banner: 'Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod'"/>
<item value="current user: 'SYS'"/>
<item value="'TESTDB.REGRESS.RDBMS.DEV.US.ORACLE.COM'"/>
<item value="r'available databases.+15.+CTXSYS.+DBSNMP.+SCOTT.+SYS.+SYSMAN'"/>
<item value="r'5 tables.+BONUS.+DEPT.+EMP.+SALGRADE.+USERS'"/>
<item value="r'3 columns.+SURNAME.+VARCHAR'"/>
<item value="r'4 entries.+nameisnull'"/>
</parse>
</case>
<case name="Oracle (--technique=U --is-dba --banner --current-user --current-db --dbs --tables -D SCOTT -T users --columns --dump)">
<switches>
<url value="http://debiandev/sqlmap/oracle/get_int.php?id=1"/>
<isDba value="True"/>
<tech value="U"/>
<getBanner value="True"/>
<getCurrentUser value="True"/>
<getCurrentDb value="True"/>
<getDbs value="True"/>
<getTables value="True"/>
<db value="SCOTT"/>
<tbl value="users"/>
<getColumns value="True"/>
<dumpTable value="True"/>
</switches>
<parse>
<item value="current user is DBA: True"/>
<item value="banner: 'Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod'"/>
<item value="current user: 'SYS'"/>
<item value="'TESTDB.REGRESS.RDBMS.DEV.US.ORACLE.COM'"/>
<item value="r'available databases.+15.+CTXSYS.+DBSNMP.+SCOTT.+SYS.+SYSMAN'"/>
<item value="r'5 tables.+BONUS.+DEPT.+EMP.+SALGRADE.+USERS'"/>
<item value="r'3 columns.+SURNAME.+VARCHAR'"/>
<item value="r'4 entries.+nameisnull'"/>
</parse>
</case>
<case name="Oracle partial union (--technique=U --is-dba --banner --current-user --current-db --dbs --tables -D SCOTT -T users --columns --dump)">
<switches>
<url value="http://debiandev/sqlmap/oracle/get_int_partialunion.php?id=1"/>
<isDba value="True"/>
<tech value="U"/>
<getBanner value="True"/>
<getCurrentUser value="True"/>
<getCurrentDb value="True"/>
<getDbs value="True"/>
<getTables value="True"/>
<db value="SCOTT"/>
<tbl value="users"/>
<getColumns value="True"/>
<dumpTable value="True"/>
</switches>
<parse>
<item value="current user is DBA: True"/>
<item value="banner: 'Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod'"/>
<item value="current user: 'SYS'"/>
<item value="'TESTDB.REGRESS.RDBMS.DEV.US.ORACLE.COM'"/>
<item value="r'available databases.+15.+CTXSYS.+DBSNMP.+SCOTT.+SYS.+SYSMAN'"/>
<item value="r'5 tables.+BONUS.+DEPT.+EMP.+SALGRADE.+USERS'"/>
<item value="r'3 columns.+SURNAME.+VARCHAR'"/>
<item value="r'4 entries.+nameisnull'"/>
</parse>
</case>
<case name="MSSQL (--technique=B --is-dba --banner --current-user --current-db --dbs --tables -D testdb -T users --columns --dump --threads=4)">
<switches>
<url value="http://windowsdev/sqlmap/mssql/iis/get_int.asp?id=1"/>
<isDba value="True"/>
<tech value="B"/>
<getBanner value="True"/>
<getCurrentUser value="True"/>
<getCurrentDb value="True"/>
<getDbs value="True"/>
<getTables value="True"/>
<db value="testdb"/>
<tbl value="users"/>
<getColumns value="True"/>
<dumpTable value="True"/>
<threads value="4"/>
</switches>
<parse>
<item value="current user is DBA: True"/>
<item value="r'Microsoft SQL Server 2005.+Oct 14 2005 00:33:37'"/>
<item value="current user: 'sa'"/>
<item value="current database: 'testdb'"/>
<item value="r'available databases.+5.+master.+model.+msdb.+tempdb.+testdb'"/>
<item value="r'dbo\.sysdiagrams.+dbo\.users'"/>
<item value="r'3 columns.+surname.+varchar'"/>
<item value="r'5 entries.+nameisnull.+'"/>
</parse>
</case>
<case name="MSSQL (--technique=E --is-dba --banner --current-user --current-db --dbs --tables -D testdb -T users --columns --dump)">
<switches>
<url value="http://windowsdev/sqlmap/mssql/iis/get_int.asp?id=1"/>
<isDba value="True"/>
<tech value="E"/>
<getBanner value="True"/>
<getCurrentUser value="True"/>
<getCurrentDb value="True"/>
<getDbs value="True"/>
<getTables value="True"/>
<db value="testdb"/>
<tbl value="users"/>
<getColumns value="True"/>
<dumpTable value="True"/>
</switches>
<parse>
<item value="current user is DBA: True"/>
<item value="r'Microsoft SQL Server 2005.+Oct 14 2005 00:33:37'"/>
<item value="current user: 'sa'"/>
<item value="current database: 'testdb'"/>
<item value="r'available databases.+5.+master.+model.+msdb.+tempdb.+testdb'"/>
<item value="r'dbo\.sysdiagrams.+dbo\.users'"/>
<item value="r'3 columns.+surname.+varchar'"/>
<item value="r'5 entries.+nameisnull.+'"/>
</parse>
</case>
<case name="MSSQL (--technique=U --is-dba --banner --current-user --current-db --dbs --tables -D testdb -T users --columns --dump)">
<switches>
<url value="http://windowsdev/sqlmap/mssql/iis/get_int.asp?id=1"/>
<isDba value="True"/>
<tech value="U"/>
<getBanner value="True"/>
<getCurrentUser value="True"/>
<getCurrentDb value="True"/>
<getDbs value="True"/>
<getTables value="True"/>
<db value="testdb"/>
<tbl value="users"/>
<getColumns value="True"/>
<dumpTable value="True"/>
</switches>
<parse>
<item value="current user is DBA: True"/>
<item value="r'Microsoft SQL Server 2005.+Oct 14 2005 00:33:37'"/>
<item value="current user: 'sa'"/>
<item value="current database: 'testdb'"/>
<item value="r'available databases.+5.+master.+model.+msdb.+tempdb.+testdb'"/>
<item value="r'dbo\.sysdiagrams.+dbo\.users'"/>
<item value="r'3 columns.+surname.+varchar'"/>
<item value="r'5 entries.+nameisnull.+'"/>
</parse>
</case>
<case name="MSSQL partial union (--technique=U --is-dba --banner --current-user --current-db --dbs --tables -D testdb -T users --columns --dump)">
<switches>
<url value="http://windowsdev/sqlmap/mssql/iis/get_int_partialunion.asp?id=1"/>
<isDba value="True"/>
<tech value="U"/>
<getBanner value="True"/>
<getCurrentUser value="True"/>
<getCurrentDb value="True"/>
<getDbs value="True"/>
<getTables value="True"/>
<db value="testdb"/>
<tbl value="users"/>
<getColumns value="True"/>
<dumpTable value="True"/>
</switches>
<parse>
<item value="current user is DBA: True"/>
<item value="r'Microsoft SQL Server 2005.+Oct 14 2005 00:33:37'"/>
<item value="current user: 'sa'"/>
<item value="current database: 'testdb'"/>
<item value="r'available databases.+5.+master.+model.+msdb.+tempdb.+testdb'"/>
<item value="r'dbo\.sysdiagrams.+dbo\.users'"/>
<item value="r'3 columns.+surname.+varchar'"/>
<item value="r'5 entries.+nameisnull.+'"/>
</parse>
</case>
</root>