버퍼 오버플로우
버퍼(Buffer)
- C언어에서 버퍼란 지정된 크기의 메모리 공간이라는 뜻이다.
버퍼 오버플로우
- 버퍼 오버플로우 취약점은 그 이름에서 나타나듯이 버퍼가 허용할 수 있는 양의 데이터보다 더 많은 값이 저장되어 버퍼가 넘치는 취약점
- 일반적으로 버퍼 오버플로우는 발생하는 위치에 따라 스택 버퍼 오버플로우, 힙 오버플로우와 같이 나눠서 부른다. ( 버퍼 오버플로우는 인접한 메모리를 오염시키는 취약점이기 때문)
스택 버퍼 오버플로우
- 가장 초기에 연구되었던 형태의 버퍼 오버플로우로, 지역 변수가 할당되는 스택 메모리에서 오버플로우가 발생하는 경우
- 만약, 변수 A에 8 바이트를 할당하고 16바이트의 데이터를 복사해 넣는다면, 할당된 A의 버퍼를 넘어 저장하게 된다. → 오버플로우 발생!
- 이는 프로그램의 Undefined Behavior(예상치 못한 동작)를 이끌어내며, 만약의 A영역 뒤에 데이터 영역인 B가 있고, 포인터로 호출된다면, 넘쳐진 값에 의하여, Segmentation Fault(접근 권한이 없는 메모리 영역을 읽거나 쓰려 할때 발생하는 예외)를 야기한다.
보안
- 대부분 프로그래머가 길이에 대한 검증을 정확히 수행하지 못해 발생한다.
- 만약 공격 벡터로부터 데이터를 입력받고 이를 버퍼에 저장하는 코드가 있다면 이를 유심히 살펴볼 필요가 있다. 특히 데이터를 버퍼에 입력받을 때는 입력받은 데이터가 버퍼의 범위를 초과하지 않는지 항상 정확히 검사해야 한다.
- 버퍼 오버플로우는 스택에서만 발생하는 취약점이 아니다. 프로그래머가 동적으로 메모리를 관리할 수 있는 힙에서도 똑같이 발생할 수 있다. 이들은 단지 발생하는 메모리 영역의 차이만 있을 뿐이고 취약점이 발생하는 원인이 본질적으로 다르진 않다.
힙 오버플로우
예제
#include <stdio.h>
#include <stdlib.h>
int main(void) {
char *input = malloc(40);
char *hello = malloc(40);
memset(input, 0, 40);
memset(hello, 0, 40);
strcpy(hello, "HI!");
read(0, input, 100);
printf("Input: %s\\n", input);
printf("hello: %s\\n", hello);
}