[OS] Buffer Overflow

애이용·2021년 6월 24일
0

OS

목록 보기
13/16
post-thumbnail

Buffer Overflow (BOF)

Buffer Overflow = Buffer Overrun = Buffer Overwrite

메모리를 다루는 데에 오류가 발생하여 잘못된 동작을 하는 프로그램 취약점이다. 프로세스가 데이터를 버퍼에 저장할 때 프로그래머가 지정한 곳 바깥에 저장하는 것을 의미한다.

예시

buffer1.c

#include <stdio.h>
#include <string.h>

int main() {
    int valid = 0;
    char str1[8] = "START";
    char str2[8];

    gets(str2);
    if (strncmp(str1, str2, 4) == 0)
        valid = 1;
    printf("buffer1: str1(%s), str2(%s), valid(%d)\n", str1, str2, valid);
}

여기서 BOF에 취약한 함수가 있다.
바로 gets() 함수이다.

gets()

gets(char *s) 는 엔터가 입력될 때까지 입력된 문자열을 버퍼에 저장한다.
버퍼의 사이즈는 전혀 고려하지 않는다.

  • C언어에서 문자열은 "NULL-Terminated"

INPUT을 받아보자

정상적인 예시

$ cc -g -o buffer1 buffer1.c // buffer1.c를 컴파일하여 실행파일 buffer1을 만든다.
$ ./buffer1 // 실행파일을 실행시킨다.
START // 입력
buffer1: str1(START), str2(START), valid(1)

버퍼사이즈를 넘지않게 입력받았으니 정상적으로 실행되었다.

비정상적인 예시

이제 버퍼의 사이즈(8)을 넘어서 입력해보자.

$ cc -g -o buffer1 buffer1.c
$ ./buffer1
BADINPUTBADINPUT
buffer1: str1(BADINPUT), str2(BADINPUTBADINPUT), valid(1)

분명 c코드를 작성할 때 str1 에 "START"를 저장하도록 했다.
그런데 str1(BADINPUT)으로 출력되는 것으로 보아 오버플로우가 발생하였다.
valid(1)을 보아 둘이 매칭되었다는 결과가 발생하였다.

오버플로우 발생 과정을 살펴보자.

input을 받기 전 스택

참고) \00 : NULL(문자열의 끝) 의미

str1과 str2에 할당된 사이즈는 8인 것을 알 수 있다.

  char str1[8];
  char str2[8];

위의 사진을 보면 str1에 "START"가 저장된 것을 알 수 있다.
이제 문자열을 입력하면 str2에 채워질 것이다.

위에서 설명한 gets() 함수의 취약점때문에 버퍼의 입력받은 문자열의 길이가 8이 넘어도 str1의 공간을 덮어쓴다(overwrite).
그래서 str1의 8글자와 str2의 앞 8글자가 "BADINPUT"으로 같아
valid가 1이 된 것이다.

아스키코드 표 참고

profile
로그를 남기자 〰️

0개의 댓글