[System Hacking][DreamHack][Stage2] Background: Linux Memory Layout

marceline·2023년 3월 29일
0

[System Hacking]

목록 보기
4/16

1. Introduce

컴퓨터 == CPU + memory 로 구성 되어있다.

CPU

실행할 명령어와 명령어 처리에 필요한 데이터를 메모리에서 읽고, Instruction Set Architecture(ISA) 에 따라 이를 처리한다.
연산의 결과는 메모리에 다시 적재한다.

Memory Corruption ; 메모리 오염 취약점

공격자의 악의적인 메모리 조작 값에 의해 CPU 도 잘못된 동작을 하는 것
메모리 오염과 관련된 취약점인
Stack Buffer Overflow, Off by one, Format String Bug, Double Free Bug, Use After Free 에 대해서 탐구하는 것이 해당 커리큘럼의 목표이다.

필요 배경지식

Linux memory Layout ; 리눅스 메모리 구조

개요

  1. segment
  2. Code segment
  3. Data segment
  4. BSS segment
  5. Stack segment
  6. Heap segment

2. Linux process 의 메모리 구조

segment

segment

적재되는 데이터의 용도별로 메모리의 구획을 나눈것
리눅스는 프로세스의 메모리를 크게 5가지의 세그먼트로 구분
-> code, data, BSS, Heap, stack

Segment 의 이점

각 용도에 맞게 적절한 권한 (R, W, X) 부여 가능

Code segment

실행가능한 기계 코드가 위치하는 영역 (Text Segment 라고도 불림)

읽기권한 / 실행권한이 부여

쓰기권한이 없는 이유 : 공격자가 악의적인 코드를 삽입하기가 쉬워지기 때문

Data Segment

컴파일 시점에 값이 정해진 전역 변수 및 전역 상수들이 위치

읽기권한 부여

CPU 가 이 세그먼트의 데이터를 읽을수 있어야 하기 때문

쓰기 가능/ 불가능으로 한번더 나뉜다

Data segment (쓰기가능 세그먼트)

프로그램이 실행되면서 값이 변할 수 있는 데이터가 위치 (ex 전역변수)

rodata(read-only data) segment (쓰기 불가능 세그먼트)

프로그램이 실행되면서 값이 변하면 안되는 데이터들이 위치
(상수 문자열은 rodata)

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, string == rodata

int main() { ... }

문자형 포인터 변수 str_ptr 이 가리키는 "readonly" 문자열은 상수문자열로 취급되어, rodata 에 위치한다!

BSS Segment

BSS segment : (Block Started By Symbol Segment)

컴파일 시점에 값이 정해지지 않은 전역 변수가 위치하는 메모리 영역

읽기권한 / 쓰기권한 부여

초기화 되지 않은 전역변수가 위치 BSS segment 에 위치!

Stack Segment

Stack Segment : 프로세스의 스택이 위치하는 영역

함수의 인자(argument) 나 지역변수 (local variable) 와 같은 임시 변수들이 실행중에 저장

Stack Frame : Stack Segment 의 단위

함수가 호출될 때 생성, 반환될 때 해제

스택은 '아래로 자란다'

스택이 확장될 때, 기존 주소보다 낮은 주소로 확장된다.

읽기 권한 / 쓰기 권한 부여

CPU 가 자유롭게 값을 읽고 쓸 수 있어야 하기 때문

void func()
{
	int choice = 0;
    scanf("%d", &choice);
    
    if(choice)
    	call_true();
    else
    	call_false();
    return 0;
}

지역변수 choice 가 스택에 저장된다.

Heap Segment

Heap Segment : 힙 데이터가 위치하는 세그먼트

스택과 마찬가지로 실행중에 동적으로 할당될 수 있다
리눅스의 경우 스택 세그먼트와 반대방향으로 자란다

malloc(), calloc() 로 할당받는 메모리가 힙세그먼트에 위치

읽기 권한 / 쓰기 권한 부여

int main()
{
	int *head_data_pttr = malloc(sizeof(*head_data_ptr));
    *head_data_ptr = 31337;
    printf("%d\n", *head_data_ptr);
    return 0;
}

Heap 과 Stack 세그먼트는 반대로 자란다

힙 세그먼트 모두 사용 후 확장할 때 스택 세그먼트와 충돌하는 것을 방지하기 위해서이다.

Conlusion

0개의 댓글