Recipe for Disaster
gpnctf
Task: x86-64 food-ordering pwn binary uses gets() to read a chef note into a fixed 32-byte struct field that is directly followed by int price. Solution: overflow note by 4 bytes to set the item's own price to 0x80000000 (-2147483648), making the running total negative, which passes the verify_total(total < 0) gate and triggers print_coupon() leaking /flag. Service is TLS-wrapped, connected via Python ssl socket.
$ ls tags/ techniques/
$ cat /etc/rate-limit
Rate limit reached (20 reads/hour per IP). Showing preview only — full content returns at the next hour roll-over.
Recipe for Disaster — GPNCTF (GPN24)
Description
Are you hungry? If so, I have this awesome food ordering app for you. I only ask you not to break it.
A food-ordering CLI app. Source challenge.c and a dynamically-linked, non-stripped x86-64 ELF (challenge) with debug info are provided. The remote service is served over TLS and reached with ncat --ssl <host> 443. Goal: trigger the flag-printing path.
Analysis
The relevant struct and logic from challenge.c:
typedef struct { char item[32]; // offset 0 char note[32]; // offset 32 int price; // offset 64 } Item; void verify_total(int total) { if (total < 0) { // <-- win condition puts("[SYSTEM] Pricing error detected! ..."); print_coupon(); // opens and prints /flag exit(0); } ... } void take_order(void) { Item order[10]; ... strncpy(cur->item, MENU[choice-1].name, sizeof(cur->item)-1); cur->price = MENU[choice-1].price; printf("Any note for the chef? ...\n> "); gets(cur->note); // VULN: unbounded write into note[32] ... int total = calculate_total(order, n_items); verify_total(total); // total += each item's price }
Key observations:
...
$ grep --similar
Similar writeups
- [web][free]Fancy Food Notifications— GPNCTF 2025 (KITCTF)
- [crypto][free]Just Follow the Recipe— kitctf
- [reverse][free]Auto Cooker— GPNCTF 2026
- [pwn][free]Restaurant— hackthebox
- [pwn][free]Forks and Knives— hackthebox