¿Qué tan grave es esta nueva vulnerabilidad de seguridad ASP.NET y cómo puedo solucionarlo?

Acabo de leer en la red sobre una vulnerabilidad de seguridad recientemente descubierta en ASP.NET. Puede leer los detalles aquí.

El problema radica en la forma en que ASP.NET implementa el algoritmo de cifrado AES para proteger la integridad de las cookies que estas aplicaciones generan para almacenar información durante las sesiones de los usuarios.

Esto es un poco vago, pero aquí hay una parte más aterradora:

La primera etapa del ataque requiere unos miles de solicitudes, pero una vez que tiene éxito y el atacante obtiene las claves secretas, es totalmente sigiloso. El conocimiento criptográfico requerido es muy básico.

En general, no estoy lo suficientemente familiarizado con el tema de seguridad / criptografía para saber si esto es realmente tan serio.

Entonces, ¿deberían todos los desarrolladores de ASP.NET temer esta técnica que puede ser propietaria de cualquier sitio web ASP.NET en segundos o qué?

¿Cómo afecta este problema al desarrollador promedio de ASP.NET? ¿Nos afecta en absoluto? En la vida real, ¿cuáles son las consecuencias de esta vulnerabilidad? Y, finalmente, ¿hay alguna solución que evite esta vulnerabilidad?

¡Gracias por tus respuestas!


EDITAR: Permítanme resumir las respuestas que obtuve

Entonces, esto es básicamente un tipo de ataque de “oracle de relleno”. @Sri brindó una gran explicación sobre qué significa este tipo de ataque. ¡Aquí hay un impactante video sobre el problema!

Acerca de la gravedad de esta vulnerabilidad: sí, es realmente grave. Le permite al atacante conocer la clave de la máquina de una aplicación. Por lo tanto, él puede hacer algunas cosas muy indeseadas.

  • En posesión de la clave de la máquina de la aplicación, el atacante puede descifrar las cookies de autenticación.
  • Incluso peor que eso, puede generar cookies de autenticación con el nombre de cualquier usuario. Por lo tanto, puede aparecer como cualquier persona en el sitio. La aplicación no puede diferenciar entre usted o el hacker que generó una cookie de autenticación con su nombre.
  • También le permite descifrar (y también generar) cookies de sesión , aunque esto no es tan peligroso como el anterior.
  • No tan serio: puede descifrar el ViewState encriptado de las páginas. (Si usa ViewState para almacenar datos confidenciales, ¡no debe hacer esto de todos modos!)
  • Muy inesperado : con el conocimiento de la clave de la máquina, el atacante puede descargar cualquier archivo arbitrario de su aplicación web, incluso aquellos que normalmente no se pueden descargar. (Incluyendo Web.Config , etc.)

Aquí hay un montón de buenas prácticas que obtuve que no resuelven el problema, pero ayudan a mejorar la seguridad general de una aplicación web.

  • Puede cifrar datos confidenciales con la configuración protegida
  • Use cookies HTTP solamente
  • Prevenir los ataques DoS

Ahora, centrémonos en este tema.

  • Scott Guthrie publicó una entrada al respecto en su blog
  • La publicación del blog de preguntas frecuentes de ScottGu sobre la vulnerabilidad
  • La actualización de ScottGu sobre la vulnerabilidad
  • Microsoft tiene un aviso de seguridad al respecto
  • Comprender la vulnerabilidad
  • Información adicional sobre la vulnerabilidad

La solución

  • Habilite customErrors y cree una sola página de error a la que se redirijan todos los errores . Sí, incluso 404s . (ScottGu dijo que diferenciar entre 404 y 500 es esencial para este ataque). Además, en su Application_Error o Error.aspx ponga algún código que Error.aspx un retraso aleatorio. (Genere un número aleatorio y use Thread.Sleep para dormir durante tanto tiempo). Esto impedirá que el atacante decida qué sucedió exactamente en su servidor.
  • Algunas personas recomendaron volver a 3DES. En teoría, si no usa AES, no encontrará la debilidad de seguridad en la implementación de AES. Como resultado, esto no se recomienda en absoluto .

Algunos otros pensamientos

  • Parece que no todos piensan que la solución es lo suficientemente buena.

Gracias a todos los que respondieron mi pregunta. Aprendí mucho sobre este tema y sobre la seguridad web en general. Marqué la respuesta de @Mikael como aceptada, pero las otras respuestas también son muy útiles.

¿Qué debería hacer para protegerme?

[Actualización 29-09-2010]

Boletín de seguridad de Microsoft

Artículo de KB con referencia al arreglo

ScottGu tiene enlaces para las descargas

[Actualización 2010-09-25]

Mientras esperamos la solución, ayer ScottGu postet una actualización sobre cómo agregar un paso adicional para proteger sus sitios con una regla de URLScan personalizada.


Básicamente, asegúrese de proporcionar una página de error personalizada para que un atacante no esté expuesto a los errores internos de .Net, que siempre debería de todos modos en el modo de lanzamiento / producción.

Además, agregue un tiempo de espera aleatorio en la página de error para evitar que el atacante temporice las respuestas para agregar información de ataque.

En web.config

        

Esto redirigirá cualquier error a una página personalizada devuelta con un código de estado 200. De esta forma, un atacante no puede ver el código de error o la información de error para obtener la información necesaria para futuros ataques.

También es seguro establecer customErrors mode="RemoteOnly" , ya que esto redirigirá a los clientes “reales”. Solo navegar desde localhost mostrará errores internos de .Net.

La parte importante es asegurarse de que todos los errores estén configurados para devolver la misma página de error. Esto requiere que establezca explícitamente el atributo defaultRedirect en la sección y asegúrese de que no se establezcan códigos por estado.

¿Lo que está en juego?

Si un atacante logra usar el exploit mencionado, él / ella puede descargar archivos internos desde su aplicación web. Normalmente, web.config es un destino y puede contener información confidencial, como la información de inicio de sesión en una cadena de conexión de base de datos, o incluso un enlace a una base de datos sql-express que no desea que alguien consiga. Pero si sigue las mejores prácticas, use la Configuración protegida para encriptar todos los datos confidenciales en su web.config.

Enlaces a referencias

Lea el comentario oficial de Microsoft sobre la vulnerabilidad en http://www.microsoft.com/technet/security/advisory/2416728.mspx . Específicamente la parte “Solución” para detalles de implementación sobre este tema.

También algo de información en el blog de ScottGu , incluyendo un script para encontrar aplicaciones ASP.Net vulnerables en su servidor web.

Para obtener una explicación sobre “Comprensión de los ataques de Oracle en el relleno”, lea la respuesta de @ sri .


Comentarios al artículo:

El ataque que Rizzo y Duong han implementado contra las aplicaciones ASP.NET requiere que la implementación de la criptografía en el sitio web tenga un oracle que, al enviar texto cifrado, no solo desencriptará el texto, sino que le dará al remitente un mensaje sobre si el relleno en el texto cifrado es valido

Si el relleno no es válido, el mensaje de error que recibe el remitente le dará cierta información sobre la forma en que funciona el proceso de descifrado del sitio.

Para que el ataque funcione, lo siguiente debe ser cierto:

  • Su aplicación debe dar un mensaje de error sobre que el relleno no es válido.
  • Alguien debe manipular sus cookies encriptadas o viewstate

Por lo tanto, si devuelve mensajes de error legibles para personas en su aplicación como “Algo salió mal, inténtelo de nuevo”, entonces debería estar bastante seguro. Leer un poco sobre los comentarios en el artículo también brinda información valiosa.

  • Almacenar una identificación de sesión en la cookie criptada
  • Almacenar los datos reales en estado de sesión (persistido en un db)
  • Agregue una espera aleatoria cuando la información del usuario sea incorrecta antes de devolver el error, para que no pueda cronometrarla

De esta forma, una cookie secuestrada solo se puede usar para recuperar una sesión que probablemente ya no esté presente o invalidada.

Será interesante ver lo que realmente se presenta en la conferencia de Ekoparty, pero ahora mismo no estoy demasiado preocupado por esta vulnerabilidad.

Comprensión de los ataques Oracle de relleno

Supongamos que su aplicación acepta una cadena encriptada como parámetro, ya sea que el parámetro sea una cookie, un parámetro de URL u otra cosa sea inmaterial. Cuando la aplicación intenta decodificarlo, hay 3 resultados posibles:

  1. Resultado 1 : la cadena cifrada descifrada correctamente, y la aplicación fue capaz de darle sentido. Es decir, si la cadena cifrada era un número de cuenta de 10 dígitos, después de descifrar la aplicación encontró algo así como “1234567890” y no “abcd1213ef”

  2. Resultado 2 : El relleno fue correcto, pero después del desencriptado, la cuerda obtenida fue un galimatías que la aplicación no pudo entender. Por ejemplo, la cadena se descifró a “abcd1213ef”, pero la aplicación solo esperaba números. La mayoría de las aplicaciones mostrarán un mensaje como “Número de cuenta no válido”.

  3. Resultado 3 : el relleno fue incorrecto y la aplicación arrojó algún tipo de mensaje de error. La mayoría de las aplicaciones mostrarán un mensaje genérico como “Se produjo algún error”.

Para que un ataque de Padding Oracle sea exitoso, el atacante debe poder realizar miles de solicitudes y debe poder clasificar la respuesta en uno de los 3 intervalos antes mencionados sin error.

Si se cumplen estas dos condiciones, el atacante puede descifrar el mensaje y luego volver a cifrarlo con lo que desee. Es solo una cuestión de tiempo.

¿Qué se puede hacer para prevenirlo?

  1. Lo más simple: cualquier cosa sensible nunca debe enviarse al cliente, encriptada o no encriptada. Guárdelo en el servidor.

  2. Asegúrese de que el resultado 2 y el resultado 3 en la lista anterior aparezcan exactamente iguales para el atacante. No debería haber forma de descubrir uno de otro. Sin embargo, esto no es tan fácil: un atacante puede discriminar usando algún tipo de ataque de sincronización.

  3. Como última línea de defensa, tenga un cortafuegos de aplicación web. El ataque oracle de relleno necesita realizar varias solicitudes que parecen casi similares (cambiando un bit a la vez), por lo que un WAF debería poder atrapar y bloquear dichas solicitudes.

PD: una buena explicación de Padding Oracle Attacks se puede encontrar en esta publicación de blog . Descargo de responsabilidad: NO es mi blog.

De lo que leí hasta ahora …

El ataque permite a alguien descifrar las cookies olfateadas, que podrían contener datos valiosos, como balances bancarios

Necesitan la cookie encriptada de un usuario que ya ha iniciado sesión en cualquier cuenta. También necesitan encontrar datos en las cookies: espero que los desarrolladores no almacenen datos críticos en las cookies :). Y hay una manera que tengo a continuación para no permitir que asp.net almacene datos en la cookie de inicio de sesión.

¿Cómo puede alguien obtener la cookie de un usuario que está en línea si no tiene acceso a los datos del navegador? ¿O huele el paquete de IP?

Una forma de prevenir eso es no permitir el transporte de cookies sin cifrado SSL.

  

También una medida más es evitar almacenar Roles en las cookies.

  

Ahora, acerca de las cookies que no son seguras para las páginas normales, esto necesita un poco más de reflexión sobre qué dejaste a tu usuario y qué no, cómo confías en él, qué control adicional puedes hacer (por ejemplo, si ves un cambio en el ip , tal vez dejar de confiar en él hasta volver a iniciar sesión desde la página de seguridad).

Referencia:
¿Puede algún hacker robar la cookie de un usuario e iniciar sesión con ese nombre en un sitio web?

Cómo verificar desde dónde vienen los ataques y no dar información. Escribí aquí una forma sencilla de evitar que el relleno sea inválido y logueo al mismo tiempo para rastrear a los atacantes: CryptographicException: el relleno no es válido y no se puede eliminar. La validación de Viewview MAC falló

La forma de rastrear al atacante es verificar que el relleno no sea válido. Con un procedimiento simple, puede rastrearlos y bloquearlos. ¡Necesitan miles de llamadas en su página para encontrar la clave!

Actualización 1.

He descargado la herramienta que supone que es encontrar la LLAVE y descifrar los datos, y como digo su trampa en el código anterior que es verificar el estado de vista . De mis pruebas, esta herramienta tiene mucho más que corregir, por ejemplo, no puedo escanear el estado de la vista comprimida tal como está y su locking en mis pruebas.

Si alguien intenta usar esta herramienta o este método, el código anterior puede rastrearlos y puede bloquearlos fuera de su página con un código simple como este “Prevenir la Denegación de Servicio (DOS)” , o como este código para prevenir la Negación de servicio .

Actualización 2

Parece de lo que leí hasta ahora que lo único que realmente se necesita es no dar información sobre el error , y simplemente colocar una página de error personalizada y si lo desea, puede simplemente crear y un retraso aleatorio en esta página.

un video muy interesante sobre este tema.

Entonces, todo lo anterior es más medida para más protecciones, pero no es 100% necesario para este problema en particular. Por ejemplo, usar ssl cookie es resolver el problema snif, no guardar en caché los Roles en las cookies, es bueno no enviar y recuperar cookies grandes, y evitar a alguien que tenga todo listo crackear el código, simplemente colocar el rol de administrador en la galleta de él.

Viewstate rastrea solo una medida más para encontrar el ataque.

Aquí está la respuesta de MS. Todo se reduce a “usar una página de error personalizada” y no se darán pistas.

EDITAR
Aquí hay información más detallada de scottgu.

Agregar las respuestas de ScottGu tomadas de la discusión en http://weblogs.asp.net/scottgu/archive/2010/09/18/important-asp-net-security-vulnerability.aspx

¿Está afectado IHttpModule personalizado en lugar de customErrors?

P: No tengo un elemento declarado en mi web.config, tengo un IHttpModule dentro de la sección. Este módulo registra el error y lo redirecciona a una página de búsqueda (para el 404) oa una página de error (para el 500). ¿Soy vulnerable?

R: Recomendaría actualizar temporalmente el módulo para redirigirlo siempre a la página de búsqueda. Una de las formas en que funciona este ataque es que busca la diferenciación entre los errores 404 y 500. Siempre devolver el mismo código HTTP y enviarlos al mismo lugar es una forma de ayudar a bloquearlo.

Tenga en cuenta que cuando salga el parche para solucionar esto, no tendrá que hacer esto (y puede volver al comportamiento anterior). Pero por ahora recomendaría no diferenciar entre los 404 y los 500 a los clientes.

¿Puedo continuar usando diferentes errores para los errores 404 y 500?

P: Supongo que aún podemos definir una página 404 personalizada además de la redirección predeterminada en caso de error, sin violar los principios descritos anteriormente.

R: No, hasta que publiquemos un parche para la solución real, recomendamos la solución anterior que homogeneiza todos los errores. Una de las formas en que funciona este ataque es que busca la diferenciación entre los errores 404 y 500. Siempre devolver el mismo código HTTP y enviarlos al mismo lugar es una forma de ayudar a bloquearlo.

Tenga en cuenta que cuando salga el parche para solucionar esto, no tendrá que hacer esto (y puede volver al comportamiento anterior). Pero por ahora no debe diferenciar entre 404 y 500 a los clientes.

¿Cómo esto permite la exposición de web.config?

P: ¿Cómo permite esto la exposición de web.config? Esto parece permitir el descifrado de ViewState solamente, ¿existe otra vulnerabilidad relacionada que también permita la divulgación de información? ¿Hay un documento técnico que detalla el ataque para una mejor explicación de lo que está sucediendo?

R: El ataque que se mostró en el público depende de una función en ASP.NET que permite descargar archivos (normalmente javascript y css), y que está asegurado con una clave que se envía como parte de la solicitud. Desafortunadamente, si puede falsificar una clave, puede usar esta característica para descargar el archivo web.config de una aplicación (pero no archivos fuera de la aplicación). Obviamente, publicaremos un parche para esto, hasta que la solución anterior cierre el vector de ataque.

EDITAR: preguntas frecuentes adicionales disponibles en el segundo blogpost en http://weblogs.asp.net/scottgu/archive/2010/09/20/frequently-asked-questions-about-the-asp-net-security-vulnerability.aspx

OMI, no existe una prevención transversal para esto, debe manejarse caso por caso:

http://www.onpreinit.com/2010/09/aspnet-vulnerability-workaround-flawed.html

Algunos enlaces significativos:

  • MS ‘Security Advisory 2416728 (esta es la información oficial)
  • Información adicional del equipo de investigación y defensa de seguridad de MS
    • “Entender la vulnerabilidad de ASP.NET” (2010-09-17)
    • “Información adicional sobre la vulnerabilidad de ASP.NET” (2010-09-20)
  • Scott Gu: “Importante: Vulnerabilidad de seguridad ASP.NET” (2010-09-18)

[Para responder al aspecto de seriedad de esto (lo que se ha publicado y las soluciones provisionales están cubiertas por otras respuestas).]

La clave atacada se usa para proteger tanto el estado de vista como las cookies de sesión. Normalmente, esta clave la genera internamente ASP.NET con cada nueva instancia de la aplicación web. Esto limitará el scope del daño a la duración del proceso de trabajo, por supuesto, para una aplicación ocupada esto podría ser días (es decir, no mucho de un límite). Durante este tiempo, el atacante puede cambiar (o inyectar) valores en ViewState y cambiar su sesión.

Incluso más en serio si desea que las sesiones puedan abarcar vidas útiles de proceso de trabajo, o permitir granjas de servidores web (es decir, todas las instancias de la granja de servidores pueden manejar cualquier sesión de usuario) la clave debe estar codificada, esto se hace en web.config :

 [...]   

Esas son, por supuesto, nuevas claves creadas, utilizo el siguiente PowerShell para acceder al generador de números aleatorios criptográficos de Windows:

 $rng = New-Object "System.Security.Cryptography.RNGCryptoServiceProvider" $bytes = [Array]::CreateInstance([byte], 20) $rng.GetBytes($bytes) $bytes | ForEach-Object -begin { $s = "" } -process { $s = $s + ("{0:X2}" -f $_) } -end { $s} 

(Utilizando una longitud de matriz de 20 para la validación y 16 para las claves de descifrado).

Además de modificar las páginas de error público para no filtrar el error específico, parecería un buen momento para cambiar las claves anteriores (o los procesos de ciclo de trabajo si se han estado ejecutando durante un tiempo).

[Editar 2010-09-21: Agregados enlaces a la cima]

Acabo de publicar mi versión completa de esto en mi blog , después de investigar más sobre el tema. Creo que es importante aclarar por qué están llegando a falsificar una cookie de autenticación.


Solo quiero aclarar algunos hechos:

  1. El ataque no le permite obtener la clave del equipo directamente. Dicho esto, es bastante parecido a lo que tenía, ya que permite descifrar los mensajes y modificar re / encriptar los nuevos.
  2. la forma en que obtienen las claves reales es mediante el uso de su capacidad para modificar re / encrypt como en 1 y obtener el web.config. Lamentablemente, hay razones por las cuales algunos colocan estas claves en el sitio web.config en el nivel del sitio (discusión diferente), y en el video de muestra se benefician de que sea el valor predeterminado de DotnetNuke.
  3. para obtener la web.config todo apunta a que están usando webresources.axd y / o scriptresources.axd. Pensé que estos solo funcionaban con recursos integrados, pero parece que ese no es el caso.
  4. si la aplicación es asp.net MVC, realmente no necesitamos webresources.axd y / o scriptresources.axd, por lo que se pueden desactivar. Tampoco usamos viewstate. Dicho esto, no está claro si alguna de las otras características de asp.net proporciona información diferente con la solución alternativa en el lugar, es decir, no sé si el relleno proporciona resultados no válidos por error mientras se rellenan los resultados válidos en el ticket de autenticación ignorado (no sé si es o no el caso) … el mismo análisis debería aplicarse a la cookie de sesión.
  5. El proveedor de membresía de asp.net ‘almacena’ las funciones en las cookies, desactívalas.

Alrededor de 1, afaik los mensajes cifrados no pueden ser 100% arbitrarios para tolerar una pequeña porción de basura en algún lugar del mensaje, ya que hay 1 bloque en el mensaje que descifra el valor que no se puede controlar.

Finalmente, me gustaría decir que este problema es el resultado de que ms no siga su propia guía en este caso: una característica se basa en que algo enviado al cliente es a prueba de manipulaciones.


Más en:

No sé si el relleno proporciona resultados no válidos por error al rellenar resultados válidos en el ticket de autenticación ignorado (no sé si es o no el caso) … el mismo análisis debería aplicarse a la cookie de sesión.

La cookie de autenticación está firmada, y de la información en el documento no deberían poder generar una cookie firmada si no llegan a las claves reales (como lo hicieron en el video antes de falsificar la cookie de autenticación).

Como dijo Aristos, para el ID de la sesión en la cookie, eso es aleatorio para la sesión del usuario, por lo que tendría que ser olido por un usuario con el nivel de seguridad objective y agrietado mientras esa sesión está activa. Aun así, si confía en la autenticación para asignar / autorizar las operaciones del usuario, entonces el impacto sería mínimo / depende en gran medida de la sesión utilizada en esa aplicación.

Asp.Net MVC también se ve afectado por este problema (como es Sharepoint, …)

He cubierto la solución para MVC aquí: ¿ASP.NET MVC es vulnerable al ataque de relleno oracle?