본 포스팅은 Dreamhack사이트의 Memory Corruption - C(1)를 제가 공부 하기 좋게 요약 한 것 입니다.
OOB(Out of Boundary) : 버퍼의 길이 범위를 벗어나는 인덱스에 접근할 때 발생하는 취약점.
이는 올바르지 않은 값이 버퍼의 인덱스로 사용될 경우 발생한다.

int형 변수 idx를 입력받은 후 이 값을 크기가 10인 int형 배열 buf의 인덱스 값으로 넣어 출력한다.
위 문제에서 buf의 크기가 10이므로 buf는 0 <= x < 10 의 정수이다.
****여기서 idx를 사용자로 부터 입력을 받는데 이의 크기를 검사하는 코드가 존재하지 않음. 따라서 이를 이용해 buf영역 밖에 접근 할 수 있다.

위와 같이 index값에 11을 넣고 문제를 풀면 된다.

oob-2.c
oob-1.c에서 12번째 줄 idx = idx % 10이 추가된 코드이다.
12번째 줄의 코드를 추가하면서 사용자로부터 입력 받는 idx값을 검사한다.
****양의 정수를 10으로 나누면 나타날 수 있는 값은 0~9이기 때문에 이는 얼핏 보면 안전해 보이지만 음의 정수를 입력할 경우 인덱스 값이 음수로 나와 총 -9 ~ 9의 값이 나올 수 있어 이를 이용해 OOB를 발생시킬 수 있다.


oob-3.c
위의 코드에서 13~15번째 줄 코드가 추가됬다.
이 코드 때문에 음수 값을 입력 해도 OOB를 발생시킬 수 없게 되었다.
****이 문제를 해결하기 위해서는 int형이 32비트인 것을 이용해야 한다. int형에서 표현 가능한 정수의 범위는
-pow(2, 31) ~ pow(2, 31) -1 까지이다. 그래서 int형에서는 -pow(2, 31)는 표현이 가능하지만 pow(2, 31)
는 표현이 불가능하고 pow(2, 31)는 표현 가능한 정수보다 하나 큰 -pow(2, 31)로 바뀌게 된다.
이 문제를 근본적으로 막기 위해서는 idx라는 변수를 int 형이 아닌 unsigned int로 선언하거나, 인덱스를 입력받은 후에 if( idx < 0 || idx >= 10)과 같은 경계 검사 구문을 추가하면 된다.

-pow(2, 31)을 입력해 13~15번째 코드에 의해 pow(2, 31)로 바뀌게 되고 int형의 정수 표현 한계 때문에 결국
-pow(2, 31)이 된다.
-pow(2, 31) = -2147483648
Off-by-one 취약점은 경계 검사에서 하나의 오차가 있을 때 발생하는 취약점입니다. 이는 버퍼의 경계 계산 혹은 반목문의 횟수 계산 시 <대신 <=을 쓰거나, 0부터 시작하는 인덱스를 고려하지 못할 때 발생한다.

off-by-one-1.c
copy_buf함수 내부에서 반복문을 0~sz(16)까지 도는 것이 off-by-one 오류를 발생시키는 원인이다.
이를 해결하기 위해서 for(i=0; i < sz; i++)와 같이 인덱스를 생각해서 코딩을 해주면 된다.

위와같이 A를 입력하며 overflow가 일어나는 것을 확인할 수 있다.
'Security > Pwnable' 카테고리의 다른 글
| [Pwnable] dreamhack Basic_BOF #2 문제 풀이 (0) | 2022.04.21 |
|---|---|
| [Pwnable] dreamhack basic_exploitation_000 문제 풀이 (0) | 2022.04.21 |
| [Pwnable] HackCTF ROP 문제 풀이 (1) | 2021.01.20 |
| [Pwnable] HackCTF Gift 문제 풀이 (0) | 2021.01.20 |
| [Pwnable] HackCTF Poet 문제 풀이 (0) | 2021.01.20 |