Problemas de confianza relativos al código abierto

15

Dos discusiones separadas me han abierto los ojos recientemente a un problema que no había considerado: cómo confirmar que el binario de código abierto que uno usa se basa en el código fuente publicado.

Hay una gran discusión hilo sobre criptografía basada en randombit en Zooko Wilcox-O'Hearn's, fundador y CEO de LeastAuthority.com, carta abierta a Phil Zimmermann y Jon Callas, dos de los directores detrás de Silent Circle, la compañía que dirigía Silent Mail que tocó el tema. Además, un artículo del Dr. Dobbs publicado hoy titulado Poniendo Absolutamente Todo en el Control de Versiones tocado en él también.

El problema que preocupa a esta pregunta es la capacidad de volver a compilar el código de código abierto y obtener los mismos resultados que el binario publicado. En otras palabras, si recrea el mismo binario y lo hash del código fuente, es poco probable que sea idéntico debido a las diferencias en las cadenas de herramientas y algunas aleatorizaciones en los compiladores.

El artículo del Dr. Dobbs sugiere poner incluso la cadena de herramientas bajo el control de versiones por razones de reproducibilidad. Jon Callas señala que en muchos casos puede ser imposible redistribuir la cadena de herramientas por varias razones, incluidas las restricciones de licencia. A menos que esté compilando el código usted mismo, está agregando un paso de confianza a su conjunto de supuestos ya que el binario no puede ser recreado por otros con los mismos resultados.

Ahora entiendo que este es un riesgo comprensible comprensible. Mi pregunta es: ¿existen otras discusiones o indicios relativos a la reproducción de byte a byte de código fuente cuando se compilan, eliminando así la necesidad de confiar en el proveedor de binarios incluso de código abierto? Como se menciona en la discusión de Jon Callas, Ken Thompson mostró "No puedes confiar en el código que no creaste totalmente". ¿Cuáles son los pensamientos de implicaciones de seguridad sobre este tema?

    
pregunta zedman9991 03.09.2013 - 22:50
fuente

8 respuestas

13

Si puede volver a compilar el código fuente y tener su propio binario, entonces tal vez no podrá obtener exactamente el mismo binario que el que se distribuye; pero ¿por qué importaría? En ese momento, usted tiene su propio binario, que necesariamente coincide con el código fuente (suponiendo que su compilador no sea malicioso): puede deshacerse del paquete binario y usar su propio binario.

En otras palabras, las situaciones en las que podrías verificar el resultado de la compilación son situaciones en las que puedes compilarte, lo que convierte la verificación en un punto discutible.

Existen marcos de distribución de paquetes que se basan en la distribución de código fuente y la compilación local en lugar de paquetes binarios; p.ej. pkgsrc (el sistema nativo para NetBSD) o MacPorts (para máquinas MacOS X). Sin embargo, no lo hacen por confianza o seguridad, sino porque la distribución de paquetes binarios implica la creación de sistemas en algún lugar, y estos no son gratuitos; Además, un punto de pkgsrc es proporcionar una gestión sencilla de las opciones de compilación locales.

El famoso ensayo de Thompson destaca la idea de que incluso hacer tu propia compilación no es suficiente. Llevado al extremo, debe escribir su propio código, pero también su propio compilador, y ejecutarlo en el hardware que diseñó y grabó usted mismo: no puede confiar en la máquina a menos que haya comenzado con un cubo de arena (para silicon , el componente principal de los semiconductores). Esto es, por supuesto, bastante impracticable . Por lo tanto, necesitamos la segunda mejor opción, y la segunda mejor es un cambio de paradigma : reemplazar la confianza por la violencia .

Lo que hacemos es que los paquetes binarios están firmado . El instalador de paquetes verifica la firma antes de instalarla y rechaza los paquetes que no provienen de "fuentes confiables". El mismo concepto se aplica a applets de Java , a los que se les puede otorgar permisos adicionales (y, de hecho, permiso para hacer lo que sea desea con su computadora) siempre que estén firmados. Tenga en cuenta que esto es de hecho una firma, no solo una autenticación; no es suficiente (ni tampoco es necesario) que el paquete se haya descargado desde un "repositorio de confianza" a través de HTTPS. Dicha descarga le brindaría bastante garantía de que el paquete proviene de quien usted cree y no se ha modificado en tránsito. Pero quieres más: quieres una prueba . Usted quiere una firma porque SI el paquete está lleno de malware, ENTONCES puede usar la firma para demostrar que el proveedor del paquete fue un cómplice, al menos "por negligencia". De las firmas viene responsabilidad , y la responsabilidad funciona sobre miedo . Miedo a los litigios de clientes maltratados. Miedo a las represalias de las agencias policiales. En última instancia, el miedo a la violencia.

    
respondido por el Tom Leek 03.09.2013 - 23:13
fuente
24

No es tan simple.

Con la gran cantidad de plataformas en las que se podría haber construido el programa, puede ser extremadamente difícil replicar el entorno de compilación original. Debido a esto, podría estar usando un compilador diferente, con configuraciones diferentes, usando diferentes versiones de bibliotecas. Estas ligeras variaciones en el entorno definitivamente pueden afectar el binario compilado. Por supuesto, si el autor está dispuesto a especificar su entorno de compilación con precisión, o si tiene suerte (diferentes idiomas pueden afectar esto) podría ser posible reconstruir exactamente el mismo binario.

Para una situación reciente en la que esto fue un problema, consulte TrueCrypt, un programa de cifrado de disco completo de código abierto 0 . Cuando el sitio de TrueCrypt fue reemplazado abruptamente con un anuncio que declaraba el final inesperado del proyecto TrueCrypt, las personas obviamente estaban interesadas en verificar el código. Sin embargo, diferentes personas que construyen TrueCrypt a menudo tienen binarios que difieren enormemente de la versión oficial, debido a las variaciones en el entorno de construcción. Una persona aparentemente manejada (después de un arduo trabajo en recrear algo muy cercano al entorno original ) para replicar la compilación TrueCrypt desde cero con solo ligeras variaciones en la salida compilada. 1 Por supuesto, no es posible verificarlo usted mismo a menos que esté dispuesto a intentar lo mismo.

Interesante en esa página es el hecho de que el binario contiene una marca de tiempo del tiempo de compilación. Esto solo significa que compilar y comparar los hashes nunca funcionaría.

0: TrueCrypt tiene una licencia extraña con algunos problemas; no es seguro si realmente sería seguro dividir el proyecto.

1: En realidad, parece que hicieron esto antes de la extrañeza del sitio TrueCrypt, pero desde entonces también han logrado replicar la compilación de la versión 7.2.

    
respondido por el ikdc 30.07.2014 - 19:03
fuente
15

Si usted mismo compila el código, puede obtener el mismo binario. O no. Básicamente, sus posibilidades son buenas si el compilador usa algoritmos de optimización determinista (ese es el caso habitual) y usted usa exactamente la misma versión del compilador con las mismas opciones de línea de comandos (que generalmente es mucho más difícil de garantizar).

La compilación determinista es más fácil con el marco de programación donde el formato "compilado" se especifica formalmente y no está realmente optimizado. Estoy hablando aquí sobre el bytecode de Java o los ensamblados de .NET. Cuando se utilizan tales herramientas, es posible poder compilar el código fuente y obtener el mismo binario, aunque es difícil. Con C o C ++, olvídalo.

Los métodos habituales son:

  • Compílate.
  • Haga que un tercero de confianza haga la compilación. El tercero obtendrá una copia de la fuente, realizará la compilación de sus máquinas y firmar (con criptografía o con papel) tanto el archivo de origen como el binario producido.
  • Haga que el proveedor del binario firme el binario y confíe en que la ingeniería inversa será lo suficientemente factible para demostrar el juego sucio si es necesario (nuevamente, esto es mucho menos inverosímil cuando se habla del código de bytes de Java que del código C compilado). / li>
  • No utilice software externo; reimplementar todo de forma interna (y sí, este es un método usual , que no es lo mismo que recomendado ).
  • Sigue adelante y confía en tu buena suerte (ciertamente no es un método recomendado, pero sí el más barato a corto plazo).

Tenga en cuenta que (re) compilar código también requiere que la máquina en la que se realiza la compilación no esté bajo control hostil. Este ensayo muy clásico es una lectura obligatoria sobre el tema. La idea subyacente es que su confianza aún debe comenzar en algún lugar (aunque solo sea en el propio hardware, cuyo firmware se supone que está libre de malware), por lo que lo mejor que puede hacer es mantener una pista de auditoría clara. . Tal rastro no garantiza contra la inserción de puerta trasera, pero puede ayudar mucho en la asignación de culpa y responsabilidad cuando surgen problemas.

    
respondido por el Thomas Pornin 30.07.2014 - 19:45
fuente
10

Sí es posible. Pero es muy difícil, ya que todo el proceso de compilación no ha sido diseñado para ese objetivo. A menudo se le llama "compilaciones deterministas", "compilaciones reproducibles", "compilaciones idempotentes" y es un desafío.

Bitcoin, Tor , y Debian , intentan usar construcciones deterministas, y el proceso técnico se describe here .

Es cierto que el proceso es imperfecto, frágil y muy difícil de corregir. Cuando se consideran construcciones multiplataforma, el problema es aún más complejo.

    
respondido por el random65537 30.07.2014 - 19:40
fuente
3

Me gusta el determinismo.

Un compilador o cualquier herramienta de software es realmente una transformada matemática desviada. Toma s (código fuente) lo pone en una función C () y produce una salida binaria b.

b = C (s) cada vez! De lo contrario, el determinismo falla y todos nos volvemos locos.

La teoría dice que, siempre que comencemos con la misma s, y la misma C (), siempre produciremos la misma b.

Y esto es bueno porque podemos realizar un hash de b o H (b) y obtener un valor relativamente corto que podemos comparar con el H (b) de otra persona para asegurarnos de que sean binarios es el que esperamos.

Y luego ocurre el cambio: s cambia a s ', C () cambia a C' (). Oh no!

Porque C (s) = b1 y C '(s) = b2 y C (s') = b3 y C '(s') = b4

y, por supuesto, no hay dos de H (b1), H (b2), H (b3) o H (b4) con ninguna coincidencia.

Y el problema es que a medida que los componentes (cadena de herramientas, entorno, configuración, sistema operativo, etc.) que se requieren para producir binarios b se vuelven más numerosos e interdependientes, se vuelve cada vez más difícil reproducir el mismo b.

Espera, ¿y si no necesitamos exactamente la misma b?

Entonces estamos tratando con b y b 'y la diferencia entre ellos.

Todo lo que necesitas para encontrar la diferencia entre un binario de referencia b y el binario generado b 'y ver qué significa la diferencia. Si la fuente para b y b 'es s, eso significa que estamos tratando con C () y C'. Y así podemos correlacionar la diferencia entre C () y C '() con la diferencia entre b y b'. Por lo tanto, incluso si no podemos reproducir exactamente b, podemos ganar algo de confianza en b 'apoyándonos en qué diferencia se debe al uso de C' () en lugar de C ().

    
respondido por el this.josh 04.09.2013 - 09:07
fuente
3

Incluso con las mismas fuentes, el mismo sistema operativo, las mismas bibliotecas, el mismo compilador y el mismo cargador, dos binarios no coincidirán, ya que incluyen información sobre la fecha de compilación y operación de carga.

En el mismo sistema y entorno de desarrollo, si creas dos veces el mismo binario, será diferente y, por lo tanto, cualquier hash será diferente:

$ md5 nmap
MD5 (nmap) = 8ef4b7c1cb2c96ce68d9e08224419b4f
$ # make clean, make install
$ md5 nmap
MD5 (nmap) = 94467bc53973550f919293f891f245f9

Por otra parte, si las tablas de símbolos no se eliminaron, estas tablas de símbolos coincidirán y serán una buena aproximación para diagnosticar que un binario realmente se construye a partir de una fuente determinada:

$ nm -a nmap >/tmp/nmap.nm.1
$ # make clean, make install
$ nm -a nmap >/tmp/nmap.nm.2
$ diff /tmp/nmap.nm.[12]
$

Esto solo es válido para mí para verificar que un binario proviene realmente de una versión dada de la fuente de mi árbol. Si sospecho una fuente externa de templado con todo, entonces incluso estas tablas de símbolos podrían estar "dispuestas".

    
respondido por el daniel Azuelos 30.07.2014 - 20:05
fuente
3

En general, si no estás seguro de confiar en la compilación de otra persona, harás el esfuerzo de hacer el tuyo o encontrar a alguien para obtenerlo de quien confías.

¿Pero está seguro de que puede confiar en que su compilador no ha sido infectado?

Es tortugas hasta el fondo. En algún momento, siempre terminará teniendo que emitir un juicio y / o confiar en los antivirus, los firewalls y otros sistemas de seguridad.

DESPUÉS DEL PENSAMIENTO - Esta es una de las razones por las que existen compañías que distribuyen versiones productizadas de código de fuente abierta. Ellos vigilan su base de código, prometen que sus compilaciones están limpias y (si lo compras) brindan apoyo continuo. Recuerde, incluso el manual de Stallman sobre GNU dijo que "el software debería ser libre, el soporte debería costar".

Mantener las descargas confiables es una forma de soporte. Usted puede obtener un buen apoyo de una comunidad gratuita ... pero puede obtener un mejor apoyo si le arroja algunos dólares. Elija su punto de intercambio preferido.

Estoy dispuesto a usar algunas versiones aleatorias de Linux para piratear en una máquina secundaria. Prefiero algo como Fedora para la máquina personal en la que realmente confío. Y si apostara por un negocio, elegiría la versión completa del producto comprado, Red Hat Enterprise o similar. (El respaldo no está implícito; Fedora y RHEL son solo buenas ilustraciones de cómo una empresa aborda dos puntos diferentes en ese espectro).

    
respondido por el keshlam 31.07.2014 - 06:11
fuente
1

Una de las cosas fundamentales en las que confías en un binario es el lugar donde lo obtuviste. Si sourceforge o download.com o quien dice que está libre de virus y eso es lo suficientemente bueno para ti, hazlo. Estás tomando su palabra al respecto.

Si no desea confiar en un binario, la única otra respuesta real es compilar desde el código fuente. Ya sea para algo como el código de bytes de Java que puede ejecutar, o un tarro, O bien hasta un binario.

Si compilas tu propio binario, sí, podrías terminar con algo que es el mismo que el binario estándar (lo que significa que TODO es el MISMO, un poco para la coincidencia de bits) ¡Genial! Sucedió que estaba ejecutando el mismo hardware, compilando para los mismos procesadores, nadie había dejado accidentalmente un salto de línea adicional en su copia del código ... ya sea que coincida o no, en ese momento está confiando en el código que usted Sólo tenía (la capacidad al menos) para leer. Si no conoces C ++ y no confías en otras personas que han investigado el código, entonces es difícil. Aprende C ++ y vetalo tu mismo.

Todo esto se reduce a que no puedes verificar un binario a menos que todo coincida EXACTAMENTE. Sin embargo, siempre puedes verificar el código fuente abierto para algo. Ya sea que se tome el tiempo o que confíe en el análisis que alguien ha hecho, es su elección.

    
respondido por el PsychoData 04.09.2013 - 01:24
fuente

Lea otras preguntas en las etiquetas