- 버퍼 : 데이터가 목적지로 이동되기 전에 보관되는 임시 저장소
- 버퍼 역할 : 간접적으로 데이터를 전달하게 하여, 빠른 속도로 이동하던 데이터가 안정적으로 목적지에 도달할 수 있도록 완충 작용 수행
- 버퍼 오버플로우 : 버퍼가 넘치는 것
- 메모리 오염 : 일반적으로 버퍼는 메모리상에 연속해서 할당되어 있으므로, 어떤 버퍼에서 오버플로우가 발생하면, 뒤에 있는 버퍼들의 값이 조작될 위험이 존재
예제
중요데이터 변조
버퍼 오버플로우가 발생하는 버퍼 뒤에 중요한 데이터가 있다면, 해당 데이터가 변조됨으로써 문제가 발생할 수 있다.
- strncpy를 사용할 때, temp 버퍼의 크기인 16바이트를 초과해 password를 복사하면 스택 버퍼 오버플로우가 발생
- temp 뒤에 위치한 auth 변수의 값이 변경되어 if(check_auth(argv[1])) 조건이 항상 참이 됨
int check_auth(char *password) {
int auth = 0; //auth는 스택에서 temp 뒤에 위치
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");
}
데이터 유출
C언어에서 문자열은 널바이트(\0)로 끝나며, 표준 출력 함수들은 이를 문자열의 끝으로 인식한다. 그러나 버퍼 오버플로우로 널바이트를 제거하면, 출력 시 다음 버퍼의 데이터까지 읽을 수 있어 정보 유출이 발생할 수 있다.
- 8바이트 크기의 name 버퍼에 12바이트를 입력하면 오버플로우가 발생해, name과 secret 버퍼 사이의 4바이트 널 배열(barrier)이 덮어씌워질 수 있음
- 널 바이트가 제거되면 secret 버퍼의 데이터까지 읽을 수 있음
int main(void) {
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);
}
실행 흐름 조작
스택 버퍼 오버플로우로 반환 주소 (return address)를 조작하면 프로세스의 실행 흐름을 바꿀 수 있다.
- buf에 16바이트 이상의 데이터를 입력하면 스택에서 buf 다음에 위치한 메모리 영역, 즉 반환 주소를 덮어쓸 수 있음
int main(void) {
char buf[8];
printf("Overwrite return address with 0x4141414141414141: ");
gets(buf);
return 0;
}
참고 - 드림핵 ( System Hacking) https://dreamhack.io/lecture/roadmaps/all/system-hacking
'시스템 해킹 > 학습' 카테고리의 다른 글
[시스템] 함수 호출 규약 (SYSV) (0) | 2024.08.22 |
---|---|
[시스템] 바이트 코드 쉘 코드 만들기 (objdump) (0) | 2024.08.20 |
[시스템] execve 셸코드 (Shellcode) (0) | 2024.08.20 |
[시스템] orw 셸코드 (Shellcode) (0) | 2024.08.20 |