[포너블] Stack Buffer Overflow

Chris Kim·2024년 10월 13일

시스템해킹

목록 보기
7/33

본 문서는 드림핵 커리큘럼 강의를 수강하고 요약한 문서입니다.

스택 오버플로우 vs 스택 버퍼 오버플로우

스택은 그 크기가 동적으로 확장될 수 있다. 스택 오버플로우는 확장이 너무 많이된 경우에 발생하는 버그다. 반면 스택 버퍼 오버플로우는 스택에 위치한 버퍼보다 큰 데이터가 입력되어 발생하는 버그다.

스택 버퍼 오버플로우

버퍼 오버플로우

스택 버퍼 오버플로우는 스택의 버퍼에서 발생하는 오버플로우다.

버퍼

버퍼는 데이터가 목적지로 이동되기 전에 보관되는 임시 저장소다. 현대에서는 데이터가 저장될 수 있는 모든 단위를 버퍼라고 한다.

버퍼 오버플로우

버퍼 오버플로우는 문자 그대로 버퍼가 넘치는 것을 의미한다. 일반적으로 버퍼는 메모리상에서 연속해서 할당되므로 임의의 버퍼에서 오버플로우가 발생하면, 뒤의 버퍼가 조작될 위험이 있다.

버퍼 오버플로우 공격 예시

중요 데이터 변조

아래는 예시로 주어진 코드다.

// Name: sbof_auth.c
// Compile: gcc -o sbof_auth sbof_auth.c -fno-stack-protector
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int check_auth(char *password) {
    int auth = 0;
    char temp[16];
    
    strncpy(temp, password, strlen(password));
    
    if(!strcmp(temp, "SECRET_PASSWORD"))
        auth = 1;
    
    return auth;
}

int main(int argc, char *argv[]) {
    if (argc != 2) {
        printf("Usage: ./sbof_auth ADMIN_PASSWORD\n");
        exit(-1);
    }

    if (check_auth(argv[1]))
        printf("Hello Admin!\n");
    else
        printf("Access Denied!\n");
}

위에서 authtemp버퍼 뒤에 존재하므로, temp 버퍼에 오버플로우를 발생시키면 auth의 값을 임의의 값으로 바꿀 수 있다.

데이터 유출

C언어에서 정상적인 문자열은 널 바이트로 종료된다. 만약 다른 버퍼와의 사이에 있는 널 바이트를 제거하면 해당 버퍼를 출력할 떄, 다른 버퍼를 출력 시킬 수도 있다.

// Name: sbof_leak.c
// Compile: gcc -o sbof_leak sbof_leak.c -fno-stack-protector
#include <stdio.h>
#include <string.h>
#include <unistd.h>

int main() {
    char secret[16] = "secret message";
    char barrier[4] = {};
    char name[8] = {};
    memset(barrier, 0, 4);
    printf("Your name: ");
    read(0, name, 12);
    printf("Your name is %s.", name);
}

실행 흐름 조작

// Name: sbof_ret_overwrite.c
// Compile: gcc -o sbof_ret_overwrite sbof_ret_overwrite.c -fno-stack-protector
#include <stdio.h>
#include <unistd.h>

void win() {
    printf("You won!\n");
}

int main(void) {
    char buf[8];
    printf("Overwrite return address with %p:\n", &win);
    read(0, buf, 32);
    return 0;
}

위 코드에서 buf이후에는 RBP 값이 있다.(이건 메인 함수를 호출하면서, 스택프레임을 설정할때 ave 된 것이다.) 즉 여기에 win()주소를 넣을 수 있게 만들면 된다.

profile
회계+IT=???

0개의 댓글