mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2026-07-09 01:51:20 +00:00
General boolean inference improvements
This commit is contained in:
parent
6597415ab0
commit
50ff3debe5
13 changed files with 14506 additions and 1629 deletions
|
|
@ -401,26 +401,39 @@ class Databases(object):
|
|||
plusOne = Backend.getIdentifiedDbms() in PLUS_ONE_DBMSES
|
||||
indexRange = getLimitRange(count, plusOne=plusOne)
|
||||
|
||||
for index in indexRange:
|
||||
if Backend.isDbms(DBMS.SYBASE):
|
||||
query = _query % (db, (kb.data.cachedTables[-1] if kb.data.cachedTables else " "))
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.MAXDB, DBMS.ACCESS, DBMS.MCKOI, DBMS.EXTREMEDB):
|
||||
query = _query % (kb.data.cachedTables[-1] if kb.data.cachedTables else " ")
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.SQLITE, DBMS.FIREBIRD):
|
||||
query = _query % index
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.HSQLDB, DBMS.INFORMIX, DBMS.FRONTBASE, DBMS.VIRTUOSO):
|
||||
query = _query % (index, unsafeSQLIdentificatorNaming(db))
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.SPANNER,):
|
||||
query = _query % (unsafeSQLIdentificatorNaming(db), unsafeSQLIdentificatorNaming(db), index)
|
||||
else:
|
||||
query = _query % (unsafeSQLIdentificatorNaming(db), index)
|
||||
# Value-parallel, prediction-assisted name enumeration for the DBMSes using the
|
||||
# generic "<db>, <index>" blind template. Retrieves whole names concurrently (one per
|
||||
# worker, each decoded sequentially so wordlist prediction applies). Used only with
|
||||
# '--threads' (like getColumns below); single-thread stays on the classic getValue loop,
|
||||
# which still gets predictive inference via getPartRun. The special templates stay serial.
|
||||
genericTemplate = Backend.getIdentifiedDbms() not in (DBMS.SYBASE, DBMS.MAXDB, DBMS.ACCESS, DBMS.MCKOI, DBMS.EXTREMEDB, DBMS.SQLITE, DBMS.FIREBIRD, DBMS.HSQLDB, DBMS.INFORMIX, DBMS.FRONTBASE, DBMS.VIRTUOSO, DBMS.SPANNER)
|
||||
|
||||
table = unArrayizeValue(inject.getValue(query, union=False, error=False))
|
||||
if genericTemplate and conf.threads > 1 and isTechniqueAvailable(PAYLOAD.TECHNIQUE.BOOLEAN):
|
||||
for table in (inject._threadedInferenceValues(lambda index: _query % (unsafeSQLIdentificatorNaming(db), index), indexRange, context="Tables") or []):
|
||||
if not isNoneValue(table):
|
||||
kb.hintValue = table
|
||||
tables.append(safeSQLIdentificatorNaming(table, True))
|
||||
else:
|
||||
for index in indexRange:
|
||||
if Backend.isDbms(DBMS.SYBASE):
|
||||
query = _query % (db, (kb.data.cachedTables[-1] if kb.data.cachedTables else " "))
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.MAXDB, DBMS.ACCESS, DBMS.MCKOI, DBMS.EXTREMEDB):
|
||||
query = _query % (kb.data.cachedTables[-1] if kb.data.cachedTables else " ")
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.SQLITE, DBMS.FIREBIRD):
|
||||
query = _query % index
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.HSQLDB, DBMS.INFORMIX, DBMS.FRONTBASE, DBMS.VIRTUOSO):
|
||||
query = _query % (index, unsafeSQLIdentificatorNaming(db))
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.SPANNER,):
|
||||
query = _query % (unsafeSQLIdentificatorNaming(db), unsafeSQLIdentificatorNaming(db), index)
|
||||
else:
|
||||
query = _query % (unsafeSQLIdentificatorNaming(db), index)
|
||||
|
||||
if not isNoneValue(table):
|
||||
kb.hintValue = table
|
||||
table = safeSQLIdentificatorNaming(table, True)
|
||||
tables.append(table)
|
||||
table = unArrayizeValue(inject.getValue(query, union=False, error=False))
|
||||
|
||||
if not isNoneValue(table):
|
||||
kb.hintValue = table
|
||||
table = safeSQLIdentificatorNaming(table, True)
|
||||
tables.append(table)
|
||||
|
||||
if tables:
|
||||
kb.data.cachedTables[db] = tables
|
||||
|
|
@ -841,7 +854,7 @@ class Databases(object):
|
|||
logger.error(errMsg)
|
||||
continue
|
||||
|
||||
for index in getLimitRange(count):
|
||||
def columnNameQuery(index):
|
||||
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.VERTICA, DBMS.PRESTO, DBMS.CRATEDB, DBMS.CUBRID, DBMS.CACHE, DBMS.FRONTBASE, DBMS.VIRTUOSO):
|
||||
query = rootQuery.blind.query % (unsafeSQLIdentificatorNaming(tbl), unsafeSQLIdentificatorNaming(conf.db))
|
||||
query += condQuery
|
||||
|
|
@ -880,8 +893,22 @@ class Databases(object):
|
|||
query += condQuery
|
||||
field = condition
|
||||
|
||||
query = agent.limitQuery(index, query, field, field)
|
||||
column = unArrayizeValue(inject.getValue(query, union=False, error=False))
|
||||
return agent.limitQuery(index, query, field, field)
|
||||
|
||||
indexList = list(getLimitRange(count))
|
||||
|
||||
# Value-parallel column-NAME enumeration: the same axis/mechanism as getTables (one name per
|
||||
# worker, decoded sequentially - no length probe, predictive inference applies, names stream
|
||||
# live). Serial fallback for single-thread and when also fetching per-column comments.
|
||||
columnNames = None
|
||||
if conf.threads > 1 and not conf.getComments and isTechniqueAvailable(PAYLOAD.TECHNIQUE.BOOLEAN):
|
||||
columnNames = inject._threadedInferenceValues(columnNameQuery, indexList, context="Columns")
|
||||
|
||||
for position, index in enumerate(indexList):
|
||||
if columnNames is not None:
|
||||
column = unArrayizeValue(columnNames[position])
|
||||
else:
|
||||
column = unArrayizeValue(inject.getValue(columnNameQuery(index), union=False, error=False))
|
||||
|
||||
if not isNoneValue(column):
|
||||
if conf.getComments:
|
||||
|
|
|
|||
|
|
@ -418,41 +418,70 @@ class Entries(object):
|
|||
debugMsg += "dumped as it appears to be empty"
|
||||
logger.debug(debugMsg)
|
||||
|
||||
def cellQuery(column, index):
|
||||
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2, DBMS.VERTICA, DBMS.PRESTO, DBMS.CRATEDB, DBMS.CACHE, DBMS.CLICKHOUSE, DBMS.SNOWFLAKE, DBMS.SPANNER):
|
||||
query = rootQuery.blind.query % (agent.preprocessField(tbl, column), conf.db, conf.tbl, prioritySortColumns(colList)[0], index)
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.DERBY, DBMS.ALTIBASE,):
|
||||
query = rootQuery.blind.query % (agent.preprocessField(tbl, column), tbl.upper() if not conf.db else ("%s.%s" % (conf.db.upper(), tbl.upper())), index)
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.MIMERSQL,):
|
||||
query = rootQuery.blind.query % (agent.preprocessField(tbl, column), tbl.upper() if not conf.db else ("%s.%s" % (conf.db.upper(), tbl.upper())), prioritySortColumns(colList)[0], index)
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.SQLITE, DBMS.EXTREMEDB):
|
||||
query = rootQuery.blind.query % (agent.preprocessField(tbl, column), tbl, index)
|
||||
elif Backend.isDbms(DBMS.FIREBIRD):
|
||||
query = rootQuery.blind.query % (index, agent.preprocessField(tbl, column), tbl)
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.INFORMIX, DBMS.VIRTUOSO):
|
||||
query = rootQuery.blind.query % (index, agent.preprocessField(tbl, column), conf.db, tbl, prioritySortColumns(colList)[0])
|
||||
elif Backend.isDbms(DBMS.FRONTBASE):
|
||||
query = rootQuery.blind.query % (index, agent.preprocessField(tbl, column), conf.db, tbl)
|
||||
else:
|
||||
query = rootQuery.blind.query % (agent.preprocessField(tbl, column), conf.db, tbl, index)
|
||||
|
||||
return agent.whereQuery(query)
|
||||
|
||||
try:
|
||||
for index in indexRange:
|
||||
# Value-parallel dumping: one whole cell per worker, decoded sequentially, so there
|
||||
# is NO per-cell LENGTH() probe (the position-parallel path needs one to split a
|
||||
# value's characters across threads) and the per-column Huffman model + low-cardinality
|
||||
# guessing engage under concurrency. Used for the boolean channel with '--threads'; the
|
||||
# classic per-character-parallel loop stays for single-thread and time-based.
|
||||
if conf.threads > 1 and not conf.dnsDomain and isTechniqueAvailable(PAYLOAD.TECHNIQUE.BOOLEAN):
|
||||
# One value-parallel pass over every (non-empty) cell, so there is a single
|
||||
# thread pool and values stream live as they complete - out of order, exactly
|
||||
# like the error/union dumps - instead of a silent progress counter.
|
||||
nonEmpty = [_ for _ in colList if _ not in emptyColumns]
|
||||
tasks = [(column, index) for column in nonEmpty for index in indexRange]
|
||||
retrieved = inject._threadedInferenceValues(lambda pair: cellQuery(pair[0], pair[1]), tasks, charsetType=None, dump=True) if tasks else []
|
||||
retrieved = retrieved if retrieved is not None else [None] * len(tasks)
|
||||
|
||||
offset = 0
|
||||
for column in colList:
|
||||
value = ""
|
||||
entries[column] = BigArray()
|
||||
lengths.setdefault(column, 0)
|
||||
|
||||
if column not in lengths:
|
||||
lengths[column] = 0
|
||||
|
||||
if column not in entries:
|
||||
entries[column] = BigArray()
|
||||
|
||||
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2, DBMS.VERTICA, DBMS.PRESTO, DBMS.CRATEDB, DBMS.CACHE, DBMS.CLICKHOUSE, DBMS.SNOWFLAKE, DBMS.SPANNER):
|
||||
query = rootQuery.blind.query % (agent.preprocessField(tbl, column), conf.db, conf.tbl, prioritySortColumns(colList)[0], index)
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.DERBY, DBMS.ALTIBASE,):
|
||||
query = rootQuery.blind.query % (agent.preprocessField(tbl, column), tbl.upper() if not conf.db else ("%s.%s" % (conf.db.upper(), tbl.upper())), index)
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.MIMERSQL,):
|
||||
query = rootQuery.blind.query % (agent.preprocessField(tbl, column), tbl.upper() if not conf.db else ("%s.%s" % (conf.db.upper(), tbl.upper())), prioritySortColumns(colList)[0], index)
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.SQLITE, DBMS.EXTREMEDB):
|
||||
query = rootQuery.blind.query % (agent.preprocessField(tbl, column), tbl, index)
|
||||
elif Backend.isDbms(DBMS.FIREBIRD):
|
||||
query = rootQuery.blind.query % (index, agent.preprocessField(tbl, column), tbl)
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.INFORMIX, DBMS.VIRTUOSO):
|
||||
query = rootQuery.blind.query % (index, agent.preprocessField(tbl, column), conf.db, tbl, prioritySortColumns(colList)[0])
|
||||
elif Backend.isDbms(DBMS.FRONTBASE):
|
||||
query = rootQuery.blind.query % (index, agent.preprocessField(tbl, column), conf.db, tbl)
|
||||
if column in emptyColumns:
|
||||
values = [NULL] * len(indexRange)
|
||||
else:
|
||||
query = rootQuery.blind.query % (agent.preprocessField(tbl, column), conf.db, tbl, index)
|
||||
values = retrieved[offset:offset + len(indexRange)]
|
||||
offset += len(indexRange)
|
||||
|
||||
query = agent.whereQuery(query)
|
||||
for value in values:
|
||||
value = '' if value is None else value
|
||||
lengths[column] = max(lengths[column], getConsoleLength(DUMP_REPLACEMENTS.get(getUnicode(value), getUnicode(value))))
|
||||
entries[column].append(value)
|
||||
else:
|
||||
for index in indexRange:
|
||||
for column in colList:
|
||||
if column not in lengths:
|
||||
lengths[column] = 0
|
||||
|
||||
value = NULL if column in emptyColumns else inject.getValue(query, union=False, error=False, dump=True)
|
||||
value = '' if value is None else value
|
||||
if column not in entries:
|
||||
entries[column] = BigArray()
|
||||
|
||||
lengths[column] = max(lengths[column], getConsoleLength(DUMP_REPLACEMENTS.get(getUnicode(value), getUnicode(value))))
|
||||
entries[column].append(value)
|
||||
value = NULL if column in emptyColumns else inject.getValue(cellQuery(column, index), union=False, error=False, dump=True)
|
||||
value = '' if value is None else value
|
||||
|
||||
lengths[column] = max(lengths[column], getConsoleLength(DUMP_REPLACEMENTS.get(getUnicode(value), getUnicode(value))))
|
||||
entries[column].append(value)
|
||||
|
||||
except KeyboardInterrupt:
|
||||
kb.dumpKeyboardInterrupt = True
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue