BLOG

Interceptar y modificar respuestas con Chrome mediante el protocolo DevTools

Miniatura F5
F5
Publicado el 17 de septiembre de 2018


En Shape nos encontramos con muchos fragmentos de código JavaScript sospechosos. Encontramos scripts que se inyectan maliciosamente en las páginas, pueden ser enviados por un cliente para solicitar asesoramiento o nuestros equipos de seguridad pueden encontrar un recurso en la web que parezca hacer referencia específica a algunos aspectos de nuestro servicio. Como parte de nuestra rutina diaria, nos sumergimos de lleno en los scripts para comprender qué están haciendo y cómo funcionan. Generalmente están minimizados, a menudo ofuscados y siempre requieren múltiples niveles de modificación antes de que estén realmente listos para un análisis profundo.

Hasta hace poco, la forma más sencilla de realizar este análisis era con configuraciones de caché local que permitían la edición manual o utilizando servidores proxy para reescribir el contenido sobre la marcha. La solución local es la más conveniente, pero los sitios web no siempre se traducen perfectamente a otros entornos y a menudo conducen a las personas a un callejón sin salida de resolución de problemas solo para ser productivos. Los servidores proxy son extremadamente flexibles, pero suelen ser engorrosos y poco portables: cada uno tiene su propia configuración personalizada para su entorno y algunas personas están más familiarizadas con un servidor proxy que con otro. Comencé a usar Chrome y su protocolo devtools para conectarme con las solicitudes y respuestas a medida que ocurren y modificarlas sobre la marcha. Es portable a cualquier plataforma que tenga Chrome, evita un montón de problemas y se integra bien con herramientas JavaScript comunes. En esta publicación, repasaré cómo interceptar y modificar JavaScript sobre la marcha utilizando el protocolo devtools de Chrome .

Usaremos node, pero gran parte del contenido es portable al lenguaje de tu elección, siempre que tengas los ganchos de devtools fácilmente accesibles.

En primer lugar, si nunca has explorado la creación de scripts en Chrome, Eric Bidelman escribió una excelente Guía de introducción a Chrome sin interfaz gráfica . Los consejos que se ofrecen allí se aplican tanto a Chrome sin cabeza como a Chrome con GUI (con una peculiaridad que abordaré en la siguiente sección).

Iniciando Chrome

Usaremos la biblioteca chrome-launcher de npm para facilitar esto.

Interceptar y modificar respuestas con Chrome a través del protocolo Devtools

chrome-launcher hace exactamente lo que crees que haría y puedes pasar los mismos parámetros de línea de comando a los que estás acostumbrado desde la terminal sin cambios ( aquí se mantiene una gran lista ). Pasaremos las siguientes opciones:

–tamaño de ventana=1200,800

  • Establezca automáticamente el tamaño de la ventana en un valor razonable.

–auto-open-devtools-for-tabs

  • Abre automáticamente las herramientas de desarrollo porque las usamos con frecuencia.

–user-data-dir=/tmp/chrome-testing

  • Establecer un directorio de datos de usuario constante. (Idealmente no necesitaríamos esto, pero el modo sin cabeza en Mac OSX no parece permitir interceptar solicitudes sin esta bandera. Si conoces una mejor manera, ¡házmelo saber a través de Twitter !)
Interceptar y modificar respuestas con Chrome a través del protocolo Devtools

Intenta ejecutar tu script para asegurarte de que puedes abrir Chrome. Deberías ver algo como esto:

Interceptar y modificar respuestas con Chrome a través del protocolo Devtools

Uso del protocolo Chrome Devtools

Esto también se conoce como “protocolo de depuración de Chrome” y ambos términos parecen usarse indistintamente en los documentos de Google. Primero, instale el paquete chrome-remote-interface a través de npm, que nos brinda métodos convenientes para interactuar con el protocolo devtools. Asegúrese de tener a mano los documentos del protocolo si desea profundizar más.

Interceptar y modificar respuestas con Chrome a través del protocolo Devtools

Para utilizar el CDP, debe conectarse al puerto del depurador y, como estamos usando la biblioteca chrome-launcher , se puede acceder fácilmente a través de chrome.port .

Interceptar y modificar respuestas con Chrome a través del protocolo Devtools

Muchos de los dominios del protocolo deben habilitarse primero, y vamos a comenzar con el dominio de tiempo de ejecución para poder conectarnos a la API de la consola y enviar cualquier llamada de consola en el navegador a la línea de comando.

Interceptar y modificar respuestas con Chrome a través del protocolo Devtools

Ahora, cuando ejecutas tu script, obtienes una ventana de Chrome completamente funcional que también envía todos los mensajes de consola a tu terminal. ¡Eso por sí solo es fantástico, especialmente para fines de prueba!

Interceptar solicitudes

Primero, necesitaremos registrar lo que queremos interceptar enviando una lista de RequestPatterns a setRequestInterception . Puede interceptar en la etapa de “Solicitud” o en la etapa de “Encabezados recibidos” y, para modificar realmente una respuesta, necesitaremos esperar a “Encabezados recibidos”. El tipo de recurso se asigna a los tipos que normalmente verías en el panel de red de las herramientas de desarrollo.

No olvides habilitar el dominio de red como lo hiciste con Runtime , arriba, agregando Network.enable() a la misma matriz.

Interceptar y modificar respuestas con Chrome a través del protocolo Devtools

Registrar el controlador de eventos es relativamente sencillo y cada solicitud interceptada viene con un ​interceptionId que puede usarse para consultar información sobre la solicitud o eventualmente emitir una continuación. Aquí simplemente intervenimos y registramos cada solicitud que interceptamos en la terminal.

Interceptar y modificar respuestas con Chrome a través del protocolo Devtools

Modificación de solicitudes

Para modificar las solicitudes necesitaremos instalar algunas bibliotecas auxiliares que codificarán y decodificarán cadenas base64. Hay muchísimas bibliotecas disponibles; siéntete libre de elegir la tuya. Usaremos atob y btoa .

Interceptar y modificar respuestas con Chrome a través del protocolo Devtools

La API para gestionar las respuestas es un poco incómoda. Para gestionar las respuestas, debe incluir toda la lógica de respuesta en la intercepción de la solicitud (en lugar de simplemente interceptar una respuesta, por ejemplo) y luego debe consultar el cuerpo por el ID de intercepción. Esto se debe a que el cuerpo podría no estar disponible en el momento en que se llama a su controlador y esto le permite esperar explícitamente solo lo que está buscando. El cuerpo también puede venir codificado en base64, por lo que deberá verificarlo y decodificarlo antes de pasarlo a ciegas.

Interceptar y modificar respuestas con Chrome a través del protocolo Devtools

En este punto, eres libre de usar JavaScript como quieras. Su código lo coloca en medio de una respuesta permitiéndole acceder al JavaScript completo que se solicitó y enviar su respuesta modificada. ¡Impresionante! Simplemente modificaremos el JS agregando un console.log al final para que nuestra terminal reciba un mensaje cuando nuestro código modificado se ejecute en el navegador.

Interceptar y modificar respuestas con Chrome a través del protocolo Devtools

No podemos simplemente pasar un cuerpo modificado solo porque el contenido podría entrar en conflicto con los encabezados que se enviaron con el recurso original. Dado que estás probando y ajustando activamente, probablemente querrás comenzar con lo básico antes de preocuparte demasiado por cualquier otra información del encabezado que necesites transmitir. Puede acceder a los encabezados de respuesta a través de ​responseHeaders pasados ​​al controlador de eventos si es necesario, pero por ahora simplemente crearemos nuestro propio conjunto mínimo en una matriz para facilitar su manipulación y edición más adelante.

Interceptar y modificar respuestas con Chrome a través del protocolo Devtools

Para enviar la nueva respuesta es necesario crear una respuesta HTTP completa codificada en base64 (incluida la línea de estado HTTP) y enviarla a través de una propiedad rawResponse en el objeto pasado a continueInterceptedRequest .

Interceptar y modificar respuestas con Chrome a través del protocolo Devtools

Ahora, cuando ejecutas tu script y navegas por Internet, verás algo como lo siguiente en tu terminal mientras tu script intercepta JavaScript y también mientras tu JavaScript modificado se ejecuta en el navegador y los ​console.log() aparecen a través del gancho que hicimos al comienzo del tutorial.

Interceptar y modificar respuestas con Chrome a través del protocolo Devtools

El código de trabajo completo para el ejemplo básico está aquí:

Interceptar y modificar respuestas con Chrome a través del protocolo Devtools

El siguiente paso a seguir

Puedes comenzar imprimiendo el código fuente, lo que siempre es una forma útil de comenzar a realizar ingeniería inversa de algo. Sí, por supuesto, puedes hacer esto en la mayoría de los navegadores modernos, pero querrás controlar cada paso de la modificación tú mismo para mantener la coherencia en todos los navegadores y versiones de navegadores y poder conectar los puntos a medida que analizas la fuente. Cuando estoy investigando código extraño y ofuscado, me gusta cambiar el nombre de las variables y funciones a medida que empiezo a comprender su propósito. Modificar JavaScript de forma segura no es un ejercicio trivial y ese sería un tema de blog por sí solo, pero por ahora puedes usar algo como ​unminify para deshacer técnicas comunes de minificación y ofuscación.

Puede instalar unminify a través de npm y envolver su nuevo cuerpo de JavaScript con una llamada a ​unminify para verlo en acción:

Interceptar y modificar respuestas con Chrome a través del protocolo Devtools

Profundizaremos más en las transformaciones en la próxima publicación. Si tienes alguna pregunta, comentario u otros trucos interesantes, ¡contáctame a través de Twitter!