Un buffer overflow (o desbordamiento de búfer) es una vulnerabilidad de seguridad que ocurre cuando un programa intenta escribir más datos en un bloque de memoria temporal (el “búfer”) de lo que este fue diseñado para contener. El exceso de datos se desborda en ubicaciones de memoria adyacentes, sobrescribiendo potencialmente otra información importante.
¡Hablemos de Buffer Overflow! 🛡️
Un buffer overflow (o desbordamiento de búfer) es una vulnerabilidad de seguridad que ocurre cuando un programa intenta escribir más datos en un bloque de memoria temporal (el “búfer”) de lo que este fue diseñado para contener. El exceso de datos se desborda en ubicaciones de memoria adyacentes, sobrescribiendo potencialmente otra información importante.
Tipos Comunes
Los dos tipos principales se diferencian por dónde se encuentra el búfer en la memoria:
Heap-based Buffer Overflow (Desbordamiento de Búfer Basado en el Heap): Ocurre en la región de la memoria del heap, que se utiliza para la asignación dinámica de memoria. Su explotación es más compleja, ya que no se puede sobrescribir directamente la dirección de retorno.
Stack-based Buffer Overflow (Desbordamiento de Búfer Basado en la Pila): Es el más común y, a menudo, el más fácil de explotar. Ocurre en la pila de llamadas de un programa, donde se almacenan variables locales y, crucialmente, la dirección de retorno de una función.
Ejemplo de codigo
#include <stdio.h>
#include <string.h>
void vulnerable_function(char *user_input) {
char buffer[10]; // Búfer de 10 bytes
strcpy(buffer, user_input); // Función insegura: no comprueba límites
printf("Input: %s\n", buffer);
}
int main(int argc, char **argv) {
if (argc > 1) {
vulnerable_function(argv[1]);
}
return 0;
}
Declaración: La función vulnerable_function declara un búfer local llamado buffer con capacidad para 10 bytes en la pila.
Inseguridad: Utiliza la función strcpy(). Esta función es insegura porque copia ciegamente el contenido de la fuente (user_input) al destino (buffer) sin verificar si el tamaño de la fuente excede la capacidad del destino.
Desbordamiento: Si un usuario proporciona una entrada (user_input) de, por ejemplo, 20 bytes, los primeros 10 bytes llenan el buffer. Los 10 bytes restantes se desbordan y sobrescriben los datos adyacentes en la pila.
💥 Explotación: Sobrescribiendo la Dirección de Retorno
La explotación más común de un desbordamiento de búfer basado en la pila busca sobrescribir la dirección de retorno de la función.
Cuando una función termina, el procesador utiliza la dirección de retorno (almacenada en la pila) para saber a qué instrucción debe volver en la función que la llamó.
- Sobreescritura: El atacante envía una cadena de entrada especialmente diseñada que es lo suficientemente larga como para desbordar el búfer y, de forma contigua, sobrescribir la dirección de retorno guardada en la pila.
- Inyección de Código Malicioso (Shellcode): Dentro de esta cadena de entrada, el atacante puede incluir un pequeño fragmento de código malicioso, a menudo llamado shellcode.
- Redirección del Flujo de Ejecución: El atacante sobrescribe la dirección de retorno por la dirección de memoria donde se ha inyectado el shellcode.
- Ejecución: Cuando la función vulnerable termina, en lugar de volver al programa original, el procesador salta a la dirección del shellcode del atacante, que luego se ejecuta con los permisos del programa vulnerable, lo que podría permitir al atacante obtener control sobre el sistema o elevar privilegios.
Las técnicas de explotación modernas son más complejas debido a las mitigaciones de seguridad como ASLR (Address Space Layout Randomization) y Stack Canaries, que dificultan predecir la ubicación del búfer o detectar la sobrescritura de la pila.
El siguiente video explica de forma práctica la explotación de un programa vulnerable a buffer overflow en C.
youtube.com/watch?v=sdZ8aE7yxMk&pp=ygUPYnVmZmVyIG92ZXJmbG93
0 Comments