Diferencia entre revisiones de «Desbordamiento de búfer»

(Página creada con '{{Definición |nombre=Desbordamiento de búfer |imagen=Desbordamiento-de-bufer-2.jpg |tamaño= |concepto=Error de software que se produce cuando un programa no controla adecuada...')
 
m (Texto reemplazado: «<div align="center">» por «»)
 
(No se muestran 2 ediciones intermedias de 2 usuarios)
Línea 6: Línea 6:
 
}}
 
}}
  
<div align="justify">
+
 
  
 
En seguridad informática y programación, un desbordamiento de buffer (del inglés buffer overflow o buffer overrun) es un error de software que se produce cuando un programa no controla adecuadamente la cantidad de datos que se copian sobre un área de memoria reservada a tal efecto (buffer), de forma que si dicha cantidad es superior a la capacidad preasignada los bytes sobrantes se almacenan en zonas de memoria adyacentes, sobrescribiendo su contenido original. Esto constituye un fallo de programación.
 
En seguridad informática y programación, un desbordamiento de buffer (del inglés buffer overflow o buffer overrun) es un error de software que se produce cuando un programa no controla adecuadamente la cantidad de datos que se copian sobre un área de memoria reservada a tal efecto (buffer), de forma que si dicha cantidad es superior a la capacidad preasignada los bytes sobrantes se almacenan en zonas de memoria adyacentes, sobrescribiendo su contenido original. Esto constituye un fallo de programación.
Línea 18: Línea 18:
 
''Ejemplo'': En este ejemplo, un programa tiene definidos dos elementos de datos continuos en memoria: un buffer de 8 bytes tipo string, A, y otro de dos bytes tipo entero, B. Al comienzo, A contiene bytes nulos y B contiene el número 3 (cada carácter se representa mediante un byte).
 
''Ejemplo'': En este ejemplo, un programa tiene definidos dos elementos de datos continuos en memoria: un buffer de 8 bytes tipo string, A, y otro de dos bytes tipo entero, B. Al comienzo, A contiene bytes nulos y B contiene el número 3 (cada carácter se representa mediante un byte).
  
<div align="center">[[Archivo:Buffer_excesive.jpg]]</div>
+
[[Archivo:Buffer_excesive.jpg]]</div>
  
 
A continuación, el programa intenta almacenar la cadena de caracteres "excessive" en el buffer A, seguido de bytes nulos para marcar el fin de string. Al no validarse la longitud de la cadena, se sobrescribe el valor de B. A pesar de que el programador no quería cambiar el contenido del búffer B, el valor de éste ha sido reemplazado por un número equivalente a parte de la cadena de caracteres. Para este ejemplo, en un sistema big-endian que use ASCII, el carácter 'o' seguido del byte nulo equivale al número 28416. Si B fuese la única variable aparte de A definida en el programa, la escritura de datos que sobrepasen los límites de B generarían un error como segmentation fault, concluyendo así el programa.
 
A continuación, el programa intenta almacenar la cadena de caracteres "excessive" en el buffer A, seguido de bytes nulos para marcar el fin de string. Al no validarse la longitud de la cadena, se sobrescribe el valor de B. A pesar de que el programador no quería cambiar el contenido del búffer B, el valor de éste ha sido reemplazado por un número equivalente a parte de la cadena de caracteres. Para este ejemplo, en un sistema big-endian que use ASCII, el carácter 'o' seguido del byte nulo equivale al número 28416. Si B fuese la única variable aparte de A definida en el programa, la escritura de datos que sobrepasen los límites de B generarían un error como segmentation fault, concluyendo así el programa.
Línea 93: Línea 93:
 
== Enlaces externos ==
 
== Enlaces externos ==
  
* [http://www.websecurity.es/desbordamiento-b-fer-buffer-overflows]
+
* [http://www.websecurity.es/desbordamiento-b-fer-buffer-overflows www.websecurity.es]
  
* [http://es.kioskea.net/contents/19-ataques-por-desbordamiento-de-bufer]
+
* [http://es.kioskea.net/contents/19-ataques-por-desbordamiento-de-bufer es.kioskea.net]
  
* [http://es.wikipedia.org/wiki/Desbordamiento_de_búfer]
+
* [http://es.wikipedia.org/wiki/Desbordamiento_de_búfer es.wikipedia.org]
  
 
[[Category:Ciencias_informáticas]]
 
[[Category:Ciencias_informáticas]]

última versión al 13:36 2 sep 2019

Desbordamiento de búfer
Información sobre la plantilla
Desbordamiento-de-bufer-2.jpg
Concepto:Error de software que se produce cuando un programa no controla adecuadamente la cantidad de datos que se copian sobre un área de memoria reservada a tal efecto (buffer).


En seguridad informática y programación, un desbordamiento de buffer (del inglés buffer overflow o buffer overrun) es un error de software que se produce cuando un programa no controla adecuadamente la cantidad de datos que se copian sobre un área de memoria reservada a tal efecto (buffer), de forma que si dicha cantidad es superior a la capacidad preasignada los bytes sobrantes se almacenan en zonas de memoria adyacentes, sobrescribiendo su contenido original. Esto constituye un fallo de programación.

"Los ataques por desbordamiento de búfer" (también denominado saturación de búfer) están diseñados para activar la ejecución de un código arbitrario en un programa al enviar un caudal de datos mayor que el que puede recibir. Los programas que admiten datos de entrada con parámetros, los almacenan temporalmente en una zona de la memoria denominada búfer. Pero algunas funciones de lectura, como las strcpy() del lenguaje C, no admiten este tipo de desbordamiento y causan el bloqueo de la aplicación, lo que puede provocar la ejecución del código arbitrario y permitir el acceso al sistema. La implementación de este tipo de ataques es extremadamente complicada ya que requiere un conocimiento exhaustivo de la arquitectura del programa y del procesador. Sin embargo, existen varios puntos vulnerables capaces de automatizar este tipo de ataques y de hacerlos accesibles para aquellos que son casi inexpertos.

Funcionamiento básico

El principio operativo de un desbordamiento de búfer guarda una relación muy estrecha con la arquitectura del procesador en la que se ejecuta una aplicación vulnerable. Los datos ingresados en una aplicación se almacenan en la memoria de acceso aleatorio en una zona que se conoce como búfer. Un programa con un diseño correcto debería estipular un tamaño máximo para los datos de entrada y garantizar que no superen ese valor. Las instrucciones y los datos de un programa en ejecución se almacenan temporalmente en forma adyacente en la memoria, en una zona llamada pila. Los datos ubicados después del búfer contienen una dirección de retorno (que se denomina puntero de instrucción) que le permite al programa continuar su tiempo de ejecución. Si el tamaño de los datos es mayor que el del búfer, la dirección de retorno se sobrescribe y el programa leerá una dirección de memoria no válida generando una violación de segmento en la aplicación.

Ejemplo: En este ejemplo, un programa tiene definidos dos elementos de datos continuos en memoria: un buffer de 8 bytes tipo string, A, y otro de dos bytes tipo entero, B. Al comienzo, A contiene bytes nulos y B contiene el número 3 (cada carácter se representa mediante un byte).

Buffer excesive.jpg

A continuación, el programa intenta almacenar la cadena de caracteres "excessive" en el buffer A, seguido de bytes nulos para marcar el fin de string. Al no validarse la longitud de la cadena, se sobrescribe el valor de B. A pesar de que el programador no quería cambiar el contenido del búffer B, el valor de éste ha sido reemplazado por un número equivalente a parte de la cadena de caracteres. Para este ejemplo, en un sistema big-endian que use ASCII, el carácter 'o' seguido del byte nulo equivale al número 28416. Si B fuese la única variable aparte de A definida en el programa, la escritura de datos que sobrepasen los límites de B generarían un error como segmentation fault, concluyendo así el programa.

Un pirata informático con un sólido conocimiento técnico puede asegurarse de que la dirección de memoria sobrescrita corresponda a una real, por ejemplo, una que esté ubicada en el mismo búfer. Como tal, al ingresar las instrucciones en el búfer (el código arbitrario), es fácil para él ejecutar este procedimiento. Por lo tanto, es posible incluir instrucciones en el búfer que permitan abrir un intérprete de comandos (shell) permitiendo que el pirata tome control del sistema. Este código arbitrario que posibilita la ejecución del intérprete de comandos se conoce como código de shell o shellcode.

Programa desbordable

Un ejemplo de un programa desbordable sería el siguiente:

#include <stdio.h>
main()
{
      char userinput[50];
      printf("Introduce una cadena: ");
      scanf("%s", &userinput); /* posible buffer overflow */
      return 0;
}

El programa anterior generará un desbordamiento de buffer si el usuario introduce una cadena mayor que 50 caracteres pues la misma se usa para llenar un buffer, sin validar previamente su longitud. Cadenas menores a 50 caracteres no provocaran inconvenientes. Un atacante podría introducir datos que contengan código de shell y luego forzar a que lo ejecute en lugar de que vuelva de la función main. El programa anterior podria escribirse de una forma mas segura de cualquiera de las dos variantes siguientes:

Variante 1

#include <stdio.h>
main()
{
      char userinput[50];
      printf("Introduce una cadena: ");
      scanf("%40s", &userinput); /* especificando ancho de campo */
      return 0;
}

Variante 2

#include <stdio.h>
main()
{
      char userinput[50];
      printf("Introduce una cadena: ");
      scanf("%as", &userinput); /* lee una cadena de cualquier longitud */
      return 0;                 /* de forma segura usando la bandera "a" */
}

Historia de abusos

Uno de los primeros aprovechamientos de los que hay registro de desbordamiento de búfers fue en 1988. Fue uno de los muchos que usó el gusano Morris para propagarse en Internet. El programa abusado fue un servicio de Unix llamado fingerd. Más tarde, en 1995, Thomas Lopatic redescubrió en forma independiente el desbordamiento de búfer y publicó sus descubrimientos en la lista de correo sobre seguridad Bugtraq.3 Un año después, en 1996, Elias Levy (conocido también como Aleph One) publicó en la revista Phrack su artículo "Smashing the Stack for Fun and Profit",4 una introducción paso a paso para aprovecharse de vulnerabilidades de desbordamientos de búfer basados en la pila.

Desde entonces, por lo menos dos de los gusanos más importantes de Internet se han aprovechado de los desbordamientos de búfer para comprometer un gran número de sistemas. En 2001, el gusano Code Red se aprovechó de un desbordamiento de búfer en el Internet Information Services (IIS) 5.0 de Microsoft5 y en 2003 el gusano SQL Slammer comprometió máquinas corriendo Microsoft SQL Server 2000.

Stack smashing

El pisado de pila o stack smashing es un tipo de desbordamiento de buffer que es aprovechado por algunos virus y otros programas maliciosos para tomar control sobre una aplicación, o provocar su terminación. Esto sucede cuando, por algún error imprevisto, se ingresa a la pila de la aplicación más datos que los que ésta puede contener, lo que provoca que esta se "desborde" y algunos datos se sobreescriban. Para evitar que suceda esto, los compiladores se mejoran cada día dejándole tiempo al programador para pensar en lo que realmente importa.

Protección contra el desbordamiento de búfer

Para protegerse contra este tipo de ataques, es importante desarrollar aplicaciones que utilicen lenguajes de programación avanzados que garanticen una administración precisa de la memoria asignada o que usen un lenguaje de bajo nivel con bibliotecas de función seguras (por ejemplo, las funciones strncpy()).

Los boletines de alerta se publican con frecuencia y advierten sobre la vulnerabilidad de ciertas aplicaciones a los ataques por desbordamiento de búfer. Después de su publicación, los editores de software afectados por la vulnerabilidad generalmente publican revisiones (patch) para corregir el problema. Es recomendable que todos los administradores de sistema y red se mantengan informados acerca de las alertas de seguridad y que apliquen las revisiones lo antes posible.

Enlaces internos

Enlaces externos