https://dreamhack.io/lecture/roadmaps/2
[ Pwnable: Stage 8: Out of Bounds(OOB) ]
→ 배열의 임의 인덱스에 접근할 수 있음
[ 배열의 속성 ]
→ 연속된 메모리 공간을 점유
→ 배열이 점유하는 공간의 크기는 요소의 개수와 요소 자료형의 크기를 곱한 값이 됨
→ 배열이 포함하는 요소의 개수 = 배열의 길이(length)
→ 배열의 각 요소의 주소는 배열의 주소, 요소의 인덱스, 요소 자료형의 크기를 이용하여 계산
[ Out of Bounds ]
→ 요소를 참조할 때, 인덱스 값이 음수이거나 배열의 길이를 벗어날 때 발생
→ 개발자가 인덱스의 범위에 대한 검사를 명시적으로 프로그래밍하지 않으면, 프로세스는 요소의 주소를 계산할 뿐,
계산한 주소가 배열의 범위 안에 있는지 검사하지 않음
→ 사용자가 배열 참조에 사용되는 인덱스를 임의의 값으로 설정할 수 있다면, 배열의 주소로부터 특정 오프셋에 있는
메모리의 값을 참조할 수 있음
[ oob 실습 예제 ]
위와 같은 코드가 있다고 했을 때, arr 배열은 int형 변수 10개를 요소로 함에도 불구하고, -1, 100을 인덱스로 사용했음에도 아무런 경고를 띄워주지 않는다.
1. 임의 주소 읽기
: oob로 임의 주소의 값을 읽으려면, 읽으려는 변수와 배열의 오프셋을 알아야 함
: 배열과 변수가 같은 세그먼트에 할당되어 있다면, 둘 사이의 오프셋은 항상 일정하므로 디버깅을 통해 쉽게 알아낼
수 있다.
: 같은 세그먼트가 아닌 경우, 다른 취약점을 통해 두 변수의 주소를 구하고 차이를 계산해야 함
[예제] obb_read
: 위의 코드에서 docs 배열은 길이가 3이고, 아래에서 인덱스 값을 큰지만 확인하고 있다.
따라서 secret.txt 파일을 미리 생성하고 값으로 0을 준다면 docs에 대한 OOB를 이용하여 secret_code의 값을 읽을 수 있다.
2. 임의 주소 쓰기
: 위의 코드는 인덱스에 대한 검증이 미흡해 임의 주소에 값을 쓸 수 있는 예제이다.
코드를 보면 24바이트 크기의 student 구조체는 10개 포함하는 배열 stu와 isAdmin을 전역 변수로 선언한다.
그리고 사용자로부터 인덱스를 입력받아 인덱스에 해당하는 student 구조체의 attending에 1을 대입한다.
코드 마지막 부분에서는 isAdmin이 참인지 검사한다.
변수에 값을 직접 쓰는 부분은 없지만, 코드에 oob 취약점을 이용하여 isAdmin 값을 조작할 수 있다.
디버거로 확인해보면 isAdmin이 stu보다 240바이트 높은 주소에 있는 것을 알 수 있다.
따라서, 배열을 구성하는 student 구조체의 크기가 24바이트이므로, 10번째 인덱스를 참조하면 isAdmin을 조작할 수 있고, 11을 입력하면 “Access granted”라는 문구를 볼 수 있다.
'Pwnable > 개념' 카테고리의 다른 글
[Pwnable] Dreamhack STAGE 11 (0) | 2022.08.26 |
---|---|
[Pwnable] Dreamhack STAGE 10 (0) | 2022.08.26 |
[Pwnable] Dreamhack STAGE 8 (0) | 2022.08.26 |
[Pwnable] Dreamhack STAGE 7 (0) | 2022.08.26 |
[Pwnable] Dreamhack STAGE 6 (0) | 2022.08.25 |