CS/SystemSoftware

SystemSoftware - Buffer OverFlow #1

Henu 2021. 5. 19. 20:12

Buffer OverFlow

  • 배열에 할당된 메모리 사이즈를 초과해서 사용하는경우 발생
  • 보안 측면에서 가장 빈번하게 일어나는 이슈 중 하나

대표적인 상황 : input string의 길이를 체크하지 않을 때 가지고 있는 buffer보다 많은 양의 string이 들어오면 buffer overflow발생

아래 코드를 통해서 buffer overflow가 발생하면 어떤일이 생기는지 알아보자

typedef struct{
    int a[2];
    double d;
} struct_t;

double fun(int i){
    volatile struct_t s;

    s.d = 3.14;
    s.a[i] = 1073741824;

    return s.d;
}

void print_fun(int to){
    for(int i = 0; i <= to; i++){
        cout << "fun(" << i << ") : " << fun(i) << "\n";
    }
}

int main(){
    print_fun(5);
    return 0;
}

fun()함수는 a배열의 i번째1073741824 라는 값을 입력하고 s.d값(3.14)를 출력하는 함수이다

fun(0)fun(1)3.14가 나오는건 당연하다

그런데 fun(3)에서는 왜 2가 나오는 것일까

이전에 했던 struct의 메모리 구조를 떠올려 보자

 

SystemSoftware - Machine data(Assembly) #2

구조체가 메모리에 기록되는 방식을 알아보고 어셈블리어가 어떻게 작동하는지 알아보자 struct rec{ int a[4]; size_t i; struct rec *next; }; Linked List의 메모리 구성과 어셈블리 struct rec{ int a[4]; in..

hyeo-noo.tistory.com

a[3]을 참조하면 어디를 보게되는 것일까? a[3]은 할당이 안되어있는데 왜 segment fault가 나지 않을까?

struct의 메모리 구조에 따라서 a[2]가 처음 8바이트를 가져가고 double d가 이후 8바이트를 가져간다

따라서 a[2], a[3]를 참조하려고 하면 double d의 0~3바이트 부분, 4~7바이트 부분을 참조하게 된다.

그래서 a[2], a[3]를 출력하면 bit를 잘라낸 이상한 값이 나오게 되고

a[5]나 a[6]같은 부분을 참조하면 그때서야 SegmentFault가 발생하게 된다.

char *gets(char *dest){
    int c = getchar();
    char *p = dest;
    while(c != EOF && c != '\n'){
        *p++ = c;
        c = getchar();
    }
    *p = '\0';
    return dest;
}

dest : buffer의 위치를 가리키는 변수 (== *p)

문제점 : getchar()를 통해서 계속 buffer(*p)증가시키며 해당 위치에 문자를 입력 받지만

buffer의 끝이 어딘지 체크하는 부분이 없기 때문에 buffer overflow발생에 매우 취약하다