Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 0605f14

Browse files
committed
Couple of fixes for SAP MaxDB
1 parent 176e89d commit 0605f14

7 files changed

Lines changed: 43 additions & 12 deletions

File tree

data/xml/errors.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@
127127
<error regexp="SQL error.*?POS([0-9]+)"/>
128128
<error regexp="Warning.*?\Wmaxdb_"/>
129129
<error regexp="DriverSapDB"/>
130+
<error regexp="-3014.*?Invalid end of SQL statement"/>
130131
<error regexp="com\.sap\.dbtech\.jdbc"/>
131132
</dbms>
132133

data/xml/queries.xml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -490,12 +490,12 @@
490490
<comment query="--" query2="#"/>
491491
<substring query="SUBSTR((%s),%d,%d)"/>
492492
<concatenate query="CONCAT(%s,%s)"/>
493-
<case query="SELECT (CASE WHEN (%s) THEN 1 ELSE 0 END)"/>
493+
<case query="SELECT (CASE WHEN (%s) THEN '1' ELSE '0' END) FROM VERSIONS"/>
494494
<hex query="HEX(%s)"/>
495495
<inference query="SUBSTR((%s),%d,1)>'%c'"/>
496496
<banner query="SELECT ID FROM SYSINFO.VERSION"/>
497-
<current_user query="SELECT USER() FROM DUAL"/>
498-
<current_db query="SELECT DATABASE() FROM DUAL"/>
497+
<current_user query="SELECT USER() FROM VERSIONS"/>
498+
<current_db query="SELECT USER() FROM VERSIONS"/>
499499
<hostname/>
500500
<table_comment/>
501501
<column_comment/>

lib/core/agent.py

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -720,21 +720,43 @@ def concatQuery(self, query, unpack=True):
720720
warnMsg = "applying generic concatenation (CONCAT)"
721721
singleTimeWarnMessage(warnMsg)
722722

723+
if FROM_DUMMY_TABLE.get(Backend.getIdentifiedDbms()):
724+
_ = re.sub(r"(?i)%s\Z" % re.escape(FROM_DUMMY_TABLE[Backend.getIdentifiedDbms()]), "", concatenatedQuery)
725+
if _ != concatenatedQuery:
726+
concatenatedQuery = _
727+
fieldsSelectFrom = None
728+
723729
if fieldsExists:
724730
concatenatedQuery = concatenatedQuery.replace("SELECT ", "CONCAT(CONCAT('%s'," % kb.chars.start, 1)
725731
concatenatedQuery += "),'%s')" % kb.chars.stop
726732
elif fieldsSelectCase:
727733
concatenatedQuery = concatenatedQuery.replace("SELECT ", "CONCAT(CONCAT('%s'," % kb.chars.start, 1)
728734
concatenatedQuery += "),'%s')" % kb.chars.stop
729-
elif fieldsSelectFrom:
735+
elif fieldsSelectFrom or fieldsSelect:
736+
fromTable = ""
737+
730738
_ = unArrayizeValue(zeroDepthSearch(concatenatedQuery, " FROM "))
731-
concatenatedQuery = "%s),'%s')%s" % (concatenatedQuery[:_].replace("SELECT ", "CONCAT(CONCAT('%s'," % kb.chars.start, 1), kb.chars.stop, concatenatedQuery[_:])
739+
if _:
740+
concatenatedQuery, fromTable = concatenatedQuery[:_], concatenatedQuery[_:]
741+
742+
concatenatedQuery = re.sub(r"(?i)\ASELECT ", "", concatenatedQuery)
743+
replacement = "'%s',%s,'%s'" % (kb.chars.start, concatenatedQuery, kb.chars.stop)
744+
chars = [_ for _ in replacement]
745+
746+
count = 0
747+
for index in zeroDepthSearch(replacement, ',')[1:]:
748+
chars[index] = "),"
749+
count += 1
750+
751+
replacement = "CONCAT(%s%s)" % ("CONCAT(" * count, "".join(chars))
752+
concatenatedQuery = "%s%s" % (replacement, fromTable)
732753
elif fieldsSelect:
733754
concatenatedQuery = concatenatedQuery.replace("SELECT ", "CONCAT(CONCAT('%s'," % kb.chars.start, 1)
734755
concatenatedQuery += "),'%s')" % kb.chars.stop
735756
elif fieldsNoSelect:
736757
concatenatedQuery = "CONCAT(CONCAT('%s',%s),'%s')" % (kb.chars.start, concatenatedQuery, kb.chars.stop)
737758

759+
738760
return concatenatedQuery
739761

740762
def forgeUnionQuery(self, query, position, count, comment, prefix, suffix, char, where, multipleUnions=None, limited=False, fromTable=None):

lib/core/dump.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -164,11 +164,9 @@ def currentUser(self, data):
164164
self.string("current user", data, content_type=CONTENT_TYPE.CURRENT_USER)
165165

166166
def currentDb(self, data):
167-
if Backend.isDbms(DBMS.MAXDB):
168-
self.string("current database (no practical usage on %s)" % Backend.getIdentifiedDbms(), data, content_type=CONTENT_TYPE.CURRENT_DB)
169-
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2, DBMS.MONETDB, DBMS.VERTICA, DBMS.CRATEDB):
167+
if Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2, DBMS.MONETDB, DBMS.VERTICA, DBMS.CRATEDB):
170168
self.string("current schema (equivalent to database on %s)" % Backend.getIdentifiedDbms(), data, content_type=CONTENT_TYPE.CURRENT_DB)
171-
elif Backend.getIdentifiedDbms() in (DBMS.ALTIBASE, DBMS.DB2, DBMS.MIMERSQL):
169+
elif Backend.getIdentifiedDbms() in (DBMS.ALTIBASE, DBMS.DB2, DBMS.MIMERSQL, DBMS.MAXDB):
172170
self.string("current user (equivalent to database on %s)" % Backend.getIdentifiedDbms(), data, content_type=CONTENT_TYPE.CURRENT_DB)
173171
else:
174172
self.string("current database", data, content_type=CONTENT_TYPE.CURRENT_DB)

lib/core/settings.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
from thirdparty.six import unichr as _unichr
1919

2020
# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
21-
VERSION = "1.4.2.30"
21+
VERSION = "1.4.2.31"
2222
TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable"
2323
TYPE_COLORS = {"dev": 33, "stable": 90, "pip": 34}
2424
VERSION_STRING = "sqlmap/%s#%s" % ('.'.join(VERSION.split('.')[:-1]) if VERSION.count('.') > 2 and VERSION.split('.')[-1] == '0' else VERSION, TYPE)

lib/core/testing.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,11 @@ def bedTest():
143143
"""
144144

145145
TESTS = (
146+
# MaxDB
147+
("-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'")),
148+
("-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'")),
149+
("-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 |")),
150+
146151
# Informix
147152
("-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'")),
148153
("-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 |")),

plugins/dbms/maxdb/enumeration.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import re
99

1010
from lib.core.common import isListLike
11+
from lib.core.common import isTechniqueAvailable
1112
from lib.core.common import readInput
1213
from lib.core.common import safeSQLIdentificatorNaming
1314
from lib.core.common import unsafeSQLIdentificatorNaming
@@ -17,6 +18,7 @@
1718
from lib.core.data import paths
1819
from lib.core.data import queries
1920
from lib.core.enums import DBMS
21+
from lib.core.enums import PAYLOAD
2022
from lib.core.exception import SqlmapMissingMandatoryOptionException
2123
from lib.core.exception import SqlmapNoneDataException
2224
from lib.core.exception import SqlmapUserQuitException
@@ -83,7 +85,8 @@ def getTables(self, bruteForce=None):
8385

8486
for db in dbs:
8587
query = rootQuery.inband.query % (("'%s'" % db) if db != "USER" else 'USER')
86-
retVal = pivotDumpTable("(%s) AS %s" % (query, kb.aliasName), ['%s.tablename' % kb.aliasName], blind=True)
88+
blind = not isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION)
89+
retVal = pivotDumpTable("(%s) AS %s" % (query, kb.aliasName), ['%s.tablename' % kb.aliasName], blind=blind)
8790

8891
if retVal:
8992
for table in list(retVal[0].values())[0]:
@@ -204,8 +207,10 @@ def getColumns(self, onlyColNames=False, colTuple=None, bruteForce=None, dumpMod
204207
infoMsg += "on database '%s'" % unsafeSQLIdentificatorNaming(conf.db)
205208
logger.info(infoMsg)
206209

210+
blind = not isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION)
211+
207212
query = rootQuery.inband.query % (unsafeSQLIdentificatorNaming(tbl), ("'%s'" % unsafeSQLIdentificatorNaming(conf.db)) if unsafeSQLIdentificatorNaming(conf.db) != "USER" else 'USER')
208-
retVal = pivotDumpTable("(%s) AS %s" % (query, kb.aliasName), ['%s.columnname' % kb.aliasName, '%s.datatype' % kb.aliasName, '%s.len' % kb.aliasName], blind=True)
213+
retVal = pivotDumpTable("(%s) AS %s" % (query, kb.aliasName), ['%s.columnname' % kb.aliasName, '%s.datatype' % kb.aliasName, '%s.len' % kb.aliasName], blind=blind)
209214

210215
if retVal:
211216
table = {}

0 commit comments

Comments
 (0)