5장. 버퍼오버플로우 피하기

 

An enemy will overrun the land; he will pull down your strongholds and plunder your fortresses.

 Amos 3:11 (NIV)
차례
5.1. C/C++ 에서의 위험
5.2. C/C++ 에서의 라이브러리 솔루션
5.2.1. 표준 C 라이브러리 솔루션
5.2.2. 정적 및 동적 할당 버퍼
5.2.3. strlcpy and strlcat
5.2.4. libmib
5.2.5. C++ std::string class
5.2.6. Libsafe
5.2.7. 다른 라이브러리
5.3. C/C++ 에서의 컴파일 솔루션
5.4. 다른 언어

극히 공통적인 보안 결함은 "버퍼 오버플로우" 에 대한 취약성이다. 버퍼 오버플로우는 "버퍼 오버런" 이라고도 하는데 "stack smashing" 과 "heap smashing" 공격을 포함하여 많은 종류의 버퍼 오버플로우 공격이 있다. 기술적으로 버퍼 오버플로우는 프로그램의 내부적인 구현과 관련된 문제이지만 저자가 이를 독자적인 장에서 다룰만큼 널리 알려진 심각한 문제이다. 이 주제가 얼마나 중요한 지에 대해 이해시키기 위해 CERT 에서는 1998 년에는 13 개 권고안 중 9개 및 1999 년에는 적어도 절반의 권고안에 버퍼 오버플로우를 포함했다. 버그트랙에 대한 1999 년의 비공식적 조사는 대략 응답자의 2/3 가 버퍼 오버플로우가 시스템 보안을 취약하게 하는 주된 요인이였다고 느꼈음을 발견했다 (나머지 응답자는 오설정을 주된 요인으로 식별하였다) [Cowan 1999]. 이는 잘 알려진 오래된 문제로 아직껏 계속해서 문제로 대두되고 있다 [McGraw 2000].

버퍼 오버플로우는 보통 문자들의 문자열인 일련의 값들을 고정된 길이를 갖는 버퍼에 작성하고 적어도 한 값을 버퍼의 경계 외부 (보통 버퍼 경계를 넘어선다) 에 작성할 때 일어난다. 버퍼 오버플로우는 사용자로부터의 입력을 버퍼내로 읽어들일 때 일어날 수 있지만 또한 프로그램내에서 다른 종류의 프로세싱 동안에 일어날 수도 있다.

보안적인 프로그램이 버퍼 오버플로우를 허용한다면 이는 대개 공격자에 의해 악용될 수 있다. 버퍼가 지역적인 C 변수라면 오버플로우는 함수로 하여금 공격자가 선택한 코드를 실행시키도록 하는데 사용될 수 있다. 이러한 특정 변형을 대개 "stack smashing" 공격이라고 한다. 힙에서 버퍼는 더욱 좋지 않은데 공격자가 프로그램내의 다른 변수를 제어하기 위해 오버플로우 등을 사용할 수 있을 지도 모른다. 더욱 세부적인 사항은 Aleph1 [1996], Mudge[1995] 또는 Nathan P. Smith 의 "Stack Smashing Security Vulnerabilities" 웹사이트 http://destroy.net/machines/security/ 에서 찾을 수 있다.

대부분의 상위 수준 프로그래밍 언어는 자동적으로 배열의 크기를 조정하거나 (예, 펄) 또는 보통 버퍼 오버플로우를 탐지해서 예방하기 때문에 (예, Ada95) 본질적으로 이 문제는 없다.그러나 C 언어는 이 문제에 대해 어떠한 보호도 제공하지 않으며 C++ 도 또한 이 문제를 야기할 수 있는 방식으로 쉽게 사용될 수 있다. 어셈블러도 또한 어떠한 보호도 제공하지 않는데 보통 이러한 보호를 제공하는 어떤 언어 (예, Ada 와 파스칼) 들은 이 보호 기능을 성능적인 측면에서 금지할 수 있다. 대부분의 프로그램이 다른 언어로 작성된다 하더라도 많은 라이브러리 루틴은 C 또는 C++ 로 작성되어 있으며 결과적으로 이 루틴을 호출하는 glue 코드도 마찬가지인데 따라서 원하는 만큼 다른 언어들은 버퍼 오버플로우에 대한 완전한 보호를 제공하지는 않는다.