Está en la página 1de 48

Análisis de Vulnerabilidades

Daniel Martínez

Buffer Overflows
Índice

1. Introducción Arquitectura Básica


▪ Banco de registros
▪ Instrucciones máquina
▪ Endianess
▪ Modelo de memoria segmentada
▪ La Pila. Ejemplo

2. Ejemplo Buffer Overflow

3. Práctica

Análisis de vulnerabilidades – Daniel Martínez


Banco de Registros x86

▪ 8 Registros de propósito general.


▪ AX,BX,CX y DX: Operaciones
aritméticas.
▪ SI,DI,BP,SP: Registros de
dirección.
▪ SI: Dirección origen
▪ DI: Dirección destino
▪ BP: Puntero a base de la pila
▪ SP: Puntero a pila
▪ PUSH/POP
▪ Registro de Flags
▪ Puntero de instrucción
▪ Segmentos de memoria
▪ Se puede acceder a medio registro (AH – AL)
▪ Windows utiliza un esquema de memoria plana (CPU puede
referenciar de manera directa todas las direcciones de memoria)

Análisis de vulnerabilidades – Daniel Martínez


Ejemplos Instrucciones x86

▪ NOP: No hace nada.


▪ MOV AX,0x8000: Almacena lo que hay en la dirección de memoria 8000
en el registro AX.
▪ ADDB AX,BH,BL: Suma BH y BL y lo guarda en AX
▪ PUSH AX: Guarda el dato almacenado en AX en la pila
▪ De manera implícita “suma” 1 posición de memoria a SP
▪ POP AX: Guarda el primer elemento de la pila en AX (LIFO)
▪ De manera implícita “resta” una posición de memoria a SP
▪ JMP 0x8048b70: salto incondicional (EIP)
▪ JNEZ 0x8048b70: Salta si el flag de cero no está activado (Reg. Flags)
▪ CALL Subrutina: Llama a la subrutina que está en la dirección de
memoria indicada por la etiqueta “Subrutina”
▪ De manera implícita PUSH EIP
▪ RET: Retoma la ejecución en el punto donde nos quedamos antes de
llamar a la subrutina.
▪ De manera implícita POP EIP

Análisis de vulnerabilidades – Daniel Martínez


Orden de los bytes en memoria

▪ Existen varias convenciones a la hora de guardar información en la


memoria principal (Endianess)
▪ BIG ENDIAN: Empieza guardando el MSB.

▪ LITTLE ENDIAN: Empieza guardando el LSB.

Análisis de vulnerabilidades – Daniel Martínez


Modelo de memoria segmentada

▪ Cuando se inicia una aplicación se crea un proceso y


se le asigna un trozo de memoria.
▪ Una reserva por cada proceso
▪ El segmento de código almacenará las instrucciones
del proceso (Read Only)
▪ El segmento de datos almacena las variables
globales y estáticas

Pila
▪ En este espacio también está el Heap (MALLOC)
▪ El segmento de pila guarda las variables locales y
datos de control. (La pila “decrece” en memoria)

Análisis de vulnerabilidades – Daniel Martínez


Ejemplo Pila
PUSH #1
int suma (int a, int b, int c){ PUSH #2
int d; PUSH #3
char buf[100]; PUSH EIP
d=a+b+c; CALL Suma
return d;
} PUSH BP
MOV BP,SP
int main(void){ SUB SP,SP,#100 MOV AX,BP-4
int x; ADD ADD AX,BP-3
x = suma(1,2,3); ADD AX,BP-2
return x; MOV SP,BP
} POP BP

RET
POP EIP

Análisis de vulnerabilidades – Daniel Martínez


Ejemplo Pila

PUSH #1
PUSH #2
PUSH #3
PUSH EIP
CALL Suma

PUSH BP
MOV BP,SP
SUB SP,SP,#100
ADD

MOV SP,BP
POP BP

RET
POP EIP

Análisis de vulnerabilidades – Daniel Martínez


Ejemplo Pila

PUSH #1
PUSH #2
PUSH #3
PUSH EIP
CALL Suma

PUSH BP
MOV BP,SP
SUB SP,SP,#100
ADD

MOV SP,BP
POP BP

RET
POP EIP

Análisis de vulnerabilidades – Daniel Martínez


Ejemplo Pila

PUSH #1
PUSH #2
PUSH #3
PUSH EIP
CALL Suma

PUSH BP
MOV BP,SP
SUB SP,SP,#100
ADD

MOV SP,BP
POP BP

RET
POP EIP

Análisis de vulnerabilidades – Daniel Martínez


Ejemplo Pila

PUSH #1
PUSH #2
PUSH #3
PUSH EIP
CALL Suma

PUSH BP
MOV BP,SP
SUB SP,SP,#100
ADD

MOV SP,BP
POP BP

RET
POP EIP

Análisis de vulnerabilidades – Daniel Martínez


Ejemplo Pila

PUSH #1
PUSH #2
PUSH #3
PUSH EIP
CALL Suma

PUSH BP
MOV BP,SP
SUB SP,SP,#100
ADD

MOV SP,BP
POP BP

RET
POP EIP

Análisis de vulnerabilidades – Daniel Martínez


Ejemplo Pila

PUSH #1
PUSH #2
PUSH #3
PUSH EIP
CALL Suma

PUSH BP
MOV BP,SP
SUB SP,SP,#100
ADD

MOV SP,BP
POP BP
POP EIP

Análisis de vulnerabilidades – Daniel Martínez


Ejemplo Pila

PUSH #1
PUSH #2
PUSH #3
PUSH EIP
CALL Suma

PUSH BP
MOV BP,SP
SUB SP,SP,#100
ADD

MOV SP,BP
POP BP
POP EIP

Análisis de vulnerabilidades – Daniel Martínez


Ejemplo Pila

PUSH #1
PUSH #2
PUSH #3
PUSH EIP
CALL Suma

PUSH BP
MOV BP,SP
SUB SP,SP,#100
MOV AX,BP-4
ADD AX,BP-3
ADD AX,BP-2

MOV SP,BP
POP BP
POP EIP

Análisis de vulnerabilidades – Daniel Martínez


Ejemplo Pila

PUSH #1
PUSH #2
PUSH #3
PUSH EIP
CALL Suma

PUSH BP
MOV BP,SP
SUB SP,SP,#100
MOV AX,BP-4
ADD AX,BP-3
ADD AX,BP-2

MOV SP,BP
POP BP
POP EIP

Análisis de vulnerabilidades – Daniel Martínez


Ejemplo Pila

PUSH #1
PUSH #2
PUSH #3
PUSH EIP
CALL Suma

PUSH BP
MOV BP,SP
SUB SP,SP,#100
MOV AX,BP-4
ADD AX,BP-3
ADD AX,BP-2

MOV SP,BP
POP BP
POP EIP

Análisis de vulnerabilidades – Daniel Martínez


Ejemplo Pila

PUSH #1
PUSH #2
PUSH #3
PUSH EIP
CALL Suma

PUSH BP
MOV BP,SP
SUB SP,SP,#100
MOV AX,BP-4
ADD AX,BP-3
ADD AX,BP-2

MOV SP,BP
POP BP
POP EIP

Análisis de vulnerabilidades – Daniel Martínez


Buffer Overflow

int suma (int a, int b, int c, char *Buffer){


int d;
char buf[100];
strcpy(buf,Buffer);
d=a+b+c;
return d;
}

int main(int argc, char **argv){


int x;
x = suma(1,2,3,argv[1]);
return x;
}

▪ Si strcpy copia Buffer en buf hasta que encuentra un carácter de fin


de String. ¿Qué sucederá con la pila?

Análisis de vulnerabilidades – Daniel Martínez


Buffer Overflow

▪ gcc programa.c –o programa


▪ ./programa AAAAAAAAAAAAAAAA……..

Análisis de vulnerabilidades – Daniel Martínez


Análisis de Vulnerabilidades
Cómo prevenir estas vulnerabilidades

• La mejor manera de evitar los desbordamientos de


buffer es mediante una programación segura, hay que
tener mucho cuidado siempre que se escriba en un
buffer, cuidando no sobrepasar el tamaño de éste.
• Los programadores que usan C deben evitar usar
funciones que no comprueban los límites:
strcpy(), strcat(), sprintf(), scanf(), sscanf(), fscanf(), vfscanf(),
vsprintf, vscanf(), vsscanf(), streadd(), strecpy(), strtrns().

Análisis de vulnerabilidades – Daniel Martínez


Análisis de Vulnerabilidades
Cómo prevenir estas vulnerabilidades
DEP (Data Execution Prevention)

• DEP ayuda a evitar la ejecución del código desde las páginas de datos.
Normalmente, el código no se ejecuta desde el montón (heap) predeterminado ni la pila.
DEP forzada por hardware detecta código que se está ejecutando desde estas
ubicaciones y produce una excepción cuando se lleva a cabo la ejecución. DEP forzada por
software puede ayudar a evitar que el código malintencionado.
• Por Hardware DEP XD/NX Intel o AMD (eXecute Disable o No Execute)
• Por Software

• También hay soluciones al problema basadas en librerías, una forma es


reimplementar las funciones inseguras y garantizar que estas funciones no
pueden exceder el tamaño del buffer en ningún caso, un ejemplo es el proyecto
Libsafe.
• Otra forma de solución basada en librerías es detectar cualquier intento de
ejecución de código ilegitimo en la pila, ejemplo de esto es la solución
SecureStack desarrollada por SecureWave.

Análisis de vulnerabilidades – Daniel Martínez


Análisis de Vulnerabilidades
Cómo prevenir estas vulnerabilidades
Stack/Canary Cookies

• Es una medida complementaria supone añadir un valor en


el stack para comprobar que el mismo no es sobreescrito.

• La idea es modificar la forma en la que el compilador


genera el prólogo y el epílogo de las funciones
añadiendo un nuevo valor aleatorio en la pila que será
comprobado una vez se salga de dicha función.

Análisis de vulnerabilidades – Daniel Martínez


Análisis de Vulnerabilidades
Cómo prevenir estas vulnerabilidades
ASLR (Address Space Layout Randomization)

• Otra forma de combatir los desbordamientos de buffer consiste en


modificar el kernel de Linux para que el segmento de pila no sea
ejecutable.
echo 2 > /proc/sys/kernel/randomize_va_space

• Esto provee menos protección de lo que parece, los atacantes


simplemente podrían forzar el sistema para llamar a otras zonas
interesantes en la memoria como el código del propio programa, en
el heap o incluso en zonas de datos estáticas.

Análisis de vulnerabilidades – Daniel Martínez


Ejemplo Buffer Overflow
▪Easy RM to MP3 Converter 2.7.3.700
▪ www.rm-to-mp3.net

Análisis de vulnerabilidades – Daniel Martínez


Ejemplo Buffer Overflow

▪ Si se introduce un fichero lo suficientemente grande. ¿Será posible


desbordar la pila?

▪ Introducimos en un fichero 10.000 “A” (41 Hexadecimal)

Análisis de vulnerabilidades – Daniel Martínez


Ejemplo Buffer Overflow
▪ Se Maneja correctamente la excepción
▪ Con 20.000 “A” nos sucede lo mismo
▪ ¿Y con 30.000?

Análisis de vulnerabilidades – Daniel Martínez


Ejemplo Buffer Overflow
▪ La excepción no se ha manejado correctamente

Análisis de vulnerabilidades – Daniel Martínez


Ejemplo Buffer Overflow
▪ Windbg: www.windbg.org

Análisis de vulnerabilidades – Daniel Martínez


Ejemplo Buffer Overflow
▪ EIP ahora contiene AAAA (41414141) – Little Endian

Análisis de vulnerabilidades – Daniel Martínez


Ejemplo Buffer Overflow

▪ Si se encuentra el desplazamiento exacto dentro de la pila que sobrescribe


el valor de EIP será posible manipular la siguiente instrucción a ejecutar.
▪ La posición que buscamos se encuentra entre 20.000 – 30.000
▪ Para reducir el rango:
– Se introducen 25.000 “A”
– Seguidamente se introducen 5.000 “B”
– Si EIP contiene “A” la dirección de EIP se encuentra entre 20.000 y
25.000
– Si EIP contiene “B” la dirección de EIP se encuentra entre 25.000 y
30.000

Análisis de vulnerabilidades – Daniel Martínez


Ejemplo Buffer Overflow

▪ EIP se encuentra entre las posiciones 25.000 y 30.000 de la pila.

Análisis de vulnerabilidades – Daniel Martínez


Ejemplo Buffer Overflow

▪ Si introdujéramos un patrón con elementos reconocibles entre las


posiciones 25.000 y 30.000 → Aislaríamos la posición que buscamos.
– Metasploit: pattern_create.rb / pattern_offset.rb

Análisis de vulnerabilidades – Daniel Martínez


Ejemplo Buffer Overflow

▪ Modificamos el script:

▪ EIP = 42356a42
– 42356A42 (Little Endian) → 426A3542 (Bj5B)

Análisis de vulnerabilidades – Daniel Martínez


Ejemplo Buffer Overflow

▪ Utilizamos pattern_offset.rb para calcular el desplazamiento:

▪ Necesitamos una longitud de buffer de 1065 bytes para sobrescribir EIP. Es


decir:
– 25.000 + 1065 bytes sobrescribirán el buffer reservado para el fichero
.m3u en la pila.
– Los siguientes 4 bytes deberían sobrescribir el EIP.
▪ El puntero de pila (SP) apuntará a alguna posición de de la pila después de
EIP. Aquí se podría incluir una shell.

Análisis de vulnerabilidades – Daniel Martínez


Ejemplo Buffer Overflow

▪ Estado de la pila tras desbordar el buffer:

▪ MOV SP,BP para deshacer la ventana de pila:


Pila BUFFER BP EIP #3 #2 #1
AAAAAAAAAAAAAAAAAAAAAAAA

BP
SP

▪ POP BP para recuperar el puntero base anterior:


Pila BUFFER BP EIP #3 #2 #1
AAAAAAAAAAAAAAAAAAAAAAAA

BP=AAAA SP


▪POP EI para recuperar la dirección de retorno:
Pila BUFFER BP EIP #3 #2 #1
AAAAAAAAAAAAAAAAAAAAAAAA

BP=AAAA SP

Análisis de vulnerabilidades – Daniel Martínez


Ejemplo Buffer Overflow
▪ Modificamos nuestro script para sobrescribir EIP y añadimos más datos
detrás para comprobar si SP realmente apunta a donde queremos:

▪ EIP ahora vale BBBB:

▪ Un volcado de SP nos muestra la memoria a la que apunta:

Análisis de vulnerabilidades – Daniel Martínez


Ejemplo Buffer Overflow

▪ SP puede que no apunte exactamente a la primera posición después de EIP


(Se almacenan más datos que EIP para retorno)
▪Modificamos nuestro script para comprobar la posición exacta:

▪ En nuestro caso hay un desplazamiento de 4 (CCCC de $esp)

Análisis de vulnerabilidades – Daniel Martínez


Ejemplo Buffer Overflow

▪ Si ahora ponemos la dirección de memoria a la que apunta ESP en nuestro


EIP se ejecutarían las instrucciones codificadas en estas posiciones de
memoria.

▪ ¿Estas posiciones de memoria serán la mismas para todos los sistemas,


arquitecturas y ejecuciones?

▪ Para conseguir que el código funcione en más sistemas podemos


aprovechar las DLL que utiliza la aplicación.

▪ Si en alguna de estas DLL encontramos la instrucción JMP ESP el exploit


será portable.
– Instalamos paquete de símbolos a WINDBG:
http://msdn.microsoft.com/en-us/windows/hardware/gg463028
– Los añadimos con Ctrl + S
– Abrimos WINDBG y seleccionamos “Attach to process” para depurar
“Easy RM To MP3”
– a (assemble) , jmp esp, u (unassemble)
Análisis de vulnerabilidades – Daniel Martínez
Ejemplo Buffer Overflow

Análisis de vulnerabilidades – Daniel Martínez


Ejemplo Buffer Overflow

▪ En la posición de memoria 7c911230 está la instrucción jmp esp con código


de operación ffe4

▪ Ahora hay que buscar este código de operación en alguno de los DLL
cargados al principio de la aplicación.
– Tiene que ser una DLL de la aplicación y no del S.O (Portabilidad)
– S “memorigen” “memdestino” “codigoop”

Análisis de vulnerabilidades – Daniel Martínez


Ejemplo Buffer Overflow

Análisis de vulnerabilidades – Daniel Martínez


Ejemplo Buffer Overflow

▪ Buscamos jmp esp (FF E4) en MRSMCcodec02.dll por ejemplo.


▪ Seleccionamos una posición de memoria de la DLL cargada en memoria que
no contenga bytes nulos (00) ya que esto pararía el cauce de la ejecución.

▪Un buen candidato es 01 B5 F2 3A . Contiene jmp esp (FF E4) y no tiene


bytes nulos (00)

Análisis de vulnerabilidades – Daniel Martínez


Ejemplo Buffer Overflow

▪ Modificamos nuestro script:

▪ Introducimos una serie de A para desbordar la pila.


▪ Reescribimos el EIP con la dirección en la que se encuentra JMP ESP .
▪ Introducimos el desplazamiento necesario para empezar a escribir en las
direcciones a las que apunta ESP.
▪ Introducimos una “shell”:
– 25 NOPS
– Break (Si se hace el salto correctamente termina aquí)
– 25 NOPS (Si no se hace seguirá ejecutando NOPS)

Análisis de vulnerabilidades – Daniel Martínez


Ejemplo Buffer Overflow

▪ Se ha realizado el break:

▪ Al hacer un volcado de ESP observamos:


– 25 NOPS (90)
– Break (cc)
– 25 NOPS
▪ ¿Y si quisiéramos realizar algo más que un break?
– Generamos un payload con metasploit y lo añadimos a nuestro exploit.

Análisis de vulnerabilidades – Daniel Martínez


Ejemplo Buffer Overflow
▪ Utilizamos un bind shell al puerto 4444.
– Se utiliza el encoder call4_dword_xor

Análisis de vulnerabilidades – Daniel Martínez


Ejemplo Buffer Overflow

Análisis de vulnerabilidades – Daniel Martínez


Referencias

Exploit writing tutorial part 1 : Stack Based Overflows


▪ https://www.corelan.be/index.php/2009/07/19/exploit-writing-tutorial-part-1-stack-
based-overflows/
Exploit writing tutorial part 2 : Stack Based Overflows – jumping to shellcode
▪ https://www.corelan.be/index.php/2009/07/23/writing-buffer-overflow-exploits-a-
quick-and-basic-tutorial-part-2/

Análisis de vulnerabilidades – Daniel Martínez

También podría gustarte