No-exec / NX

Tip

Leer en oefen AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Leer en oefen GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Leer en oefen Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Ondersteun HackTricks

Basiese Inligting

Die No-Execute (NX) bit, ook bekend as Execute Disable (XD) in Intel-terminologie, is ’n hardeware-gebaseerde sekuriteitsfunksie ontwerp om die effekte van buffer overflow-aanvalle te verminder. Wanneer dit geïmplementeer en geaktiveer is, onderskei dit tussen geheuegebiede wat bedoel is vir executable code en dié vir data, soos die stack en heap. Die kernidee is om te verhoed dat ’n aanvaller kwaadwillige kode uitvoer deur middel van buffer overflow-kwetsbaarhede deur byvoorbeeld die kwaadwillige kode op die stack te plaas en die uitvoeringsvloei daarna toe te lei.

Moderne bedryfstelsels handhaaf NX deur die bladsytafelatribute wat die ELF program headers ondersteun. Byvoorbeeld, die PT_GNU_STACK header in kombinasie met die GNU_PROPERTY_X86_FEATURE_1_SHSTK of GNU_PROPERTY_X86_FEATURE_1_IBT eienskappe laat die loader weet of die stack RW of RWX moet wees. Wanneer NX geaktiveer is en die binêre met ’n nie-uitvoerbare stack (-z noexecstack) geskakel is, sal enige poging om die uitvoering na aanvallersbeheerde databladsye (stack, heap, mmap’ed buffers, ens.) te skuif ’n fout veroorsaak tensy daardie bladsye uitdruklik as uitvoerbaar gemerk is.

NX vinnig opspoor

  • checksec --file ./vuln sal NX enabled of NX disabled vertoon gebaseer op die GNU_STACK program header.
  • readelf -W -l ./vuln | grep GNU_STACK openbaar die stack-permissies; die teenwoordigheid van ’n E flag dui aan dat die stack uitvoerbaar is. Voorbeeld:
$ readelf -W -l ./vuln | grep GNU_STACK
GNU_STACK      0x000000 0x000000 0x000000 0x000000 0x000000 RW  0x10
  • execstack -q ./vuln (from prelink) is handig wanneer jy groot versamelings binaries ouditeer, omdat dit X toon vir binaries wat steeds ’n executable stack het.
  • By runtime sal /proc/<pid>/maps wys of ’n toekenning rwx, rw-, r-x, ens. is, wat nuttig is wanneer JIT engines of custom allocators geverifieer word.

Omseilings

Kode-hergebruik primitiewe

Dit is moontlik om tegnieke soos ROP te gebruik om hierdie beskerming te omseil deur stukke uitvoerbare kode wat reeds in die binary teenwoordig is uit te voer. Tipiese kettings sluit in:

  • Ret2libc
  • Ret2syscall
  • Ret2dlresolve when the binary does not import system/execve
  • Ret2csu or Ret2vdso to synthesize syscalls
  • Ret2… — any dispatcher that lets you stitch controlled register state with existing executable code to invoke syscalls or library gadgets.

Die werkvloeisel is gewoonlik: (1) leak ’n code- of libc-pointer deur ’n info leak, (2) bepaal funksie-basisse, en (3) vervaardig ’n ketting wat nooit aanvaller-beheerde executable bytes benodig nie.

Sigreturn Oriented Programming (SROP)

SROP bou ’n valse sigframe op ’n writable page en skuif uitvoering na sys_rt_sigreturn (of die relevante ABI-ekwivalent). Die kernel “herstellig” dan die vervaardigde konteks en gee onmiddellik volle beheer oor alle general-purpose registers, rip, en eflags. Onlangse CTF-uitdagings (bv. die Hostel taak in n00bzCTF 2023) wys hoe SROP-kettings eers mprotect aanroep om die stack na RWX om te draai, en dan dieselfde stack vir shellcode hergebruik, wat NX effektief omseil selfs wanneer slegs ’n enkele syscall; ret gadget beskikbaar is. Check die toegewyde SROP page vir meer argitektuur-spesifieke truuks.

Ret2mprotect / ret2syscall to flip permissions

If you can call mprotect, pkey_mprotect, or even dlopen, you can legitimately request an executable mapping before running shellcode. A small pwntools skeleton looks like:

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())})

Dieselfde idee geld vir ret2syscall-kettings wat rax=__NR_mprotect stel, rdi na ’n mmap/.bss bladsy wys, die verlangde lengte in rsi stoor, en rdx=7 (PROT_RWX) instel. Sodra ’n RWX-streek bestaan, kan die uitvoering veilig na aanvaller-beheerde bytes spring.

RWX-primitiewe vanaf JIT engines en kernels

JIT engines, interpreters, GPU drivers, en kernel subsystems wat dinamies kode genereer, is ’n algemene manier om uitvoerbare geheue terug te kry selfs onder streng NX-beleid. Die 2024 Linux kernel kwesbaarheid CVE-2024-42067 het getoon dat foute in set_memory_rox() eBPF JIT-bladsye skryfbaar en uitvoerbaar gelaat het, wat aanvallers in staat gestel het om gadgets of volledige shellcode-blobs binne die kernel te spuit ondanks NX/W^X-verwagtinge. Eksploite wat beheer oor ’n JIT-compiler (BPF, JavaScript, Lua, etc.) kry, kan dus reël dat hul payload in daardie RWX-areas woon en slegs ’n enkele function pointer overwrite benodig om daarin te spring.

Nie-terugkeer kodehergebruik (JOP/COP)

As ret instruksies verhard is (bv. CET/IBT) of die binêre lêer nie uitdrukkingsvolle ret gadgets het nie, skakel oor na Jump-Oriented Programming (JOP) of Call-Oriented Programming (COP). Hierdie tegnieke bou dispatchers wat jmp [reg] of call [reg] reekse gebruik wat in die binêre of gelaaide libraries gevind word. Hulle respekteer steeds NX omdat hulle bestaande uitvoerbare kode hergebruik, maar hulle omseil mitigasies wat spesifiek na groot kettings van ret instruksies kyk.

ROP & JOP

Verwysings

Tip

Leer en oefen AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Leer en oefen GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Leer en oefen Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Ondersteun HackTricks