From 282eea37435c28e20acecce5b374fec281b03da9 Mon Sep 17 00:00:00 2001 From: Miroslav Stampar Date: Wed, 6 Nov 2024 12:06:34 +0100 Subject: [PATCH] Another patch for #5798 --- data/txt/sha256sums.txt | 4 +- lib/core/settings.py | 2 +- lib/utils/brute.py | 138 ++++++++++++++++++++-------------------- 3 files changed, 73 insertions(+), 71 deletions(-) diff --git a/data/txt/sha256sums.txt b/data/txt/sha256sums.txt index 05019af1d..502654f7e 100644 --- a/data/txt/sha256sums.txt +++ b/data/txt/sha256sums.txt @@ -188,7 +188,7 @@ bf77f9fc4296f239687297aee1fd6113b34f855965a6f690b52e26bd348cb353 lib/core/profi 4eff81c639a72b261c8ba1c876a01246e718e6626e8e77ae9cc6298b20a39355 lib/core/replication.py bbd1dcda835934728efc6d68686e9b0da72b09b3ee38f3c0ab78e8c18b0ba726 lib/core/revision.py eed6b0a21b3e69c5583133346b0639dc89937bd588887968ee85f8389d7c3c96 lib/core/session.py -d21819319315ee0e2b686639f6ca426b5172d0105315a42b3d3f1a98d1f2e8ad lib/core/settings.py +adc1416c7893869711eda091bb4d8b0699a528f012a79377be3cf3e336b4474a lib/core/settings.py 2bec97d8a950f7b884e31dfe9410467f00d24f21b35672b95f8d68ed59685fd4 lib/core/shell.py e90a359b37a55c446c60e70ccd533f87276714d0b09e34f69b0740fd729ddbf8 lib/core/subprocessng.py 54f7c70b4c7a9931f7ff3c1c12030180bde38e35a306d5e343ad6052919974cd lib/core/target.py @@ -242,7 +242,7 @@ f948fefb0fa67da8cf037f7abbcdbb740148babda9ad8a58fab1693456834817 lib/techniques 700cc5e8cae85bd86674d0cb6c97093fde2c52a480cc1e40ae0010fffd649395 lib/techniques/union/test.py 4252a1829e60bb9a69e3927bf68a320976b8ef637804b7032d7497699f2e89e7 lib/techniques/union/use.py 6b3f83a85c576830783a64e943a58e90b1f25e9e24cd51ae12b1d706796124e9 lib/utils/api.py -1d4d1e49a0897746d4ad64316d4d777f4804c4c11e349e9eb3844130183d4887 lib/utils/brute.py +e00740b9a4c997152fa8b00d3f0abf45ae15e23c33a92966eaa658fde83c586f lib/utils/brute.py c0a4765aa80c5d9b7ef1abe93401a78dd45b2766a1f4ff6286287dc6188294de lib/utils/crawler.py 3f97e327c548d8b5d74fda96a2a0d1b2933b289b9ec2351b06c91cefdd38629d lib/utils/deps.py e81393f0d077578e6dcd3db2887e93ac2bfbdef2ce87686e83236a36112ca7d3 lib/utils/getch.py diff --git a/lib/core/settings.py b/lib/core/settings.py index cb7871248..640e0ede6 100644 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -19,7 +19,7 @@ from lib.core.enums import OS from thirdparty import six # sqlmap version (...) -VERSION = "1.8.11.0" +VERSION = "1.8.11.1" TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable" 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) diff --git a/lib/utils/brute.py b/lib/utils/brute.py index 89577fff8..2db4058fa 100644 --- a/lib/utils/brute.py +++ b/lib/utils/brute.py @@ -228,93 +228,95 @@ def columnExists(columnFile, regex=None): columns.extend(_addPageTextWords()) columns = filterListValue(columns, regex) - table = safeSQLIdentificatorNaming(conf.tbl, True) + for table in conf.tbl.split(','): + table = safeSQLIdentificatorNaming(table, True) - if conf.db and METADB_SUFFIX not in conf.db and Backend.getIdentifiedDbms() not in (DBMS.SQLITE, DBMS.ACCESS, DBMS.FIREBIRD): - table = "%s.%s" % (safeSQLIdentificatorNaming(conf.db), table) + if conf.db and METADB_SUFFIX not in conf.db and Backend.getIdentifiedDbms() not in (DBMS.SQLITE, DBMS.ACCESS, DBMS.FIREBIRD): + table = "%s.%s" % (safeSQLIdentificatorNaming(conf.db), table) - kb.threadContinue = True - kb.bruteMode = True + kb.threadContinue = True + kb.bruteMode = True - threadData = getCurrentThreadData() - threadData.shared.count = 0 - threadData.shared.limit = len(columns) - threadData.shared.files = [] - - def columnExistsThread(): threadData = getCurrentThreadData() + threadData.shared.count = 0 + threadData.shared.limit = len(columns) + threadData.shared.files = [] - while kb.threadContinue: - kb.locks.count.acquire() - if threadData.shared.count < threadData.shared.limit: - column = safeSQLIdentificatorNaming(columns[threadData.shared.count]) - threadData.shared.count += 1 - kb.locks.count.release() - else: - kb.locks.count.release() - break + def columnExistsThread(): + threadData = getCurrentThreadData() - if Backend.isDbms(DBMS.MCKOI): - result = inject.checkBooleanExpression(safeStringFormat("0<(SELECT COUNT(%s) FROM %s)", (column, table))) - else: - result = inject.checkBooleanExpression(safeStringFormat(BRUTE_COLUMN_EXISTS_TEMPLATE, (column, table))) + while kb.threadContinue: + kb.locks.count.acquire() - kb.locks.io.acquire() + if threadData.shared.count < threadData.shared.limit: + column = safeSQLIdentificatorNaming(columns[threadData.shared.count]) + threadData.shared.count += 1 + kb.locks.count.release() + else: + kb.locks.count.release() + break - if result: - threadData.shared.files.append(column) + if Backend.isDbms(DBMS.MCKOI): + result = inject.checkBooleanExpression(safeStringFormat("0<(SELECT COUNT(%s) FROM %s)", (column, table))) + else: + result = inject.checkBooleanExpression(safeStringFormat(BRUTE_COLUMN_EXISTS_TEMPLATE, (column, table))) - if conf.verbose in (1, 2) and not conf.api: - clearConsoleLine(True) - infoMsg = "[%s] [INFO] retrieved: %s\n" % (time.strftime("%X"), unsafeSQLIdentificatorNaming(column)) - dataToStdout(infoMsg, True) + kb.locks.io.acquire() - 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) + if result: + threadData.shared.files.append(column) - kb.locks.io.release() + if conf.verbose in (1, 2) and not conf.api: + clearConsoleLine(True) + infoMsg = "[%s] [INFO] retrieved: %s\n" % (time.strftime("%X"), unsafeSQLIdentificatorNaming(column)) + dataToStdout(infoMsg, True) - try: - runThreads(conf.threads, columnExistsThread, threadChoice=True) - except KeyboardInterrupt: - warnMsg = "user aborted during column existence " - warnMsg += "check. sqlmap will display partial output" - logger.warning(warnMsg) - finally: - kb.bruteMode = False + 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) - clearConsoleLine(True) - dataToStdout("\n") + kb.locks.io.release() - if not threadData.shared.files: - warnMsg = "no column(s) found" - logger.warning(warnMsg) - else: - columns = {} + try: + runThreads(conf.threads, columnExistsThread, threadChoice=True) + except KeyboardInterrupt: + warnMsg = "user aborted during column existence " + warnMsg += "check. sqlmap will display partial output" + logger.warning(warnMsg) + finally: + kb.bruteMode = False - for column in threadData.shared.files: - if Backend.getIdentifiedDbms() in (DBMS.MYSQL,): - result = not inject.checkBooleanExpression("%s" % safeStringFormat("EXISTS(SELECT %s FROM %s WHERE %s REGEXP '[^0-9]')", (column, table, column))) - elif Backend.getIdentifiedDbms() in (DBMS.SQLITE,): - result = inject.checkBooleanExpression("%s" % safeStringFormat("EXISTS(SELECT %s FROM %s WHERE %s NOT GLOB '*[^0-9]*')", (column, table, column))) - elif Backend.getIdentifiedDbms() in (DBMS.MCKOI,): - result = inject.checkBooleanExpression("%s" % safeStringFormat("0=(SELECT MAX(%s)-MAX(%s) FROM %s)", (column, column, table))) - else: - result = inject.checkBooleanExpression("%s" % safeStringFormat("EXISTS(SELECT %s FROM %s WHERE ROUND(%s)=ROUND(%s))", (column, table, column, column))) + clearConsoleLine(True) + dataToStdout("\n") - if result: - columns[column] = "numeric" - else: - columns[column] = "non-numeric" + if not threadData.shared.files: + warnMsg = "no column(s) found" + logger.warning(warnMsg) + else: + columns = {} - kb.data.cachedColumns[conf.db] = {conf.tbl: columns} + for column in threadData.shared.files: + if Backend.getIdentifiedDbms() in (DBMS.MYSQL,): + result = not inject.checkBooleanExpression("%s" % safeStringFormat("EXISTS(SELECT %s FROM %s WHERE %s REGEXP '[^0-9]')", (column, table, column))) + elif Backend.getIdentifiedDbms() in (DBMS.SQLITE,): + result = inject.checkBooleanExpression("%s" % safeStringFormat("EXISTS(SELECT %s FROM %s WHERE %s NOT GLOB '*[^0-9]*')", (column, table, column))) + elif Backend.getIdentifiedDbms() in (DBMS.MCKOI,): + result = inject.checkBooleanExpression("%s" % safeStringFormat("0=(SELECT MAX(%s)-MAX(%s) FROM %s)", (column, column, table))) + else: + result = inject.checkBooleanExpression("%s" % safeStringFormat("EXISTS(SELECT %s FROM %s WHERE ROUND(%s)=ROUND(%s))", (column, table, column, column))) - for _ in ((conf.db, conf.tbl, item[0], item[1]) for item in columns.items()): - if _ not in kb.brute.columns: - kb.brute.columns.append(_) + if result: + columns[column] = "numeric" + else: + columns[column] = "non-numeric" - hashDBWrite(HASHDB_KEYS.KB_BRUTE_COLUMNS, kb.brute.columns, True) + kb.data.cachedColumns[conf.db] = {table: columns} + + for _ in ((conf.db, table, item[0], item[1]) for item in columns.items()): + if _ not in kb.brute.columns: + kb.brute.columns.append(_) + + hashDBWrite(HASHDB_KEYS.KB_BRUTE_COLUMNS, kb.brute.columns, True) return kb.data.cachedColumns