mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2026-08-04 14:55:40 +00:00
Fixing multi-column blind --search
This commit is contained in:
parent
356984929f
commit
ffffe2d0b2
3 changed files with 36 additions and 2 deletions
|
|
@ -20,7 +20,7 @@ from lib.core.enums import OS
|
|||
from thirdparty import six
|
||||
|
||||
# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
|
||||
VERSION = "1.10.7.223"
|
||||
VERSION = "1.10.7.224"
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -535,7 +535,10 @@ class Search(object):
|
|||
origDb = conf.db
|
||||
origTbl = conf.tbl
|
||||
|
||||
for column, dbData in foundCols.items():
|
||||
# Note: only the current column - foundCols also holds columns from earlier
|
||||
# colList iterations, and re-walking them here re-issued their table lookups
|
||||
# (O(n^2) blind requests) and duplicated their found tables
|
||||
for column, dbData in ((column, foundCols[column]),):
|
||||
colQuery = "%s%s" % (colCond, colCondParam)
|
||||
colQuery = colQuery % unsafeSQLIdentificatorNaming(column)
|
||||
|
||||
|
|
|
|||
|
|
@ -372,6 +372,7 @@ class _TestSearchInf(Search):
|
|||
self.like = ('2', "='%s'") # exact match (colConsider '2')
|
||||
self.dumpFoundTablesCalls = []
|
||||
self.dumpFoundColumnCalls = []
|
||||
self.getColumnsCalls = []
|
||||
|
||||
def likeOrExact(self, what):
|
||||
return self.like
|
||||
|
|
@ -390,6 +391,7 @@ class _TestSearchInf(Search):
|
|||
|
||||
def getColumns(self, onlyColNames=False, colTuple=None, bruteForce=None, dumpMode=False):
|
||||
db, tbl, col = conf.db, conf.tbl, conf.col
|
||||
self.getColumnsCalls.append((db, tbl, col))
|
||||
if db and tbl:
|
||||
kb.data.cachedColumns.setdefault(db, {}).setdefault(tbl, {})
|
||||
kb.data.cachedColumns[db][tbl][col] = "varchar"
|
||||
|
|
@ -533,6 +535,35 @@ class TestSearchInference(_SearchBase):
|
|||
self.assertIn("users", dbs["testdb"])
|
||||
self.assertIn("password", dbs["testdb"]["users"])
|
||||
|
||||
def test_search_column_multi_no_reprocess(self):
|
||||
# Regression: multi-column blind search must process each column exactly once.
|
||||
# The nested table-discovery loop used to walk ALL accumulated columns per outer
|
||||
# pass, re-querying earlier columns (O(n^2) requests) and appending their tables twice.
|
||||
s = _TestSearchInf()
|
||||
conf.col = "cola,colb"
|
||||
conf.db = None
|
||||
conf.tbl = None
|
||||
|
||||
def gv(query, *a, **k):
|
||||
if k.get("expected") == EXPECTED.INT:
|
||||
return "1" # 1 db / 1 table per column
|
||||
if "table_schema)" in query: # DISTINCT(table_schema) -> db-name fetch
|
||||
return "testdb"
|
||||
col = "cola" if "cola" in query else "colb"
|
||||
return "t_%s" % col # DISTINCT(table_name) -> table-name fetch
|
||||
smod.inject.getValue = gv
|
||||
|
||||
s.searchColumn()
|
||||
|
||||
# each (db, tbl, col) discovered once - no earlier column re-walked
|
||||
self.assertEqual(len(s.getColumnsCalls), len(set(s.getColumnsCalls)))
|
||||
self.assertEqual(len(s.getColumnsCalls), 2)
|
||||
# and no duplicate table under any found column
|
||||
foundCols = conf.dumper.dbColumnsArg[0]
|
||||
for _dbmap in foundCols.values():
|
||||
for _tbls in _dbmap.values():
|
||||
self.assertEqual(len(_tbls), len(set(_tbls)))
|
||||
|
||||
def test_search_column_mysql_lt5_bruteforce_decline(self):
|
||||
s = _TestSearchInf()
|
||||
conf.col = "password"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue