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 3Lección 2: "Control de ataques de hackers"
Parte 1 /
Parte 2 /
Parte 3Lección 3: “Desbordamientos del búfer: exploits y protección”
Parte 1 /
Parte 2 /
Parte 3Lección 4: “Separación de privilegios”
Parte 1 /
Parte 2 /
Parte 3Lección 5: “¿De dónde vienen los sistemas de seguridad?”
Parte 1 /
Parte 2Lección 6: “Oportunidades”
Parte 1 /
Parte 2 /
Parte 3Lección 7: “Sandbox de cliente nativo”
Parte 1 /
Parte 2 /
Parte 3Lección 8: "Modelo de seguridad de red"
Parte 1 /
Parte 2 /
Parte 3 Entonces, ¿qué sucede si el navegador no procesa correctamente el objeto y no puede identificar su tipo? En este caso, puede tener problemas de seguridad. Uno de ellos se llama ataque MIME.
Probablemente esté familiarizado con MIME: este es un tipo de encabezados sin cifrar como text / html, image.jpeg, etc. Entonces, las versiones anteriores del navegador IE usaban esto porque pensaban que ayudaría al usuario. Pero a veces sucede que los servidores web asignan la extensión incorrecta al archivo objeto.
Un servidor web configurado incorrectamente puede adjuntar el sufijo .html a lo que realmente tiene la extensión .jpeg, o viceversa, por ejemplo, crear foo.jpg en lugar de foo.html.

Entonces, en los viejos tiempos, IE estaba tratando de ayudarte. Es decir, fue a tomar algún tipo de recurso, mientras pensaba: "OK, este recurso dice ser de este tipo, de acuerdo con su extensión de nombre de archivo". Pero luego solo verá los primeros 256 bytes disponibles en este objeto. Y si encontraba ciertos significados mágicos que indicaban que había un tipo diferente de extensión para este objeto, simplemente diría: “¡Oye, encontré algo genial aquí! "Creo que el servidor web definió este objeto por error, así que permítanme tratarlo como el tipo que encontré en estos primeros 256 bytes".
Y luego todos se vuelven ganadores, porque un navegador como ayudó al desarrollador del servidor web, ya que ahora su sitio se mostrará correctamente. Y al usuario le gustará, porque podrán desbloquear este contenido, que solía ser basura.
¡Pero esta es una clara vulnerabilidad! Supongamos que la página contiene contenido pasivo, por ejemplo, una imagen de un dominio controlado por un atacante. Sin embargo, la página de la víctima piensa: "incluso si es el contenido de un sitio malicioso de piratas informáticos, es solo contenido pasivo. ¡No puede hacerme nada! En un caso extremo, se mostrará una imagen fallida, pero no podrá abrir ningún código, porque el contenido pasivo tiene cero privilegios.

Pero el hecho es que IE puede primero "oler" esta imagen, sus primeros 256 bytes. Y un atacante puede poner intencionalmente código HTML y JavaScript allí. Luego resulta que el sitio de la víctima traerá lo que considera una imagen, y IE ejecutará código malicioso en el contexto de la página incrustada.
Este es un tipo de ejemplo de cuán complejos son los navegadores y cómo agregar incluso buenas intenciones puede causar errores de seguridad muy sutiles. Así que echemos un vistazo más de cerca a cómo el navegador protege varios recursos.
Veamos los marcos y los objetos de ventana (objetos que son una ventana que contiene un documento DOM). Los marcos representan estos universos JavaScript independientes de los que hablamos aquí. Quiero decir, JavaScript es una instancia del nodo DOM, como se muestra en la imagen del árbol DOM.
De esa manera, el marco existirá como un objeto de nodo DOM en algún lugar de esta jerarquía que sea visible para JavaScript.
En JavaScript, el objeto de ventana es en realidad un alias para el espacio de nombres global. Suena como una idea estúpida. Es decir, si encontrara el nombre de la variable global x, también podría acceder a él a través del nombre window.x.
Por lo tanto, los marcos y los objetos de ventana son referencias muy poderosas para darle accesibilidad. Y contienen punteros entre sí. Un marco puede contener un puntero a un objeto de ventana vinculado y viceversa. De hecho, estas dos cosas son equivalentes.
Tanto los marcos como los objetos de ventana reciben el origen de origen del marco URL, o como siempre están en una parte segura de la red, pueden obtener el sufijo del nombre de dominio original, es decir, su origen original.
Por ejemplo, un marco puede comenzar así: .xyzcom, aquí puede ignorar el esquema y el protocolo por un segundo.
En este caso, podemos suponer que la fuente de origen de (document.domain) es el sufijo yzcom. Del mismo modo, la fuente de origen de este documento es la expresión z.com. Esto es posible porque z.com es un sufijo de yzcom.

Lo único que no puede servir como tal fuente es la expresión .ayzcom, porque es el sufijo incorrecto para la fuente de origen. Además, el sufijo de fuente correcto de la fuente de origen no puede considerarse simplemente .com, porque en este caso el sitio podrá afectar de alguna manera las cookies o algo así en cualquier sitio como .com, lo que puede tener consecuencias bastante devastadoras.
La motivación de por qué este tipo de cosas son aceptables es que está relacionado con algún tipo de relación de confianza existente. Entonces parece que con los tres parámetros principales todo está en orden, y el trastorno solo está en .com.
Audiencia: ¿ resulta que es posible hacer tales divisiones en cualquier punto o en el punto final? Por ejemplo, ¿se puede cambiar su xyzcom a su z.com?
Profesor: no, esto solo se aplica a cada punto.
Público: ¿hay alguna razón por la que no se haya hecho para que pueda indicar un super o subdominio, pero al mismo tiempo deberían acordar de alguna manera de dónde vendrá la información? Digamos que quiero aceptar solo lo que tiene el mismo origen que el mío, para que cualquiera de estos recursos pueda atacarme. Además, haríamos esta interacción simétrica, para que yo también pudiera influir en ella. Después de todo, el sufijo .com de origen significa que cualquier cosa que tenga el mismo sufijo .com puede afectarme.
Profesor: sí, esto es difícil, por lo que hay varias respuestas a esta pregunta. En primer lugar, la gente estaba muy preocupada por la posibilidad de un ataque con .com. Por lo tanto, querían que el lenguaje de manipulación de dominio fuera fácil de entender. Por lo tanto, no permitieron estropear la configuración.
En un segundo hablaré sobre una cosa que le permite hacer lo que está hablando, pero solo con respecto a los sufijos de dominio. Por ahora, quiero señalar que la interfaz Publicar mensaje permite a los dominios comunicarse entre sí si están de acuerdo con esto. Entonces, en la práctica, las personas usan Publicar mensaje para implementar la comunicación entre dominios si no pueden establecer la misma fuente de origen utilizando los trucos descritos anteriormente. De esta forma, los navegadores pueden restringir dominios de acuerdo con estos sufijos del dominio de origen. Y aquí también hay un pequeño matiz interesante: los navegadores entienden cuándo se puede escribir (document.domain) y cuándo no.
Hay una razón para esto, que consideraremos en un segundo. Por lo tanto, dos marcos pueden acceder entre sí si al menos una de las siguientes dos condiciones es verdadera:
- ambos conjuntos de marcos establecen (document.domain) el mismo valor;
- ninguno de estos marcos puede cambiar (document.domain), a pesar de que el valor de este documento en ambos marcos es el mismo.

La idea principal de estas reglas es que protegen el dominio del ataque causado por sus propios errores o la nocividad de uno de los subdominios.
Imagine que tiene un dominio xyzcom que está intentando atacar el dominio yzcom porque el primer dominio contiene un error o es malicioso. Intentará acortar el dominio yzcom a un aspecto .com, y luego comenzará a "quimizar" con el estado de JavaScript, cookies u otras cosas.

Entonces, estas dos reglas significan que si yzcom no quiere permitir que nadie interactúe con él, nunca cambiará el valor (document.domain). Entonces, cuando el marco xyzcom quiere acortarlo, el navegador dirá: "Sí, quieres acortarlo, ¡pero no tienes derecho a hacerlo!" Hay una coincidencia de valores, pero el dominio yzcom no ha indicado que quiera participar en esto. ¿Eso está claro? En este caso, se puede ver que la mayoría de los marcos funcionan con la misma política de origen.
Ahora podemos ver cómo se procesa nuestro nodo DOM. Es bastante simple Típicamente, los nodos DOM obtienen origen del marco circundante. En el caso de las cookies, esto es algo más complicado. Las cookies tienen un dominio y tienen su propio camino. Por ejemplo, podría imaginar que una cookie podría asociarse con la siguiente información, por ejemplo * .mit.edu / 6.858. En este caso, la cookie tiene un * .mit.edu / domain y una ruta 6.858.

Tenga en cuenta que este dominio puede ser el sufijo completo de las páginas en el dominio actual. Así que puedes realizar los mismos trucos con él que los que mencionamos anteriormente. Tenga en cuenta que esta ruta 6.858 también se puede representar como una barra diagonal, seguida de nada, lo que indica que todas las rutas de dominio deben tener acceso a la cookie que se encuentra aquí.
Pero en este caso, tenemos una dirección de ruta específica. Entonces, quien establezca estas cookies, tiene la oportunidad de ver cómo se ve el dominio y la ruta. Y estos valores se pueden establecer tanto en el lado del servidor como en el lado del cliente. En el lado del cliente, tendrá un objeto JavaScript llamado document.cookie. Este es el formato utilizado para indicar todas las rutas a objetos similares.
Hay una bandera de seguridad de bandera segura que puede establecer en una cookie para indicar que es un archivo HTTPS. En este caso, el contenido HTTP no debería tener acceso a esta cookie. Esta es la idea principal de las cookies.
Tenga en cuenta que cada vez que un navegador genera una solicitud a un servidor web específico, incluirá todas las cookies relevantes en esta solicitud. Existe una especie de línea de correspondencia y algoritmos que permiten descubrir que estas son las cookies correctas que deben enviarse en respuesta a una solicitud, ya que pueden tener cosas extrañas con sufijos de dominio, etc.
Público: ¿ pueden los marcos acceder a las cookies de los demás si cumplen con estas reglas?
Profesor: sí, los marcos pueden hacer esto. Pero depende de cómo se configure document.domain, el dominio de cookies y la ruta. Entonces, los marcos pueden acceder a las cookies de los demás, por lo tanto, surge la pregunta: ¿puede haber un problema si permitimos que los marcos arbitrarios escriban cookies arbitrarias para las personas? Baste decir que será malo. La razón por la cual esto es malo es porque estas cookies permiten que el lado del cliente de la aplicación almacene los datos del usuario.
Entonces, puede imaginar que si un atacante puede controlar o anular las cookies del usuario, puede, por ejemplo, cambiar la cookie de Gmail para que el usuario inicie sesión a través de la cuenta de Gmail que pertenece a este atacante. En este caso, un atacante podría leer cualquier carta de usuario. Puede imaginar que alguien podrá obtener cookies de Amazon.com para colocar todo tipo de compras ridículas y similares en su cesta.
Por lo tanto, las cookies son un recurso muy importante para la protección. Y muchos ataques a la seguridad de la red están diseñados para robar y usarlos para hacer daño.
Hay otra pregunta interesante relacionada con las cookies. Supongamos que tiene un sitio foo.co.uk. ¿Qué sucede si un sitio con este nombre de host puede establecer cookies para co.uk?

Aquí hay una sutileza relacionada con las reglas que discutimos anteriormente, porque el primer sitio debería poder acortar su dominio y establecer cookies para el segundo, todo parece legal aquí. Pero desde un punto de vista humano, lo miramos con recelo, porque entendemos que co.uk es un dominio atómico único. Sin embargo, esto es equivalente a .com. Podemos decir que los británicos arruinaron que deberían tener un punto aquí. Pero eso no es culpa de ellos. Desde un punto de vista moral, este es un dominio único que no se puede romper. Por lo tanto, debemos tener una infraestructura especial para que las cookies funcionen correctamente.
Mozilla tiene un sitio web llamado publicsuffix.org que contiene listas de reglas sobre cómo se deben acortar las cookies, el origen y los dominios, teniendo en cuenta que puede haber puntos en algunas cosas, mientras que, de hecho, deben considerarse como un solo atómico el todo
Entonces, cuando su navegador descubra cómo debe manipular las diferentes cookies, tendrá que verificar este lado del problema. O de alguna manera asegúrese de que foo.co.uk no pueda acortar el dominio a co.uk. Entonces hay un tema muy delicado aquí.
Hay muchos más problemas de seguridad web interesantes que descubrimos en el proceso, porque gran parte de la infraestructura original se desarrolló específicamente para el idioma inglés. Por ejemplo, texto ASCII o algo así. Originalmente no fue diseñado para ser utilizado por la comunidad internacional.
Pero a medida que Internet se hizo más popular, la gente comenzó a decir: "oye, al principio creamos un diseño bastante grande de soluciones y ahora tenemos que hacerlo adecuado para las personas que se ven obligadas a usar nuestra comprensión limitada de lo que significa el lenguaje". Por lo tanto, ahora enfrentamos todos estos problemas locos.
Considere cómo las respuestas HTTP XML son manejadas por la misma política de origen de origen. Por defecto, JavaScript solo puede generar uno de ellos si está construido en su servidor de origen. Sin embargo, hay una nueva interfaz llamada Solicitud de origen cruzado, o CORS.
Entonces, este es el mismo origen, a menos que el servidor haya habilitado este dispositivo CORS. Básicamente, se agrega un nuevo encabezado de respuesta HTTP llamado Access-Control-Allow-Origin.

Digamos que JavaScript de foo.com quiere hacer una solicitud XML HTTP a bar.com. Como se describe en las reglas, el origen cruzado tiene lugar aquí. Y si el servidor bar.com quiere permitir esto, devolverá su respuesta HTTP con el título: "sí, dejo que foo.com me envíe estas solicitudes XML XML de origen cruzado".
En realidad, el servidor de bar.com puede responder "no", es decir, puede rechazar la solicitud. En este caso, el navegador no puede completar la solicitud HTTP XML. Así que este es un tipo de cosa nueva, que apareció principalmente debido a aplicaciones mixtas. Es necesario para aplicaciones de diferentes desarrolladores y diferentes dominios, para que tengan la oportunidad de intercambiar datos entre sí.

Entonces, en lugar de foo.com, puede haber asteriscos aquí si alguien quiere obtener datos de origen cruzado, y así sucesivamente. Creo que esto es bastante simple. Hay muchos otros recursos que podríamos mirar, como las imágenes. Gracias a Access-Control-Allow-Origin, un marco puede cargar imágenes desde cualquier fuente que desee. Pero no puede verificar los bits de esta imagen, porque se cree que con diferentes políticas de fuentes de origen no es bueno verificar el contenido de los archivos de cada uno.
Aunque el marco no puede verificar los bits, aún puede inferir el tamaño de las imágenes porque ve cómo se colocan en la página. Entonces, este es otro de estos casos extraños cuando la misma política de fuente de origen supuestamente intenta evitar todas las filtraciones de información. Pero, de hecho, no puede evitar todo esto, porque la herencia de incrustación, de hecho, muestra algunos tipos de información.
CSS es similar a las imágenes, por lo que un marco puede incrustar CSS desde cualquier fuente. Sin embargo, no puede verificar directamente el texto dentro del archivo CSS si es de otra fuente. Pero puede reconocer lo que hace este CSS porque simplemente crea un grupo de nodos y luego observa cómo cambia su estilo. Y se ve un poco extraño.
JavaScript es mi ejemplo favorito de cómo esta misma política de origen intenta admitir cualquier tipo de secuencia inteligente. La idea aquí es que si busca JavaScript de forma cruzada, entonces esto está permitido. Puede habilitar la ejecución de JavaScript externo en el contexto de su propia página, pero no puede mirar el código fuente.

Por lo tanto, si tiene una fuente de etiqueta de script igual a algo fuera de su dominio, cuando se ejecuta esta fuente, puede iniciar funciones en ella. Pero no podrá ver el código fuente de JavaScript en él.
Todo esto se ve muy bien, pero tiene un montón de "agujeros". Por ejemplo, JavaScript es un lenguaje de script dinámico. Y las funciones son objetos de primera clase. Por lo tanto, para cualquier función f, simplemente puede usar la función f.tostring (), y esto le dará el código fuente de la función f. Y la gente hace esto todo el tiempo, hacen reescritura dinámica y cosas por el estilo.

Por lo tanto, aunque las políticas de origen no le permiten ver directamente el contenido de la etiqueta del script, simplemente puede realizar la operación especificada y obtener el código fuente.
Del mismo modo, puede obtener su servidor doméstico de su dominio, solo para obtener el código fuente y luego enviárselo. Es decir, de hecho, acaba de pedirle a su servidor doméstico que ejecute el programa Wget para obtener el código fuente de esta manera. Por lo tanto, también parece un poco tonto, es decir, la política de origen aquí es un poco extraña.
Público: suponga que la razón por la que hacen esto es para evitar que el usuario reciba JavaScript, porque entonces también se pueden enviar cookies. Es decir, el usuario podrá adaptar el JavaScript resultante a sus necesidades.
Profesor: sí, lo es.
Público: así que si logra que su servidor haga esto, no podrá proporcionarle cookies personalizadas.
Profesor: esto es cierto, aunque en la práctica el código fuente "en bruto" no está destinado a ser reelaborado por el usuario. Pero tienes razón en que esto evitará algunos ataques.
, , JavaScript, . , - , -, , . , , , . , , .
, . - - , - HTML JavaScript. , , . .
, JavaScript, , . Java, .

, HTML5 , , , , Java. , .
, HTTP, cookie. , URL, ?

, URL- bank.com. , - . , URL, , , $500 . , .
— , origin, bank.com - , , cookie . : «, , , $500 attacker! , ».
. , , , , . . , , , , - . , , CSRF.
, URL. , c .
, - . – , , :
<form action = “/transfer.cdi”…>
Y dentro de este formulario, tendremos los datos de entrada, que generalmente se utilizan para ingresar texto, pulsaciones de teclas, clics del mouse y similares. De hecho, podemos ocultar esta entrada para que no aparezca en la página del usuario: input type = "hidden", asígnele el nombre del atributo = "csrf" y el valor de valor aleatorio = "a72f ...". Este formulario se generará en el servidor.

Por lo tanto, cuando el usuario va a esta página, en el lado del servidor, el servidor genera este valor de aleatoriedad = "a72f ..." y lo incrusta en el HTML que recibe el usuario. Por lo tanto, cuando el usuario completa este formulario, esta URL del formulario:
bank.com/xfer?amount=500&to=attackerSe complementa con una ficha aleatoria:
http:
Esto significa que ahora el atacante debería poder adivinar el token específico que el servidor genera para el usuario cada vez que va a la página del banco. Entonces, si tenemos un valor lo suficientemente aleatorio, el pirata informático no podrá falsificar nada, porque si indica el token incorrecto, las reglas del servidor rechazarán su solicitud.
58:00 min
Continuación:
Curso MIT "Seguridad de sistemas informáticos". Lección 8: Modelo de seguridad de red, parte 3La 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).
VPS (KVM) E5-2650 v4 (6 núcleos) 10GB DDR4 240GB SSD 1Gbps hasta diciembre de forma gratuita al pagar por un período de seis meses, puede ordenar
aquí .
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?