write-up/pwnable

[HackCTF] Basic_FSB

여니두 2019. 10. 4.

★ FSB (Format String Bug)

ex. printf(buf) --> 입력값을 포맷스트링으로 넣으면 입력값을 문자로 취급하는 게 아니라 서식문자로 취급하여 취약점이 일어날 수 있다.

서식문자를 만나면 메모리의 다음 4byte 위치를 참조하여 그 서식문자의 기능대로 출력한다.

>> %d를 입력했을 때, 메모리에 있는 값을 10진수로 출력하는 것을 뜻함.

 

buf 배열을 가리키고 있는 다음 4byte부터 입력한 서식문자의 기능대로 출력한다.

 

- setvbuf(FILE 구조체에 대한 포인터, buffer, 버퍼링 모드, size)

: 스트림 버퍼링 및 버퍼 크기를 제어.

 

- vuln()

fgets로 버퍼 s에 1024byte만큼 입력받는다.

 

- snprintf()

버퍼로 사용될 변수로 출력이 된다. 즉 char *f로 선언된 변수 안에 입력된 내용이 문자열로써 담긴다.

BOF를 막기 위해 문자열의 길이를 지정하는 좀 더 안전한 함수.

 

이 함수를 이용하여 s 버퍼의 내용을 format 버퍼에 저장하고 있다.

그 후, printf에서도 포맷스트링 없이 변수를 그대로 출력하고 있다!

 

s 버퍼의 내용물을 0x408(1032byte)만큼 출력시키는 것을 알 수 있다.

 

함수 목록에 flag가 있어 살펴보니, 쉘을 실행시키는 system() 함수가 있었다.

 

★ 결론

vuln() 함수에서 snprintf()에서 FSB를 일으킨 후, 아래에서 return printf()로 값을 출력해줄 때

printf@got Overwirte를 발생시켜 flag() 함수로 값을 조작해주자.

 

2번째 부분에서 aaaa가 들어간 것을 알 수 있다. 이 부분에서 %n을 이용할 것이고,

이전의 입력값을 이용하여 크기를 맞춰주자.

 

1) 자신이 입력한 dummy 값(aaaa)이 나오는 위치를 찾기

--> 우리가 최종적으로 %n을 사용할 위치임. 덮어쓸 주소를 %n을 이용하여 만들어주기.

 

2) 덮임을 당할 주소(aaaa 위치)에 %n으로 만들어진 값들이 채워진다. 그 후 flag() 함수의 주소로 덮어주자.

 

flag() = 0x080485b4 = 134514100 (dex)

 

%n을 이용하여 flag을 주소값을 맞춰주어야 하는데, 앞에 printf@got가 입력되었으므로 4byte를 빼줘야 한다.

 

 

payload = printf@got(덮을 위치) + %(134514096)%n

 

'write-up > pwnable' 카테고리의 다른 글

[HackCTF] x64 Buffer Overflow  (0) 2019.10.04
[HackCTF] 내 버퍼가 흘러넘친다!!!  (0) 2019.10.04
[HackCTF] Basic_BOF #2  (0) 2019.10.04
[HackCTF] Basic_BOF #1  (0) 2019.10.04
[pwnable.kr] cmd1  (0) 2019.09.29

댓글