NX & ASLR

  • Canary 보호 기법만 적용하면 스택 버퍼 오버플로우 익스플로잇 조건은 다음과 같다.
    • 반환 주소를 임의 주소로 덮을 수 있다.
    • 사용자가 데이터를 입력할 수 있는 버퍼의 주소를 알 수 있다.
    • 버퍼가 실행 가능하다.
  • Canary 보호 기법은 위 조건의 첫 번째 조건에 해당하는데, NX와 ASLR 보호 기법은 두 번째와 세 번째 조건을 보호한다.


NX

  • No-eXecute(NX)는 실행에 사용되는 메모리 영역과 쓰기에 사용되는 메모리 영역을 분리하는 보호 기법이다.
    • 코드 영역에 쓰기 권한이 있으면, 코드를 수정하여 원하는 코드 실행 가능
    • 스택이나 데이터 영역에 실행 권한이 있으면 Return to Shell 공격 시도 가능
  • CPU가 NX를 지원하면 컴파일러 옵션을 통해 바이너리에 NX를 적용할 수 있다.
  • NX가 적용된 바이너리는 실행될 때 각 메모리 영역에 필요한 권한만을 부여받는다.

  • NX를 인텔은 XD(eXecute Disable), AMD는 NX, 윈도우는 DEP(Data Execution Prevention), ARM에서는 XN(eXecute Never)라고 칭하며, 모두 비슷한 보호 기법이다.
  • 🫢 5.4.0 미만 버전의 리눅스 커널에서는 r 권한이 있는 모든 페이지에 x 권한이 부여된다.


ASLR

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

  • ASLR은 커널에서 지원하는 보호 기법이며, 다음의 명령어로 확인할 수 있다.

    $ cat /proc/sys/kernel/randomize_va_space 
    2
    
    • 0: ASLR을 적용하지 않음
    • 1: 스택, 힙 라이브러리, vdso 등
    • 2: (1)의 영역과 brk로 할당한 영역
  • ASLR의 특징으로는 코드 영역을 제외한 다른 영역의 주소들이 실행할 때마다 변경된다.


  • 아래는 stack, heap, libc_base, printf, main 영역을 ASLR 보호 기법을 적용하고 실행한 결과이다.

image-20240406025741371

  • libc_base나 printf를 살펴보면, 리눅스는 파일을 페이지(page) 단위로 임의 주소에 매핑하기 때문에 주소 하위 12비트는 여러번 실행해도 변경되지 않는다.
  • libc_base와 printf의 주소 차이는 항상 같다.
    • ASLR은 라이브러리를 임의 주소에 매핑하는데, 이 파일 그대로 매핑하는 것이므로 매핑된 주소로부터 라이브러리의 다른 심볼들 까지의 거리(Offset)이 항상 같다.


요약

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

댓글남기기