Format String Bug

포멧 스트링 버그

포맷 스트링 버그는 printf나 sprintf와 같이 포맷 스트링을 사용하는 함수에서 발생하는 취약점으로, "%x"나 "%s"와 같이 프로그래머가 지정한 문자열이 아닌 사용자의 입력이 포맷 스트링으로 전달될 때 발생하는 취약점이다.

예시 코드를 봐보자면,

#include <stdio.h>
int main(void) {
    char buf[100] = {0, };
    
    read(0, buf, 100);
    printf(buf);
}

진짜 매우 간단해보이는 코드임에도, read가 100자리 문자열을 받는데 그 문자열이 만약 "%x" 나 "%s"와 같은 포멧 스트링으로 넣는다면????

허허......

bf3977c0 100

우리가 원한대로 친 값을 출력해주긴 한데... 이런 버그같은 취약점이 실행되어버린거다.

그러나 "%x %d"와 같은 포맷 스트링을 문자열로 입력한다면, printf(buf)는 printf("%x %d")가 된다.

printf("%x %d")에는 두 번째 인자와 세 번째 인자가 전달되지 않기 때문에 쓰레기 값을 인자로 취급해 출력한다. 이건 기억해두자.

게다가, fprintf 도 printf와 똑.같.이 작용하니 진짜 조심하자. 뭣도 모르다가 포멧 스트링 버그가 날 수 있다.

포맷 스트링 버그는 포맷 스트링을 사용하는 함수의 인자만 잘 검토하면 되기 때문에 다른 취약점들에 비해 막기 쉽다.

특히 최신 컴파일러에서는 포맷 스트링으로 전달되는 인자가 문자열 리터럴이 아닐 경우 경고 메시지를 출력하기 때문에 요즘에는 잘 발생하지 않는 취약점이다.