No-exec / NX
Tip
AWS 해킹 배우기 및 연습하기:
HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기:HackTricks Training GCP Red Team Expert (GRTE)
Azure 해킹 배우기 및 연습하기:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks 지원하기
- 구독 계획 확인하기!
- **💬 디스코드 그룹 또는 텔레그램 그룹에 참여하거나 트위터 🐦 @hacktricks_live를 팔로우하세요.
- HackTricks 및 HackTricks Cloud 깃허브 리포지토리에 PR을 제출하여 해킹 트릭을 공유하세요.
기본 정보
The No-Execute (NX) bit, Intel 용어로는 **Execute Disable (XD)**라고도 불리며, buffer overflow 공격의 영향을 완화하기 위해 설계된 하드웨어 기반 보안 기능입니다. 적용 및 활성화되면, executable code용 메모리 영역과 data용 영역(예: stack, heap)을 구분합니다. 핵심 아이디어는 공격자가 예를 들어 악성 코드를 stack에 넣고 실행 흐름을 그쪽으로 돌려 buffer overflow 취약점을 통해 악성 코드를 실행하는 것을 방지하는 것입니다.
현대 운영체제는 ELF 프로그램 헤더를 뒷받침하는 페이지 테이블 속성을 통해 NX를 적용합니다. 예를 들어 PT_GNU_STACK 헤더와 GNU_PROPERTY_X86_FEATURE_1_SHSTK 또는 GNU_PROPERTY_X86_FEATURE_1_IBT 속성의 조합은 로더에 stack이 RW인지 RWX인지 알려줍니다. NX가 활성화되어 있고 바이너리가 non-executable stack (-z noexecstack)으로 링크되어 있다면, 공격자가 제어하는 데이터 페이지(stack, heap, mmap’ed buffers 등)로 실행을 전환하려는 모든 시도는 해당 페이지들이 명시적으로 실행 가능(executable)으로 표시되지 않는 한 fault를 발생시킵니다.
NX 빠르게 탐지하기
checksec --file ./vuln는GNU_STACK프로그램 헤더를 기준으로NX enabled또는NX disabled를 표시합니다.readelf -W -l ./vuln | grep GNU_STACK는 stack 권한을 보여줍니다;E플래그가 존재하면 stack이 executable임을 나타냅니다. 예:
$ readelf -W -l ./vuln | grep GNU_STACK
GNU_STACK 0x000000 0x000000 0x000000 0x000000 0x000000 RW 0x10
execstack -q ./vuln(fromprelink)는 실행 스택이 남아 있는 바이너리에 대해X를 출력하므로 대규모 바이너리 모음을 감사할 때 유용합니다.- 런타임에서는
/proc/<pid>/maps가 해당 할당이rwx,rw-,r-x등인지 보여주며, 이는 JIT 엔진이나 커스텀 할당자를 검증할 때 유용합니다.
우회 방법
코드 재사용 프리미티브
바이너리에 이미 존재하는 실행 가능한 코드 조각을 실행하여 이 보호를 우회하기 위해 ROP와 같은 기법을 사용할 수 있습니다. 일반적인 체인에는 다음이 포함됩니다:
- Ret2libc
- Ret2syscall
- Ret2dlresolve — 바이너리가
system/execve를 임포트하지 않을 때 - Ret2csu 또는 Ret2vdso — syscall을 합성하기 위해
- Ret2… — 제어된 레지스터 상태를 기존 실행 코드와 연결해 syscalls 또는 라이브러리 가젯을 호출할 수 있게 해주는 어떤 디스패처든
흐름은 보통 다음과 같습니다: (1) info leak을 통해 코드 또는 libc 포인터를 leak한다, (2) 함수 베이스를 결정한다, (3) 공격자가 제어하는 실행 가능한 바이트가 전혀 필요 없는 체인을 구성한다.
Sigreturn Oriented Programming (SROP)
SROP는 쓰기 가능한 페이지에 가짜 sigframe을 구성하고 실행을 sys_rt_sigreturn(또는 해당 ABI의 동등 기능)으로 피벗합니다. 그러면 커널이 조작한 컨텍스트를 “복원”하여 모든 범용 레지스터와 rip, eflags를 즉시 완전 제어할 수 있게 합니다. 최근 CTF 문제들(예: n00bzCTF 2023의 Hostel 과제)은 SROP 체인이 먼저 mprotect를 호출해 스택을 RWX로 바꾼 다음 동일한 스택을 shellcode에 재사용하여, 단 하나의 syscall; ret 가젯만 있어도 NX를 효과적으로 우회하는 방법을 보여줍니다. 아키텍처별 트릭은 전용 SROP page를 참고하세요.
Ret2mprotect / ret2syscall로 권한 변경
만약 mprotect, pkey_mprotect, 또는 dlopen을 호출할 수 있다면, shellcode를 실행하기 전에 정당하게 실행 가능한 매핑을 요청할 수 있습니다. 작은 pwntools 스켈레톤은 다음과 같습니다:
from pwn import *
elf = ELF("./vuln")
rop = ROP(elf)
rop.mprotect(elf.bss(), 0x1000, 7)
payload = flat({offset: rop.chain(), offset+len(rop.chain()): asm(shellcraft.sh())})
The same idea applies to ret2syscall chains that set rax=__NR_mprotect, point rdi to a mmap/.bss page, store the desired length in rsi, and set rdx=7 (PROT_RWX). Once a RWX region exists, execution can safely jump into attacker-controlled bytes.
RWX primitives from JIT engines and kernels
코드를 동적으로 생성하는 JIT engines, interpreters, GPU drivers, 그리고 kernel subsystems는 엄격한 NX 정책 하에서도 실행 가능한 메모리를 회복하는 흔한 방법입니다. 2024년 Linux 커널 취약점 CVE-2024-42067는 set_memory_rox()의 실패로 eBPF JIT 페이지가 쓰기 가능하면서 동시에 실행 가능하게 남아 있어, 공격자가 NX/W^X 기대와는 달리 커널 내부에 gadgets나 전체 shellcode 블롭을 뿌릴 수 있게 했음을 보여주었습니다. 따라서 JIT 컴파일러(BPF, JavaScript, Lua 등)를 제어하는 익스플로잇은 페이로드를 그런 RWX 영역에 위치시키고, 단 한 번의 function pointer overwrite로 그곳으로 점프할 수 있도록 만들 수 있습니다.
Non-return code reuse (JOP/COP)
If ret instructions are hardened (e.g., CET/IBT) or the binary lacks expressive ret gadgets, pivot to Jump-Oriented Programming (JOP) or Call-Oriented Programming (COP). These techniques build dispatchers that use jmp [reg] or call [reg] sequences found in the binary or loaded libraries. They still respect NX because they reuse existing executable code, but they sidestep mitigations that specifically watch for large chains of ret instructions.
References
Tip
AWS 해킹 배우기 및 연습하기:
HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기:HackTricks Training GCP Red Team Expert (GRTE)
Azure 해킹 배우기 및 연습하기:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks 지원하기
- 구독 계획 확인하기!
- **💬 디스코드 그룹 또는 텔레그램 그룹에 참여하거나 트위터 🐦 @hacktricks_live를 팔로우하세요.
- HackTricks 및 HackTricks Cloud 깃허브 리포지토리에 PR을 제출하여 해킹 트릭을 공유하세요.


