¿Es peligroso compilar una C arbitraria? [duplicar]

69

Tengo un servidor pequeño y me gustaría verificar los tiempos de compilación en los programas C proporcionados por los usuarios. Los programas nunca serían ejecutados solo compilados.

¿Qué riesgos existen para permitir que los usuarios compilen C de forma arbitraria utilizando gcc 5.4.0?

    
pregunta W W 06.10.2016 - 04:01
fuente

6 respuestas

94

Un poco extraño, pero: es un riesgo de denegación de servicio o posible divulgación de información.

Debido a que el preprocesador de C incluirá alegremente cualquier archivo especificado en una directiva #include , alguien puede #include "../../../../../../../../../../dev/zero" y el preprocesador intentará leer hasta el final de /dev/zero (buena suerte).

De manera similar, especialmente si deja que las personas vean el resultado de sus intentos de compilación, alguien podría intentar incluir varios archivos que pueden o no estar presentes en su sistema, y podría aprender cosas sobre su máquina. Combinado con el uso inteligente de #pragma poison , pueden incluso puede aprender cosas sobre el contenido del archivo incluso si no proporciona mensajes de error completos.

Relacionadamente, los pragmas pueden alterar una gran cantidad de comportamiento del preprocesador, compilador o vinculador, y se especifican en los archivos de origen. No hay probablemente uno que le permita a alguien hacer algo como especificar el nombre del archivo de salida o algo así, pero si lo hay, se podría abusar para anular archivos confidenciales, o ejecutarse (escribiendo en cron o similar). Puede haber algo igualmente peligroso. Deberías tener cuidado al compilar código no confiable.

    
respondido por el CBHacking 06.10.2016 - 05:54
fuente
40

Bombas compiladoras

C es un lenguaje muy poderoso, y algunas de las cosas terribles que puedes hacer con él te sorprenderían. Por ejemplo, puede crear un programa de 16 bytes C que demora 27 minutos en compilar , y cuando finalmente termina, se compila en un archivo ejecutable de 16 Gigabyte . Y eso es solo usando 16 bytes. Cuando tenga en cuenta el preprocesador y los archivos de código fuente más grandes, estoy seguro de que podría crear bombas de compilación mucho más grandes.

Esto significa que cualquier persona con acceso a su servidor podría hacer un ataque de DoS en su servidor. Ahora para ser justos, esto es significativamente menos peligroso que tener a alguien que abuse de una vulnerabilidad en el compilador, o que incluya archivos confidenciales para obtener información acerca de su servidor (como hablaron otros encuestados).

Pero es otra posible molestia que encontrarás al compilar un código arbitrario. Estoy seguro de que podría establecer un límite de tiempo en todas las compilaciones y asegurarse de no almacenar nunca los archivos binarios. Aunque, por supuesto, aún debe mantenerlo en el disco mientras se está creando , por lo que si alguien hipotéticamente hiciera una bomba de compilación más grande que su disco duro, estaría en problemas (si deja que la compilación terminar).

    
respondido por el DJMcMayhem 06.10.2016 - 16:10
fuente
28

@ AndréBorie es correcto. Los compiladores y la configuración correspondiente no serán examinados por problemas de seguridad, por lo que en general no debe compilar código no confiable.

El riesgo es que se explote un desbordamiento del búfer o algún tipo de vulnerabilidad de ejecución de la biblioteca, y el atacante obtiene acceso a la cuenta de usuario (con suerte no root !) que ejecutó el compilador. Incluso un hackeo que no sea root es grave en la mayoría de los casos. Esto podría ser desarrollado en una pregunta separada.

Crear una VM es una buena solución, ya que contiene posibles vulnerabilidades para que no dañen el resto de tu aplicación.

Es mejor tener una plantilla de Linux VM que pueda iniciar según sea necesario con un entorno de compilador de pizarra limpio.

Lo ideal es que lo deseche después de cada uso, pero esto puede no ser estrictamente necesario. Si aísla la máquina virtual lo suficientemente bien, y desinfecta adecuadamente los datos de respuesta de la máquina virtual, lo que debería estar haciendo de todos modos; entonces lo peor que un hack podría hacer es hacer DoS o crear tiempos de compilación falsos. Estos no son problemas serios por sí mismos; al menos no tan serio como acceder al resto de su aplicación.

Sin embargo, restablecer la VM después de cada uso (es decir, en lugar de hacerlo a diario) proporciona un entorno más estable en general y puede mejorar la seguridad en ciertos casos de borde.

Algunos sistemas operativos proporcionan contenedores como alternativa a las máquinas virtuales. Este puede ser un enfoque más ágil, pero se aplican los mismos principios.

    
respondido por el George Bailey 06.10.2016 - 05:01
fuente
15

Sí, es peligroso: pero como la gente ha dicho, es posible hacerlo. Soy el autor y mantenedor de los compiladores en línea en enlace , y he encontrado que es bastante factible hacerlo seguro utilizando una combinación de:

  • Todo el sitio se ejecuta en una instancia de máquina virtual con pocos permisos para hacer cualquier cosa. La red está severamente limitada con solo el puerto 80 visible, y ssh habilitado solo desde IPs en lista blanca (las mías).
  • Cada instancia de compilación se ejecuta dentro de un contenedor de Docker desechable con menos permiso
  • El compilador se ejecuta desde un script que establece todos los límites del proceso (memoria, tiempo de CPU, etc.) a límites bajos para evitar las bombas de código.
  • El compilador se ejecuta con un envoltorio LD_PRELOAD ( fuente aquí ) que evita que el compilador abra cualquier archivo que no esté en una lista blanca explícita. Esto evita que lea / etc / passwd u otras cosas similares (no es que eso ayude tanto).
  • Como simpatía, analizo las opciones de la línea de comandos y no ejecuto el compilador si hay algo particularmente sospechoso. Esto no es una protección real; solo una forma de dar un mensaje de error "en serio, no intentes esto" en lugar de que LD_PRELOAD detecte un mal comportamiento.

La fuente completa está en GitHub , ya que es la fuente de docker container images y compiladores y demás.

Escribí una publicación de blog explicando cómo se ejecuta toda la configuración.

    
respondido por el Matt G 07.10.2016 - 16:13
fuente
12

No querría estar ejecutando el compilador como root, aunque he visto que esto sucede por razones de "facilidad y conveniencia". Sería demasiado fácil para un atacante incluir algo como:

#include "../../../../etc/passwd"
#include "../../../../etc/shadow"

y recupere el contenido de estos archivos como parte del mensaje de error del compilador.

También los compiladores son programas como todo lo demás, y tendrán sus errores que podrían ser vulnerables, sería muy fácil para alguien simplemente confundir los programas C y causar problemas.

La mayor parte de la seguridad de las aplicaciones se centrará en primer lugar en la validación de entrada, desafortunadamente, la definición de una entrada "segura y válida" para un compilador de C es probablemente un problema de detención en términos de dificultad :)

    
respondido por el Colin Cassidy 06.10.2016 - 10:20
fuente
3

Si permite que un usuario proporcione un archivo que contenga el código, puede tener problemas, no exactamente con el compilador sino con el vinculador que utiliza;)

ld sigue enlaces simbólicos si apuntan a un archivo que no existe. Lo que significa es que si compila test.c en la salida a.out pero ya tiene un enlace simbólico llamado a.out en su directorio que apunta a un archivo no existente, el archivo ejecutable compilado se escribirá en la ubicación que apunta a archivo (con la limitación de los derechos de usuario).

En la práctica, un atacante podría, por ejemplo, incluir una cadena que contenga una clave pública ssh en su código y proporcionar un enlace simbólico llamado a.out a ~ / .ssh / authorized_keys . Si ese archivo aún no existe, esto le permite al atacante plantar su clave ssh en la máquina objetivo, permitiéndole acceso externo sin tener que descifrar ninguna contraseña.

    
respondido por el cym13 07.10.2016 - 01:13
fuente

Lea otras preguntas en las etiquetas