본문 바로가기
Security/System Hacking

[Lazenca] Protection Tech > NX, ASLR

by 단월໒꒱ 2022. 2. 6.

[NX]

1. NX

 1) NX Bit(NX bit, Never eXecute bit, 실행 방지 비트

   - 프로세스 명령어나 코드 또는 데이터 저장을 위한 메모리 영역을 따로 분리하는 CPU의 기술

   - NX 특성으로 지정된 모든 메모리 구역은 데이터 저장을 위해서만 사용되며, 프로세서 명령어가 그 곳에 상주하지 않음으로써 실행되지 않도록 만들어 줌

 

 2) DEP(Data Execution Prevention)

   - 마이크로소프트 윈도우 운영 체제에 포함된 보안 기능

   - 악의적인 코드가 실행되는 것을 방지하기 위해 메모리를 추가로 확인하는 하드웨어 및 소프트웨어 기술

   - 모드 종류

     ① 하드웨어 DEP: 메모리에 명시적으로 실행 코드가 포함되어 있는 경우를 제외하고 프로세스의 모든 메모리 위치에서 실행할 수 없도록 표시 (대부분의 최신 프로세서는 하드웨어 적용 DEP 지원)

     ② 소프트웨어 DEP: CPU가 하드웨어 DEP를 지원하지 않을 경우 사용

 

 3) 공격자가 Heap, Stack 영역에 Shellcode를 저장해서 실행하기 위해서는 해당 영역에 실행권한이 있어야 함

   - DEP가 적용되지 않았을 경우에는 쉘코드가 실행이 됨

   - DEP가 적용된 경우에는 실행권한이 없으므로 쉘코드 실행되지 않음

      - 프로그램에서 해당 동작에 대한 예외처리 후 프로세스가 종료 됨

 

 

2. 예시

 1) 예시

   - bof 취약점이 존재하는 프로그램에 빌드할 때 스택에 실행 권한을 설정하여 컴파일

#include <stdio.h>
#include <stdlib.h>
 
int main(){
    char str[256];
    char *chare = (char*)malloc(100);
 
    printf("Input: ");
    gets(str);
    printf("%p\n", str);
}
 

 

   - Build Command (DEP disable)

 

 gcc -z execstack -o DEP-disabled DEP.c

 

 

 

3. 바이너리 파일의 보호 기법 확인

 1) checksec.sh

   - checksec.sh에서 아래와 같은 결과 출력

     ① DEP-disabled file : NX disabled

     ② DEP-enabled file : NX enabled

 

 

 2) 메모리에서 권한 체크

   - 아래와 같이 메모리 맵에서 메모리 영역별 설정된 권한 확인 가능

     ① DEP enabled의 경우 실행권한(--x-)을 가지고 있는 영역은 5곳입니다.

     ② DEP disabled의 경우 실행권한(--x-)을 가지고 있는 영역은 17곳입니다.

 

 

 

 

4. "Checksec.sh" 파일에서 NX 설정여부 확인 방법

 1) Binary

   - 아래와 같은 방법으로 바이너리의 NX 설정여부 확인

      ① readelf 명령어를 이용해 파일의 세그먼트 헤더 정보에서 NX 여부 확인

      ② 파일의 세그먼트 헤더 정보에서 'GNU_STACK'의 Flg 값이 'RWE'이라면 NX가 활성화되었다고 판단

 

# check for NX support
if readelf -W -l $1 2>/dev/null | grep 'GNU_STACK' | grep -q 'RWE'; then
  echo -n -e '\033[31mNX disabled\033[m   '
else
  echo -n -e '\033[32mNX enabled \033[m   '
fi

 

 
 
   - NX가 적용된 바이너리의 Flg 값 : 'RW'
   - NX가 적용되지 않은 바이너리의 Flg 값 : 'RWE'
 
 
$ readelf -W -l ./DEP-disabled |grep 'GNU_STACK' | grep 'RWE'
$ readelf -W -l ./DEP-enabled |grep 'GNU_STACK' | grep 'RWE'
 

 

 

 2) Process

   - 아래와 같은 방법으로 실행중인 프로세서의 NX 설정여부 확인

      ① Binary의 확인 방식과 동일하며, 전달되는 파일의 경로가 다음과 같이 다름 ex. /proc/<PID>/exe

 

# fallback check for NX support
elif readelf -W -l $1/exe 2>/dev/null | grep 'GNU_STACK' | grep -q 'RWE'; then
  echo -n -e '\033[31mNX disabled\033[m   '
else
  echo -n -e '\033[32mNX enabled \033[m   '
fi

 

$ readelf -W -l /proc/<PID>/exe |grep 'GNU_STACK'

 

 

 3) CPU

   - 아래와 같은 방법으로 CPU의 NX 설정여부 확인

      ① "/proc/cpuinfo" 파일에서 'nx' 문자가 있는지 확인

 

 
# check cpu nx flag
nxcheck() {
  if grep -q nx /proc/cpuinfo; then
    echo -n -e '\033[32mYes\033[m\n\n'
  else
    echo -n -e '\033[31mNo\033[m\n\n'
  fi
}

 

$ grep nx /proc/cpuinfo
 

 

 


[ASLR]

1. ASLR

 1) ASLR (Address Space Layout Randomization)

   - 메모리 손상 취약점 공격을 방지하기 위한 기술

   - 스택, 힙, 라이브러리 등의 주소를 랜덤한 영역에 배치하여, 공격에 필요한 Target address를 예측하기 어렵게 만듦

   - 프로그램이 실행될 때마다 각 주소들이 변경됨

 

2. Set ASLR

 1) cmd

 

echo 0 > /proc/sys/kernel/randomize_va_space

 

 2) option

 

0 ASLR 해제
1 랜덤 스택 & 랜덤 라이브러리 설정
2 랜덤 스택 & 랜덤 라이브러리 & 랜덤 힙 설정

 

3. 바이너리 파일의 보호 기법 확인

 1) checksec.sh

   - checksec.sh에서 아래와 같은 결과 출력

      - System-wide ASLR (kernel.randomize_va_space): On (Setting : 2)

 

lazenca0x0@ubuntu:~/Documents/Definition/protection/ASLR$ ./ASLR
[Heap]  address: 0x1137010
[Stack] address: 0x7fffcfcd6b20
[libc]  address: 0x7f9526812830
^Z
[1]+  Stopped                 ./ASLR
lazenca0x0@ubuntu:~/Documents/Definition/protection/ASLR$ checksec.sh --proc ASLR
* System-wide ASLR (kernel.randomize_va_space): On (Setting: 2)
 
  Description - Make the addresses of mmap base, heap, stack and VDSO page randomized.
  This, among other things, implies that shared libraries will be loaded to random
  addresses. Also for PIE-linked binaries, the location of code start is randomized.
 
  See the kernel file 'Documentation/sysctl/kernel.txt' for more details.
 
* Does the CPU support NX: Yes
 
         COMMAND    PID RELRO             STACK CANARY           NX/PaX        PIE
            ASLR  10366 Partial RELRO     Canary found           NX enabled    No PIE                 
lazenca0x0@ubuntu:~/Documents/Definition/protection/ASLR$

 

 

2) Memory map

   - 아래와 같이 메모리의 변화 확인 가능

      - "/proc/<PID>/maps" 파일을 통해 프로세스 메모리 구조 및 주소를 확인할 수 있음

      - randomize_va_space에 2를 설정한 환경

      - 프로그램을 처음 실행했을 때와 두 번째 실행했을 때의 메모리 배치가 다른 것을 확인할 수 있음

 

메모리 영역 첫 번째 실행 두 번째 실행
Stack 0x7ffea624c000 ~ 0x7ffea626d000 0x7ffc75b23000 ~ 0x7ffc75b44000
Heap 0x0229e000 ~ 0x022bf000 0x01198000 ~ 0x011b9000
Libc 0x7fb51e026000 ~ 0x7fb51e618000 0x7f6adb39b000 ~ 0x7f6adb98d000

 

 

 3) Linux 폴더 정보

 

/proc process의 줄임말이며, 이 디렉토리에 프로세스들의 정보들이 저장됨
/proc/self 현재 실행되고 있는 프로세스의 정보가 담겨있는 디렉토리
/proc/self/maps 현재 실행되고 있는 프로세스의 주소 맵

 

 

4. 예시

1) 소스 코드

   - 아래의 코드는 heap, stack, libc의 주소를 출력하는 코드

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
char *global = "Lazenca.0x0";
  
int main(){
    char *heap = malloc(100);
    char *stack[] = {"LAZENCA.0x0"};
 
    printf("[Heap]  address: %p\n", heap);
    printf("[Stack] address: %p\n", stack);
    printf("[libc]  address: %p\n",**(&stack + 3));
    printf("[.data] address: %p\n",global);
    gets(heap);
    return 0;
}

 

 

 2) echo 0 > /proc/sys/kernel/randomize_va_space

   - 아래와 같이 프로그램을 실행할 때마다 Heap, Stack, Libc의 주소 영역이 바뀌지 않음

 

 

 

 3) echo 1 > /proc/sys/kernel/randomize_va_space

   - 아래와 같이 프로그램을 실행할 때마다 Stack, Libc의 주소 영역이 변경됨

 

 

 

 4) echo 2 > /proc/sys/kernel/randomize_va_space

   - 아래와 같이 프로그램을 실행할 때마다 Heap, Stack, Libc의 주소 영역이 변경됨

 

 

 

 5) .data

   - ASLR의 설정을 2로 설정해도 .data 영역의 주소는 변경되지 않음

   - 해당 영역을 매번 새로운 주소에 할당하기 위해서는 PIE를 적용해야 함

 

 

 

5. "Checksec.sh" 파일에서 ASLR 설정여부 확인 방법

   - 아래와 같은 방법으로 시스템의 ASLR 설정여부 확인

      ① "/proc/1/status" 파일 내에 'PaX' 단어를 검색하고 검색 결과에서 'R'이 존재하는지 확인

           -> 존재한다면 "ASLR enabled"로 판단

      ② "/proc/1/status" 파일 내에 'PaX'라는 단어가 없을 경우 'sysctl' 명령어를 이용해 확인

           -> 'sysctl' 명령어를 통해 출력된 내용 중 "kernel.randomize_va_space ="의 값을 확인하여 ASLR 설정 판단

 

   - 먼저 "/proc/1/status" 파일을 이용해 ASLR 설정여부 확인

       -하지만 해당 시스템에서는 "/proc/1/status"를 이용해 ASLR이 적용되었는지 확인 불가 (해당 파일에 "Pax" 정보가 없기 때문)

   - 'sysctl' 명령어를 이용하여 ASLR 설정 여부 판단 가능

 

 

댓글