Prueba de lápiz de aplicaciones web en un contexto angular

Si eres fanático de las pruebas de lápiz de aplicaciones web, a lo largo de los años te han echado a perder muchas elecciones fáciles. A todos nos encantan nuestros proxies de interceptación, y sé que muchos de nosotros somos grandes admiradores del gran trabajo que PortSwigger ha realizado con Burp Suite a lo largo de los años. Habiendo dicho esto, probar aplicaciones en la era de las aplicaciones web modernas que tienen marcos enfocados en el Modelo de Objetos de Documento (DOM) es un poco diferente a probar una aplicación tradicional basada en HTML.

Para el resto de esta publicación de blog, suponga que me refiero a las versiones 2 y posteriores de Angular, que están orientadas a objetos y se basan en la versión 6 de ECMAScript (ES6 o ECMAScript 2015). La versión 1.x de Angular, anteriormente conocida como AngularJS, está obsoleta y es menos probable que se encuentre, ¡aunque aún no está muerta!

Dicho esto, no entre en pánico y no abandone sus técnicas habituales de prueba de penetración de aplicaciones web. Lo que debe comprender es que en el mundo de Angular 2+, que está diseñado teniendo en cuenta la seguridad desde cero, sus oportunidades normales específicamente para inyectar JavaScript en el DOM están muy limitadas si el desarrollador usa los valores predeterminados y las mejores prácticas comunes. . ¡Deberíamos celebrar que las cosas van en la dirección correcta con marcos modernos en los que los desarrolladores no tienen que reinventar continuamente la rueda!

Aquí hay algunas referencias con una gran experiencia para usted.

Hay errores que los desarrolladores pueden cometer y que hacen que una aplicación Angular sea vulnerable desde la perspectiva DOM. Estos errores se reducen en gran medida a que los desarrolladores trabajan deliberadamente en torno a las salvaguardas que establece el marco. Los ejemplos serían los siguientes:

  • Si un desarrollador combina la entrada del usuario con la creación de una plantilla, entonces esa entrada del usuario puede impactar directamente en la representación del DOM y generar una vulnerabilidad de inyección de plantilla. Angular considera que las plantillas son confiables de forma predeterminada.
  • Si un desarrollador decide marcar la entrada del usuario como confiable y deshabilita los métodos de codificación de salida y saneamiento angular extremadamente efectivos, entonces está de vuelta a los malos viejos tiempos de la introducción del potencial Cross-Site Scripting. Como regla general, cualquier contenido interpolado de Angular siempre se escapa.
  • ¡Se desaconseja el uso directo de las API DOM! Probablemente exista un método angular para todo lo que necesita hacer. Si no es así, hay una función Angular “DomSanitize ()” si solo tienes que jugar donde realmente no deberías.

Desde la perspectiva del atacante, una parte considerable de la superficie de ataque se ha eliminado si el desarrollador sigue las mejores prácticas. Sin embargo, hay oportunidades para descubrir. Algunos pensamientos son los siguientes:

  • Lo más probable es que el backend de la aplicación sean llamadas a API basadas en JSON / RESTful. Es posible que se produzcan errores en la validación adecuada de los datos del lado del servidor.
  • Las referencias de objeto directo inseguras (IDOR) se pueden descubrir en las API y siempre debe solicitar varias cuentas autenticadas para realizar pruebas para examinar las incursiones de roles de usuarios cruzados.
  • La gestión de sesiones aún debe implementarse correctamente. No es inusual ver JSON Web Tokens (JWT) utilizados para la gestión de sesiones en aplicaciones basadas en Angular.
  • Es posible que el token de sesión no se invalide correctamente al cerrar la sesión, que sea de larga duración o que se invalide el token al cerrar la sesión por completo bajo el control del DOM del lado del cliente.
  • Es posible que el JWT se pueda volver a firmar con un valor «Ninguno» como algoritmo de firma que crea un token no seguro, o la clave de firma en sí puede romperse.
  • Firmar su propia aplicación JWT podría llevar a otro usuario autenticado comprometido.
  • Para obtener un par de referencias rápidas de JWT, visite estas URL: https://jwt.io/ https://en.wikipedia.org/wiki/JSON_Web_Token

La funcionalidad de la API de depuración o no documentada se puede descubrir cambiando un valor en el DOM del navegador.
Si un desarrollador decide implementar el renderizado del lado del servidor (SSR) en lugar del renderizado del lado del cliente (CSR) pesado DOM normal, es posible reintroducir las oportunidades de inyección de JavaScript. El proyecto Angular está tratando de adelantarse a esto presentando Angular Universal. Aquí tienes un par de referencias.

Cuando se prueba con lápiz una aplicación Angular, uno de los resultados del cambio tecnológico es que probablemente pasará más tiempo en la consola del desarrollador del navegador, así como en su proxy de intercepción. Angular 2+ tiene una característica en forma de una función especial llamada «enableProdMode ()» que se llama justo después de que el marco se inicia en el DOM. Esto supone que los desarrolladores han implementado la aplicación en «modo de producción».

La función «enableProdMode ()» hace que Angular omita la construcción del árbol de elementos de depuración en el navegador. Este árbol de elementos de depuración es útil para usted como probador de penetración, ya que puede usar la función angular “ng.probe ()” para examinar los elementos de la página después de seleccionar ese elemento en una página. En el modo de producción, «ng.probe ()» para un componente de página devolverá un valor nulo que no es útil.

Una de las primeras cosas que desea hacer es modificar esta función «en vuelo» en su proxy de interceptación para que «falle» al habilitar el modo de producción.

Hay un pequeño giro en esto. Si la aplicación también se implementa con https://webpack.js.org, es posible que el nombre de la función esté ofuscado. Afortunadamente, hay una cadena dentro de la función que dice «No se puede habilitar el modo prod después de la configuración de la plataforma» que puede usar para encontrar el nombre de la función ofuscada.

Si está utilizando Burp Suite, aquí hay una forma en que puede configurar el proxy para reescribir la función en vuelo. Este ejemplo asume que el paquete web no se ha utilizado para ofuscar nombres de funciones. Los pasos son los siguientes:

  • Seleccione la pestaña Proxy en Burp Suite
  • Seleccione la subpestaña Proxy -> Opciones
  • Desplácese hacia abajo hasta la sección «Coincidir / Reemplazar» y elimine las reglas existentes
  • Haga clic en «Agregar» para agregar una nueva regla
  • Seleccione «Cuerpo de respuesta» como el tipo
  • Coincide con la cadena «function enableProdMode () {«

Agregue una cadena de reemplazo que agregue «_devMode = 1;» y regresa de la función. Una vez hecho esto, es importante tener cuidado de preservar la integridad de la sintaxis de la secuencia de comandos para no interrumpir por completo la funcionalidad.

Hay otro inconveniente con el que puede encontrarse y que lo obligará a agregar otra regla de coincidencia / reemplazo. Aprendí este de la manera difícil, por supuesto (como tantas cosas).

Desde 2016, algunas etiquetas fuente incluidas en HTML tienen una opción de «integridad» que en realidad es una característica bastante buena. En resumen, la etiqueta de integridad permite al desarrollador especificar un algoritmo hash y un hash codificado en base64. El navegador intentará validar el hash y no ejecutará JavaScript si el hash no coincide.

Una técnica de defensa en profundidad relacionada es aprovechar la Política de seguridad de contenido (CSP). CSP es una técnica de listas blancas que permite a los administradores de servidores web especificar los dominios que los navegadores deben considerar como fuentes válidas de scripts ejecutables. Para los navegadores que admiten CSP, esta técnica ayuda a mitigar los ataques de inyección de datos y Cross-Site Scripting. CSP se implementa con un encabezado HTTP agregado a las respuestas del servidor. Los navegadores que no son compatibles con CSP volverán al modelo normal de política del mismo origen. Para obtener más información, consulte https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP.

Como puede imaginar, reescribir una función de JavaScript en vuelo ciertamente violará la verificación de la etiqueta de integridad si está presente. Una segunda regla de coincidencia / reemplazo similar a la siguiente captura de pantalla solucionará este obstáculo para que continúe probando.

Después de poner esto en su lugar y volver a cargar el contenido de la aplicación Angular, puede seleccionar cualquier elemento de la página y probar su estado usando «ng.probe ()» en la consola de herramientas del desarrollador, y luego incluso crear una instancia del objeto JavaScript para comenzar su exploración. Desde aquí puede manipular los atributos de ese objeto para ver qué impacto tiene. Lo que intenta hacer solo está limitado por su creatividad y limitaciones de tiempo. A continuación se muestra un ejemplo del uso de esta técnica de sonda.

Eso es todo lo que tengo para ti ahora. Felices senderos de prueba de aplicaciones web y sigue hackeando.