ghkdtlwns987

[Heap Techniques] Heap Memory leak (Unsorted bin)(main_arena) 본문

Heap Exploitation

[Heap Techniques] Heap Memory leak (Unsorted bin)(main_arena)

2020/03/31 2021. 1. 31. 18:17

Heap 으로 Memory leak 하는 방법은 무엇일까?

그 방법은 여러가지가 존재한다. (포인터에 특정 함수의 GOT 를 넣어 출력되게 하거나, File * 를 활용하거나... 등등)

이번에 Heap Exploit 할때, 가장 많이 쓰이는 방법을 하나 소개하려 한다. 

 

small bin 이나 large bin 을 해제하게 되면 unsorted bin 에 들어가게 된다. 

unsorted bin 에 들어가게 된 chunk 는 FD, BK 에 main_arena 의 주소가 들어가게 되는데,

main_arena 는 libc.so.6 라이브러리에 존재하는 구조체이기 때문에, libc_leak 이 가능해 진다.

 

다음은 드림핵에 나와있는 코드를 컴파일 했다. 

내가 보여줄 환경은 glibc2.23 버젼이다. (glibc2.27 은 안됨)

// gcc -o leak1 leak1.c
#include <stdio.h>
#include <stdlib.h>
int main()
{
	char *ptr = malloc(0x100);
	char *ptr2 = malloc(0x100);
	free(ptr);
	ptr = malloc(0x100);
	printf("0x%lx\n", *(long long *)ptr);
	
	return 0;
}

한번 libc_base 를 구해보자.

 

 

위와같이 출력이 되는 이유는 무엇일까 

unsorted bin은 small bin 이나 large bin 이 free() 되었을 시 들어가게 되는 bin인데, 만약, fastbin 을 선언하지 않고, 

바로 small bin 이나 large bin을 선언하면 unsorted bin 의 fd,bk 는 main_arena + 88 이 들어가게 된다.

 

위 코드는 small bin 크기의 heap을 할당하고 free() 해서 unsorted bin 에 heap chunk가 들어가는데,

이때 헤제된 ptr chunk의 FD, BK 영역에 main_arena 영역의 주소가 쓰이게 된다. 

이후에 unsorted bin 에 들어간  chunk의 크기보다 작거나 같은 크기의 chunk를 할당해 출력하면

main_arena 역역의 주소를 출력할 수 있다.

 -> 이렇게 되는 이유는 malloc() 할 때, 데이터 영역을 초기화하지 않기 때문이다. 

하지만 calloc() 과 같이 메모리를 할당하는 동시에 초기화하는 함수를 사용하면 위와같이 leak 하는 것은 안된다. 

 

여기서 나온 값을 가지고 offset 을 구하면 되는데,

간혹 이 방법이 안통할 때가 있다. 

그럴땐 libc_base = unsorted bin_leak - libc.symbols['__malloc_hook'] - 0x10 이다. 

주소를 보면 main_arena + 88 에 위치한 추소는 malloc_hook + 0x10 에 존재하기 때문이다.

두 주소가 같은것을 볼 수 있다. 

Comments