CONTENTS
1. 컴퓨터 구조와 메모리 오염
2. 리눅스 메모리 구조
2-1. 코드 세그먼트
2-2. 데이터 세그먼트
2-3. BSS 세그먼트
2-4. 힙 세그먼트
2-5. 스택 세그먼트
3. 요약
1. 컴퓨터 구조와 메모리 오염
[컴퓨터 = CPU + 메모리]
▷공격자가 메모리를 조작하면, 조작된 메모 값에 의해 CPU도 잘못 동작
▷ 이러한 메모리 오염을 유발하는 취약점을 '메모리 오염(Memory Corruption)' 취약점이라고 한다
※ 메모리 오염과 관련된 취약점으로 다음과 같다
① Stack Buffer Overflow
② Off by One
③ Format String Bug
④ Double Free Bug
⑤ Use After Free
2. 리눅스 메모리 구조(Memory Layout)

2-1. 세그먼트란
- 리눅스에서는 프로세스의 메모리를 크게 5가지의 세그먼트(Segment)로 구분
▷ 코드 세그먼트, 데이터 세그먼트, BSS 세그먼트, 힙 세그먼트, 스택 세그먼트
- 용도별로 나눈 세그먼트 별로 권한(읽기, 쓰기, 실행)을 각각 부여하여 관리 가능
2-2. 코드 세그먼트(Code Segment)
- 실행 가능한 기계코드가 위치하는 영역
- 텍스트 세그먼트(Text Segment)라고도 불림
- 이 세그먼트에는 읽기 권한과 실행 권한이 부여
- 쓰기 권한이 있을 경우, 공격자가 코드를 삽입하여 공격할 수 있으므로 제거
int main() { return 31337; }
// 정수 '31337'을 반환하는 main함수가 컴파일 되면
// '554889e5b8697a00005dc3'이라는 기계코드로 변환되는데
// 이 기계코드가 코드 세그먼트에 위치한다
2-3. 데이터 세그먼트(Data Segment)
- 컴파일 시점에 값이 정해진 전역 변수 및 전역 상수들이 위치
- CPU가 이 세그먼트의 데이터를 읽어야하므로 읽기 권한이 부여
▷ 데이터 세그먼트는 쓰기가 가능한 세그먼트와 쓰기가 불가능한 세그먼트로 아래와 같이 분류 된다.
| 쓰기가 가능한 세그먼트 | 쓰기가 불가능한 세그먼트 |
| 전역 변수와 같이 프로그램이 실행되면서 값이 변할 수 있는 데이터들이 위치 | 프로그램이 실행되면서 값이 변하면 안되는 데이터들이 위치하며, 전역으로 선언된 상수가 여기에 포함 |
| data 세그먼트 | rodata(read-only data) 세그먼트 |
▷아래는 데이터 세그먼트에 포함되는 여러 데이터의 유형이다
- 변수 str_ptr은 "readonly"라는 문자열을 가리킨다
- 이 문자열은 상수 문자열로 취급되어 rodata에 위치
- 이를 가리키는 str_ptr은 전역 변수로서 data에 위치
int data_num = 31337; // data
char data_rwstr[] = "writable_data"; // data
const char data_rostr[] = "readonly_data"; // rodata
char *str_ptr = "readonly"; // str_ptr은 data, 문자열은 rodata
int main() { ... }
2-4. BSS 세그먼트(BSS Segment, Block Started By Symbol Segment)
- 컴파일 시점에 값이 정해지지 않은 전역 변수가 위치하는 메모리 영역
- 프로그램이시작될 때, 모두 0으로 값이 초기화
- 이 세그먼트에는 읽기 권한 및 쓰기 권한이 부여
▷ 아래 코드에서 초기화되지 않은 전역 변수인 bss_data가 BSS 세그먼트에 위치
int bss_data;
int main() {
pintf("%d\n", bss_data); //0
return 0;
}
2-5. 힙 세그먼트(Heap Segment)
- 힙 데이터가 위치하는 세그먼트
- 스택과 마찬가지고 실행중에 동적으로 할당될 수 있으며, 리눅스에서는 스택 세그먼트와 반대 방향으로 자란다
- C언어에서 malloc(), calloc() 등을 호출해서 할당받는 메모리가 이 세그먼트에 위치하게 되며, 일반적으로 읽기 권한과 쓰기 권한이 부여
▷ 아래 코드는 heap_data_ptr에 malloc()으로 동적 할당한 영역의 주소를 대입이 영역에 값을 작성.
heap_data_ptr은 지역변수이므로 스택에 위치하며, malloc으로 할당받은 힙 세그먼트의 주소를 가리킨다.
int main() {
int *heap_data_ptr =
malloc(sizeof(*heap_data_ptr)); // 동적 할당한 힙 영역의 주소를 가리킵
*heap_data_ptr = 31337; // 힙 영역에 값을 씀
printf("%d\n", *heap_data_ptr); // 힙 영역의 값을 사용함
return 0;
}
2-6. 스택 세그먼트(Stack Segment)
- 프로세스의 스택이 위치하는 영역으로 함수의 인자나 지역 변수와 같은 임시 변수들이 실행중에 이곳에 저장된다
- 스택 세그먼트는 스택 프레임(Stack Frame)이라는 단위로 사용
- 이 영역에는 CPU가 자유롭게 값을 읽고 쓸 수 있어야 하므로, 읽기 권한과 쓰기 권한이 부여
▷ 아래의 코드에서는 지역변수 choice가 스택에 저장된다
Voide func() {
int choice = 0;
scanf("%d", &choice);
if (choice)
call_true();
else
call_calse();
return 0;
}
3. 요약
| 세그먼트 | 역할 | 일반적인 권한 | 사용 예 |
| 코드 세그먼트 | 실행 가능한 코드가 저장된 영역 | 읽기, 실행 | main() 등의 함수 코드 |
| 데이터 세그먼트 | 초기화된 전역 변수 또는 상수가 위치하는 영역 | 읽기와 쓰기 또는 읽기 전용 | 초기화된 전역 변수, 전역 상수 |
| BSS 세그먼트 | 초기화되지 않은 데이터가 위치하는 영역 | 읽기, 쓰기 | 초기화되지 않은 전역 변수 |
| 스택 세그먼트 | 임시 변수가 저장되는 영역 | 읽기, 쓰기 | 지역 변수, 함수의 인자 등 |
| 힙 세그먼트 | 실행중에 동적으로 사용되는 영역 | 읽기, 쓰기 | malloc(), calloc() 등으로 할당받은 메모리 |
※ 이 게시글은 DREAMHACK 사이트 강의를 참조하여 작성되었습니다.
'시스템해킹' 카테고리의 다른 글
| Syetem Hacking - [02] Computer Science - (3-2) x86 Assembly (0) | 2022.12.02 |
|---|---|
| Syetem Hacking - [02] Computer Science - (3-1) x86 Assembly (0) | 2022.12.01 |
| Syetem Hacking - [02] Computer Science - (2) Computer Architecture (0) | 2022.12.01 |
| Syetem Hacking - [01] 리눅스 환경 구축 (0) | 2022.11.30 |