Lion Cipher Lab
Write a DNS resolver from scratch (build and parse DNS packets over UDP; resolve from the root)
- Foundations
- Advanced
- ~90 min
- Free · no account required
Why it matters
Name resolution is the first thing that happens in almost every connection on the internet, and it is the layer most security people treat as a black box: you type a hostname, a number comes back, you move on. But DNS is also one of the most attacked layers there is -- cache poisoning, spoofed responses, subdomain takeovers, tunneling, and NXDOMAIN abuse all live here -- and you cannot reason about any of those attacks if you have never seen what a DNS packet actually is. This lab fixes that by making you BUILD the resolver instead of reading about it. When you have assembled the 12-byte…
What you'll learn
- what DNS actually is and the difference between a STUB resolver (your OS), a RECURSIVE/caching resolver (8.8.8.8), and an AUTHORITATIVE server (the one that truly owns the zone)
- hand-building a DNS query packet byte by byte: the 12-byte header (random ID, the RD flag, QDCOUNT=1) and the question section
- encoding a domain into a QNAME as length-prefixed labels (www.example.com -> 3www7example3com0) and appending QTYPE=A(1) and QCLASS=IN(1)
- sending the query as a single UDP datagram (SOCK_DGRAM) to port 53 and reading the raw response bytes
- parsing the response header and answer records, and implementing DNS NAME COMPRESSION (the 0xC0 pointer) -- the one thing without which the parser breaks
- decoding A (4-byte IP), CNAME, and NS record data, respecting network byte order with struct's '!' format
- stepping up to ITERATIVE resolution: query a root server with RD=0, follow the NS referral to the TLD server, then to the authoritative server, using glue A records to avoid a chicken-and-egg lookup
- recognizing the failure modes that make DNS hard: the TC truncation bit ('answer too big for UDP -- retry over TCP'), EDNS0/OPT for larger UDP responses, and endianness
- the judgment of WHEN you'd ever build a resolver (to understand resolution and DNS attacks like cache poisoning/spoofing and tools like dnschef) versus using getaddrinfo, dig, or a hardened Unbound with DNSSEC in production, and using `dig +trace` to cross-check your work
Steps in this lab
- What DNS is, and the three kinds of server that answer
- The wire format: the 12-byte header and the question section
- Encode the QNAME and build the query packet by hand
- Send it over UDP and get the raw bytes back
- The hard part: parse the answer AND implement name compression (0xC0)
- The failure modes: the TC truncation bit, TCP fallback, and EDNS0
- Climb the tree: iterative resolution from the root, following NS + glue
- Cross-check with dig +trace, and prove you match the real thing
- The judgment: why you built this, and what to run in production