Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Hacking uploaders

735 views

Published on

Se propone montar algunos entornos donde se demuestre que funcionan bien o mal este tipo de filtros.

  • Be the first to comment

  • Be the first to like this

Hacking uploaders

  1. 1. Hacking Uploaders Securizar Uploaders en Aplicaciones Web Linenoise
  2. 2. Índice <ul><li>Uploaders State-of-the-art </li></ul><ul><li>Content-type </li></ul><ul><li>Verificación de contenido del archivo de imagen </li></ul><ul><li>Verificación de extensiones </li></ul><ul><li>Acceso indirecto a ficheros </li></ul><ul><li>Inclusión local de ficheros </li></ul><ul><li>Otras consideraciones </li></ul>
  3. 3. Uploaders State-of-the-art
  4. 4. Uploaders State-of-the-art <ul><li>Las aplicaciones Web permiten a los usuarios subir ficheros. </li></ul><ul><li>Los foros permiten a los usuarios subir avatares. </li></ul><ul><li>Las galerías de imágenes permiten subir fotos. </li></ul><ul><li>Las redes sociales pueden permitir la carga de imágenes, videos, etc. </li></ul><ul><li>Los blogs permiten subir avatares o fotos. </li></ul><ul><li>Muchas intranets permiten la subida indiscriminada de ficheros. </li></ul>
  5. 5.
  6. 6. ¿En qué consiste implementar un Uploader? <ul><li>Basicamente un Uploader consiste en 2 funciones independientes: </li></ul><ul><li>Aceptar ficheros de usuarios. </li></ul><ul><li>Mostrar esos ficheros a usuarios. </li></ul>Implementar funciones de upload puede ser una fuente problemas sino se toman las medidas de seguridad necesarias.
  7. 7. <ul><li>Consideremos este sencillo código: </li></ul><?php $uploaddir = 'uploads/'; $uploadfile = $uploaddir . basename($_FILES['userfile']['name']); if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) { echo &quot;File is valid, and was successfully uploaded.n&quot;; } else { echo &quot;File uploading failed.n&quot;; } ?> Los usuarios recuperaran archivos a traves de la URL: http://www.server.com/uploads/filename.txt
  8. 8. <ul><li>El código anterior ofrece uno de los mayores agujeros de seguridad: Envío de ficheros arbitrarios al servidor Web . </li></ul><ul><li>Cualquier usuario puede subir un fichero, por ejemplo, un shell script que permita ejecutar comandos arbitrarios en el servidor: </li></ul><?php system($_GET[‘command’]); ?> Acto seguido podrá ejecutar comandos a través de la URL: http://www.server.com/shell.php?command=id
  9. 9. Content-Type
  10. 10. ¿Qué es y para que sirve? <ul><li>La cabecera Content-type pertenece al protocolo HTTP. </li></ul><ul><li>Específica la forma en la que quien envía los datos (normalmente el servidor) le pueda decir a quien los recibe (el navegador, por lo general) que tipo de datos se están envíando. </li></ul><ul><li>Utiliza identificadores de tipo y subtipo, facilitando información auxiliar en caso de ser necesario. </li></ul><ul><li>Los tipos de contenido están 'normalizados' para que sirvan como deben, por ejemplo, los formatos basados en texto comienzan con text/, los de imágenes con image/, etc. </li></ul><ul><li>Se puede utilizar para comprobar el tipo de fichero que vamos a envíar al servidor. </li></ul>
  11. 11. <ul><li>Observemos el siguiente código: </li></ul><?php if($_FILES['userfile']['type'] != &quot;image/gif&quot;) { echo &quot;Sorry, we only allow uploading GIF images&quot;; exit; } $uploaddir = 'uploads/'; $uploadfile = $uploaddir . basename($_FILES['userfile']['name']); if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) { echo &quot;File is valid, and was successfully uploaded.n&quot;; } else { echo &quot;File uploading failed.n&quot;; } ?>
  12. 12. Verificación de contenido del archivo de imagen
  13. 13. ¿Por qué validar imagenes? <ul><li>Confiar en la cabecera Content-type no es del todo efectivo cuando se trata de ficheros con imagen. </li></ul><ul><li>Muchos formatos de imagen permiten incluir comentarios en sus metadatos (Vease GIF o JPEG). </li></ul><ul><li>Es posible crear un archivo de imagen valido que contenga código arbitrario en los comentarios. </li></ul>
  14. 14. Verificación de extensiones
  15. 15. ¿Qué tienen de interesante las extensiones? <ul><li>Pueden alterarse escribiendo la extensión del archivo alternando mayúsculas/minúsculas: .pHp, PHp, .pHP </li></ul><ul><li>Uso de extensiones menos conocidas: Php5 </li></ul><ul><li>Técnica de la doble extension: .jpeg.php </li></ul><ul><li>Añadir al final del nombre del archivo espacios y/o puntos (shell.php ... ......) </li></ul><ul><li>Usar Null Bytes. </li></ul><ul><li>Incluir caracteres extraños (&quot;;&quot;, &quot;&&quot;, &quot;[&quot;): shell.php;jpeg. </li></ul><ul><li>En determinadas ocasiones dependen de la configuración del servidor. </li></ul><ul><li>El uso de listas negras no soluciona el problema. </li></ul>
  16. 16. <ul><li>Veamos el siguiente código: </li></ul><?php $blacklist = array(&quot;.gif&quot;, &quot;.jpeg&quot;, &quot;.jpg&quot;); foreach ($blacklist as $item) { if(preg_match(&quot;/$item$/i&quot;, $_FILES['userfile']['name'])) { echo &quot;We do not allow uploading IMAGE filesn&quot;; exit; } } $uploaddir = 'uploads/'; $uploadfile = $uploaddir . basename($_FILES['userfile']['name']); if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) { echo &quot;File is valid, and was successfully uploaded.n&quot;; } else { echo &quot;File uploading failed.n&quot;; } ?>
  17. 17. Acceso indirecto a ficheros
  18. 18. ¿Qué implica almacenar archivos fuera del directorio raíz? <ul><li>Para poder subir archivos a través de formularios web es necesario que el sistema de ficheros tenga el directorio habilitado como escritura. </li></ul><ul><li>Es importarte que el servidor web bloquee el resto de accesos al sistema de ficheros para evitar la subida arbitraria de archivos. </li></ul><ul><li>En caso de una débil configuración se permite la navegación trasversal en el servidor permitiendo al usuario leer cualquier tipo de información contenida en el mismo. </li></ul>
  19. 19. <ul><li>En este caso tenemos el siguiente codigo de Upload: </li></ul><?php $uploaddir = '/var/spool/uploads/'; # Outside of web root $uploadfile = $uploaddir . basename($_FILES['userfile']['name']); if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) { echo &quot;File is valid, and was successfully uploaded.n&quot;; } else { echo &quot;File uploading failed.n&quot;; } ?> Y necesitamos de un control visor de imágenes: <?php $uploaddir = '/var/spool/uploads/'; $name = $_GET['name']; readfile($uploaddir.$name); ?>
  20. 20. Inclusión local de ficheros
  21. 21. Posibilidades limitadas <ul><li>La implementación anterior almacena archivos cargados fuera de la raiz web del servidor. </li></ul><ul><li>Estos ficheros no son accesibles directamente y no pueden ejecutarse. </li></ul><ul><li>A pesar de ello, permiten obtener una pequeña ventaja: la inclusión local de ficheros. </li></ul><ul><li>Un atacante puede ser capaz de cargar archivos, incluso fuera de la raíz del servidor web, si conoce el nombre y la ubicación de los mismos. </li></ul><ul><li>Las posibilidades de este ataque son limitadas. </li></ul>
  22. 22. <ul><li>Imaginemos el siguiente código: </li></ul><?php # ... some code here if(isset($_COOKIE['lang'])) { $lang = $_COOKIE['lang']; } elseif (isset($_GET['lang'])) { $lang = $_GET['lang']; } else { $lang = 'english'; } include(&quot;language/$lang.php&quot;); # ... some more code here ?>
  23. 23. <ul><li>Una posible solución al problema: </li></ul><ul><li>Impedir que un atacante conozca el nombre y ubicación del archivo. </li></ul><ul><li>¿Cómo? Realizando una generación aleatoria de nombres de archivo mediante un seguimiento de los mismos en Base de Datos. </li></ul><ul><li>Estos archivos al subirse no se pueden solicitar ni ejecutar directamente y además desconocemos el nombre que le asigna el sistema al archivo. </li></ul><ul><li>Mediante esta técnica solucionamos el problema de directorio transversal y de inclusión local de ficheros, ya que los archivos hacen referencia a un índice númerico en Base de Datos. </li></ul><ul><li>Remarcar que el uso de Base de Datos implica securizar las consultas SQL que se realizan a la misma. </li></ul>
  24. 24. Otras consideraciones
  25. 25. Denegación de servicio <ul><li>La carga de gran cantidad de archivos de gran tamaño puede consumir todo el espacio disponible en disco. </li></ul><ul><li>Una buena contramedida es limitar el tamaño y número de archivos que un usuario puede cargar durante un período determinado de tiempo. </li></ul>Rendimiento <ul><li>Los visores de archivos pueden ser un cuello de botella en el rendimiento del servidor si son vistos a menudo. </li></ul><ul><li>Una buena solución es crear un segundo servidor alternativo y copiar los archivos subidos para que sean servidos desde allí directamente. </li></ul><ul><li>Otra posible solución es utilizar un proxy frontal al servidor que pueda almacenar caché de los archivos. </li></ul>
  26. 26. Control de acceso <ul><li>En los supuestos que hemos contemplado se supone que todo el mundo puede ver cualquiera de los archivos subidos. </li></ul><ul><li>Sin embargo, en determinadas ocasiones se puede requerir que sólo el usuario que ha subido el archivo pueda verlo. </li></ul><ul><li>Una posible solución a esta casuística es generar una tabla de archivos que contiene la información sobre propiedades del archivo, con el fin de verificar si el usuario que lo solicita es el propietario. </li></ul>
  27. 27. ¿Preguntas? ¡Muchas gracias! Mario López Jiménez

×