reverse-skills-max: initial public release (restored, redacted, hardened)

This commit is contained in:
baradok609hecl1pq6qi
2026-10-20 02:17:15 +03:00
commit da24c2bd20
2227 changed files with 443931 additions and 0 deletions

View File

@@ -0,0 +1,119 @@
---
name: re-browser-ext
type: atomic
description: >
浏览器扩展逆向:权限清单、恶意行为定位、混淆还原、上架审查绕过面。
触发词:浏览器扩展、Chrome扩展、Firefox扩展、恶意扩展、extension。
capabilities: [browser-extension]
---
# 浏览器扩展逆向
## 何时使用 / 何时不用
- 用:扩展文件(crx/xpi/zip)、恶意扩展行为分析、扩展权限审计
- 用:判断扩展是否过度授权、远程代码、更新投毒(首版干净后续版本恶意)
- 不用:网页 JS 混淆([[re-script-deob]] 覆盖纯脚本)
- 不用:Chrome/Edge 浏览器本身的漏洞利用(扩展与浏览器漏洞是两个对象)
- 注意:动态加载扩展跑恶意行为属执行未知代码——沙箱内进行([[re-sandbox]],[[re-analyze/platform-tips]] 最高原则)
## 工具准备
### unzip / 7z / python zipfile(解包)
- 安装与验证见 [[re-doc-malware]] 工具准备(7z)
- crx = "Cr24" 头(版本号 + 头长度;crx2 含公钥与签名、crx3 含 protobuf 头与 proof)+ 尾部 zip 数据——`unzip`/`7z` 直接解包会报 `extra bytes at beginning` 警告但结果正确;`python3 -m zipfile -e sample.crx ext/` 无警告
- xpi 就是纯 zip,直接解
### jq(manifest 解析)
- Linux: `apt install jq`;macOS: `brew install jq`;Windows: 官方构建
- 验证: `jq --version`
### node / js-beautify(脚本还原)
- Linux: `apt install nodejs`;macOS: `brew install node`;Windows: nodejs.org 官方安装包;验证: `node --version`
- js-beautify: `npm install -g js-beautify`,验证 `js-beautify --version`(压缩 JS 先格式化再读)
### 浏览器加载验证(动态,沙箱)
- Chromium 系: `chrome://extensions` 开发者模式 → Load unpacked;Edge 同(`edge://extensions`)
- Firefox: `about:debugging#/runtime/this-firefox` → Load Temporary Add-on(免签名临时加载)
- 验证: 扩展出现在扩展列表、后台脚本/页面能打开
## 操作步骤
按顺序执行,每步产物存档(路径 + sha256,见 [[re-triage]])。
1. **解包与结构**:
```sh
unzip -o sample.crx -d ext/ 2>/dev/null || python3 -m zipfile -e sample.crx ext/
jq '.manifest_version, .name, .version' ext/manifest.json
jq '.permissions, .host_permissions' ext/manifest.json
# host_permissions 为 MV3 字段;MV2 站点权限在 permissions 内(含 URL 匹配模式)
```
- 结构:manifest.json + 背景脚本(MV3 service worker / MV2 background page)+ 内容脚本(content_scripts)+ 页面(options/popup)+ 资源(web_accessible_resources)
- 先确认 `manifest_version`(2 还是 3)——MV2/MV3 的权限模型与能力差异决定后续所有判断(见 [[gotchas]])
- 其他关键字段:`update_url`(自托管更新清单,投毒面)、`key`(扩展 ID 派生)、`externally_connectable`(外部页面消息通道)、`oauth2`(令牌)、`optional_permissions`(运行时再要权)、`minimum_chrome_version`(兼容边界)
- 次要结构:`_locales/`(i18n 消息,可藏字符串)、`icons/`、`options_page` / `options_ui`、`commands`(快捷键,触发行为入口)、`incognito`(隐身窗口行为声明)
2. **权限审计(能力边界)**:
- 高危 API 权限:`tabs`(读标签页 URL/标题)、`storage`(数据收集缓存)、`webRequest`(流量观察;MV3 阻断能力仅企业策略部署例外,一般改走 `declarativeNetRequest`)、`scripting`(MV3 动态注入)、`clipboardRead`(剪贴板)、`cookies`(读站点 Cookie)、`history`、`downloads`、`nativeMessaging`(与宿主程序通信)、`debugger`
- 站点权限(host_permissions / MV2 permissions 内 URL 模式)决定能碰哪些网站的数据——`<all_urls>` 或 `*://*/*` 是高危信号
- 权限与声明用途对照:装了 `storage`+`tabs`+`<all_urls>` 但功能只是改主题——越权信号
- 权限风险速查(声明即能力,不必看代码):
| 权限 | 能力 | 恶意用途 |
|---|---|---|
| `tabs` + `<all_urls>` | 读标签页 URL/标题 | 浏览习惯收集 |
| `storage` | 本地持久化 | 收集数据缓存/配置下发 |
| `webRequest` / `declarativeNetRequest` | 流量观察/规则修改 | 监控、注入、拦截 |
| `scripting` / `content_scripts` | 页面注入 | 键盘记录、表单窃取 |
| `clipboardRead` | 读剪贴板 | 剪贴板内容窃取(如钱包地址) |
| `cookies` | 读/写站点 Cookie | 会话劫持 |
| `nativeMessaging` | 与宿主程序通信 | 落地可执行/外带数据 |
| `downloads` | 读写下载 | 下载投毒/篡改下载文件 |
3. **恶意行为定位**:
- 数据外泄:fetch/XHR/`navigator.sendBeacon`、图片像素外传(`new Image().src`)、`chrome.storage` 收集后批量上传([[re-netcap]] 衔接)
- 注入面:content_scripts 匹配站点、动态注入(MV3 `chrome.scripting.executeScript`;MV2 `tabs.executeScript`)、`web_accessible_resources` 开放页面供第三方站点调用
- 键盘记录:content script 监听 keydown/input 并外传——搜索 `addEventListener('keydown'` 与 `value` 读取
- 触发时机:`chrome.runtime.onInstalled` / `onStartup`(安装/启动即跑)、`chrome.alarms` / `setInterval`(定时任务)、`chrome.runtime.onMessage`(消息驱动)——按触发点还原调用链,别只看顶层代码
- 后台脚本是核心:MV3 的 service worker / MV2 的 background page;MV3 service worker 空闲约 30 秒被终止、事件唤醒——状态在 `chrome.storage` 或 IndexedDB 落地,别在全局变量里找持久状态
4. **混淆还原**:
- 衔接 [[re-script-deob]] 高级混淆对抗(bootstrap/字符串表/CFF);压缩代码先 js-beautify 再读
- 远程代码:MV2 允许远程 JS(`eval`/动态加载);MV3 禁止远程代码(所有代码必须打包)——MV3 里出现远程拉取 = 审查绕过信号,重点标记
- 二进制载荷:Wasm/ArrayBuffer 下载后分析(转 [[re-binary-core]] 初勘)
- 字符串定位:`grep -rniE 'http|sendBeacon|fetch|XMLHttpRequest|chrome\.' ext/` 扫全包;i18n 字符串在 `_locales/*/messages.json`(消息外衣下藏真实 URL 常见)
5. **更新机制与版本投毒**:
- Chrome 系:`update_url` 自托管更新清单(XML 指向新 crx)是投毒入口;商店自动更新同理
- 版本对比:拉旧版本扩展与当前版本做 diff(文件清单/哈希/manifest/脚本),定位"何时引入恶意"([[re-variant]] 思路)
- 变更归因:diff 结果按文件归类(manifest 权限变化 / 新增脚本 / 存量脚本改写),权限在更新中扩大是投毒信号
- Firefox:更新只经 AMO 渠道,`update_url` 不生效——投毒面不同
6. **动态验证**(沙箱):
- 加载到浏览器(工具准备),配好代理/抓包([[re-netcap]]),触发功能看网络与存储变化
- 分上下文分析:background / content script / 扩展页面 三套隔离上下文,API 调用点按上下文定位(坑 4)
- 扩展页面/弹窗可直接开 DevTools(`chrome-extension://<id>/` 页面 F12)——配合断点看 service worker 内全局状态与网络调用
- 行为记录与 [[re-ioc]] 指标提取(C2 域名、命令格式)衔接
## 跨域联合
- [[re-managed]] 网关:本技能归属(选择树「浏览器扩展」分支)
- [[re-script-deob]]:混淆还原
- [[re-netcap]]:网络行为衔接(外传/远程拉取)
- [[re-variant]]:扩展版本对比(更新后恶意检测)
- [[re-triage]]:解包物哈希/初勘存证
## 常见坑与陷阱
- **manifest 版本差异**:现象——MV2 分析思路套 MV3 失效;原因——权限模型不同(MV3 禁远程代码/后台改 service worker);对策——先确认 manifest_version,按版本分支分析(见 [[gotchas]])
- **远程代码策略**:现象——静态找不到恶意逻辑;原因——代码远程拉取(MV2);对策——网络侧抓取([[re-netcap]])后还原
- **动态注入绕过静态分析**:现象——content_scripts 无恶意但行为异常;原因——运行时注入;对策——hook 注入 API(scripting.executeScript / tabs.executeScript)
- **沙箱与页面隔离**:现象——扩展 API 调用点难定位;原因——扩展上下文与页面上下文隔离;对策——分上下文分析(background/content/page),按 API 归属判断在哪个上下文执行
- **更新后恶意**:现象——首版干净;原因——版本更新注入恶意;对策——版本 diff([[re-variant]])
- **service worker 状态丢失**:现象——MV3 后台脚本里找不到持久数据;原因——service worker 空闲被终止,状态在存储层;对策——查 `chrome.storage`/IndexedDB 落地数据
- **Firefox MV3 差异**:现象——manifest 写了 `background.service_worker` 但 Firefox 里后台不跑;原因——Firefox MV3 不支持 service_worker 字段,用 `background.scripts` 事件页;对策——双字段写法(Chrome 用 service_worker、Firefox 用 scripts)按浏览器分别验证
- 更多 MV2/MV3 差异、crx 格式细节与审查绕过边界见 [[gotchas]] 与 [[decision-tree]]

View File

@@ -0,0 +1,89 @@
# 浏览器扩展分析决策树与证据分级
## 场景决策树(入口 → 分支)
### 1. 包格式判定(第一级)
```
扩展文件
├─ "Cr24" 头 → CRX(Chromium 系)
│ ├─ 版本号 2 → crx2(旧;Chrome 78 起不再支持安装,分析照常解包)
│ └─ 版本号 3 → crx3(当前标准,带 protobuf 头 + proof 签名)
├─ 纯 zip 无 Cr24 → 可能是 xpi(Firefox)或未打包目录压缩包
│ └─ 解包后看 manifest.json 是否存在
└─ 既非 Cr24 也非 zip → 不是标准扩展包,回 [[re-triage]] 重新识别
```
- 扩展目录(未打包)也可直接分析:manifest.json + 脚本文件与打包后内容一致
- crx2/crx3 头都只是前缀,zip 数据从尾部偏移开始——`unzip` 报 `extra bytes` 警告即正常解包信号
### 2. manifest 版本分支(第二级)
```
manifest_version
├─ 3(MV3)
│ ├─ 后台: background.service_worker(Chrome);Firefox 用 background.scripts
│ ├─ 远程代码: 禁止——出现远程拉取 = 审查绕过信号
│ ├─ 站点权限: host_permissions 独立字段
│ └─ 流量修改: declarativeNetRequest(webRequest 阻断仅企业策略例外)
├─ 2(MV2)
│ ├─ 后台: background.page 常驻页面
│ ├─ 远程代码: 允许(eval/动态加载)——远程拉取是常见投毒手法
│ ├─ 站点权限: 混在 permissions 里(URL 匹配模式)
│ └─ 流量修改: webRequest blocking
└─ 缺失/非法 → manifest 损坏或伪造,标注异常
```
### 3. 行为定位分支(第三级)
```
静态读完 manifest + 脚本后
├─ 有网络外传代码(fetch/XHR/sendBeacon/Image.src)
│ └─ 目标地址静态可判定 → [[re-ioc]] 指标提取
│ └─ 目标地址动态生成/远程拉取 → 网络侧抓取([[re-netcap]])→ 沙箱动态
├─ 有注入能力(content_scripts/scripting.executeScript/动态脚本标签)
│ ├─ 注入代码内嵌 → 静态还原([[re-script-deob]])
│ └─ 注入代码远程 → 动态加载抓包还原
├─ 有敏感数据收集(tabs/storage/cookies/keydown 监听/clipboard)
│ ├─ 收集量小且本地上送 → 重点标记外传目标
│ └─ 收集 + 批量上传 → 高可疑
├─ 有 update_url 自托管更新 → 拉历史版本 diff([[re-variant]])定位投毒点
├─ 有 nativeMessaging → 查宿主清单文件(manifest 外)与宿主程序
└─ 静态全干净 → 沙箱动态加载,观察网络/存储/权限调用
```
### 4. 动态阶段分支
```
沙箱加载扩展
├─ 网络有异常外传 → 抓包 → 还原数据格式 → 指标提取
├─ 无外传但 storage 有写入 → 查看存储内容,找外传触发条件(交互/定时/特定站点)
├─ 只在特定站点触发 → 用目标站点模拟访问,观察 content script 行为
└─ 全程无行为 → 检查触发条件:用户交互、权限授予弹窗、未匹配 host 权限
```
## 证据分级表
| 级别 | 证据形态 | 示例 | 用途 |
|---|---|---|---|
| A 强 | 动态行为 + 网络侧闭合 | 沙箱内观察到数据外传,抓包与静态代码目标一致 | 可下"恶意"结论 |
| B 中 | 静态代码链闭合 | 代码明文收集并上传、manifest 越权声明成立 | 可下"高可疑" |
| C 弱 | 静态特征 | 只有高危权限声明、混淆程度高 | 只支持"需深入",不下结论 |
| 反证 | 良性解释 | 权限用途与功能相符、无外传代码 | 记录并存档 |
- 恶意扩展常"首版干净、更新投毒":单版本结论需标注版本范围(哪个版本起恶意),版本链对比是必要环节
- 结论同时标注浏览器族(Chromium/Firefox)——同一扩展两平台行为可不同(Firefox 无 service_worker、AMO 渠道更新)
## 实现教训(内化)
- 先定 MV 版本再定分析框架:MV2/MV3 的权限语义、远程代码合法性、流量修改 API 完全不同,交叉套用必然误判
- 静态定位要区分"数据流向":收集(读 API)→ 汇聚(storage)→ 外传(网络)三段,各段都要有落点
- 远程代码是 MV3 里最强的恶意信号,但 MV2 里是合法能力——同一特征在不同 MV 版本下证据强度不同
- 更新投毒检测靠版本 diff,不是靠单版本分析:保留文件清单/哈希基线,新版本逐文件对比
- 动态验证前先静态读完 manifest 权限——决定沙箱里哪些 API 调用会被权限弹窗拦下,避免误判"无行为"
- 证据链记录:文件 sha256、manifest 原文、外传目标、触发条件(哪个上下文/哪个事件)
## 使用注意
- 动态加载与触发在沙箱内进行([[re-sandbox]],[[re-analyze/platform-tips]] 最高原则);扩展与浏览器同权限运行,隔离不当等于执行恶意代码
- 分析结论按本表分级标注;权限审计结论(越权/过度授权)与恶意结论分开陈述

View File

@@ -0,0 +1,35 @@
# 浏览器扩展分析方法论坑与边界
## MV2 / MV3 差异组(最容易踩)
- **权限字段语义不同**:MV3 站点权限独立在 `host_permissions`,MV2 混在 `permissions` 内(URL 匹配模式)——只读一个字段会漏判一半权限边界
- **远程代码合法性相反**:MV2 允许远程 JS(动态加载/`eval`),MV3 一律禁止(所有代码必须打包随扩展分发)——"远程拉取代码"在 MV2 是常见能力、在 MV3 是审查绕过信号,证据强度随版本不同
- **后台形态不同**:MV2 是常驻 background page;MV3 是 service worker——MV3 worker 空闲约 30 秒被终止、事件唤醒,**全局变量状态丢失**;持久状态必然落在 `chrome.storage`/IndexedDB,静态分析别在全局变量里找持久数据
- **流量修改 API 换血**:MV2 `webRequest` blocking 可拦截修改;MV3 商店扩展一般只剩 `declarativeNetRequest`(声明式规则),webRequest 阻断仅企业策略部署的例外——MV3 里找不到 webRequest 拦截代码是正常的
- **executeScript 挪窝**:动态注入 MV2 是 `tabs.executeScript`,MV3 是 `scripting.executeScript`(需 `scripting` 权限)——按版本搜对应 API 名
- **action 统一**:MV2 的 `browser_action`/`page_action` 在 MV3 统一为 `action`——页面弹窗代码位置按版本不同
## 跨浏览器差异组(Chromium vs Firefox)
- **Firefox MV3 不支持 `background.service_worker`**:声明了也不执行(warning 后忽略),实际用 `background.scripts` 事件页——同一扩展在 Firefox 里后台可能根本不跑,动态验证要按浏览器分别做
- **更新渠道不同**:Chrome 系支持 `update_url` 自托管更新清单(投毒入口);Firefox 更新只经 AMO 渠道,`update_url` 不生效——"自托管更新投毒"仅 Chromium 系成立
- **签名要求不同**:Firefox AMO 要求扩展签名(临时加载例外);Chromium 系开发者模式可加载未打包目录——动态分析入口不同
- **扩展 ID 派生**:Chrome 扩展 ID 由 manifest `key` 字段公钥/打包签名派生;Firefox ID 在 manifest 的 `browser_specific_settings.gecko.id` 显式声明——找 ID 的位置不同
## 解包与格式组
- **crx 解包警告别当错误**:`unzip`/`7z` 对 crx 报 `extra bytes at beginning or within zipfile` 是正常(Cr24 头在前),结果可用;想无警告用 `python3 -m zipfile -e`
- **crx2/crx3 头差异**:crx2 头含公钥与签名(可变长),crx3 是 protobuf 头 + proof——头长度字段是 LE 4 字节,先读版本号再读头长度,别按固定偏移跳
- **xpi 与 zip 无头**:Firefox xpi 就是 zip,解包无警告——"解包报错"本身可作格式判定线索
## 审查绕过与反例组
- **无远程代码也有投毒面**:扩展更新机制(自托管/商店)本身就是远程代码通道——单版本静态干净 ≠ 安全,必须看更新链(反例:首版干净、更新后恶意是常见形态)
- **混淆不是恶意证据**:商店政策允许合理打包混淆,但高混淆 + 高危权限 + 少功能组合才是可疑信号——别单凭混淆下结论
- **`<all_urls>` 权限不是必然恶意**:部分合法功能(翻译/词典/脚本管理器)确实需要全站点权限——按"权限 vs 声明功能"对照判断,越权信号要结合行为
- **content script 的隔离上下文**:content script 与页面共享 DOM 但不共享 JS 环境——页面里找不到扩展注入的变量,扩展里也读不到页面全局;跨上下文证据链要按消息传递(runtime.sendMessage)还原
## 使用注意
- 动态加载与行为触发在沙箱内([[re-sandbox]],[[re-analyze/platform-tips]] 最高原则);扩展以浏览器进程权限运行,未隔离环境不加载
- 分析结论按 [[decision-tree]] 证据分级标注,并注明浏览器族与版本范围