Aprende a Desofuscar JavaScript

1. Introducción

En este post te guiaré paso a paso para encontrar, entender y limpiar código JavaScript ofuscado. No te preocupes si nunca lo has hecho antes; juntos revisaremos ejemplos de la vida real, herramientas útiles y buenas prácticas para que domines el proceso.


2. Localiza el JavaScript en la página

Cuando una web carga, el HTML estructura los elementos, el CSS define la apariencia y el JavaScript ejecuta la lógica. Para ver ese JavaScript:

  1. Abre la página en tu navegador (por ejemplo, Firefox).
  2. Pulsa Ctrl+U para ver el HTML fuente.
  3. Busca etiquetas <script>:
    • Si la etiqueta contiene código, está embebido.
    • Si usa src="archivo.js", haz clic para ver el script externo.

Por ejemplo, verás:

<script src="secret.js"></script>

Al abrir secret.js, notarás algo críptico como:

eval(function(p,a,c,k,e,d){...})(...));

¡Ahí empieza la diversión!


3. ¿Qué es la ofuscación?

Ofuscar significa reescribir el código para que sea casi ilegible, pero siga funcionando. Se emplea tanto para proteger propiedad intelectual como para ocultar malware.

  • Objetivo: hacer difícil la lectura humana.
  • Técnica: herramientas automáticas renombrando variables, empaquetando texto en diccionarios, insertando capas de funciones eval, etc.

3.1 ¿Para qué se usa?

  • Protección de IP: evitar copia directa.
  • Seguridad ligera: aunque no reemplaza cifrado serio.
  • Malware: esconder payloads y burlar detección.

4. Tipos de ofuscación

4.1 Minificación

Reducir espacios, comentarios y saltos de línea:

// Original
function saludo(nombre) {
    // Comentario útil para desarrolladores
    console.log("Hola " + nombre);
}

// Llamada a la función
saludo("Mundo");

// Minificado
function saludo(n){console.log("Hola "+n);}saludo("Mundo");

4.2 Packer (empacado)

Convierte tu script en un eval de seis parámetros:

eval(function(p,a,c,k,e,d){e=function(c){return c};if(!''.replace(/^/,String)){while(c--){d[c]=k[c]||c}k=[function(e){return d[e]}];e=function(){return'\w+'};c=1;}while(c--){if(k[c]){p=p.replace(new RegExp('\b'+e(c)+'\b','g'),k[c])}}return p}('5.4(\'3 2 1 0\');',6,6,'Module|Deobfuscation|JavaScript|Demo|log|console'.split('|'),0,{}))

Esto sigue imprimiendo HTB JavaScript Deobfuscation Module, pero con mucha menos claridad.

4.3 Ofuscación avanzada (Base64, renombrado dinámico)

Ejemplo con Array Encoding en base64:

var _0x1ec6=['Bg9N','sfrciePHDMfty3jPChqGrgvVyMz1C2nHDgLVBIbnB2r1Bgu='];
(function(_0x13249d,_0x1ec6e5){...})(_0x1ec6,0xb4);
var _0x14f8=function(_0x13249d,_0x1ec6e5){...};
console[_0x14f8('0x0')](_0x14f8('0x1'));

O incluso trucos con ![], +[], etc. (JSFuck):

[][(![]+[])[+[]]+... ](...))()

5. Desofuscación paso a paso

5.1 «Pretty Print» o «Beautify»

Para scripts minimizados, abre las DevTools (Ctrl+Shift+Z en Firefox). En la pestaña de depuración, haz clic en el botón {} para darle formato legible.

También puedes usar editores o servicios online:

5.2 «Unpacker» para scripts empacados

Herramientas gratuitas como UnPacker (https://matthewfl.com/unPacker.html) revelan funciones y variables:

function generateSerial() {
  var xhr = new XMLHttpRequest();
  var url = "/serial.php";
  xhr.open("POST", url, true);
  xhr.send(null);
};

Recuerda eliminar líneas vacías antes de pegar el código, para evitar errores.


6. Ingeniería inversa manual

Cuando las herramientas automáticas no bastan (ofuscadores personalizados), deberás:

  1. Identificar patrones: cadenas, llamadas a eval, loops raros.
  2. Extraer datos: imprime variables intermedias (console.log).
  3. Reconstruir lógica: renombra funciones/variables.

7. Análisis de la lógica y solicitudes HTTP

Tras desofuscar, inspecciona la función principal:

'use strict';
function generateSerial() {
  var xhr = new XMLHttpRequest();
  var url = "/serial.php";
  xhr.open("POST", url, true);
  xhr.send(null);
};
  • XMLHttpRequest: maneja peticiones web.
  • POST a /serial.php: no envía datos, solo dispara la acción.

Para replicarlo con cURL:

# Petición GET
curl http://SERVER_IP:PORT/

# Petición POST vacía
curl -s http://SERVER_IP:PORT/ -X POST

Si la función aceptase parámetros, usarías -d "param1=valor".


8. Decodificación de cadenas

A menudo encontrarás textos codificados dentro del script. Los más comunes:

8.1 Base64

  • Caracteres: alfanuméricos + + /, relleno con =.
  • Decodificar:echo "aGVsbG8= " | base64 -d
  • Codificar:echo "hola mundo" | base64

8.2 Hexadecimal

  • Solo 0-9 y a-f.
  • Decodificar:echo "686f6c61" | xxd -p -r
  • Codificar:echo "hola" | xxd -p

8.3 César / ROT13

  • Desplaza 13 posiciones.
  • Codificar/Decodificar:echo "uggcf://jjj" | tr 'A-Za-z' 'N-ZA-Mn-za-m'

Para métodos extraños, prueba Cipher Identifier.


9. Recapitulando

Hoy cubrimos:

  1. Ubicar el JavaScript en el HTML.
  2. Entender los diferentes niveles de ofuscación.
  3. Formatear scripts minimizados con pretty print.
  4. Desempaquetar código con unpackers.
  5. Aplicar ingeniería inversa cuando haga falta.
  6. Replicar funcionalidades via HTTP (XMLHttpRequest, cURL).
  7. Decodificar cadenas comunes (Base64, hex, ROT13).

Con esta hoja de ruta podrás enfrentarte a casi cualquier JavaScript ofuscado. ¡Practica y comparte tus hallazgos!

Comparte esta Publicación en Redes Sociales