pwnfreeeasy

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/
gets_exploitationintra_struct_field_overwritesigned_integer_underflowlittle_endian_overwritetls_socket_pwn

$ 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