JavaScript, también conocido como “JS”, es un lenguaje de programación interpretado, orientado a objetos, y del tipo scripting (secuencia de comandos). Es ampliamente utilizado de forma legítima en el desarrollo de distintas aplicaciones, como aplicaciones web, aplicaciones para celulares, juegos, entre otros. Dado que este lenguaje puede ser interpretado por diferentes navegadores de Internet, los cibercriminales aprovechan esto para sus actividades maliciosas; por ejemplo, comprometiendo sitios legítimos de diferentes tópicos o temáticas e inyectando su propio código malicioso con el objetivo de que sea ejecutado por el navegador de una víctima al ingresar al sitio comprometido.

Por otro lado, este lenguaje también puede ser utilizado para la creación de extensiones maliciosas dirigidas a distintos navegadores de Internet. Estas extensiones pueden ser capaces de realizar distintas acciones. Por ejemplo:

  • Robar información sensible; por ejemplo, credenciales de acceso u otro tipo de información sensible
  • Detectar y reemplazar una billetera de criptomonedas por una controlada por los atacantes

Hecha esta pequeña introducción sobre el lenguaje JavaScript y de sus posibles usos por los cibercriminales, compartimos algunos consejos útiles al momento de analizar un código malicioso desarrollado en este lenguaje.

Por último, vale la pena recordar que si vamos a realizar el análisis de un código malicioso, es recomendable hacerlo dentro de una máquina virtual o un ambiente aislado, para evitar una posible infección sobre la computadora física.

Consejos a tener en cuenta

Declaración de funciones

Cuando analizamos un código malicioso, ya sea en JavaScript o en otro lenguaje, siempre es importante conocer los conceptos básicos de su sintaxis. Los mismos nos pueden ser de ayuda durante la etapa de análisis, como veremos a continuación.

En el siguiente ejemplo, vamos a ver una de las formas más básicas de crear una función en JavaScript:

Pero esa no es la única forma, JavaScript también permite la creación de funciones que van a ser invocadas de forma inmediata, esto quiere decir apenas se ejecute el script. Un ejemplo de esto puede verse a continuación:

Si bien las dos funciones mostradas anteriormente para fines prácticos hacen lo mismo, es importante detectar estas diferencias dentro de un código malicioso para determinar aquellas funciones que deban ser analizadas primero.

A su vez, puede pasar que algunas funciones que se ejecutan automáticamente sean parte de una técnica de ofuscación implementada en el código malicioso, pero no hagan alguna acción maliciosa en sí. Por ende, si bien es importante analizar esas funciones, diferenciar el contenido y la prioridad de ejecución de las funciones puede ayudarnos a determinar a qué debemos prestar atención primero al momento de analizar un código malicioso.

Detectar el punto de entrada

Poder determinar el punto de entrada o el punto donde comienza a ejecutarse un código malicioso es muy importante, ya que nos permite posicionarnos al comienzo de la actividad maliciosa del código. Esto resulta ventajoso en lenguajes del tipo scripting, como es el caso de JavaScript, porque los mismos tienden a tener funciones declaradas en distintas secciones del script y puede pasar que no todas esas funciones vayan a ser invocadas o ejecutadas.

Por lo tanto, detectar y comenzar el análisis desde el punto de entrada nos brinda la ventaja de enforcarnos sobre lo que es realmente importante del código malicioso en cuestión, y en muchos casos, nos permite descartar código  “basura” o código que no realiza ninguna actividad maliciosa y que suele usarse como una capa de ofuscación para confundir al analista.

En la siguiente imagen se puede ver un ejemplo del punto de entrada de un código malicioso, el cual explicaremos a continuación.

Ejemplo de punto de entrada de un código malicioso.

De la imagen anterior podemos ver distintas cosas, como declaración de funciones, funciones auto invocadas, o funciones que se asignan sobre variables y luego se ejecutan. Pero también, vemos el uso de la API del navegador Google Chrome, chrome.runtine. Esta API es utilizada (en este caso) para la creación de un evento Listener que va a estar a la espera de un mensaje que, una vez que lo recibe, el mismo ejecuta la función clear que se encuentra dentro de este código malicioso. Entonces, si tenemos en cuenta las palabras claves que no pueden ser ofuscadas y vemos que ese evento está llamando a una función perteneciente a este código malicioso, con cierta confianza podemos decir que encontramos el punto de entrada de este código malicioso.

Por último, podemos decir que aquellas funciones que no son llamadas o invocadas por el evento Listener, ni tampoco por la función clear, podemos obviarlas, ya que es muy probable que formen parte de distintas técnicas de ofuscación que son irrelevantes a la hora de analizar el comportamiento principal de este código malicioso.

Ofuscación de código

La ofuscación de código es un proceso mediante el cual a través de distintas técnicas o métodos se transforma un código existente de forma tal que resulte muy complicado de entender o analizar.

En las siguientes capturas de pantalla se puede ver, a modo de ejemplo, un código sin ofuscar y luego el mismo código con alguna capa de ofuscación encima.

Ejemplo de código sin ofuscar

Ejemplo del mismo código pero con ofuscación

Dependiendo del grado de sofisticación que tengan los cibercriminales, los mismos pueden optar por crear sus propios ofuscadores o, en muchos otros casos, utilizan ofuscadores que se encuentren en repositorios públicos en Internet. Del segundo caso es importante mencionar que esos ofuscadores fueron creados con la idea de ayudar a proteger la propiedad intelectual de los desarrolladores de un software legítimo, no para que sea utilizado en actividades maliciosas.

Por ende, cuando nos topemos con un código malicioso que posea una o varias capaz de ofuscación, lo recomendable seria primero buscar desofuscadores que se encuentren en repositorios públicos para ver si nuestro código malicioso emplea alguna técnica de ofuscación ya conocida. De esta manera evitamos invertir tiempo en desofuscar el código manualmente.

A continuación compartimos enlaces donde pueden encontrarse desofuscadores para código JavaScript:

javascript-deobfuscator
de4js
Javascript-deobfuscator
deobfuscator
JStillery
jsdetox
beautifier.io

Ejecución controlada desde un navegador

Dado que los navegadores web pueden interpretar y ejecutar código JavaScript, los mismos pueden ser de utilidad para realizar una ejecución parcial o total de un código malicioso desarrollado en este lenguaje. De esta forma se puede hacer una combinación entre el análisis estático y dinámico sobre un código malicioso con el fin de tener un mejor entendimiento del mismo.

Para poder ejecutar un código JavaScript sobre un navegador web, como puede ser Mozilla Firefox, primero debemos activar las herramientas de desarrollo utilizando el botón F12 (esto puede variar dependiendo del navegador que se use), luego ir a la sección Console y colocar ahí el código que deseemos ejecutar.

En la siguiente captura de pantalla se puede ver un ejemplo de cómo ejecutar un código JavaScript desde el navegador Mozilla Firefox.

Ejemplo de ejecución de un código JavaScript utilizando el navegador Firefox.

Conclusión

Estos son algunos de los métodos o consejos que nos podrían ayudar al momento tener que realizar el análisis de un código malicioso desarrollado en JavaScript. Es importante destacar que, dependiendo del tipo de código malicioso que se analice, es posible que alguna de estas técnicas no puedan aplicarse.