미역줄기의 이모저모
[ Dreamhack ] NX & ASLR 본문
NX
nx는 실행에 사용되는 메모리 영역과 쓰기에 사용되는 메모리 영역을 분리하는 보호기법이다. 어떤 메모리 영역에 대해 쓰기 권한과 실행 권한이 함께 있으면 취약해지기 쉽다.
CPU가 NX를 지원하면 컴파일러 옵션을 통해 바이너리에 NS를 적용할 수있다. 그럼 각 메모리 영역에 필요한 권한만을 부여받을 수 있다.
checksec을 이용해서 NX를 확인할 수 있다.
NX를 intel은 XD, AMD는 NX, 윈도우는 DEP, ARM에서는 XN이라고 칭한다.
Return to Shellcode w/t NX
r2s에 NX 보호기법을 적용한 후, 동일한 익스플로잇을 실행해본다.
r2s.c를 -zexecstack 옵션을 제거해 컴파일하고, checksec으로 확인해보면 NX가 활성화되어 있다.
$ checksec ./r2s_nx
[*] '/home/dreamhack/r2s_nx'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)
그럼 예전에 사용한 pwntools 파이썬 코드는 안 먹힌다..
ASLR
바이너리가 실행될 때마다 스택, 힙, 공유 라이브러리 등을 임의의 주소에 할당하는 보호기법이다.
ASLR은 커널에서 지원하는 보호 기법이며, 다음의 명령어로 확인할 수 있다.
$ cat /proc/sys/kernel/randomize_va_space
리눅스에서 이 값은 0, 1, 또는 2의 값을 가질 수 있습니다. 각 ASLR이 적용되는 메모리 영역은 다음과 같다.
- No ASLR(0): ASLR을 적용하지 않음
- Conservative Randomization(1): 스택, 힙, 라이브러리, vdso 등
- Conservative Randomization + brk(2): (1)의 영역과 brk로 할당한 영역
오른쪽 코드를 예제로 사용하여 ASLR의 특징을 자세히 살펴보자.
// Name: addr.c
// Compile: gcc addr.c -o addr -ldl -no-pie -fno-PIE
#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
int main() {
char buf_stack[0x10]; // 스택 버퍼
char *buf_heap = (char *)malloc(0x10); // 힙 버퍼
printf("buf_stack addr: %p\n", buf_stack);
printf("buf_heap addr: %p\n", buf_heap);
printf("libc_base addr: %p\n",
*(void **)dlopen("libc.so.6", RTLD_LAZY)); // 라이브러리 주소
printf("printf addr: %p\n",
dlsym(dlopen("libc.so.6", RTLD_LAZY),
"printf")); // 라이브러리 함수의 주소
printf("main addr: %p\n", main); // 코드 영역의 함수 주소
}
메모리의 주소를 출력하는 코드이다.
gcc로 컴파일하면 위와 같은 결과가 나온다.
스택 영역의 buf_stack, 힙 영역의 buf_heap, 라이브러리 함수 printf, 코드 영역의 함수 main, 그리고 라이브러리 매핑 주소 libc_base가 출력되었다. 다음과 같은 특징이 있다.
- 코드 영역의 main함수를 제외한 다른 영역의 주소들은 실행할 때마다 변경
실행할 때 마다 주소가 변경되기 때문에 바이너리를 실행하기 전에 해당 영역들의 주소를 예측할 수 없음. - 바이너리를 반복해서 실행해도 libc_base 주소 하위 12비트 값과 printf 주소 하위 12비트 값은 변경되지 않음.
리눅스는 ASLR이 적용됐을 때, 파일을 페이지(page) 단위로 임의 주소에 매핑한다. 따라서 페이지의 크기인 12비트 이하로는 주소가 변경되지 않음 - libc_base와 printf의 주소 차이는 항상 같음
ASLR이 적용되면, 라이브러리는 임의 주소에 매핑된다. 그러나 라이브러리 파일을 그대로 매핑하는 것이므로 매핑된 주소로부터 라이브러리의 다른 심볼들 까지의 거리(Offset)는 항상 같다.
NX와 ASLR이 적용되면 스택, 힙, 데이터 영역에는 실행 권한이 제거되며, 할당되는 주소가 계속 변한다. 그러나 바이너리의 코드가 존재하는 영역은 실행권한이 존재하며 할당되는 주소도 고정되어 있다. (잘 기억해놓고 exploit할 때 써먹어야겠다.)
관련된 대표적인 공격 방법에는
- ROT
- RTL
이 있다.
'Hacking > DreamHack 시스템 해킹 강의' 카테고리의 다른 글
[ Dreamhack ] Hook Overwrite (0) | 2024.02.17 |
---|---|
[ Dreamhack ] link (0) | 2024.02.09 |
[ Dreamhack ] Stack Canary (1) | 2024.02.08 |
[ Dreamhack ] Return Address Overwrite (0) | 2024.02.06 |
[ Dreamhack ] Tool: gdb (1) | 2024.02.05 |