mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2025-06-08 15:13:16 +03:00
Couple of fixes for SAP MaxDB
This commit is contained in:
parent
176e89d978
commit
0605f14d87
|
@ -127,6 +127,7 @@
|
||||||
<error regexp="SQL error.*?POS([0-9]+)"/>
|
<error regexp="SQL error.*?POS([0-9]+)"/>
|
||||||
<error regexp="Warning.*?\Wmaxdb_"/>
|
<error regexp="Warning.*?\Wmaxdb_"/>
|
||||||
<error regexp="DriverSapDB"/>
|
<error regexp="DriverSapDB"/>
|
||||||
|
<error regexp="-3014.*?Invalid end of SQL statement"/>
|
||||||
<error regexp="com\.sap\.dbtech\.jdbc"/>
|
<error regexp="com\.sap\.dbtech\.jdbc"/>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
|
|
|
@ -490,12 +490,12 @@
|
||||||
<comment query="--" query2="#"/>
|
<comment query="--" query2="#"/>
|
||||||
<substring query="SUBSTR((%s),%d,%d)"/>
|
<substring query="SUBSTR((%s),%d,%d)"/>
|
||||||
<concatenate query="CONCAT(%s,%s)"/>
|
<concatenate query="CONCAT(%s,%s)"/>
|
||||||
<case query="SELECT (CASE WHEN (%s) THEN 1 ELSE 0 END)"/>
|
<case query="SELECT (CASE WHEN (%s) THEN '1' ELSE '0' END) FROM VERSIONS"/>
|
||||||
<hex query="HEX(%s)"/>
|
<hex query="HEX(%s)"/>
|
||||||
<inference query="SUBSTR((%s),%d,1)>'%c'"/>
|
<inference query="SUBSTR((%s),%d,1)>'%c'"/>
|
||||||
<banner query="SELECT ID FROM SYSINFO.VERSION"/>
|
<banner query="SELECT ID FROM SYSINFO.VERSION"/>
|
||||||
<current_user query="SELECT USER() FROM DUAL"/>
|
<current_user query="SELECT USER() FROM VERSIONS"/>
|
||||||
<current_db query="SELECT DATABASE() FROM DUAL"/>
|
<current_db query="SELECT USER() FROM VERSIONS"/>
|
||||||
<hostname/>
|
<hostname/>
|
||||||
<table_comment/>
|
<table_comment/>
|
||||||
<column_comment/>
|
<column_comment/>
|
||||||
|
|
|
@ -720,21 +720,43 @@ class Agent(object):
|
||||||
warnMsg = "applying generic concatenation (CONCAT)"
|
warnMsg = "applying generic concatenation (CONCAT)"
|
||||||
singleTimeWarnMessage(warnMsg)
|
singleTimeWarnMessage(warnMsg)
|
||||||
|
|
||||||
|
if FROM_DUMMY_TABLE.get(Backend.getIdentifiedDbms()):
|
||||||
|
_ = re.sub(r"(?i)%s\Z" % re.escape(FROM_DUMMY_TABLE[Backend.getIdentifiedDbms()]), "", concatenatedQuery)
|
||||||
|
if _ != concatenatedQuery:
|
||||||
|
concatenatedQuery = _
|
||||||
|
fieldsSelectFrom = None
|
||||||
|
|
||||||
if fieldsExists:
|
if fieldsExists:
|
||||||
concatenatedQuery = concatenatedQuery.replace("SELECT ", "CONCAT(CONCAT('%s'," % kb.chars.start, 1)
|
concatenatedQuery = concatenatedQuery.replace("SELECT ", "CONCAT(CONCAT('%s'," % kb.chars.start, 1)
|
||||||
concatenatedQuery += "),'%s')" % kb.chars.stop
|
concatenatedQuery += "),'%s')" % kb.chars.stop
|
||||||
elif fieldsSelectCase:
|
elif fieldsSelectCase:
|
||||||
concatenatedQuery = concatenatedQuery.replace("SELECT ", "CONCAT(CONCAT('%s'," % kb.chars.start, 1)
|
concatenatedQuery = concatenatedQuery.replace("SELECT ", "CONCAT(CONCAT('%s'," % kb.chars.start, 1)
|
||||||
concatenatedQuery += "),'%s')" % kb.chars.stop
|
concatenatedQuery += "),'%s')" % kb.chars.stop
|
||||||
elif fieldsSelectFrom:
|
elif fieldsSelectFrom or fieldsSelect:
|
||||||
|
fromTable = ""
|
||||||
|
|
||||||
_ = unArrayizeValue(zeroDepthSearch(concatenatedQuery, " FROM "))
|
_ = unArrayizeValue(zeroDepthSearch(concatenatedQuery, " FROM "))
|
||||||
concatenatedQuery = "%s),'%s')%s" % (concatenatedQuery[:_].replace("SELECT ", "CONCAT(CONCAT('%s'," % kb.chars.start, 1), kb.chars.stop, concatenatedQuery[_:])
|
if _:
|
||||||
|
concatenatedQuery, fromTable = concatenatedQuery[:_], concatenatedQuery[_:]
|
||||||
|
|
||||||
|
concatenatedQuery = re.sub(r"(?i)\ASELECT ", "", concatenatedQuery)
|
||||||
|
replacement = "'%s',%s,'%s'" % (kb.chars.start, concatenatedQuery, kb.chars.stop)
|
||||||
|
chars = [_ for _ in replacement]
|
||||||
|
|
||||||
|
count = 0
|
||||||
|
for index in zeroDepthSearch(replacement, ',')[1:]:
|
||||||
|
chars[index] = "),"
|
||||||
|
count += 1
|
||||||
|
|
||||||
|
replacement = "CONCAT(%s%s)" % ("CONCAT(" * count, "".join(chars))
|
||||||
|
concatenatedQuery = "%s%s" % (replacement, fromTable)
|
||||||
elif fieldsSelect:
|
elif fieldsSelect:
|
||||||
concatenatedQuery = concatenatedQuery.replace("SELECT ", "CONCAT(CONCAT('%s'," % kb.chars.start, 1)
|
concatenatedQuery = concatenatedQuery.replace("SELECT ", "CONCAT(CONCAT('%s'," % kb.chars.start, 1)
|
||||||
concatenatedQuery += "),'%s')" % kb.chars.stop
|
concatenatedQuery += "),'%s')" % kb.chars.stop
|
||||||
elif fieldsNoSelect:
|
elif fieldsNoSelect:
|
||||||
concatenatedQuery = "CONCAT(CONCAT('%s',%s),'%s')" % (kb.chars.start, concatenatedQuery, kb.chars.stop)
|
concatenatedQuery = "CONCAT(CONCAT('%s',%s),'%s')" % (kb.chars.start, concatenatedQuery, kb.chars.stop)
|
||||||
|
|
||||||
|
|
||||||
return concatenatedQuery
|
return concatenatedQuery
|
||||||
|
|
||||||
def forgeUnionQuery(self, query, position, count, comment, prefix, suffix, char, where, multipleUnions=None, limited=False, fromTable=None):
|
def forgeUnionQuery(self, query, position, count, comment, prefix, suffix, char, where, multipleUnions=None, limited=False, fromTable=None):
|
||||||
|
|
|
@ -164,11 +164,9 @@ class Dump(object):
|
||||||
self.string("current user", data, content_type=CONTENT_TYPE.CURRENT_USER)
|
self.string("current user", data, content_type=CONTENT_TYPE.CURRENT_USER)
|
||||||
|
|
||||||
def currentDb(self, data):
|
def currentDb(self, data):
|
||||||
if Backend.isDbms(DBMS.MAXDB):
|
if Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2, DBMS.MONETDB, DBMS.VERTICA, DBMS.CRATEDB):
|
||||||
self.string("current database (no practical usage on %s)" % Backend.getIdentifiedDbms(), data, content_type=CONTENT_TYPE.CURRENT_DB)
|
|
||||||
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2, DBMS.MONETDB, DBMS.VERTICA, DBMS.CRATEDB):
|
|
||||||
self.string("current schema (equivalent to database on %s)" % Backend.getIdentifiedDbms(), data, content_type=CONTENT_TYPE.CURRENT_DB)
|
self.string("current schema (equivalent to database on %s)" % Backend.getIdentifiedDbms(), data, content_type=CONTENT_TYPE.CURRENT_DB)
|
||||||
elif Backend.getIdentifiedDbms() in (DBMS.ALTIBASE, DBMS.DB2, DBMS.MIMERSQL):
|
elif Backend.getIdentifiedDbms() in (DBMS.ALTIBASE, DBMS.DB2, DBMS.MIMERSQL, DBMS.MAXDB):
|
||||||
self.string("current user (equivalent to database on %s)" % Backend.getIdentifiedDbms(), data, content_type=CONTENT_TYPE.CURRENT_DB)
|
self.string("current user (equivalent to database on %s)" % Backend.getIdentifiedDbms(), data, content_type=CONTENT_TYPE.CURRENT_DB)
|
||||||
else:
|
else:
|
||||||
self.string("current database", data, content_type=CONTENT_TYPE.CURRENT_DB)
|
self.string("current database", data, content_type=CONTENT_TYPE.CURRENT_DB)
|
||||||
|
|
|
@ -18,7 +18,7 @@ from lib.core.enums import OS
|
||||||
from thirdparty.six import unichr as _unichr
|
from thirdparty.six import unichr as _unichr
|
||||||
|
|
||||||
# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
|
# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
|
||||||
VERSION = "1.4.2.30"
|
VERSION = "1.4.2.31"
|
||||||
TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable"
|
TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable"
|
||||||
TYPE_COLORS = {"dev": 33, "stable": 90, "pip": 34}
|
TYPE_COLORS = {"dev": 33, "stable": 90, "pip": 34}
|
||||||
VERSION_STRING = "sqlmap/%s#%s" % ('.'.join(VERSION.split('.')[:-1]) if VERSION.count('.') > 2 and VERSION.split('.')[-1] == '0' else VERSION, TYPE)
|
VERSION_STRING = "sqlmap/%s#%s" % ('.'.join(VERSION.split('.')[:-1]) if VERSION.count('.') > 2 and VERSION.split('.')[-1] == '0' else VERSION, TYPE)
|
||||||
|
|
|
@ -143,6 +143,11 @@ def bedTest():
|
||||||
"""
|
"""
|
||||||
|
|
||||||
TESTS = (
|
TESTS = (
|
||||||
|
# MaxDB
|
||||||
|
("-u 'http://testbed/maxdb/get_int.php?id=1' --flush-session --technique=B --is-dba --threads=4 --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("Kernel____7.9.10___Build_003-123-265-343", "Database: TESTB", "Table: TESTUSERS", "5 entries", "ID", "NAME", "SURNAME", "luther", "blisset", "NULL", "Payload: id=1 AND ", "back-end DBMS could be 'SAP MaxDB'", "the back-end DBMS is SAP MaxDB", "current user is DBA: True", ": 'foobar'")),
|
||||||
|
("-u 'http://testbed/maxdb/get_int.php?id=1' --flush-session --technique=U --is-dba --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("Kernel____7.9.10___Build_003-123-265-343", "Database: TESTDB", "Table: TESTUSERS", "5 entries", "ID", "NAME", "SURNAME", "luther", "blisset", "NULL", "Title: Generic UNION query (NULL) - 3 columns", "the back-end DBMS is SAP MaxDB", "appears to have 3 columns", "current user is DBA: True", ": 'foobar'")),
|
||||||
|
("-u 'http://testbed/maxdb/get_int.php?id=1' --flush-session --technique=U --hex --banner --current-user --current-db --search -C surname --answers='dump=n'", ("Kernel____7.9.10___Build_003-123-265-343", "current user (equivalent to database on Altibase): 'SYS'", "current user: 'DBADMIN'", "[1 column]", "| SURNAME | VARCHAR |")),
|
||||||
|
|
||||||
# Informix
|
# Informix
|
||||||
("-u 'http://testbed/informix/get_int.php?id=1' --flush-session --technique=B --is-dba --threads=4 --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("IBM Informix Dynamic Server Version 14.10.FC2DE", "Database: testdb", "Table: users", "5 entries", "id", "name", "surname", "luther", "blisset", "NULL", "Payload: id=1 AND ", "back-end DBMS could be 'Informix'", "the back-end DBMS is Informix", "current user is DBA: True", ": 'foobar'")),
|
("-u 'http://testbed/informix/get_int.php?id=1' --flush-session --technique=B --is-dba --threads=4 --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("IBM Informix Dynamic Server Version 14.10.FC2DE", "Database: testdb", "Table: users", "5 entries", "id", "name", "surname", "luther", "blisset", "NULL", "Payload: id=1 AND ", "back-end DBMS could be 'Informix'", "the back-end DBMS is Informix", "current user is DBA: True", ": 'foobar'")),
|
||||||
("-u 'http://testbed/informix/get_int.php?id=1' --flush-session --hex --banner --current-user --current-db --search -C surname --answers='dump=n'", ("IBM Informix Dynamic Server Version 14.10.FC2DE", "current database: 'testdb'", "current user: 'testuser'", "[1 column]", "| surname | varchar |")),
|
("-u 'http://testbed/informix/get_int.php?id=1' --flush-session --hex --banner --current-user --current-db --search -C surname --answers='dump=n'", ("IBM Informix Dynamic Server Version 14.10.FC2DE", "current database: 'testdb'", "current user: 'testuser'", "[1 column]", "| surname | varchar |")),
|
||||||
|
|
|
@ -8,6 +8,7 @@ See the file 'LICENSE' for copying permission
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from lib.core.common import isListLike
|
from lib.core.common import isListLike
|
||||||
|
from lib.core.common import isTechniqueAvailable
|
||||||
from lib.core.common import readInput
|
from lib.core.common import readInput
|
||||||
from lib.core.common import safeSQLIdentificatorNaming
|
from lib.core.common import safeSQLIdentificatorNaming
|
||||||
from lib.core.common import unsafeSQLIdentificatorNaming
|
from lib.core.common import unsafeSQLIdentificatorNaming
|
||||||
|
@ -17,6 +18,7 @@ from lib.core.data import logger
|
||||||
from lib.core.data import paths
|
from lib.core.data import paths
|
||||||
from lib.core.data import queries
|
from lib.core.data import queries
|
||||||
from lib.core.enums import DBMS
|
from lib.core.enums import DBMS
|
||||||
|
from lib.core.enums import PAYLOAD
|
||||||
from lib.core.exception import SqlmapMissingMandatoryOptionException
|
from lib.core.exception import SqlmapMissingMandatoryOptionException
|
||||||
from lib.core.exception import SqlmapNoneDataException
|
from lib.core.exception import SqlmapNoneDataException
|
||||||
from lib.core.exception import SqlmapUserQuitException
|
from lib.core.exception import SqlmapUserQuitException
|
||||||
|
@ -83,7 +85,8 @@ class Enumeration(GenericEnumeration):
|
||||||
|
|
||||||
for db in dbs:
|
for db in dbs:
|
||||||
query = rootQuery.inband.query % (("'%s'" % db) if db != "USER" else 'USER')
|
query = rootQuery.inband.query % (("'%s'" % db) if db != "USER" else 'USER')
|
||||||
retVal = pivotDumpTable("(%s) AS %s" % (query, kb.aliasName), ['%s.tablename' % kb.aliasName], blind=True)
|
blind = not isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION)
|
||||||
|
retVal = pivotDumpTable("(%s) AS %s" % (query, kb.aliasName), ['%s.tablename' % kb.aliasName], blind=blind)
|
||||||
|
|
||||||
if retVal:
|
if retVal:
|
||||||
for table in list(retVal[0].values())[0]:
|
for table in list(retVal[0].values())[0]:
|
||||||
|
@ -204,8 +207,10 @@ class Enumeration(GenericEnumeration):
|
||||||
infoMsg += "on database '%s'" % unsafeSQLIdentificatorNaming(conf.db)
|
infoMsg += "on database '%s'" % unsafeSQLIdentificatorNaming(conf.db)
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
|
blind = not isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION)
|
||||||
|
|
||||||
query = rootQuery.inband.query % (unsafeSQLIdentificatorNaming(tbl), ("'%s'" % unsafeSQLIdentificatorNaming(conf.db)) if unsafeSQLIdentificatorNaming(conf.db) != "USER" else 'USER')
|
query = rootQuery.inband.query % (unsafeSQLIdentificatorNaming(tbl), ("'%s'" % unsafeSQLIdentificatorNaming(conf.db)) if unsafeSQLIdentificatorNaming(conf.db) != "USER" else 'USER')
|
||||||
retVal = pivotDumpTable("(%s) AS %s" % (query, kb.aliasName), ['%s.columnname' % kb.aliasName, '%s.datatype' % kb.aliasName, '%s.len' % kb.aliasName], blind=True)
|
retVal = pivotDumpTable("(%s) AS %s" % (query, kb.aliasName), ['%s.columnname' % kb.aliasName, '%s.datatype' % kb.aliasName, '%s.len' % kb.aliasName], blind=blind)
|
||||||
|
|
||||||
if retVal:
|
if retVal:
|
||||||
table = {}
|
table = {}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user