This commit is contained in:
Miroslav Stampar 2019-08-13 12:23:45 +02:00
parent 94ef433a37
commit aa2682ec16
2 changed files with 68 additions and 57 deletions

View File

@ -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)

View File

@ -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