보안/시스템 해킹

[ 시스템 해킹 ] Mitigation: NX & ASLR

haena02 2022. 8. 10. 03:23
반응형

어떤 공격이 새롭게 등장할지는 누구도 예상할 수 없기 때문에 시스템 개발자들은 여러 겹의 보호 기법을 적용하여 시스템이 공격당할 수 있는 표면(Attack Surface)자체를 줄여나가려고 했다.

 

공격자의 침입을 더 어렵게 하려면, 공격자가 메모리에서 임의 버퍼의 주소를 알기 어렵게 하고, 메모리 영역에서 불필요한 실행 권한을 제거하는 보호 기법을 추가로 도입해야 한다.

이와 관련하여 시스템 개발자들은 Address Space Layout Randomization(ASLR) No-eXecute(NX)을 개발하고, 시스템에 적용했다. 

 

1. ASLR

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

 

아래 코드로 ASLR이 적용되는 영역을 알 수 있다.

$ cat /proc/sys/kernel/randomize_va_space

 

각 ASLR이 적용되는 메모리 영역은 다음과 같다.

  • No ASLR(0): ASLR을 적용하지 않음
  • Conservative Randomization(1): 스택, 힙, 라이브러리, vdso 등
  • Conservative Randomization + brk(2): (1)의 영역과 brk로 할당한 영역

vdso - 커널이 모든 사용자 공간 응용 프로그램의 주소 공간으로 자동으로 맵 하는 작은 공유 라이브러리

brk -  주소 위치에 program break를 설정

 

 

실제로 코드를 돌려보고 주소를 보면 아래와 같은 특징이 있다.

 

  • 코드 영역의 main함수를 제외한 다른 영역의 주소들은 실행할 때마다 변경됨.
    실행할 때 마다 주소가 변경되기 때문에 바이너리를 실행하기 전에 해당 영역들의 주소를 예측할 수 없다.
  • 바이너리를 반복해서 실행해도 printf 주소의 하위 12비트 값은 변경되지 않는다.
    리눅스는 ASLR이 적용됐을 때, 파일을 페이지(page)1 단위로 임의 주소에 매핑한다. 따라서 페이지의 크기인 12비트 이하로는 주소가 변경되지 않는다.
  • libc_base와 printf의 주소 차이는 항상 같습니다.
    ASLR이 적용되면, 라이브러리는 임의 주소에 매핑됩니다. 그러나 라이브러리 파일을 그대로 매핑하는 것이므로 매핑된 주소로부터 라이브러리의 다른 심볼들 까지의 거리(Offset)는 항상 같습니다.

 

2. NX

 

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

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

 

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

 

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

 

gdb의 vmmap으로 NX 적용 전후의 메모리 맵을 비교하면,

NX가 적용된 바이너리에는 코드 영역 외에 실행 권한이 없는 것을 확인할 수 있다.

반면, NX가 적용되지 않은 바이너리에는 스택, 힙, 데이터 영역에 실행 권한이 존재하는 것을 확인할 수 있다.

 

* NX를 인텔은 XD(eXecute Disable), AMD는 NX, 윈도우는 DEP(Data Execution Prevention), ARM에서는 XN(eXecute Never)라고 칭하고 있다.

 

 

반응형