mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2024-11-25 19:13:48 +03:00
Fix for an Issue #179
This commit is contained in:
parent
9a631331a5
commit
1f49e4ae36
|
@ -16,6 +16,7 @@ from lib.core.data import queries
|
||||||
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.settings import CURRENT_DB
|
from lib.core.settings import CURRENT_DB
|
||||||
|
from lib.utils.pivotdumptable import pivotDumpTable
|
||||||
from plugins.generic.enumeration import Enumeration as GenericEnumeration
|
from plugins.generic.enumeration import Enumeration as GenericEnumeration
|
||||||
|
|
||||||
class Enumeration(GenericEnumeration):
|
class Enumeration(GenericEnumeration):
|
||||||
|
@ -40,7 +41,7 @@ class Enumeration(GenericEnumeration):
|
||||||
rootQuery = queries[Backend.getIdentifiedDbms()].dbs
|
rootQuery = queries[Backend.getIdentifiedDbms()].dbs
|
||||||
randStr = randomStr()
|
randStr = randomStr()
|
||||||
query = rootQuery.inband.query
|
query = rootQuery.inband.query
|
||||||
retVal = self.__pivotDumpTable("(%s) AS %s" % (query, randStr), ['%s.schemaname' % randStr], blind=True)
|
retVal = pivotDumpTable("(%s) AS %s" % (query, randStr), ['%s.schemaname' % randStr], blind=True)
|
||||||
|
|
||||||
if retVal:
|
if retVal:
|
||||||
kb.data.cachedDbs = retVal[0].values()[0]
|
kb.data.cachedDbs = retVal[0].values()[0]
|
||||||
|
@ -76,7 +77,7 @@ class Enumeration(GenericEnumeration):
|
||||||
for db in dbs:
|
for db in dbs:
|
||||||
randStr = randomStr()
|
randStr = randomStr()
|
||||||
query = rootQuery.inband.query % (("'%s'" % db) if db != "USER" else 'USER')
|
query = rootQuery.inband.query % (("'%s'" % db) if db != "USER" else 'USER')
|
||||||
retVal = self.__pivotDumpTable("(%s) AS %s" % (query, randStr), ['%s.tablename' % randStr], blind=True)
|
retVal = pivotDumpTable("(%s) AS %s" % (query, randStr), ['%s.tablename' % randStr], blind=True)
|
||||||
|
|
||||||
if retVal:
|
if retVal:
|
||||||
for table in retVal[0].values()[0]:
|
for table in retVal[0].values()[0]:
|
||||||
|
@ -147,7 +148,7 @@ class Enumeration(GenericEnumeration):
|
||||||
|
|
||||||
randStr = randomStr()
|
randStr = randomStr()
|
||||||
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 = self.__pivotDumpTable("(%s) AS %s" % (query, randStr), ['%s.columnname' % randStr,'%s.datatype' % randStr,'%s.len' % randStr], blind=True)
|
retVal = pivotDumpTable("(%s) AS %s" % (query, randStr), ['%s.columnname' % randStr,'%s.datatype' % randStr,'%s.len' % randStr], blind=True)
|
||||||
|
|
||||||
if retVal:
|
if retVal:
|
||||||
table = {}
|
table = {}
|
||||||
|
|
|
@ -20,6 +20,7 @@ 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.settings import CURRENT_DB
|
from lib.core.settings import CURRENT_DB
|
||||||
|
from lib.utils.pivotdumptable import pivotDumpTable
|
||||||
from plugins.generic.enumeration import Enumeration as GenericEnumeration
|
from plugins.generic.enumeration import Enumeration as GenericEnumeration
|
||||||
|
|
||||||
class Enumeration(GenericEnumeration):
|
class Enumeration(GenericEnumeration):
|
||||||
|
@ -41,7 +42,7 @@ class Enumeration(GenericEnumeration):
|
||||||
blinds = (True,)
|
blinds = (True,)
|
||||||
|
|
||||||
for blind in blinds:
|
for blind in blinds:
|
||||||
retVal = self.__pivotDumpTable("(%s) AS %s" % (query, randStr), ['%s.name' % randStr], blind=blind)
|
retVal = pivotDumpTable("(%s) AS %s" % (query, randStr), ['%s.name' % randStr], blind=blind)
|
||||||
|
|
||||||
if retVal:
|
if retVal:
|
||||||
kb.data.cachedUsers = retVal[0].values()[0]
|
kb.data.cachedUsers = retVal[0].values()[0]
|
||||||
|
@ -95,7 +96,7 @@ class Enumeration(GenericEnumeration):
|
||||||
blinds = [True]
|
blinds = [True]
|
||||||
|
|
||||||
for blind in blinds:
|
for blind in blinds:
|
||||||
retVal = self.__pivotDumpTable("(%s) AS %s" % (query, randStr), ['%s.name' % randStr], blind=blind)
|
retVal = pivotDumpTable("(%s) AS %s" % (query, randStr), ['%s.name' % randStr], blind=blind)
|
||||||
|
|
||||||
if retVal:
|
if retVal:
|
||||||
kb.data.cachedDbs = retVal[0].values()[0]
|
kb.data.cachedDbs = retVal[0].values()[0]
|
||||||
|
@ -140,7 +141,7 @@ class Enumeration(GenericEnumeration):
|
||||||
for blind in blinds:
|
for blind in blinds:
|
||||||
randStr = randomStr()
|
randStr = randomStr()
|
||||||
query = rootQuery.inband.query % db
|
query = rootQuery.inband.query % db
|
||||||
retVal = self.__pivotDumpTable("(%s) AS %s" % (query, randStr), ['%s.name' % randStr], blind=blind)
|
retVal = pivotDumpTable("(%s) AS %s" % (query, randStr), ['%s.name' % randStr], blind=blind)
|
||||||
|
|
||||||
if retVal:
|
if retVal:
|
||||||
for table in retVal[0].values()[0]:
|
for table in retVal[0].values()[0]:
|
||||||
|
@ -232,7 +233,7 @@ class Enumeration(GenericEnumeration):
|
||||||
for blind in blinds:
|
for blind in blinds:
|
||||||
randStr = randomStr()
|
randStr = randomStr()
|
||||||
query = rootQuery.inband.query % (conf.db, conf.db, conf.db, conf.db, conf.db, conf.db, conf.db, unsafeSQLIdentificatorNaming(tbl))
|
query = rootQuery.inband.query % (conf.db, conf.db, conf.db, conf.db, conf.db, conf.db, conf.db, unsafeSQLIdentificatorNaming(tbl))
|
||||||
retVal = self.__pivotDumpTable("(%s) AS %s" % (query, randStr), ['%s.name' % randStr,'%s.usertype' % randStr], blind=blind)
|
retVal = pivotDumpTable("(%s) AS %s" % (query, randStr), ['%s.name' % randStr,'%s.usertype' % randStr], blind=blind)
|
||||||
|
|
||||||
if retVal:
|
if retVal:
|
||||||
table = {}
|
table = {}
|
||||||
|
|
|
@ -42,6 +42,7 @@ from lib.core.settings import MAX_INT
|
||||||
from lib.core.settings import NULL
|
from lib.core.settings import NULL
|
||||||
from lib.request import inject
|
from lib.request import inject
|
||||||
from lib.utils.hash import attackDumpedTable
|
from lib.utils.hash import attackDumpedTable
|
||||||
|
from lib.utils.pivotdumptable import pivotDumpTable
|
||||||
|
|
||||||
class Entries:
|
class Entries:
|
||||||
"""
|
"""
|
||||||
|
@ -51,129 +52,6 @@ class Entries:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def __pivotDumpTable(self, table, colList, count=None, blind=True):
|
|
||||||
lengths = {}
|
|
||||||
entries = {}
|
|
||||||
|
|
||||||
dumpNode = queries[Backend.getIdentifiedDbms()].dump_table.blind
|
|
||||||
|
|
||||||
validColumnList = False
|
|
||||||
validPivotValue = False
|
|
||||||
|
|
||||||
if count is None:
|
|
||||||
query = dumpNode.count % table
|
|
||||||
count = inject.getValue(query, inband=False, error=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS) if blind else inject.getValue(query, blind=False, expected=EXPECTED.INT)
|
|
||||||
|
|
||||||
if isinstance(count, basestring) and count.isdigit():
|
|
||||||
count = int(count)
|
|
||||||
|
|
||||||
if count == 0:
|
|
||||||
infoMsg = "table '%s' appears to be empty" % unsafeSQLIdentificatorNaming(table)
|
|
||||||
logger.info(infoMsg)
|
|
||||||
|
|
||||||
for column in colList:
|
|
||||||
lengths[column] = len(column)
|
|
||||||
entries[column] = []
|
|
||||||
|
|
||||||
return entries, lengths
|
|
||||||
|
|
||||||
elif not isNumPosStrValue(count):
|
|
||||||
return None
|
|
||||||
|
|
||||||
for column in colList:
|
|
||||||
lengths[column] = 0
|
|
||||||
entries[column] = BigArray()
|
|
||||||
|
|
||||||
colList = filter(None, sorted(colList, key=lambda x: len(x) if x else MAX_INT))
|
|
||||||
|
|
||||||
for column in colList:
|
|
||||||
infoMsg = "fetching number of distinct "
|
|
||||||
infoMsg += "values for column '%s'" % column
|
|
||||||
logger.info(infoMsg)
|
|
||||||
|
|
||||||
query = dumpNode.count2 % (column, table)
|
|
||||||
value = inject.getValue(query, blind=blind, inband=not blind, error=not blind, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS)
|
|
||||||
|
|
||||||
if isNumPosStrValue(value):
|
|
||||||
validColumnList = True
|
|
||||||
|
|
||||||
if value == count:
|
|
||||||
infoMsg = "using column '%s' as a pivot " % column
|
|
||||||
infoMsg += "for retrieving row data"
|
|
||||||
logger.info(infoMsg)
|
|
||||||
|
|
||||||
validPivotValue = True
|
|
||||||
|
|
||||||
colList.remove(column)
|
|
||||||
colList.insert(0, column)
|
|
||||||
break
|
|
||||||
|
|
||||||
if not validColumnList:
|
|
||||||
errMsg = "all column name(s) provided are non-existent"
|
|
||||||
raise sqlmapNoneDataException, errMsg
|
|
||||||
|
|
||||||
if not validPivotValue:
|
|
||||||
warnMsg = "no proper pivot column provided (with unique values)."
|
|
||||||
warnMsg += " It won't be possible to retrieve all rows"
|
|
||||||
logger.warn(warnMsg)
|
|
||||||
|
|
||||||
pivotValue = " "
|
|
||||||
breakRetrieval = False
|
|
||||||
|
|
||||||
try:
|
|
||||||
for i in xrange(count):
|
|
||||||
if breakRetrieval:
|
|
||||||
break
|
|
||||||
|
|
||||||
for column in colList:
|
|
||||||
# Correction for pivotValues with unrecognized/problematic chars
|
|
||||||
for char in ('\'', '?'):
|
|
||||||
if pivotValue and char in pivotValue and pivotValue[0] != char:
|
|
||||||
pivotValue = pivotValue.split(char)[0]
|
|
||||||
pivotValue = pivotValue[:-1] + decodeIntToUnicode(ord(pivotValue[-1]) + 1)
|
|
||||||
break
|
|
||||||
if column == colList[0]:
|
|
||||||
query = dumpNode.query % (column, table, column, pivotValue)
|
|
||||||
else:
|
|
||||||
query = dumpNode.query2 % (column, table, colList[0], pivotValue)
|
|
||||||
|
|
||||||
value = inject.getValue(query, blind=blind, inband=not blind, error=not blind)
|
|
||||||
|
|
||||||
if column == colList[0]:
|
|
||||||
if isNoneValue(value):
|
|
||||||
breakRetrieval = True
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
pivotValue = safechardecode(value)
|
|
||||||
|
|
||||||
if conf.limitStart or conf.limitStop:
|
|
||||||
if conf.limitStart and (i + 1) < conf.limitStart:
|
|
||||||
warnMsg = "skipping first %d pivot " % conf.limitStart
|
|
||||||
warnMsg += "point values"
|
|
||||||
singleTimeWarnMessage(warnMsg)
|
|
||||||
break
|
|
||||||
elif conf.limitStop and (i + 1) > conf.limitStop:
|
|
||||||
breakRetrieval = True
|
|
||||||
break
|
|
||||||
|
|
||||||
value = "" if isNoneValue(value) else unArrayizeValue(value)
|
|
||||||
|
|
||||||
lengths[column] = max(lengths[column], len(value) if value else 0)
|
|
||||||
entries[column].append(value)
|
|
||||||
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
warnMsg = "user aborted during enumeration. sqlmap "
|
|
||||||
warnMsg += "will display partial output"
|
|
||||||
logger.warn(warnMsg)
|
|
||||||
|
|
||||||
except sqlmapConnectionException, e:
|
|
||||||
errMsg = "connection exception detected. sqlmap "
|
|
||||||
errMsg += "will display partial output"
|
|
||||||
errMsg += "'%s'" % e
|
|
||||||
logger.critical(errMsg)
|
|
||||||
|
|
||||||
return entries, lengths
|
|
||||||
|
|
||||||
def dumpTable(self, foundData=None):
|
def dumpTable(self, foundData=None):
|
||||||
self.forceDbmsEnum()
|
self.forceDbmsEnum()
|
||||||
|
|
||||||
|
@ -269,7 +147,7 @@ class Entries:
|
||||||
if not (isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION) and kb.injection.data[PAYLOAD.TECHNIQUE.UNION].where == PAYLOAD.WHERE.ORIGINAL):
|
if not (isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION) and kb.injection.data[PAYLOAD.TECHNIQUE.UNION].where == PAYLOAD.WHERE.ORIGINAL):
|
||||||
table = "%s.%s" % (conf.db, tbl)
|
table = "%s.%s" % (conf.db, tbl)
|
||||||
|
|
||||||
retVal = self.__pivotDumpTable(table, colList, blind=False)
|
retVal = pivotDumpTable(table, colList, blind=False)
|
||||||
|
|
||||||
if retVal:
|
if retVal:
|
||||||
entries, _ = retVal
|
entries, _ = retVal
|
||||||
|
@ -365,7 +243,7 @@ class Entries:
|
||||||
elif Backend.isDbms(DBMS.MAXDB):
|
elif Backend.isDbms(DBMS.MAXDB):
|
||||||
table = "%s.%s" % (conf.db, tbl)
|
table = "%s.%s" % (conf.db, tbl)
|
||||||
|
|
||||||
retVal = self.__pivotDumpTable(table, colList, count, blind=True)
|
retVal = pivotDumpTable(table, colList, count, blind=True)
|
||||||
|
|
||||||
if retVal:
|
if retVal:
|
||||||
entries, lengths = retVal
|
entries, lengths = retVal
|
||||||
|
|
|
@ -39,6 +39,7 @@ from lib.core.exception import sqlmapUserQuitException
|
||||||
from lib.core.threads import getCurrentThreadData
|
from lib.core.threads import getCurrentThreadData
|
||||||
from lib.request import inject
|
from lib.request import inject
|
||||||
from lib.utils.hash import attackCachedUsersPasswords
|
from lib.utils.hash import attackCachedUsersPasswords
|
||||||
|
from lib.utils.pivotdumptable import pivotDumpTable
|
||||||
|
|
||||||
class Users:
|
class Users:
|
||||||
"""
|
"""
|
||||||
|
@ -179,7 +180,7 @@ class Users:
|
||||||
randStr = randomStr()
|
randStr = randomStr()
|
||||||
getCurrentThreadData().disableStdOut = True
|
getCurrentThreadData().disableStdOut = True
|
||||||
|
|
||||||
retVal = self.__pivotDumpTable("(%s) AS %s" % (query, randStr), ['%s.name' % randStr, '%s.password' % randStr], blind=False)
|
retVal = pivotDumpTable("(%s) AS %s" % (query, randStr), ['%s.name' % randStr, '%s.password' % randStr], blind=False)
|
||||||
|
|
||||||
if retVal:
|
if retVal:
|
||||||
for user, password in filterPairValues(zip(retVal[0]["%s.name" % randStr], retVal[0]["%s.password" % randStr])):
|
for user, password in filterPairValues(zip(retVal[0]["%s.name" % randStr], retVal[0]["%s.password" % randStr])):
|
||||||
|
@ -221,7 +222,7 @@ class Users:
|
||||||
randStr = randomStr()
|
randStr = randomStr()
|
||||||
query = rootQuery.inband.query
|
query = rootQuery.inband.query
|
||||||
|
|
||||||
retVal = self.__pivotDumpTable("(%s) AS %s" % (query, randStr), ['%s.name' % randStr, '%s.password' % randStr], blind=True)
|
retVal = pivotDumpTable("(%s) AS %s" % (query, randStr), ['%s.name' % randStr, '%s.password' % randStr], blind=True)
|
||||||
|
|
||||||
if retVal:
|
if retVal:
|
||||||
for user, password in filterPairValues(zip(retVal[0]["%s.name" % randStr], retVal[0]["%s.password" % randStr])):
|
for user, password in filterPairValues(zip(retVal[0]["%s.name" % randStr], retVal[0]["%s.password" % randStr])):
|
||||||
|
|
Loading…
Reference in New Issue
Block a user