Resultados 1 al 4 de 4

Introduccion a los Buffer Overflows

Vista híbrida

Mensaje anterior Mensaje anterior   Próximo mensaje Próximo mensaje
  1. #1 Introduccion a los Buffer Overflows 
    Iniciado
    Fecha de ingreso
    Oct 2004
    Ubicación
    Bs As, Argentina
    Mensajes
    13
    Descargas
    0
    Uploads
    0
    bueno, este es un texto que escribi para eMc2H y que ahora comparto con ustedes, trata sobre encontrar y explotar bugs del tipo de Buffer overflows
    doy una breve explicacion de la pila y todo lo necesario pero los que sepan ASM y C les ayudara de mucho



    Introducción y explicación de Bufer Overflow By T0wn3R.

    indice:
    Introducción.
    Buffer overflow I. Explicación.
    La pila.
    Asm y shellcodes.
    Buffer overflow II. Explotación.
    Despidiendome
    Me despedí.



    Introducción:

    Muchos de nosotros hemos visto nombrar vulnerabilidades que se basan en un buffer overflow.
    Pero... ¿que significa eso? y... ¿porque esperar a que la vulnerabilidad sea publicada por todos lados, porque no verla nosotros mismos? . Eso es algo de lo que intentaré hacer entender.
    Comenzaré explicando algunas cosas básicas antes de explotar un overflow... recomiendo tener conocimientos minimos de C, aunque lo escencial aquí lo explicaré.

    Buffer Overflow:

    Comencemos viendo que sería un buffer... simplemente un bloque contiguo de memoria (todos sabrán lo que es memoria, callad por amor de dios!!! ) que mantiene múltiples registros de un tipo de datos.
    Por deducción decimos que un buffer overflow es el desbordamiento de memoria o mejor dicho, de ese “bloque contiguo de memoria”. También llamado "desbordamiento de la pila" o del ingles: "stack smashing".
    Gracias a un Buffer podemos obtener privilegios como administrador en un sistema, simplemente ejecutando un exploit.
    Lo que quizá mucha gente no se explica aún es como puede ser posible que a pesar de tanto tiempo de que se descubrio el primer desbordamiento de la pila, sigan existiendo.
    Para ser esactos desde 1988 ya se conocía el tema, y aún en los bnoletines de securityfocus y otros sigo recibiendo avisos de programas vulnerables... para ser esactos digamos que no pasa una semana que la que no reciva aviso.
    Para poder explotar el error del cual platicamos tenemos que tener una mínima idea de como funciona el lenguaje C y tambien sería muy bueno saber algo de ensamblador. Estas dos cosas las explicaré brevemente para no hacerles "bolas" y entiendan lo mas claro posible este artículo.
    C es un lenguaje... no me pondré a dar un curso de C, aunque podría pero no es a lo que se enfoca este texto. Este complejo lenguaje es que nos permite explotar los errores ... no es que el lenguaje sea malo, es mas, en mi opinion es el mejor (después del ensamblador =) pero los programadores son muy despistados y eso es de lo que nos aprovechamos.
    Algunas implementaciones de C son vulnerables, no todas, aprovechandonos de los array's. Esto puede causar que la dirección de retorno de dicha función sea una dirección aleatoria y por eso ejecutar un exploit que nos permita acceder como root en la maquina linux de un amigo que persumia ser hacker.
    Comprendo que es un tema que a mucha gente se le hace aburrido, o difícil... de las cientas personas con las que he platicado muy pocas conocen el tema... digamos que un 90%... o menos.
    Antes de Explicar como explotar esto haremos un STOP! para ver "la pila".

    La pila.
    Una pila es un tipo especial de lista que a veces se llama lista LIFO. Last in first out (ultimo en entrar, primero en salir). Cuando se utiliza una pila en un programa de C/C++, todos los elemenos se insertan y se borran desde el final de la pila, tambien conocida como parte superior de la pila (xD, lo digo porque hay gente que le cuesta entender...XDDDD). Insertar en una pila se denomina "introducir en la pila", y borrar un nodo de la pila se llama "extraer de la pila"... no crean que me volví idiota, pero con estos terminos me referiré y quiero que lo sepan.
    Un compilador debe utilizar una pila para recordar la posicion a la que un programa debe retornar cuando acabe su ejecucion una subrutina o función.
    Un ejemplo claro de la funcion de la pila es la de RPN (notación polaca inversa(en calculadoras ¬¬))
    Para crear una pila hay que crear un modelo de esctructura que utlice una asignación dinámica de nodos para insertarlos o extraerlos de la pila. También se debe declarar una variable puntero o "puntero de la pila" que apunte al nodo situado en la parte superior de la pila.
    Todos los nodos nuevos se introducen en la pila en la posición a la que apunta el puntero de pila (top) y cuando se introduce un nuevo nodo en la pila el calor del puntero top cambia para que apunte al nuevo nodo insertado.
    Para extraer un nodo de la pila hay que tenber en cuenta que se extrae el nodo al que apunta el puntero de la pila. El puntero de la pila se ajusta para que apunte al nodo al que apunta el siguiente puntero del nodo, al que en ese momento apunta el puntero de la pila (top). Y ya con esto sabemos lo que es una pila... o bien en lugar de haberles explicado todo esto les podria haber dicho:
    "una pila es esto:
    ---------------a
    ---------------b
    ---------------c
    ---------------d
    ---------------e
    donde ------------x sería un objeto y consecuentemente si se agrega un objeto va arriba de todo:
    ---------------y (objeto agregado)
    ---------------a
    ---------------b
    ---------------c
    ---------------d
    ---------------e
    y para sacar uno de esos objetos hay que ir sacando primero el de arriba (y ya no hago dibujito porque pensaba sacar el --------------e XDDD)
    Claro, con esa definición de kinder no dominarán nunca el tema... (tampoco con todo mi texto(pero les sera de mas ayuda(espero=)=)=)


    Shellcodes y ASM =>.

    Lo básico y escencial sobre ASM sería que nos sepamos anque sea cuatro o cinco palabritas de 3 o cuatro letras...
    jmp salto
    jump salto
    call llamada
    mov mueve
    end fin
    push,add,ret,etc...
    Buscate un manual de ensamblador y revisa las funciones, mientras mas: mejor.
    Tan solo es cosa de entender cosas muy básicas... por ejemplo cuando es una llamada (call) siempre encontraremos algo asi:
    call 0xffffffffff
    donde las ffff son un numero en ehexa, o mejor dicho, la hubicación a donde se hace la llamada! =>

    Los shellcodes cambian segun estructura o SO pero esto es lo mas común: (en linux ixxx)
    movl %ebx,%eax
    popl %esi
    movl %esi,%ebx
    movl %esi,0x8(%esi)
    xorl %eax,%eax
    movb %eax,0x7(%esi)
    inc %eax
    movl %eax,0xc(%esi)
    movb $0xb,%al
    leal 0x8(%esi),%ecx
    jmp 0x1f
    leal 0xc(%esi),%edx
    int $0x80
    xorl %ebx,%ebx
    call -0x24
    int $0x80
    serán códigos que nos serviran para obtener una chell => (lista de shellcodes: Smashing the stack for fun and profit)

    Explotando!

    Bueno, nosotros lo que haremos es aprovechar que C no comprueba en tiempo de ejecucion los arrays... quiza no entiendas, veamos un ejemplo:

    #include <conio.h> /* broma, jajaja, es una larga historia lo de los bros include y conio.h en un canal de irc. *\
    int main(int argc, char *argv[]) {
    char arr1[5] = "eeee\0";
    char arr2[5];

    puts(arr1);
    strcpy(arr2, "OOOOOOOOOOOO");
    puts(arr1);

    exit(0);
    }

    Si lo ejecutamos vemos que en “puts(arr1)”; L salida es ooo y el origen es mas largo que el destino (observar strpy) por lo que comienza a sobreescribir posiciones de la memoria (arr1)

    ¿Pero esto que tiene que ver con la pila?

    Bueno, veamos un ejemplo adaptado:
    void funcion(char *p) {
    char arr[16];
    strcpy(arr, p);
    return;
    }

    int main(int argc, char *argv[]) {
    funcion(argv[1]);
    }
    y lo desamblamos (recuerda lo que es un ensamblador, usalo para desamblar, simplemente habre el archivo con él)
    Y nos aparecerá algo asi:
    disassemble main (en gdb)
    /*para los que no saben usar gdb XDD... ponemos cc archivo.c -o archivo y luego lo desamblamos con gdb archivo*\
    0x80483ec <main>: push %ebp
    0x80483ed <main+1>: mov %esp,%ebp
    0x80483ef <main+3>: mov 0xc(%ebp),%eax
    0x80483f2 <main+6>: add $0x4,%eax
    0x80483f5 <main+9>: mov (%eax),%edx

    0x80483f7 <main+11>: push %edx
    0x80483f8 <main+12>: call 0x80483d0
    0x80483fd <main+17>: add $0x4,%esp

    0x8048400 <main+20>: leave
    0x8048401 <main+21>: ret
    0x8048402 <main+22>: nop

    Lo que nos interesa es de 0x80483f7 a 0x80483fd (eso en el debguer aparece a la izquierda,m solo es una orientacion. METEMOS el parametro de la función en pila(push). Llamamos a la funcion (call... la llamada esta hecha a 0x80483d0) y trecuperamos el espacio en la pila(add $0x4, %esp)

    sigamos:
    disassemble función (en gdb)
    0x80483d0 <funcion>: push %ebp
    0x80483d1 <funcion+1>: mov %esp,%ebp
    0x80483d3 <funcion+3>: sub $0x10,%esp

    0x80483d6 <funcion+6>: mov 0x8(%ebp),%eax
    0x80483d9 <funcion+9>: push %eax
    0x80483da <funcion+10>: lea 0xfffffff0(%ebp),%eax
    0x80483dd <funcion+13>: push %eax
    0x80483de <funcion+14>: call 0x8048308
    0x80483e3 <funcion+19>: add $0x8,%esp
    0x80483e6 <funcion+22>: jmp 0x80483e8
    0x80483e8 <funcion+24>: leave
    0x80483e9 <funcion+25>: ret
    0x80483ea <funcion+26>: mov %esi,%esi
    Lo que debemos hacer es introducir un código máquina en el espacio reservado para las variables locales y después modificar la dirección de retorno para que apunte a la posición de memoria donde hemos introducido nuestro código. Lo que se suele hacer es aprovechar la función strcpy para sobreescribir posiciones de memoria. El string origen de la función strcpy contiene nuestro código máquina al principio y después la nueva dirección de retorno repetida tantas veces como sea necesaria para llegar a sobreescribir la antigua entonces al llamar a ret (retorno) se recupera la dirección y la ejecucion del programa sera donde nosotros ponemos nuestro exploit (codigo que usaremos para explotar todo esto y que lo haran ustedes en C de acuerdo a sus necesidades.... por algo les pido que aprendan dos cosas basicas antes de empezar!!!! por amor de dios!!!)

    Despidiendome...

    Antes de despedirme quiero recomendar un gran texto... suele estar en ingles, pero su nombre en español sería: “desbordamiento de la pila por diversion y beneficio” esta requete bien explicado escrito por alph1 y publicado en phreack #49 felicidades por ese texto.
    waw... se supone que iba a trasnochar por este texto 8-)... bueno =>... espero que nos veamos en algun texto más, no se si será en eMc2H ezine, en un foro, en msn, irc, etc... donde sea pero estoy seguro que nos veremos
    Feliz overflowing! xD

    AGRADECIMIENTOS:

    Por supuesto que a alph1 por su maravilloso texto que me inicio en este tema.
    A kobito que fue el que hace 5 meses me dijo: “excribe sobre buffer overflow” y y po no tenia ni idea y gracias a el lei a alph1.
    Include por hacerme reir en el irc.
    Nekro por hacerme pings de 2 mb mientras escribia esto.
    Todos los que no he nombrado y quieren figurar aquí.

    o bien pueden bajarlo en www.emc2h.cc donde hay varios textos que merecen la pena una ojeada
    Tengo planeado escribir algo sobre race conditions, asi que proximamente...
    Citar  
     

  2. #2  
    Iniciado
    Fecha de ingreso
    Oct 2004
    Mensajes
    15
    Descargas
    0
    Uploads
    0
    Muy buen texto compañero y parese que le dedicaste muxo tiempo gracias...
    Que pasa si ocupamos las llamadas de interrupcion del procesador (assembler) y en ese momentro trataramos de entrar como root??
    Citar  
     

  3. #3  
    Iniciado
    Fecha de ingreso
    Oct 2004
    Ubicación
    Bs As, Argentina
    Mensajes
    13
    Descargas
    0
    Uploads
    0
    pues
    1.- no ha ocupado mucho tiempo, es una leve introduccion.
    2.- ojeate www.shellcode.com.ar
    www.phrack.org
    www.11a.nu
    http://community.core-sdi.com/~gera/InsecureProgramming/
    http://www.netric.org
    3.- para obtener root es necesario ejecutar un shellcode que te ponga root... claro, como ejecutas el shellcode? pues para esto es el texto, simplemente lo que se hace es revalsar los bufers para que la pila indique al shellcode y lo ejecute
    Citar  
     

  4. #4 Se me complica con Pascal 
    Iniciado
    Fecha de ingreso
    Dec 2004
    Mensajes
    23
    Descargas
    0
    Uploads
    0
    Hola gente, soy nuevo en esto.. Al parecer el ASM que pones es sobre Linux, pero necesito shellcode sobre Window. Habia leido sobre el famoso overflow. Pues lo haces sobreescribiendo la direccion de retorno que por suerte esta en la PILA. Y digo por suerte, ya que me pregunto como puedo hacer si esta en el HEAP. ¿es una loteria la direccion del buffer?.. Otra cosita,¿donde puedo conseguir un curso de ASM32, o sea ASM en 32bits?. Saludos....
    Citar  
     

Temas similares

  1. Integer Buffer Overflow
    Por __BoKeN__ en el foro VULNERABILIDADES
    Respuestas: 1
    Último mensaje: 06-05-2005, 20:39
  2. Introduccion
    Por SxR en el foro DIGITAL+
    Respuestas: 3
    Último mensaje: 01-12-2004, 10:24
  3. buffer overflow
    Por TseTse en el foro VULNERABILIDADES
    Respuestas: 0
    Último mensaje: 24-11-2002, 15:52
  4. Buffer overflow vulnerability
    Por TseTse en el foro VULNERABILIDADES
    Respuestas: 0
    Último mensaje: 24-11-2002, 15:48
  5. Linux: buffer overflows and other security issues in squid
    Por TseTse en el foro VULNERABILIDADES
    Respuestas: 0
    Último mensaje: 20-11-2002, 23:15

Marcadores

Marcadores