주요 내용으로 건너뛰기

메모리 취약점:과거, 현재, 미래 (5) Format String Attacks

포맷 스트링 취약점은 printf 로 대표되는 다음과 같은 형식출력 함수들에게서 발생한다. 

  • fprintf — prints to a FILE stream 
  • printf — prints to the ‘stdout’ stream 
  • sprintf — prints into a string 
  • snprintf — prints into a string with length checking 
  • vfprintf — print to a FILE stream from a va_arg structure 
  • vprintf — prints to ‘stdout’ from a va_arg structure 
  • vsprintf — prints to a string from a va_arg structure 
  • vsnprintf — prints to a string with length checking from a va_arg structure

이 함수들은 변수를 인자로 하여 문자열의 형식을 지정하는데, 이 지정자를 의도적으로 조작하면 전혀 다른 방향의 부작용을 가져올 수 있다.

흔히 예를 드는 방법은 printf(buf) 과 같은 방법으로, 이렇게 악용되면 시스템이 exploit 될 수 있다. 프로그램의 printf 함수 사용이 취약하게 구현되어 있다면 사용된 format에 따라 %x를 통해 직접적으로 프로세스의 주소 공간에 접근하거나, %s를 통해 간접적으로라도 내용을 구할 수 있다. 또한 %n이나 그와 유사한 %hn, %hhn, %k$n 등을 통해 지금까지 기록된 바이트 수를 계산하고, 스택의 다음 실행 주소를 덮어쓸 수도 있다.

앞선 글에서 다룬 heap attack과 유사하게 (하지만 classic buffer overflow와는 다르게) 포맷 스트링 취약점은 write-anything-anywhere 권한을 획득하기에 수월한 exploit이며, 대상 프로세스의 전체 주소 공간에 어디에나 접근할 수 있고, 내용을 임의로 수정할 수도 있다. 이는 기밀 데이터(암호화 키, seed 정보 등)을 가로채는 일에 사용되기도 하고 심지어 임의의 코드를 실행하도록 유도하는 것 역시 가능하다.

포맷 스트링 취약점은 1999년 ProFTPD 프로그램을 분석하던 중 최초로 발견되었다. [T. Twillman, “Exploit for proftpd 1.2.0pre6,” September 1999] 이후 유명세를 얻게되어 2000년에는 Wu-Ftpd 를 원격 조작할 수 있는 방법이 BugTraq에 보고되기도 했다. [BugTraq, “Wu-Ftpd Remote Format String Stack Overwrite Vulnera- bility,” June 2000.]

앞서 Tim Newsham에 의해 포맷 스트링 공격에 대한 기본 개념과 그 취약점의 의미가 설명되긴했지만, 이를 실제로 대중들에게 폭넓게 전달하여 진입장벽을 낮추게 된 계기는 TESO team의 Scut이 2001년 발표한 Whitepaper 덕분이다. 


일반적으로 적용할 수 있는 string format 취약점을 자세히 설명하면서 이를 악용할 수 있는 새로운 공격 기법을 제시하기도 하였다. 게다가 format reply output에 대한 brute force를 수행함으로써 공격의 복잡성을 낮추는 방안도 제안하였다. 특히 write-anything-anywhere 권한이 획득된다면 대상 프로그램의 control-flow와 관련된 GOT, dtors 등의 데이터를 조작할 수 있음을 보였다. 심지어 Canaries, Return address integrity check 등의 보호기법에 대해서도 이를 우회할 수 있음이 알려졌다. [G. . Riq, “Advances in format string exploitation,” Phrack, July 2002]


포맷 스트링 공격에 대한 방어기법은 2001년 USENIX Security Symposium에서 “Format- Guard: Automatic Protection From printf Format String Vulnerabilities” 가 발표되었다. 이는 소스코드 레벨에서 정적분석을 사용하여 printf와 같은 함수에 명시된 파라미터의 개수와 실제 함수의 형식 문자열에 지정된 갯수를 비교한다. 만약 불일치가 발생한다면 이는 공격으로 간주되어 자동으로 프로세스를 종료한다. 하지만 이러한 방법은 정적 분석이 갖는 한계에 한정된다는 단점이 있다.


다행히도 포맷 스트링 취약점은 비교적 탐지하기도 쉽고 이를 수정하는데 드는 비용도 크지 않다. 게다가 Windows 등의 운영체제는 2010년부터 %n 등의 기능을 비활성화하였으며 [Microsoft, “Disable %n format string” 2010.], GNU C 라이브러리의 FORTIFY_SOURCE 에서도 포맷 스트링을 통한 exploit을 현저하게 곤란하게 만드는 보호 기법이 패치되었다. 하지만 Write 하는 방법을 막는다하더라도 Read는 여전히 가능하기 때문에 아직 문제가 있다고 볼 수 있다.

이렇게 새로운 방어기법에 대한 또다른 공격기법은 여전히 현재진행형이다. [C. Planet, “A Eulogy for Format Strings,” Phrack, Nov. 2010.]


Software Security Engineer

CPUU 님의 창작활동을 응원하고 싶으세요?

댓글

SNS 계정으로 간편하게 로그인하고 댓글을 남겨주세요.