Dark PDF: MongoBleed findings (CVE-2025-14847) plus the open host:port inventory.
Target
One per line: IP, CIDR, or hostname. Default 192.0.2.1/32 (TEST-NET, scans nothing).
CIDRs wider than /16 are skipped.
How It Works
rustscan finds open MongoDB (27017). nuclei flags unauthenticated listeners.
Open Mongo ports go to mongobleed for CVE-2025-14847. Read-only.
Overview
A database reachable from the internet without authentication is not a
vulnerability you exploit. It is a database you read. There is no chain to build
and no payload to land, which is why these turn up in breach write-ups so often:
a container published a port it should not have, a managed service was created
with an open network policy, a test instance outlived the test.
Finding the open ports is the easy half. The question you actually have is which
of them matters, and a port list does not answer it. This run sorts a range into
the two states that decide your afternoon: a database port that demands
credentials, and one that answers to anybody who connects. It checks eight
engines at once rather than one at a time, names the engine behind each open
service, and groups what it finds by severity, so the first item in the report is
the first thing to fix and the rest is an inventory you can hand to whoever owns
the host. Scheduled against your own space, it belongs in
exposure management as a recurring check, since
this failure is usually introduced by a deploy rather than discovered in one.
Pipeline
Read the targets, normalize them to IPs or CIDRs, and cap the range.
rustscan scans the eight database ports across each batch,
distributed over the fleet.
Open services are parsed out as ip:port pairs.
nuclei TCP templates check each open service for
unauthenticated access.
Anything on the MongoDB port additionally gets a dedicated CVE-2025-14847
probe.
Findings collect into one report, grouped by engine and severity.
Inputs
Targets. One per line, as an IP, a CIDR, a hostname, or a host list. The
safe default is the reserved documentation range 192.0.2.1/32, where nothing
is routed and nothing answers, so a first run exercises the graph and returns
an empty inventory. Replace it with a range you own before you expect results.
Ports. The eight database ports scanned by default: MongoDB 27017, Redis
6379, Elasticsearch 9200, CouchDB 5984, Cassandra 9042, Memcached 11211,
PostgreSQL 5432, MySQL 3306. Edit the list to widen coverage.
Range caps. A safety limit rather than a setting you tune. CIDRs wider
than /16 are skipped and the host count is capped, so a mistyped target
cannot become an internet-wide sweep.
Outputs
A PDF report that separates the two states you have to triage on: services
that are reachable but still ask for credentials, and services that answer a
connection anonymously. The second group is ranked first, grouped by engine and
severity, and the methodology behind each finding is printed with it.
The full host:port inventory of open database services, grouped by engine.
When nothing answers anonymously this inventory is the finding, since it is
proof of a clean database footprint.
Unauthenticated-access findings per open service, in JSON lines, from the
nuclei TCP templates. This is the record that turns a reachable port into a
confirmed exposure.
A MongoBleed probe result for every open MongoDB port, recording what was
tried and what came back.
Sample output
Illustrative output on TEST-NET documentation addresses. Nothing answers on those
ranges, so this shows the shape of each stage rather than somebody's exposed
database.
Open database ports are parsed into targets for the auth check:
ip
port
engine
auth_required
severity
cve
192.0.2.1
27017
mongodb
false
critical
null
192.0.2.5
6379
redis
false
critical
null
192.0.2.10
9200
elasticsearch
true
info
null
192.0.2.23
5432
postgresql
true
info
null
192.0.2.41
27017
mongodb
false
critical
CVE-2025-14847
192.0.2.55
3306
mysql
true
info
null
The MongoDB probe reports what it tried and what it found:
Against a real range, an engine that answers without credentials is reported with
the port and the service behind it. Nothing is read from the database itself.
FAQ
How do you confirm an exposure without pulling data out of it?
The check stops at the handshake. A TCP template opens a connection, observes
that the engine accepts it without asking for credentials, and records that fact.
No collection is listed, no key is fetched, no row is read. What you hand to the
host owner is the proof that authentication is absent, not a copy of what it was
protecting.
What happens if I run it on the default target?
Nothing gets scanned. The default is a reserved documentation range with no hosts
behind it, so the run completes and the inventory comes back empty. Point it at a
range you own to get findings.
Which engines does it cover?
Eight by default: MongoDB, Redis, Elasticsearch, CouchDB, Cassandra, Memcached,
PostgreSQL and MySQL. Add ports to the list to cover engines outside that set.
Is it safe to point at production?
The template selection excludes intrusive, fuzzing and denial-of-service checks
along with informational noise, and both rate and concurrency are capped. Every
step is read-only.
How large a range can I give it?
CIDRs wider than /16 are skipped and the host count is capped, so a typo cannot
turn into an internet-wide sweep. Split anything bigger across several runs.
Related workflows
ASN-Wide Vulnerability Scan. Reach for this
instead when you want the whole CVE and web surface of the range assessed, not
only the data stores sitting in it.
Passive Port & CVE Scan (Shodan). Reach for
this instead when you are not allowed to send packets at the target and need
the exposure picture from data somebody else already collected.
Cloud Bucket Finder (S3, GCS, Azure).
Reach for this instead when the data you are worried about is parked in object
storage rather than in a database process on a port.