¡Magia! ¿Unas pocas líneas de JS pueden leer todos los datos en la computadora?

He analizado muchas estrategias de navegador para usted antes:

Después de leer estos artículos, muchos estudiantes dijeron que estaban confundidos, de hecho, estas estrategias mencionaron una escapatoria: Spectreescapatorias, qué magia tiene esta escapatoria, para que los navegadores actualicen con frecuencia las estrategias para ello, hoy les explico.

Espectro

Si una laguna es difícil de construir, incluso si puede causar un gran daño, es posible que no atraiga tanto la atención de los navegadores. Entonces nuestro protagonista de hoy Spectrees fácil de construir, y el daño causado también es grande   Spectre. Puedes:

Con solo unas pocas líneas JavaScript, puede leer todos los datos en la computadora/teléfono móvil, la página web en el navegador puede leer todas sus contraseñas y saber qué están haciendo otros programas. Esto ni siquiera requiere que el programa que escribe sea vulnerable, porque se trata de una vulnerabilidad a nivel de hardware del ordenador.

Para entender Spectre, necesitamos el conocimiento de los siguientes tres aspectos:

  • Comprender qué es un ataque de canal lateral

  • Comprender cómo funciona la memoria.

  • Comprender la ejecución predictiva de la computadora

De hecho, todos son conocimientos informáticos muy básicos, que todos pueden haber aprendido en la escuela, por lo Spectreque utiliza inteligentemente los tres principios anteriores, echemos un vistazo a ellos uno por uno.

No tienes que preocuparte en absoluto, te lo explicaré de la manera más sencilla, primero desmonta este conocimiento y finalmente únelo, en realidad es muy fácil de entender.

como funciona la memoria

Primero, nuestras computadoras se componen de muchas partes:

  • Almacenamiento: memoria, disco duro, etc.

  • UPC

  • Dispositivos de entrada y salida: teclado, ratón, etc.

f8bf76f7df9bffef36b4a2e80bf4b98b.png

Cuando nuestra computadora está funcionando, el programa se carga desde el dispositivo de almacenamiento CPUy CPUse encarga de procesar una gran cantidad de operaciones, estas operaciones requieren que los datos en la memoria sean leídos muchas veces. Luego envíe los resultados a dispositivos de salida como nuestros monitores, lo que probablemente sea un principio de funcionamiento simple de una computadora.

b47ff41c2d1928d5c891484a9ac3d040.png

A continuación, CPUnos la memoria.La memoria almacena muchos programas que está ejecutando, incluido el sistema, los datos del usuario, etc., y también almacena los CPUresultados intermedios de la operación.

de20436921b3b5605555c8dd460c27c7.png

Para almacenar tanta información, necesitamos un método de almacenamiento normalizado.Podemos pensar en la memoria como un montón de pequeños bloques de memoria dispuestos, cada bloque de memoria contiene un poco de información.

ee53a176aa3be1486d2289db648d07ac.png

Además, hay muchas capas de memoria, y es muy lento para la CPU leer datos en ella, por lo que hemos creado varios niveles de cachés en la CPU y la memoria. Cuando recuperamos datos almacenados en caché, la velocidad será más rápido. . Al acceder a un dato que no se ha almacenado en caché, los datos crearán una copia en la memoria caché, y la próxima vez que se acceda, será muy rápido.

39747367b386505ad60e236a45050ad3.png

Este es el principio general de funcionamiento de la memoria. Por supuesto, este proceso se simplifica mucho. Solo necesitamos una comprensión simple aquí.

ataque de canal lateral

Entonces, ¿qué es el bypass ( side-channel)?

Simplemente podemos entenderlo de esta manera: si se generan otras funciones fuera del canal de comunicación normal de su programa, estas funciones reflejan la información que no desea generar, si alguien obtiene esta información, la filtrará. El canal de información generado por esta característica de borde se denomina derivación.

Por ejemplo, cuando su memoria está realizando operaciones, se genera una onda de radio. Esta onda de radio refleja el contenido de la memoria. Alguien recopila esta onda de radio utilizando un método específico, que crea una derivación. Un ataque de canal lateral se denomina ataque de canal lateral.

Las omisiones comunes son: retraso, anormalidad, consumo de energía, electromagnético, ruido, luz visible, mensaje de error, frecuencia, etc. .

Tomemos un ejemplo de un ataque de canal lateral basado en retraso:

Supongamos que queremos que la computadora verifique la contraseña, como nuestra contraseña es ConardLi.

Adivinemos desde el punto de vista del atacante, cuál es la contraseña, adivinemos a partir de una letra:

  • La contraseña es A, 1msla me dice: ¡No!

  • La contraseña es B, 1msla me dice: ¡No!

26ab4f78baa4dbd2d6c7f9a6210d8261.png
  • La contraseña es C, 1.1msla me dice: ¡No!

¿Encontraste algún problema? Adivinamos la primera letra correctamente, pero ¿ha aumentado la cantidad de tiempo que la computadora nos dice que la contraseña es incorrecta 0.1ms?

45839f916b4b09e5a40633deddf26555.png

Porque esta vez, después de que la computadora encuentre que el primero coincide, necesita verificar si el segundo coincide, por lo que tomará más tiempo. ¿No es muy inteligente?

ea7f041c9a33b0313ca834954bb35f2c.png

De la misma forma podremos seguir verificando Ca、Cb、... Coy finalmente adivinar nuestra contraseña.

En este momento, nuestro tiempo de adivinación y la longitud de la contraseña son lineales, y podemos adivinar la contraseña con una complejidad de tiempo O(n). Si se dispara directamente, ¡necesitamos calcular al menos 52 elevado a la octava potencia!

¡Ese es un ataque de canal lateral, el maldito encanto!

44f454e9340013e475fe19c871dae8ce.png

Ejecución especulativa de la CPU

Como mencionamos anteriormente, cuando la CPU se está ejecutando, con frecuencia obtendrá información de la memoria. Pero la lectura de la memoria es muy lenta, y la CPU pasa mucho tiempo inactiva esperando los datos en la memoria. Esto obviamente no es una buena solución.

Entonces, la gente se pregunta, ¿puede la CPU especular sobre el comando que debe ejecutarse?

Supongamos que tenemos el siguiente código, que juzga y ejecuta diferentes declaraciones en función de ciertos datos en la memoria:

if(Menory === 0){
  // 进行第一步计算
  // 进行第二步计算
  // 进行第三步计算
}

Aquí hay dos posibilidades, Menory0 o no.

f7b364174efd4a529ca32c98d07ba908.png

En este momento, se pronosticará cuando CPUespere datos de la memoria. Suponiendo que la lectura de la memoria devuelve 0, CPUpuede apresurarse directamente sin esperar a que regrese la memoria: omita el juicio if y ejecute directamente el comando de cálculo interno.

Luego, si la memoria realmente devuelve 0, CPUse ha ejecutado con éxito y CPUpuede continuar ejecutando los siguientes comandos. Pero si la memoria no devuelve 0, la CPU revertirá los resultados de la ejecución anterior.

Por lo tanto, la ejecución de la CPU debe ser muy cuidadosa y no puede sobrescribir directamente el valor del registro, para cambiar realmente el estado del programa e inmediatamente revertir los cambios una vez que falla la predicción.

principio de ataque

Anteriormente, hemos dominado todos los factores utilizados por esta vulnerabilidad, echemos un vistazo a lo que es.

Digamos que debajo está nuestro caché y leerlo es lento. El kernel del sistema lo bloquea y lo asigna a diferentes programas, posiblemente a diferentes máquinas virtuales si se considera la computación en la nube.

619b05f14efef5ae521d7031f0a0873b.png

Los bloques de memoria que pueden ser asignados por diferentes programas son adyacentes, ¡continuemos usando el caché HTTP del artículo anterior y no lo usemos indiscriminadamente! ¡Recomiende la mejor pose para una configuración de caché! Ejemplo en:

El bloque de memoria rojo almacena los datos de nuestra víctima, como una determinada contraseña de la víctima:

807616ab1c41236a6f8acf34b2ede21b.png

El sistema operativo intentará asegurarse de que un programa no pueda acceder a los bloques de memoria que pertenecen a otros programas, y los bloques de memoria de diferentes programas serán aislados.

Entonces otros programas no pueden leer directamente los datos de la "víctima" (área roja):

2e03fb9a7708bd411702d8909a17abad.png

Únase a nosotros tratando de acceder directamente al área roja que definitivamente no se lee, pero es posible que ya haya algunos datos en el caché, intentemos hacer algo con el caché.

60f1f74a50952e1bcd13a7b3b240f889.png

En el bloque de memoria morado ponemos un array A. Esta memoria pertenece a nuestro programa y se puede acceder legalmente, pero es pequeña y solo tiene dos bits.

466303ca37d4f31c887debaed2538623.png

Pero no estamos satisfechos con leer dos elementos en la matriz A, intentamos salir del rango de A (subíndice fuera de los límites) y acceder al bit X de la matriz A. Pero X puede estar mucho más allá de la longitud de la matriz A.

abb459e01b7c5232ae63f775a38660fd.png

Normalmente, la CPU bloqueará esta operación, arrojará un error: "Operación ilegal", y la operación se verá obligada a finalizar, pero podemos intentar observar el proceso nuevamente y veremos cómo se hace.

Creamos una nueva área nuevamente dentro del rango de memoria al que permitimos el acceso, que se puede llamar caja de herramientas.

79ce4983e2db97c44dd3e92307fb7b7f.png

Le pedimos específicamente a la CPU que no copie estos datos en el caché, sino que los mantenga en la memoria, que es un área de memoria continua.

46eb6e881d0246d3618bf56590eca978.png

Supongamos que la instrucción que ejecutamos es tan larga como esta, en primer lugar hay una declaración de juicio if:

if(name === 'code秘密花园'){
  // ...
}

En términos generales, la ejecución de la CPU ignorará este juicio primero, porque necesita esperar a que nameel sea igual code秘密花园Debido a la tecnología de ejecución predictiva, las cosas en la declaración if se ejecutarán por adelantado.

if(name === 'code秘密花园'){
  access Tools[A[x]]
}

Intentamos leer Toolsel elemento (Xth element of A) de . Supongamos que leemos que la memoria de la víctima contiene 3:

affa8c6ffd4ad65264b6263bf481f8b8.png

Esto es algo que no deberíamos leer, pero podemos hacer lo siguiente con ejecución especulativa:

CPUDespués de ejecutar este comando que no debe ejecutarse, CPUcreo que necesita ver cuál A[X]es el valor de . En este momento, CPUno compruebo A[X]si el subíndice ha cruzado los límites, porque CPUcreo que el kernel siempre verificará si el subíndice está fuera de los límites. Si lo hace, obligará a que finalice el programa. .

Por lo tanto, la ejecución de la predicción consulta directamente A[X]el valor de y luego encuentra que A[X] = 3, es decir:

Tools[A[x]] = Tools[3]

Ese es el cuarto elemento Toolsalmacenado a, el siguiente es el punto clave:

a¡ Después de que la CPU accede , se coloca a(es decir Tools[3]) en el caché!

105d8052ea5ce39b0d36b54a818e4d82.png

El último paso es Toolatravesar cada elemento en , y encontramos que acceder a los primeros elementos es un poco lento, ¡hasta que el tercero es repentinamente rápido! ¡ Porque el tercer elemento almacena una copia aen el caché!

Cuando la ejecución especulativa encuentra un error, revierte los cambios de registro, ¡pero no el caché!

92e0dd1f9bf31ffd47c8d9ee5dbd786a.png

Por lo tanto, la información se filtra, ¡porque acceder al elemento 3th lleva menos tiempo que a los demás! Esto también se conoce como derivación basada en el tiempo.

Entonces, sabemos que la "víctima" tiene uno en esta ubicación en la memoria 3.

Más tarde, podemos agrandar Toolsesta área, ¡y puedes adivinar otros datos más! Por supuesto, esta es la pérdida que debe tenerse en cuenta cuando se ataca realmente~

Impacto en la Web

Hemos analizado claramente los principios anteriores. De hecho, es muy fácil JavaScriptimplementar , JavaScripty casi todas las verificaciones de límites se pueden omitir en , para lograr una lectura arbitraria de los límites de la memoria. Podemos mirar el siguiente código:

if(index < array.length){
  index = array[index | 0];
  index = (((index * TABLE_STRIDE) | 0) & (TABLE_BYTES - 1)) | 0;
  localJunk ^= probeTable[index | 0] | 0;
}

Múltiples páginas de diferentes sitios pueden terminar compartiendo un proceso en el navegador. Pueden ocurrir problemas cuando una persona usa window.open, o , <a href="..." target="_blank">o abre otra página, y si un sitio web contiene datos confidenciales para un usuario en particular, otro sitio web podría explotar tal vulnerabilidad para leer los datos de ese usuario.iframe

Lo anterior es solo un ejemplo simple. De hecho, la superficie de ataque real es mucho más amplia que esto. Por esta razón, los navegadores han desarrollado muchas políticas de seguridad para resolver este problema. Echemos un vistazo:

política del navegador

Configuración recomendada de caché

El último artículo trata sobre este caché HTTP, ¡no lo uses indiscriminadamente! ¡Recomiende la mejor pose para una configuración de caché!

  • Para evitar el almacenamiento en caché de nivel medio, se recomienda configurar:Cache-Control: private

  • Se recomienda configurar una caché secundaria adecuada key: si la respuesta a nuestra solicitud está Cookierelacionada la solicitud, se recomienda configurar:Vary: Cookie

Ahora debería quedar más claro que para configurar estos dos cachés, el navegador no tiene derecho a matar el caché, solo puede apretar la holgura del caché al máximo y aumentar la dificultad del ataque.

Deshabilitar el temporizador de alta resolución

Para explotar Spectre, un atacante necesita medir con precisión el tiempo que tarda en leer un valor de la memoria. Por lo tanto, se necesita un temporizador confiable y preciso.

La proporcionada por el navegador performance.now() API, la precisión de tiempo puede ser de 5microsegundos . Como mitigación, todos los principales navegadores han reducido performance.now()la resolución de , lo que puede dificultar el ataque.

Otra forma de obtener un temporizador de alta resolución es usar SharedArrayBuffer. web workerÚselo Bufferpara incrementar el contador. El hilo principal puede usar este contador para implementar un temporizador. El navegador está deshabilitado por este motivo SharedArrayBuffer.

rel="noopener"

Un navegador Context Groupes un conjunto de tab、windowOR que comparten el mismo contexto iframe. Por ejemplo, si un sitio web ( https://a.example) abre una ventana emergente ( https://b.example), la ventana de apertura y la ventana emergente comparten el mismo contexto de navegación y pueden acceder DOM APIentre sí de , p window.opener.

Por lo tanto, los navegadores recomiendan que especifique al abrir páginas externas que no son de confianza rel="noopener".

Política de apertura de origen cruzado (COOP)

Al explotarlo Spectre, un atacante puede leer cualquier recurso Context Groupbajo .

COOP: Póliza de apertura de origen cruzado, correspondiente a HTTP Headeres Cross-Origin-Opener-Policy.c97a7d8278003dfb84f86b23f51874d5.png

Al COOPestablecer en Cross-Origin-Opener-Policy: same-origin, puede aislar otras ventanas de diferentes fuentes abiertas desde este sitio web en diferentes navegadores Context Group, creando así un entorno aislado para los recursos.

Para obtener más información, consulte mi artículo: Nueva política de origen cruzado: uso de COOP y COEP para crear un entorno más seguro para los navegadores

Política del Programa de Integración de Origen Cruzado (COEP)

COEP: Política del Programa de Integración de Origen Cruzado, correspondiente a HTTP Headeres Cross-Origin-Embedder-Policy.

7b3b01d0fc13880f8217046ba1869e2e.png

Cuando está habilitado Cross-Origin-Embedder-Policy: require-corp, puede hacer que su sitio cargue solo recursos de origen cruzado que están marcados explícitamente como recursos compartibles o del mismo origen.

No entraré en detalles en detalle, pero lo he cubierto todo en este artículo: Nueva política de dominio cruzado: uso de COOP y COEP para crear un entorno más seguro para los navegadores

Bloqueo de lectura de origen cruzado (CORB)

Incluso si todas las páginas de diferentes orígenes están en sus propios procesos separados, las páginas aún pueden solicitar legítimamente algunos recursos entre sitios, como imágenes y secuencias de JavaScriptcomandos , y algunas páginas maliciosas pueden <img>cargar JSONarchivos .

De lo contrario 站点隔离, el contenido del JSONarchivo se guarda en la memoria del proceso de renderizado, momento en el cual el renderizador notará que no es un formato de imagen válido y no renderizará la imagen. Sin embargo, un atacante podría Spectreaprovechar una vulnerabilidad para leer potencialmente este bloque de memoria.

El bloqueo de lectura de origen cruzado ( ) evita que el contenido entre en la memoria del proceso del renderizador CORBen función de su MIMEtipo .balance

Para conocer los principios detallados, puede leer este artículo: Multidominio, no solo CORS

Referirse a

  • https://www.bilibili.com/video/av18144159/

  • https://zhuanlan.zhihu.com/p/32784852

finalmente

El navegador ha adoptado tantas estrategias, de hecho, solo se puede decir que esta vulnerabilidad se puede paliar hasta cierto punto, de hecho, no se puede eliminar de raíz, porque es Spectreesencialmente una vulnerabilidad a nivel de hardware y aumenta el costo de ataque de la vulnerabilidad.

Esta vulnerabilidad en sí también es difícil de solucionar, ya sea de ejecución predictiva o de caché, el rendimiento se verá muy reducido, por lo que este problema no se ha solucionado a nivel de hardware.

Los navegadores de seguimiento pueden presentar más estrategias o configuraciones recomendadas, puede continuar prestando atención ~

Bueno, después de este artículo, debería ser mucho Spectremás claro , y los artículos anteriores también deberían ser más claros.

Me tomó mucho tiempo dibujar este artículo y puse mucha energía en él. Si aprendes algo, haz clic en 点赞y 在看~

往期干货:
 26个经典微信小程序+35套微信小程序源码+微信小程序合集源码下载(免费) 干货~~~2021最新前端学习视频~~速度领取
 前端书籍-前端290本高清pdf电子书打包下载
点赞和在看就是最大的支持❤️

Supongo que te gusta

Origin blog.csdn.net/qq_36538012/article/details/123700603
Recomendado
Clasificación