JavaScript 信标和 C2,用于 XSS 有效载荷或后利用植入,针对 Web 应用服务器或桌面软件,以监视用户并维持持久性。包含浏览器扩展、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
在 HackSpaceCon 上演示的 JS-Tap 第2版,包括 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 的进攻性工具包,专为红队设计。它最初是一个通用的 JavaScript 载荷,用于通过 XSS 或后渗透植入攻击 web 应用,现已发展出浏览器扩展和 Electron 桌面应用植入——所有这些都报告给同一个 C2 服务器。
该载荷不需要运行载荷的目标用户已认证到被攻击的应用,也不需要事先了解应用,只需找到一种方法将 JavaScript 注入应用中即可。
JS-Tap 载荷不直接攻击应用服务器,而是专注于应用客户端并对其代码进行大量检测。C2 系统允许添加自定义 JavaScript 载荷并作为任务在 JS-Tap 客户端上运行,从而提供直接攻击应用服务器的手段。为了更快地转向攻击服务器,JS-Tap 现在包含一个“模仿”功能,可自动生成自定义载荷并将其交给 C2 系统。
示例 DOM Beacon 载荷包含在 payloads 目录的 telemlib.js 文件中,但此目录中的所有文件均未经认证即可提供,因此你可以同时提供多个针对不同应用的配置不同的载荷。
将 telemlib.js 文件复制为你希望的任何文件名,并根据需要修改配置。该文件_未_经过混淆。在参与行动之前,强烈建议更改端点命名、删除注释并对载荷进行高度混淆。默认情况下,应用使用相当明显的 API 端点(例如 /loot/screenshot),在 应用设置 中你可以开启流量混淆。
在公共暴露的服务器上使用之前,请务必仔细阅读下面的配置部分。
JS-Tap 有五种信标/代理类型连接到同一台服务器:
| 信标类型 | 说明 | 如何部署 |
|---|---|---|
| DOM Beacon (telemlib.js) | 注入到网页中的 JavaScript 载荷。检测 DOM、捕获用户活动、屏幕截图、网络调用。 | XSS 漏洞,或直接添加到目标应用的 JavaScript 文件中(后渗透)。 |
| BEX Beacon | 浏览器扩展(Chrome MV3 / Firefox MV2)。监控所有浏览活动,捕获 Cookie(包括 httpOnly)、localStorage、sessionStorage 和请求头。可根据命令向特定域名注入 DOM Beacon。 | 安装在目标用户的浏览器中(社会工程、物理访问、策略推送等)。 |
| Sidecar | 在目标操作系统上运行的原生 Go 二进制文件。提供文件系统浏览、文件读取和命令执行功能。 | 通过原生消息与 BEX Beacon 一起安装。需要 BEX Beacon 来中继命令。 |
| Atom Beacon | 用于 Electron 桌面应用的双层植入。注入主进程代理(Node.js 运行时)+ 渲染器载荷到所有应用窗口。结合了浏览器级别的数据收集和主机级别的操作系统访问——无需单独的二进制文件。支持浏览器代理模式。 | 使用 atomize.py 修补目标 Electron 应用的 ASAR 存档(或未打包的应用目录)。 |
| V8 Beacon | 用于 Node.js 和 Bun CLI 应用(Gemini CLI、Claude Code 等)的 JavaScript 代理。拦截所有 HTTP/Fetch 网络调用,捕获按键,并提供文件系统和 shell 访问。零依赖。 | 通过环境变量注入:NODE_OPTIONS="--require"(Node.js)或 BUN_OPTIONS="--preload"(Bun)。无需修补应用。 |
所有五种信标都报告给同一个 JS-Tap 服务器门户,在此查看战利品并发出 C2 命令。
门户还包括两个会话克隆工具:
| 工具 | 功能 |
|---|---|
| 浏览器代理 | JS-Tap 服务器上的 MITM 代理,通过 WebSocket 将操作员的 HTTP/HTTPS 流量路由到受害者的浏览器(或 Node.js 进程)。请求从受害者的网络上下文中获取,因此目标站点看到的是受害者的 IP 和 TLS 指纹。与 Session Ticket 结合,可通过受害者的网络进行认证浏览。BEX、Atom 和 V8 Beacons 均支持。参见下面的 浏览器代理。 |
| JS-Tap Conductor | 独立的 Firefox 扩展,导入 BEX Beacon 捕获的会话数据(作为“JS-Tap Ticket”)并在本地重放——设置 Cookie、注入头、填充存储、伪造 User-Agent——以便操作员以受害者身份浏览。参见下面的 JS-Tap Tickets & JS-Tap Conductor。 |
独立的 DOM Beacon: DOM Beacon 载荷 (telemlib.js) 独立工作。通过 XSS 注入或植入目标应用的 JS 文件中。它会自行向 JS-Tap 服务器回连。
BEX Beacon 作为投放器: BEX Beacon 监控浏览并收集被动情报(Cookie、localStorage、sessionStorage、请求头、导航)。从 JS-Tap 门户,你可以命令信标将 DOM Beacon 注入到特定域名。由 BEX Beacon 派生的 DOM Beacon 通过扩展的 captureVisibleTab API 获得高质量的屏幕截图(“BEX-Assist”模式)。
Sidecar 用于操作系统访问: 安装后,Sidecar 二进制文件使 BEX Beacon 能够访问底层操作系统。命令从 JS-Tap 门户发送,通过信标的加密通道中继到原生二进制文件,结果返回。这将浏览器扩展转变为文件系统访问和命令执行的立足点。
浏览器代理用于实时浏览: 操作员将浏览器配置为使用 JS-Tap 代理,所有 HTTP/HTTPS 流量实时通过受害者的浏览器路由。代理执行 MITM TLS 终止(使用自动生成的 CA),以便操作员可以浏览 HTTPS 站点。代理是一个“哑管道”——它精确转发操作员浏览器发送的内容。对于认证浏览,与 Session Ticket 结合:JS-Tap Conductor 将受害者的 Cookie、头和 User-Agent 注入到操作员的浏览器中,MITM 代理将其转发给信标,信标从受害者的网络中获取。这使操作员从受害者的 IP 地址获得认证会话。BEX、Atom 和 V8 Beacons 都支持代理模式。
用于 Electron 应用的 Atom Beacon: atomize.py 修补程序修改 Electron 应用的 ASAR 存档以注入 Atom Beacon 代理。启动时,代理向 JS-Tap 服务器注册,开始加密的 C2 通信,并自动将渲染器载荷注入到应用创建的每个 BrowserWindow 中。主进程代理提供原生操作系统访问(文件系统、命令执行),而渲染器载荷收集 DOM 级别的数据(按键、输入、表单、Cookie、存储、网络调用)。由于它在 Electron 主进程中运行,具有完整的 Node.js 访问权限,因此不需要单独的 sidecar 二进制文件——文件浏览、文件读取和 shell 命令都是内置的。
用于 CLI 工具的 V8 Beacon: V8 Beacon 针对基于 Node.js 和 Bun 的 CLI 应用。设置环境变量(NODE_OPTIONS 或 BUN_OPTIONS),信标在应用自身代码之前加载——无需修补或修改目标应用。它猴子补丁 http.request、https.request、fetch 和 http2.connect 以拦截所有网络流量,挂钩 process.stdin 以捕获按键,并通过 C2 通道提供文件浏览和 shell 执行。产生子进程的 CLI 工具(例如 Gemini CLI 为交互式会话产生自身作为子进程)会自动处理——子进程继承父进程的会话密钥,并在门户中共享同一个逻辑客户端。跨运行时子进程过滤可防止 Bun 应用的 Node.js 实用子进程注册为单独的客户端。
用于特定应用攻击的插件: Atom Beacon 和 V8 Beacon 客户端支持运行时加载的插件。插件是从 JS-Tap 门户加载的 JavaScript 模块,用于扩展信标针对特定目标应用(例如 Mattermost 插件)的能力。插件可以访问信标的 Node.js API(fs、http、crypto、child_process)、Electron API(适用于 Atom Beacons)以及返回服务器的数据外泄通道。每个插件包含一个清单(manifest.json),声明其目标应用、能力和操作员可配置的设置,以及一个可选的 UI 面板(ui.html)在门户中显示。
注意:在陷阱模式下可以接收 XHR 和 Fetch API 调用的副本。在植入模式下,目前只能复制 Fetch API。植入模式下表单提交的拦截有时可能会错过。
browser.cookies.getAll() 获取,附带元数据:httpOnly、secure、sameSite、path、domain、expiration)主进程代理(Node.js 运行时):
session.cookies API(包括 httpOnly,带元数据)webRequest.onBeforeSendHeaderswebRequest.onHeadersReceiveddesktopCapturer API(捕获 GPU 合成输出)渲染器载荷(注入到所有应用窗口):
document.cookie,跟踪变更)process.stdin 捕获按键(缓冲为可读字符串,每 2 秒或按 Enter 时刷新)DOM Beacon 载荷有两种操作模式。模式是 trap 还是 implant 在 initGlobals() 函数中设置,搜索 window.taperMode 变量。
陷阱模式通常是你作为 XSS 载荷使用的模式。XSS 载荷的执行通常是短暂的,查看恶意 JavaScript 载荷运行的页面的用户可能会关闭浏览器标签(页面不有趣)或导航到应用的其他地方。在这两种情况下,载荷将从内存中删除并停止工作。JS-Tap 需要运行很长时间,否则你不会收集到有用的数据。
陷阱模式通过使用 iFrame 陷阱技术 建立持久性来应对这一问题。JS-Tap 载荷将创建一个全页 iFrame,并将用户引导到应用的其他地方。这个起始页面必须提前配置。在 initGlobals() 函数中搜索 window.taperstartingPage 变量,并将其设置为目标应用中的一个适当起始位置。
在陷阱模式下,JS-Tap 监控用户在 iframe 陷阱中的位置,并伪造浏览器的地址栏以匹配 iframe 的位置。
请注意,如果目标应用设置了 CSP 或 X-Frame-Options 头部,它必须允许来自同源或自身的 iFraming。基于 JavaScript 的框架破坏器也可能阻止 iFrame 陷阱工作。
注意,我在非常特定的应用位置使用陷阱模式作为后渗透植入时取得了良好效果,或者当我不确定应用在认证部分内部使用了哪些资源时。你可以将植入放在登录页面,陷阱模式启动页面设置为 window.location.href(即当前位置)。当用户访问登录页面时,陷阱将生效,并且希望他们会继续在 iframe 陷阱内进入应用的认证部分。
用户刷新页面通常会破坏/逃脱 iframe 陷阱。
植入模式通常在你直接将载荷添加到目标应用中时使用。也许你在托管应用 JavaScript 文件的服务器上有一个 shell。将载荷添加到整个应用中都使用的 JavaScript 文件中(jQuery、main.js 等)。哪个文件最理想实际上取决于具体的应用以及它如何使用 JavaScript 文件。植入模式不需要配置起始页面,也不使用 iFrame 陷阱技术。
在植入模式下,用户刷新页面通常会继续运行 JS-Tap 载荷。