본문 바로가기
코딩/C언어

C언어에서의 포맷 스트링 (Format String) 취약점

by zz! 2024. 4. 30.
728x90

"printf"와 같은 함수를 사용할 때 주의해야 할 보안 취약점 중 하나가 포맷 문자열 취약점이다.

이 취약점은 프로그램이 사용자 입력을 적절히 검증하지 않고 포맷 문자열 함수(printf, fprintf 등)에 전달할 때 발생하는 보안 문제입니다. 

이러한 상황에서는 사용자가 의도하지 않은 형식 지정자를 입력하여 프로그램이 비정상적으로 동작하거나 보안 문제가 발생할 수 있다.

 

C언어에서의 포맷 스트링 (Format String) 취약점

아래의 코드를 살펴봅시다.

#include <stdio.h>

int main()
{
	char buf[100];
	printf("이름: ");
	scanf("%s", buf);
	printf(buf);	// 여기서 취약점이 발생. 
	return 0;
}

"printf" 함수는 포맷 문자열을 사용하여 입력된 이름을 출력한다. 정상적으로 "홍길동"이라는 이름으로 입력했을 경우 아래와 같은 출력이 나온다.

하지만, 사용자가 %x 와 같은 형식 지정자를 입력하면 스택 메모리의 다른 값이 노출될 수 있다. 이는 보안상 문제를 초래할 수 있다. 

입력을 %x라고 했을 경우의 출력값입니다.

 

포맷 스트링 (Format String) 취약점 대안

- 사용자 입력을 포맷 문자열 함수에 직접 전달하지 말고, % s 등의 형식 지정자를 사용하여 출력한다.

- 정적 코드 분석 도구를 사용하여 포맷 문자열 취약점을 사전에 탐지한다.

아까 위에 사용했던 코드를 다시 작성을 해보면, 아래와 같이 수정을 할 수 있습니다.

#include <stdio.h>

int main()
{
	char buf[100];
	printf("이름: ");
	scanf("%s", buf);
	printf("%s", buf);	// 여기서 취약점이 발생. 
	return 0;
}

결과

이렇게 하면 사용자 입력이 포맷 문자열로 직접 전달되지 않으므로, 포맷 스트링 취약점을 방지할 수 있습니다.

 

참고 자료

 

포맷스트링 공격 - 해시넷

포맷스트링 공격(Format String Attack)이란 포맷스트링과 이것을 사용하는 printf() 함수의 취약점을 이용하여 RET의 위치에 셸 코드의 주소를 읽어 셸을 획득하는 해킹 공격이다. 기존에 널리 사용되던

wiki.hash.kr

728x90