$ cat writeup.md…
$ cat writeup.md…
umdctf
Task: a stripped PIE casino allocator exposes seat-based heap operations, encrypted inspection output, and a payout path guarded by a stack checksum. Solution: combine UAF and post-ledger OOB write for safe-linked tcache poisoning onto the payout stack frame, leak and decrypt stack data, replace the reject callback with the hidden win function, repair the checksum, and trigger payout.
$ cat /etc/rate-limit
Rate limit reached (20 reads/hour per IP). Showing preview only — full content returns at the next hour roll-over.
Remote: nc challs.umdctf.io 30304
Binary: velvet-table
Protections:
The program is a stripped menu-driven allocator with 16 seat records. Each seat stores:
ptrsizeoccupiedTwo nearby internal callbacks are especially important:
0x1b50 prints ticket rejected.0x1b60 prints yay. and calls system("/bin/sh")The goal is to redirect the payout path to the hidden function.
Reversing the binary shows three key primitives.
cashoutFor 0x80 chunks, cashout frees the chunk but leaves the seat pointer behind. That gives a reliable dangling-pointer primitive.
settle-ledgerAfter enough actions, settle-ledger enables a stronger update path that performs:
memcpy(ptr, buf, len)
with no bounds check. Combined with the dangling pointer, this lets us overwrite freed tcache metadata.
inspectinspect prints up to 0x40 bytes from a seat, but XORed with an internal keystream. That is still useful: if we first write known plaintext into a live chunk, then inspect it, we recover the keystream with:
keystream = ciphertext ^ plaintext
Then later inspect outputs can be decrypted the same way.
The service prints a table marker. That value is enough to reconstruct the payout frame location on the stack:
low32 = marker ^ 0x9ac90307 stackbuf = 0x7ff000000000 | (low32 << 4) saved_highbits = ((low32 ^ 0x5a17c3d9) & 0xffffffff) << 32
Relevant fields inside that stack buffer:
stackbuf + 0x20stackbuf + 0x28The integrity formula is:
checksum = saved_highbits ^ funcptr ^ 0x686f7573655f6564
So the full plan is:
...
$ grep --similar