[Dreamhack] Background: 1 - Linux Memory Layout

securitykss·2022년 10월 16일
0
post-thumbnail

이 글은 https://dreamhack.io/lecture/courses/52을 토대로 작성한 글입니다.

1. Introduction

Pwnable(System Hacking)에서 가장 기본이자 중요한 부분인 Memory Layout에 대해서 소개하려고 한다.

2. Memory Layout

memexaple.c

   // memexample.c
   // 임시 코드입니다.
   
   
	#include<stdio.h>
   
   int data = 10;
   const char data_rostr;
   int bss;
   
   int main() {
   	int *h = malloc(4);
       *h = 1234;
   	int s = 20;
       
       return 0;
   }
   

위에 코드는, 전역변수 data와 data_rostr, bss, main()함수 안에 있는 지역변수 h와 s가 선언이 되어있다.

변수 data, data_rostr, bss, h, s 그리고 main() 함수들은 메모리에 어떻게 mapping이 될까?

메모리는 여러 세그먼트들로 구분합니다. 대표적으로 크게 5가지의 code, data, BSS, heap, stack 세그먼트들이 있다.

segmenat
code
data
BSS
heap
↓.↓
.
↑.↑
stack

표와 같이 메모리가 저장되는 위치를 간략하게 표현해 보았다.

이제 위에서 작성한 memexample.c에서 main()함수와 변수들이 어디에 mapping이 되는지 설명하려고 한다.

2-1. Code Segment

segmenat
code
data
BSS
heap
↓.↓
.
↑.↑
stack

설명

Code Segment에는 실행 가능한 기계코드가 위치하는 영역이다.

main()함수 등 함수들이 위치하게 된다.

또한, 프로그램이 동작하려면 함수들은 실행이 가능해야 하므로, 읽기 권한, 실행 권한 이 주어진다.

쓰기 권한은 이 영역에서 없다. 왜냐하면 이 영역에는 실행 권한이 있기 때문에 공격자(해커)가 이 영역에서 마음대로 자신이 원하는 영역으로 위치시키는 코드를 작성할 수 있게 되기 때문이다.

    // memexample.c
    // 임시 코드입니다.
    
    
	#include<stdio.h>
    
    int data = 10;
    const char data_rostr;
    int bss;
    
    int main() {				// Code Segment, readable and executable
    	int *h = malloc(4);
        *h = 1234;
    	int s = 20;
        
        return 0;
    }
    

2-2. Data Segment

segmenat
code
data
BSS
heap
↓.↓
.
↑.↑
stack

설명

Data Segemnt에는 전역 변수 및 전역 상수들이 위치한다. (data, data_rostr)

이 영역은 다시 쓰기가 가능한 영역과 쓰기가 불가능한 영역으로 다시 나뉜다.

쓰기가 가능한 영역은 프로그램이 실행되면서 값이 변할 수 있는 데이터들이 위치합니다. 이 영역을 Data Segment라고 한다. (data)

쓰기가 불가능한 영역은 프로그램이 실행되면서 값이 변하면 안되는 데이터들이 위치합니다. 이 영역을 rodata(read-only data) Segment라고 한다.

    // memexample.c
    // 임시 코드입니다.
    
    
	#include<stdio.h>
    
    int data = 10;				// Data Segment, writable and readable
    const char data_rostr;		// rodata Segemnt in Data Segment, only readable
    int bss;
    
    int main() {				// Code Segment, readable and executable
    	int *h = malloc(4);
        *h = 1234;
    	int s = 20;
        
        return 0;
    }
    

2-3. BSS Segment

segmenat
code
data
BSS
heap
↓.↓
.
↑.↑
stack

설명

BSS Segment(Block Started By Symbol Segment)에는 값이 정해지지 않은 전역 변수들이 위치하는 영역이다.(bss)

다시 말해 선언만 하고 값을 할당하지 않은(초기화하지 않은) 전역변수들이 위치한다.

이 영역의 메모리 영역은 프로그램이 시작될 때, 모두 0으로 값을 초기화시킨다.

이 영역에는 쓰기 권한과 읽기 권한이 주어진다.

    // memexample.c
    // 임시 코드입니다.
    
    
	#include<stdio.h>
    
    int data = 10;				// Data Segment, writable and readable
    const char data_rostr;		// rodata Segemnt in Data Segment, only readable
    int bss;					// BSS Segment, writable and readable
    
    int main() {				// Code Segment, readable and executable
    	int *h = malloc(4);
        *h = 1234;
    	int s = 20;
        
        return 0;
    }
    

2-4. Stack Segment

segmenat
code
data
BSS
heap
↓.↓
.
↑.↑
stack

설명

Stack Segment는 스택이 위치하는 세그먼트입니다.

함수의 인자나 지역변수들이 저장된다.(s)

Stack Segment는 주소가 높은 곳에서 주소가 낮은 곳으로 자란다.

다시 말해, 지역 변수가 선언 될 때 주소가 높은 곳에서 부터 값을 넣을 수 있는 공간을 만든다.

이 영역에는 쓰기 권한과 읽기 권한이 주어진다.

2-5. Heap Segment

segmenat
code
data
BSS
heap
↓.↓
.
↑.↑
stack

설명

Heap Segemnt에는 힙 데이터가 위치하는 세그먼트입니다.

실행중에 동적으로 할당될 수 있다.

이 영역은 Stack Segment와 반대로 주소가 낮은 곳에서 높은 곳으로 자란다.

C언어에서 malloc(), calloc() 등을 호출해서 할당받는 데이터들이 이 영역에 위치하게 된다.(h)

이 영역에는 쓰기 권한과 읽기 권한이 주어진다.

memexaple.c 에서 h에 malloc()으로 동적 할당한 영역의 주소를 대입하고, 이 영역에 값을 넣는다.

h는 지역변수이므로 stack에 위치하며, malloc으로 할당 받은 Heap Segment의 주소를 가리킨다.

즉, h는 지역 변수이므로 Stack에 위치하고, 이 h안에는 Heap 영역의 주소를 가리키고, 그 후 heap에서 malloc()으로 값을 할당을 받는다.

    // memexample.c
    // 임시 코드입니다.
    
    
	#include<stdio.h>
    
    int data = 10;				// Data Segment, writable and readable
    const char data_rostr;		// rodata Segemnt in Data Segment, only readable
    int bss;					// BSS Segment, writable and readable
    
    int main() {				// Code Segment, readable and executable
    	int *h = malloc(4);		// Stack에는 h, h에는 Heap Segment의 주소를 가리킴
        *h = 1234;				// Heap Segment에서 값을 할당
    	int s = 20;
        
        return 0;
    }
    

3. Conclusion

세그먼트역할권한사용 예
코드 세그먼트실행 가능한 코드가 저장된 영역읽기, 실행main() 등의 함수 코드
데이터 세그먼트초기화된 전역 변수 또는 상수가 위치하는 영역읽기와 쓰기 또는 읽기만초기화된 전역 변수, 전역 상수
BSS 세그먼트초기화되지 않은 데이터가 위치하는 영역읽기, 쓰기초기화되지 않은 전역 변수
스택 세그먼트임시 변수가 저장되는 영역읽기, 쓰기지역 변수, 함수의 인자 등
힙 세그먼트실행중에 동적으로 사용되는 영역읽기, 쓰기malloc(), calloc() 등으로 할당 받은 메모리

마치며

여기까지 Memory Layout에 대해서 알아보았다.

다음 시간에는 Background: Computer Architecture를 알아보자.

Reference

https://dreamhack.io/lecture/courses/52

http://itnovice1.blogspot.com/2019/09/blog-post_29.html

profile
보안 공부를 하는 학생입니다.

0개의 댓글