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: Spectre
escapatorias, 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 Spectre
es 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 Spectre
que 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.
Cuando nuestra computadora está funcionando, el programa se carga desde el dispositivo de almacenamiento CPU
y CPU
se 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.
A continuación, CPU
nos la memoria.La memoria almacena muchos programas que está ejecutando, incluido el sistema, los datos del usuario, etc., y también almacena los CPU
resultados intermedios de la operación.
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.
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.
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
,1ms
la me dice: ¡No!La contraseña es
B
,1ms
la me dice: ¡No!
La contraseña es
C
,1.1ms
la 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
?
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?
De la misma forma podremos seguir verificando Ca、Cb、... Co
y 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!
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, Menory
0 o no.
En este momento, se pronosticará cuando CPU
espere datos de la memoria. Suponiendo que la lectura de la memoria devuelve 0, CPU
puede 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, CPU
se ha ejecutado con éxito y CPU
puede 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.
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:
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):
Ú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é.
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.
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.
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.
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.
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 name
el 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 Tools
el elemento (Xth element of A) de . Supongamos que leemos que la memoria de la víctima contiene 3
:
Esto es algo que no deberíamos leer, pero podemos hacer lo siguiente con ejecución especulativa:
CPU
Después de ejecutar este comando que no debe ejecutarse, CPU
creo que necesita ver cuál A[X]
es el valor de . En este momento, CPU
no compruebo A[X]
si el subíndice ha cruzado los límites, porque CPU
creo 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 Tools
almacenado 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é!
El último paso es Tool
atravesar 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 a
en el caché!
Cuando la ejecución especulativa encuentra un error, revierte los cambios de registro, ¡pero no el caché!
Por lo tanto, la información se filtra, ¡porque acceder al elemento 3
th 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 Tools
esta á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 JavaScript
implementar , JavaScript
y 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áCookie
relacionada 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 5
microsegundos . 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 Buffer
para 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 Group
es un conjunto de tab、window
OR 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 API
entre 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 Group
bajo .
COOP
: Póliza de apertura de origen cruzado, correspondiente a HTTP Header
es Cross-Origin-Opener-Policy
.
Al COOP
establecer 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 Header
es Cross-Origin-Embedder-Policy
.
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 JavaScript
comandos , y algunas páginas maliciosas pueden <img>
cargar JSON
archivos .
De lo contrario 站点隔离
, el contenido del JSON
archivo 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 Spectre
aprovechar 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 CORB
en función de su MIME
tipo .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 Spectre
esencialmente 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 Spectre
má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电子书打包下载
点赞和在看就是最大的支持❤️