¿Qué es, la Vulnerabilidad File Upload?

Vulnerabilidades de carga de archivos

En esta sección, aprenderá cómo las funciones simples de carga de archivos se pueden usar como un poderoso vector para una serie de ataques de alta gravedad. Le mostraremos cómo eludir los mecanismos de defensa comunes para cargar un shell web, lo que le permitirá tomar el control total de un servidor web vulnerable. Dado lo comunes que son las funciones de carga de archivos, saber cómo probarlas correctamente es un conocimiento esencial.

¿Qué es la Vulnerabilidad de Carga de Archivos?

Las vulnerabilidades de carga de archivos ocurren cuando un servidor web permite a los usuarios cargar archivos en su sistema de archivos sin validar suficientemente cosas como su nombre, tipo, contenido o tamaño. Si no se aplican correctamente las restricciones, podría significar que incluso una función básica de carga de imágenes se puede usar para cargar archivos arbitrarios y potencialmente peligrosos. Esto podría incluso incluir archivos de script del lado del servidor que permitan la ejecución remota de código.

En algunos casos, el acto de cargar el archivo es suficiente para causar daños. Otros ataques pueden implicar una solicitud HTTP de seguimiento del archivo, generalmente para desencadenar su ejecución por parte del servidor.

Detecte más de 7000 vulnerabilidades con el escaneo DAST + IAST combinado

Conocer..

¿Cuál es el impacto de las vulnerabilidades de carga de archivos?

El impacto de las vulnerabilidades de carga de archivos generalmente depende de dos factores clave:

  • Qué aspecto del archivo el sitio web no valida correctamente, ya sea su tamaño, tipo, contenido, etc.
  • Qué restricciones se imponen al archivo una vez que se ha subido correctamente.

En el peor de los casos, el tipo de archivo no se valida correctamente y la configuración del servidor permite que ciertos tipos de archivos (como .php.jsp) se ejecuten como código. En este caso, un atacante podría potencialmente cargar un archivo de código del lado del servidor que funciona como un shell web, otorgándole efectivamente un control total sobre el servidor.

Si el nombre del archivo no se valida correctamente, esto podría permitir que un atacante sobrescriba archivos críticos simplemente cargando un archivo con el mismo nombre. Si el servidor también es vulnerable al cruce de directorios , esto podría significar que los atacantes pueden incluso cargar archivos en ubicaciones no previstas.

No asegurarse de que el tamaño del archivo se encuentre dentro de los umbrales esperados también podría habilitar una forma de ataque de denegación de servicio (DoS), en el que el atacante llena el espacio disponible en el disco.

¿Cómo surgen las vulnerabilidades de carga de archivos?

Dados los peligros bastante obvios, es raro que los sitios web en la naturaleza no tengan restricciones de ningún tipo sobre qué archivos pueden cargar los usuarios. Más comúnmente, los desarrolladores implementan lo que creen que es una validación robusta que es inherentemente defectuosa o que se puede omitir fácilmente.

Por ejemplo, pueden intentar incluir en la lista negra tipos de archivos peligrosos, pero no tener en cuenta las discrepancias de análisis al verificar las extensiones de archivo. Al igual que con cualquier lista negra, también es fácil omitir accidentalmente tipos de archivos más oscuros que aún pueden ser peligrosos.

En otros casos, el sitio web puede intentar verificar el tipo de archivo mediante la verificación de propiedades que un atacante puede manipular fácilmente utilizando herramientas como Burp Proxy o Repeater.

En última instancia, incluso las medidas de validación sólidas pueden aplicarse de manera inconsistente en la red de hosts y directorios que forman el sitio web, lo que genera discrepancias que pueden aprovecharse.

Más adelante en este tema, le enseñaremos cómo aprovechar algunas de estas fallas para cargar un shell web para la ejecución remota de código. Incluso hemos creado algunos laboratorios interactivos y deliberadamente vulnerables para que pueda practicar lo que ha aprendido con algunos objetivos realistas.

¿Cómo manejan los servidores web las solicitudes de archivos estáticos?

Antes de ver cómo explotar las vulnerabilidades de carga de archivos, es importante que tenga un conocimiento básico de cómo los servidores manejan las solicitudes de archivos estáticos.

Históricamente, los sitios web consistían casi en su totalidad en archivos estáticos que se entregaban a los usuarios cuando lo solicitaban. Como resultado, la ruta de cada solicitud podría mapearse 1:1 con la jerarquía de directorios y archivos en el sistema de archivos del servidor. Hoy en día, los sitios web son cada vez más dinámicos y la ruta de una solicitud a menudo no tiene ninguna relación directa con el sistema de archivos. Sin embargo, los servidores web aún se ocupan de las solicitudes de algunos archivos estáticos, incluidas hojas de estilo, imágenes, etc.

El proceso para manejar estos archivos estáticos sigue siendo prácticamente el mismo. En algún momento, el servidor analiza la ruta en la solicitud para identificar la extensión del archivo. Luego usa esto para determinar el tipo de archivo que se solicita, generalmente comparándolo con una lista de asignaciones preconfiguradas entre extensiones y tipos MIME. Lo que sucede a continuación depende del tipo de archivo y la configuración del servidor.

  • Si este tipo de archivo no es ejecutable, como una imagen o una página HTML estática, el servidor puede simplemente enviar el contenido del archivo al cliente en una respuesta HTTP.
  • Si el tipo de archivo es ejecutable, como un archivo PHP, y el servidor está configurado para ejecutar archivos de este tipo, asignará variables según los encabezados y parámetros en la solicitud HTTP antes de ejecutar el script. La salida resultante se puede enviar al cliente en una respuesta HTTP.
  • Si el tipo de archivo es ejecutable, pero el servidor no está configurado para ejecutar archivos de este tipo, generalmente responderá con un error. Sin embargo, en algunos casos, el contenido del archivo aún se puede entregar al cliente como texto sin formato. Tales configuraciones incorrectas pueden explotarse ocasionalmente para filtrar el código fuente y otra información confidencial. Puede ver un ejemplo de esto en nuestros materiales de aprendizaje sobre divulgación de información.

Consejo
El "Content-Type" encabezado de respuesta puede proporcionar pistas sobre qué tipo de archivo cree que ha servido el servidor. Si este encabezado no ha sido establecido explícitamente por el código de la aplicación, normalmente contiene el resultado de la asignación de extensión de archivo/tipo MIME.

Ahora que está familiarizado con los conceptos clave, veamos cómo puede explotar potencialmente este tipo de vulnerabilidades.

Solicita una cotización del mejor escaner de vulnerabilidades de sitios web y aplicativos expuestos, con precios por anualidad e intercambio de targets, BURP SUITE ENTERPRISE es el único que lo ofrece, cambia YA!

Cotizar..

Explotación de cargas de archivos sin restricciones para implementar un shell web

Desde una perspectiva de seguridad, el peor escenario posible es cuando un sitio web le permite cargar secuencias de comandos del lado del servidor, como archivos PHP, Java o Python, y también está configurado para ejecutarlos como código. Esto hace que sea trivial crear su propio shell web en el servidor.

Web shell
Un Web shell es un script malicioso que permite a un atacante ejecutar comandos arbitrarios en un servidor web remoto simplemente enviando solicitudes HTTP al punto final correcto.

Si puede cargar con éxito un shell web, efectivamente tiene control total sobre el servidor. Esto significa que puede leer y escribir archivos arbitrarios, filtrar datos confidenciales e incluso utilizar el servidor para realizar ataques contra la infraestructura interna y otros servidores fuera de la red. Por ejemplo, la siguiente línea de PHP podría usarse para leer archivos arbitrarios del sistema de archivos del servidor:

<?php echo file_get_contents('/path/to/target/file'); ?>

Una vez cargado, el envío de una solicitud de este archivo malicioso devolverá el contenido del archivo de destino en la respuesta.

Un shell web más versátil puede verse así:

<?php echo system($_GET['command']); ?>

Este script le permite pasar un comando de sistema arbitrario a través de un parámetro de consulta de la siguiente manera:

GET /example/exploit.php?command=id HTTP/1.1

Explotación de la validación defectuosa de las cargas de archivos

En la naturaleza, es poco probable que encuentre un sitio web que no tenga protección alguna contra los ataques de carga de archivos como vimos en el laboratorio anterior. Pero el hecho de que las defensas estén en su lugar no significa que sean sólidas.

En esta sección, veremos algunas formas en que los servidores web intentan validar y desinfectar las cargas de archivos, así como también cómo puede explotar fallas en estos mecanismos para obtener un shell web para la ejecución remota de código.

Validación de tipo de archivo defectuoso

Al enviar formularios HTML, el navegador normalmente envía los datos proporcionados en una POST solicitud con el tipo de contenido application/x-www-form-url-encoded. Esto está bien para enviar texto simple como su nombre, dirección, etc., pero no es adecuado para enviar grandes cantidades de datos binarios, como un archivo de imagen completo o un documento PDF. En este caso, el tipo de contenido multipart/form-data es el enfoque preferido.

Considere un formulario que contenga campos para cargar una imagen, proporcione una descripción e ingrese su nombre de usuario. Enviar dicho formulario podría resultar en una solicitud similar a esta:

POST /images HTTP/1.1 Host: normal-website.com Content-Length: 12345 Content-Type: multipart/form-data; boundary=---------------------------012345678901234567890123456---------------------------012345678901234567890123456 Content-Disposition: form-data; name="image"; filename="example.jpg" Content-Type: image/jpeg[...binary content of example.jpg...]---------------------------012345678901234567890123456 Content-Disposition: form-data; name="description"This is an interesting description of my image.---------------------------012345678901234567890123456 Content-Disposition: form-data; name="username"wiener ---------------------------012345678901234567890123456--

Como puede ver, el cuerpo del mensaje se divide en partes separadas para cada una de las entradas del formulario. Cada parte contiene un Content-Disposition encabezado, que proporciona información básica sobre el campo de entrada con el que se relaciona. Estas partes individuales también pueden contener su propio Content-Type encabezado, que le dice al servidor el tipo MIME de los datos que se enviaron usando esta entrada.

Una forma en que los sitios web pueden intentar validar las cargas de archivos es verificar que este Content-Type encabezado específico de entrada coincida con un tipo MIME esperado. Si el servidor solo espera archivos de imagen, por ejemplo, es posible que solo permita tipos como image/jpegimage/png. Pueden surgir problemas cuando el servidor confía implícitamente en el valor de este encabezado. Si no se realiza una validación adicional para verificar si el contenido del archivo realmente coincide con el supuesto tipo MIME, esta defensa se puede eludir fácilmente con herramientas como Burp Repeater.

Prevención de la ejecución de archivos en directorios accesibles para el usuario

Si bien es claramente mejor evitar que se carguen tipos de archivos peligrosos en primer lugar, la segunda línea de defensa es evitar que el servidor ejecute cualquier script que se escape de la red.

Como precaución, los servidores generalmente solo ejecutan secuencias de comandos cuyo tipo MIME se ha configurado explícitamente para ejecutar. De lo contrario, pueden devolver algún tipo de mensaje de error o, en algunos casos, mostrar el contenido del archivo como texto sin formato:

GET /static/exploit.php?command=id HTTP/1.1 Host: normal-website.comHTTP/1.1 200 OK Content-Type: text/plain Content-Length: 39<?php echo system($_GET['command']); ?>

Este comportamiento es potencialmente interesante por derecho propio, ya que puede proporcionar una forma de filtrar el código fuente, pero anula cualquier intento de crear un shell web.

Este tipo de configuración a menudo difiere entre directorios. Es probable que un directorio en el que se cargan los archivos proporcionados por el usuario tenga controles mucho más estrictos que otras ubicaciones en el sistema de archivos que se supone que están fuera del alcance de los usuarios finales. Si puede encontrar una manera de cargar una secuencia de comandos en un directorio diferente que se supone que no debe contener archivos proporcionados por el usuario, el servidor puede ejecutar su secuencia de comandos después de todo.

Consejo
Los servidores web a menudo usan el filenamecampo en multipart/form-datalas solicitudes para determinar el nombre y la ubicación donde se debe guardar el archivo.

También debe tener en cuenta que, aunque puede enviar todas sus solicitudes al mismo nombre de dominio, esto a menudo apunta a algún tipo de servidor proxy inverso, como un equilibrador de carga. Sus solicitudes a menudo serán manejadas por servidores adicionales detrás de escena, que también pueden configurarse de manera diferente.

Lista negra insuficiente de tipos de archivos peligrosos

Una de las formas más obvias de evitar que los usuarios carguen scripts maliciosos es incluir en la lista negra las extensiones de archivo potencialmente peligrosas como .php. La práctica de las listas negras es inherentemente defectuosa, ya que es difícil bloquear explícitamente todas las extensiones de archivo posibles que podrían usarse para ejecutar código. Estas listas negras a veces se pueden omitir mediante el uso de extensiones de archivo alternativas menos conocidas que aún pueden ser ejecutables, como .php5.shtml, etc.

Anulando la configuración del servidor

Como discutimos en la sección anterior, los servidores normalmente no ejecutarán archivos a menos que hayan sido configurados para hacerlo. Por ejemplo, antes de que un servidor Apache ejecute archivos PHP solicitados por un cliente, es posible que los desarrolladores deban agregar las siguientes directivas a su /etc/apache2/apache2.conf archivo:

LoadModule php_module /usr/lib/apache2/modules/libphp.so AddType application/x-httpd-php .php

Muchos servidores también permiten a los desarrolladores crear archivos de configuración especiales dentro de directorios individuales para anular o agregar una o más configuraciones globales. Los servidores Apache, por ejemplo, cargarán una configuración específica de directorio desde un archivo llamado .htaccess si hay uno presente.

De manera similar, los desarrolladores pueden realizar configuraciones específicas de directorios en servidores IIS utilizando un web.config archivo. Esto podría incluir directivas como las siguientes, que en este caso permiten que los archivos JSON se sirvan a los usuarios:

<staticContent> <mimeMap fileExtension=".json" mimeType="application/json" /> </staticContent>

Los servidores web usan este tipo de archivos de configuración cuando están presentes, pero normalmente no se le permite acceder a ellos mediante solicitudes HTTP. Sin embargo, es posible que ocasionalmente encuentre servidores que no le impidan cargar su propio archivo de configuración malicioso. En este caso, incluso si la extensión de archivo que necesita está en la lista negra, es posible que pueda engañar al servidor para que asigne una extensión de archivo personalizada y arbitraria a un tipo MIME ejecutable.

Solicita una cotización del mejor escaner de vulnerabilidades de sitios web y aplicativos expuestos, con precios por anualidad e intercambio de targets, BURP SUITE ENTERPRISE es el único que lo ofrece, cambia YA!

Cotizar..

Ofuscar las extensiones de archivo

Incluso las listas negras más exhaustivas pueden pasarse por alto utilizando técnicas de ofuscación clásicas. Digamos que el código de validación distingue entre mayúsculas y minúsculas y no reconoce que exploit.pHp, de hecho, es un .php archivo. Si el código que posteriormente asigna la extensión de archivo a un tipo MIME no distingue entre mayúsculas y minúsculas, esta discrepancia le permite colar archivos PHP maliciosos más allá de la validación que eventualmente puede ejecutar el servidor.

También puede lograr resultados similares utilizando las siguientes técnicas:

  • Proporcione múltiples extensiones. Según el algoritmo utilizado para analizar el nombre del archivo, el siguiente archivo puede interpretarse como un archivo PHP o una imagen JPG:exploit.php.jpg
  • Agregar caracteres finales. Algunos componentes eliminarán o ignorarán los espacios en blanco finales, los puntos y similares:exploit.php.
  • Intente usar la codificación de URL (o codificación de URL doble) para puntos, barras inclinadas y barras inclinadas hacia atrás. Si el valor no se decodifica al validar la extensión del archivo, pero luego se decodifica en el lado del servidor, esto también puede permitirle cargar archivos maliciosos que de otro modo serían bloqueados:exploit%2Ephp
  • Agregue punto y coma o caracteres de bytes nulos codificados en URL antes de la extensión del archivo. Si la validación está escrita en un lenguaje de alto nivel como PHP o Java, pero el servidor procesa el archivo usando funciones de nivel inferior en C/C++, por ejemplo, esto puede causar discrepancias en lo que se trata como el final del nombre del archivo: exploit.asp;.jpg o exploit.asp%00.jpg
  • Intente usar caracteres Unicode de varios bytes, que pueden convertirse en bytes nulos y puntos después de la conversión o normalización de Unicode. Secuencias como xC0 x2ExC4 xAExC0 xAE pueden traducirse a x2Esi el nombre de archivo se analizó como una cadena UTF-8, pero luego se convirtió a caracteres ASCII antes de usarse en una ruta.

Otras defensas implican eliminar o reemplazar extensiones peligrosas para evitar que se ejecute el archivo. Si esta transformación no se aplica de forma recursiva, puede colocar la cadena prohibida de tal manera que al eliminarla aún quede una extensión de archivo válida. Por ejemplo, considere lo que sucede si elimina .php el siguiente nombre de archivo:

exploit.p.phphp

Esta es solo una pequeña selección de las muchas formas en que es posible ofuscar las extensiones de archivo.

Validación defectuosa del contenido del archivo.

En lugar de confiar implícitamente en lo Content-Type especificado en una solicitud, los servidores más seguros intentan verificar que el contenido del archivo realmente coincida con lo esperado.

En el caso de una función de carga de imágenes, el servidor podría intentar verificar ciertas propiedades intrínsecas de una imagen, como sus dimensiones. Si intenta cargar un script PHP, por ejemplo, no tendrá ninguna dimensión. Por lo tanto, el servidor puede deducir que no puede ser una imagen y rechazar la carga en consecuencia.

De manera similar, ciertos tipos de archivos siempre pueden contener una secuencia específica de bytes en su encabezado o pie de página. Estos se pueden usar como una huella digital o una firma para determinar si el contenido coincide con el tipo esperado. Por ejemplo, los archivos JPEG siempre comienzan con los bytes FF D8 FF.

Esta es una forma mucho más sólida de validar el tipo de archivo, pero incluso esto no es infalible. Usando herramientas especiales, como ExifTool, puede ser trivial crear un archivo JPEG políglota que contenga código malicioso dentro de sus metadatos.

Explotación de las condiciones de carrera de carga de archivos

Los marcos modernos están más endurecidos contra este tipo de ataques. Por lo general, no suben archivos directamente a su destino previsto en el sistema de archivos. En su lugar, toman precauciones como subir primero a un directorio temporal en un espacio aislado y aleatorizar el nombre para evitar sobrescribir los archivos existentes. Luego realizan la validación de este archivo temporal y solo lo transfieren a su destino una vez que se considera seguro hacerlo.

Dicho esto, los desarrolladores a veces implementan su propio procesamiento de carga de archivos independientemente de cualquier marco. No solo es bastante complejo hacerlo bien, sino que también puede introducir condiciones de carrera peligrosas que permiten a un atacante eludir por completo incluso la validación más robusta.

Por ejemplo, algunos sitios web cargan el archivo directamente en el sistema de archivos principal y luego lo eliminan nuevamente si no pasa la validación. Este tipo de comportamiento es típico en sitios web que dependen de software antivirus y similares para buscar malware. Esto puede tomar solo unos pocos milisegundos, pero durante el breve tiempo que el archivo existe en el servidor, el atacante aún puede ejecutarlo.

Estas vulnerabilidades suelen ser extremadamente sutiles, lo que las hace difíciles de detectar durante las pruebas de caja negra, a menos que pueda encontrar una manera de filtrar el código fuente relevante.

Condiciones de carrera en cargas de archivos basadas en URL

Pueden ocurrir condiciones de carrera similares en funciones que le permiten cargar un archivo al proporcionar una URL. En este caso, el servidor tiene que obtener el archivo a través de Internet y crear una copia local antes de poder realizar cualquier validación.

Como el archivo se carga mediante HTTP, los desarrolladores no pueden utilizar los mecanismos integrados de su marco para validar archivos de forma segura. En cambio, pueden crear manualmente sus propios procesos para almacenar y validar temporalmente el archivo, lo que puede no ser tan seguro.

Por ejemplo, si el archivo se carga en un directorio temporal con un nombre aleatorio, en teoría, debería ser imposible que un atacante aproveche las condiciones de carrera. Si no conocen el nombre del directorio, no podrán solicitar el archivo para activar su ejecución. Por otro lado, si el nombre del directorio aleatorio se genera utilizando funciones pseudoaleatorias como las de PHP uniqid(), puede ser potencialmente forzado.

Para facilitar ataques como este, puede intentar ampliar la cantidad de tiempo necesario para procesar el archivo, lo que alarga la ventana para forzar el nombre del directorio. Una forma de hacerlo es cargando un archivo más grande. Si se procesa en fragmentos, puede aprovechar potencialmente esto creando un archivo malicioso con la carga útil al principio, seguido de una gran cantidad de bytes de relleno arbitrarios.

Explotación de vulnerabilidades de carga de archivos sin ejecución remota de código

En los ejemplos que hemos visto hasta ahora, hemos podido cargar scripts del lado del servidor para la ejecución remota de código. Esta es la consecuencia más grave de una función de carga de archivos insegura, pero estas vulnerabilidades aún pueden explotarse de otras maneras.

Subir scripts maliciosos del lado del cliente

Aunque es posible que no pueda ejecutar secuencias de comandos en el servidor, aún puede cargar secuencias de comandos para ataques del lado del cliente. Por ejemplo, si puede cargar archivos HTML o imágenes SVG, puede usar <script> etiquetas para crear cargas útiles XSS almacenadas .

Si el archivo cargado luego aparece en una página que es visitada por otros usuarios, su navegador ejecutará el script cuando intente mostrar la página. Tenga en cuenta que, debido a las restricciones de la política del mismo origen , este tipo de ataques solo funcionarán si el archivo cargado se sirve desde el mismo origen en el que lo cargó.

Explotación de vulnerabilidades en el análisis de archivos cargados

Si el archivo cargado parece estar almacenado y servido de forma segura, el último recurso es intentar explotar las vulnerabilidades específicas del análisis o procesamiento de diferentes formatos de archivo. Por ejemplo, sabe que el servidor analiza archivos basados ​​en XML, como Microsoft Office .doc.xls archivos, esto puede ser un vector potencial para ataques de inyección XXE .

Subir archivos usando PUT

Vale la pena señalar que algunos servidores web pueden estar configurados para admitir PUT solicitudes. Si no se cuenta con las defensas adecuadas, esto puede proporcionar un medio alternativo para cargar archivos maliciosos, incluso cuando la función de carga no está disponible a través de la interfaz web.

PUT /images/exploit.php HTTP/1.1 Host: vulnerable-website.com Content-Type: application/x-httpd-php Content-Length: 49<?php echo file_get_contents('/path/to/file'); ?>

Consejo
Puede intentar enviar "OPTIONS" solicitudes a diferentes puntos finales para probar cualquiera que anuncie soporte para el método "PUT".

Cómo prevenir vulnerabilidades de carga de archivos

Permitir que los usuarios carguen archivos es un lugar común y no tiene por qué ser peligroso siempre que tome las precauciones adecuadas. En general, la forma más efectiva de proteger sus propios sitios web de estas vulnerabilidades es implementar todas las siguientes prácticas:

  • Verifique la extensión del archivo con una lista blanca de extensiones permitidas en lugar de una lista negra de extensiones prohibidas. Es mucho más fácil adivinar qué extensiones podría querer permitir que adivinar cuáles podría intentar cargar un atacante.
  • Asegúrese de que el nombre del archivo no contenga subcadenas que puedan interpretarse como un directorio o una secuencia transversal ( ../).
  • Cambie el nombre de los archivos cargados para evitar colisiones que pueden hacer que se sobrescriban los archivos existentes.
  • No cargue archivos en el sistema de archivos permanente del servidor hasta que hayan sido completamente validados.
  • En la medida de lo posible, utilice un marco establecido para preprocesar las cargas de archivos en lugar de intentar escribir sus propios mecanismos de validación.

Si te ha gustado, ¡compártelo con tus amigos!

Scroll al inicio

Portal de Clientes