Secure Coding)Buffer Overflow

시큐어 코딩

Featured image

@

Buffer Overflow란?

프로그램이 입력(사용자, 파일, 네트워크를 통하거나 또는 다른 방법)을 요구할 때마다, 부적절한 데이터를 받을 가능성이 있다. 입력 데이터가 예약된 공간보다 큰 경우 이것을 자르지 않는다면 그 데이터는 다른 데이터를 덮어 쓰게 될 것이다. 이 경우를 Buffer Overflow라고 한다.

Buffer Overflow의 특징

Buffer Overflow는 어플리케이션에 충돌을 일으키거나 데이터를 손상 시킬 수 있다. 그리고 어플리케이션이 작동하는 시스템에 손상을 입힐 수 있는 추가적인 권한 상승을 위한 공격 벡터를 제공할 수 있다.

모든 응용 프로그램 또는 시스템 소프트웨어는 적어도 일시적으로 사용자로부터의 입력, 파일로부터의 입력, 네트워크로부터의 입력을 저장할 수 있다. 특별한 경우를 제외하고 대부분의 어플리케이션 메모리는 두 장소 중 하나에 저장된다. 따라서 두 장소를 공격하는 Stack Overflows, Heap Overflows가 있다.

Buffer Underflow란?

입력된 데이터가 있거나 예약된 공간(잘못된 가정, 잘못된 길이 값 또는 C 문자열과 같은 원시 데이터 복사로 인한)보다 짧게 나타날 때를 Buffer Underflow라고 한다. 이것은 오작동부터 현재 스택 또는 힙에 있는 데이터 유출까지 여러 문제가 발생할 수 있다.

해결 방안1. String Handling

많은 문자열 처리 함수는 문자열 길이에 대한 확인을 하지 않고 있기 때문에 문자열은 자주 익스플로잇 가능한 버퍼 오버플로우 소스이다. 위의 그림은 세 개의 문자열 복사 함수가 길이를 초과하는 동일한 문자열을 처리하는 다른 방법을 나타낸 것이다.

이외에도 주의해야할 함수들이 많이 존재한다. 그것들을 모두 다루는 것은 다소 무리가 있다. Objective-C에선 NSString, CFString을 사용하는 것이 위의 문제들을 해결한 API이기에 특별한 경우가 없다면 Core Foundation을 사용하자.

해결 방안2. Calculating Buffer Sizes

고정된 길이의 버퍼로 작업을 할 때, 버퍼의 사이즈를 계산하기 위해 항상 sizeof 를 사용해야 한다. 그리고 보유할 수 있는 것보다 더 많은 데이터를 버퍼에 넣지 않았는지 확인해야 한다. 원래 버퍼에 정적 크기를 할당하더라도, 당신 또는 나중에 당신의 코드를 유지하는 어떤 사람 중 누군가 버퍼 사이즈를 변경할 수 있지만, 버퍼에 기록하는 모든 경우를 변경하는 것은 실패 할 수 있다.

해결 방안3. Avoiding Integer Overflows and Underflows

버퍼에 들어간 데이터의 크기와 버퍼의 크기를 계산할 때, 항상 size_t와 같은 unsigned 변수를 사용해야 한다. 음수는 큰 정수로 저장되기 때문에, 만약 signed 변수를 사용하는 경우 프로그램에 큰 수를 써서 공격자는 데이터 또는 버퍼의 크기에서 잘못된 계산을 일으킬 수 있다.

해결 방안4. Detecting Buffer Overflows

Buffer Overflow를 테스트하기 위해, 프로그램에서 입력 허용하는 데이터보다 더 많은 데이터가 들어가는 것을 허용해야 한다. 또한, 만약 프로그램이 그래픽 또는 오디오 데이터와 같은 표준형 데이터를 허용하는 경우, 잘못된 데이터를 전달하는 것을 시도해야 한다. 이 과정은 퍼징으로 알려져 있다.

해결 방안5. Avoiding Buffer Underflows

근본적으로 버퍼의 사이즈 또는 버퍼에서 데이터에 대해 코드의 두 가지 부분이 맞지 않는 경우 Buffer Underflow는 발생한다. 예를 들어 고정된 길이의 C 문자열 변수는 256 바이트 공간을 갖게 될 것이다. 그러나 단지 12 바이트 길이 문자열을 포함할 수 있다.

다음 규칙을 따를 경우, 대부분의 언더플로우 공격을 피할 수 있을 것이다.