Es hora de repensar la seguridad de OpenBSD

OpenBSD se posiciona como un sistema operativo seguro. Sin embargo, en los últimos meses, se han encontrado una serie de vulnerabilidades en el sistema. Por supuesto, no hay nada extraordinario en esto. Aunque algunas vulnerabilidades son bastante inusuales. Incluso podrías decir crítico. Los desarrolladores de OpenBSD tienen varias pautas sobre cómo garantizar la seguridad. Aquí hay dos de ellos:

  • evitar errores;
  • minimizar el riesgo de errores

No todos están de acuerdo en que estos principios son suficientes para construir sistemas seguros. Me parece que tiene sentido estudiar si el enfoque de OpenBSD funciona o si está inicialmente condenado.

Por ejemplo, no seleccioné todos, sino solo algunos errores interesantes que coinciden accidentalmente con el tema de nuestra conversación.

autenticación de libc


Las funciones de autenticación ejecutan ayudantes sin verificación argv. Informe . Patch .

Este es un error sorprendentemente simple, pero probablemente no parecía demasiado obvio durante la revisión del código. Me parece, en parte, que la razón en cierta confusión es quién es responsable de verificar los datos de entrada. Puede llamar a cada uno de los tres componentes involucrados: un programa, una biblioteca o login_passwd, y es razonable suponer que alguien más está revisando. Al final, creo que la biblioteca fue declarada culpable, porque fue por ella que apareció un parche, pero personalmente a primera vista, su código no parece inequívocamente incorrecto.

Una parte más interesante de la historia es que incluso con el error de libc mencionado, la función login_passwdNo sería vulnerable de esta manera si no fuera por otro error. En 2001, login_passwd fue reescrito para admitir kerberos, y tal vez fue cuando introdujeron cuál es la verdadera causa del error. Una oferta de autenticación de tipo solicitud-respuesta (como en el sistema s / key) devuelve un estado autenticado, no silencio. Muchos años después, se eliminó el código kerberos, pero quedó parte del código para soportarlo, así como el error introducido.

Si el código kerberos se limpiara completamente, el error de autenticación aún permanecería (había otros problemas relacionados con el análisis argv), pero su efecto ciertamente disminuiría considerablemente.

No es fácil analizar correctamente argv en un contexto de seguridad. Muchos consejos y enfoques lógicos no funcionan aquí. Solo notaré que esta vulnerabilidad apareció despuésotra discusión sobre el problema con los nombres de archivo en Unix / Linux / POSIX , aunque el signo menos (guión) no se aplica realmente al nombre del archivo.

ld.so


Las variables de entorno incorrectas no se han eliminado del código ld.so. Informe . Patch .

Algo así como un error de memoria. Pero no. El error aquí es vincular el éxito de una operación, dividir la variable de entorno, a eliminar esa variable. Muy confiado.

Por supuesto, los defensores de varios sistemas de mecanografía asegurarán que procesarán estas operaciones en el orden correcto, pero no el hecho de que esto ayude. El código C no se bloqueó debido a la falta de manejo de errores o porque el error de asignación de memoria permaneció invisible.

ftp


ftp sigue los redireccionamientos a archivos locales. Informe . Patch .

El error de redirección ftp de NetBSD ha sido durante mucho tiempo un ejemplo típico de funciones no controladas . ¡Y aquí nuevamente el mismo error (afortunadamente, con consecuencias menores)! Chicos, bueno, siéntense en casa. No agregue funciones adicionales a sus programas.

smtpd de


smtpd no puede verificar algunas direcciones de remitente. Informe . Patch . Comentario .

Creo que todo se dice en el comentario de Gilles, pero recordaré los antecedentes. Érase una vez, todo el correo se almacenaba localmente para cada usuario en / var / mailen archivos mbox. Esto no es muy bueno, porque existe la posibilidad de daños si mua elimina el correo electrónico mientras mda entrega uno nuevo (sin mencionar otros problemas como distorsionar el campo De). Por lo tanto, el archivo mbox debe estar bloqueado. Pero bloquear un sistema de archivos de red no funciona de manera confiable. Entonces, en lugar de bloquear, usamos archivos de bloqueo. Sin embargo, debe acordar un protocolo de bloqueo específico, ya que el usuario posee los archivos mbox y la propia raíz posee el directorio. Por lo tanto, para modificar realmente el archivo mbox, debe ejecutar la función auxiliar setuid cada vez. Bueno, este es el primer problema. Otra reliquia de los viejos tiempos es la configuración de mda, que se puede usar no solo como un programa, sino como una tubería de shell. La gente prescribe algo comospam-assassin | mail.mday no puedes simplemente pasarlo execve().

Hay muchas dificultades arraigadas en el pasado. Y, desafortunadamente, este código problemático no puede simplemente ser reemplazado. El correo electrónico se usó hace mucho tiempo, y los sistemas y flujos de trabajo muy complejos se construyen sobre la base, por lo que es muy difícil simplemente cortar un fragmento de código y pegar uno nuevo. A pesar de los distintos niveles de separación de privilegios, un proceso padre con privilegios raíz aún confía en sus procesos hijos menos privilegiados de muchas maneras. Ejecutará los comandos y argumentos que recibirá.

Evitar esto parece tan simple como cambiar al formato de almacenamiento maildir, pero requiere varios cambios en muchos lugares. Correo mua estándarNo entiende este formato. En cuanto a mí, mbox ha sobrevivido durante mucho tiempo a su existencia, pero aún así se adapta a muchas personas, y el procedimiento de actualización puede no ser completamente transparente y no funcionará automáticamente.

smtpd read


La lectura fuera del alcance en smtpd se puede usar para ejecutar comandos. Informe . Patch .

Esto es realmente un problema de seguridad de la memoria. Al enviar algunas barras de estado divertidas, el servidor smtp remoto puede inyectar comandos en la cola smtpd para su ejecución. Cuando un correo electrónico se pone en cola para reenvío, smtpd agrega información de destino al encabezado para saber qué comando ejecutar (ver arriba). Este ataque es similar al "contrabando" de solicitudes http . Si puede generar una "mierda" con comandos inesperados en el encabezado, smtpd los ejecutará cuando intente volver a entregar.

Como arriba, uno de los problemas es que las partes más sensibles de smtpd están demasiado cerca de la superficie de ataque. Me parece que el verdadero problema es que smtpd almacena sus propios metadatos dentro de los datos del correo electrónico. Debido a esto, se hace posible un análisis fuera de sincronización. Si la respuesta citada del servidor se almacenó completamente separada del archivo con las instrucciones de entrega, entonces leer fuera de las fronteras no haría mucho daño.

Esta vulnerabilidad me parece indicativa, porque aquí vemos el peligro de mezclar datos con diferentes niveles de confianza. Este peligro nunca ha sido discutido. Y ella definitivamente lo es.

recomendaciones


Por supuesto, la conclusión fue clara desde el principio, pero hablaremos de ello de todos modos.

Creo que algunos de estos errores ayudan a demostrar cómo los principios como la eliminación de interfaces obsoletas y la reducción de la complejidad del código son vitales para la seguridad . En su mayor parte, el fracaso se produjo debido al hecho de que estos principios no se siguieron hasta el final, y no porque los principios en sí mismos se echen a perder o sean insostenibles. Algunas cosas se están perdiendo de vista, pero no estoy de acuerdo con que los desarrolladores necesiten algún tipo de vigilancia sobrehumana. Es fácil dar consejos inútiles, como tener cuidado, no cometer errores y git gud [la expresión del argot gamer significa 'mejorar', es decir, "mejorar, mejorar pronto" - aprox. trans.]. Pero creo que OpenBSD tiene problemas más serios.

Incluso OpenBSD puede arriesgar la seguridad por la practicidad utilitaria. Es por eso que algunos proyectos obsoletos no se han modificado durante mucho tiempo. Entonces, quizás la lección es que siempre se deben seguir principios efectivos, y no solo cuando sea conveniente. Aunque a menudo es difícil tomar la decisión correcta.

Las tres vulnerabilidades más graves, auth y dos smtpd, son más o menos adecuadas para la explotación solo debido a problemas arquitectónicos que van más allá del alcance del error original. Deberían haber seguido siendo solo fallas menores que demuestran que en un sistema bien protegido no es necesario luchar por el código perfecto, es decir, se permiten errores menores y no afectan la seguridad. Por desgracia, puede ser difícil identificar fallas de diseño en forma abstracta. Y todas las partes del sistema se ven protegidas individualmente, pero si se combinan, pueden aparecer debilidades.

La separación de privilegios es un componente clave de la seguridad de OpenBSD, y se basa en la comunicación entre procesos. Tiene sentido observar más de cerca qué problemas pueden surgir con los procesos dañados. Los navegadores protegidos refuerzan cada vez más la protección y obstaculizan los ataques. En particular, smtpd debe protegerse contra la corrupción de la memoria en las tareas de red. Pero la facilidad con la que puede controlar el proceso parental es alarmante.

Solo se puede evitar un error utilizando un lenguaje más seguro. Sí, probablemente, hay algún tipo de lenguaje de programa, que en algunos casos puede ayudar si lo sigue con perseverancia religiosa. Pero todavía no estoy seguro de que, por defecto, cada programador codifique correctamente todos los invariantes correspondientes.

Escribir un servidor de correo es un negocio complicado. Especialmente si los marcos heredados te están apretando.




All Articles