본문 바로가기
Systemhacking/Base info

Heap Base

by reindeer002 2021. 4. 3.
728x90

이제 Heap 영역을 공격하기 위한 기초 지식을 쌓을 것이다.

필자의 pwndbg가 올바르게 작동하지 않아 bound7님의 자료를 참고하여 글을 포스팅함을 알린다.

(감사합니다 형님 꾸벅 (_ㅇ_) )

 

우리는 C언어를 공부하면서 malloc이라는 함수를 자주 사용한 적이 있다.

그런데 이런 의문을 가진 적은 없는가?

"동적 할당된 메모리의 크기를 어떻게 알고 해제(free)할 수 있는거지?"

사실 이러한 문제 말고도 여러 문제가 존재할 수 있다!

(예를 들어 해제한 메모리는 어떻게 저장해놓고 다시 사용하는 것이지 등등...)

 

제작자는 이러한 문제를 해결하기 위해 동적할당한 메모리를 하나의 구조체에 담아서 사용하고 있다.

HEAP chunk의 구조

 

pwndbg로 확인하면 다음과 같은 모습으로 나타나게 된다.

malloc함수를 통해 받은 동적메모리의 주소는 free된 후 fd가 존재할 곳이다.

각 데이터의 의미는 다음과 같다.

prev_size - 이전에 해제된 힙 청크의 크기를 의미함
- 이전 힙 chunk의 데이터 영역으로 사용할 수 있음
- 즉, prev_size는 NMP flag의 P 플래그가 1로 set된 상태에서 사용되어야 함
size 할당된 현재 chunk의 크기를 의미
fd 동일한 bin에 존재하는 다음 free chunk의 주소
bk 동일한 bin에 존재하는 이전 free chunk의 주소
fd_nextsize 현재 chunk의 크기보다 작은 free chunk의 주소
bk_nextsize 현재 chunk의 크기보다 큰 free chunk의 주소
NMP N: non main arena
M: is mapped
P: prev_inuse(이전 chunk가 사용되는 중인가?)

 

힙 메모리의 마지막에는 TOP chunk가 존재하고 적절한 free된 chunk가 없다면 TOP chunk를 짤라서 사용하게 된다.

 

그럼 이제 bins는 무엇인지 알아보도록 하자.

bins는 free된 chunk의 공간을 효율적으로 사용하기 위해 탄생한 것으로,

free된 chunk들을 연결리스트로 관리하고 main_arena라는 초기화된 전역 변수 구조체에서 관리한다.

다음은 main_arena의 모습이다.

각 bins마다 시작 chunk의 주소값을 지닌다.

 

bins는 다음과 같이 분류된다.

  size range explaination
small bins 0x10 ~ 0x400 -> 0x10 사이즈 별로 별개의 이중 연결리스트로 관리
-> 같은 사이즈의 청크들끼리의 연결리스트
large bins 0x400 ~ 0x4400 -> 0x100 사이즈 별로 별개의 이중 연결리스트로 관리
-> 다른 크기의 청크들이 같은 연결리스트에서 쓰일 수 있음
-> 한 연결리스트 안에서 청크들을 크기 순으로 내림차순 정렬
unsorted bins X -> small, large bins로 옮겨지기 전에 무조건 이동하는 bins로 이중 연결리스트로 관리
-> 다시 malloc할 때 이곳에서 분할해서 할당할 수 있는 청크면 분할하여 바로 할당
-> 일종의 cache역할을 하는 bins로 속도가 매우 빠름
fast bins 0x10 ~ 0x80 -> 단일 연결리스트로 관리(fd값만 사용하여 리스트를 형성함)
-> 다른 모든 청크는 인접한 청크가 존재할 경우 병합하는 특징이 있지만 이곳은 인접한 청크를 free해도 병합되지 않음
-> LIFO 방식을 사용하여 free chunk를 해제 후 등록 및 할당함
-> 병합하지 않는 bin이기 때문에 prev_inuse를 set하지 않음

 

Global_max_fast의 모습이다.

이는 Global_max_fast로 fastbins의 최대 청크의 크기를 정의해 둔 공간이다.

이 값을 바꿔서 큰 사이즈 청크도 fast bins처럼 동작하게 할 수 있다.

 

이제 동적할당을 위해 malloc를 사용할 시 어떠한 방식으로 동작하는지 malloc 알고리즘에 대해 알아보자.

순서는 다음과 같다.

1. __malloc_hook에 값이 있는가?

더보기

__malloc_hook이란?

libc에서 main_arena 직전에 있는 .data 변수값으로 기본 값은 0으로 설정되어 있으나 만약 다른 값이 설정된다면 malloc 호출 시에 설정된 값으로 jump한다.

__malloc_hook에 값이 없을 경우 malloc에서 size값에 따라 0x10 단위로 청크 사이즈를 맞춤

보통 0x20 크기의 동적메모리를 할당하려하면 0x10의 공간이 추가되어 할당되는데

이는 prev_size와 size의 공간이 추가적으로 필요하기 때문이다.

추가 예시)

size 0x16 -> 0x20

size 0x38 -> 0x40 (다음 chunk의 prev_size를 사용하면 충분함)

size 0x6f -> 0x80 (다음 chubk의 prev_size를 사용해도 부족함)

 

 

2. Chunk 사이즈가 global_max_fast 범위 안에 있는가? (fastbins)

더보기

size < global_max_fast?

chunk 사이즈를 맞춘 후 사이즈가 global_max_fast안에 있는지 검사한다.

만약 있을 경우 fastbins에서 해당하는 chunk 사이즈 리스트를 탐색 후 찾으면 바로 리턴함

 

 

3. Chunk 사이즈가 0x400 범위 안에 있는가? (small bins)

더보기

size < 0x400?

global_max_fast < size < 0x400 인지 검사

만약 검사를 통과했다면 small bins에 해당하는 사이즈의 리스트 탐색 후 있다면 리턴함

 

 

4. Large bin 안에 할당하려는 값보다 큰 chunk가 있는가? (large bins)

더보기

앞의 검사를 모두 마치면 일단 이 chunk는 무조건 large chunk라고 간주하고

이후 적은 사이즈 청크가 없을 것이라 예측한 뒤 fastbins chunk들을 합친다.

이후 합쳐진 chunk는 unsorted bins로 이동한다(유일하게 fast chunk들이 합쳐지는 시점).

이때부터 분기가 2가지로 나뉘게 된다.

첫 번째, unsorted bins에서 요청된 사이즈 만큼의 청크가 있는지 확인하고 있을 경우  unsorted bins에서 청크를 분할하여 할당

두 번째, unsorted bins에서 할당할 수 없는 청크라면 large bins를 확인해서 있을 경우 해당 large bins에서 청크를 분할하여 할당

 

 

5. Top chunk보다 큰 chunk인가? (top chunks)

더보기

마땅한 free된 청크가 없을 경우 청크 중에서 가장 아래에 있는 청크를 분할하여 할당한다.

 

 

6. Mmap으로 할당(is_mmaped flag set)

 

 

그럼 malloc 알고리즘에 대해 탐구해보았는데 chunk가 합쳐진다는 의미는 무엇일까?

예를 들어 다음과 같은 상황에서 0x603410 청크를 free 할 경우

!fastbins

FD, BK에 main_arena 주소가 생기고 다음 청크에 변화가 생긴다.

!fastbins

다음에 0x6034b0을 free할 때 0x603410청크와 합치기 위해서다.

free 0x6034b0을 할 경우 0x603410 청크와 합쳐지는 모습을 확인할 수 있다.

!fastbins

 

그럼 이것으로 heap에 메모리를 동적할당할 때 이루어지는 기본적인 메커니즘에 대해 살펴보았다.

다음에는 how2heap에서 확인할 수 있는 코드들을 가지고 본격적으로 malloc을 통해 나타날 수 있는

취약점들에 대해 알아보도록 하자.


[참고] https://rninche01.tistory.com/entry/heap4-glibc-malloc3-feat-bin?category=838537 

 

heap(4) - glibc malloc(3) (feat. bin)

참고 : GNU C Library의 Memory Allocator인 ptmalloc2(glibc 2.23)를 대상으로 설명 이번에는 Free된 Chunk들을 다시 재활용하기 위해서 Free Chunk들을 어떻게 관리하는지 자세하게 다뤄보겠다. 0. Boundary Tag 이전 시

rninche01.tistory.com

 

728x90

'Systemhacking > Base info' 카테고리의 다른 글

unsafe Unlink in heap  (0) 2022.11.07
Fastbin Double Free  (0) 2021.04.04
What is GOT & PLT  (0) 2021.01.24
Security Techniques 1.  (0) 2021.01.22
Tools setting  (0) 2021.01.22

댓글