No-exec / NX
Tip
Učite i vežbajte AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Učite i vežbajte Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Podržite HackTricks
- Proverite planove pretplate!
- Pridružite se 💬 Discord grupi ili telegram grupi ili pratite nas na Twitteru 🐦 @hacktricks_live.
- Podelite hakerske trikove slanjem PR-ova na HackTricks i HackTricks Cloud github repozitorijume.
Osnovne informacije
The No-Execute (NX) bit, also known as Execute Disable (XD) in Intel terminology, is a hardware-based security feature designed to mitigate the effects of buffer overflow attacks. When implemented and enabled, it distinguishes between memory regions that are intended for executable code and those meant for data, such as the stack and heap. The core idea is to prevent an attacker from executing malicious code through buffer overflow vulnerabilities by putting the malicious code in the stack for example and directing the execution flow to it.
Modern operating systems enforce NX through the page table attributes that back the ELF program headers. For example, the PT_GNU_STACK header combined with the GNU_PROPERTY_X86_FEATURE_1_SHSTK or GNU_PROPERTY_X86_FEATURE_1_IBT properties let the loader know whether the stack should be RW or RWX. When NX is enabled and the binary was linked with a non-executable stack (-z noexecstack), any attempt to pivot execution into attacker-controlled data pages (stack, heap, mmap’ed buffers, etc.) will raise a fault unless those pages were explicitly marked as executable.
Brzo otkrivanje NX
checksec --file ./vulnwill displayNX enabledorNX disabledbased on theGNU_STACKprogram header.readelf -W -l ./vuln | grep GNU_STACKexposes the stack permissions; the presence of anEflag indicates that the stack is executable. Example:
$ readelf -W -l ./vuln | grep GNU_STACK
GNU_STACK 0x000000 0x000000 0x000000 0x000000 0x000000 RW 0x10
execstack -q ./vuln(fromprelink) je koristan pri auditu velikih kolekcija binarnih fajlova jer ispisujeXza binarije koje i dalje imaju izvršni stack.- U runtime-u,
/proc/<pid>/mapsće pokazati da li je alokacijarwx,rw-,r-x, itd., što je korisno pri proveri JIT engines-a ili custom allocators-a.
Zaobilaženja
Primitivi za ponovno korišćenje koda
Moguće je koristiti tehnike kao što je ROP da biste zaobišli ovu zaštitu izvršavanjem delova izvršnog koda koji su već prisutni u binarnom fajlu. Tipični lanci uključuju:
- Ret2libc
- Ret2syscall
- Ret2dlresolve kada binar ne importuje
system/execve - Ret2csu ili Ret2vdso za sintezu syscall-ova
- Ret2… — bilo koji dispatcher koji vam omogućava da spojite kontrolisano stanje registara sa postojećim izvršnim kodom da biste pozvali syscall-ove ili library gadgets.
Tok rada obično je: (1) leak pointera u kodu ili libc kroz info leak, (2) rešavanje baza funkcija, i (3) izrada lanca koji nikada ne zahteva izvršne bajtove pod kontrolom napadača.
Sigreturn Oriented Programming (SROP)
SROP gradi lažni sigframe na writable strani i pivota izvršenje na sys_rt_sigreturn (ili odgovarajući ABI ekvivalent). Kernel zatim „vraća“ kreirani kontekst, odmah dajući punu kontrolu nad svim opštim registrima, rip, i eflags. Nedavni CTF izazovi (npr. zadatak Hostel na n00bzCTF 2023) pokazuju kako SROP lanci prvo pozivaju mprotect da prebace stack na RWX, zatim ponovo koriste isti stack za shellcode, efektivno zaobilazeći NX čak i kada je dostupan samo jedan syscall; ret gadget. Check the dedicated SROP page for more architecture-specific tricks.
Ret2mprotect / ret2syscall za promenu permisija
Ako možete pozvati mprotect, pkey_mprotect, ili čak dlopen, možete legitimno zatražiti izvršno mapiranje pre pokretanja shellcode-a. Mali pwntools skelet izgleda ovako:
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())})
Ista ideja važi i za ret2syscall lance koji постave rax=__NR_mprotect, усмере rdi на mmap/.bss страницу, сместе жељену дужину у rsi и поставе rdx=7 (PROT_RWX). Када постоји RWX регион, извршавање може безбедно скочити у бајтове које контролише нападач.
RWX primitives from JIT engines and kernels
JIT engines, interpreters, GPU drivers и kernel subsistemi који динамички емитују код често су начин да се поврати извршна меморија чак и под строгим NX политикама. Ranljivost Linux kernela из 2024. CVE-2024-42067 показала је да пропусти у set_memory_rox() остављају eBPF JIT странице записивим и извршним, допуштајући нападачима да распрше gadgets или читаве shellcode blob-ове унутар кернела упркос NX/W^X очекивањима. Eksploiti који добију контролу над JIT компајлером (BPF, JavaScript, Lua итд.) могу зато поставити свој payload да борави у тим RWX зонама и потребна им је само једна function pointer overwrite да скоче у њих.
Non-return code reuse (JOP/COP)
Ако су ret инструкције ојачане (нпр. CET/IBT) или бинарни фајл нема изразите ret gadgets, пређите на Jump-Oriented Programming (JOP) или Call-Oriented Programming (COP). Ове технике праве dispatchere који користе jmp [reg] или call [reg] секвенце пронађене у бинарцу или учитаним библиотекама. Оне и даље поштују NX јер поново користе постојећи извршни код, али заобилазе mitigacije које посебно прате велике ланце ret инструкција.
References
Tip
Učite i vežbajte AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Učite i vežbajte Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Podržite HackTricks
- Proverite planove pretplate!
- Pridružite se 💬 Discord grupi ili telegram grupi ili pratite nas na Twitteru 🐦 @hacktricks_live.
- Podelite hakerske trikove slanjem PR-ova na HackTricks i HackTricks Cloud github repozitorijume.


