Iriton's log

Mitigation: NX & ASLR 본문

Pwnable/Study

Mitigation: NX & ASLR

Iriton 2024. 5. 22. 03:38

*본 포스트는 Dreamhack - Systemhacking Lecture 을 참고하여 작성되었습니다.

NX(No-eXecute)

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

어떤 메모리 영역에 대해 쓰기 권한과 실행 권한이 함께 있으면 시스템이 취약해지기 쉽다.

예를 들어, 코드 영역에 쓰기 권한이 있으면 공격자는 코드를 수정하여 원하는 코드가 실행되게 할 수 있고, 반대로 스택이나 데이터 영역에 실행 권한이 있으면 Return to Shellcode와 같은 공격을 시도할 수 있음.

CPU가 NX를 지원하면 컴파일러 옵션을 통해 바이너리에 NX를 적용할 수 있으며, NX가 적용된 바이너리는 실행될 때 각 메모리 영역에 필요한 권한만을 부여받는다.

checksec 명령어를 이용하면 바이너리에 NX가 적용됐는지 확인할 수 있다.

더보기

📍 NX의 다양한 명칭

NX를 인텔은 XD(eXecute Disable) , AMD는 NX, 윈도우는 DEP(Data Execution Prevention) , ARM에서는 XN(eXecute Never) 라고 칭하고 있습니다. 명칭만 다를 뿐 모두 비슷한 보호 기법입니다.

Return to Shellcode w/t NX

이전에 실습한 Return to shellcode의 예제인 r2s에 NX 보호 기법을 적용한 후, 동일한 익스플로잇을 실행해보고 결과를 확인하자.

이 바이너리를 대상으로 익스플로잇 코드를 실행하면, 위와 같이 Segmentation fault가 발생합니다. 이는 NX가 적용되어 스택 영역에 실행 권한이 사라지게 되면서, 셸코드가 실행되지 못하고 종료된 것이.

ASLR

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

Return to shellcode에서 r2s는 ASLR이 적용되어 실행할 때마다 buf의 주소가 변경되었다.

해당 바이너리는 실습의 편의를 위해 buf의 주소를 출력해주었으므로 buf를 공격에 활용하는 것이 어렵지 않았다. 그러나 일반적인 바이너리였다면 buf의 주소를 구하는 과정이 선행되어야 할 것이다.

ASLR은 커널에서 지원하는 보호 기법이며

$ cat /proc/sys/kernel/randomize_va_space 위 명령어로 확인할 수 있다.

아래 코드로 실습해서 ASLR의 특징을 살펴보자.

$ gcc addr.c -o addr -ldl -no-pie -fno-PIE

$ ./addr
buf_stack addr: 0x7ffcd3fcffc0
buf_heap addr: 0xb97260
libc_base addr: 0x7fd7504cd000
printf addr: 0x7fd750531f00
main addr: 0x400667
$ ./addr
buf_stack addr: 0x7ffe4c661f90
buf_heap addr: 0x176d260
libc_base addr: 0x7ffad9e1b000
printf addr: 0x7ffad9e7ff00
main addr: 0x400667
$ ./addr
buf_stack addr: 0x7ffcf2386d80
buf_heap addr: 0x840260
libc_base addr: 0x7fed2664b000
printf addr: 0x7fed266aff00
main addr: 0x400667

 

스택 영역의 buf_stack, 힙 영역의 buf_heap, 라이브러리 함수 printf, 코드 영역의 함수 main, 그리고 라이브러리 매핑 주소 libc_base가 출력되었다. 결과를 살펴보면 다음과 같은 특징이 있다.

  • 코드 영역의 main함수를 제외한 다른 영역의 주소들은 실행할 때마다 변경.
  • 실행할 때 마다 주소가 변경되기 때문에 바이너리를 실행하기 전에 해당 영역들의 주소를 예측할 수 없다.
  • 바이너리를 반복해서 실행해도 libc_base 주소 하위 12비트 값과 printf 주소 하위 12비트 값은 변경되지 않는다.
  • 리눅스는 ASLR이 적용됐을 때, 파일을 페이지(page) 단위로 임의 주소에 매핑. 따라서 페이지의 크기인 12비트 이하로는 주소가 변경되지 않는다.
  • libc_base와 printf의 주소 차이는 항상 같다.

 

키워드

  • Address Space Layout Randomization(ASLR): 메모리를 무작위 주소에 할당하는 보호 기법. 최신 커널들은 대부분 적용되어 있음. 리눅스에서는 페이지 단위로 할당이 이루어지므로 하위 12비트는 변하지 않는다는 특징이 있음.
  • NX(No-eXecute bit): 프로세스의 각 세그먼트에 필요한 권한만 부여하는 보호 기법. 일반적으로 코드 영역에는 읽기와 실행을, 나머지 영역에는 읽기와 쓰기 권한이 부여됨.

'Pwnable > Study' 카테고리의 다른 글

Exploit Tech: Return to Library  (0) 2024.05.29
Background: Library  (0) 2024.05.22
Exploit Tech: Return to Shellcode  (0) 2024.05.15
Mitigation: Stack Canary  (0) 2024.05.07
Exploit Tech: Return Address Overwrite  (0) 2024.04.09
Comments