Para ampliar lo que dijo vonbrand (correctamente, +1), hay dos partes en la protección de la pila de Linux.
Apilar canarios
Los valores canarios de pila son la característica impuesta por el compilador a la que se refiere vonbrand. Estos no se pueden deshabilitar sin una recompilación.
Para comprobarlo por sí mismo y ver cómo funcionan, tome el siguiente código:
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
int mybadfunction(char* a_bad_idea)
{
char what[100];
strcpy(what, a_bad_idea);
printf("You passed %s\n", what);
}
int main(int argc, char** argv)
{
printf("Tralalalaala\n");
mybadfunction(argv[1]);
}
Ahora compila eso (gcc -fstack-protector -masm=intel -S test.c
) en algo gnu, ya que estaría feliz de ensamblar y leer la salida. El punto importante es que al salir del mybadfunction
función, hay este pequeño fragmento de código:
mov edx, DWORD PTR [ebp-12]
xor edx, DWORD PTR gs:20
je .L2
call __stack_chk_fail
Como puede adivinar, eso es tomar una cookie de pila de [ebp-12]
y comparándolo con el valor en gs:20
. ¿No coincide? Luego llama a una función __stack_chk_fail
en glibc que mata su programa allí mismo.
Hay formas de evitar esto en términos de escribir exploits, pero la forma más fácil en términos de construir un caso de prueba de shellcode es compilar su programa con -fno-stack-protector
.
Páginas no ejecutables
Hay algunas otras consideraciones sobre los sistemas Linux modernos. Si toma el talón de prueba de shellcode habitual:
char buffer[] = {...};
typedef void (* func)(void);
int main(int argc, char** argv)
{
func f = (func) buffer;
f();
return 0;
}
GCC/Linux moderno asignará el .rodata
sección del archivo PE de solo lectura sin permisos de ejecución. Debe desactivarlo, lo que se puede hacer usando el ejemplo de código de esta publicación de blog. Idea básica:usas mprotect
para agregar los permisos que desee a las páginas en las que residen los datos de shellcode.
Pilas no ejecutables
Si va a probar un escenario de explotación tradicional, p. mi código incorrecto anterior, con su shellcode, entonces también debe asegurarse de que la pila sea ejecutable para los casos simples. El formato de archivo PE contiene un campo para determinar si la pila es ejecutable; puede consultar y controlar esto con execstack. Para habilitar una pila ejecutable, ejecute
execstack -s /path/to/myprog
Este puede se puede hacer en programas arbitrarios sin necesidad de volver a compilar, pero no deshabilitará automáticamente los canarios de pila, ya que estos se integran en la compilación.
Bonificación adicional:aslr:
Para desactivarlo, echo 0 > /proc/sys/kernel/randomize_va_space
.
¿Acabas de decirle a alguien cómo explotar a mi precioso pingüino?
No. Cualquier exploit debe funcionar alrededor de los canarios de pila (muy no triviales) y encontrar un programa con execstack
set, o set it (lo que significa que ya puede ejecutar comandos arbitrarios de todos modos) o usar técnicas más difíciles, como volver a la programación orientada a libc/return.
La protección de la pila la realiza el compilador (agregue algunos datos adicionales a la pila y guarde algunos cuando lo llame, verifique la cordura al regresar). No se puede deshabilitar eso sin volver a compilar. Es parte del punto, realmente...