mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2025-06-15 18:43:16 +03:00
Fixes #3873
This commit is contained in:
parent
94ef433a37
commit
aa2682ec16
|
@ -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.3.8.6"
|
VERSION = "1.3.8.7"
|
||||||
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)
|
||||||
|
|
|
@ -60,6 +60,7 @@ def _addPageTextWords():
|
||||||
|
|
||||||
return wordsList
|
return wordsList
|
||||||
|
|
||||||
|
@stackedmethod
|
||||||
def tableExists(tableFile, regex=None):
|
def tableExists(tableFile, regex=None):
|
||||||
if kb.tableExistsChoice is None and not any(_ for _ in kb.injection.data if _ not in (PAYLOAD.TECHNIQUE.TIME, PAYLOAD.TECHNIQUE.STACKED)) and not conf.direct:
|
if kb.tableExistsChoice is None and not any(_ for _ in kb.injection.data if _ not in (PAYLOAD.TECHNIQUE.TIME, PAYLOAD.TECHNIQUE.STACKED)) and not conf.direct:
|
||||||
warnMsg = "it's not recommended to use '%s' and/or '%s' " % (PAYLOAD.SQLINJECTION[PAYLOAD.TECHNIQUE.TIME], PAYLOAD.SQLINJECTION[PAYLOAD.TECHNIQUE.STACKED])
|
warnMsg = "it's not recommended to use '%s' and/or '%s' " % (PAYLOAD.SQLINJECTION[PAYLOAD.TECHNIQUE.TIME], PAYLOAD.SQLINJECTION[PAYLOAD.TECHNIQUE.STACKED])
|
||||||
|
@ -74,15 +75,17 @@ def tableExists(tableFile, regex=None):
|
||||||
|
|
||||||
result = inject.checkBooleanExpression("%s" % safeStringFormat(BRUTE_TABLE_EXISTS_TEMPLATE, (randomInt(1), randomStr())))
|
result = inject.checkBooleanExpression("%s" % safeStringFormat(BRUTE_TABLE_EXISTS_TEMPLATE, (randomInt(1), randomStr())))
|
||||||
|
|
||||||
if conf.db and Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2):
|
|
||||||
conf.db = conf.db.upper()
|
|
||||||
|
|
||||||
if result:
|
if result:
|
||||||
errMsg = "can't use table existence check because of detected invalid results "
|
errMsg = "can't use table existence check because of detected invalid results "
|
||||||
errMsg += "(most likely caused by inability of the used injection "
|
errMsg += "(most likely caused by inability of the used injection "
|
||||||
errMsg += "to distinguish erroneous results)"
|
errMsg += "to distinguish erroneous results)"
|
||||||
raise SqlmapDataException(errMsg)
|
raise SqlmapDataException(errMsg)
|
||||||
|
|
||||||
|
pushValue(conf.db)
|
||||||
|
|
||||||
|
if conf.db and Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2):
|
||||||
|
conf.db = conf.db.upper()
|
||||||
|
|
||||||
message = "which common tables (wordlist) file do you want to use?\n"
|
message = "which common tables (wordlist) file do you want to use?\n"
|
||||||
message += "[1] default '%s' (press Enter)\n" % tableFile
|
message += "[1] default '%s' (press Enter)\n" % tableFile
|
||||||
message += "[2] custom"
|
message += "[2] custom"
|
||||||
|
@ -92,80 +95,88 @@ def tableExists(tableFile, regex=None):
|
||||||
message = "what's the custom common tables file location?\n"
|
message = "what's the custom common tables file location?\n"
|
||||||
tableFile = readInput(message) or tableFile
|
tableFile = readInput(message) or tableFile
|
||||||
|
|
||||||
infoMsg = "checking table existence using items from '%s'" % tableFile
|
infoMsg = "performing table existence using items from '%s'" % tableFile
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
tables = getFileItems(tableFile, lowercase=Backend.getIdentifiedDbms() in (DBMS.ACCESS,), unique=True)
|
tables = getFileItems(tableFile, lowercase=Backend.getIdentifiedDbms() in (DBMS.ACCESS,), unique=True)
|
||||||
tables.extend(_addPageTextWords())
|
tables.extend(_addPageTextWords())
|
||||||
tables = filterListValue(tables, regex)
|
tables = filterListValue(tables, regex)
|
||||||
|
|
||||||
threadData = getCurrentThreadData()
|
for conf.db in (conf.db.split(',') if conf.db else [conf.db]):
|
||||||
threadData.shared.count = 0
|
if conf.db:
|
||||||
threadData.shared.limit = len(tables)
|
infoMsg = "checking database '%s'" % conf.db
|
||||||
threadData.shared.files = []
|
logger.info(infoMsg)
|
||||||
threadData.shared.unique = set()
|
|
||||||
|
|
||||||
def tableExistsThread():
|
|
||||||
threadData = getCurrentThreadData()
|
threadData = getCurrentThreadData()
|
||||||
|
threadData.shared.count = 0
|
||||||
|
threadData.shared.limit = len(tables)
|
||||||
|
threadData.shared.files = []
|
||||||
|
threadData.shared.unique = set()
|
||||||
|
|
||||||
while kb.threadContinue:
|
def tableExistsThread():
|
||||||
kb.locks.count.acquire()
|
threadData = getCurrentThreadData()
|
||||||
if threadData.shared.count < threadData.shared.limit:
|
|
||||||
table = safeSQLIdentificatorNaming(tables[threadData.shared.count], True)
|
|
||||||
threadData.shared.count += 1
|
|
||||||
kb.locks.count.release()
|
|
||||||
else:
|
|
||||||
kb.locks.count.release()
|
|
||||||
break
|
|
||||||
|
|
||||||
if conf.db and METADB_SUFFIX not in conf.db and Backend.getIdentifiedDbms() not in (DBMS.SQLITE, DBMS.ACCESS, DBMS.FIREBIRD):
|
while kb.threadContinue:
|
||||||
fullTableName = "%s.%s" % (conf.db, table)
|
kb.locks.count.acquire()
|
||||||
else:
|
if threadData.shared.count < threadData.shared.limit:
|
||||||
fullTableName = table
|
table = safeSQLIdentificatorNaming(tables[threadData.shared.count], True)
|
||||||
|
threadData.shared.count += 1
|
||||||
|
kb.locks.count.release()
|
||||||
|
else:
|
||||||
|
kb.locks.count.release()
|
||||||
|
break
|
||||||
|
|
||||||
result = inject.checkBooleanExpression("%s" % safeStringFormat(BRUTE_TABLE_EXISTS_TEMPLATE, (randomInt(1), fullTableName)))
|
if conf.db and METADB_SUFFIX not in conf.db and Backend.getIdentifiedDbms() not in (DBMS.SQLITE, DBMS.ACCESS, DBMS.FIREBIRD):
|
||||||
|
fullTableName = "%s.%s" % (conf.db, table)
|
||||||
|
else:
|
||||||
|
fullTableName = table
|
||||||
|
|
||||||
kb.locks.io.acquire()
|
result = inject.checkBooleanExpression("%s" % safeStringFormat(BRUTE_TABLE_EXISTS_TEMPLATE, (randomInt(1), fullTableName)))
|
||||||
|
|
||||||
if result and table.lower() not in threadData.shared.unique:
|
kb.locks.io.acquire()
|
||||||
threadData.shared.files.append(table)
|
|
||||||
threadData.shared.unique.add(table.lower())
|
|
||||||
|
|
||||||
if conf.verbose in (1, 2) and not conf.api:
|
if result and table.lower() not in threadData.shared.unique:
|
||||||
clearConsoleLine(True)
|
threadData.shared.files.append(table)
|
||||||
infoMsg = "[%s] [INFO] retrieved: %s\n" % (time.strftime("%X"), unsafeSQLIdentificatorNaming(table))
|
threadData.shared.unique.add(table.lower())
|
||||||
dataToStdout(infoMsg, True)
|
|
||||||
|
|
||||||
if conf.verbose in (1, 2):
|
if conf.verbose in (1, 2) and not conf.api:
|
||||||
status = '%d/%d items (%d%%)' % (threadData.shared.count, threadData.shared.limit, round(100.0 * threadData.shared.count / threadData.shared.limit))
|
clearConsoleLine(True)
|
||||||
dataToStdout("\r[%s] [INFO] tried %s" % (time.strftime("%X"), status), True)
|
infoMsg = "[%s] [INFO] retrieved: %s\n" % (time.strftime("%X"), unsafeSQLIdentificatorNaming(table))
|
||||||
|
dataToStdout(infoMsg, True)
|
||||||
|
|
||||||
kb.locks.io.release()
|
if conf.verbose in (1, 2):
|
||||||
|
status = '%d/%d items (%d%%)' % (threadData.shared.count, threadData.shared.limit, round(100.0 * threadData.shared.count / threadData.shared.limit))
|
||||||
|
dataToStdout("\r[%s] [INFO] tried %s" % (time.strftime("%X"), status), True)
|
||||||
|
|
||||||
try:
|
kb.locks.io.release()
|
||||||
runThreads(conf.threads, tableExistsThread, threadChoice=True)
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
warnMsg = "user aborted during table existence "
|
|
||||||
warnMsg += "check. sqlmap will display partial output"
|
|
||||||
logger.warn(warnMsg)
|
|
||||||
|
|
||||||
clearConsoleLine(True)
|
try:
|
||||||
dataToStdout("\n")
|
runThreads(conf.threads, tableExistsThread, threadChoice=True)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
warnMsg = "user aborted during table existence "
|
||||||
|
warnMsg += "check. sqlmap will display partial output"
|
||||||
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
if not threadData.shared.files:
|
clearConsoleLine(True)
|
||||||
warnMsg = "no table(s) found"
|
dataToStdout("\n")
|
||||||
logger.warn(warnMsg)
|
|
||||||
else:
|
|
||||||
for item in threadData.shared.files:
|
|
||||||
if conf.db not in kb.data.cachedTables:
|
|
||||||
kb.data.cachedTables[conf.db] = [item]
|
|
||||||
else:
|
|
||||||
kb.data.cachedTables[conf.db].append(item)
|
|
||||||
|
|
||||||
for _ in ((conf.db, item) for item in threadData.shared.files):
|
if not threadData.shared.files:
|
||||||
if _ not in kb.brute.tables:
|
warnMsg = "no table(s) found"
|
||||||
kb.brute.tables.append(_)
|
if conf.db:
|
||||||
|
warnMsg += "for database '%s'" % conf.db
|
||||||
|
logger.warn(warnMsg)
|
||||||
|
else:
|
||||||
|
for item in threadData.shared.files:
|
||||||
|
if conf.db not in kb.data.cachedTables:
|
||||||
|
kb.data.cachedTables[conf.db] = [item]
|
||||||
|
else:
|
||||||
|
kb.data.cachedTables[conf.db].append(item)
|
||||||
|
|
||||||
|
for _ in ((conf.db, item) for item in threadData.shared.files):
|
||||||
|
if _ not in kb.brute.tables:
|
||||||
|
kb.brute.tables.append(_)
|
||||||
|
|
||||||
|
conf.db = popValue()
|
||||||
hashDBWrite(HASHDB_KEYS.KB_BRUTE_TABLES, kb.brute.tables, True)
|
hashDBWrite(HASHDB_KEYS.KB_BRUTE_TABLES, kb.brute.tables, True)
|
||||||
|
|
||||||
return kb.data.cachedTables
|
return kb.data.cachedTables
|
||||||
|
|
Loading…
Reference in New Issue
Block a user