Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
box-js — Una herramienta para estudiar malware en JavaScript. | Kitploit
Herramientas/GitHubGitHub/capacitorset/box-js
Gestión de Indicadores de Compromiso (IOC)Análisis Dinámico (Sandboxing)Análisis ForenseAnálisis de Malware
GitHubcapacitorset/box-js

box-js

Una herramienta para estudiar malware en JavaScript.

Ver Repositorio
67288hace 1 mesRevisado por Kitploit

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

box.js

npm Build Status paypal

Una utilidad para analizar JavaScript malicioso.

Instalación

Simplemente instala box-js desde npm:

root@kitploit:~
npm install box-js --global

box-js también está disponible:

  • como módulo de Cuckoo (consulta el directorio integrations y Nwinternights/Cuckoo_Boxjs);
  • como Dockerfile (consulta integrations/README.md);
  • como paquete en distribuciones para profesionales de seguridad (REMnux, BlackArch);
  • como parte de aplicaciones de código abierto (Intel Owl);
  • como parte de servicios comerciales de terceros (any.run).

Uso

Supongamos que tienes una muestra llamada sample.js: para analizarla, simplemente ejecuta

root@kitploit:~
box-js sample.js

Probablemente también querrás descargar cualquier payload; usa la bandera --download para habilitar la descarga. De lo contrario, el motor simulará un error 404, de modo que el script será engañado para pensar que el sitio de distribución está caído y contactar con cualquier sitio de respaldo.

Box.js emulará un entorno Windows JScript, imprimirá un resumen de la emulación en la consola y creará una carpeta llamada sample.js.results (si ya existe, creará sample.js.1.results y así sucesivamente). Esta carpeta contendrá:

  • analysis.log, un registro del análisis tal como se imprimió en pantalla;
  • una serie de archivos identificados por UUIDs;
  • snippets.json, una lista de fragmentos de código ejecutados por la muestra (JavaScript, comandos de shell, etc.);
  • urls.json, una lista de URLs contactadas;
  • active_urls.json, una lista de URLs que parecen soltar malware activo;
  • resources.json, los flujos ADODB (es decir, los archivos que el script escribió en el disco) con tipos de archivo y hashes;
  • IOC.json, una lista de comportamientos identificados como IOCs (Indicadores de Compromiso). Estos incluyen accesos al registro, archivos escritos, solicitudes HTTP, etc.

Puedes analizarlos por tu cuenta, o puedes enviarlos automáticamente a Malwr, VirusTotal o una sandbox de Cuckoo: para más información, ejecuta box-export --help.

Para un mayor aislamiento, se recomienda ejecutar el análisis en un contenedor Docker temporal. Consulta integrations/README.md para más información.

Si deseas automatizar el análisis, puedes usar los códigos de retorno - documentados en integrations/README.md - para distinguir entre diferentes tipos de errores.

El análisis falla debido a la falta del objeto 'document' u otros objetos/funciones

El repositorio de box-js desde git incluye un archivo boilerplate.js. Este archivo define algunas versiones simuladas de objetos comunes del navegador como document. Intenta volver a ejecutar tu análisis con la opción --prepended-code=DIR/boilerplate.js, donde DIR es el directorio del repositorio clonado de box-js o con --prepended-code=default. La opción --prepended-code le indica a box-js que anteponga el JavaScript del archivo dado a la muestra que se está analizando.

Ten en cuenta que puedes copiar boilerplate.js y agregar tus propias clases, objetos, etc. simulados según sea necesario. Usa la opción de línea de comandos --prepended-code=show-default para imprimir la ruta completa al archivo boilerplate.js predeterminado de box-js.

Uso por lotes

Aunque box.js se usa típicamente en archivos individuales, también puede ejecutar análisis por lotes. Simplemente puedes pasar una lista de archivos o carpetas a analizar:

root@kitploit:~
box-js sample1.js sample2.js /var/data/mySamples ...

Por defecto, box.js procesará las muestras en paralelo, ejecutando un análisis por núcleo. Puedes usar una configuración diferente especificando un valor para --threads: en particular, 0 eliminará el límite, haciendo que box-js genere tantos hilos de análisis como sea posible y resultando en un análisis muy rápido pero posiblemente sobrecargando el sistema (nota que los análisis suelen estar limitados por la CPU, no por la RAM).

Puedes usar --loglevel=warn para silenciar los mensajes relacionados con el análisis y solo mostrar información de progreso.

Después de que el análisis termine, puedes extraer las URLs activas de esta manera:

root@kitploit:~
cat ./*.results/active_urls.json | sort | uniq

Banderas

root@kitploit:~
NOMBRE                   DESCRIPCIÓN                                                                     
-h, --help                 Muestra el texto de ayuda y sale                                                     
-v, --version              Muestra la versión del paquete y sale                                               
--license                  Muestra la licencia y sale                                                       
--debug                    Termina cuando ocurre un error de emulación, incluso en "modo por lotes", y pasa el código de salida
                           .                                                                           
--loglevel                 Nivel de registro (debug, verbose, info, warning, error - por defecto "info")           
--threads                  Cuando se ejecuta en modo por lotes, cuántos análisis ejecutar al mismo tiempo (0 = ilimitado, por defecto: tantos como núcleos de CPU)                         
--download                 Descargar realmente los payloads                                                  
--encoding                 Codificación de la muestra de entrada (se detectará automáticamente por defecto)        
--timeout                  El script expirará después de tantos segundos (por defecto 10)                    
--output-dir               La ubicación en disco para escribir los archivos y carpetas de resultados (por defecto el
                           directorio actual)                                                              
--preprocess               Preprocesa el código fuente original (facilita la ingeniería inversa, pero lleva
                           unos segundos)                                                                  
--unsafe-preprocess        Preprocesamiento más agresivo. A menudo produce mejor código, pero puede romperse en
                           algunos casos extremos (por ejemplo, redefiniendo prototipos)                                     
--prepended-code           Archivo o directorio de entrada que contiene código que debe anteponerse a los archivos JS
                           que estamos analizando. Si se da un directorio, antepone el contenido de todos los archivos
                           en el directorio. Si se da 'default', usa el boilerplate.js predeterminado que
                           viene con box-js. Si se da 'show-default', solo imprime la ruta de boilerplate.js
                           y sale (útil si quieres copiar y modificar el código boilerplate predeterminado).      
--fake-script-engine       El motor de script a reportar en WScript.FullName y WScript.Name (ej.
                           'cscript.exe', 'wscript.exe', o 'node'). El predeterminado es wscript.exe.               
--fake-cl-args             Argumentos falsos de línea de comandos del script. En la cadena deben estar separados por comas
                           separados.                                                                      
--fake-sample-name         Nombre de archivo falso para usar para la muestra que se analiza. Puede ser una ruta completa o solo
                           el nombre de archivo a usar. Si tienes '\' en la ruta, escápalos como '\\' en este
                           valor del argumento de línea de comandos (ej. --fake-sample-name=C:\\foo\\bar.js).           
--fake-language            Especifica el código de idioma a devolver para Win32_OperatingSystem.OSLanguage.
                           Los valores admitidos son 'spanish', 'english' y 'portuguese'.                    
--fake-domain              Especifica el dominio del usuario a devolver para WScript.Network.UserDomain.
--fake-download            Finge que las solicitudes HTTP funcionan y haz que devuelvan un payload falso                
--no-kill                  No terminar la aplicación cuando ocurran errores en tiempo de ejecución                           
--no-echo                  Cuando el script imprime datos, no imprimirlos en la consola                     
--no-rewrite               No reescribir el código fuente en absoluto, excepto para el soporte de `@cc_on`          
--no-catch-rewrite         No reescribir las cláusulas try..catch para hacer la excepción de ámbito global           
--no-cc_on-rewrite         No reescribir `/*@cc_on <...>@*/` a `<...>`                                   
--no-eval-rewrite          No reescribir `eval` para que su argumento sea reescrito                         
--no-file-exists           Devolver `false` para Scripting.FileSystemObject.FileExists(x)                     
--limit-file-checks        Cambiar el valor predeterminado para las comprobaciones de existencia de carpetas/archivos si se realizan muchas comprobaciones
                           (intenta romper bucles infinitos de comprobación de archivos).                                       
--no-folder-exists         Devolver `false` para Scripting.FileSystemObject.FileExists(x)                     
--function-rewrite         Reescribir llamadas a funciones para capturar llamadas a eval                             
--no-rewrite-prototype     No reescribir expresiones como `function A.prototype.B()` como `A.prototype.B =
                           function()`                                                                     
--no-hoist-prototype       No elevar expresiones como `function A.prototype.B()` (implicado por
                           no-rewrite-prototype)                                                           
--no-shell-error           No lanzar un error falso al ejecutar `WScriptShell.Run` (lanza un error falso
                           por defecto para simular que los sitios de distribución están caídos, para que el
                           script intente consultar cada sitio)                                         
--no-typeof-rewrite        No reescribir `typeof` (por ejemplo, `typeof ActiveXObject`, que debe devolver
                           'unknown' en el estándar JScript y no 'object')                             
--proxy                    [experimental] Usar el proxy especificado para descargas. Esto no es relevante si
                           la bandera --download no está presente.                                             
--windows-xp               Emular Windows XP (influye en el valor de las variables de entorno)              
--dangerous-vm             Usar el módulo `vm`, en lugar de `vm2`. Esta sandbox puede romperse, así que **no
                           uses esto** a menos que estés 100% seguro de lo que haces. Ayuda con la depuración al
                           dar trazas de pila correctas.                                                    
--rewrite-loops            Reescribir algunos tipos de bucles para hacer el análisis más rápido                             
--throttle-writes          Limitar el informe y el seguimiento de datos de escrituras de archivos que escriben MUCHOS datos    
--throttle-commands        Detener el análisis si se han ejecutado MUCHOS comandos iguales                   
--extract-conditional-code Extraer el código real a analizar de los comentarios condicionales de JScript (/*@if(...).  
--loose-script-name        Reescribir comprobaciones == para que las comparaciones del nombre del script actual con un nombre
                           de script codificado siempre devuelvan true.                                                 
--real-script-name         Devolver el nombre de archivo real del script analizado actualmente en lugar de uno
                           falso.                                                                           
--activex-as-ioc           Registra todas las llamadas ActiveX como IOCs e intenta determinar si la llamada está ofuscada
                           en el código fuente JS.                                                               
--ignore-wscript-quit      Ignorar llamadas a WSCript.Quit() y continuar la ejecución.                          
--ignore-rewrite-errors    Analizar la muestra original si falla alguna reescritura de muestra.                            

Analizando la salida

Salida de la consola

La primera fuente de información es la salida de la consola. En un análisis exitoso, generalmente imprimirá algo como esto:

root@kitploit:~
Using a 10 seconds timeout, pass --timeout to specify another timeout in seconds
Analyzing sample.js
Header set for http://foo.bar/baz: User-Agent Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)
Emulating a GET request to http://foo.bar/baz
Downloaded 301054 bytes.
Saved sample.js.results/a0af1253-597c-4eed-9e8f-5b633ff5f66a (301054 bytes)
sample.js.results/a0af1253-597c-4eed-9e8f-5b633ff5f66a has been detected as data.
Saved sample.js.results/f8df7228-7e0a-4241-9dae-c4e1664dc5d8 (303128 bytes)
sample.js.results/f8df7228-7e0a-4241-9dae-c4e1664dc5d8 has been detected as PE32 executable (GUI) Intel 80386, for MS Windows.
http://foo.bar/baz is an active URL.
Executing sample.js.results/d241e130-346f-4c0c-a698-f925dbd68f0c in the WScript shell
Header set for http://somethingelse.com/: User-Agent Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)
Emulating a GET request to http://somethingelse.com/
...

En este caso, estamos viendo un dropper que descarga un archivo de http://foo.bar/baz, estableciendo la cabecera HTTP User-Agent a Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0). Luego, procede a decodificarlo y escribe el resultado en el disco (un ejecutable PE32). Finalmente, ejecuta algún comando en el shell de Windows.

  • sample.js.results/a0af1253-597c-4eed-9e8f-5b633ff5f66a contendrá el payload tal como se descargó de http://foo.bar/baz;
  • sample.js.results/f8df7228-7e0a-4241-9dae-c4e1664dc5d8 contendrá el payload real (ejecutable PE);
  • sample.js.results/d241e130-346f-4c0c-a698-f925dbd68f0c contendrá el comando que se ejecutó en el shell de Windows.

Registros JSON

Cada solicitud HTTP se imprime tanto en la terminal como se registra en urls.json. Las URLs duplicadas no se insertan (es decir, solicitar la misma URL dos veces resultará en solo una línea en urls.json).

active_urls.json contiene la lista de URLs que finalmente resultaron en un payload ejecutable. Este archivo es el más interesante, si buscas derribar sitios de distribución.

snippets.json contiene cada pieza de código que box-js encontró, ya sea JavaScript, un comando de cmd.exe o un script de PowerShell.

resources.json contiene cada archivo escrito en el disco por la muestra. Por ejemplo, si la aplicación intentó guardar Hello world! en $PATH/foo.txt, el contenido de resources.json sería:

root@kitploit:~
{
	"9a24...": {
		"path": "(path)\\foo.txt",
		"type": "ASCII text, with no line terminators",
		"md5": "86fb269d190d2c85f6e0468ceca42a20",
		"sha1": "d3486ae9136e7856bc42212385ea797094475802",
		"sha256": "c0535e4be2b79ffd93291305436bf889314e4a3faec05ecffcbb7df31ad9e51a"
	}
}

El archivo resources.json también es importante: presta atención a cualquier recurso ejecutable (ej. con "type": "PE32 executable (GUI) Intel 80386, for MS Windows").

Parcheo

Se ha observado que algunos scripts en la naturaleza usan new Date().getYear() donde new Date().getFullYear(). Si una muestra no muestra ningún comportamiento sospechoso, presta atención a las comprobaciones de Date.


Si te encuentras con archivos .JSE, compila el decodificador y ejecútalo así:

root@kitploit:~
cc decoder.c -o decoder
./decoder foo.jse bar.js
node run bar.js

Ampliación

Ocasionalmente puedes encontrarte con componentes no compatibles. En este caso, puedes abrir un issue en GitHub, o emular el componente tú mismo si sabes JavaScript.

El error típicamente se verá así (los números de línea pueden ser diferentes):

root@kitploit:~
1 Jan 00:00:00 - Unknown ActiveXObject WinHttp.WinHttpRequest.5.1
Trace
    at kill (/home/CapacitorSet/box-js/run.js:24:10)
    at Proxy.ActiveXObject (/home/CapacitorSet/box-js/run.js:75:4)
    at evalmachine.<anonymous>:1:6471
    at ContextifyScript.Script.runInNewContext (vm.js:18:15)
    at ...

Puedes ver que la excepción se lanzó en Proxy.ActiveXObject, que se ve así:

root@kitploit:~
function ActiveXObject(name) {
	name = name.toLowerCase();
	/* ... */
	switch (name) {
		case "wscript.shell":
			return require("./emulator/WScriptShell");
		/* ... */
		default:
			kill(`Unknown ActiveXObject ${name}`);
			break;
	}
}

Añade un nuevo case "winhttp.winhttprequest.5.1" (¡nota las minúsculas!), y haz que devuelva un objeto Proxy de ES6 (ej. ProxiedWinHttpRequest). Esto se usa para detectar características no implementadas tan pronto como las solicite la muestra maliciosa:

root@kitploit:~
/* emulator/WinHttpRequest.exe */
const lib = require("../lib");

module.exports = function ProxiedWinHttpRequest() {
	return new Proxy(new WinHttpRequest(), {
		get: function(target, name, receiver) {
			switch (name) {
				/* Add here "special" traps with case statements */
				default:
					if (name in target) return target[name];
					else lib.kill(`WinHttpRequest.${name} not implemented!`)
			}
		}
	})
}

function WinHttpRequest() {
	
}

Vuelve a ejecutar el análisis: fallará de nuevo, diciéndote exactamente lo que no estaba implementado.

root@kitploit:~
1 Jan 00:00:00 - WinHttpRequest.open not implemented!
Trace
    at kill (/home/CapacitorSet/box-js/run.js:24:10)
    at Object.ProxiedWinHttpRequest.Proxy.get (/home/CapacitorSet/box-js/run.js:89:7)

Emula WinHttpRequest.open según sea necesario:

root@kitploit:~
function WinHttpRequest() {
	this.open = function(method, url) {
		URLLogger(method, url);
		this.url = url;
	}
}

e itera hasta que el código se emule sin errores.

Contribuidores

@CapacitorSet: Desarrollador original

@kirk-sayre-work: Mantenedor

@daviesjamie:

  • empaquetado npm
  • ayuda de línea de comandos
  • --output-directory
  • corrección de errores

@ALange:

  • soporte para codificaciones no UTF-8
  • reporte de errores

@alexlamsl, @kzc

  • asesoramiento sobre la integración de UglifyJS en box-js
  • mejora de las características de UglifyJS utilizadas en la desofuscación

@psrok:

  • corrección de errores

@gaelmuller:

  • corrección de errores
Descargar herramienta