SH1R0_HACKER

002. OOB (Out Of Boundary) 본문

System/System Exploitation

002. OOB (Out Of Boundary)

SH1R0_HACKER 2021. 2. 3. 22:35

OOB (Out Of Boundary)는 버퍼의 길이 범위를 벗어나는 인덱스에 접근할 때 발생하는 취약점 입니다.

 

다음은 첫 번째 예제입니다.

// oob-1.c
#include <stdio.h>
int main(void) {
    int win;
    int idx;
    int buf[10];
    
    printf("Which index? ");
    scanf("%d", &idx);
    printf("Value: ");
    scanf("%d", &buf[idx]);
    printf("idx: %d, value: %d\n", idx, buf[idx]);
    if(win == 31337){
        printf("Theori{-----------redacted---------}");
    }
}

scanf 함수로 idx 값을 저장하고 buf[idx]에 입력한 값을 저장합니다.

이후 idx값과 buf[idx] 값을 출력합니다.

 

win의 값이 31337이 된다면 Theori{-----------redacted---------} 를 출력합니다.

 

int buf[10]의 크기는 40byte이므로

41byte부터 데이터를 입력하면 존재하지 않는 인덱스에 접근이 가능합니다.

 

buf[10]은 idx 변수이고 buf[11]은 win 변수이므로

buf[11]에 접근하여 win을 조작하면 될 것 같습니다.

 


두 번째 예제입니다.

 

// oob-2.c
#include <stdio.h>
int main(void) {
    int idx;
    int buf[10];
    int win;
    
    printf("Which index? ");
    scanf("%d", &idx);
    
    idx = idx % 10;	// 여기가 추가되었어요!
    printf("Value: ");
    scanf("%d", &buf[idx]);
    printf("idx: %d, value: %d\n", idx, buf[idx]);
    if(win == 31337){
        printf("Theori{-----------redacted---------}");
    }
}

첫 번째 예제와 비슷하게 idx값을 입력받고 buf[idx]에 값을 저장한 뒤 idx와 buf[idx]를 출력하는 코드입니다.

다만 idx에 입력한 값을 10으로 나눈 나머지를 idx에 저장하는 부분이 추가되었습니다.

 

얼핏보면 0~9까지의 값만 idx에 저장되는것처럼 보입니다.

하지만 C언어에서는 피연산자가 음수라면 나머지 연산의 결과도 음수로 만들 수 있습니다.

 

위 코드가 스택에 쌓이는 과정을 표현한다면 아래와 같습니다.

 

 

idx 값에 -1을 넣어 win 값을 참조하도록 만들고 31337 값을 넣어줍니다.

 

공격에 성공하여 Theori 값이 출력됩니다.


마지막 예제입니다.

 

//oob-3.c
#include <stdio.h>
int main(void) {
    int idx;
    int buf[10];
    int dummy[7];
    int win;
    printf("Which index? ");
    scanf("%d", &idx);
    
    if(idx < 0)
        idx = -idx;
    idx = idx % 10; // No more OOB!@!#!
    printf("Value: ");
    scanf("%d", &buf[idx]);
    printf("idx: %d, value: %d\n", idx, buf[idx]);
    if(win == 31337){
        printf("Theori{-----------redacted---------}");
    }
}

idx 값이 음수라면 양수로 만들어버리고

idx 값을 10으로 나눈 나머지를 저장해서 idx 범위를 0~9까지로 제한합니다.

 

나머지 코드는 위와 동일합니다.

 

여기서 buf[-8]이 된다면 win에 접근할 수 있을 것 같습니다.

 

 

여기서 우리가 알아야 할 것은 int 의 범위입니다.

int형의 값의 범위는 아래와 같습니다.

 

-2,147,483,648 ~ 2,147,483,647

-pow (2, 31) ~ pow (2, 31) -1

 

여기서 idx에 -2,147,483,648 값을 입력하게 된다면 어떨까요?

if문에 의해서 idx가 음수이므로 2,147,483,648로 변하게 됩니다.

하지만 이는 int형의 범위를 초과합니다.

 

이는 signed 4byte int 에서 -2,147,483,648과 같아집니다.

 

따라서 -2147483648 % 10 = -8이므로 win에 접근할 수 있습니다.

 

이 포스트는 dreamhack.io의 강의를 정리한 게시글입니다.

저작권이나 기타 문제사항이 발생할 경우 포스트가 비공개 처리됩니다.

'System > System Exploitation' 카테고리의 다른 글

006. 초기화되지 않은 메모리  (0) 2021.02.07
005. Double Free & Use After Free  (0) 2021.02.07
004. Format String Bug  (0) 2021.02.07
003. Off-by-one  (0) 2021.02.03
001. 스택 버퍼 오버플로우 (Stack Buffer Overflow)  (0) 2021.02.01