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์ ์ ์ถํ์ฌ ํดํน ํธ๋ฆญ์ ๊ณต์ ํ์ธ์.


