$ cat writeup.md…
$ cat writeup.md…
umdctf
Task: a wrapper forwards exactly two TCP-supplied DNS packets to a local UDP DNS server, where TXT queries leak one character of an 819-byte secret and the full secret subdomain returns the flag. Solution: craft compressed multi-question DNS packets to dump all secret characters in one request, then build a chained-pointer qname that expands past the usual DNS length limit and triggers the flag response.
$ cat /etc/rate-limit
Rate limit reached (20 reads/hour per IP). Showing preview only — full content returns at the next hour roll-over.
No organizer description was included in the provided workspace files.
English summary: the service accepts exactly two length-prefixed DNS packets over TCP and forwards them to a local UDP resolver. TXT requests for <index>.inside.info reveal one character of a hidden 819-character secret, and querying the full secret as a subdomain of inside.info returns the flag.
Reading dns_server.py reveals the core behavior:
819 is generated,13 labels of length 63,N.inside.info TXT returns secret[N],full_secret.inside.info TXT returns the flag.The intended blocker is DNS name length. A normal domain name is limited to 253 bytes, so the final 819-character subdomain cannot be encoded directly. However, the bundled dnslib parser only checks per-label length during decoding; decode_name() follows compression pointers without enforcing the total expanded qname length.
That gives two useful ideas:
819 TXT questions into a single DNS packet..inside.info.The first packet also needs compression. A naive request with 819 full qnames is too large for the UDP receive path (recv(8192)). Reusing the repeated .inside.info suffix with DNS pointers shrinks the request to about 8103 bytes, which fits.
...
$ grep --similar