Format String Bug (FSB) : printf() 함수 계열을 사용할 때, 인자로 포맷 스트링과 포맷 스트링에 대응하는 인자를 사용하지 않고 바로 변수를 인자로 지정했을 때, 악의적인 공격자가 포맷 스트링을 입력하여 스택의 값을 leak 하거나, RET나 _DTOR_END__, GOT와 같은 프로그램의 흐름을 제어할 수 있는 메모리 주소값을 변조하여 악의적인 행동을 할 수 있게 된다.
윈도우와 우분투에 파일을 다운받고 IDA로 코드를 확인해보자.
메인함수에선 따로 확인할건 없어보인다.
vuln 함수를보자.
snprintf 함수와 printf 함수에서 서식문자를 따로 지정해주지 않고 바로 넘겨버린다.
이 함수에서 FSB 취약점이 발생한다는 것을 알 수 있다. 두 함수에 대해 알아보자.
sprintf(char * buffer, const char * format, ...)
- ... 은 가변 파라미터를 뜻 한다.
- 첫 번째 인자에 두 번째 인자의 내용이 문자열로써 담기게 된다.
snprintf(char * buffer, int buf_size, const char * format, ...)
- sprintf 함수에서 두 번째 인자로 size가 추가된 함수로, buffer overflow를 방지하기위해 출력할 문자열의 길이를 지정하였다.
gdb를 이용해 basic_fsb에 flag 함수가 있는걸 확인했다.
이 함수를 이용하면 될 것 같다.
우분투에서 파일을 실행해서 서식문자를 넣어보자.
두 번째 서식문자에는 입력된 AAAA의 hex값인 41414141이 출력된다.
%n : 서식문자 앞까지의 바이트 수를 계산 후 출력, 출력했던 값을 주소로 생각하고 계산한 값을 주소에 넣는다.
그렇다면 위의 서식문자를 바탕으로 이렇게 사용할 수 있을 것 같다.
-> printf_GOT 주소에 %n 이 오게한 다음, %n이 flag 함수의 주소를 계산하게 만들면 문제가 해결될 것이다!!
GOT는 PLT가 참조하는 테이블이다. 쉽게 말하면 함수의 실제 주소가 들어있다.
자! 이제 printf_GOT의 주소와 flag 함수의 주소를 찾아보자.
모두 찾았다. python으로 익스를 짜보자.
flag 함수의 주소값 0x80485b4을 10진수로 바꾼만큼 %x 포맷을 이용해 출력 해준다.
그리고 위에서 포맷스트링 두 번째부터 입력값이 출력됐기 때문에 -4byte를 해줘야 한다.
0x80485b4 -> 134514100
134514100 - 4 = 134514096
실행해보자.
익스가 되고 플래그가 나왔다.
플래그는 HackCTF{여보게_오늘_반찬은_포맷스트링이_어떠한가?} 이다.
문제를 이해하기 위해 많은 시간을 들였다. 좀 더 열심히 공부해야겠다.
'HackCTF > WriteUp' 카테고리의 다른 글
HackCTF - Simple_Overflow_ver_2 [150] (0) | 2021.01.19 |
---|---|
HackCTF - x64 Simple_size_BOF [150] (0) | 2021.01.17 |
HackCTF - x64 Buffer Overflow [150] (0) | 2021.01.13 |
HackCTF - 내 버퍼가 흘러넘친다!!! [150] (0) | 2020.12.22 |
HackCTF - Basic_BOF #2 [100] (0) | 2020.12.06 |