La protección contra desbordamiento del búfer es cualquiera de las diversas técnicas que se utilizan durante el desarrollo de software para mejorar la seguridad de los programas ejecutables al detectar desbordamientos del búfer en las variables asignadas a la pila y evitar que causen un mal comportamiento del programa o que se conviertan en una seguridad gravevulnerabilidades. Un desbordamiento del búfer de pila se produce cuando un programa escribe en una dirección de memoria en la pila de llamadas del programa fuera de la estructura de datos prevista, que suele ser un búfer de longitud fija. Los errores de desbordamiento del búfer de pila se producen cuando un programa escribe más datos en un búfer ubicado en la pila de lo que realmente está asignado para ese búfer. Esto casi siempre da como resultado la corrupción de los datos adyacentes en la pila, lo que podría provocar fallas del programa, operación incorrecta o problemas de seguridad.
Por lo general, la protección de desbordamiento del búfer modifica la organización de los datos asignados a la pila, por lo que incluye un valor canario que, cuando se destruye por un desbordamiento del búfer de la pila, muestra que un búfer que lo precede en la memoria se ha desbordado. Al verificar el valor canary, se puede terminar la ejecución del programa afectado, evitando que se comporte mal o permitiendo que un atacante tome el control sobre él. Otras técnicas de protección contra desbordamiento del búfer incluyen la verificación de límites , que verifica los accesos a cada bloque de memoria asignado para que no puedan ir más allá del espacio realmente asignado, y el etiquetado , que garantiza que la memoria asignada para almacenar datos no pueda contener código ejecutable.
Es más probable que sobrellenar un búfer asignado en la pila influya en la ejecución del programa que sobrellenar un búfer en el montón porque la pila contiene las direcciones de retorno para todas las llamadas a funciones activas. Sin embargo, también existen protecciones específicas de implementación similares contra desbordamientos basados en el montón.
Hay varias implementaciones de protección contra desbordamiento de búfer, incluidas las de GNU Compiler Collection , LLVM , Microsoft Visual Studio y otros compiladores.
Descripción general
Un desbordamiento del búfer de pila se produce cuando un programa escribe en una dirección de memoria en la pila de llamadas del programa fuera de la estructura de datos prevista, que suele ser un búfer de longitud fija. Los errores de desbordamiento del búfer de pila se producen cuando un programa escribe más datos en un búfer ubicado en la pila de lo que realmente está asignado para ese búfer. Esto casi siempre da como resultado la corrupción de datos adyacentes en la pila y, en los casos en que el desbordamiento se desencadenó por error, a menudo hará que el programa se bloquee o funcione incorrectamente. El desbordamiento del búfer de pila es un tipo de mal funcionamiento de programación más general conocido como desbordamiento del búfer (o desbordamiento del búfer). Sobrellenar un búfer en la pila es más probable que descarrile la ejecución del programa que sobrellenar un búfer en el montón porque la pila contiene las direcciones de retorno para todas las llamadas a funciones activas. [1]
El desbordamiento del búfer de pila se puede provocar deliberadamente como parte de un ataque conocido como rotura de pila . Si el programa afectado se ejecuta con privilegios especiales, o si acepta datos de hosts de red que no son de confianza (por ejemplo, un servidor web público ), entonces el error es una vulnerabilidad de seguridad potencial que permite a un atacante inyectar código ejecutable en el programa en ejecución y tomar control del proceso. Este es uno de los métodos más antiguos y confiables para que los atacantes obtengan acceso no autorizado a una computadora. [2]
Normalmente, la protección de desbordamiento del búfer modifica la organización de los datos en el marco de pila de una llamada de función para incluir un valor "canario" que, cuando se destruye, muestra que un búfer que lo precede en la memoria se ha desbordado. Esto proporciona el beneficio de prevenir toda una clase de ataques. Según algunos investigadores, [3] el impacto en el rendimiento de estas técnicas es insignificante.
La protección contra la acumulación de pilas no puede proteger contra ciertas formas de ataque. Por ejemplo, no puede proteger contra desbordamientos de búfer en el montón. No existe una forma sensata de alterar el diseño de los datos dentro de una estructura ; Se espera que las estructuras sean las mismas entre módulos, especialmente con bibliotecas compartidas. Cualquier dato en una estructura después de un búfer es imposible de proteger con canarios; por lo tanto, los programadores deben tener mucho cuidado con la forma en que organizan sus variables y usan sus estructuras.
Canarias
Canarias o palabras canarias son valores conocidos que se colocan entre un búfer y los datos de control en la pila para monitorear los desbordamientos del búfer. Cuando el búfer se desborda, los primeros datos que se corrompen generalmente serán el canario y, por lo tanto, una verificación fallida de los datos canarios alertará de un desbordamiento, que luego se puede manejar, por ejemplo, invalidando los datos corrompidos. Un valor canario no debe confundirse con un valor centinela .
La terminología es una referencia a la práctica histórica de utilizar canarios en las minas de carbón , ya que se verían afectados por gases tóxicos antes que los mineros, proporcionando así un sistema de alerta biológica. Los canarios se conocen alternativamente como cookies , lo que pretende evocar la imagen de una "cookie rota" cuando el valor está dañado.
Hay tres tipos de canarios en uso: terminador , aleatorio y XOR aleatorio . Las versiones actuales de StackGuard admiten los tres, mientras que ProPolice admite terminator y canarios aleatorios .
Canarios Terminator
Los canarios Terminator utilizan la observación de que la mayoría de los ataques de desbordamiento de búfer se basan en ciertas operaciones de cadena que terminan en terminadores de cadena. La reacción a esta observación es que los canarios están formados por terminadores nulos , CR , LF y FF . Como resultado, el atacante debe escribir un carácter nulo antes de escribir la dirección de retorno para evitar alterar el canario. Esto evita ataques usando strcpy()
y otros métodos que regresan al copiar un carácter nulo, mientras que el resultado indeseable es que el canario es conocido. Incluso con la protección, un atacante podría potencialmente sobrescribir el canary con su valor conocido y la información de control con valores no coincidentes, pasando así el código de verificación canary, que se ejecuta poco antes de la instrucción de retorno de llamada del procesador específico.
Canarios al azar
Los canarios aleatorios se generan aleatoriamente, generalmente a partir de un demonio de recolección de entropía , para evitar que un atacante conozca su valor. Por lo general, no es lógicamente posible o plausible leer el canario para explotar; el canario es un valor seguro conocido sólo por aquellos que necesitan conocerlo, el código de protección de desbordamiento de búfer en este caso.
Normalmente, se genera un canario aleatorio en la inicialización del programa y se almacena en una variable global. Esta variable generalmente se rellena con páginas no mapeadas, de modo que intentar leerla usando cualquier tipo de trucos que aprovechen los errores para leer la RAM causa una falla de segmentación, terminando el programa. Es posible que aún sea posible leer el canario, si el atacante sabe dónde está, o puede hacer que el programa lea de la pila.
Canarios XOR aleatorios
Los canarios XOR aleatorios son canarios aleatorios que se codifican mediante XOR utilizando todos o parte de los datos de control. De esta forma, una vez que el canario o los datos de control son golpeados, el valor canario es incorrecto.
Los canarios aleatorios XOR tienen las mismas vulnerabilidades que los canarios aleatorios, excepto que el método de "lectura de la pila" para obtener el canario es un poco más complicado. El atacante debe obtener el canary, el algoritmo y los datos de control para volver a generar el canary original necesario para falsificar la protección.
Además, los canarios XOR aleatorios pueden proteger contra cierto tipo de ataque que implica desbordar un búfer en una estructura en un puntero para cambiar el puntero para apuntar a una pieza de datos de control. Debido a la codificación XOR, el canario se equivocará si se cambian los datos de control o el valor de retorno. Debido al puntero, los datos de control o el valor de retorno se pueden cambiar sin desbordar el canario.
Aunque estos canarios protegen los datos de control para que no sean alterados por punteros golpeados, no protegen ningún otro dato ni los punteros en sí. Los punteros de función son especialmente un problema aquí, ya que pueden desbordarse y pueden ejecutar shellcode cuando se llaman.
Comprobación de límites
La comprobación de límites es una técnica basada en el compilador que agrega información de límites en tiempo de ejecución para cada bloque de memoria asignado y compara todos los punteros con los del tiempo de ejecución. Para C y C ++, la verificación de límites se puede realizar en el momento del cálculo del puntero [4] o en el momento de la eliminación de la referencia. [5] [6] [7]
Las implementaciones de este enfoque utilizan un repositorio central, que describe cada bloque de memoria asignado, [4] [5] [6] o punteros gordos , [7] que contienen tanto el puntero como datos adicionales, que describen la región a la que apuntan .
Etiquetado
El etiquetado [8] es una técnica basada en compilador o hardware (que requiere una arquitectura etiquetada ) para etiquetar el tipo de un dato en la memoria, que se utiliza principalmente para la verificación de tipos. Al marcar ciertas áreas de la memoria como no ejecutables, efectivamente evita que la memoria asignada para almacenar datos contenga código ejecutable. Además, ciertas áreas de la memoria se pueden marcar como no asignadas, lo que evita los desbordamientos del búfer.
Históricamente, el etiquetado se ha utilizado para implementar lenguajes de programación de alto nivel; [9] con el apoyo adecuado del sistema operativo , el etiquetado también se puede utilizar para detectar desbordamientos de búfer. [10] Un ejemplo es la función de hardware de bits NX , compatible con procesadores Intel , AMD y ARM .
Implementaciones
Colección de compiladores GNU (GCC)
StackGuard implementó por primera vez la protección contra la destrucción de pilas en 1997 y se publicó en el Simposio de seguridad de USENIX de 1998 . [11] StackGuard se introdujo como un conjunto de parches para el backend Intel x86 de GCC 2.7. StackGuard se mantuvo para la distribución de Immunix Linux desde 1998 hasta 2003, y se amplió con implementaciones para terminador, canarios aleatorios y XOR aleatorios. Se sugirió la inclusión de StackGuard en GCC 3.x en las Actas de la Cumbre de 2003 de GCC, [12] pero esto nunca se logró.
De 2001 a 2005, IBM desarrolló parches GCC para la protección contra la destrucción de pilas , conocidos como ProPolice . [13] Mejoró la idea de StackGuard colocando búferes después de punteros locales y argumentos de función en el marco de pila. Esto ayudó a evitar la corrupción de punteros, impidiendo el acceso a ubicaciones de memoria arbitrarias.
Sin embargo, los ingenieros de Red Hat identificaron problemas con ProPolice y en 2005 volvieron a implementar la protección contra la destrucción de pilas para su inclusión en GCC 4.1. [14] [15] Este trabajo introdujo la -fstack-protectorbandera, que protege solo algunas funciones vulnerables, y la -fstack-protector-allbandera, que protege todas las funciones, lo necesiten o no. [dieciséis]
En 2012, los ingenieros de Google implementaron la -fstack-protector-strongbandera para lograr un mejor equilibrio entre seguridad y rendimiento. [17] Esta bandera protege más tipos de funciones vulnerables que lo -fstack-protectorhace, pero no todas las funciones, proporcionando un mejor rendimiento que -fstack-protector-all. Está disponible en GCC desde su versión 4.9. [18]
Todos los paquetes de Fedora se compilan -fstack-protectordesde Fedora Core 5 y -fstack-protector-strongdesde Fedora 20. [19] [20] La mayoría de los paquetes en Ubuntu se compilan -fstack-protectordesde la versión 6.10. [21] Todos los paquetes de Arch Linux se compilan -fstack-protectordesde 2011. [22] Todos los paquetes de Arch Linux construidos desde el 4 de mayo de 2014 usan -fstack-protector-strong. [23] La protección de pila solo se usa para algunos paquetes en Debian , [24] y solo para el sistema base FreeBSD desde 8.0. [25] La protección de pila es estándar en ciertos sistemas operativos, incluyendo OpenBSD , [26] Hardened Gentoo [27] y DragonFly BSD [ cita requerida ] .
StackGuard y ProPolice no pueden proteger contra desbordamientos en estructuras asignadas automáticamente que se desbordan en punteros de función. ProPolice, al menos, reorganizará el orden de asignación para que dichas estructuras se asignen antes de los punteros de función. En PointGuard [28] se propuso un mecanismo separado para la protección de punteros y está disponible en Microsoft Windows. [29]
Microsoft Visual Studio
El conjunto de compiladores de Microsoft implementa la protección de desbordamiento del búfer desde la versión 2003 a través del modificador de línea de comandos / GS , que está habilitado de forma predeterminada desde la versión 2005. [30] Usando / GS- desactiva la protección.
Compilador de IBM
La protección contra la rotura de pilas se puede activar mediante el indicador del compilador -qstackprotect
. [31]
Clang / LLVM
Clang soporta tres detectores de desbordamiento del búfer, a saber AddressSanitizer (-fsanitize = dirección), [6] -fsanitize = límites, [32] y SAFECode. [33] Estos sistemas tienen diferentes compensaciones en términos de penalización de rendimiento, sobrecarga de memoria y clases de errores detectados. La protección de pila es estándar en ciertos sistemas operativos, incluido OpenBSD . [34]
Compilador Intel
El compilador C y C ++ de Intel admite la protección contra la destrucción de pilas con opciones similares a las proporcionadas por GCC y Microsoft Visual Studio. [35]
A prueba de fallas C
Fail-Safe C [7] es un compilador ANSI C de código abierto seguro para la memoria que realiza una comprobación de límites basada en punteros gordos y acceso a memoria orientado a objetos. [36]
StackGhost (basado en hardware)
Inventado por Mike Frantzen , StackGhost es un simple ajuste a las rutinas de derrame / llenado de la ventana de registro que hace que los desbordamientos de búfer sean mucho más difíciles de explotar. Utiliza una característica de hardware única de la arquitectura SPARC de Sun Microsystems (que es: derrame / relleno diferido de la ventana de registro en el marco en la pila) para detectar modificaciones de los punteros de retorno (una forma común en que un exploit secuestra las rutas de ejecución) de forma transparente y automática protegiendo todas las aplicaciones sin requerir modificaciones binarias o de fuente. El impacto en el rendimiento es insignificante, menos del uno por ciento. Mark Kettenis resolvió los problemas de gdb resultantes dos años después, lo que permitió habilitar la función. Después de este evento, el código StackGhost se integró (y optimizó) en OpenBSD / SPARC.
Un ejemplo canario
La asignación de búfer normal para arquitecturas x86 y otras arquitecturas similares se muestra en la entrada de desbordamiento de búfer . Aquí, mostraremos el proceso modificado en lo que respecta a StackGuard.
Cuando se llama a una función, se crea un marco de pila. Un marco de pila se construye desde el final de la memoria hasta el principio; y cada marco de pila se coloca en la parte superior de la pila, más cerca del comienzo de la memoria. Por lo tanto, ejecutar el final de un dato en un marco de pila altera los datos ingresados previamente en el marco de pila; y correr desde el final de un marco de pila coloca los datos en el marco de pila anterior. Un marco de pila típico puede verse como a continuación, con una dirección de retorno (RETA) colocada en primer lugar, seguida de otra información de control (CTLI).
(CTLI) (RETA)
En C , una función puede contener muchas estructuras de datos por llamada diferentes. Cada dato creado en la llamada se coloca en el marco de la pila en orden y, por lo tanto, se ordena desde el final hasta el comienzo de la memoria. A continuación se muestra una función hipotética y su marco de pila.
int foo () { int a ; / * entero * / int * b ; / * puntero a entero * / char c [ 10 ]; / * matrices de caracteres * / char d [ 3 ]; b = & a ; / * inicializa b para apuntar a la ubicación de a * / strcpy ( c , get_c ()); / * obtener c de algún lugar, escribirlo en c * / * b = 5 ; / * los datos en el punto en la memoria b indica que están establecidos en 5 * / strcpy ( d , get_d ()); return * b ; / * leer de by pasarlo a la persona que llama * / }
(d ..) (c .........) (b ...) (a ...) (CTLI) (RETA)
En esta situación hipotética, si se escriben más de diez bytes en la matriz c
, o más de 13 en la matriz de caracteres d
, el exceso se desbordará en un puntero entero b
, luego en un entero a
, luego en la información de control y finalmente en la dirección de retorno. Al sobrescribir b
, se hace que el puntero haga referencia a cualquier posición en la memoria, lo que provoca una lectura desde una dirección arbitraria. Al sobrescribir RETA , se puede hacer que la función ejecute otro código (cuando intenta regresar), ya sea funciones existentes ( ret2libc ) o código escrito en la pila durante el desbordamiento.
En pocas palabras, la mala manipulación de c
y d
, como la ilimitada strcpy () llama anteriormente, puede permitir a un atacante para controlar un programa influyendo en los valores asignados a c
y d
directamente. El objetivo de la protección contra desbordamiento del búfer es detectar este problema de la forma menos intrusiva posible. Esto se hace eliminando lo que puede estar fuera de peligro y colocando una especie de cable trampa, o canario , después del amortiguador.
La protección contra desbordamiento del búfer se implementa como un cambio en el compilador. Como tal, es posible que la protección altere la estructura de los datos en el marco de la pila. Este es exactamente el caso en sistemas como ProPolice . Las variables automáticas de la función anterior se reorganizan de manera más segura: matrices c
y d
se asignan primero en el marco de pila, que coloca el entero a
y el puntero de entero b
antes que ellos en la memoria. Entonces el marco de la pila se convierte en
(b ...) (a ...) (d ..) (c .........) (CTLI) (RETA)
Como es imposible mover CTLI o RETA sin romper el código producido, se emplea otra táctica. Una pieza adicional de información, llamada "canario" (CNRY), se coloca después de los búferes en el marco de la pila. Cuando los búferes se desbordan, se cambia el valor canario. Por lo tanto, para atacar eficazmente el programa, un atacante debe dejar una indicación definida de su ataque. El marco de la pila es
(b ...) (a ...) (d ..) (c .........) (CNRY) (CTLI) (RETA)
Al final de cada función hay una instrucción que continúa la ejecución desde la dirección de memoria indicada por RETA . Antes de que se ejecute esta instrucción, una verificación de CNRY asegura que no se haya alterado. Si el valor de CNRY falla la prueba, la ejecución del programa finaliza inmediatamente. En esencia, tanto los ataques deliberados como los errores de programación involuntarios resultan en un aborto del programa.
La técnica canary agrega algunas instrucciones de sobrecarga para cada llamada de función con una matriz automática, inmediatamente antes de toda la asignación dinámica del búfer y después de la desasignación dinámica del búfer. La sobrecarga generada en esta técnica no es significativa. Sin embargo, funciona, a menos que el canario permanezca sin cambios. Si el atacante sabe que está ahí y puede determinar el valor del canario, simplemente puede copiarlo consigo mismo. Esto suele ser difícil de arreglar intencionalmente y muy improbable en situaciones no intencionales.
La posición del canario es específica de la implementación, pero siempre está entre los búferes y los datos protegidos. Las posiciones y longitudes variadas tienen beneficios variados.
Ver también
- Valor centinela (que no debe confundirse con un valor canario)
- Integridad del flujo de control
- Aleatorización del diseño del espacio de direcciones
- Protección de espacio ejecutable
- Depurador de memoria
- Paz
- Análisis de código estático
Referencias
- ^ Fithen, William L .; Seacord, Robert (27 de marzo de 2007). "VT-MB. Violación de los límites de la memoria" . US CERT .
- ^ Levy, Elias (8 de noviembre de 1996). "Rompiendo la pila por diversión y ganancias" . Phrack . 7 (49): 14.
- ^ "Desbordamientos de búfer: ataques y defensas para la vulnerabilidad de la década *" (PDF) . Archivado desde el original (PDF) el 2013-03-09.
- ^ a b "Comprobación de límites para C" . Doc.ic.ac.uk. Archivado desde el original el 26 de marzo de 2016 . Consultado el 27 de abril de 2014 .
- ^ a b "SAFECode: Arquitectura virtual segura" . Sva.cs.illinois.edu. 2009-08-12 . Consultado el 27 de abril de 2014 .
- ^ a b c "google / sanitizers" . 19 de junio de 2021.
- ^ a b c "Fail-Safe C: página superior" . Staff.aist.go.jp. 2013-05-07. Archivado desde el original el 7 de julio de 2016 . Consultado el 27 de abril de 2014 .
- ^ "Martes, 05 de abril de 2005" (PDF) . Feustel.us . Archivado desde el original (PDF) el 23 de junio de 2016 . Consultado el 17 de septiembre de 2016 .
- ^ Steenkiste, Peter; Hennessy, John (1987). "Etiquetas y verificación de tipos en LISP: enfoques de hardware y software" . Revisión de sistemas operativos ACM Sigops . ACM. 21 (4): 50–59. doi : 10.1145 / 36204.36183 .
- ^ "Descripción general de la seguridad MCP de ClearPath Enterprise Servers" (PDF) . Public.support.unisys.com. Archivado desde el original (PDF) el 24 de enero de 2013 . Consultado el 27 de abril de 2014 .
- ^ "Artículos - 7mo Simposio de Seguridad de USENIX, 1998" . Usenix.org. 2002-04-12 . Consultado el 27 de abril de 2014 .
- ^ "Actas de la Cumbre de desarrolladores de GCC" (PDF) . Mayo de 2003. Archivado desde el original el 15 de julio de 2004 . Consultado el 17 de septiembre de 2016 .CS1 maint: bot: estado de URL original desconocido ( enlace )
- ^ "Extensión de GCC para proteger las aplicaciones de ataques de destrucción de pilas" . Research.ibm.com . Consultado el 27 de abril de 2014 .
- ^ "Serie de versiones GCC 4.1 - Cambios, nuevas funciones y correcciones - Proyecto GNU - Free Software Foundation (FSF)" . Gcc.gnu.org . Consultado el 27 de abril de 2014 .
- ^ "Richard Henderson - [rfc] reimplementación de ibm stack-smashing protector" . Gcc.gnu.org . Consultado el 27 de abril de 2014 .
- ^ "Optimizar opciones: usar la colección de compiladores GNU (GCC)" . Gcc.gnu.org . Consultado el 27 de abril de 2014 .
- ^ "Han Shen (ææ) - [PATCH] Agrega una nueva opción" -fstack-protector-strong "(parche / doc adentro)" . Gcc.gnu.org. 2012-06-14 . Consultado el 27 de abril de 2014 .
- ^ Edge, Jake (5 de febrero de 2014). " " Una fuerte protección "pila de GCC" . Noticias semanales de Linux . Consultado el 28 de noviembre de 2014 .
Ha llegado a GCC 4.9
- ^ "Funciones de seguridad" . FedoraProject. 2013-12-11 . Consultado el 27 de abril de 2014 .
- ^ "# 1128 (cambiando de" -fstack-protector "a" -fstack-protector-strong "en Fedora 20) - FESCo" . Fedorahosted.org . Consultado el 27 de abril de 2014 .
- ^ "Seguridad / Funciones - Wiki de Ubuntu" . Wiki.ubuntu.com . Consultado el 27 de abril de 2014 .
- ^ "FS # 18864: Considere la posibilidad de habilitar la protección de destrucción de pilas de GCC (ProPolice, SSP) para todos los paquetes" . Bugs.archlinux.org . Consultado el 27 de abril de 2014 .
- ^ "svntogit / packages.git - Clon de Git del repositorio de 'paquetes'" .
- ^ "Estadísticas de refuerzo de la seguridad de Debian" . Outflux.net . Consultado el 27 de abril de 2014 .
- ^ "Notas de la versión de FreeBSD 8.0-RELEASE" . Freebsd.org. 2013-11-13 . Consultado el 27 de abril de 2014 .
- ^ "Página del manual gcc-local (1) de OpenBSD" .
gcc viene con la extensión de protección de pila ProPolice , que está habilitada de forma predeterminada.
- ^ "Hardened / Toolchain - Gentoo Wiki" . 2016-07-31.
El GCC reforzado con Gentoo activa el protector de pila de forma predeterminada a menos que se solicite explícitamente que no lo haga.
- ^ "12º Simposio de Seguridad de USENIX - Documento técnico" .
- ^ "Blogs de MSDN: obtenga la información, los conocimientos, los anuncios y las noticias más recientes de los desarrolladores y expertos de Microsoft en los blogs de MSDN" .
- ^ "/ GS (Comprobación de seguridad del búfer) (C ++)" . msdn.microsoft.com . Consultado el 27 de abril de 2014 .
- ^ "qstackprotect" . Publib.boulder.ibm.com . Consultado el 27 de abril de 2014 .
- ^ "Manual del usuario del compilador de Clang - Documentación de Clang 3.5" . Clang.llvm.org . Consultado el 27 de abril de 2014 .
- ^ "SAFECode" . Safecode.cs.illinois.edu . Consultado el 27 de abril de 2014 .
- ^ "Página de manual de clang-local (1) de OpenBSD" .
clang viene con la protección de pila habilitada por defecto, equivalente a la opción -fstack-protector-strong en otros sistemas.
- ^ "Guía de usuario y referencia para el compilador Intel C ++ 15.0: fstack-security-check, GS" . software.intel.com . Consultado el 13 de febrero de 2015 .
- ^ "thesis.dvi" (PDF) . Staff.aist.go.jp . Consultado el 17 de septiembre de 2016 .
enlaces externos
- Actas de la Cumbre del CCG de 2003 (PDF)
- Rompiendo la pila por diversión y ganancias por Aleph One
- Hogar oficial de ProPolice
- Página de inicio de Immunix StackGuard
- Papel StackGuard original en USENIX Security 1998
- StackGhost: protección de pila facilitada por hardware
- Implementación propolice de FreeBSD 5.4 y 6.2
- Cuatro trucos diferentes para evitar la protección StackShield y StackGuard
- Protector de aplastamiento de pilas