Curso MIT "Seguridad de sistemas informáticos". Lección 6: "Oportunidades", parte 1

Instituto de Tecnología de Massachusetts. Conferencia Curso # 6.858. "Seguridad de los sistemas informáticos". Nikolai Zeldovich, James Mickens. Año 2014


Computer Systems Security es un curso sobre el desarrollo e implementación de sistemas informáticos seguros. Las conferencias cubren modelos de amenazas, ataques que comprometen la seguridad y técnicas de seguridad basadas en trabajos científicos recientes. Los temas incluyen seguridad del sistema operativo (SO), características, gestión del flujo de información, seguridad del idioma, protocolos de red, seguridad de hardware y seguridad de aplicaciones web.

Lección 1: "Introducción: modelos de amenaza" Parte 1 / Parte 2 / Parte 3
Lección 2: "Control de ataques de hackers" Parte 1 / Parte 2 / Parte 3
Lección 3: “Desbordamientos del búfer: exploits y protección” Parte 1 / Parte 2 / Parte 3
Lección 4: “Separación de privilegios” Parte 1 / Parte 2 / Parte 3
Lección 5: “¿De dónde vienen los sistemas de seguridad?” Parte 1 / Parte 2
Lección 6: “Oportunidades” Parte 1 / Parte 2 / Parte 3

Entonces, en continuación del tema de compartir privilegios, hoy hablaremos de oportunidades. Si recuerdas, la semana pasada hablamos sobre cómo Unix proporciona algunos mecanismos para aplicaciones que podemos usar si necesitamos separar los privilegios de la estructura interna de la aplicación.

Hoy hablaremos sobre las posibilidades que nos harán pensar de manera muy diferente sobre los privilegios que puede tener la aplicación. Por lo tanto, en la conferencia de hoy tenemos dos temas separados para la discusión. Una pregunta es sobre cómo evitar la confusión al determinar la autoridad y hacer que sus privilegios al escribir un programa sean más claros e inequívocos para que no use accidentalmente los privilegios incorrectos.

La segunda pregunta se refiere al "sandbox" llamado Capsicum , es un sistema similar al OKWS , que le permitirá ejecutar un fragmento de código con menos privilegios. Por lo tanto, si el sistema se ve comprometido, esto no amenazará con mucho daño.



Este enfoque le permite manipular los privilegios de manera diferente a lo que permite Unix . Para empezar, veamos este confuso problema de autoridad, que enfrentó el autor del artículo que estamos discutiendo sobre Norman Hardy, y descubramos por qué estaba tan desconcertado por él.

Este artículo fue escrito hace mucho tiempo, y el autor utiliza una estructura sintáctica para los nombres de archivos, lo cual es un poco sorprendente. Pero podemos intentar al menos transcribir su problema en una sintaxis de nombre de estilo Unix más familiar.

Por lo que puedo decir, utilizó el compilador Fortran , que estaba ubicado en / sysx / fort , y quería cambiar este compilador para mantener estadísticas sobre lo que se compiló, qué partes del compilador eran las que más recursos requerían, etc. Por lo tanto, quería asegurarse de que este compilador Fortran de alguna manera proporcionaría una entrada en el archivo / sysx / stat y que escribiría aquí información sobre varias llamadas del compilador.



Su sistema operativo tenía algo así como la función setuid de la que hablamos en Unix . Lo llamaron la licencia de archivo de inicio. Esto significaba que si ejecutabas / sysx / fort , y este programa tenía una llamada licencia de archivos de inicio , entonces este proceso que acabas de lanzar tendrá permisos de escritura adicionales para todo en / sysx / . Es decir, puede escribir después de la barra todo lo que generalmente está marcado con un asterisco, obteniendo una expresión de la forma / sysx / * . Esto daba acceso a todos los archivos escritos en el directorio después de / , y el usuario podía ejecutarlos. Por lo tanto, el problema específico que enfrentaban era que algún tipo de usuario inteligente podría hacer esto ejecutando el compilador podría tomar muchos argumentos como lo hace GCC .

Tal usuario podría, por ejemplo, recopilar algo como foo.f , donde f es el código fuente de Fortran , y agregar aquí - o / sysx / stat .



Tenían otro archivo en el sistema / sysx , que era un archivo de facturación para todos los clientes del sistema. Su daño haría aún más daño. De manera similar, fue posible "pedir" al compilador que compile el archivo fuente / sysx / bill y lo coloque en un archivo especial en / sysx . Y en su caso, funcionó. A pesar de que el propio usuario no tenía acceso de escritura a este archivo o directorio, utilizó el compilador, que tenía este privilegio adicional: una licencia para los archivos de inicio. Gracias a los privilegios del compilador, pudo reemplazar archivos contrarios a las intenciones del desarrollador.



¿A quién deberían culpar por lo que sucedió? ¿Qué creen que salió mal? ¿Podría haber actuado de manera diferente para no encontrar tales problemas? Creían que el compilador de Fortran sería muy cuidadoso al usar sus privilegios. De hecho, en cierto nivel, el compilador Fortran tiene dos tipos de privilegios que utiliza.

Uno, el principal, se basa en el hecho de que si el usuario llamó al compilador, debería poder acceder al archivo fuente, como foo.f. Y si fue algún otro usuario el que no activó, o no llamó al compilador, ese usuario no podría acceder al código fuente del usuario "correcto".

El segundo tipo de privilegio lo proporciona esta misma licencia, que le permite escribir estos archivos especiales. En el nivel interno del código fuente del compilador, debería haber instrucciones claras sobre cuáles de estos privilegios desea usar al abrir un archivo o al realizar cualquier operación privilegiada. Simplemente podría abrir, leer y escribir archivos como cualquier otro programa. Utiliza implícitamente todos los privilegios que posee, es decir, en el diseño de su sistema era una especie de combinación de privilegios de usuario y licencias para el uso de archivos de inicio.

Por lo tanto, estos chicos estaban realmente interesados ​​en resolver este problema. Y de alguna manera llamaron a este compilador un "ayudante estúpido", porque tenía que distinguir entre los muchos privilegios que tenía y usarlos con cuidado si fuera necesario.

Por lo tanto, deberíamos considerar cómo desarrollar un compilador similar en Unix . En su sistema, todo estaba vinculado a esta licencia de archivo. Existen otros mecanismos que luego introdujeron en su programa para identificar oportunidades, hablaremos de ellos en un futuro próximo. Pero, ¿podemos resolver este problema en un sistema Unix ?

Suponga que tiene que escribir este compilador de Fortran en Unix , escribir este archivo especial y evitar el problema. Que harias Alguna idea? Creo que simplemente puede declarar que este es un mal plan y, por ejemplo, no mantener estadísticas. O no es compatible con el tipo de entrada de datos - oh . Por otro lado, puede especificar qué código fuente desea compilar para poder leer el archivo / bill o el archivo de estadísticas, que puede ser secreto.

O tal vez podría proporcionar soporte para el código fuente estándar, pero luego tendría que contener partes de otro código fuente, por lo que es un poco absurdo.

Audiencia: se podrían compartir los privilegios del compilador.

Profesor: sí, ese sería otro diseño potencialmente bueno compartiendo sus credenciales. Sabemos que, de hecho, el compilador Fortran no necesita ambos privilegios al mismo tiempo. Entonces, quizás, hablando en Unix , podríamos crear un compilador como world / bin / fortcc , y sería solo un programa regular sin privilegios adicionales. Y luego crearíamos / bin / fortlog , que será un programa especial con algunos privilegios adicionales, y recopilará estadísticas sobre lo que está sucediendo en el compilador, y la función fortcc llamará a fortlog . Entonces, ¿qué privilegios le daríamos a este fortlog ?



Público: tal vez si usa algo como setuid o fortlog , cualquier otro usuario también puede registrar cualquier información arbitraria a través de él.

Profesor: sí, así que no es tan bueno. Debido a que la única forma en Unix de otorgar privilegios adicionales a fortlog es convertirse en su propietario, no sé, tal vez crear fort UID y setuid . Y cada vez que ejecuta fortlog , cambia a ese UID de fortaleza . Y, quizás, todavía se necesita algún archivo de estadísticas especial aquí. Pero, después de todo, todos pueden llamar a este fortlog .



Y esto no es bueno, porque cualquiera puede escribir en el archivo de estadísticas. En este caso, por seguridad, este es un pequeño problema, pero ¿qué sucede si en lugar de stat es un archivo de pago de facturas ? En este caso, los problemas serán mucho más serios.

Unix tiene un mecanismo bastante complicado, que omitimos de la última conferencia del lunes. Este mecanismo permite que la aplicación cambie entre múltiples uid . Por lo tanto, para ejecutar diferentes aplicaciones, puede cambiar entre ID de usuario. Es un poco difícil de hacer de la manera correcta, pero factible. Entonces, este mecanismo puede ser otro diseño potencial de nuestro sistema.

Creo que podría hacer un truco más: hacer que el fortlog “binario” sea ejecutable solo para un determinado grupo y cree el binario fortcc setgid para ese grupo. Sin embargo, esto no es muy bueno, ya que borra cualquier lista de grupos que el usuario tenía originalmente. Pero quién sabe, quizás esto sea mejor que nada.

En cualquier caso, este es un problema bastante complicado, pero se puede resolver completamente utilizando mecanismos Unix . Tal vez debería repensar su problema y no estar demasiado preocupado por el archivo de estadísticas estadísticas, poniendo su seguridad primero. ¿Qué está mal en nuestro proyecto?

Hay dos cosas a tener en cuenta si algo sale mal. El primero se llama autoridad ambiental , o autoridad externa. ¿Alguien entiende lo que querían decir? Nunca dieron esta definición exacta.

Público: esto significa que tiene la autoridad que le otorga el medio ambiente. Como si fuera un usuario actuando sin restricciones.

Profesor: sí, está realizando una operación, y puede indicar qué operación desea realizar, pero la decisión sobre si esta operación será exitosa proviene de algunos parámetros indirectos adicionales en su proceso.

En Unix, puede averiguar cómo se verá la verificación de la autoridad ambiental. Por lo tanto, si realiza una llamada al sistema, probablemente le dio un nombre al sistema. Y dentro del núcleo, este nombre se asigna a algún objeto. Y este objeto supuestamente contiene dentro de sí algún tipo de lista de control de acceso, por ejemplo, permisos para este archivo, etc.



Por lo tanto, hay algunos permisos que puede obtener de este objeto, y debe determinar si se permitirá la operación con este nombre que se le otorgó a la aplicación, es decir, se crea la cadena Nombre -> Objeto -> Permiso . Esto es lo que la aplicación puede ver el proceso.

Dentro del núcleo, está el ID de usuario actual del proceso UID del proceso que hace llamadas. También está involucrado en la decisión de permitir o no la ejecución de una operación en particular. Por lo tanto, este ID de usuario del proceso actual es un privilegio externo. El núcleo intentará verificar cualquier operación que desee realizar utilizando su UID actual y su GID actual, y cualquier otro privilegio adicional que pueda tener. Y si bien hay un cierto conjunto de privilegios que le permiten hacer esto, puede hacerlo. Sin embargo, es posible que no desee utilizar todos estos privilegios para abrir un archivo específico o realizar cualquier otra operación.

¿Entiendes cuáles son estos privilegios ambientales , privilegios externos? En el caso del sistema operativo, esto significa que el proceso tiene algún tipo de ID de usuario. ¿Puede dar ejemplos de tales privilegios que no están relacionados con el sistema operativo? Por ejemplo, cuando realiza una operación de identificación de proceso para averiguar si tuvo éxito o no. Un cortafuegos puede servir de ejemplo: si está dentro de la red o tiene una dirección IP interna, puede realizar algún tipo de operación, y si está fuera de la red, la misma operación estará prohibida.

Supongamos que visita algún sitio web que contiene un enlace a otro servidor, y tal vez no quiera usar los privilegios que tiene para seguir este enlace. Porque tal vez esto le dará a alguien acceso a su impresora de red interna y esa persona podrá usarla. Pero en realidad, el que le proporcionó el enlace no debería llegar a su impresora, ya que está ubicada fuera de la red. O el firewall de su navegador, al visitar este enlace, puede hacerlo de manera fraudulenta.



Este es un tipo de equivalente moral de este problema confuso en los modelos de red.

Audiencia: los permisos existentes también afectan esto.

Profesor: si.

Audiencia: porque Capsicum esencialmente usa DAC - control de acceso discrecional.

Profesor: sí, esto se debe principalmente a que los muchachos de Capsicum usan algo como el control de acceso discrecional. Esto significa que el usuario o propietario del objeto decide cómo será la política de seguridad para este objeto. Para Unix, esto es muy natural: estos son mis archivos, y puedo decidir qué quiero hacer con ellos, puedo dárselos o conservarlos. Por lo tanto, casi todos los sistemas DAC se ven así porque necesitan algún tipo de permisos que el usuario pueda cambiar para administrar la política de seguridad de sus archivos.



La otra cara del DAC es el control de acceso obligatorio. Hablaremos de esto más adelante, pero en algún nivel, estos sistemas tienen una visión muy diferente del mundo. Piensan que usted es solo un usuario de la computadora, y alguien más establece una política de seguridad para usar esta computadora. Esta visión vino de los años 70 u 80, cuando los militares realmente querían tener sistemas informáticos secretos en los que trabajasen en algunas cosas que están marcadas como "secretas". Y si está trabajando en cosas que están marcadas como "secretas", y yo estoy trabajando en cosas etiquetadas como "alto secreto", entonces no pueden obtenerlo tan fácilmente. Pero no tengo que establecer los derechos del archivo y así sucesivamente, simplemente no está permitido por algún tipo de persona superior.

Por lo tanto, el control de acceso obligatorio realmente trata de poner varios tipos de políticas de acceso en primer lugar donde hay un usuario y un desarrollador de aplicaciones, y además de ellos, hay otro tipo que establece esta política. Sin embargo, como puedes adivinar, esto no siempre funciona. Hablaremos de esto un poco más tarde. Pero este es el significado esencial del control de acceso discrecional.

Tenemos muchos otros ejemplos de uso de control de acceso externo. Esto no es necesariamente malo, solo debes tener mucho cuidado al usarlo. Si tiene un sistema de privilegios ambientales , debe tener mucho cuidado al realizar operaciones privilegiadas. Debes asegurarte de que realmente estás usando los permisos correctos y no serás engañado accidentalmente, como con este compilador de Fortran hace casi 25 años.

Entonces esta es una de las interpretaciones de lo que está sucediendo. Y esta no es necesariamente la única forma de pensar sobre lo que sale mal, ¿verdad? Otra posibilidad es que sería bueno que la aplicación en sí supiera si debería acceder al archivo en nombre de algún principio. Por lo tanto, el problema número 2 es la complejidad de las verificaciones de control de acceso.



En cierto sentido, cuando el compilador Fortran se está ejecutando, abre el archivo en nombre del usuario, y debe repetir la misma lógica que vemos aquí en el diagrama, excepto que el compilador Fortran debe conectar algo más para el UID del proceso Sur . En lugar de usar los privilegios actuales, simplemente debe repetir la verificación Nombre -> Objeto -> Permiso e intentar hacer esto con un conjunto diferente de privilegios para su UID de proceso .

En Unix, esto es bastante difícil de hacer, porque hay muchos lugares donde se realizan controles de seguridad. Si tiene enlaces simbólicos, entonces el enlace simbólico se escanea y el nombre de la ruta también se evalúa con algunos privilegios, etc. Pero puede suceder que en algunos sistemas se pueda simplificar la verificación del control de acceso si se puede hacer de forma independiente en la aplicación. ¿No crees que este es un plan inteligente? ¿Estarías de acuerdo con eso? ¿Existe el peligro de repetir esta prueba?

Público: si realiza verificaciones en la aplicación, simplemente no podría hacer otras verificaciones.

Profesor: sí, puede saltear fácilmente otros controles, esto es absolutamente cierto. Entonces, en cierto modo, cuando usaron el compilador Fortran aquí, ni siquiera intentó hacer ninguna verificación, por lo que fallaron. Otra consecuencia, además de la falta de comprobaciones, es que el núcleo puede cambiar todo el tiempo, y luego tendrá comprobaciones ligeramente diferentes. Esto introducirá algunos requisitos de seguridad adicionales, pero la aplicación no cambiará e implementará el viejo estilo de controles. Entonces este no es un buen plan.

Recuerde que hay una buena idea en el campo de la seguridad: una reducción en el número de mecanismos involucrados. Por lo tanto, el programa tiene solo un pequeño número de lugares en los que se aplican las políticas de seguridad. Probablemente no desee repetir la misma funcionalidad en las aplicaciones, en el núcleo, etc. Realmente desea centrar estos controles en un solo lugar en el programa. Entonces, ¿cuál debería ser la solución al problema de otorgar autoridad?

Lo más cercano a resolver el problema son las capacidades de descripción de archivos en Unix .



En el mundo de las posibilidades, una alternativa a este esquema es que en lugar de seguir el nombre de la cadena -> Objeto -> Permiso y decidir si usarlo en función de los permisos externos del UID del proceso de proceso , puede usar un esquema muy simple.

Supongamos que tiene capacidades relacionadas con un objeto específico. Y estas características pueden tener una serie de limitaciones en cuanto a lo que puede hacer con este objeto.



Pero básicamente, si tiene oportunidades para este objeto, puede acceder a él. . , , , .
, Capability , , , , . . Capability , - , — .

Capability , . , ?

, , . , . , , .

, , , « ». , , Capsicum ? ?

: , , , Capability .

: , , , , . — . Unix , 0, , 1, . . , , . , - , , . PID , , PID:57 , . , , . , , , , , .. .



, , , . , -, - , .

, , , Unix , , , /etc/pwd .

. . , . , « »?



, , integer . , . , .

, . , ? , . , .

, , Capability , Fortran . sysx/fort ? , ?

: , . , , output- . , , .

: , . , Fortran /sysx/stat . , .

, , . , , «» Unix . , , , Fortran , , , , , .

. fort1 , , - , , foo.f , , , — o , . , . , .

, , , . ! , , , , setuid Fortran .



, setuid - , . , . , , , , .

, , , , . , , , Capability , , , , .

26:30

:

Curso MIT "Seguridad de sistemas informáticos". Lección 6: Oportunidades, Parte 2


La versión completa del curso está disponible aquí .

Gracias por quedarte con nosotros. ¿Te gustan nuestros artículos? ¿Quieres ver más materiales interesantes? Apóyenos haciendo un pedido o recomendándolo a sus amigos, un descuento del 30% para los usuarios de Habr en un análogo único de servidores de nivel de entrada que inventamos para usted: toda la verdad sobre VPS (KVM) E5-2650 v4 (6 núcleos) 10GB DDR4 240GB SSD 1Gbps de $ 20 o cómo dividir el servidor? (las opciones están disponibles con RAID1 y RAID10, hasta 24 núcleos y hasta 40GB DDR4).

Dell R730xd 2 veces más barato? ¡Solo tenemos 2 x Intel Dodeca-Core Xeon E5-2650v4 128GB DDR4 6x480GB SSD 1Gbps 100 TV desde $ 249 en los Países Bajos y los Estados Unidos! Lea sobre Cómo construir un edificio de infraestructura. clase utilizando servidores Dell R730xd E5-2650 v4 que cuestan 9,000 euros por un centavo?

Source: https://habr.com/ru/post/es418217/


All Articles