2011-12-17 14 views
8

Hola a todos,¿Diferencia entre declarar shellcode como una matriz char [] y char *?

estoy tratando de aprender shellcoding básico y me he encontrado con algo curioso que espero que alguien me puede explicar. He compilado el siguiente código de dos maneras: declarando el shellcode como una matriz y como un char *. Cuando declaro Shellcode como una matriz, Linux detecta que estoy tratando de ejecutar datos y obtengo una segfault en la primera instrucción. Sin embargo, cuando declaro Shellcode como un char * todo el Shellcode se ejecuta y obtengo un "¡Hola mundo!". ¿Cómo trata el compilador estas dos declaraciones de manera diferente y por qué uno termina en shellcode que vive en la memoria que está desprotegida? Gracias por adelantado.

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

/* This declaration ends in a segfault */ 
//char shellcode[] = 

/* This declaration ends in successful execution */ 
char* shellcode = 

/* Shellcode prints "Hello world!" and exits */  
"\xeb\x1f\x48\x31\xc0\x48\x31\xdb\x48\x31\xc9\x48\x31\xd2\xb0\x04\xb3\x01\x59\xb2\x0c\xcd\x80\x48\x31\xc0\xb0\x01\x48\x31\xdb\xcd\x80\xe8\xdc\xff\xff\xff\x48\x65\x6c\x6c\x6f\x20\x57\x6f\x72\x6c\x64\x21"; 

int main() 
{ 
    void (*f)(); 
    f = (void (*)())shellcode; 
    (void)(*f)(); 
} 

Respuesta

8

Cuando se declara como un char[], la memoria está en la pila. Cuando lo declara como char* y le asigna un literal de cadena, la memoria está en la imagen ejecutable. A Linux no le gusta que ejecutes código en la pila, pero está bien que ejecutes la memoria en esa parte de la imagen ejecutable. Esto se debe a que está tratando de evitar un cierto tipo de ataque de desbordamiento de pila donde las personas pueden desbordar la pila con algunas instrucciones arbitrarias y luego ejecutarlas.

Puede usar mprotect en Linux para establecer los permisos para una región de memoria o VirtualProtectEx en Windows. De esta forma, puede establecer explícitamente que los permisos de la memoria sean ejecutables.

3

En el primer caso:

char shellcode[] = 

Esto pone la cadena literal en la pila como un array local. La pila y la memoria del montón generalmente no tienen permisos de ejecución (por razones obvias de seguridad).

En el segundo caso:

char* shellcode = 

La cadena vive en la memoria estática - típicamente en la misma región que el resto del programa binario - que es ejecutable.

Cuestiones relacionadas