Artículo Buffer Overflow bajo Windows.

Iniciado por Fraile, Noviembre 20, 2021, 07:12:28 AM

Tema anterior - Siguiente tema

0 Miembros y 1 Visitante están viendo este tema.

Con este artículo me gustaría explicar en qué consiste la técnica de Buffer Overflow o Stack Overflow.

"Esta técnica, aprovecha un fallo por parte de un programador, al no tener controlado el límite de caracteres que puede introducir un usuario en un campo".
Esta definición corta y sencilla, es realmente compleja de detectar y al mismo tiempo apasionante. Ahí afuera hay toda una industria dedicada a buscar este tipo de vulnerabilidad.
Es una disciplina que lleva su tiempo, en investigación y en conocimientos de lenguajes de programación como C o Ensamblador e Ingeniería Inversa (Reversing).
Para explicar su funcionamiento en este artículo, he confeccionado una pequeña prueba de concepto (POC), realizada en su totalidad con lenguaje Ensamblador, bajo Windows 10.
Para entender esta técnica es necesario comprender como se almacena la información que introducimos en un programa, por ejemplo imagine que está introduciendo datos en una pantalla de una aplicación.



Estos datos, una vez que le damos al botón "Guardar", el programa los recoge y los almacena en una variable. Una variable seria una porción de la memoria de su ordenador, donde estará la información introducida, por ejemplo "Cayetano".



Cada porción de memoria que se reserva para almacenar sus datos, está definida con un tamaño específico. Por ejemplo, el "NIF", podría estar definido con un tamaño de 10 caracteres, el "Nombre" con un tamaño de 25 caracteres y el "Primer Apellido" con un tamaño de 35 Caracteres."

En el siguiente dibujo vera los datos introducidos dentro de su memoria.



Ahora suponga que el programador que ha diseñado el programa, previamente a reservado en memoria bloques de 10, 25 y 35 caracteres, una vez que recibe la información introducida en el formulario, no controla la longitud de los caracteres introducidos por el usuario, ¿Qué pasaría con los bloques de memoria que están ya definidos?.

Suponga que el usuario en el campo "NIF", en vez de introducir siete "XXXXXXX",  introduce dieciséis "XXXXXXXXXXXXXXXX". !!Mmmmmm, veamos que pasa.



Pues que se desbordaría el bloque de memoria definido para "NIF" y metería el resto de caracteres en el siguiente bloque de memoria que estaba definido para el "Nombre".

Bien, pues si ha entendido todo esto, ya sabe lo que es un Buffer Overflow!!.

¿Y realmente hay gente que pierde su tiempo en buscar estos pequeños fallos que ha cometido un programador por no revisar que coincida la longitud de los datos introducidos por un usuario con la longitud reservada en memoria para los mismo?, ¿Qué beneficio puede obtener de esta vulnerabilidad?.

Una persona mal intencionada, un ciberdelincuente, puede usar esto para inyectar un código malicioso en la memoria de su programa.

Veamos esto con un pequeño programa realizado en Ensamblador.



Este sería el código de un programa simulado (DLL), este programa es vulnerable a la técnica de Buffer Overflow. Tendría una función llamada "Cadena", esta función recibe dos argumentos, el primero, es un puntero hacia una cadena de texto, el segundo recibe la longitud de la cadena de texto pasada en el primer argumento.

Fíjese que la primera línea de este procedimiento, es una definición de variable, local, de 20 Bytes, para almacenar el valor pasado al primer argumento de la función "Cadena".



El resto del código, lo que hace es mover todos los bytes del argumento hacia la variable local definida "Locbuffer".

Bien, vea ahora un programa que una vez detectado que el programa anterior es vulnerable a la técnica de Buffer Overflow, va a explotar esta vulnerabilidad, enviando más bytes de los que la variable "Locbuffer" puede soportar y desbordando de esta forma la pila del programa, una vez desbordada obligara al programa vulnerable a llamar a un procedimiento de código "malicioso".



En el segmento de datos, defino una "variable", que contiene el código que va a desbordar la pila del programa vulnerable.



Si se fija en los últimos 4 bytes, están todos a "00H", en esos cuatro últimos bytes, guardare la dirección donde estará el código malicioso que sustituiré por la dirección de regreso que tiene asignada la pila.

En la parte del segmento de  código, llamo al procedimiento del programa que va a explotar la vulnerabilidad.



Ahora le muestro el procedimiento "Exploit" que es donde está el código que explotara la vulnerabilidad.



Por último está el procedimiento donde estará el código "malicioso" a ejecutar, en este POC, ese código es un simple pitido, pero esto se podría cambiar por una Shell, o cualquier otro código...... Pero ese tipo de código sobrepasa la pretensiones de este artículo.



Hasta ahora tenemos un programa simulado, que es vulnerable a esta técnica y un programa que va a desbordar el buffer de pila del programa vulnerable. Pero para ver esto bien, se tiene que ver con un desensamblador o depurador. Voy a usar el OllyDBG para que vea como se procesa todo esto en memoria.



Si pongo un punto de ruptura en la llamada al programa vulnerable, podemos ver como la pila se desborda y cambia la dirección de retorno por la dirección nueva que apunta a nuestro procedimiento "malicioso".



Vea que pasa cuando nuestro programa pasa el control al programa vulnerable y le pasa 28 Bytes cuando el programa vulnerable solo puede admitir en su variable local 20 bytes.

El código que le muestro ahora, seria la función "Cadena" de nuestro programa vulnerable.



En las primeras líneas básicamente lo que hace el ordenador es reservar espacio en la pila para la variable local "Locbuffer".



Las siguientes líneas del programa vulnerable, se encargan de mover a "Locbuffer", los bytes enviados.



Si ejecuto podemos ver paso a paso que pasa cuando se empiezan a copiar los datos enviados al buffer "Locbuffer".

He puesto un punto de ruptura en esta línea del código, que es la que se encarga de ir moviendo los bytes enviado hacia nuestro buffer local "Locbuffer".



Si se fija en el comportamiento de la pila.



Voy a ir ejecutando el código paso a paso y pondré las fotos de cómo se va cambiando la pila.

Primeros 4 bytes cambiados en la pila, hasta ahora el buffer "Locbuffer", se está cargando de forma correcta.



Siguientes 4 bytes introducidos en el buffer "Locbuffer".



Siguientes 4 bytes introducidos en el buffer "Locbuffer".



Y así, hasta que llegamos a los 20 bytes.



Hasta aquí, perfecto, el buffer "Locbuffer", que estaba definido con 20 bytes, esta relleno. El problema es que yo he enviado 28 bytes, así que la función "Cadena" de nuestro programa vulnerable, seguirá introduciendo bytes en el buffer "Locbuffer", al no haber reservado más espacio para este buffer, pisara los valores de la pila que estén a continuación del mismo.



¿Y que se encuentra justo debajo del buffer "Locbuffer"?, pues entre otras cosas la dirección de retorno a nuestro programa de explotación que llamo al programa vulnerable función "Cadena".



Esta dirección le recuerdo que apuntaría a la siguiente línea del código del programa de explotación.



Que pasa, pues que, como le he pasado más bytes de los que soporta el buffer de la función "Cadena", y dentro de esos bytes pasados, le recuerdo que puse la nueva dirección donde quiero que la pila devuelva el control, que seria sobre nuestro código "malicioso".

Si termino de ejecutar el programa, vera que la dirección de retorno original cambia por la pasada por nuestro programa de explotación.



¿Y donde esta apuntado esta dirección de retorno?, pues a nuestro código "malicioso".



Aclaraciones del Artículo.

En ningún momento pretendo con este artículo mostrar información no relevante que pueda ser usada de forma indebida, esto es una POC, muy básica.

Estudiando esta técnica, podrá enviar directamente sobre la pila un payload, totalmente autónomo y ejecutarlo. Hay muchas técnicas de explotación de Buffer Overflow, que podrá ver en internet, con este artículo quería mostrar algo diferente, sin entrar en muchos tecnicismos.

Para poder entender realmente esta técnica tiene que saber cómo funcionan los registros del procesador, pila, segmentos.... Desde The Security Sentinel, le recomendamos nuestro curso de Ensamblador y nuestro curso de Ingeniería Inversa (Reversing).

Quiero dedicar este artículo a mi amigo y compañero David Gaona, incansable en su afán de formarse y aprender, para estar siempre al día en esta disciplina tan compleja como es la ciberseguridad.

Espero que este artículo haya sido de su interés.

Un cordial saludo,

Fuente del Artículo: No tienes permitido ver los links. Registrarse o Entrar a mi cuenta






Que buen aporte!! muchisimas gracias!!
Tenia tiempo que no veía material de debugging


Muchas gracias, intentare aportar más temas sobre este tipo, el proximo artículo, sera sobre lenguejes interpretados.