Cross-site request forgery (CSRF)
1. 没有防御措施的 CSRF 漏洞
题目中已告知易受攻击的是电子邮件的更改功能,而目标是利用 csrf 漏洞更改受害者的电子邮件地址,最后给出了登录凭据:wiener:peter。
- 登录 wiener 用户——首先做的事是根据给定的登录凭据进行登录,点击 My account 登录,登录后就到了一个更改邮箱的界面,这时候然设置代理以便 burp 抓包。
- burp 抓包——尝试输入
[email protected]
,点击 update email,通过 burp 抓包,发送到 repeater 后关闭拦截,此时回到更改邮箱的界面发现电子邮件已被更改为[email protected]
。 - 进行 csrf 攻击——因为 burp 有自动生成脚本的功能,右键 Generate CSRF PoC,进入界面后在选项一栏把自动提交脚本勾选上,这时候 burp 会自动提交表单不需要自己点击提交了。点击 regenerate 重新生成发现多了
document.forms[0].submit();
。 - 进行 csrf 攻击——把代码中的 emali 修改为
[email protected]
以便测试之用,接着 copyhtml,转到漏洞利用服务器,在 body 中放入 html,store 保存,点击 View exploit 查看漏洞,最后 Deliver to victim,传递给受害者即可成功
2. token 验证取决于请求方法
- 登录 wiener 用户——依旧是账号密码进行登录,wiener:peter,然后在更改邮箱的界面输入
[email protected]
进行抓包
- 改变请求方法——因为 POST 请求会对 token 验证(在没有 token 的情况下会 404),从而无法修改邮箱,而 GET 不需要。于是右键 burp 点击 Change request method,将请求方法从 POST 更改为 GET
- 进行 csrf 攻击在 burp 中右键生成 csrf poc,选项中把自动提交脚本选择上,代码中的 emali 修改为
[email protected]
,copy html,用 burp 的服务器托管脚本,粘贴到 body 中。最后点击"Store",并发送给受害者,完成试验
3. token 验证取决于 token 的存在
- 在上一个关卡,请求改为 GET 是因为检查了 POST 方法是否允许我们删除 token,删除 token 后,POST 请求 404, 所以可以用 GET 方法进行绕过
- 在这一关中攻击者删除 token,返回 302。这说明 token 不存在请求便会通过,简单粗暴
- 右键生成 CSRF Poc,后续步骤和前面一致
4. token 与用户会话无关
题目给出了两个账户
- 攻击者账户——
wiener:peter
- 受害者账户——
carlos:montoya
- 登录两个账户——把两个账户分别分别登陆,目标是从 wiener 那更改 carlos 的电子邮件地址
- 改变请求方法——拦截 wiener 的请求在 burp 中查看,删除 csrt token 的一个字符返回 404,请求方法改为 GET,依旧是 404
-
从 carlos 用户中找到 CSRF Token——登录 carlos,在更改邮箱的界面打开“开发者工具”找到 CSRF Token,复制后在 burp 中粘贴到相应位置,返回 302
- 这说明虽然应用程序需要一个 token 处理请求,但不关心它是怎么来的。换言之,应用系统仅会验证 CSRF Token 的有效性,而不会验证该 Token 是否属于当前用户,也就是标题说的 Token 不会与用户会话绑定
-
进行 csrf 攻击——最后利用 burp 的 csrf poc 功能,复制 html 后需要回到攻击者 wiener,刷新 carlos 的网页来收集新的 token(token 随着请求的变化而变化)替换到 burp 中
5. token 绑定到非会话 cookie
题目给出了两个账户
- 攻击者账户——
wiener:peter
- 受害者账户——
carlos:montoya
测试 CSRF Token 和 CSRF Cookie
-
抓包 wiener 用户 ——发现 Cookie 中存在一个 csrfkey。删除 CSRF Token 的某个字符则返回 400。
-
查看 carlos 用户的 CSRF Token——从另一个用户查看 Cookie 是否相互绑定。登录另一个用户(carlos),可以在火狐无痕窗口,查看 CSRF Token,粘贴到 wiener 用户的 burp,send 发送后 400。
- 查看 carlos 用户的 CSRFKey cookie——在 carlos 账户中,点开网络,点重新载入,找到 CSRFKey cookie。粘贴到 wiener 用户的 burp,send 发送后 302,这说明两者没有进行绑定的,可喜可贺。
-
**wiener 用户首页搜索框中 CSRFKey 参数注入 **——在 wiener 账户的首页发现有搜索框,输入“ceui”进行抓包处理,能看到搜索的关键词在 Set-Cookie 标头。因为搜索功能没有 CSRF 保护,所以可以轻而易举的注入 cookie。
-
将已知的 csrfKey cookie 注入给被攻击者
-
/?search=test%0d%0aSet-Cookie:%20csrfKey=YOUR-KEY%3b%20SameSite=None # SameSite=None——显式设置 SameSite=None(一个新值),该值表示放弃对 Cookie 的 Same-Site 策略设置,通俗说就是“我不管了”。
-
- csrf 攻击——最后存储漏洞,单击“交付给受害者”。
6. token 在 cookie 中重复
- 如图所示,应用程序只需验证在请求参数中提交的 Token 是否与 Cookie 中提交的值匹配
- 搜索,查看 Set-Cookie 标头中是否有搜索词
- 将虚假 CSRF Cookie 注入受害者浏览器的 URL
- 最后注入 cookie 并提交表单
7. Referer 验证取决于 header 是否存在
- 登录帐户,抓取“更新电子邮件”表单的请求
- 在 burp 中查看,发现出现了 Referer,删除则返回 302 即成功
- 在 HTTP 头中有一个字段叫 Referer,记录了该 HTTP 请求的来源地址,同源检测(Origin 和 Referer 验证)
- 生成 PoC 网页返回 "Invalid referer header",这是因为 Referer 的来源是 burp
- 禁止 Referer 标头,
<meta name="referrer" content="no-referrer">
,作用是控制页面发送给 server 的 referer 信息,告诉服务器端用户是从哪个页面来到当前网页的。- no-referrer: 所有请求不发送 referrer
8. Referer 验证失效的 CSRF
-
登录帐户,抓取“更新电子邮件”表单的请求
-
追加到 Referer 标头请求成功,这说明网站似乎接受任何包含预期的 Referer 标头
-
在 script 中编辑 JavaScript
-
history.pushState("", "", "/?0aac003b03b74a00c0510db300a200ff.web-security-academy.net")
-
-
在头部添
Referrer-Policy: unsafe-url
,是因为需要请求中包含完整的 URL ,以此来覆盖浏览器的默认配置(默认从 Referer 标头中删除查询字符串)