mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2024-11-22 17:46:37 +03:00
update regarding brute force retrieval of table names and table column names
This commit is contained in:
parent
45f2d8f5d2
commit
a7fa8d4975
|
@ -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())
|
||||||
|
|
||||||
|
|
137
lib/core/dump.py
137
lib/core/dump.py
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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))
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user