Buffer overflow 란 무엇일까 ?
Buffer + overflow 하다
말 그대로 버퍼의 공간에 담길 데이터가 흘러넘침을 뜻한다.
데이터가 흘러넘치면 어떻게 되는가? 버퍼에 할당된 구역을 넘어서 다른 데이터가 저장된 메모리 영역
까지 침범하여 데이터를 덮어쓰게 된다.
이로 인해 시스템은 정상적으로 동작하지 않게 된다.
버퍼 오버 플로우는 기본적인 해킹 스킬이다.
버퍼는 임시 저장 공간으로 메모리 영역에서 스택 혹은 히프 혹은 데이터 영역에 존재할 수 있는데 각 영역에 따라 스택 버퍼 오버 플로우, 힙 버퍼 오버 플로우, 데이터 버퍼 오버 플로우로 불릴 수 있다.
링크텍스트 --- 참고
위의 사진처럼 히프 영역과 스택 영역은 Free store의 영역으로 각자의 데이터를 확장시켜나가는데 버퍼 오버 플로우가 발생되면 확장된 데이터가 다른 섹터 메모리의 데이터를 덮어쓰게 된다. 그렇게 되면 컴퓨터가 맛이 간다.
C언어로 작성된 다음의 함수를 확인해보자.
위의 이미지는 사용자가 값을 입력했는데 그것이 START라면 valid를 나타내는 함수다. 사용자가 입력한 값은 str2에 담긴다. 다음 이미지에서 위의 함수에서 스택 버퍼 오버 플로우가 어떻게 발생하는지 확인할 수 있다.
위의 이미지 중 첫번째 케이스는 START를 넣어 valid가 정상적으로 나타나는 경우고 두번째부터 버퍼 오버플로우 케이스다.
EVILINPUTVALUE 총 14자를 집어넣어 글자 8개까지 담을 수 있는 str2의 영역에 앞 8글자가 담기고 남은 6글자는 str1의 영역을 침범해 START를 TVALUE로 덮어쓰게 된다.
때문에 정상적인 판별이 진행되지 않게 된다.
세 번째 케이스는 BADINPUT을 두번 반복하는 총 16자의 값을 입력하였다. 역시 str2의 값을 넘어 str1에 담긴 START를 BADINPUT으로 덮어쓰게 만들고 str2 str1 둘다 BADINPUT으로 만들어 유효한 값이라고 정상 판별되게 만들었다.
위에서 버퍼 오버 플로우가 발생한 원인은 C 라이브러리가 제공한 함수 gets( )가 복사할 문자열의 길이를 검사하지 않았기 때문이다.
다음의 스택 버퍼 오버 플로우 케이스도 보자. 아래는 x86 기반 어셈블리어로 작성된 코드가 담긴 메모리 영역이다.
la, lb, lc는 지역변수로 만약 la를 4바이트 용량으로 선언했지만 16바이트 입력을 넣어준다면 스택 데이터를 처리하고 돌아갈 주소를 담은 윗 계층의 old frame pointer 그리고 return address in f1 값도 덮어쓸 수 있게 된다. ( 혹은 그 이상 )
이렇게 되면 스택을 처리하고 돌아가야 될 주소가 정상적이지 않게 되니 시스템이 망가진다.
이러한 스택 오버 플로우를 방지하기 위해선 개발자는
버퍼 크기를 검사하는 함수와 스택 쉴드 기법을 구현해야 한다.
또한 프로세서의 MMU(Memory Management Unit)를 이용하여
가드 페이지를 구현, 즉 가상 메모리의 특정 페이지를 실행 금지 영역으로 설정함으로써 버퍼 오버 플로가 진행중이어도 피해가 없도록 하여야 한다.