본문 바로가기
공부/정보보안

버퍼 오버플로(buffer overflow)

by Skogkatt의 개인 블로그 2020. 2. 15.
반응형

버퍼 오버플로(buffer overflow)

  • 프로그램이 데이터를 버퍼(buffer)에 저장할 때, 버퍼가 가득 차 넘치게 되어 프로그래머가 지정한 부분 바깥에 덮어 씌워버리는 취약점, 버그, 이를 이용한 공격 방법을 말한다.
  • 넘쳐난 데이터는 원래 데이터를 밀어내거나 이상한 곳에 저장하는 것이 아니라 덮어 씌우는 것이다. 덮어 씌워진 메모리에는 다른 데이터가 이미 포함되어 있을 수 있고, 이 때문에 메모리 접근 오류, 프로그램 종료, 시스템 보안 취약점 등이 발생할 수 있다.
  • 버퍼 오버플로는 보통 데이터를 저장하는 과정에서 그 데이터를 저장할 메모리 위치가 유효한지를 검사하지 않아 발생한다. 이러한 경우 데이터가 담긴 위치 근처에 있는 값이 손상되고 그 손상이 프로그램 실행에 영향을 미칠 수도 있다. 특히, 악의적인 공격으로 인해 프로그램에 취약점이 발생할 수 있다.
  • 흔히 버퍼 오버플로와 관련되는 프로그래밍 언어는 C와 C++로, 어떤 영역의 메모리에서도 내장된 데이터 접근 또는 덮어쓰기 보호 기능을 제공하지 않으며 어떤 배열에 기록되는 데이터가 그 배열의 범위 안에 포함되는지 자동으로 검사하지 않는다.

버퍼 오버플로 공격

예제 소스코드
#include <stdio.h>
#include <string.h>

int main(iint argc, char *argv[])
{
  char buffer[16];
  if(argc < 2)
    return -1;
  strcpy(buffer, argv[1]);
  }
  • 실행 시 인수로 받은 문자열을 버퍼에 옮기고 버퍼를 출력하는 간단한 C언어 코드이다.

 

int main(int argc, char *argv[])
  • argc는 해당 코드가 컴파일되어 실행되는 프로그램의 인수 개수이다.
  • *argv[]는 포인터 배열로 인자로 입력되는 값에 대한 주소(번지수)를 차례대로 저장한다.[각주:1]
  • argv[0] : 실행 파일의 이름
    argv[1] : 첫 번째 인자의 내용
    argv[2] : 두 번째 인자의 내용
  char buffer[16];
  • 10byte 크기의 buffer 배열을 선언한다.
  if(argc < 2)
    return -1;
  • argc가 2보다 작으면 -1을 반환하여 매개변수를 반드시 넣어줄 수 있도록 한다.
  • argc는 첫번째로 실행 파일의 이름, 두번째로 처음 사용된 인자를 받기 때문에 2보다 작다 함은 매개 변수를 받지 않았다는 뜻이 된다.
  strcpy(buffer, argv[1]);
  • 버퍼에 첫 번째 인자(argv[1])를 복사한다.
  • strcpy함수는 입력된 인수의 경계를 검사하지 않는다.(문자열의 길이를 제한하지 않는다). 즉, 인수는 char buffer[10]으로 10byte 크기를 넘어가면 안 되지만 이보다 큰 값인 20, 30byte를 받아도 실행된다.
  • 이곳에서 버퍼 오버플로 공격이 일어난다.[각주:2]
스택 오버플로(stack buffer overflow)

버퍼 오버런(Buffer Overrun)
  • 메모리 공간에 할당된 공간보다 더 큰 데이터를 입력하면 프로그램의 오류를 유발할 수 있다. 즉 공격자는 프로그램의 오류를 유발하여 시스템을 장악하거나 Shellcode 등의 악성코드를 실행한다.
힙 버퍼 오버플로 공격(Heap Buffer Overflow Attack)
  • 힙 영역은 하위 주소에서 상위주소로 메모리를 할당한다 .그러므로 경계 값을 검사하지 않고 메모리를 사용하면 경계를 초과하는 취약점이 발생한다.

버퍼 오버플로 대처

https://ko.wikipedia.org/wiki/%EB%B2%84%ED%8D%BC_%EC%98%A4%EB%B2%84%ED%94%8C%EB%A1%9C#%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D_%EC%96%B8%EC%96%B4_%EC%84%A0%ED%83%9D

버퍼 오버플로 문제는 오래 전부터 문제되었기 때문에 이제는 파일러 레벨에서 오버플로를 막거나 사용자에게 안전한 함수를 사용하라고 경고한다.

위험한 함수 사용 자제
  • 사용 자제를 권장하는 함수 : strcat(), strcpy(), gets(), scanf(), sscanf(), vscanf(), vsscanf(), sprintf(), vsprintf(), gethostbyname(), realpath()
  • 대체 함수 : strncat(), strncpy(), fgets(), fscanf(), vfscanf(), snprintf(), vsnprintf()
안전한 라이브러리 사용
  • Libsafe[각주:3]와 같이 안전한 라이브러리를 사용한다. 
  • 수정된 라이브러리는 최소한 표준 라이브러리만큼 효율적이라 알려져 있으며, 기존의 프로그램에 대한 버퍼 오버플로 공격 예방을 도와준다.
스택 보호 매커니즘(Stack Guard)
스택 쉴드(Stack Shield)
경계 검사

 

참고 링크

https://www.youtube.com/watch?v=ZRHncXwedZ8

  1. argc는 개수, argv[]는 실질적으로 들어오는 값 [본문으로]
  2. C언어가 문자열의 끝을 무조건 0(NULL 문자)까지로 인식한다는 점과 strcpy이 인수의 경계를 검사하지 않기 때문에 문제가 발생한다. [본문으로]
  3. 추가적으로 복사(copy) 연산이 스택 프레임 내부의 지역 변수 공간을 넘어가지 않도록 검사하는 기능을 구현한 라이브러리 [본문으로]
반응형

'공부 > 정보보안' 카테고리의 다른 글

포맷 스트링 버그(format string bug)  (0) 2020.02.17
제로 트러스트 보안 모델  (0) 2020.02.03
[DVWA] File Upload  (0) 2019.11.27
[DVWA] CSP Bypass  (0) 2019.11.25
[Wargame.kr] QR CODE PUZZLE 문제  (0) 2019.09.23

댓글