En seguridad informática , la protección del espacio ejecutable marca las regiones de memoria como no ejecutables, de modo que cualquier intento de ejecutar código máquina en estas regiones provocará una excepción . Se basa en características de hardware como el bit NX (bit de no ejecución) o en la emulación por software cuando no se dispone de soporte de hardware. La emulación por software suele generar una pérdida de rendimiento ( tiempo o recursos de procesamiento adicionales), mientras que las implementaciones del bit NX basadas en hardware no tienen un impacto apreciable en el rendimiento.
Los grandes sistemas de Burroughs , comenzando con el Burroughs 5000 presentado en 1961, implementaron la protección del espacio ejecutable mediante una arquitectura etiquetada . Todos los accesos al código y a los datos se realizaban a través de descriptores , que tenían etiquetas de memoria que impedían su modificación; los descriptores de código no permitían que el código se modificara, y los descriptores de datos no permitían que los datos se ejecutaran como código.
Actualmente, los sistemas operativos utilizan la protección del espacio ejecutable para marcar las áreas de memoria modificables, como la pila y el montón , como no ejecutables, lo que ayuda a prevenir ataques de desbordamiento de búfer . Estos ataques dependen de que alguna parte de la memoria, generalmente la pila, sea tanto modificable como ejecutable; si no lo es, el ataque falla.
Implementaciones de sistemas operativos
Muchos sistemas operativos implementan o disponen de una política de protección del espacio ejecutable. A continuación, se presenta una lista de dichos sistemas en orden alfabético, con las tecnologías ordenadas de la más reciente a la más antigua.
Una tecnología que proporciona emulación independiente de la arquitectura funcionará en todos los procesadores que no sean compatibles con el hardware. La línea "Otros compatibles" se refiere a procesadores que permiten algún método intermedio, donde no existe un bit NX explícito, pero el hardware permite emularlo de alguna manera.
Androide
A partir de Android 2.3 y versiones posteriores, las arquitecturas que lo admiten tienen páginas no ejecutables por defecto, incluyendo pila y montón no ejecutables. [ 1 ] [ 2 ] [ 3 ]
FreeBSD
La compatibilidad inicial con el bit NX , en procesadores x86-64 e IA-32 compatibles, apareció por primera vez en FreeBSD -CURRENT el 8 de junio de 2004. Ha estado presente en las versiones de FreeBSD desde la versión 5.3.
Linux
El kernel de Linux admite el bit NX en procesadores x86-64 e IA-32 compatibles, como los modernos procesadores de 64 bits de AMD, Intel, Transmeta y VIA. Andi Kleen añadió la compatibilidad con esta función en modo de 64 bits para CPU x86-64 en 2004 , y ese mismo año, Ingo Molnár añadió la compatibilidad en modo de 32 bits para CPU de 64 bits. Estas funciones forman parte del kernel principal de Linux desde el lanzamiento de la versión 2.6.8 en agosto de 2004. [ 4 ]
La disponibilidad del bit NX en los núcleos x86 de 32 bits, que pueden ejecutarse tanto en CPU x86 de 32 bits como en CPU compatibles con IA-32 de 64 bits, es significativa porque un núcleo x86 de 32 bits normalmente no esperaría el bit NX que proporciona un AMD64 o un IA-64 ; el parche habilitador de NX garantiza que estos núcleos intentarán usar el bit NX si está presente.
Algunas distribuciones de Linux de escritorio , como Fedora , Ubuntu y openSUSE , no habilitan la opción HIGHMEM64 por defecto en sus kernels predeterminados, que es necesaria para obtener acceso al bit NX en modo de 32 bits, porque el modo PAE que se requiere para usar el bit NX causa fallos de arranque en procesadores anteriores a Pentium Pro (incluido Pentium MMX) y Celeron M y Pentium M sin soporte para NX. Otros procesadores que no admiten PAE son AMD K6 y anteriores, Transmeta Crusoe , VIA C3 y anteriores, y Geode GX y LX. Las versiones de VMware Workstation anteriores a 4.0, las versiones de Parallels Workstation anteriores a 4.0 y Microsoft Virtual PC y Virtual Server no admiten PAE en el invitado. Fedora Core 6 y Ubuntu 9.10 y posteriores proporcionan un paquete kernel-PAE que admite PAE y NX.
La protección de memoria NX siempre ha estado disponible en Ubuntu para cualquier sistema que contara con el hardware necesario y ejecutara el kernel de 64 bits o el kernel de servidor de 32 bits. El kernel de escritorio PAE de 32 bits (linux-image-generic-pae) en Ubuntu 9.10 y versiones posteriores también proporciona el modo PAE necesario para el hardware con la función NX CPU. Para los sistemas que carecen de hardware NX, los kernels de 32 bits ahora ofrecen una aproximación de la función NX CPU mediante emulación por software, lo que puede ayudar a bloquear muchos exploits que un atacante podría ejecutar desde la memoria de pila o de montón.
La funcionalidad de no ejecución también ha estado presente en otros procesadores que no son x86 y que admiten esta funcionalidad desde hace muchas versiones.
Escudo ejecutivo
El desarrollador del kernel de Red Hat, Ingo Molnár, publicó un parche para el kernel de Linux llamado Exec Shield para aproximar y utilizar la funcionalidad NX en CPUs x86 de 32 bits . El parche Exec Shield se publicó en la lista de correo del kernel de Linux el 2 de mayo de 2003, pero fue rechazado para su integración con el kernel base debido a que implicaba cambios intrusivos en el código principal para gestionar las partes complejas de la emulación. La compatibilidad de Exec Shield con CPUs antiguas aproxima la emulación NX mediante el seguimiento del límite superior del segmento de código. Esto impone solo unos pocos ciclos de sobrecarga durante los cambios de contexto, lo cual es prácticamente imperceptible. Para las CPUs antiguas sin un bit NX, Exec Shield no protege las páginas por debajo del límite del segmento de código; una llamada a mprotect() para marcar como ejecutable la memoria superior, como la pila, también marcará como ejecutable toda la memoria por debajo de ese límite. Por lo tanto, en estas situaciones, los esquemas de Exec Shield fallan. Este es el precio de la baja sobrecarga de Exec Shield. Exec Shield comprueba dos marcas de encabezado ELF que determinan si la pila o el montón deben ser ejecutables. Estas se denominan PT_GNU_STACK y PT_GNU_HEAP, respectivamente. Exec Shield permite configurar estos controles tanto para ejecutables binarios como para bibliotecas; si un ejecutable carga una biblioteca que requiere que se flexibilice una restricción determinada, el ejecutable heredará esa marca y se flexibilizará dicha restricción.
- Procesadores compatibles con hardware: Todos los que Linux admite NX en
- Emulación: aproximación NX utilizando el límite de segmento de código en IA-32 ( x86 ) y compatible.
- Otros compatibles: Ninguno
- Distribución estándar: Fedora Core y Red Hat Enterprise Linux
- Fecha de lanzamiento: 2 de mayo de 2003
Paz
La tecnología PaX NX puede emular la funcionalidad NX o utilizar un bit NX de hardware. PaX funciona en procesadores x86 que no disponen del bit NX, como los de 32 bits. El kernel de Linux aún no incluye PaX (a fecha de mayo de 2007); el parche debe integrarse manualmente.
PaX proporciona dos métodos de emulación de bits NX, llamados SEGMEXEC y PAGEEXEC. El método SEGMEXEC impone una sobrecarga medible pero baja, típicamente inferior al 1%, que es un escalar constante incurrido debido a la duplicación de memoria virtual utilizada para la separación entre la ejecución y los accesos a datos. [ 5 ] SEGMEXEC también tiene el efecto de reducir a la mitad el espacio de direcciones virtuales de la tarea, lo que permite que la tarea acceda a menos memoria de la que normalmente podría. Esto no es un problema hasta que la tarea requiere acceso a más de la mitad del espacio de direcciones normal, lo cual es raro. SEGMEXEC no hace que los programas usen más memoria del sistema (es decir, RAM), solo restringe la cantidad a la que pueden acceder. En CPU de 32 bits, esto se convierte en 1,5 GB en lugar de 3 GB.
PaX proporciona un método similar a la aproximación de Exec Shield en PAGEEXEC para acelerar el proceso; sin embargo, cuando se marca como ejecutable una memoria superior, este método pierde su protección. En estos casos, PaX recurre al método anterior de sobrecarga variable utilizado por PAGEEXEC para proteger las páginas por debajo del límite CS, lo que puede generar una sobrecarga considerable en ciertos patrones de acceso a memoria . Cuando se utiliza el método PAGEEXEC en una CPU que proporciona un bit NX de hardware, se utiliza dicho bit, por lo que no se genera una sobrecarga significativa.
PaX proporciona restricciones mprotect() para evitar que los programas marquen la memoria de forma que pueda generar memoria útil para un posible ataque . Esta política provoca que ciertas aplicaciones dejen de funcionar, pero puede desactivarse para los programas afectados.
PaX permite el control individual sobre las siguientes funciones de la tecnología para cada ejecutable binario:
- PAGEEXEC
- SEGMEXEC
- Restricciones de mprotect()
- Emulación de trampolín
- Base ejecutable aleatoria
- Base mmap() aleatoria
PaX ignora tanto PT_GNU_STACK como PT_GNU_HEAP. Anteriormente, PaX contaba con una opción de configuración para respetar estos ajustes, pero dicha opción se eliminó por motivos de seguridad, ya que se consideró inútil. Normalmente, se pueden obtener los mismos resultados que con PT_GNU_STACK desactivando las restricciones de mprotect(), dado que el programa suele proteger la pila con mprotect() al cargarse. Sin embargo, esto no siempre es así; en los casos en que esto falle, simplemente desactivando PAGEEXEC y SEGMEXEC se eliminarán todas las restricciones del espacio ejecutable, lo que proporcionará a la tarea las mismas protecciones en su espacio ejecutable que en un sistema que no sea PaX.
macOS
macOS para Intel admite el bit NX en todas las CPU compatibles con Apple (desde Mac OS X 10.4.4, la primera versión para Intel, en adelante). Mac OS X 10.4 solo admitía la protección de pila NX. En Mac OS X 10.5, todos los ejecutables de 64 bits cuentan con protección de pila y montón NX, además de protección W^X. Esto incluye x86-64 (Core 2 o posterior) y PowerPC de 64 bits en las Mac G5 .
NetBSD
A partir de NetBSD 2.0 y versiones posteriores (9 de diciembre de 2004), las arquitecturas que lo admiten tienen pila y montón no ejecutables. [ 6 ]
Las arquitecturas que tienen granularidad por página son: alpha , amd64 , hppa , i386 (con PAE ), powerpc (ibm4xx), sh5 , sparc ( sun4m , sun4d ), sparc64.
Las arquitecturas que solo pueden admitir estas funciones con granularidad regional son: i386 (sin PAE), otras powerpc (como macppc).
Otras arquitecturas no se benefician de la pila o el montón no ejecutables; NetBSD no utiliza por defecto ninguna emulación de software para ofrecer estas características en dichas arquitecturas.
OpenBSD
Una tecnología del sistema operativo OpenBSD , conocida como W^X, marca por defecto las páginas modificables como no ejecutables en los procesadores que la admiten. En los procesadores x86 de 32 bits , el segmento de código se configura para incluir solo una parte del espacio de direcciones, lo que proporciona cierto nivel de protección del espacio ejecutable.
OpenBSD 3.3 se lanzó el 1 de mayo de 2003 y fue la primera versión en incluir W^X.
Solaris
Solaris ha admitido la desactivación global de la ejecución de la pila en procesadores SPARC desde Solaris 2.6 (1997); en Solaris 9 (2002), se agregó la compatibilidad para deshabilitar la ejecución de la pila por archivo ejecutable.
Windows
La primera implementación de una pila no ejecutable para Windows (NT 4.0, 2000 y XP) fue publicada por SecureWave a través de su producto SecureStack en 2001, basada en el trabajo de PaX. [ 7 ] [ 8 ]
A partir de Windows XP Service Pack 2 (2004) y Windows Server 2003 Service Pack 1 (2005), las funciones NX se implementaron por primera vez en la arquitectura x86 . La protección del espacio ejecutable en Windows se denomina "Prevención de ejecución de datos" (DEP).
En Windows XP o Server 2003, la protección NX se aplicaba de forma predeterminada exclusivamente a los servicios críticos de Windows . Si el procesador x86 admitía esta función a nivel de hardware, las funciones NX se activaban automáticamente en Windows XP/Server 2003 de forma predeterminada. Si el procesador x86 no admitía la función, no se aplicaba ninguna protección.
Las primeras implementaciones de DEP no proporcionaban aleatorización del espacio de direcciones (ASLR), lo que permitía posibles ataques de retorno a libc que podrían haberse utilizado para deshabilitar DEP durante un ataque. [ 9 ] La documentación de PaX explica por qué es necesario ASLR; [ 10 ] se produjo una prueba de concepto que detallaba un método mediante el cual se podría eludir DEP en ausencia de ASLR. [ 11 ] Puede ser posible desarrollar un ataque exitoso si el atacante puede conocer la dirección de los datos preparados, como imágenes corruptas o MP3 .
Microsoft agregó la funcionalidad ASLR en Windows Vista y Windows Server 2008. En esta plataforma, DEP se implementa a través del uso automático del kernel PAE en Windows de 32 bits y el soporte nativo en kernels de 64 bits. Windows Vista DEP funciona marcando ciertas partes de la memoria como destinadas a contener solo datos, que el procesador habilitado para el bit NX o XD entiende entonces como no ejecutable. [ 12 ] En Windows, a partir de la versión Vista, si DEP está habilitado o deshabilitado para un proceso en particular se puede ver en la pestaña Procesos/Detalles en el Administrador de tareas de Windows .
Windows implementa la protección de excepciones de software (sin usar el bit NX ) mediante el sistema de Microsoft "Safe Structured Exception Handling " (SafeSEH). Para aplicaciones compiladas correctamente, SafeSEH verifica que, cuando se produce una excepción durante la ejecución del programa, el controlador de excepciones sea el definido por la aplicación tal como se compiló originalmente. El efecto de esta protección es que un atacante no puede agregar su propio controlador de excepciones almacenado en una página de datos mediante una entrada de programa no verificada. [ 12 ] [ 13 ]
Cuando se admite NX, se habilita de forma predeterminada. Windows permite que los programas controlen qué páginas no permiten la ejecución a través de su API , así como a través de los encabezados de sección en un archivo PE . En la API, el acceso en tiempo de ejecución al bit NX se expone a través de las llamadas a la API de Win32 VirtualAlloc[Ex] y VirtualProtect[Ex] . Cada página puede marcarse individualmente como ejecutable o no ejecutable. A pesar de la falta de compatibilidad con hardware x86 anterior, las configuraciones de página ejecutable y no ejecutable se han proporcionado desde el principio. En las CPU anteriores a NX, la presencia del atributo 'executable' no tiene efecto. Se documentó como si funcionara y, como resultado, la mayoría de los programadores lo usaron correctamente. En el formato de archivo PE, cada sección puede especificar su ejecutabilidad. La bandera de ejecución ha existido desde el inicio del formato y los enlazadores estándar siempre la han usado correctamente, incluso mucho antes del bit NX. Debido a esto, Windows puede aplicar el bit NX a programas antiguos. Si el programador siguió las "mejores prácticas", las aplicaciones deberían funcionar correctamente ahora que NX es obligatorio. Solo en contados casos se han presentado problemas; el propio .NET Runtime de Microsoft tuvo problemas con NX y se actualizó.
- Procesadores compatibles: x86-64 (AMD64 e Intel 64), IA-64 , Efficeon , Pentium M (revisiones posteriores), AMD Sempron (revisiones posteriores)
- Emulación: Sí
- Otros compatibles: Ninguno
- Distribución estándar: Posterior a Windows XP
- Fecha de lanzamiento: 6 de agosto de 2004
Xbox
En la Xbox de Microsoft , aunque la CPU no tiene el bit NX, las versiones más recientes del XDK establecen el límite del segmento de código al inicio de la sección .data del kernel (en circunstancias normales, no debería haber código después de este punto). A partir de la versión 51xx , este cambio también se implementó en el kernel de las nuevas Xbox. Esto invalidó las técnicas que utilizaban los antiguos exploits para convertirse en un programa residente que terminaba y permanecía en el sistema. Sin embargo, rápidamente se lanzaron nuevos exploits que aprovechaban esta nueva versión del kernel, ya que la vulnerabilidad fundamental del kernel de Xbox no se vio afectada.
Limitaciones
Cuando el código se escribe y ejecuta en tiempo de ejecución —un compilador JIT es un ejemplo destacado—, el compilador puede utilizarse potencialmente para producir código de explotación (por ejemplo, usando JIT Spray ) que ha sido marcado para su ejecución y, por lo tanto, no sería interceptado. [ 14 ] [ 15 ]
La programación orientada a retorno puede permitir que un atacante ejecute código arbitrario incluso cuando se aplica la protección del espacio ejecutable.
Véase también
Referencias
- ↑ "Mejoras de seguridad en la gestión de memoria", Descripción general de seguridad de Android , consultado el 29/07/2012.
- ↑ "Cambio en el código de Android que habilita NX por defecto" . Cambio en el repositorio de código fuente de Android . Consultado el 27 de agosto de 2019 .
- ↑ "Requisito de compatibilidad con Android para NX" . Revisión del código de Android . Consultado el 27 de agosto de 2019 .
- ↑ "Núcleo de Linux 2.6.8" . kernelnewbies.org . 14 de agosto de 2004. Consultado el 1 de agosto de 2015 .
- ↑ "Documentación de PaX SEGMEXEC" (TXT) . pax.grsecurity.net . 10 de septiembre de 2004. Consultado el 25 de enero de 2015 .
- ↑ NetBSD, pila y montón no ejecutables , consultado el 14/07/2011.
- ↑ "SecureWave | SecureNT" . 31 de marzo de 2001. Archivado del original el 31 de marzo de 2001. Consultado el 27 de diciembre de 2023 .
- ↑ "Página principal de PaX: la implementación del indicador PAGE_EXEC para IA-32" . 31 de marzo de 2001. Archivado del original el 31 de marzo de 2001. Consultado el 27 de diciembre de 2023 .
- ↑ "Blog sobre ciberterrorismo" . Archivado del original el 9 de febrero de 2012. Consultado el 8 de enero de 2008 .
- ↑ "aleatorización del diseño del espacio de direcciones" . Proyecto PaX .
- ↑ "Desinformados - vol. 2, artículo 4" . Archivado del original el 12 de marzo de 2016. Consultado el 19 de marzo de 2010 .
- 1 2 "Una descripción detallada de la función de Prevención de Ejecución de Datos (DEP) en Windows XP Service Pack 2, Windows XP Tablet PC Edition 2005 y Windows Server 2003" . Microsoft . 26 de septiembre de 2006. Archivado del original el 11 de septiembre de 2014. Consultado el 11 de julio de 2008 .
- ↑ Johnson, Peter. "Manual de usuario de Yasm, win32: Manejo seguro de excepciones estructuradas" . Tortall Networks: Software libre y de código abierto . Archivado del original el 2 de enero de 2015. Consultado el 27 de septiembre de 2015 .
- ↑ Dion Blazakis. "Explotación de intérpretes: inferencia de punteros y pulverización JIT" (PDF) .
- ↑ Alexey Sintsov (5 de marzo de 2010). "Escribiendo JIT-Spray Shellcode por diversión y beneficio" (PDF) . Archivado del original (PDF) el 4 de marzo de 2016.
- Seguridad del sistema operativo