Skip to content

Commit 7b60bc8

Browse files
committed
Minor improvements
1 parent 820efa7 commit 7b60bc8

11 files changed

Lines changed: 626 additions & 104 deletions

File tree

data/txt/sha256sums.txt

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ ca86d61d3349ed2d94a6b164d4648cff9701199b5e32378c3f40fca0f517b128 extra/shutils/
160160
df768bcb9838dc6c46dab9b4a877056cb4742bd6cfaaf438c4a3712c5cc0d264 extra/shutils/recloak.sh
161161
1972990a67caf2d0231eacf60e211acf545d9d0beeb3c145a49ba33d5d491b3f extra/shutils/strip.sh
162162
1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 extra/vulnserver/__init__.py
163-
f96ceae5ecb2bfe5eb3b8ae5cf344a93943f13322bc79bb92dbaeafa30f9321f extra/vulnserver/vulnserver.py
163+
617cec1b731e0baacafa6f58c2f56a85b6128d1416627cc1b2f61519c8539a2e extra/vulnserver/vulnserver.py
164164
a2bf70d7f87c3a4e0675c0bad54119a4e04efa6ea2730a8338d5aebcd995630e lib/controller/action.py
165165
9137a8f7368496c84b21944f6b94c28004d3a2a849ac9c8e0b20e294e4c4a93a lib/controller/checks.py
166166
4598de22ed3df63432e9643ba48533a01bec9f0b253c3a11f322ccedaef353f0 lib/controller/controller.py
@@ -189,7 +189,7 @@ e033b20a0f7821797a10f4bf4235723f38c7db551c611fbb713faa621b123c4a lib/core/optio
189189
9bf174058f15d14e24e94f9aaf42df045119d3617c6c54bd2f3af79b462f331d lib/core/replication.py
190190
0b8c38a01bb01f843d94a6c5f2075ee47520d0c4aa799cecea9c3e2c5a4a23a6 lib/core/revision.py
191191
888daba83fd4a34e9503fe21f01fef4cc730e5cde871b1d40e15d4cbc847d56c lib/core/session.py
192-
7f811ed56c2ce56e2575e732d0853a2064cefa57fa850c51b9e08e00d685ca08 lib/core/settings.py
192+
7461f9959d80cade863d9ee2f9aa30a2a5ac054f0913357c796f1282ec346a9f lib/core/settings.py
193193
c7804223319e18eb0b8e2cbf0a8b6896d1cefb7b0b1a2e9f1cf826a8a3b56750 lib/core/shell.py
194194
a2e98a94b231432736d6b304fc75525c8b5fdb4768c418387c5b4c1a610dad64 lib/core/subprocessng.py
195195
19f1e3c5e3ba703d28d510cd7a9ab8284d5fbe9df5ce7e77c86e5931571364b7 lib/core/target.py
@@ -240,19 +240,19 @@ a66a4b9df6207dce722c9b71d290ea426723cb4b697b416065dc7dd5db96fe8e lib/techniques
240240
1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/techniques/error/__init__.py
241241
5bbef46c16e34fd80e3f9f0e9aa255ce2e39be0d0e57479e25890b041c7efc7d lib/techniques/error/use.py
242242
1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/techniques/graphql/__init__.py
243-
ffbc7583a563bb9fe5a560ca8363f3e4ec84ecf907b956883ab1f2904f19d529 lib/techniques/graphql/inject.py
243+
c3e5cf7e5e35ae5fd86b63a515b37e6f06e61c70d2690252f2ee8373aa16637e lib/techniques/graphql/inject.py
244244
1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/techniques/__init__.py
245245
1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/techniques/ldap/__init__.py
246-
cc90c641d74244e45fa0c8c4026315452137e66b6fb5cef681d0eacd4e11eb69 lib/techniques/ldap/inject.py
246+
039d64a610b0e92e953fa6eaa740e7c2867e34e12b82e0113204e8f6100dc368 lib/techniques/ldap/inject.py
247247
44401cad3e39ae9fb899ed5d0e2fdd0879561de05c3117f17f3b0db54f4e3724 lib/techniques/nosql/__init__.py
248-
e2cd2b19f82393f9bbc8f374686cd851a4ccc264bb898ea54547ec479a05674c lib/techniques/nosql/inject.py
248+
e465d9cb6ac83dafe38aeec851856183b93f5aa19f628fb64371a290797e2518 lib/techniques/nosql/inject.py
249249
1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/techniques/ssti/__init__.py
250-
cb8806c285962593b963464ba870d61f274ee73d9ba878c76fe52795cbe4eced lib/techniques/ssti/inject.py
250+
29ab841b6129106f19db692a5a30f90a5e758d6cd24d47da0a35c8090910ae18 lib/techniques/ssti/inject.py
251251
1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/techniques/union/__init__.py
252252
ceec65f8cb7c3254c4671351c837418c76ac5bc55ccbc40779f67231b54d7085 lib/techniques/union/test.py
253253
c65766f71e285fc85cdf58e7448c4c1d015af2a9dbb44fa3b665a9f13362fbcc lib/techniques/union/use.py
254254
1966ca704961fb987ab757f0a4afddbf841d1a880631b701487c75cef63d60c3 lib/techniques/xpath/__init__.py
255-
ece1fca81148ccf3c5f13b6ad7fb64966cb1ebef245216eac5cb0dd2490989db lib/techniques/xpath/inject.py
255+
c61816c9dba9f6cc2223aed1a923f95130979e5f0a88ec254ee667d955ed2734 lib/techniques/xpath/inject.py
256256
aeefb42ea0c68f72744bc1bfd7194ec1bc06480d8a7e23f4b8d3d23fbba2b014 lib/utils/api.py
257257
442555ab85277aff7c9e0cf465ea5b0d28395c326f68363449b2d3941f4b6de2 lib/utils/brute.py
258258
da5bcbcda3f667582adf5db8c1b5d511b469ac61b55d387cec66de35720ed718 lib/utils/crawler.py
@@ -615,7 +615,7 @@ bb6991260a994fcbe79e05febaa34affd5631d02299fbc626820addd5f6ea4f4 tests/test_err
615615
26730151abea598f193131c5d64ef92b531941972f3d6236f9951c3116030b1c tests/test_filesystem.py
616616
16fba97cba6afe8af11aa30bcc4266f53b00f2530161e010af10b51db1509703 tests/test_fingerprint.py
617617
20844dfc758e99b2f757906c51ef32aca0f699283ec5aa629158d3dc0fd279ea tests/test_generic_takeover.py
618-
bde97a4781c4ee84e0fe86f7a33206f114167eb14b704013ecf1c26b838193d7 tests/test_graphql.py
618+
f1f38f8b8ca667caadcb027d1a20eb895be4ef0935511114db235e66903bb463 tests/test_graphql.py
619619
50b71422ee91b9a4864f4d5ce6c9bdf169dc5f57ed1db05c152eb010c282136b tests/test_gui_helpers.py
620620
92648f2fe81e22c5726b198bbbda14961cd4d3294a0d9139dcea808b324142ac tests/test_har.py
621621
70919c6ee8fbb3d619873489c819fa37d9035beb2e9b658cc5aa531d86a40380 tests/test_hash_crack.py
@@ -643,7 +643,7 @@ cec98d72992c0799229a780fa7f0d7f3fb01ec2d708187ce0e4a05c8612f291b tests/test_saf
643643
a1c6cda1e5b483f61e6a4f8ddd0b06a15ddaa3fd2119bfb9dbd9cc970d7a751d tests/test_settings_regex.py
644644
29d0278e3718b0fee422d3f6bb85ca02560138d48cd76f9fe1f35ac19d96071b tests/test_sgmllib.py
645645
d3d991331096e16e5019de3d652e9fff92c09bd9f97c50b1c2c3ceb0ed49b17e tests/test_sqlparse.py
646-
49c72cf40cfa78c573826ca1ab3ad11886e353158a31f15b29c6d71b0e561fcc tests/test_ssti.py
646+
4a9409a070770cc6300ed2b0c954254273479252fa602ffd19d78917f895756c tests/test_ssti.py
647647
8bcbf1091134dd0a62f6201f8b3645ed87b5ff2f7ba40a87231a29dac412591f tests/test_strings.py
648648
8f1c5f0f337ecd26d35c5551060034e0aa33a62cce5385fc1227fdc485f6383e tests/test_tamper.py
649649
67472bd71c20782cc0f738e2c2e674c29d6985669e14d15b69baef7d0e33de62 tests/test_target_parsing.py
@@ -659,7 +659,7 @@ eca021208e388b4d14c53f1e9f8a6e7d685e54ba572fb2a8487e6b620a20bcb5 tests/test_use
659659
2364db35025a53ea4e5a0a80c034997642785f7e6d1566d0d0f1db959fe3c82e tests/test_utils.py
660660
93ef9944effc62d4f744c57bd643137c90fd92205c6a6cbe891e0e99efb80a7f tests/test_wafbypass.py
661661
81bb6d7449f224fa337734ae361c1a340bf9a51768a854d6a1a6e718ed1263ca tests/test_wordlist.py
662-
c7584cad4f99416e6415744412941f5a47b2f5284270326624bd291edf6d9994 tests/test_xpath.py
662+
9c1c23a83408e6012e019e82ffb53e25e317054d1b28ca61a2c4fe830a472fcf tests/test_xpath.py
663663
55eaefc664bd8598329d535370612351ec8443c52465f0a37172ea46a97c458a thirdparty/ansistrm/ansistrm.py
664664
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 thirdparty/ansistrm/__init__.py
665665
f597b49ef445bfbfb8f98d1f1a08dcfe4810de5769c0abfab7cdce4eebbfcae7 thirdparty/beautifulsoup/beautifulsoup.py

extra/vulnserver/vulnserver.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -986,7 +986,7 @@ def do_REQUEST(self):
986986
elements = root.xpath(xpath_expr)
987987
entries = [_xpath_element_to_dict(el) for el in elements]
988988
except Exception as ex:
989-
error = "%s: %s" % (type(ex).__name__, getUnicode(ex))
989+
error = "%s: %s" % (type(ex).__name__, str(ex))
990990

991991
output = json.dumps({"entries": entries, "count": len(entries), "error": error}, default=str)
992992
self.wfile.write(output.encode(UNICODE_ENCODING))
@@ -1013,7 +1013,7 @@ def do_REQUEST(self):
10131013
if results:
10141014
authenticated = True
10151015
except Exception as ex:
1016-
error = "%s: %s" % (type(ex).__name__, getUnicode(ex))
1016+
error = "%s: %s" % (type(ex).__name__, str(ex))
10171017

10181018
output = json.dumps({"authenticated": authenticated, "error": error}, default=str)
10191019
self.wfile.write(output.encode(UNICODE_ENCODING))
@@ -1036,7 +1036,7 @@ def do_REQUEST(self):
10361036
output += template.render()
10371037
except Exception as ex:
10381038
# Leak template engine error for error-based detection
1039-
output += "<b>%s: %s</b>" % (type(ex).__name__, getUnicode(ex))
1039+
output += "<b>%s: %s</b>" % (type(ex).__name__, str(ex))
10401040
else:
10411041
output += "Hello"
10421042

lib/core/settings.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
from thirdparty import six
2121

2222
# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
23-
VERSION = "1.10.6.190"
23+
VERSION = "1.10.6.191"
2424
TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable"
2525
TYPE_COLORS = {"dev": 33, "stable": 90, "pip": 34}
2626
VERSION_STRING = "sqlmap/%s#%s" % ('.'.join(VERSION.split('.')[:-1]) if VERSION.count('.') > 2 and VERSION.split('.')[-1] == '0' else VERSION, TYPE)
@@ -878,7 +878,15 @@
878878
NOSQL_MAX_LENGTH = 1024
879879

880880
# GraphQL endpoint paths to probe when the user supplies a base URL with --graphql (no explicit /graphql)
881-
GRAPHQL_ENDPOINT_PATHS = ("/graphql", "/api/graphql", "/v1/graphql", "/graphql/api", "/graph", "/gql")
881+
GRAPHQL_ENDPOINT_PATHS = ("/graphql", "/api/graphql", "/v1/graphql", "/api/v1/graphql", "/graphql/api", "/graphql/console", "/graphql.php", "/graphiql", "/graph", "/gql", "/query")
882+
883+
# Seed field/argument names used to recover a GraphQL schema from "Did you mean" suggestion error
884+
# messages when introspection is disabled (the field-suggestion / "Clairvoyance" technique)
885+
GRAPHQL_FIELD_WORDLIST = ("user", "users", "me", "search", "login", "node", "post", "posts",
886+
"account", "accounts", "profile", "product", "products", "order", "orders", "item", "items",
887+
"customer", "find", "get", "list", "comment", "comments", "message", "messages", "updateUser")
888+
GRAPHQL_ARG_WORDLIST = ("id", "username", "user", "name", "term", "query", "q", "search",
889+
"email", "input", "password", "key", "filter", "slug", "title", "uid")
882890

883891
# Canonical GraphQL introspection query (the one everyone copy-pastes). Returned schema carries the
884892
# full type system: query/mutation/subscription roots, OBJECT/INPUT_OBJECT/ENUM/SCALAR types, their
@@ -967,6 +975,9 @@
967975
# Upper bound for the value-length search during LDAP blind extraction
968976
LDAP_MAX_LENGTH = 256
969977

978+
# Maximum number of directory entries enumerated during LDAP blind dumping
979+
LDAP_MAX_RECORDS = 20
980+
970981
# Attributes that definitively identify the backend vendor when probed on the RootDSE or
971982
# a well-known directory entry. Each tuple is (attribute, expected_value_substring, backend).
972983
LDAP_FINGERPRINT_ATTRIBUTES = (

lib/techniques/graphql/inject.py

Lines changed: 110 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,10 @@
2222
from lib.core.enums import CUSTOM_LOGGING
2323
from lib.core.enums import POST_HINT
2424
from lib.core.settings import ERROR_PARSING_REGEXES
25+
from lib.core.settings import GRAPHQL_ARG_WORDLIST
2526
from lib.core.settings import GRAPHQL_ENDPOINT_PATHS
2627
from lib.core.settings import GRAPHQL_ERROR_REGEX
28+
from lib.core.settings import GRAPHQL_FIELD_WORDLIST
2729
from lib.core.settings import GRAPHQL_INTROSPECTION_QUERY
2830
from lib.core.settings import NOSQL_ERROR_REGEX
2931
from lib.core.settings import UPPER_RATIO_BOUND
@@ -354,6 +356,90 @@ def _introspect(endpoint):
354356
return None
355357

356358

359+
# --- Schema recovery via field suggestions (introspection disabled) ---------
360+
361+
def _gqlErrors(page):
362+
# GraphQL error-envelope messages as a list of strings
363+
doc = _parseJSON(page)
364+
if not isinstance(doc, dict):
365+
return []
366+
return [getUnicode(e.get("message", "")) for e in (doc.get("errors") or []) if isinstance(e, dict)]
367+
368+
369+
def _harvestSuggestions(message):
370+
# Pull suggested identifiers out of a "Did you mean ..." GraphQL validation message,
371+
# handling both single- and double-quoted phrasings ('a', 'b', or 'c' / "a" or "b")
372+
idx = message.find("Did you mean")
373+
if idx < 0:
374+
return []
375+
return re.findall(r"""['"]([A-Za-z_][A-Za-z0-9_]*)['"]""", message[idx:])
376+
377+
378+
def _suggestFields(endpoint, op):
379+
# Recover root field names for an operation via suggestion harvesting: probe a random
380+
# (guaranteed-unknown) field to collect the closest matches, then confirm/expand using a
381+
# seed wordlist. A seed that does NOT come back as "Cannot query field" is itself a real field.
382+
prefix = "" if op == "query" else "mutation "
383+
found = set()
384+
probes = [randomStr(length=10, lowercase=True)] + list(GRAPHQL_FIELD_WORDLIST)
385+
386+
for seed in probes:
387+
page, _ = _gqlSend(endpoint, "%s{ %s }" % (prefix, seed))
388+
doc = _parseJSON(page) or {}
389+
for entry in (doc.get("errors") or []):
390+
message = getUnicode(entry.get("message", "")) if isinstance(entry, dict) else ""
391+
if "Did you mean" in message and "on type" in message:
392+
found.update(_harvestSuggestions(message))
393+
# a seeded name counts as a real field only if it actually resolved (appears in `data`);
394+
# "no unknown-field error" alone is too weak (lenient servers accept anything)
395+
data = doc.get("data")
396+
if seed in GRAPHQL_FIELD_WORDLIST and isinstance(data, dict) and seed in data:
397+
found.add(seed)
398+
399+
return sorted(found)
400+
401+
402+
def _suggestArgs(endpoint, op, field):
403+
# Recover an argument name for `field` from an "Unknown argument ... Did you mean ..." message
404+
prefix = "" if op == "query" else "mutation "
405+
bogus = randomStr(length=10, lowercase=True)
406+
page, _ = _gqlSend(endpoint, '%s{ %s(%s: 1) }' % (prefix, field, bogus))
407+
found = set()
408+
for message in _gqlErrors(page):
409+
if "Unknown argument" in message:
410+
found.update(_harvestSuggestions(message))
411+
return sorted(found)
412+
413+
414+
def _introspectViaSuggestions(endpoint):
415+
# Fallback schema recovery when introspection is disabled but the server still leaks field/argument
416+
# names through "Did you mean" validation errors. Builds best-effort Slots: known scalar arg types
417+
# are unavailable here, so we default to the 'string' strategy (the most broadly injectable) and let
418+
# the per-slot injection oracle confirm which (field, argument) pairs are actually vulnerable.
419+
420+
probe = randomStr(length=10, lowercase=True)
421+
page, _ = _gqlSend(endpoint, "{ %s }" % probe)
422+
if not any("Did you mean" in m for m in _gqlErrors(page)):
423+
return None
424+
425+
logger.info("introspection is disabled; recovering the schema from field-suggestion errors")
426+
427+
slots = []
428+
for op, parentName in (("query", "Query"), ("mutation", "Mutation")):
429+
fields = _suggestFields(endpoint, op)
430+
if not fields:
431+
continue
432+
logger.info("recovered %d %s field(s) via suggestions: %s" % (
433+
len(fields), op, ", ".join(fields)))
434+
for field in fields:
435+
args = _suggestArgs(endpoint, op, field) or list(GRAPHQL_ARG_WORDLIST)
436+
for arg in args:
437+
# returnSel="" renders as "{ __typename }" (valid on any OBJECT); strategy="string"
438+
slots.append(Slot(op, parentName, field, [(arg, {}, None)],
439+
arg, "string", "OBJECT", "", ""))
440+
return slots or None
441+
442+
357443
# --- Schema walking ---------------------------------------------------------
358444

359445
def _extractSlots(schema):
@@ -1087,11 +1173,11 @@ def graphqlScan():
10871173
global SENTINEL
10881174
SENTINEL = randomStr(length=10, lowercase=True)
10891175

1090-
infoMsg = "'--graphql' is self-contained: it discovers the GraphQL endpoint, "
1091-
infoMsg += "enumerates the schema, and injects SQL/NoSQL payloads into reachable "
1092-
infoMsg += "argument slots. SQL enumeration switches (e.g. --banner, --dbs, "
1093-
infoMsg += "--tables) are ignored"
1094-
logger.info(infoMsg)
1176+
debugMsg = "'--graphql' is self-contained: it discovers the GraphQL endpoint, "
1177+
debugMsg += "enumerates the schema, and injects SQL/NoSQL payloads into reachable "
1178+
debugMsg += "argument slots. SQL enumeration switches (e.g. --banner, --dbs, "
1179+
debugMsg += "--tables) are ignored"
1180+
logger.debug(debugMsg)
10951181

10961182
url = conf.url.rstrip("/") if conf.url else ""
10971183

@@ -1120,19 +1206,22 @@ def graphqlScan():
11201206
# 2. Schema introspection
11211207
logger.info("introspecting the GraphQL schema")
11221208
schema = _introspect(endpoint)
1123-
if not schema:
1124-
logger.error("introspection failed (disabled or the endpoint rejected the query)")
1125-
return
1126-
1127-
types = schema.get("types") or []
1128-
logger.info("introspection returned %d types" % len(types))
11291209

1130-
# 3. Slot enumeration
1131-
slots = _extractSlots(schema)
1132-
if not slots:
1133-
logger.warning("no injectable argument slots found in the schema")
1134-
_dumpSchema(schema, endpoint)
1135-
return
1210+
if schema:
1211+
types = schema.get("types") or []
1212+
logger.info("introspection returned %d types" % len(types))
1213+
slots = _extractSlots(schema)
1214+
if not slots:
1215+
logger.warning("no injectable argument slots found in the schema")
1216+
_dumpSchema(schema, endpoint)
1217+
return
1218+
else:
1219+
# Introspection blocked: try to recover the schema from field-suggestion errors
1220+
logger.warning("introspection failed (disabled or rejected); trying suggestion-based recovery")
1221+
slots = _introspectViaSuggestions(endpoint)
1222+
if not slots:
1223+
logger.error("could not recover the schema (introspection disabled and no field suggestions)")
1224+
return
11361225

11371226
querySlots = [_ for _ in slots if _.operation == "query"]
11381227
mutationSlots = [_ for _ in slots if _.operation == "mutation"]
@@ -1141,8 +1230,10 @@ def graphqlScan():
11411230
len(slots), len(querySlots), len(mutationSlots)))
11421231

11431232
# 4. Schema dump (before detection -- matches regular sqlmap table/column
1144-
# enumeration preceding data retrieval)
1145-
_dumpSchema(schema, endpoint)
1233+
# enumeration preceding data retrieval). Only when introspection succeeded; the
1234+
# suggestion-recovered path has no full schema document to render.
1235+
if schema:
1236+
_dumpSchema(schema, endpoint)
11461237

11471238
if mutationSlots:
11481239
names = sorted(set("%s(%s:)" % (_.fieldName, _.targetArg) for _ in mutationSlots))

lib/techniques/ldap/inject.py

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,11 @@
2424
from lib.core.settings import LDAP_ERROR_SIGNATURES
2525
from lib.core.settings import LDAP_FINGERPRINT_ATTRIBUTES
2626
from lib.core.settings import LDAP_MAX_LENGTH
27+
from lib.core.settings import LDAP_MAX_RECORDS
2728
from lib.core.settings import UPPER_RATIO_BOUND
2829
from lib.request.connect import Connect as Request
2930
from lib.utils.xrange import xrange
3031

31-
try:
32-
from lib.core.settings import LDAP_MAX_RECORDS
33-
except ImportError:
34-
LDAP_MAX_RECORDS = 20
35-
3632

3733
SENTINEL = randomStr(length=10, lowercase=True)
3834

@@ -644,10 +640,10 @@ def ldapScan():
644640
global SENTINEL
645641
SENTINEL = randomStr(length=10, lowercase=True)
646642

647-
infoMsg = "'--ldap' is self-contained: it detects LDAP injection in HTTP "
648-
infoMsg += "parameters and dumps reachable directory entries. SQL enumeration "
649-
infoMsg += "switches (--banner, --dbs, --tables, --users, --sql-query) are ignored"
650-
logger.info(infoMsg)
643+
debugMsg = "'--ldap' is self-contained: it detects LDAP injection in HTTP "
644+
debugMsg += "parameters and dumps reachable directory entries. SQL enumeration "
645+
debugMsg += "switches (--banner, --dbs, --tables, --users, --sql-query) are ignored"
646+
logger.debug(debugMsg)
651647

652648
if not conf.paramDict:
653649
logger.error("no request parameters to test (use --data, GET params, or similar)")

lib/techniques/nosql/inject.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -684,10 +684,10 @@ def nosqlScan():
684684
# NoSQL injection from an application-scoped point is confined to the back-end's single query
685685
# (one collection/label) - it confirms and dumps what that query can reach, with no analog to the
686686
# SQL database/table/user/banner enumeration, so those switches do not apply here
687-
infoMsg = "'--nosql' is self-contained: it confirms the injection and dumps the reachable "
688-
infoMsg += "collection/document. SQL enumeration switches (e.g. --banner, --dbs, --tables, "
689-
infoMsg += "--users, --sql-query) do not map to a NoSQL back-end and are ignored"
690-
logger.info(infoMsg)
687+
debugMsg = "'--nosql' is self-contained: it confirms the injection and dumps the reachable "
688+
debugMsg += "collection/document. SQL enumeration switches (e.g. --banner, --dbs, --tables, "
689+
debugMsg += "--users, --sql-query) do not map to a NoSQL back-end and are ignored"
690+
logger.debug(debugMsg)
691691

692692
tested = found = 0
693693

0 commit comments

Comments
 (0)