배열
배열의 각 요소(a배열의 0번째 요소,..)별 주소는 배열의 주소, 요소의 인덱스, 요소 자료형의 크기를 이용해 계산된다.
Out of Bound
OOB는 요소의 크기를 벗어난 참조가 일어날 때 발생한다. 위의 예시처럼 배열의 크기가 4일 때, a[-1], a[4] 등의 요소에 접근할 경우 배열을 벗어난 참조가 일어난다. OOB는 컴파일 단계에서 탐지가 불가능하고, 이를 방지하는 것은 개발자의 몫이다.
OOB 실습
아래의 c언어 코드를 컴파일한 후, docs의 배열에 OOB를 이용해 secret.txt의 내용을 읽을 수 있다.
// Name: oob_read.c
// Compile: gcc -o oob_read oob_read.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
char secret[256];
int read_secret() {
FILE *fp;
if ((fp = fopen("secret.txt", "r")) == NULL) {
fprintf(stderr, "`secret.txt` does not exist");
return -1;
}
fgets(secret, sizeof(secret), fp);
fclose(fp);
return 0;
}
int main() {
char *docs[] = {"COMPANY INFORMATION", "MEMBER LIST", "MEMBER SALARY",
"COMMUNITY"};
char *secret_code = secret;
int idx;
// Read the secret file
if (read_secret() != 0) {
exit(-1);
}
// Exploit OOB to print the secret
puts("What do you want to read?");
for (int i = 0; i < 4; i++) {
printf("%d. %s\n", i + 1, docs[i]);
}
printf("> ");
scanf("%d", &idx);
if (idx > 4) {
printf("Detect out-of-bounds");
exit(-1);
}
puts(docs[idx - 1]);
return 0;
}
위의 코드를 보면 line41에서 얻은 idx 값을 line48에서 검증하지 않고, docs[idx-1]의 값을 출력한다. idx로 0을 넣을 경우, docs[-1]이 출력되는 것이다.
idx에 어떤 값을 넣어야 secret.txt의 값이 출력되는지를 위해, 스택 구조가 어떻게 되는지 확인한다.
스택 구조상 docs[-1]이면 secret의 값이 출력된다. 따라서, 0을 입력할 경우 secret.txt에 적힌 값이 출력된다.
'CS > system' 카테고리의 다른 글
[System][Dreamhack] Exploit Tech: Hook Overwrite - one_gadget (0) | 2024.03.11 |
---|---|
[System][Dreamhack] Exploit Tech: Hook Overwrite(2/2) (0) | 2024.03.04 |
[System][Dreamhack] Exploit Tech: Hook Overwrite(1/2) (0) | 2024.01.24 |
[System][Dreamhack] RELRO - RELocation Read-Only (1) | 2024.01.02 |
[System][Dreamhack] PIE - Position-Independent Executable (0) | 2023.12.26 |