제어되지 않는 형식 문자열

Uncontrolled format string

제어되지 않는 형식 문자열은 1989년경에 발견된 소프트웨어 취약성의 일종으로 보안 취약성에 사용될 수 있다.[1]원래 무해하다고 생각되었던 형식 문자열 이용은 프로그램을 중단시키거나 유해 코드를 실행하는 데 사용될 수 있다.문제는 다음과 같은 형식을 수행하는 특정 C 함수에서 체크되지 않은 사용자 입력형식 문자열 파라미터로 사용하는 데서 기인한다.printf()악의적인 사용자는 다음을 사용할 수 있다.%s그리고%x무엇보다도, 통화 스택 또는 메모리의 다른 위치에서 데이터를 인쇄하기 위해 토큰을 포맷한다.또한 을 사용하여 임의의 위치에 임의의 데이터를 쓸 수도 있다.%n형식 토큰, 명령어printf()그리고 스택에 저장된 주소에 포맷된 바이트 수를 기록할 수 있는 유사한 기능.

세부 사항

예를 들어, 프로그램이 라이브러리 함수 또는 스택의 반환 주소를 일부 악의적인 코드에 대한 포인터로 덮어쓰도록 강제하는 등,[2] 일반적인 공격에서는 이러한 기법의 조합을 사용하여 프로세스의 명령 포인터(IP)를 제어한다.형식 지정자에 대한 패딩 매개 변수는 바이트 출력 수와%x토큰은 형식 문자열 자체의 시작에 도달할 때까지 스택에서 바이트를 팝업하는 데 사용된다.형식 문자열의 시작은 다음과 같은 주소를 포함하도록 조작된 것이다.%n포맷 토큰은 실행할 악성 코드의 주소로 덮어쓸 수 있다.

이는 포맷 버그가 이전에 무해하다고 생각되어 많은 공통 도구에 취약성을 초래했기 때문에 흔한 취약성이다.MITRE의 CVE 프로젝트는 2007년 6월 현재 약 500개의 취약한 프로그램을 나열하고 있으며, 추세 분석은 2001년부터 2006년 사이에 가장 많이 보고된 취약성 유형 중 9번째로 순위를 매긴다.[3]

포맷 문자열 버그는 프로그래머가 사용자 제공 데이터(파일, 버퍼 또는 사용자)를 포함하는 문자열을 출력하고자 할 때 가장 일반적으로 나타난다.프로그래머는 실수로 글을 쓸 수 있다.printf(buffer)대신에printf("%s", buffer)첫 번째 버전은buffer형식 문자열로, 형식 지정 지시사항을 구문 분석한다.두 번째 버전은 프로그래머가 의도한 대로 단순히 화면에 문자열을 인쇄한다.두 버전 모두 문자열의 형식 지정자가 없을 때 동일하게 동작하므로, 개발자가 실수를 눈치채기 쉽다.

포맷 버그는 C의 논거 통과 규약이 타입-세이프가 아니기 때문에 발생한다.특히 더.varargs메커니즘은 함수가 임의의 수의 인수(예:printf)는 통화 스택에서 원하는 만큼 많은 주장을 "해결"하여, 초기 주장을 신뢰하여 얼마나 많은 추가 논거를 발생시킬 것인지, 그리고 어떤 유형의 논거를 발생시킬 것인지를 표시한다.

포맷 문자열 버그는 더 적은 빈도로 나타나며 대개 공격자가 선택한 코드를 실행하는 데 악용될 수 없지만 Perl과 같이 C 이외의 다른 프로그래밍 언어에서 발생할 수 있다.[4]

역사

포맷 버그는 1989년 위스콘신 대학에서 행해진 솜털 테스트 작업에 의해 처음 언급되었는데, 이 실험은 명령 이력 메커니즘과 안전 문자열 입력을 가정한 오류 루틴 사이의 C 쉘(csh)에서 "상호작용 효과"를 발견했다.[5]

형식 문자열 버그를 공격 벡터로 사용한 것은 1999년 9월 Tymm Twillman에 의해 ProFTPD 데몬의 보안 감사 에 발견되었다.[6]감사에서 ...을 적발했다.snprintf형식 문자열 없이 사용자가 생성한 데이터를 직접 전달.인쇄형 함수를 위해 고안된 인수를 사용한 광범위한 테스트는 권한 상승에 이를 사용할 수 있다는 것을 보여주었다.이로 인해 1999년 9월 Bugtraq 메일링 리스트에 기초적인 착취를 포함한 이 취약성 등급에 대한 첫 게시글이 게시되었다.[6]그러나 이 방법을 사용하는 다른 소프트웨어에 대한 공격이 표면화하기 시작함에 따라 보안 커뮤니티가 형식 문자열 취약성의 완전한 위험을 인식하기까지는 아직 몇 달이 지났다.(코드 실행을 통한 원격 루트 액세스 제공으로) 이 문제를 일반의식에 가져온 첫 번째 공적은 2000년 6월 Przemyswow Frasunek[7] tf8이라는 닉네임을 사용하는 사람에 의해 Bugtraq 목록에 동시에 게재되었다.[8]곧 이어 라마그라라는 별명을 사용하는 사람이 올린 설명이 이어졌다.[9]"포맷 버그"는 2000년 7월 파스칼 부샤레인에 의해 Bugtraq 목록에 게시되었다.[10]팀 뉴샴의 세미날 논문 「형식 문자열 공격」[11]은 2000년 9월에 발표되었으며, Teso 팀에서는 2001년 9월에 Attacking Format String 취약성 등의 상세한 기술 설명서가 발표되었다.[2]

컴파일러의 예방

많은 컴파일러는 형식 문자열을 정적으로 검사할 수 있으며 위험하거나 의심스러운 형식에 대한 경고를 생성할 수 있다.GNU 컴파일러 컬렉션에서 관련 컴파일러 플래그는 다음과 같다.-Wall,-Wformat,-Wno-format-extra-args,-Wformat-security,-Wformat-nonliteral그리고-Wformat=2.[12]

이 중 대부분은 컴파일 시간에 알려진 잘못된 형식 문자열을 탐지하는 데만 유용하다.형식 문자열이 사용자 또는 응용 프로그램의 외부 소스로부터 올 수 있는 경우, 응용 프로그램은 형식 문자열을 사용하기 전에 형식 문자열을 검증해야 한다.응용 프로그램이 즉시 형식 문자열을 생성하거나 선택하는 경우에도 주의해야 한다.GNU C 라이브러리를 사용하는 경우-D_FORTIFY_SOURCE=2매개변수를 사용하여 런타임에 발생하는 특정 유형의 공격을 탐지할 수 있다.-Wformat-nonliteral점검이 더 엄격하다.

탐지

다른 많은 보안 문제와 달리 형식 문자열 취약성의 근본 원인은 x86 컴파일 실행 파일에서 비교적 쉽게 탐지할 수 있다.을 위해printf- 패밀리 함수, 적절한 사용은 포맷 문자열과 포맷할 인수에 대한 별도의 인수를 의미한다.그러한 기능의 잘못된 사용은 기능에 전달된 논쟁의 개수를 세는 것만으로도 알 수 있다; 그렇다면 '주장 부족'[2]은 그 기능이 잘못 사용되었다는 강력한 지표가 된다.

x86 컴파일된 이진에서 탐지

x86에서는 통화 후 스택 포인터에 추가하여 스택에 밀어넣은 인수를 제거하는 호출 규약 때문에 인수 횟수를 세는 것이 쉽게 이루어지기 때문에 스택 보정을 간단히 검토하면 인수의 합계가 산출된다.printf-가족 기능.'[2]

참고 항목

참조

  1. ^ "CWE-134: Uncontrolled Format String". Common Weakness Enumeration. MITRE. 2010-12-13. Retrieved 2011-03-05.
  2. ^ a b c d http://julianor.tripod.com/bc/formatstring-1.2.pdf[bare URL PDF]
  3. ^ Bugtraq: Perl 프로그램의 형식 문자열 취약성
  4. ^ Miller, Barton P.; Fredriksen, Lars; So, Bryan (December 1990) [1989]. "An Empirical Study of the Reliability of UNIX Utilities" (PDF). Communications of the ACM. 33 (12): 32–44. doi:10.1145/96267.96279. S2CID 14313707.
  5. ^ a b Bugtraq: proftpd 1.2.0pre6에 대한 공격
  6. ^ 'UFTPD 2.6.0 원격 루트 취약성' - MARC, 2000년 6월 Przemyswow Frasunek
  7. ^ 'WuFTPD: 최소 1994년부터 *원격* 루트 제공' - tf8별 MARC
  8. ^ Bugtraq: 2000년 6월 라마그라 아르가말(Lamagra Argamal)에 의해 Wuftpd 버그 외에 버그를 포맷
  9. ^ Bugtraq: Pascal Bouchareine의 2000년 7월 버그 포맷 버그
  10. ^ Bugtraq: 문자열 공격 형식 지정팀 뉴샴 2000년 9월
  11. ^ 경고 옵션 - GNU 컴파일러 모음(GCC) 사용

추가 읽기

외부 링크