Hacking uploaders

27
Hacking Uploaders Securizar Uploaders en Aplicaciones Web Linenoise

description

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

Transcript of Hacking uploaders

Page 1: Hacking uploaders

Hacking UploadersSecurizar Uploaders en Aplicaciones Web

Linenoise

Page 2: Hacking uploaders

Índice

Uploaders State-of-the-art

Content-type

Verificación de contenido del archivo de imagen

Verificación de extensiones

Acceso indirecto a ficheros

Inclusión local de ficheros

Otras consideraciones

Page 3: Hacking uploaders

Uploaders State-of-the-art

Page 4: Hacking uploaders

Uploaders State-of-the-art

Las aplicaciones Web permiten a los usuarios subir ficheros.

Los foros permiten a los usuarios subir avatares.

Las galerías de imágenes permiten subir fotos.

Las redes sociales pueden permitir la carga de imágenes, videos, etc.

Los blogs permiten subir avatares o fotos.

Muchas intranets permiten la subida indiscriminada de ficheros.

Page 5: Hacking uploaders

5

Page 6: Hacking uploaders

¿En qué consiste implementar un Uploader?

Basicamente un Uploader consiste en 2 funciones independientes:

1. Aceptar ficheros de usuarios.

2. Mostrar esos ficheros a usuarios.

Implementar funciones de upload puede ser una fuente problemas sino se toman las medidas de seguridad necesarias.

Page 7: Hacking uploaders

Consideremos este sencillo código:

<?php

$uploaddir = 'uploads/';

$uploadfile = $uploaddir . basename($_FILES['userfile']['name']);

if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) {

echo "File is valid, and was successfully uploaded.\n";

} else {

echo "File uploading failed.\n";

}

?>

Los usuarios recuperaran archivos a traves de la URL:

http://www.server.com/uploads/filename.txt

Page 8: Hacking uploaders

El código anterior ofrece uno de los mayores agujeros de seguridad: Envío de ficheros arbitrarios al servidor Web.

Cualquier usuario puede subir un fichero, por ejemplo, un shell script que permita ejecutar comandos arbitrarios en el servidor:

<?php

system($_GET[‘command’]);

?>

Acto seguido podrá ejecutar comandos a través de la URL:

http://www.server.com/shell.php?command=id

Page 9: Hacking uploaders

Content-Type

Page 10: Hacking uploaders

¿Qué es y para que sirve?

La cabecera Content-type pertenece al protocolo HTTP.

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.

Utiliza identificadores de tipo y subtipo, facilitando información auxiliar en caso de ser necesario.

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.

Se puede utilizar para comprobar el tipo de fichero que vamos a envíar al servidor.

Page 11: Hacking uploaders

Observemos el siguiente código:

<?php

if($_FILES['userfile']['type'] != "image/gif") {

echo "Sorry, we only allow uploading GIF images";

exit;

}

$uploaddir = 'uploads/';

$uploadfile = $uploaddir . basename($_FILES['userfile']['name']);

if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) {

echo "File is valid, and was successfully uploaded.\n";

} else {

echo "File uploading failed.\n";

}

?>

Page 12: Hacking uploaders

Verificación de contenido del archivo de imagen

Page 13: Hacking uploaders

¿Por qué validar imagenes?

Confiar en la cabecera Content-type no es del todo efectivo cuando se trata de ficheros con imagen.

Muchos formatos de imagen permiten incluir comentarios en sus metadatos (Vease GIF o JPEG).

Es posible crear un archivo de imagen valido que contenga código arbitrario en los comentarios.

Page 14: Hacking uploaders

Verificación de extensiones

Page 15: Hacking uploaders

¿Qué tienen de interesante las extensiones? Pueden alterarse escribiendo la extensión del archivo alternando mayúsculas/minúsculas: .pHp, PHp, .pHP

Uso de extensiones menos conocidas: Php5

Técnica de la doble extension: .jpeg.php

Añadir al final del nombre del archivo espacios y/o puntos (shell.php ... ......)

Usar Null Bytes.

Incluir caracteres extraños (";", "&", "["): shell.php;jpeg.

En determinadas ocasiones dependen de la configuración del servidor.

El uso de listas negras no soluciona el problema.

Page 16: Hacking uploaders

Veamos el siguiente código:<?php

$blacklist = array(".gif", ".jpeg", ".jpg");

foreach ($blacklist as $item) {

if(preg_match("/$item\$/i", $_FILES['userfile']['name'])) {

echo "We do not allow uploading IMAGE files\n";

exit;

}

}

$uploaddir = 'uploads/';

$uploadfile = $uploaddir . basename($_FILES['userfile']['name']);

if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) {

echo "File is valid, and was successfully uploaded.\n";

} else {

echo "File uploading failed.\n";

}

?>

Page 17: Hacking uploaders

Acceso indirecto a ficheros

Page 18: Hacking uploaders

¿Qué implica almacenar archivos fuera del directorio raíz?

Para poder subir archivos a través de formularios web es necesario que el sistema de ficheros tenga el directorio habilitado como escritura.

Es importarte que el servidor web bloquee el resto de accesos al sistema de ficheros para evitar la subida arbitraria de archivos.

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.

Page 19: Hacking uploaders

En este caso tenemos el siguiente codigo de Upload:<?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 "File is valid, and was successfully uploaded.\n";

} else {

echo "File uploading failed.\n";

}

?>

Y necesitamos de un control visor de imágenes:<?php

$uploaddir = '/var/spool/uploads/';

$name = $_GET['name'];

readfile($uploaddir.$name);

?>

Page 20: Hacking uploaders

Inclusión local de ficheros

Page 21: Hacking uploaders

Posibilidades limitadas

La implementación anterior almacena archivos cargados fuera de la raiz web del servidor.

Estos ficheros no son accesibles directamente y no pueden ejecutarse.

A pesar de ello, permiten obtener una pequeña ventaja: la inclusión local de ficheros.

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.

Las posibilidades de este ataque son limitadas.

Page 22: Hacking uploaders

Imaginemos el siguiente código:<?php

# ... some code here

if(isset($_COOKIE['lang'])) {

$lang = $_COOKIE['lang'];

} elseif (isset($_GET['lang'])) {

$lang = $_GET['lang'];

} else {

$lang = 'english';

}

include("language/$lang.php");

# ... some more code here

?>

Page 23: Hacking uploaders

Una posible solución al problema:

Impedir que un atacante conozca el nombre y ubicación del archivo.

¿Cómo? Realizando una generación aleatoria de nombres de archivo mediante un seguimiento de los mismos en Base de Datos.

Estos archivos al subirse no se pueden solicitar ni ejecutar directamente y además desconocemos el nombre que le asigna el sistema al archivo.

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.

Remarcar que el uso de Base de Datos implica securizar las consultas SQL que se realizan a la misma.

Page 24: Hacking uploaders

Otras consideraciones

Page 25: Hacking uploaders

Denegación de servicio

La carga de gran cantidad de archivos de gran tamaño puede consumir todo el espacio disponible en disco.

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.

Rendimiento Los visores de archivos pueden ser un cuello de botella en el rendimiento

del servidor si son vistos a menudo.

Una buena solución es crear un segundo servidor alternativo y copiar los archivos subidos para que sean servidos desde allí directamente.

Otra posible solución es utilizar un proxy frontal al servidor que pueda almacenar caché de los archivos.

Page 26: Hacking uploaders

Control de acceso En los supuestos que hemos contemplado se supone que todo el mundo puede ver cualquiera de los

archivos subidos.

Sin embargo, en determinadas ocasiones se puede requerir que sólo el usuario que ha subido el archivo pueda verlo.

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.

Page 27: Hacking uploaders

¿Preguntas?

¡Muchas gracias!

Mario López Jiménez