update regarding brute force retrieval of table names and table column names

This commit is contained in:
Miroslav Stampar 2010-11-09 16:15:55 +00:00
parent 45f2d8f5d2
commit a7fa8d4975
4 changed files with 106 additions and 67 deletions

View File

@ -16,6 +16,7 @@ from lib.core.data import paths
from lib.core.exception import sqlmapUnsupportedDBMSException from lib.core.exception import sqlmapUnsupportedDBMSException
from lib.core.settings import SUPPORTED_DBMS from lib.core.settings import SUPPORTED_DBMS
from lib.techniques.blind.timebased import timeTest from lib.techniques.blind.timebased import timeTest
from lib.techniques.brute.use import columnExists
from lib.techniques.brute.use import tableExists from lib.techniques.brute.use import tableExists
from lib.techniques.error.test import errorTest from lib.techniques.error.test import errorTest
from lib.techniques.inband.union.test import unionTest from lib.techniques.inband.union.test import unionTest
@ -105,15 +106,15 @@ def action():
if conf.getTables: if conf.getTables:
conf.dumper.dbTables(conf.dbmsHandler.getTables()) conf.dumper.dbTables(conf.dbmsHandler.getTables())
if conf.cExists: if conf.bruteTables:
conf.dumper.dbTables(tableExists(paths.COMMON_TABLES)) conf.dumper.dbTables(tableExists(paths.COMMON_TABLES))
if conf.tableFile:
conf.dumper.dbTables(tableExists(conf.tableFile))
if conf.getColumns: if conf.getColumns:
conf.dumper.dbTableColumns(conf.dbmsHandler.getColumns()) conf.dumper.dbTableColumns(conf.dbmsHandler.getColumns())
if conf.bruteColumns:
conf.dumper.dbTableColumns(columnExists(paths.COMMON_COLUMNS))
if conf.dumpTable: if conf.dumpTable:
conf.dumper.dbTableValues(conf.dbmsHandler.dumpTable()) conf.dumper.dbTableValues(conf.dbmsHandler.dumpTable())

View File

@ -148,7 +148,7 @@ class Dump:
dbTables.sort(key=lambda x: x.lower()) dbTables.sort(key=lambda x: x.lower())
self.__write("Brute-forced tables:") self.__write("Brute-forced table names:")
if len(dbTables) == 1: if len(dbTables) == 1:
self.__write("[1 table]") self.__write("[1 table]")
@ -199,69 +199,96 @@ class Dump:
self.string("tables", dbTables) self.string("tables", dbTables)
def dbTableColumns(self, tableColumns): def dbTableColumns(self, tableColumns):
for db, tables in tableColumns.items(): if isinstance(tableColumns, list) and len(tableColumns) > 0:
if not db: maxlength = 0
db = "All"
for table, columns in tables.items(): for table in tableColumns:
maxlength1 = 0 maxlength = max(maxlength, len(table))
maxlength2 = 0
colList = columns.keys() lines = "-" * (int(maxlength) + 2)
colList.sort(key=lambda x: x.lower())
for column in colList: tableColumns.sort(key=lambda x: x.lower())
colType = columns[column]
maxlength1 = max(maxlength1, len(column)) self.__write("Brute-forced column names for table '%s':" % conf.tbl)
if len(tableColumns) == 1:
self.__write("[1 column]")
else:
self.__write("[%d columns]" % len(tableColumns))
self.__write("+%s+" % lines)
for table in tableColumns:
blank = " " * (maxlength - len(table))
self.__write("| %s%s |" % (table, blank))
self.__write("+%s+\n" % lines)
elif isinstance(tableColumns, dict) and len(tableColumns) > 0:
for db, tables in tableColumns.items():
if not db:
db = "All"
for table, columns in tables.items():
maxlength1 = 0
maxlength2 = 0
colList = columns.keys()
colList.sort(key=lambda x: x.lower())
for column in colList:
colType = columns[column]
maxlength1 = max(maxlength1, len(column))
if colType is not None:
maxlength2 = max(maxlength2, len(colType))
maxlength1 = max(maxlength1, len("COLUMN"))
lines1 = "-" * (int(maxlength1) + 2)
if colType is not None: if colType is not None:
maxlength2 = max(maxlength2, len(colType)) maxlength2 = max(maxlength2, len("TYPE"))
lines2 = "-" * (int(maxlength2) + 2)
maxlength1 = max(maxlength1, len("COLUMN")) self.__write("Database: %s\nTable: %s" % (db, table))
lines1 = "-" * (int(maxlength1) + 2)
if colType is not None: if len(columns) == 1:
maxlength2 = max(maxlength2, len("TYPE")) self.__write("[1 column]")
lines2 = "-" * (int(maxlength2) + 2)
self.__write("Database: %s\nTable: %s" % (db, table))
if len(columns) == 1:
self.__write("[1 column]")
else:
self.__write("[%d columns]" % len(columns))
if colType is not None:
self.__write("+%s+%s+" % (lines1, lines2))
else:
self.__write("+%s+" % lines1)
blank1 = " " * (maxlength1 - len("COLUMN"))
if colType is not None:
blank2 = " " * (maxlength2 - len("TYPE"))
if colType is not None:
self.__write("| Column%s | Type%s |" % (blank1, blank2))
self.__write("+%s+%s+" % (lines1, lines2))
else:
self.__write("| Column%s |" % blank1)
self.__write("+%s+" % lines1)
for column in colList:
colType = columns[column]
blank1 = " " * (maxlength1 - len(column))
if colType is not None:
blank2 = " " * (maxlength2 - len(colType))
self.__write("| %s%s | %s%s |" % (column, blank1, colType, blank2))
else: else:
self.__write("| %s%s |" % (column, blank1)) self.__write("[%d columns]" % len(columns))
if colType is not None: if colType is not None:
self.__write("+%s+%s+\n" % (lines1, lines2)) self.__write("+%s+%s+" % (lines1, lines2))
else: else:
self.__write("+%s+\n" % lines1) self.__write("+%s+" % lines1)
blank1 = " " * (maxlength1 - len("COLUMN"))
if colType is not None:
blank2 = " " * (maxlength2 - len("TYPE"))
if colType is not None:
self.__write("| Column%s | Type%s |" % (blank1, blank2))
self.__write("+%s+%s+" % (lines1, lines2))
else:
self.__write("| Column%s |" % blank1)
self.__write("+%s+" % lines1)
for column in colList:
colType = columns[column]
blank1 = " " * (maxlength1 - len(column))
if colType is not None:
blank2 = " " * (maxlength2 - len(colType))
self.__write("| %s%s | %s%s |" % (column, blank1, colType, blank2))
else:
self.__write("| %s%s |" % (column, blank1))
if colType is not None:
self.__write("+%s+%s+\n" % (lines1, lines2))
else:
self.__write("+%s+\n" % lines1)
def dbTableValues(self, tableValues): def dbTableValues(self, tableValues):
replication = None replication = None

View File

@ -341,11 +341,16 @@ def cmdLineParser():
action="store_true", default=False, action="store_true", default=False,
help="Prompt for an interactive SQL shell") help="Prompt for an interactive SQL shell")
enumeration.add_option("--common-exists", dest="cExists", action="store_true", # User-defined function options
brute = OptionGroup(parser, "Brute force", "These "
"options can be used to run brute force "
"checks.")
brute.add_option("--brute-tables", dest="bruteTables", action="store_true",
default=False, help="Check existence of common tables") default=False, help="Check existence of common tables")
enumeration.add_option("--exists", dest="tableFile", brute.add_option("--brute-columns", dest="bruteColumns", action="store_true",
help="Check existence of user specified tables") default=False, help="Check existence of common columns")
# User-defined function options # User-defined function options
udf = OptionGroup(parser, "User-defined function injection", "These " udf = OptionGroup(parser, "User-defined function injection", "These "
@ -526,6 +531,7 @@ def cmdLineParser():
parser.add_option_group(techniques) parser.add_option_group(techniques)
parser.add_option_group(fingerprint) parser.add_option_group(fingerprint)
parser.add_option_group(enumeration) parser.add_option_group(enumeration)
parser.add_option_group(brute)
parser.add_option_group(udf) parser.add_option_group(udf)
parser.add_option_group(filesystem) parser.add_option_group(filesystem)
parser.add_option_group(takeover) parser.add_option_group(takeover)

View File

@ -19,6 +19,7 @@ from lib.core.common import randomInt
from lib.core.common import safeStringFormat from lib.core.common import safeStringFormat
from lib.core.data import conf from lib.core.data import conf
from lib.core.data import logger from lib.core.data import logger
from lib.core.exception import sqlmapMissingMandatoryOptionException
from lib.request.connect import Connect as Request from lib.request.connect import Connect as Request
def tableExists(tableFile): def tableExists(tableFile):
@ -57,19 +58,23 @@ def tableExists(tableFile):
return retVal return retVal
def columnExists(table, columnFile): def columnExists(columnFile):
tables = getFileItems(columnFile, None) if not conf.tbl:
errMsg = "missing table parameter"
raise sqlmapMissingMandatoryOptionException, errMsg
columns = getFileItems(columnFile, None)
retVal = [] retVal = []
infoMsg = "checking column existence for table '%s' using items from '%s'" % (table, columnFile) infoMsg = "checking column existence for table '%s' using items from '%s'" % (conf.tbl, columnFile)
logger.info(infoMsg) logger.info(infoMsg)
pushValue(conf.verbose) pushValue(conf.verbose)
conf.verbose = 0 conf.verbose = 0
count = 0 count = 0
length = len(tables) length = len(columns)
for column in columns: for column in columns:
query = agent.prefixQuery("%s" % safeStringFormat("AND EXISTS(SELECT %s FROM %s)", (column, table))) query = agent.prefixQuery("%s" % safeStringFormat("AND EXISTS(SELECT %s FROM %s)", (column, conf.tbl)))
query = agent.postfixQuery(query) query = agent.postfixQuery(query)
result = Request.queryPage(agent.payload(newValue=query)) result = Request.queryPage(agent.payload(newValue=query))