mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2024-11-22 01:26:42 +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 sqlmapNoneDataException
|
||||
from lib.core.settings import CURRENT_DB
|
||||
from lib.utils.pivotdumptable import pivotDumpTable
|
||||
from plugins.generic.enumeration import Enumeration as GenericEnumeration
|
||||
|
||||
class Enumeration(GenericEnumeration):
|
||||
|
@ -40,7 +41,7 @@ class Enumeration(GenericEnumeration):
|
|||
rootQuery = queries[Backend.getIdentifiedDbms()].dbs
|
||||
randStr = randomStr()
|
||||
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:
|
||||
kb.data.cachedDbs = retVal[0].values()[0]
|
||||
|
@ -76,7 +77,7 @@ class Enumeration(GenericEnumeration):
|
|||
for db in dbs:
|
||||
randStr = randomStr()
|
||||
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:
|
||||
for table in retVal[0].values()[0]:
|
||||
|
@ -147,7 +148,7 @@ class Enumeration(GenericEnumeration):
|
|||
|
||||
randStr = randomStr()
|
||||
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:
|
||||
table = {}
|
||||
|
|
|
@ -20,6 +20,7 @@ from lib.core.enums import PAYLOAD
|
|||
from lib.core.exception import sqlmapMissingMandatoryOptionException
|
||||
from lib.core.exception import sqlmapNoneDataException
|
||||
from lib.core.settings import CURRENT_DB
|
||||
from lib.utils.pivotdumptable import pivotDumpTable
|
||||
from plugins.generic.enumeration import Enumeration as GenericEnumeration
|
||||
|
||||
class Enumeration(GenericEnumeration):
|
||||
|
@ -41,7 +42,7 @@ class Enumeration(GenericEnumeration):
|
|||
blinds = (True,)
|
||||
|
||||
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:
|
||||
kb.data.cachedUsers = retVal[0].values()[0]
|
||||
|
@ -95,7 +96,7 @@ class Enumeration(GenericEnumeration):
|
|||
blinds = [True]
|
||||
|
||||
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:
|
||||
kb.data.cachedDbs = retVal[0].values()[0]
|
||||
|
@ -140,7 +141,7 @@ class Enumeration(GenericEnumeration):
|
|||
for blind in blinds:
|
||||
randStr = randomStr()
|
||||
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:
|
||||
for table in retVal[0].values()[0]:
|
||||
|
@ -232,7 +233,7 @@ class Enumeration(GenericEnumeration):
|
|||
for blind in blinds:
|
||||
randStr = randomStr()
|
||||
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:
|
||||
table = {}
|
||||
|
|
|
@ -42,6 +42,7 @@ from lib.core.settings import MAX_INT
|
|||
from lib.core.settings import NULL
|
||||
from lib.request import inject
|
||||
from lib.utils.hash import attackDumpedTable
|
||||
from lib.utils.pivotdumptable import pivotDumpTable
|
||||
|
||||
class Entries:
|
||||
"""
|
||||
|
@ -51,129 +52,6 @@ class Entries:
|
|||
def __init__(self):
|
||||
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):
|
||||
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):
|
||||
table = "%s.%s" % (conf.db, tbl)
|
||||
|
||||
retVal = self.__pivotDumpTable(table, colList, blind=False)
|
||||
retVal = pivotDumpTable(table, colList, blind=False)
|
||||
|
||||
if retVal:
|
||||
entries, _ = retVal
|
||||
|
@ -365,7 +243,7 @@ class Entries:
|
|||
elif Backend.isDbms(DBMS.MAXDB):
|
||||
table = "%s.%s" % (conf.db, tbl)
|
||||
|
||||
retVal = self.__pivotDumpTable(table, colList, count, blind=True)
|
||||
retVal = pivotDumpTable(table, colList, count, blind=True)
|
||||
|
||||
if retVal:
|
||||
entries, lengths = retVal
|
||||
|
|
|
@ -39,6 +39,7 @@ from lib.core.exception import sqlmapUserQuitException
|
|||
from lib.core.threads import getCurrentThreadData
|
||||
from lib.request import inject
|
||||
from lib.utils.hash import attackCachedUsersPasswords
|
||||
from lib.utils.pivotdumptable import pivotDumpTable
|
||||
|
||||
class Users:
|
||||
"""
|
||||
|
@ -179,7 +180,7 @@ class Users:
|
|||
randStr = randomStr()
|
||||
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:
|
||||
for user, password in filterPairValues(zip(retVal[0]["%s.name" % randStr], retVal[0]["%s.password" % randStr])):
|
||||
|
@ -221,7 +222,7 @@ class Users:
|
|||
randStr = randomStr()
|
||||
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:
|
||||
for user, password in filterPairValues(zip(retVal[0]["%s.name" % randStr], retVal[0]["%s.password" % randStr])):
|
||||
|
|
Loading…
Reference in New Issue
Block a user