$ cat writeup.md…
$ cat writeup.md…
umdctf
Task: a Python service forwards a raw DNS packet over TCP to a local dnslib resolver and only returns the TXT answer when specific raw qname bytes appear in the request. Solution: forge a DNS query where the UTF-8 bytes of `ȳ` become a compression pointer, then place a zero byte at offset `0x08b3` so the parser accepts the name and reveals the flag.
$ 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 preserved in the local task files.
We are given a Python service that accepts a length-prefixed DNS packet over TCP, forwards the raw packet to a local UDP dnslib resolver, and returns the DNS response. The goal is to make the resolver return the TXT record containing the flag.
The important behavior is in dns_server.py:
if '\x04flag\x06market\x03polȳ'.encode('utf8') in handler.request[0][12:30]: reply.add_answer(RR("flag.market.polȳ", QTYPE.TXT, rdata=TXT(flag)))
There are two different interpretations of the same bytes:
handler.request[0][12:30].dnslib parses the same bytes as a DNS name.That mismatch is exploitable because the final character in polȳ is not ASCII. UTF-8 encodes ȳ as c8 b3, and in DNS name parsing any byte with the top two bits set (11xxxxxx) starts a compression pointer. So c8 b3 is interpreted as a pointer to absolute offset 0x08b3.
This means the qname bytes can satisfy the raw substring check:
04 66 6c 61 67 06 6d 61 72 6b 65 74 03 70 6f 6c c8 b3
while the DNS parser reads them as:
flagmarketpol0x08b3To keep the query valid, the pointer target must contain a valid DNS label sequence. The simplest choice is a zero byte, which represents the root label. So we pad the packet until absolute offset 0x08b3 and place 00 there. Then the compressed qname parses successfully, the raw byte check passes, and the resolver returns the TXT answer.
The remaining fields are normal DNS question fields:
QTYPE = TXT (16), because the server rejects any other query type.QCLASS = IN (1)....
$ grep --similar