No-exec / NX
Tip
Aprende y practica Hacking en AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP:HackTricks Training GCP Red Team Expert (GRTE)
Aprende y practica Hacking en Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Apoya a HackTricks
- Revisa los planes de suscripción!
- Únete al 💬 grupo de Discord o al grupo de telegram o síguenos en Twitter 🐦 @hacktricks_live.
- Comparte trucos de hacking enviando PRs a los HackTricks y HackTricks Cloud repositorios de github.
Información básica
El No-Execute (NX) bit, también conocido como Execute Disable (XD) en la terminología de Intel, es una característica de seguridad basada en hardware diseñada para mitigar los efectos de ataques buffer overflow. Cuando se implementa y habilita, distingue entre regiones de memoria destinadas a código ejecutable y aquellas destinadas a datos, como la stack y la heap. La idea central es evitar que un atacante ejecute código malicioso aprovechando vulnerabilidades de buffer overflow, por ejemplo colocando el código malicioso en la stack y dirigiendo el flujo de ejecución hacia él.
Los sistemas operativos modernos hacen cumplir NX a través de los atributos de la tabla de páginas que respaldan los ELF program headers. Por ejemplo, el encabezado PT_GNU_STACK combinado con las propiedades GNU_PROPERTY_X86_FEATURE_1_SHSTK o GNU_PROPERTY_X86_FEATURE_1_IBT permiten al loader saber si la stack debe ser RW o RWX. Cuando NX está habilitado y el binario fue enlazado con una stack no ejecutable (-z noexecstack), cualquier intento de pivotar la ejecución hacia páginas de datos controladas por el atacante (stack, heap, mmap’ed buffers, etc.) provocará una falla a menos que esas páginas hayan sido marcadas explícitamente como ejecutables.
Detectar NX rápidamente
checksec --file ./vulnmostraráNX enabledoNX disabledbasado en el encabezado de programaGNU_STACK.readelf -W -l ./vuln | grep GNU_STACKmuestra los permisos de la stack; la presencia de una banderaEindica que la stack es ejecutable. Ejemplo:
$ readelf -W -l ./vuln | grep GNU_STACK
GNU_STACK 0x000000 0x000000 0x000000 0x000000 0x000000 RW 0x10
execstack -q ./vuln(fromprelink) es útil cuando se auditan grandes colecciones de binarios porque imprimeXpara los binarios que aún tienen una pila ejecutable.- En tiempo de ejecución,
/proc/<pid>/mapsmostrará si una asignación esrwx,rw-,r-x, etc., lo cual es útil al verificar JIT engines o custom allocators.
Bypasses
Primitivas de reutilización de código
Es posible usar técnicas como ROP para eludir esta protección ejecutando fragmentos de código ejecutable ya presentes en el binario. Las cadenas típicas incluyen:
- Ret2libc
- Ret2syscall
- Ret2dlresolve cuando el binario no importa
system/execve - Ret2csu o Ret2vdso para sintetizar syscalls
- Ret2… — cualquier despachador que te permita combinar el estado controlado de registros con código ejecutable existente para invocar syscalls o gadgets de librería.
El flujo de trabajo suele ser: (1) leak un puntero de código o de libc a través de un info leak, (2) resolver las bases de las funciones, y (3) crear una cadena que nunca necesite bytes ejecutables controlados por el atacante.
Sigreturn Oriented Programming (SROP)
SROP construye un sigframe falso en una página escribible y pivota la ejecución a sys_rt_sigreturn (o al equivalente ABI relevante). El kernel entonces “restaura” el contexto fabricado, otorgando instantáneamente control completo sobre todos los registros de propósito general, rip y eflags. Retos recientes de CTF (p. ej., la tarea Hostel en n00bzCTF 2023) muestran cómo las cadenas SROP invocan primero mprotect para cambiar la pila a RWX, y luego reutilizan la misma pila para shellcode, eludiendo efectivamente NX incluso cuando solo hay disponible un único gadget syscall; ret. Consulta la página dedicada SROP page para más trucos específicos de arquitectura.
Ret2mprotect / ret2syscall para cambiar permisos
Si puedes llamar a mprotect, pkey_mprotect, o incluso dlopen, puedes solicitar legítimamente un mapeo ejecutable antes de ejecutar shellcode. Un pequeño esqueleto de pwntools se ve así:
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())})
La misma idea se aplica a las cadenas ret2syscall que establecen rax=__NR_mprotect, apuntan rdi a una página de mmap/.bss, almacenan la longitud deseada en rsi y fijan rdx=7 (PROT_RWX). Una vez que existe una región RWX, la ejecución puede saltar con seguridad a bytes controlados por el atacante.
Primitivas RWX desde JIT engines y kernels
JIT engines, interpreters, GPU drivers y subsistemas del kernel que emiten código de forma dinámica son una vía común para recuperar memoria ejecutable incluso bajo políticas NX estrictas. La vulnerabilidad del kernel de Linux de 2024 CVE-2024-42067 mostró que fallos en set_memory_rox() dejaban las páginas eBPF JIT escribibles y ejecutables, permitiendo a los atacantes pulverizar gadgets o blobs completos de shellcode dentro del kernel a pesar de las expectativas NX/W^X. Exploits que gain control over a JIT compiler (BPF, JavaScript, Lua, etc.) pueden por tanto arrange for their payload to live in esos arenas RWX y only need a single function pointer overwrite para saltar dentro de ellos.
Reutilización de código sin retorno (JOP/COP)
Si las instrucciones ret están reforzadas (p. ej., CET/IBT) o el binario carece de ret gadgets expresivos, cambia a Jump-Oriented Programming (JOP) o Call-Oriented Programming (COP). Estas técnicas construyen dispatchers que usan secuencias jmp [reg] o call [reg] encontradas en el binario o en librerías cargadas. Aún respetan NX porque reutilizan código ejecutable existente, pero evitan mitigaciones que vigilan específicamente grandes cadenas de instrucciones ret.
Referencias
Tip
Aprende y practica Hacking en AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP:HackTricks Training GCP Red Team Expert (GRTE)
Aprende y practica Hacking en Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Apoya a HackTricks
- Revisa los planes de suscripción!
- Únete al 💬 grupo de Discord o al grupo de telegram o síguenos en Twitter 🐦 @hacktricks_live.
- Comparte trucos de hacking enviando PRs a los HackTricks y HackTricks Cloud repositorios de github.


