버퍼 오버플로우(buffer overflow)
버퍼 오버플로우는 프로그램이 고정폭을 가진 버퍼로 복사될때 발생합니다.
정보가 버퍼보다 크다면, 표준 C 메모리 및 문자열 루틴은 알아차리지못하고, 버퍼 외부의 쓰레기정보가 되는것입니다.
이것은 시스템을 공격하는 사람이 잘못된 코드를 실행함으로서, 호출하는 함수에 대한 정보를 겹쳐쓰기위해 사용될수있습니다.

이것은 여러가지방법으로 사용될수있습니다.
예를 들면, 인텔 기반의 시스템에서 버퍼오버플로우가 발생하면 어떤일이 발생할지 상상해봅시다.
일반적으로, 이런상황이 발생하면 UNIX 시스템에서 SIGSEGV로 인해 프로그램이 영향을 받게됩니다.
Windows사용자는 GPF(General Protection Fault)대화상자 또는 블루스크린으로 인해 프로그램이 정상적으로 실행되지않는
경우가 발생합니다.

인텔기반 시스템에서 C언어로 작성한 프로그램에서 함수를 호출하기위해 어느정도의 메모리를 할당해야 하는지 생각해봅시다.
일반적으로, 함수의 매개변수및 모든 변수는 일시적인 저장공간을 위해 임시적인 장소에 보관되는 Stack에 저장됩니다.
Stack은 CPU가 직접관리하며, LIFO(Last-In-First-Out) 큐(queue)로서 정렬됩니다. 즉, 메모리 블록의 최상위 부분이
가장 먼저 사용되며, 정보가 추가될때 아래로 내려가는 구조입니다.

함수가 호출될때, 각 매개 변수는 우선 Stack에 저장된후, 함수가 호출됩니다.
CPU 실행함수는 Stack에서 명령어 지시자(Instruction pointer)의 현재 위치를 저장함으로서 호출됩니다.
함수의 첫번째 Stack은 지역변수에 대한 Stack의 크기보다 많이 할당됩니다.
그러므로, 함수는 다음과 같이 호출됩니다.

void foo(char *bar)
{
  char baz[16] = "quux";
  ...
}

호출된후 다음과 같이 Stack에 저장됩니다.

baz--------->return addr------->bar----->
quux\0-------[void *]-----------[char *]

이제 문제점이 어디서 발생하는지 파악했을겁니다.
위의 예제에서, 16바이트보다 큰 데이터가 baz버퍼로 복사된다면, 오버플로우는 함수가 값을 되돌려줄때 코드주소로서
해석하는 루틴을 호출하기 위해 포인터를 겹쳐쓰게 됩니다.
이것은 SIGSEGV를 발생시킵니다. 즉, 포인터는 사용할수없는 메모리 범위를 카리키는 쓰레기값으로 겹쳐쓰기가됩니다.

시스템을 공격하는 사람에 의해 데이터가 복사된다면 어떤일이 벌어질지 생각해봅시다.
문자열이 버퍼에 기록되면 사용할수없는 주소가 저장될것입니다.
또한, 프로그램은 정상적으로 실행되지않고 잘못된 주소로 이동한후, 실행될것입니다.
버퍼자체는 메모리 상의 사용가능한 주소에 저장되므로, 버퍼의 주소는 버퍼의 시작부분을 가리키게됩니다.

버퍼에 사용 가능한 코드가 포함되어있다면, 프로그램이 가지고있는 모든권한으로 코드를 무의식적으로 실행합니다.
공통적으로 쉘을 실행하기위해 exec(2) 함수를 호출하는 코드를 포함합니다. 루트권한으로 프로그램을 실행했다면,
쉘은 루트의 모든권한을 가지게되겠지요.

인텔 기반의 시스템에서 Stack을 사용하는 버퍼오버플로우는 기본 매커니즘을 가지고있습니다.
거의 동일한 매커니즘이 여러 하드웨어 플랫폼에서 사용되고있습니다. 또한 시스템을 공격하는 사람은 이와 유사하게
Heap buffer를 사용할수있습니다.

버퍼오버플로우 문제해결

버퍼오버플로우는 보안성이 없는 데이터를 무작정 복사하기때문에 발생합니다.
즉, 보안성 있는 정보에서 파생되지않은 데이터를 사용하기때문입니다. 따라서, 이런 문제점을 해결하려면
보안성이 없는 데이터를 사용하여 버퍼로 복사하지말아야겠죠.

이런 문제점을 해결하는 가장 쉬운방법은 최대 길이를 가지는 인수를 허용하지않는 데이터를 받아들이는
라이브러리 루틴을 사용하지않는것입니다. 예를 들면, strcpy대신에 strncpy를 사용하는거죠.


위험         안전
strcpy --> strncpy
strcat --> strncat
sprintf --> snprintf
gets --> fgets

scanf함수는 입력시 공백제거문자열을 가리키는 %s 형식을 제공합니다.
문자열이 버퍼로 복사되므로, 보안성이 없는 입력으로 처리할때 최대 필드길이가 항상제공됩니다.
이런 정보를 입력하면 시스템을 공격하는 사람은 공백 및 오버플로우가 없이 긴 문자열을 입력할수있겠죠.

내용출처 : [기타] 인터넷 : http://udanax.org/ 원문 : Neil Matthew
안정적인 DNS서비스 DNSEver DNS server, DNS service
Posted by 키르히아이스
,