¿Cambiar la extensión de archivo de un ejecutable cargado a .png lo hace seguro?

34

Un colega mío tiene un sitio web personal en el que permite a los usuarios cargar cualquier cosa dentro de un tamaño determinado,

pero antes de la carga real, comprueba para ver la extensión del archivo:

if ( $type == 'image/gif'){
  $ext = '.gif';
} elseif ( $type == 'image/jpeg'){
  $ext = '.jpg';
} elseif ( $type == 'image/png' ){
  $ext= '.png';
}  else {
  $ext = '.png';  
}

Me dice, que al hacer que todas las imágenes de los archivos no causen ningún daño al servidor.

por ejemplo:

  evilscript.evil

se convertiría en:

evilscript.png

Y por lo tanto, se vuelven inútiles. ¿Hay algo de verdad en sus afirmaciones?

    
pregunta Peter verleg 09.08.2016 - 12:09
fuente

5 respuestas

49

Básicamente, hay dos formas principales en que un archivo cargado puede ser dañino: al ejecutarse (como un script o binario) o al ejecutarse / usarse en una aplicación y abusar de un exploit en él (por ejemplo, un MP3 cargado que luego se abre por un jugador específico, abusando de una debilidad conocida en él).

En otras palabras, todo depende de lo que pase con el archivo después de cargarlo. Si alguien puede cargar una secuencia de comandos Perl, pero el servidor nunca ejecuta los archivos cargados o incluso no tiene Perl instalado, nunca podrá suceder nada. En general: si se asegura de que el archivo cargado nunca se ejecute o interprete, estará seguro.

Cambiar el nombre de los archivos solo ayuda con una cosa: en algunos sistemas operativos, algunas extensiones de archivos pueden estar vinculadas con una aplicación específica. Si cambia el nombre del archivo, puede evitar que el archivo se abra con una aplicación vinculada. Pero dependiendo del sistema y la configuración, los archivos cargados aún podrían abrirse con una aplicación vulnerable. Para permanecer en el ejemplo anterior: si algún archivo cargado se abre con un reproductor de MP3, incluso si le cambia el nombre a song.png , aún podría explotar una debilidad en el reproductor (excepto si el jugador tiene su propia capa de comprobando y, por ejemplo, solo acepta archivos .mp3 ).

Los archivos renombrados no son imágenes de repente, solo por el cambio de nombre. En Unix y sistemas similares, existe incluso el comando file para analizar el tipo / tipo MIME de un archivo.

Conclusión: en mis ojos solo hay una cosa que puedes hacer. Sea muy específico en su configuración acerca de lo que puede y se hará con los archivos cargados. Cualquier biblioteca, extensión o aplicación que acepte estos archivos siempre debe actualizarse a la última versión.

    
respondido por el Draugr 09.08.2016 - 12:28
fuente
12

No. Cambiar el nombre de un archivo no aumenta la seguridad.

  

Me dice que al hacer que todas las imágenes de los archivos no se puedan hacer daño al servidor.

     

por ejemplo, evilscript.evil se convertiría en evilscript.png

Cuando cambia el nombre de evilscript.evil a evilscript.png , no lo convierte en una imagen. Acaba de cambiar su nombre. En general, un nombre de archivo no es relevante. Es solo un nombre dado a un bloque de datos, nada más.

Si puedes ejecutar un script cargado, probablemente puedas hacerlo independientemente de su nombre. Si no puede, cargar un script malicioso no daña el sistema, ya que el script no se ejecutará de todos modos.

Sin embargo, puede evitar que un archivo se ejecute accidentalmente. La única protección que el cambio de nombre podría proporcionar es la protección contra el lanzamiento accidental de Windows (o un shell que utiliza de manera similar las extensiones de archivo). Entonces, cambiar el nombre de virus.exe a virus.exe~ realmente ayuda, cuando accidentalmente tocas Enter en él.

Los shells de Unix usan formatos de archivo en lugar de extensiones. Como ejemplo, puede guardar un script como evilscript.png y ejecutarlo con un shell de Linux, siempre que el archivo tenga el permiso de "ejecutar". En términos de seguridad, generalmente es mejor controlar los permisos de los archivos en lugar de los nombres de los archivos.

    
respondido por el enkryptor 09.08.2016 - 19:41
fuente
2

Comprobar la única extensión de un archivo cargado no es suficiente. Ej .: verifique la respuesta en esta pregunta .

Una propuesta: hay una manera más confiable de averiguar el tipo de archivo. Si su amigo está ejecutando el servidor en una máquina Unix, puede usar el comando ' file ' que inspecciona el contenido del archivo para determinar el formato.

    
respondido por el George Gkitsas 09.08.2016 - 12:32
fuente
2

Hay dos problemas: proteger contra ataques directos en el servidor y proteger contra ataques a otros clientes (lo que a su vez puede provocar ataques en el servidor)

Primero el servidor, cuando un cliente solicita un archivo, el servidor tiene que decidir si lo sirve o lo ejecuta de alguna manera. Esta decisión puede depender de varios factores, entre ellos.

  1. La extensión de archivo
  2. El directorio donde se encuentra el archivo
  3. Si el bit ejecutable está establecido.

No tengo conocimiento de que ningún servidor web realice una inspección de contenido en el lado del servidor, pero no puedo descartar que exista uno.

Lo ideal es que en el servidor no coloque los archivos provistos por el usuario en un directorio donde se permita la ejecución del script en primer lugar, pero restringir la extensión del archivo es probablemente una política sensata de "defensa en profundidad" en caso de que un archivo termine inadvertidamente en el lugar equivocado.

Si el servidor decide servir el archivo, debe decidir qué tipo de mime enviar. Los servidores de Afaict suelen elegir el tipo mime en función de la extensión del archivo. El cliente debe decidir qué hacer con el archivo. Debería basarse en el tipo de mime enviado por el servidor, pero en la práctica puede basarse en la extensión del archivo o en la inspección del contenido del mismo,

Si el navegador elige tratar el archivo como un tipo que puede involucrar secuencias de comandos del lado del cliente, entonces el dominio desde el cual se sirve el archivo se vuelve importante. Si el archivo se sirve desde su dominio principal, entonces es probable que el script pueda leer las cookies que configuró y usarlas para hacerse pasar por el usuario.

Creo que una restricción de extensión de archivo debe ser parte de la estrategia de seguridad, pero no debe ser toda. El almacenamiento en directorios que prohíben la ejecución de secuencias de comandos, la aplicación de la extensión de concordancia de contenidos y el uso de un nombre de dominio separado deben considerarse como parte de la estrategia de defensa general.

    
respondido por el Peter Green 10.08.2016 - 14:14
fuente
1

Esto es seguro.

Uno siempre puede contrabandear código ejecutable dentro de una imagen:

  • Simplemente cargue su código PHP con otra extensión.
  • Póngalo en metadatos, como EXIF.
  • Use píxeles específicamente coloreados de modo que su representación binaria sea su código PHP deseado, que sobrevivirá a la recodificación (en realidad lo vi en la vida real, explotado usando: enlace ).

Por lo tanto, ya debe asumir que los contenidos de su archivo no son seguros cuando son suministrados por el usuario. Incluso si vuelve a codificar la imagen, e incluso si convierte formatos, es todavía una imagen, así que no la ejecute con sangre . Si su servidor web (como Apache o Nginx) lo ejecuta a través del intérprete de PHP, entonces alguien encontrará una manera de hacer que PHP haga algo desagradable. Al obligar a la extensión a ser una de las pocas extensiones incluidas en la lista blanca, puede decirle a su servidor web que es una imagen (no ejecutable) y que no debe pasar por el intérprete.

Hay, por supuesto, algunos riesgos relacionados a tener en cuenta:

  • Su usuario podría poner bytes nulos u otras cosas divertidas en el nombre del archivo, lo que podría permitirles elegir su extensión después de todo.
  • Su usuario podría tratar de usar el recorrido de la ruta si le permite elegir el nombre de archivo, lo que podría permitirle hacer todo tipo de cosas.
  • Puede cometer un error en la configuración del servidor web y todo se ejecuta a través del intérprete, independientemente de la extensión (ya he visto esto antes: es un error silencioso, porque PHP genera literalmente todo lo que no reconoce, por lo que las imágenes se verá igual antes y después de la interpretación de PHP).
  • El archivo puede contener un exploit para un decodificador específico, por ejemplo, si sabe que el administrador puede ver su imagen y usa un navegador que tiene un visor PNG vulnerable, puede cargar una imagen PNG que explote esa vulnerabilidad.

Los dos primeros se resuelven fácilmente: nunca permita que el usuario elija su nombre de archivo, o al menos incluya en la lista blanca un conjunto de caracteres que son definitivamente seguros, como ^[a-zA-Z0-9_-]*$ (alfanumérico, guión bajo y guión).

Se puede verificar el tercero colocando un archivo llamado "test.png" en algún lugar y colocando <?php echo "test1"; en él. Cuando solicite el archivo a través de curl, debería ver el código completo. Si solo ves "test1", entonces es vulnerable.

Finalmente, el último es difícil de verificar y está algo fuera de alcance. Puede usar un escáner de virus en el lado del servidor, pero los escáneres de virus solo detectan algunos casos comunes y, por lo general, no podrán detectar todas las variantes de una vulnerabilidad, si conocen la vulnerabilidad en primer lugar. El usuario debería, idealmente, actualizar su sistema y no ejecutar software vulnerable. Pero si se encuentra en un entorno de alta seguridad, debería aplicar la defensa en profundidad y hacer cosas como volver a codificar la imagen, tal vez solo permita que los usuarios vean las imágenes en una máquina virtual, etc. Pero eso está fuera del alcance de esta pregunta. .

Resumen: Hay algunos ataques relacionados que no se han demostrado para mitigar, pero cuando solo se considera el fragmento de código como publicado: esa parte es segura.

    
respondido por el Luc 16.07.2018 - 01:30
fuente

Lea otras preguntas en las etiquetas