[Dreamhack] Bypass NX & ASLR: 1 - Description

securitykss·2022년 11월 1일
0

Pwnable 강의(dreamhack)

목록 보기
17/58

이 글은 https://dreamhack.io/lecture/courses/85 을 토대로 작성한 글입니다.

1. Introduction

지난 Return to Shellcode 문제에서 Canary를 leak 한 후 stack영역의 buf에 shellcraft를 이용해 shellcode를 넣고, return address에 bufaddress를 넣어서 exploit을 했다.

이는 buf의 주소를 알 수 있었고, stack 영역에 실행 권한이 있기때문에 exploit이 가능 했다.

만약 buf의 주소를 쉽게 못 알아내거나 stack 영역의 실행 권한이 없었더라면, exploit이 불가능했을 것이다.

이에 대해 이번 시간에는

메모리에서 임의 버퍼 주소를 알기 어렵게 하는 ASLR(Address Space Layout Randomization)

메모리 영역에서 불필요한 실행 권한을 제거하는 NX(No-eXecute)

에 대해 알아보자.

2. ASLR

2.1 ASLR 설명

ASLR은 바이너리가 실행될 때마다 스택, 힙, 공유 라이브러리 등을 임의의 주소에 할당하는 보호 기법이다.

즉, 주소를 랜덤화하여 공격을 어렵게 만든다.

2.2 ASLR 확인 및 설정

ASLR 확인

cat /proc/sys/kernel/randomize_va_space 을 통해 ASLR 설정 상태를 확인 할 수 있다.

0인 경우

No ASLR로 ASLR을 적용하지 않는다.

1인 경우

스택, 힙, 라이브러리, vdso 등에 ASLR을 적용한다.

2인 경우

1인 경우에서와 brk로 할당한 영역에 ASLR을 적용한다.

ASLR 설정

echo 0 > /proc/sys/kernel/randomize_va_space

echo 1 > /proc/sys/kernel/randomize_va_space

echo 2 > /proc/sys/kernel/randomize_va_space

2.3 ASLR 예제 C code

// 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);  // 코드 영역의 함수 주소

}

2.4 컴파일 후 실행

매 실행마다 main함수의 주소를 제외하고,

stack, heap, libc_base, printf의 주소가 변경이 된다.

그리고 libc_base, printf의 주소의 하위 12비트는 변경이 되지 않는다.

리눅스는 ASLR이 적용됐을 때, 파일을 페이지 단위로 임의 주소에 매핑하기 때문에

페이지의 크기인 12비트 이하로는 주소가 변경이 되지 않는다.

또한, libc_base와 printf의 주소 차이는 항상같다.

ASLR이 적용되면 라이브러리는 임의 주소에 매핑된다.

하지만 라이브러리 파일을 그대로 매핑하는 것이기 때문에 매핑 주소로부터의 라이브러리의 다른 심볼들 까지의 거리(offset)은 항상 같다.

3. NX

3.1 NX 설명

NX는 실행에 사용되는 메모리 영역과 쓰기에 사용되는 메모리 영역을 분리하는 보호 기법이다.

메모리 영역에 대해 쓰기 권한과 실행 권한이 함께 있으면 굉장히 취약하기 때문이다. (지난 Return to Shellcode 문제처럼)

3.2 NX 설정

NX-disabled

gcc -z execstack -o file file.c

NX-enabled

gcc -o file file.c

3.3 NX 확인

지난 Return to Shellcode의 r2s 파일을 통해 disabled과 enabled 차이를 확인해 보자.

3.3.1 NX-disabled

checksec

vmmap

stack 영역에 실행권한이 있는 모습을 확인할 수 있다.

3.3.2 NX-enabled

checksec

vmmap

stack 영역에 실행권한이 없는 모습을 확인할 수 있다.

3.3.3 exploit 결과

NX가 enabled인 상태에 저번에 사용했던 exploit code로 exploit이 되는지 확인해 보자.

NX-enabled인 상태라 EOF error가 발생하는 모습을 확인할 수 있다.

4. Conclusion

ASLR: 주소 랜덤화로 메모리 오염을 방지하는 보호 기법

NX: 프로세스의 각 세그먼트에 필요한 권한만 부여해 메모리 오염을 방지하는 보호 기법

마치며

이번 시간에는 ASLR과 NX에 대해 알아보았다.

코드 영역에는 유용한 코드 가젯들이 포함되어 있기에 이를 이용해 ASLR과 NX를 우회를 할 수 있다.

이와 관련된 공격 기법으로는 RTL와 ROP가 있다.

다음 시간에는 라이브러리와 동적, 정적 링크에 대해 알아보자.

Reference

https://dreamhack.io/lecture/courses/85

https://learn.dreamhack.io/85#4 (코드 예제)

profile
보안 공부를 하는 학생입니다.

0개의 댓글