Web취약점 진단 - 포맷스트링

1. 포맷스트링(FS)

 

2. 취약점 개요 

 

포맷 스트링은 외부 입력을 포맷 문자열로 사용하면 메모리 노출 및 실행 흐름 변조로 이어질 수 있는 취약점을 말하며, 공격자는 포맷 토큰을 삽입하여 메모리 내용을 조회하거나, 특정 환경에서는 프로그램 제어 흐름을 변경하여 권한 상승으로 이어질 수 있다.

- 포맷 문자열은 소스 코드에 하드코딩된 리터럴(값)이다.

- 포맷 함수는 항상 포맷 문자열을 해석함 

- printf, fprintf, syslog와 같은 포맷 함수를 외부 입력값에 포맷 문자열로 사용했을 때 취약

- printf("포맷 문자열", 데이터들...);

✅ 안전한 패턴  

printf("Hello %s\n", user_input); // 포맷 문자열 : "Hello %s\n" ▶ 포맷 문자열이 고정된 상태, 하드코딩됨

- 컴파일된 순간부터 토큰(%s)로 고정 

 

❌ 위험한 패턴

printf(user_input);  // 외부 입력 값 : user_input

-  포맷 토큰 : %x, %s, %n 등 

-  포맷 문자열 자리에 외부 입력값이 들어갔기 때문에 공격자는 포맷 토큰을 삽입해서 메모리 내용 조회하거나 특정 경우엔 메모리를 쓴다

- 공격자 : printf(user_input)에 user_input 대신 %x %x %x %x를 넣으면 printf("%x %x %x %x")를 실행시킨 것과 같으므로 메모리 정보 노출을 일으킨다

 

3. 점검 결과 

1) 웹 사이트에서 사용자가 입력한 파라미터 값에 아래와 같은 패턴 입력 후 전송 시 다 른 값을 입력했을 때는 발생하지 않는 에러 반응이나 멈추는 등 이상 반응을 보이는지 점검

패턴1 - %n%n%n%n%n%n%n%n%n%n, ▶ 

패턴2 - %s%s%s%s%s%s%s%s%s%s,

패턴3 - %1!n!%2!n!%3!n!%4!n!%5!n!%6!n!%7!n!%8!n!%9!n!%10!n!

패턴4 - %1!s!%2!s!%3!s!%4!s!%5!s!%6!s!%7!s!%8!s!%9!s!%10!s!

 

4. 권고사항

1) 컴파일러의 자체 검사 기능을 활용하여 문자열 입력 포맷의 일치 여부를 검증하고 소스 코드에 적용해야 함 ( 예:GCC 컴파일러의 경고 옵션 활용 )런타임 환경에서는 Fuzz testing 등의 방법을 사용하여 포맷 스트링 버그가 존재하는지 지속적으로 검증해야 함 2) 웹 서버 프로그램에 대해 최신 보안 패치를 즉시 적용하여 알려진 취약점을 제거하고, 서버의 안정성을 확보해야 함

3) 웹 사이트에서 사용자가 입력한 파라미터 값 처리 과정 중 발생하는 취약점을 방지하기 위해 , 입력값의 유효성에 대한 검증 로직을 반드시 구현해야 함 (예: 데이터 타입 길이 허용 문자 등 검사)