미친해커

[Memory Protection] ASLR (Address Space Layout Randomization) 본문

Hacking/Memory Protection Tech

[Memory Protection] ASLR (Address Space Layout Randomization)

미친해커 2021. 7. 19. 01:49
반응형

ASLR (Address Space Layout Randomization, 주소 공간 배열 무작위화)

ASLR 보호기법이란 말 그대로 주소를 매번 실행 때마다 랜덤하게 배치하는 것을 말한다. PIE 보호기법과 비슷하다고도 볼 수 있는데 엄연히 다른 보호기법이다. ASLR은 데이터 영역의 주소를 랜덤하게 배치한다. 그 이유는 ret 주소를 임의로 조작할 수 있을 때 가장 필요한 것은 주소이다. 공격자가 주소를 알 수 있다면 그 주소에 ShellCode와 같은 악성코드를 주입하여 실행시킬 수 있기 때문이다. 그렇다면 그 ShellCode와 같은 것이 작성되는 영역은 데이터 영역이기 때문에 이 영역의 주소를 랜덤하게 배치되도록 만든다면 공격을 훨씬 어렵게 만들 수 있기 때문이다.

간단요약

데이터 영역의 주소를 랜덤하게 바꾸어 공격자가 삽입한 악성 코드의 주소를 알 수 없게 만들어 공격하기 어렵게 만들기 위함이다.

보호기법 확인

// file : ASLR.c
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>

typedef void* HANDLE;

char bss[8];

int main()
{
	static int data = 10;
	int stack;
	char *heap = (char *)malloc(8);

	HANDLE handle = dlopen("/lib/libc.so.6", RTLD_LAZY);
	void *function = (void *)dlsym(handle, "printf");

	printf("==========================\n");
	printf(" code section : %p\n", main);
	printf("==========================\n");
	printf(" data section : %p\n", &data);
	printf("==========================\n");
	printf("  bss section : %p\n", bss);
	printf("==========================\n");
	printf("stack section : %p\n", &stack);
	printf("==========================\n");
	printf(" heap section : %p\n", heap);
	printf("==========================\n");
	printf(" libc section : %p\n", function);
	printf("==========================\n");
}
┌──(root💀kali)-[~/blog/Memory_Protection/ASLR]
└─# gcc -no-pie ASLR.c -o ASLR -ldl

컴파일 옵션에서 -no-pie 옵션을 주는 이유는 ASLR이 설명대로 stack, heap, libc 영역에만 적용이 되는지 확인하기 위해서 pie 보호기법은 off 해준다.

┌──(root💀kali)-[~/blog/Memory_Protection/ASLR]
└─# checksec ASLR
    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x8048000)

checksec으로 바이너리에 적용된 보호기법을 확인해보면 나머지는 기본값이고 PIE만 적용되지 않았음을 확인하고 실험을 진행한다.

 

ASLR 보호기법은 OS에서 지원하는 보호기법이기 때문에 따로 컴파일 타임에서 적용하는 옵션은 존재하지 않는다. 리눅스 환경에서 ASLR의 on/off 방법은 다음과 같다.

┌──(root💀kali)-[~/blog/Memory_Protection/ASLR]
└─# echo [option_number] > /proc/sys/kernel/randomize_va_space

option_number에 대한 설명은 다음과 같다.

0 : ASLR 해제

1 : 스택, 라이브러리 랜덤화

2 : 스택, 라이브러리, 힙 랜덤화

 

하나씩 확인해보자 (중복되는 1번 옵션은 제외하고 0번과 2번 옵션만 확인한다)

 

ASLR 옵션이 0번 일때 결과이다. 바이너리를 2번 실행시켜 보았지만 그 어떤 영역의 주소도 바뀌지 않았음을 알 수 있다.

┌──(root💀kali)-[~/blog/Memory_Protection/ASLR]
└─# echo 0 > /proc/sys/kernel/randomize_va_space

┌──(root💀kali)-[~/blog/Memory_Protection/ASLR]
└─# ./ASLR
==========================
 code section : 0x80491a2
==========================
 data section : 0x804c02c
==========================
  bss section : 0x804c034
==========================
stack section : 0xffffd170
==========================
 heap section : 0x5655a1a0
==========================
 libc section : 0xf7e17060
==========================

┌──(root💀kali)-[~/blog/Memory_Protection/ASLR]
└─# ./ASLR
==========================
 code section : 0x80491a2
==========================
 data section : 0x804c02c
==========================
  bss section : 0x804c034
==========================
stack section : 0xffffd170
==========================
 heap section : 0x5655a1a0
==========================
 libc section : 0xf7e17060
==========================

ASLR 옵션이 2번 일때 결과이다. 이번엔 바이너리를 실행 시켰을 때 code, data, bss 영역의 주소는 그대로이지만 stack, heap, libc의 주소는 바뀐것을 확인 할 수 있다.

┌──(root💀kali)-[~/blog/Memory_Protection/ASLR]
└─# echo 2 > /proc/sys/kernel/randomize_va_space

┌──(root💀kali)-[~/blog/Memory_Protection/ASLR]
└─# ./ASLR
==========================
 code section : 0x80491a2
==========================
 data section : 0x804c02c
==========================
  bss section : 0x804c034
==========================
stack section : 0xffc30b90
==========================
 heap section : 0x8e941a0
==========================
 libc section : 0xf7d57060
==========================

┌──(root💀kali)-[~/blog/Memory_Protection/ASLR]
└─# ./ASLR
==========================
 code section : 0x80491a2
==========================
 data section : 0x804c02c
==========================
  bss section : 0x804c034
==========================
stack section : 0xffb62950
==========================
 heap section : 0x87e51a0
==========================
 libc section : 0xf7d2f060
==========================

이렇게 ASLR 보호기법에 대해서 확인해 봤다. ASLR 보호기법은 stack과 heap 영역을 사용하는데 있어서도 매우 까다로운 기법이지만 라이브러리에 적용되면 더더욱 까다로워진다. 왜냐하면 우리가 원하는 함수를 호출해야할 때 라이브러리에서 주소를 구해 호출해야하지만 ASLR이 걸려있다면 Leak을 하지 않고서는 함수의 주소를 찾기 어렵기 때문이다.

반응형
Comments