본문 바로가기

Pwnable/HackCTF

[ProjectH4C] HackCTF (Basic_FSB)

 


포맷 스트링 버그(FSB)

포맷 스트링 버그는 주로 C언어의 printf 함수를 사용할 때 발생한다.  %d, %s 와 같은 것들을 포맷 스트링이라고 하는데, buf를 입력받고 해당 buf를 출력할 때 포맷 스트링을 이용해 흐름을 바꿀 수 있다.

 

 

 

보통 문자열을 출력하기 위해 C언어에서는 다음과 같이 코드를 작성한다.

#include <stdio.h>

int main(){
	char buf[];
    
	scanf("%s", buf);
	printf("%s", buf);
    
	return 0;
}

printf 함수를 위의 형태가 아닌 아래의 형태로 사용해도 그대로 출력되기는 한다.

 

printf(buf);

 

 

하지만 이 때, buf에 %s 와 같이 포맷 스트링을 입력하게 되면, printf("%s")가 되는데, %s에 들어갈 값을 지정해주지 않았기 때문에 잘못된 동작을 하게 되는데, 이를 이용해 원하는 메모리에 원하는 값을 쓸 수가 있게 된다.

메모리에 값을 쓸 때에는 %n 지정자를 사용한다. 나머지의 서식 지정자들은 지정된 변수의 값을 읽어 출력하는 방식이지만, %n 지정자는 해당 지정자 전까지 출력된 문자의 개수를 세어서 10진수의 형태로 출력하는 역할을 한다.

 


 

 

IDA를 이용해 basic_fsb 소스코드를 먼저 확인해보았다.

 

 

main 함수

 

main에서 stdout을 정의해준 후에 vuln 함수 호출한다.

 

vuln 함수

vuln 함수에서는 fgets를 통해 1024바이트를 s에 입력받고, snprintf를 이용해 s의 출력을 format에 저장한 후에 format을 출력하면서 함수를 종료한다. 이 때, format이 "%s"라면, printf("%s")가 실행되는데 이러한 취약점을 이용해 공격하면 된다.

또한 main, vuln 함수 외에도 flag라는 함수가 존재한다. flag 함수는 쉘을 실행시켜주는 함수이다. 

 

버퍼 오버플로우는 보통 ret 주소를 변조하는 것이 목적인데, fsb는 어떠한 함수의 GOT을 조작하여서 흐름을 바꿀 수 있다. GOT이란 해당 함수의 시작 주소를 가지고 있는 테이블이라고 보면 되는데, printf 함수의 GOT을 flag 함수의 주소로 바꾸어주면, printf가 아닌 flag 함수가 실행되는 것이다.

 

페이로드를 작성하는 방법은 다음과 같다.

 

payload = "printf의 got 주소 + %[flag 함수 주소]x%n"

printf의 got은 pwntools에서 elf 함수를 이용해 쉽게 구할 수 있다. elf는 적용되어 있는 보호기법, plt, got 등을 제공한다.

 

from pwn import *

r = remote("ctf.j0n9hyun.xyz", 3002)
e = ELF("/Users/moose/downloads/basic_fsb")
r.recvuntil("input : ")

printf_got = e.got['printf']
print(printf_got)
Moose:Python moose$ python tool.py
[+] Opening connection to ctf.j0n9hyun.xyz on port 3002: Done
[*] '/Users/moose/downloads/basic_fsb'
    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX disabled
    PIE:      No PIE (0x8048000)
    RWX:      Has RWX segments
    134520844

보호기법은 아무것도 적용되어 있지 않고, 마지막 줄에 134520844가 출력되는데, 이를 16진수로 바꾸면 0x804A00C가 된다. 해당 주소가 바로 printf의 got이며, flag 함수의 주소를 덮어씌울 위치이기도 하다. 페이로드는 다음과 같다.

 

flag를 획득하는데 성공하였다.