From d5de5306d66e0c95000d7aed5f75fb0582aec6ae Mon Sep 17 00:00:00 2001 From: Bernardo Damele Date: Mon, 21 Jan 2013 16:38:31 +0000 Subject: [PATCH 01/12] minor fixes following recent enhancements --- xml/livetests.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/xml/livetests.xml b/xml/livetests.xml index d2b7d4d0a..135a95037 100644 --- a/xml/livetests.xml +++ b/xml/livetests.xml @@ -807,7 +807,7 @@ - + @@ -839,7 +839,7 @@ - + @@ -927,7 +927,7 @@ - + + --> @@ -1005,7 +1005,7 @@ - + From 3cfa6cd191274538f1cf916f30af68e783658a71 Mon Sep 17 00:00:00 2001 From: Bernardo Damele Date: Mon, 21 Jan 2013 16:41:47 +0000 Subject: [PATCH 02/12] minor adjustments --- xml/livetests.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xml/livetests.xml b/xml/livetests.xml index 135a95037..516a28f99 100644 --- a/xml/livetests.xml +++ b/xml/livetests.xml @@ -2467,7 +2467,7 @@ - + From d43b04c5829aa4c7143049e9cfc98de0c47906d9 Mon Sep 17 00:00:00 2001 From: Bernardo Damele Date: Mon, 21 Jan 2013 17:09:35 +0000 Subject: [PATCH 03/12] better detection if vulnerable of not for regression test --- lib/core/testing.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/core/testing.py b/lib/core/testing.py index ff4ed5258..e229ea3ca 100644 --- a/lib/core/testing.py +++ b/lib/core/testing.py @@ -139,6 +139,7 @@ def liveTest(): parse = [] switches = dict(global_) value = "" + vulnerable = True if case.hasAttribute("name"): name = case.getAttribute("name") @@ -165,7 +166,10 @@ def liveTest(): msg = "running live test case: %s (%d/%d)" % (name, count, length) logger.info(msg) - result = runCase(switches, parse) + try: + runCase(switches, parse) + except SqlmapNotVulnerableException: + vulnerable = False test_case_fd = codecs.open(os.path.join(paths.SQLMAP_OUTPUT_PATH, "test_case"), "wb", UNICODE_ENCODING) test_case_fd.write("%s\n" % name) @@ -182,7 +186,7 @@ def liveTest(): errMsg += "- scan folder: %s " % paths.SQLMAP_OUTPUT_PATH errMsg += "- traceback: %s" % bool(failedTraceBack) - if result is False: + if not vulnerable: errMsg += " - SQL injection not detected" logger.error(errMsg) From e558040810859277e6d50d4df33d037a53606ac3 Mon Sep 17 00:00:00 2001 From: Bernardo Damele Date: Mon, 21 Jan 2013 17:10:56 +0000 Subject: [PATCH 04/12] minor fix to previous commit --- lib/core/testing.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/core/testing.py b/lib/core/testing.py index e229ea3ca..137b0a7fb 100644 --- a/lib/core/testing.py +++ b/lib/core/testing.py @@ -140,6 +140,7 @@ def liveTest(): switches = dict(global_) value = "" vulnerable = True + result = None if case.hasAttribute("name"): name = case.getAttribute("name") @@ -167,14 +168,14 @@ def liveTest(): logger.info(msg) try: - runCase(switches, parse) + result = runCase(switches, parse) except SqlmapNotVulnerableException: vulnerable = False test_case_fd = codecs.open(os.path.join(paths.SQLMAP_OUTPUT_PATH, "test_case"), "wb", UNICODE_ENCODING) test_case_fd.write("%s\n" % name) - if result: + if result is True: logger.info("test passed") cleanCase() else: From e9dea8d3942355c5b90630d9b40861b994f60ff9 Mon Sep 17 00:00:00 2001 From: Bernardo Damele Date: Mon, 21 Jan 2013 17:11:46 +0000 Subject: [PATCH 05/12] no need to raise an exception if one enumeration fails --- plugins/generic/users.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/generic/users.py b/plugins/generic/users.py index d0c8c4167..438c2929b 100644 --- a/plugins/generic/users.py +++ b/plugins/generic/users.py @@ -135,7 +135,7 @@ class Users: if not kb.data.cachedUsers: errMsg = "unable to retrieve the database users" - raise SqlmapNoneDataException(errMsg) + logger.error(errMsg) return kb.data.cachedUsers From f3cead17294bc0abe44469f70771f70d34f282da Mon Sep 17 00:00:00 2001 From: Bernardo Damele Date: Mon, 21 Jan 2013 20:05:25 +0000 Subject: [PATCH 06/12] cosmetics --- extra/shutils/regressiontest.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/extra/shutils/regressiontest.py b/extra/shutils/regressiontest.py index 6b280ef48..06cc37c5a 100644 --- a/extra/shutils/regressiontest.py +++ b/extra/shutils/regressiontest.py @@ -71,7 +71,7 @@ def main(): stdout, stderr = proc.communicate() if stderr: - msg = prepare_email("Execution of regression test failed with error: %s" % stderr) + msg = prepare_email("Execution of regression test failed with error:\n\n%s" % stderr) send_email(msg) sys.exit(1) @@ -112,13 +112,15 @@ def main(): if parse: content += " at parsing: %s:\n\n" % parse content += "### Log file:\n\n" - content += "%s\n" % log + content += "%s\n\n" % log elif not detected: content += " - SQL injection not detected\n\n" + else: + content += "\n\n" if traceback: - content += "\n\n### Traceback:\n\n" - content += "%s\n" % str(traceback) + content += "### Traceback:\n\n" + content += "%s\n\n" % str(traceback) content += "#######################################################################\n\n" @@ -137,4 +139,3 @@ def main(): if __name__ == "__main__": main() - From bc5a7e49e946b9407993dd6d8aa70b3532dfea5c Mon Sep 17 00:00:00 2001 From: Bernardo Damele Date: Mon, 21 Jan 2013 20:53:11 +0000 Subject: [PATCH 07/12] done with DB2 test cases (issue #312) --- xml/livetests.xml | 119 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 117 insertions(+), 2 deletions(-) diff --git a/xml/livetests.xml b/xml/livetests.xml index 516a28f99..e9aff7d70 100644 --- a/xml/livetests.xml +++ b/xml/livetests.xml @@ -2184,7 +2184,101 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2425,7 +2519,28 @@ - + + + + + + + + + + + + + + + + + + + + + + From d2ff9bccbbbc41e27f2f28feea7e6db2a519073f Mon Sep 17 00:00:00 2001 From: Bernardo Damele Date: Mon, 21 Jan 2013 21:00:03 +0000 Subject: [PATCH 08/12] minor adjustment --- xml/livetests.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/xml/livetests.xml b/xml/livetests.xml index e9aff7d70..9bc5e3264 100644 --- a/xml/livetests.xml +++ b/xml/livetests.xml @@ -2524,10 +2524,10 @@ - + - + @@ -2535,10 +2535,10 @@ - + - + From e23340f00263781c229e0ada0b2806378aaa3251 Mon Sep 17 00:00:00 2001 From: Bernardo Damele Date: Tue, 22 Jan 2013 09:53:05 +0000 Subject: [PATCH 09/12] added support for search for tables on Firebird (issue #365) --- plugins/dbms/firebird/enumeration.py | 10 ---------- plugins/generic/search.py | 23 ++++++++++++++++------- xml/queries.xml | 8 +++++--- 3 files changed, 21 insertions(+), 20 deletions(-) diff --git a/plugins/dbms/firebird/enumeration.py b/plugins/dbms/firebird/enumeration.py index 1f7fc8cab..0d49a9028 100644 --- a/plugins/dbms/firebird/enumeration.py +++ b/plugins/dbms/firebird/enumeration.py @@ -30,22 +30,12 @@ class Enumeration(GenericEnumeration): return [] - def searchTable(self): - warnMsg = "on Firebird searching of tables is not implemented" - logger.warn(warnMsg) - - return [] - def searchColumn(self): warnMsg = "on Firebird searching of columns is not implemented" logger.warn(warnMsg) return [] - def search(self): - warnMsg = "on Firebird search option is not available" - logger.warn(warnMsg) - def getHostname(self): warnMsg = "on Firebird it is not possible to enumerate the hostname" logger.warn(warnMsg) diff --git a/plugins/generic/search.py b/plugins/generic/search.py index e4d6a89e6..69364d8f2 100644 --- a/plugins/generic/search.py +++ b/plugins/generic/search.py @@ -194,13 +194,14 @@ class Search: query += whereDbsQuery values = inject.getValue(query, blind=False, time=False) - if Backend.isDbms(DBMS.SQLITE): + if Backend.getIdentifiedDbms() in (DBMS.SQLITE, DBMS.FIREBIRD): newValues = [] if isinstance(values, basestring): values = [values] for value in values: - newValues.append(["SQLite%s" % METADB_SUFFIX, value]) + dbName = "SQLite" if Backend.isDbms(DBMS.SQLITE) else "Firebird" + newValues.append(["%s%s" % (dbName, METADB_SUFFIX), value]) values = newValues @@ -216,7 +217,7 @@ class Search: else: foundTbls[foundDb] = [foundTbl] else: - if not Backend.isDbms(DBMS.SQLITE): + if Backend.getIdentifiedDbms() not in (DBMS.SQLITE, DBMS.FIREBIRD): infoMsg = "fetching number of databases with table" if tblConsider == "1": infoMsg += "s like" @@ -259,7 +260,8 @@ class Search: if tblConsider == "2": continue else: - foundTbls["SQLite%s" % METADB_SUFFIX] = [] + dbName = "SQLite" if Backend.isDbms(DBMS.SQLITE) else "Firebird" + foundTbls["%s%s" % (dbName, METADB_SUFFIX)] = [] for db in foundTbls.keys(): db = safeSQLIdentificatorNaming(db) @@ -271,7 +273,7 @@ class Search: logger.info(infoMsg) query = rootQuery.blind.count2 - if not Backend.isDbms(DBMS.SQLITE): + if Backend.getIdentifiedDbms() not in (DBMS.SQLITE, DBMS.FIREBIRD): query = query % unsafeSQLIdentificatorNaming(db) query += " AND %s" % tblQuery count = inject.getValue(query, union=False, error=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS) @@ -290,10 +292,17 @@ class Search: for index in indexRange: query = rootQuery.blind.query2 - if not Backend.isDbms(DBMS.SQLITE): + + if Backend.isDbms(DBMS.FIREBIRD): + query = query % index + + if Backend.getIdentifiedDbms() not in (DBMS.SQLITE, DBMS.FIREBIRD): query = query % unsafeSQLIdentificatorNaming(db) + query += " AND %s" % tblQuery - query = agent.limitQuery(index, query) + + if not Backend.isDbms(DBMS.FIREBIRD): + query = agent.limitQuery(index, query) foundTbl = unArrayizeValue(inject.getValue(query, union=False, error=False)) kb.hintValue = foundTbl diff --git a/xml/queries.xml b/xml/queries.xml index 63c5983dd..83fdc416f 100644 --- a/xml/queries.xml +++ b/xml/queries.xml @@ -431,17 +431,19 @@ - + + + + + - - From 11413a0f03aa9c67c26ff0f01e577210e84d6db7 Mon Sep 17 00:00:00 2001 From: Bernardo Damele Date: Tue, 22 Jan 2013 10:04:17 +0000 Subject: [PATCH 10/12] added Firebird search test cases --- plugins/dbms/firebird/enumeration.py | 2 +- xml/livetests.xml | 37 ++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/plugins/dbms/firebird/enumeration.py b/plugins/dbms/firebird/enumeration.py index 0d49a9028..16e444b8a 100644 --- a/plugins/dbms/firebird/enumeration.py +++ b/plugins/dbms/firebird/enumeration.py @@ -31,7 +31,7 @@ class Enumeration(GenericEnumeration): return [] def searchColumn(self): - warnMsg = "on Firebird searching of columns is not implemented" + warnMsg = "on Firebird it is not possible to search columns" logger.warn(warnMsg) return [] diff --git a/xml/livetests.xml b/xml/livetests.xml index 9bc5e3264..0f3aa26b7 100644 --- a/xml/livetests.xml +++ b/xml/livetests.xml @@ -2316,6 +2316,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From edb977a74e58dd37697f18ca9172433b5374c38a Mon Sep 17 00:00:00 2001 From: Bernardo Damele Date: Tue, 22 Jan 2013 10:14:35 +0000 Subject: [PATCH 11/12] bug fix so that if search fails with union/error and blind techniques are available, it falls back to them (like any other enumeration switch) and minor bug fix so that in search mode, the provided table name to search is upped --- plugins/generic/search.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/plugins/generic/search.py b/plugins/generic/search.py index 69364d8f2..f0e968581 100644 --- a/plugins/generic/search.py +++ b/plugins/generic/search.py @@ -91,7 +91,8 @@ class Search: for value in values: value = safeSQLIdentificatorNaming(value) foundDbs.append(value) - else: + + if len(foundDbs) == 0 and isInferenceAvailable() and not conf.direct: infoMsg = "fetching number of database" if dbConsider == "1": infoMsg += "s like" @@ -166,7 +167,7 @@ class Search: for tbl in tblList: tbl = safeSQLIdentificatorNaming(tbl, True) - if Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2): + if Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.FIREBIRD): tbl = tbl.upper() infoMsg = "searching table" @@ -194,7 +195,7 @@ class Search: query += whereDbsQuery values = inject.getValue(query, blind=False, time=False) - if Backend.getIdentifiedDbms() in (DBMS.SQLITE, DBMS.FIREBIRD): + if values and Backend.getIdentifiedDbms() in (DBMS.SQLITE, DBMS.FIREBIRD): newValues = [] if isinstance(values, basestring): @@ -216,7 +217,8 @@ class Search: foundTbls[foundDb].append(foundTbl) else: foundTbls[foundDb] = [foundTbl] - else: + + if len(foundTbls) == 0 and isInferenceAvailable() and not conf.direct: if Backend.getIdentifiedDbms() not in (DBMS.SQLITE, DBMS.FIREBIRD): infoMsg = "fetching number of databases with table" if tblConsider == "1": @@ -445,7 +447,8 @@ class Search: foundCols[column][db] = [tbl] kb.data.cachedColumns = {} - else: + + if len(dbs) == 0 and isInferenceAvailable() and not conf.direct: if not conf.db: infoMsg = "fetching number of databases with tables containing column" if colConsider == "1": From bd7fd862b0a97441845021d97b74b99892adc5e8 Mon Sep 17 00:00:00 2001 From: Bernardo Damele Date: Tue, 22 Jan 2013 10:16:18 +0000 Subject: [PATCH 12/12] forgot import --- plugins/generic/search.py | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/generic/search.py b/plugins/generic/search.py index f0e968581..e30b6ac33 100644 --- a/plugins/generic/search.py +++ b/plugins/generic/search.py @@ -10,6 +10,7 @@ from lib.core.common import arrayizeValue from lib.core.common import Backend from lib.core.common import filterPairValues from lib.core.common import getLimitRange +from lib.core.common import isInferenceAvailable from lib.core.common import isNoneValue from lib.core.common import isNumPosStrValue from lib.core.common import isTechniqueAvailable