SH1R0_HACKER
004. Format String Bug 본문
포맷 스트링 버그는 printf나 sprintf와 같이 포맷 스트링을 사용하는 함수에서 발생하는 취약점입니다.
// fsb-1.c
#include <stdio.h>
int main(void) {
char buf[100] = {0, };
read(0, buf, 100);
printf(buf);
}
위 예제는 buf에 100byte를 입력받고 printf 함수를 통해 buf를 출력하는 예제입니다.
사용자가 "Hello" 나 "12345" 같은 문자열을 입력다면
printf("Hello");
printf("12345");
와 같이 정상적으로 문자열이 출력됩니다.
하지만 %x %d 와 같은 포맷 스트링을 문자열로 입력한다면,
printf("%x %d")와 같이 인자를 받을 수 있는 함수로 변해버립니다.
하지만 전해줄 인자가 없기 때문에 쓰레기 값을 출력하게 됩니다.
두 번째 예제입니다.
// fsb-2.c
#include <stdio.h>
#include <stdlib.h>
int main(void) {
FILE *fp = fopen("log.txt", "w");
char buf[100] = {0, };
read(0, buf, 100-1);
fprintf(fp, "BUFFER-LOG: ");
fprintf(fp, buf);
fclose(fp);
return 0;
}
log.txt 파일을 읽기 전용으로 열어서 read 함수로 99byte만큼 buf에 데이터를 저장합니다.
fprintf의 원형은 아래와 같습니다.
#include <stdio.h>
int fprintf(FILE* stream, const char* format, ...);
fprintf(fp, "BUFFER-LOG: %s "); 와 같이 포맷스트링이 들어가야 할 곳에 사용자의 입력이 들어갑니다.
예제 1번과 마찬가지로 %x, %d 같은 포맷 스트링을 입력하면 의도치 않은 값이 파일에 저장됩니다.
포맷 스트링 버그는 함수의 인자만 잘 검토하면 막기 쉽습니다.
최근에는 컴파일러에서 경고 메시지를 출력하기 때문에 잘 발생하지 않는 취약점입니다.
// fsb-easy.c
#include <stdio.h>
int main(void) {
int flag = 0x41414141;
char buf[32] = {0, };
read(0, buf, 31);
printf(buf);
}
위 예제는 사용자의 입력을 31byte만큼 printf로 buf를 출력하는 예제입니다.
여기에 포맷 스트링을 입력해 버린다면 의도치 않은 값을 출력할 수 있습니다.
따라서 %x를 10번 입력하여 flag 값을 출력하도록 합니다.
'System > System Exploitation' 카테고리의 다른 글
006. 초기화되지 않은 메모리 (0) | 2021.02.07 |
---|---|
005. Double Free & Use After Free (0) | 2021.02.07 |
003. Off-by-one (0) | 2021.02.03 |
002. OOB (Out Of Boundary) (0) | 2021.02.03 |
001. 스택 버퍼 오버플로우 (Stack Buffer Overflow) (0) | 2021.02.01 |