elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.
 
Inicio Ayuda Ingresar Registrarse
13 Octubre 2008, 07:31  



+  Foro de elhacker.net
|-+  Seguridad Informática
| |-+  Bugs y Exploits (Moderadores: sirdarckcat, berz3k)
| | |-+  Trasteando un poco con SEH y usandolo para tomar el control....(muy basico)
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Imprimir
Autor Tema: Trasteando un poco con SEH y usandolo para tomar el control....(muy basico)  (Leído 1066 veces)
Rojodos
"If you wanna be free, you must be different"

Desconectado Desconectado

Mensajes: 3.525



Ver Perfil
Trasteando un poco con SEH y usandolo para tomar el control....(muy basico)
« en: 01 Febrero 2005, 21:16 »

Bueno, esto lo hable con mek, pero como curra demasiado, pues no pudimos seguir avanzando juntos.

Me he documentado todo lo que he podido (tanto como se crean las excepciones controladas por el usuario, asi como que pasa cuando el sistema toma el control de la excepcion).

De todas formas, antes de empezar, algunos documentos interesantes:

http://www.thc.org/papers/Practical-SEH-exploitation.pdf

http://members.v3space.com/blackfenix/seh.html

http://www.shellcode.com.ar/docz/bof/UN-shellcodes_1.txt

Y algunos de Micro$soft, solo tienen que buscarlos :)

POR FAVOR, TANTO SI HAY ERRORES PEQUEÑOS, COMO GRANDES, COMO INMENSAS METEDURAS DE PATA, DECIDMELO!!!! AGRADEZCO TODA LA INFORMACION REFERENTE AL TEMA!!!!  (pero de buen rollo joder)

Bueno, el caso, todos conocemos (mas o menos) el tipico overflow de pila:

Código:
#include <stdio.h>
#include <string.h>


int main (int argc, char **argv) {
    char buffer[7];
    strcpy (buffer, argv[1]);
    return 0;
    }
   


Si le metemos por argumento AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA petara el programa, con EIP=41414141 (A en Hexadecimal es 0x41)

Pero porque se produce el overflow exactamente? Echemos mano del olly...

CALL <JMP.&msvcrt.strcpy>                ; \strcpy
ADD ESP,10
MOV EAX,0
LEAVE
RETN

El overflow se produce en el strcpy,  ya que al copiar en la pila mas AAAs de la que soporta el "buffer", sobreescribe la direccion de retorno de MAIN, que es llamada en la instruccion RETN.

Si ponemos un BP en RETN, vemos esto en la pila:

0022FF74   41414141
0022FF78   41414141
0022FF7C   41414141

ESP apunta a 0022FF74, que es donde deberia estar la direccion de retorno de main (en este caso un return 0, y empezar la finalizacion del programa). Pero esta 41414141 (AAAA), que es donde se dirigira EIP. Esta es la clasica direccion de "ret" o "ret address", etc, donde tenemos que conseguir que EIP coja un valor que nos interese, y que acabe en nuestra shellcode. Pero eso esta mas que explicado por todos laos :)

Bueno, EIP coge el valor de 41414141, y al tratarlo de ejecutar, produce la excepcion:

Access violation when executing [41414141] - use Shift+F7/F8/F9) to pass exception to program

Aqui mas o menos ya sabemos que hacer, el clasico overflow de pila (lo que pasa en el exploit del Winamp). Yo cambie 41414141 por un offset de olepre32.dll que llamaba a un jmp esp, y como ESP apuntaba a mi shellcode, pues se ejecutaba y listo. Un stack overflow facilisimo :)

Peeero, no siempre es tan facil :) Ojo, a partir de aqui, soy novato total xDDDDDD, no respondo de gazapos, y si escribo esto, es para ayudar y que me ayuden.

Bueno, si os fijais en la pila, despues de meter las AAAAs en ella, antes de que pete el programa:

0022FF78   41414141
0022FF7C   41414141
0022FF80   41414141
0022FF84   41414141
0022FF88   41414141
0022FF8C   EE004141
0022FF90   E2CEBC00
0022FF94   003D29B8
0022FF98   00000000
0022FF9C   7FFDF000
0022FFA0  /0022FFC0
0022FFA4  |00401013  RETURN to pruebaSE.<ModuleEntryPoint>+13 from pruebaSE.00401080
0022FFA8  |00000001
0022FFAC  |EE1A0045
0022FFB0  |77F4C294  RETURN to ntdll.77F4C294
0022FFB4  |77E61417  RETURN to kernel32.77E61417 from ntdll.ZwSetInformationThread
0022FFB8  |FFFFFFFE
0022FFBC  |00000009
0022FFC0  \0022FFF0
0022FFC4   77E6141A  RETURN to kernel32.77E6141A
0022FFC8   004D7EF9
0022FFCC   0012D548
0022FFD0   7FFDF000
0022FFD4   F4B47CF0
0022FFD8   0022FFC8
0022FFDC   8053A675
0022FFE0   FFFFFFFF  End of SEH chain
0022FFE4   77E7B2E5  SE handler

Fijaros al final hay un SE handler, un manejador de excepciones. Esto nos va a servir para jugar :)

Un SE handler es un manejador de excepciones. Por ejemplo, cuando EIP alcaza la direccion 41414141 y ve que no puede ejecutar, se produce una excepcion. Hay muchos tipos de excepciones, las mas comunes son divison por 0, lectura/escritura en memoria invalidas, etc....

En tu programa, puedes incluir manejadores que permitan "arreglar" excepciones, y seguir ejecutandolo con total normalidad. Esto es otro tema que no viene al caso (como hacerlo), hay bastante info por la red, aparte que no lo entiendo muy bien :P

Bueno, si la excepcion no la puede manejar el SEH de ese thread, la "chainea" a otro SEH que la trate, si este no puede, a otro, etc.... Eso lo podemos ver en la pila:

XXXXXX00    XXXXXX1F Point to next SEH Handler
XXXXXX04    00445500  SE Handler
............
............
XXXXXX1B   XXXXXX2F Point to next SEH Handler
XXXXXX1F   00446000 SE Handler
............
.............
XXXXXX2B   FFFFFFFF End of SE Chain
XXXXXX2F    77E7B2E5  SE Handler

Los Handlers van chaineados (encadenados) y se van ejecutando uno tras otro, hasta que uno devuelva en EAX 0 (significa que ha tratado la excepcion, con lo que puede volver a tratar de ejecutar el codigo que produjo la excepcion)

Si ninguno de los "handlers" puede tratar la excepcion, llega a la ultima, que es una llamada basicamente a (despues de salvar los registros en la pila, buscad a ver que hay en esa direccion con el olly, os encontrareis con muchos push registro) kernel32.UnHanded Exception Filter () (a filtro de excepciones no manejado) y luego a ntdll.ZwRaiseException, y basicamente, te sale el cuadrito de que se ha producido una excepcion blablabla y ExitProccess();

Al rollo :)

Si ejecutaramos de nuevo el programita de arriba, pasandole muchas AAAAs, pero antes de que "pete", meter un BP en la direccion que muestre el SE Handler de la pila (sera una direccion de kernel32.dll) y luego otro en kernel32.UnhandedExceptionFilter().

En mi caso (Win XP SP1) son respectivamente 77E7b2e5 y 77e79b95.

Al seguir con la ejecucion, os saltara aviso de excepcion y pulsais SHIFT + F9 (shift+f7 manda la excepcion al programa, en este caso es lo mismo porque el programa no tiene manejador de excepciones y la mandara respectivamente al sistema. shift+f9 manda la excepcion al sistema directamente, es decir, al ultimo SE Handler, el que todo thread iniciado en Windows tiene)

Entonces vereis que primero salta a 77e7b2e5 (el ultimo SEH que habia en la pila, el de sistema) y luego en 77e79b95, que es donde reside la funcion de Unhanded Exception Filter :)

Para que sirve todo esto? Bueno :) Si le meteis tooodos estos argumentos al programa (arguments en el olly, reseteais, y lo ejecutais de nuevo con f9):

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

Al ejecutarlo y copiar las AAAs al buffer, tenemos esto en la pila:

0022FFD4   41414141
0022FFD8   41414141
0022FFDC   41414141
0022FFE0   FFFFFF00  Pointer to next SEH record
0022FFE4   77E7B2E5  SE handler
0022FFE8   77E77CE0  kernel32.77E77CE0

El null que hay en el pointer se cuela ahi, no se porque xDD, pero no nos estorba para nada. Hemos metido tantas AAAs (y hemos sobreescrito un monton del stack) que hemos llegado a donde se guarda el SEH handler (en este caso, el unico, que es el que pone el sistema por defecto). Que pasa si lo sobreescribimos?? (el pointer se sobreescribe sin que importe)

Metemos el argumento anterior (AAAA....) mas 8 bytes mas (AAAA+BBBB):

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+AAAA+BBBB  (los "+" quitadlos, es para que veais como va el tema :))

Que ocurre? Se produce la excepcion (trata de ejecutar 41414141) y si le damos a shift f9 (repito, en este caso, saltara igual al SEH del sistema) y....

PREMIO!!!!!

Access violation when executing [42424242] - use Shift+F7/F8/F9) to pass exception to program

Trata de ejecutar BBBB, que es con lo que habiamos sobreescrito el SEH!!!!!

Tenemos el control absoluto del programa :) :)

Bueno, y todo este rollo, para que sirve? En el anterior buffer overflow, para nada, ya que con muchos menos bytes (simplemente sobreescribiendo el ret en la pila y apuntado a la shellcode) solucionabamos el problema.

Como ya he dicho, los programas "comerciales" se suelen meter manejadores de excepciones para tratar de "arreglar" el problema sin llegar a cerrar el programa. Esto se puede entender bien en el texto de Undersec (arriba del todo, textos), con el texto del exploit del WarFTP.

En el, se produce un stack overflow (EIP=41414141 en ese caso tambien al probarlo Eid0) pero el WarFTP tiene un manejador de excepciones que "soluciona" el problema, y al usuario no se le muestra NADA, es decir, el programa "arregla" el problema y parece que no ha pasado nada.

Esto mas o menos se hace (y es lo que interesa) metiendo en cada thread la direccion del siguiente SEH handler, asi como el manejador propio de ese thread, en la pila, como vimos arriba, donde los handlers van chaineados hasta el ultimo.

Bien, ahora imaginemos que tenemos el control de un registro en un overflow, pero, pero, el RET (la direccion de retorno) esta "muy abajo", y tenemos que sobreescribir demasiado, incluso funciones, valores o punteros que el programa necesita para llegar a ese RET y que tomemos el control del programa.

Si tenemos el control del registro ECX (por lo que sea, una variable, un POP ECX lo que sea) que se usa en una, por ejemplo, instruccion como esta

 POP ECX
 MOV EAX,DWORD PTR SS:[ECX+C]
 .....
 ....
 .....
 (no hay call eax ni call ecx ni nada, no tenemos el control de la ejecucion del programa)
 .....


Si metemos AAAAs... en ECX (porque antes ha habido por ejemplo un POP ECX), esta instruccion generara un error de lectura (fijo) al intentar leer AAB6 (osea, 41414206)que ademas no es de la pila.

Es decir, sabemos que hay un overflow ahi, lo controlamos, podemos sobreescribir variables en la pila hasta el final (algo exagerado, me refiero a que podemos sobreescribir variables en la pila, pero no tomar el control con un ret normal), pero no podemos dirigir la ejecucion del codigo a nuestra shellcode.

Pero, pero, si dicho thread en la pila tiene un SEH (un SEH local, por ejemplo, si se trata de una funcion que hace divisiones, el SEH puede tratar de manejar las divisones por 0, en vez de que lo haga el sistema, que acaba con un ExitProccess()), y lo podemos sobreescribir, tenemos el control absoluto del programa :)

Ejemplo de varios SEH en la pila:

007DF018   30343831
007DF01C   77C00031  msvcrt.77C00031
007DF020   007DF14C
007DF024   77C03EB0  msvcrt._except_handler3
007DF028   77BE2030  msvcrt.77BE2030
007DF02C   FFFFFFFF
007DF030   77BFAB33  RETURN to msvcrt.77BFAB33 from msvcrt.77C054FD
007DF034   007DF064  Pointer to next SEH record
007DF038   0045CD5B  SE handler
007DF03C   00000000
007DF040   0043F67A  war-ftpd.00429490
007DF044   00AD9C8E 
007DF048   007DF080
007DF04C   000003E8
007DF050   00477E18  war-ftpd.00477E18
007DF054   00000012
007DF058   00AD4370 
007DF05C   00000271
007DF060   00000255
007DF064   007DF14C  Pointer to next SEH record
007DF068   0045D588  SE handler

En muchos exploits se hace asi, sobre todo en los basados en servicios de Windows (buscadlos, casi siempre hay SEH overwritting ;)) Tambien fijaros en el paper de arriba de Practical-SEH-Exploitation donde se usa esto precisamente.

En el SEH sobreescrito, se puede meter de "todo", desde offsetsa DLLs a jmp esp o jmp ebp (salta al inicio del stack del thread,ESP, o al final, EBP), a offsets para sacar uno o varios valores de la pila con POPs (como el del SERVU) (tambien en DLLs, tienen que ser cargadas por el programa vulnerable) o incluso, un valor fijo de la pila (cosa que no funcionara en casi ningun sistema, pero....)

Bueno, trasteando con el tema, he aprendido bastante, era algo que no conocia :) Espero que os sirva el texto, va dedicado a todos mis detractores :)

Espero que a gospel no le importe que le ponga una chincheta  ;D (humildad? si soy perfecto!!!" ;D ;D ;D)

Ya en serio, espero que lo entendais, y que POR FAVOR, POR FAVOR, reportadme los errores (de buen rollo joder, no llamandome de todo), que soy muy muy novato en el tema, solo estoy probando cosas :)

Salu2




En línea
Sha0

Desconectado Desconectado

Mensajes: 18


Sehr gut !!


Ver Perfil
Re: Trasteando un poco con SEH y usandolo para tomar el control....(muy basico)
« Respuesta #1 en: 02 Febrero 2005, 06:48 »

>022FFD4   41414141
>0022FFD8   41414141
>0022FFDC   41414141
>0022FFE0   FFFFFF00  Pointer to next SEH record
>0022FFE4   77E7B2E5  SE handler
>0022FFE8   77E77CE0  kernel32.77E77CE0

>El null que hay en el pointer se cuela ahi, no se porque xDD, pero >no nos estorba para nada.

Ese null es el final de tu string, date cuenta, que
"AAAAAAAA"  te pone el \0 al final
y commo k es little endian la memoria vista como string queda asi:
AAAAAAAAA\0****

con los * quiero decir el ascii 0xff
visto como unsigned long seria asi:
0x41414141
0x41414141
0xFFFFFF00  (el cero esta a la derecha logicamente por la conversión de ascii a u_long, pero no te preocupes, windows y linux son little endian asi rinde mejor)

salu2
Sha0




« Última modificación: 02 Febrero 2005, 06:50 por Sha0 » En línea

No intentes doblar la cuchara, eso es imposible.
Solo intenta comprender la realidad ...
que no hay cuchara.
-- a hacker --
Sha0

Desconectado Desconectado

Mensajes: 18


Sehr gut !!


Ver Perfil
Re: Trasteando un poco con SEH y usandolo para tomar el control....(muy basico)
« Respuesta #2 en: 02 Febrero 2005, 07:13 »

>En tu programa, puedes incluir manejadores que permitan "arreglar" excepciones, y seguir ejecutandolo con total >normalidad. Esto es otro tema que no viene al caso (como hacerlo), hay bastante >info por la red, aparte que no lo entiendo muy bien

Capturar una escepcion en c es un simple _try (es mas facil que explotar el SEH y buena practia de programacion)

por debajo siempre tira el SEH que implementa windows,
es como el on error de VB pero en realidad es todo lo mismo

un ejemplillo:
 
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclang/html/_langref_try_except_statement.asp
no hagas por ahora mucho caso al filter.

>(de buen rollo joder, no llamandome de todo),
Siento lo sucedido en el foro de 7a69, considero que te lo curras y enseñas a los demas.
Sha0



En línea

No intentes doblar la cuchara, eso es imposible.
Solo intenta comprender la realidad ...
que no hay cuchara.
-- a hacker --
Rojodos
"If you wanna be free, you must be different"

Desconectado Desconectado

Mensajes: 3.525



Ver Perfil
Re: Trasteando un poco con SEH y usandolo para tomar el control....(muy basico)
« Respuesta #3 en: 02 Febrero 2005, 07:39 »

Gracias Sha0  :)
En línea
Páginas: [1] Ir Arriba Imprimir 
Ir a:  







Consolas     La Web de Goku     MilW0rm     MundoDivx

Hispabyte     Truzone     TodoReviews     ZonaPhotoshop

hard-h2o modding    Foros de ayuda    Yashira.org    Videojuegos    indetectables.net   

Noticias Informatica    Seguridad Informática    ADSL    Foros en español    eNYe Sec

Todas las webs afiliadas están libres de publicidad engañosa.

Powered by SMF 1.1.6 | SMF © 2006-2008, Simple Machines LLC