[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
$ 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 설정 여부 판단 가능
'Security > System Hacking' 카테고리의 다른 글
[Dreamhack System Hacking] STAGE 7 - 함께실습 (0) | 2022.02.10 |
---|---|
[Dreamhack System Hacking] STAGE 7 (0) | 2022.02.10 |
[Dreamhack System Hacking] STAGE 6 - basic_rop_x86 (0) | 2022.02.06 |
[Dreamhack System Hacking] STAGE 6 - basic_rop_x64 (0) | 2022.02.06 |
[Dreamhack System Hacking] STAGE 6 - 함께실습 (0) | 2022.02.06 |
댓글