Supongamos que estoy revisando el código que envían los solicitantes de empleo para demostrar sus habilidades. Claramente, no quiero ejecutar ejecutables que envían. No es tan claro que prefiero no ejecutar el resultado de la compilación de su código (solo, por ejemplo, Java permite ocultar el código ejecutable en los comentarios ).
¿Qué hay de compilar su código? Quiero advertencias del compilador si las hay, pero ¿y si su código contiene algunas secuencias de caracteres inteligentes que explotan mi compilador y mi compilador compromete mi máquina?
Cuando busco en Google las "vulnerabilidades del compilador", los resultados que obtengo tienen que ver con las optimizaciones del compilador y la emisión del código, y si el código emitido es tan seguro como se pretendía que fuera el código fuente original.
¿Los compiladores generalmente se validan para garantizar que no comprometerán la máquina del usuario al compilar algún código inteligente? ¿Qué tan seguro es compilar un fragmento de código de un extraño?
fuente
Respuestas:
Depende.
Esta pieza de archivo MAKE podría eliminar su directorio de inicio:
Por lo tanto, si necesita usar una herramienta (como cmake o sistema de archivos MAKE), entonces no es seguro. Solo depende de lo malicioso que sea el codificador.
Por otro lado, los compiladores son programados por personas, por lo tanto, tienen errores. Entonces, tal vez sea posible que alguien encuentre una manera de ejecutar código malicioso durante la compilación.
Como se sugiere en los comentarios, si desea estar seguro de que no se están haciendo cosas graciosas en su máquina, use una máquina virtual.
fuente
Estoy bastante seguro de que en algún lugar del negocio hay algunos tipos inteligentes que ya han creado un truco para un idioma específico y una versión del compilador. Mi lugar favorito para buscar algo como esto probablemente sería el concurso internacional C ofuscado (no sé si hay algo comparable para Java). Sin embargo, en realidad, qué tan alto considera el riesgo, asumió que
el solicitante le deja una impresión plausible de que realmente quiere el trabajo en su empresa (y no una demanda)
el chico no sabe cuánto se hace la revisión en la tuya
él / ella no sabe qué versión exacta del compilador está utilizando
él / ella no sabe si usa un entorno virtual o un compilador en línea, solo para estar seguro
no acepta programas que son demasiado grandes para ser revisados efectivamente
no compilas nada que te parezca sospechoso
no hay muchas personas en el mundo que realmente sepan cómo realizar técnicamente dicha tarea (y solo buscar en Google no le dará una "referencia rápida" o un tutorial sobre esto, como ya lo ha descubierto usted mismo).
Entonces, aunque la compilación no es "totalmente segura" en teoría, en mi humilde opinión, en realidad, el riesgo es extremadamente bajo de que su "compilador se pwned".
fuente
Tenemos que distinguir varios casos:
Makefile
, abuild.xml
, unconfigure
script de shell, etc. Técnicamente, esto no se debe a la compilación del código del atacante, sino a la configuración del entorno de compilación.# 4. y # 5. como máximo resultará en una denegación de servicio. En la práctica, los compiladores de C ++ y Scala limitan la cantidad de recursividad se puede hacer, por lo que no es realmente posible escribir un bucle infinito. En Scala, eso es solo una restricción de implementación, pero en C ++, está explícitamente permitido por la especificación, creo.
# 2 está técnicamente fuera del alcance de la pregunta porque la pregunta era sobre compilar código que no lo ejecuta (OTOH, está la profunda pregunta filosófica: si la verificación de tipo de un programa Haskell puede realizar un cálculo arbitrario de Turing, ¿es esa compilación o ejecutar un programa?)
# 1 es poco probable Por un lado, los compiladores de producción son muy complejos, por lo que la probabilidad de errores es alta. Por otro lado, se prueban rigurosamente, después de todo, manejar la entrada mal formada es parte de la descripción del trabajo de un compilador. Incluso si no se prueban, serán bombardeados con código mal formado de todos modos ... ¡solo mire algunas preguntas de StackOverflow para obtener ejemplos de lo que la gente basura arroja a sus compiladores!
Esto nos deja con 3. Algunos compiladores pueden limitar el tipo de acceso que el código de tiempo de compilación tiene al sistema, pero para algunos de los casos de uso, tener acceso total es inevitable. El propósito de los proveedores de tipos de F #, por ejemplo, es "falsificar" tipos sintéticos para datos cuyo sistema de tipos no coincide con F # 's, para que pueda interactuar, por ejemplo, con un servicio web que tiene un esquema WSDL en un tipo fuertemente tipado Moda. Sin embargo, para hacer esto, el proveedor de tipos debe tener acceso al recurso de esquema WSDL en el sistema de archivos o en la web, por lo que debe tener acceso a la red y al sistema de archivos.
Entonces, ¿es seguro? Técnicamente no. ¿Es arriesgado? Realmente no.
fuente
No debería haber ningún riesgo simplemente compilando el código. En teoría , podría haber un error en el compilador que un pirata informático inteligente podría aprovechar, pero parece extremadamente improbable.
Tenga en cuenta que el edificio puede ser inseguro. Por ejemplo, en C #, 'evento de compilación' le permite especificar líneas de comando arbitrarias para ejecutar antes y después de la compilación, lo cual es obviamente peligroso y mucho más fácil de explotar que los desbordamientos del búfer en el código del compilador.
fuente
En lugar de especular, en realidad me molesté en investigar un poco sobre este tema antes de responder, yendo al recurso más autorizado que se me ocurrió ( Detalles de CVE ). Esta lista completa de vulnerabilidades de seguridad divulgadas públicamente es probablemente la mejor que se podría hacer para evaluar los niveles de amenaza de varios tipos de software.
Por supuesto, no me tomé el tiempo de leer todo el material disponible, pero seleccioné algunos compiladores "principales", IDE y editores de texto para elaborar una evaluación de amenaza de muestra. Si se toma en serio la ejecución de cualquier software, al menos debería ver qué amenazas existen. También tenga en cuenta que el software más antiguo es generalmente más defectuoso que el software más nuevo, por lo que es ideal ejecutar lo último que esté ejecutando.
Primero, podemos echar un vistazo a varios editores de texto. Parece que los mejores editores son los más simples. Vi si está utilizando un shell de Linux, o Bloc de notas si está en Windows. Algo sin capacidades de formato, sin análisis, solo visualización directa de datos y terminación automática del análisis si un solo carácter está fuera del esquema de codificación actual. Incluso Notepad ++ ha tenido un puñado de vulnerabilidades. Evite cualquier cosa compleja cuando vea archivos no confiables.
En segundo lugar, podemos mirar IDEs. Si elige abrir el archivo en un IDE, debe tener en cuenta que algunos IDE han reportado errores. Aparentemente, Visual Studio ha tenido vulnerabilidades disponibles a través del mecanismo de extensiones, por lo que abrir una solución puede ser problemático. Evitar IDE evita toda una clase de problemas entre usted y el código no confiable. Seguir con VI parece mucho más seguro.
Tercero, podemos ver los compiladores reales. Hojeé algunos, incluidos Adobe, Microsoft, Java y C / C ++ de GNU, y descubrí que, en general, compilar código (e incluso construir , suponiendo que no haya un archivo de creación personalizado) es relativamente seguro, pero cada uno de esos compiladores lo hizo o lo hizo tener vulnerabilidades de seguridad que podrían surgir de la ejecución real de los binarios compilados. En otras palabras, no podrían controlar su sistema simplemente compilando, sino que podrían ejecutar código.
Entonces, en conclusión, suponiendo que el método de entrega no haya secuestrado su sistema (por ejemplo, su cliente de correo electrónico fue pirateado, o la unidad USB en la que estaba infectada ...), leer el código fuente y compilar el código fuente probablemente sea seguro . Al investigar su software específico, podría hacerlo aún más seguro, por ejemplo, validar que el archivo está en la página de códigos correcta, etc. La ejecución del código solo debe realizarse en hardware que simplemente no le interesa. No es una VM, sino una computadora completamente diferente físicamente sin acceso a la red y sin archivos confidenciales o dispositivos externos. Incluso si crees que entiendes el código, una investigación simple muestra que incluso los compiladores tienen errores que podrían permitir que un exploit de desbordamiento de búfer oculto se escabulle por detrás y ejecute código arbitrario, pero solo si eligesejecutar o depurar el programa La compilación real debe ser segura.
fuente
Bueno, comenzaría con "revisar su código". ¿Por qué hay una necesidad de ejecutar el código?
Además de eso, hay muchos compiladores en línea en los que puedes poner el código y compilarlo y / o ejecutarlo. Puede hacer que sea un requisito: se compila en este y aquel compilador en línea.
Aquí hay un ejemplo de una página con compiladores en línea: compiladores en línea
El código de revisión para una entrevista de trabajo no debería ser tan grande como para que no entiendas lo que está sucediendo.
fuente
En general, son demasiado complejos y a menudo se escriben usando idiomas en los que no es práctico probar esta propiedad.
Posiblemente no con esta intención específica, pero al menos se conoce la noción de compiladores de pruebas fuzz ( LLVM ahora puede probar fuzz por sí mismo ). Las pruebas destinadas a detectar datos que bloquean el compilador debido a errores del compilador también tenderán a generar fallas explotables.
Naturalmente, tendrías que investigar si el compilador específico en el que estás interesado es probado o probado por fuzz para encontrar posibles bloqueos, y si los errores que se encuentran son realmente corregidos. La regla general es que si hay accidentes que son peores que las excepciones no recuperadas de la memoria, entonces, sin investigar más los detalles, debe considerar una posibilidad seria de que puedan aprovecharse para explotar.
Desafortunadamente, cuánto dura un trozo de cuerda. En principio, el correo electrónico podría explotar su cliente de correo, o el código fuente podría explotar su editor de texto o cppcheck, incluso antes de que llegue a su compilador. La sugerencia de Sebastian en los comentarios de usar un compilador en línea es bastante buena, pero, por supuesto, el código debe estar en una forma que el compilador acepte.
Cualquier lenguaje o compilador con facilidades para la ejecución en tiempo de compilación de código general es, por supuesto, altamente sospechoso. Las plantillas de C ++ son funcionalmente completas pero no tienen acceso (previsto) al sistema, por lo que tienen un riesgo relativamente bajo. BЈовић menciona
make
un riesgo extremadamente alto (ya que está ejecutando el código del extraño, es solo que el código está escrito en elmake
lenguaje, no en C ++). Si el compilador se ejecutará,system
entonces estás en el mismo barco. Solía trabajar con un ensamblador que, si no recuerdo mal, podría hacer una ejecución arbitraria de código en tiempo de compilación. Estaba destinado a calcular tablas de búsqueda, pero no creo que nada te impidiera hacer llamadas al sistema.En la práctica , si el código me parece correcto y creo que lo entiendo, entonces consideraría un riesgo extremadamente bajo compilarlo, un riesgo mucho menor que decir "navegar por Internet con un navegador bloqueado". Hago cosas más riesgosas rutinariamente en mi máquina de uso general, pero muchas de ellas no las haría, por ejemplo, dentro de un laboratorio de virus o en un servidor crítico. Si el código tiene un aspecto gracioso o evidentemente ofuscado, entonces no podría arriesgarme a compilarlo porque, aparte del riesgo, podría contener un exploit oculto en la basura ilegible, es un código basura. El código oculto es difícil pero posible. El código oculto que genera la máquina a través de un exploit de compilación debe contener una carga útil ejecutable no trivial, por lo que es extremadamente difícil.
Si desea investigar más sobre esto, intente preguntar a las personas que alojan compiladores en línea. Si no se les ha hecho a ellos, entonces (salvo que usted llame la atención de la NSA o equivalente), puede asumir razonablemente que no se le hará a usted. Pusieron algo de esfuerzo en ejecutar su compilador en una caja de arena adecuada, lo que podría ser más esfuerzo de lo que estás dispuesto a hacer, pero al menos podrían decirte con qué frecuencia esa caja de arena les ahorra problemas.
fuente
Aunque esto es generalmente una preocupación, creo que el problema no existe debido a la configuración.
El solicitante le envió un código fuente. ¿Cómo o por qué sucedió eso?
Bueno, obviamente solo hay tres posibilidades:
Aproximadamente 2) y 3)
El principal riesgo es distinguir entre 2) y 3). Hay muchas posibilidades de que si vale la pena mirar lo que escribió , es algo que puede obtener el código fuente en línea (de una fuente "neutral") y que incluso puede estar familiarizado, o es algo que realmente no tiene No quiero mirar porque infringiría la propiedad intelectual de un competidor (antiguo empleador). Esto último significaría que no querría contratar a esa persona de todos modos.
Si puede obtener la fuente en línea, hágalo. Si puede verificar la contribución del solicitante a un software conocido (incluido el software propietario) por su nombre en algún lugar de los créditos, hágalo.
En cualquier otro caso, simplemente ignora lo que sea que te envió. No vale la pena mirarlo, o es ilegal o de alto riesgo.
Alrededor de 1)
El solicitante le envió algo porque le asignó una tarea. Si tiene alguna competencia (¡lo que supongo que tiene!), Entonces para una tarea de programación típica (... ¡que incluso se eligió a sí mismo!), Podrá saber si es una solución plausible que parece que podría funcionar mirando el código fuente por menos de 30 segundos (más probablemente 10 segundos).
Si no puede decir que el programa probablemente funcionará (o lo que está haciendo) en 30 segundos, el que lo escribió no es el tipo de persona que desea contratar, completo. Desea personas que escriban código que otros humanos puedan entender y mantener. No quieres a alguien que intente ser inteligente contigo, ni a alguien que gane regularmente el concurso de C ofuscado. Ni siquiera importa si el programa funciona. Tan pronto como otra persona no pueda entender el código, nunca "funciona".
Si parece que el programa probablemente funcionará, pero encuentra algo que parece "extraño" (por ejemplo, secuencias de escape Unicode de Java, literales de cadena sin formato C ++, cosas que parecen trigráficos, lo que sea), trate la asignación como "fallida", muévase al siguiente solicitante. No es necesario incluir algo similar en el 99% de todos los programas (y, efectivamente, no en su tarea, espero). Entonces, si encuentra algo "extraño" como ese, el solicitante no es alguien que quiera contratar.
Si el código pasa ese primer triaje, es posible que desee pasar otros 2-3 minutos mirándolo más a fondo. Si aún está satisfecho con lo que ve después de eso, puede ejecutarlo a través de un analizador estático y compilarlo en una máquina virtual con un alto nivel de advertencia.
Eso debería plantear problemas que puede haber pasado por alto al leer la fuente (como invocar un comportamiento indefinido o reducir la conversión).
La compilación le dirá en primer lugar si el solicitante tiene la diligencia y la atención al detalle necesarias, no tanto si tiene habilidades de programación. Al igual que escribir el nombre del empleador correctamente en su solicitud y revisar ortográficamente su CV antes de entregarlo, es una buena práctica asegurarse de que el código fuente que entrega compila sin errores (y preferiblemente sin advertencias). Si alguien no hace eso, no quiere contratarlo.
El riesgo de que sucedan cosas malas en este punto (explotar el compilador y salir de la máquina virtual) es insignificante, ya que ya ha realizado una comprobación de plausibilidad sobre el código. No va a pasar.
fuente
Si la posibilidad le preocupa, tome una máquina más antigua (¿la mayoría de nosotros no tenemos algunas sentadas?), Instale la versión actual de Linux y el compilador & c, copie el código fuente, desconecte el cable de red (o apague WiFi ), y compila. Si sucede algo desagradable, no * afectará a nada más.
Y para el malware en el Makefile, ejecútelo con el indicador -n (IIRC, RTMF) para ver qué hará sin realmente hacerlo.
* A menos que, por supuesto, su programador codifique el malware para que espere una reconexión, pero en ese caso usted: a) limpia la máquina; y b) reenviar el currículum del tipo a la NSA, porque está malgastado en el mundo comercial :-)
fuente
La conclusión es que no es riesgo. El riesgo es bastante pequeño como señalan otras respuestas, pero existe un riesgo. Eso significa que debe hacer dos preguntas:
El segundo es lo que has planteado aquí en esta pregunta, pero es el enfoque incorrecto para este caso particular. La respuesta para mitigar el riesgo es clara y fácilmente disponible: no compile el código en su máquina . Tiene dos formas obvias de compilarlo sin usar su máquina:
Estas formas de mitigar su riesgo son tan obvias, baratas y de fácil acceso que no vale la pena pasar mucho tiempo tratando de analizar qué tan grande es el riesgo. Solo haz uno de ellos y termina de una vez.
fuente
Visual Studio realmente le advierte si abre un proyecto desde una ubicación no confiable (e, g, descargado o recurso compartido de red).
Un ejemplo de cómo podría explotarse esto sería con un proyecto WPF: puede hacer referencia a clases .NET desde XAML y proporcionar IntelliSense, VS carga y ejecuta las clases referenciadas en tiempo de diseño.
Eso significa que un atacante puede colocar un archivo .dll malicioso en el directorio bin, reemplazar el código fuente por uno no malicioso y, en el momento del diseño, se ejecuta el archivo DLL. Después de su primera compilación, todos los rastros del binario malicioso desaparecen.
Entonces, aunque todo el código provisto esté "limpio", el compilador está libre de errores y, por supuesto, nunca ejecutas manualmente ningún .EXE provisto, el código malicioso aún podría ejecutarse en segundo plano. (Para estar a salvo de ese ataque específico, puede asegurarse de que NO haya binarios en el árbol de directorios antes de abrir la solución. VS le pedirá que cree la solución antes de proporcionar IntelliSense en tiempo de diseño).
Vectores similares probablemente existen con otros lenguajes / sistemas operativos.
fuente
Lectura del código fuente: totalmente seguro. Compilación de código fuente: totalmente seguro. Ejecutando binarios compilados: bueno ... eso depende.
Compilar es solo la computadora que lee el código fuente y escribe su equivalente en forma binaria. Después de la compilación, solo tiene 2 documentos: uno legible por humanos y otro legible por computadora. A menos que haga que la computadora lea (es decir, ejecute) el segundo documento, no sucederá nada.
fuente
mvn package
" descuidado puede extraer cosas y realizar tareas con complementos adicionales que quizás no conozca fácilmente. Estoy seguro de que lo mismo podría aplicarse a otros sistemas de compilación.Creo que te preocupa uno de los dos sabores:
Algunas personas han sugerido máquinas virtuales o sistemas antiguos, pero ofrezco una solución mucho más fácil: compilar como un usuario diferente con permisos reducidos / diferentes . Mucho más fácil que configurar una máquina virtual o una computadora dedicada.
Si es poco probable incluso que su sistema se vea afectado por exploits en tiempo de compilación, restaure desde copias de seguridad (las tiene, ¿verdad?).
fuente