일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- c
- HTML
- Sookmyung Information Security Study
- C언어
- 기계학습
- 머신러닝
- hackerrank
- siss
- Javascript
- CSS
- lob
- BOJ Python
- 숙명여자대학교 정보보안 동아리
- SWEA
- BOJ
- 웹페이지 만들기
- 백준
- hackctf
- PHP 웹페이지 만들기
- 풀이
- WarGame
- 생활코딩
- Python
- 숙명여자대학교 정보보안동아리
- The Loard of BOF
- c++
- 드림핵
- 파이썬
- XSS Game
- 자료구조 복습
- Today
- Total
혜랑's STORY
[System Hacking STAGE 4] Memory Corruption: Stack Buffer Overflow 본문
[System Hacking STAGE 4] Memory Corruption: Stack Buffer Overflow
hyerang0125 2022. 1. 26. 14:56스택 버퍼 오버플로우
스택 버퍼 오버플로우는 스택의 버퍼에서 발생하는 오버플로우를 말한다
버퍼(buffer)
버퍼는 컴퓨터 과학에서 '데이터가 목적지로 이동되기 전에 보관되는 임시 저장소'의 의미를 갖는다.
수신 측과 송신 측 사이에 버퍼라는 임시 저장소를 두고, 이를 통해 간접적으로 데이터를 전달하게 한다. 송신 측은 버퍼로 데이터를 전송하고, 수신 측은 버퍼에서 데이터를 꺼내 사용한다. 이렇게 하면 버퍼가 가득 찰 때까지는 유실되는 데이터 없이 통신할 수 있다. 빠른 속도로 이동하던 데이터가 안정적으로 목적지에 도달할 수 있도록 완충 작용을 하는 것이 버퍼의 역할이라고 할 수 있다.
버퍼 오버플로우(Buffer Overflow)
버퍼 오버플로우는 문자 그대로 버퍼가 넘치는 것을 의미한다. 버퍼는 제작기 크기를 가지고 있는데, int로 선언한 지역 변수는 4바이트의 크기를 갖고, 10개의 원소를 갖는 char 배열은 10바이트의 크기를 갖는다. 만약 10바이트 크기의 버퍼에 20바이트 크기의 데이터가 들어가려 하면 오버플로우가 발생한다.
일반적으로 버퍼는 메모리상에 연속해서 할당되어 있으므로, 어떤 버퍼에서 오버플로우가 발생하면, 뒤에 있는 버퍼들의 값이 조작될 위험이 있다.
버퍼 오버플로우는 일반적으로 어떤 메모리 영역에서 발생해도 큰 보안 위협으로 이어진다.
중요 데이터 변조
버퍼 오버플로우가 발생하는 버퍼 뒤에 중요한 데이터가 있다면, 해당 데이터가 변조됨으로써 문제가 발생할 수 있다.
스택 버퍼 오버플로우 예제
// Name: sbof_auth.c
// Compile: gcc -o sbof_auth sbof_auth.c -fno-stack-protector
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int check_auth(char *password) {
int auth = 0;
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");
}
- main 함수
argv[1]을 check_auth 함수의 인자로 전달한 후, 반환 값을 받아온다. 이 때, 반환 값이 0이 아니라면 "Hello Admin!"을 0이라면 "Access Denied!"라는 문자열을 출력한다.
- check_auth 함수
16 바이트 크기의 temp 버퍼에 입력받은 패스워드를 복사한 후, 이를 "SECRET_PASSWORD" 문자열과 비교한다. 문자열이 같다면 auth를 1로 설정하고 반환한다.
이때 strncpy 함수를 통해 temp 버퍼를 복사할 때, temp의 크기인 16바이트가 아닌 인자로 전달된 password의 크기만큼 복사한다. 즉, argv[1]에 16바이트가 넘는 문자열을 전달하면, 이들이 모두 복사되어 스택 버퍼 오버플로우가 발생하게 된다.
auth는 temp 버퍼의 뒤에 존재하므로, temp 버퍼에 오버플로우를 발생시키면 auth의 값을 0이 아닌 임의의 값으로 바꿀 수 있다. 이 경우, 실제 인증 여부와는 상관없이 main 함수의 if(check_auth(argv[1]))는 항상 참이 된다.
데이터 유출
C언어에서 정상적인 문자열은 널바이트로 종결되며, 표준 문자열 출력 함수들은 널바이트를 문자열의 끝으로 인식한다. 만약 어떤 버퍼에 오버플로우를 발생시켜서 다른 버퍼와의 사이에 있는 널바이트를 모두 제거하면, 해당 버퍼를 출력시켜서 다른 버퍼의 데이터를 읽을 수 있다. 획득한 데이터는 각종 보호기법을 우회하는데 사용될 수 있으며, 해당 데이터 자체가 중요한 정보일 수도 있다.
스택 버퍼 오버플로우와 메모리 릭 예제
// Name: sbof_leak.c
// Compile: gcc -o sbof_leak sbof_leak.c -fno-stack-protector
#include <stdio.h>
#include <string.h>
#include <unistd.h>
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);
}
8바이트 크기의 name 버퍼에 12바이트의 입력을 받는다. 읽고자 하는 데이터인 secret 버퍼와의 사이에 barrier라는 4바이트의 널 배열이 존재하는데, 오버플로우를 이용하여 널 바이트를 모두 다른 값으로 변경하면 secret을 읽을 수 있다.
실행 흐름 조작
함수를 호출할 때 반환 주소를 스택에 쌓고, 함수에서 반환될 때 이를 꺼내어 원래의 실행 흐름으로 돌아간다. 스택 버퍼 오버플로우로 반환 주소(Return Address)를 조작하면 프로세스의 실행 흐름을 바꿀 수 있다.
스택 버퍼 오버플로우를 통한 반환 주소 덮어쓰기
// Name: sbof_ret_overwrite.c
// Compile: gcc -o sbof_ret_overwrite sbof_ret_overwrite.c -fno-stack-protector
#include <stdio.h>
#include <stdlib.h>
int main(void) {
char buf[8];
printf("Overwrite return address with 0x4141414141414141: ");
gets(buf);
return 0;
}
main 함수의 반환 주소를 0x4141414141414141로 변경하면 "Success!"라는 문자열이 출력된다.
'무지성 공부방 > Dreamhack SystemHacking' 카테고리의 다른 글
[System Hacking STAGE 4] Return Address Overwrite (0) | 2022.01.26 |
---|---|
[System Hacking STAGE 4] Exploit Tech: Return Address Overwrite (0) | 2022.01.26 |
[System Hacking STAGE 4] Background: Calling Convention (0) | 2022.01.26 |
[System Hacking STAGE 3] Tool: pwntools (0) | 2022.01.26 |
[System Hacking STAGE 3] Tool: gdb (0) | 2022.01.26 |