CSRF
Lab: CSRF vulnerability with no defenses
This lab’s email change functionality is vulnerable to CSRF.
To solve the lab, craft some HTML that uses a CSRF attack to change the viewer’s email address and upload it to your exploit server.
You can log in to your own account using the following credentials:
wiener:peter
找到修改邮件的流量包,右键 Engagement tools => Generate CSRF POC ,然后点击 Copy Html 自己到浏览器试验一下
最后发到服务器上即可
Lab: CSRF where token validation depends on request method
This lab’s email change functionality is vulnerable to CSRF. It attempts to block CSRF attacks, but only applies defenses to certain types of requests.
To solve the lab, use your exploit server to host an HTML page that uses a CSRF attack to change the viewer’s email address.
You can log in to your own account using the following credentials:
wiener:peter
有些开发者也许会对 post 请求验证 csrf token 是不是对的,但是可能会忘记验证 get 请求,要是 get 请求也能实现接口,并且开发者忘记验证 token 就能实现绕过。
所以先把请求包改成 get ,然后再创建 csrf 模版
Lab: CSRF where token validation depends on token being present
This lab’s email change functionality is vulnerable to CSRF.
To solve the lab, use your exploit server to host an HTML page that uses a CSRF attack to change the viewer’s email address.
You can log in to your own account using the following credentials:
wiener:peter
上一题不校验请求方法,这一题在 token 存在时会正确验证 token ,但如果缺少 token 则会跳过验证
Lab: CSRF where token is not tied to user session
有些网站会维护一个 csrf token 集合,只要是集合里的 token 都能使用。也就是说 csrf token 不再是和用户的 session 一对一绑定。所以登陆自己的账号拿 csrf token 用就行了
注意这道题的 csrf token 用一次就会刷新(token 是一次性的),旧的被淘汰,所以我们要用刷新后的 token 去设计 POC
Lab: CSRF where token is tied to non-session cookie
This lab’s email change functionality is vulnerable to CSRF. It uses tokens to try to prevent CSRF attacks, but they aren’t fully integrated into the site’s session handling system.
To solve the lab, use your exploit server to host an HTML page that uses a CSRF attack to change the viewer’s email address.
You have two accounts on the application that you can use to help design your attack. The credentials are as follows:
wiener:petercarlos:montoya
CSRF令牌与非 session cookie相关联
这道题的 csrf-token 和 另一段 cookie 绑定,和 session 无关,可以看成是上一题的变体。也就是说这种 token 也和用户身份不直接相关,比如说
1 | POST /email/change |
也就是说 csrf token 是和 cookie 里的 csrf-key 绑定 在这种情况下,如果网站包含任何 cookie 设置功能,攻击者可以再次发起 CSRF 攻击
在搜索功能处存在 header 头注入;
后端代码大概是这样:
Python
1 | # 伪代码,直接把用户输入拼进去,没有过滤 |
vps 先挂一个 302 跳转,来 http header 注入
1 | 302 Found |
为什么是 %0d%0a 呢
| 步骤 | 说明 |
|---|---|
%0d%0a → \r\n |
服务端 URL 解码时还原成真实的回车换行符 |
\r\n 拼入响应头 |
没有过滤,直接写进 TCP 流 |
那为什么要加 \r\n 呢,不加的话从 bp repeater 里看根本就没变颜色,格式出错了
根本原因:这是一个 Set-Cookie 头,浏览器按照 RFC 6265 解析
RFC 6265 规定 Set-Cookie 的格式是:
1 | Set-Cookie: <name>=<value>; attr1; attr2=val; attr3 |
所以一个 Set-Cookie 只能设置一个 cookie
要让注入生效,唯一的办法
必须注入 \r\n(CRLF) 来另起一行,构造独立的第二个 Set-Cookie 头:
Code
1 | 输入: 123\r\nSet-Cookie: csrfKey=attacker |
服务端生成的响应头就变成两行:
HTTP
1 | Set-Cookie: LastSearchTerm=123 |
浏览器收到两个独立的 Set-Cookie 头,就会分别创建两个 Cookie,覆盖原始 csrfKey。
Lab: CSRF where token is duplicated in cookie
This lab’s email change functionality is vulnerable to CSRF. It attempts to use the insecure “double submit” CSRF prevention technique.
To solve the lab, use your exploit server to host an HTML page that uses a CSRF attack to change the viewer’s email address.
You can log in to your own account using the following credentials:
wiener:peter
这道题就更那啥了,比如
1 | POST /email/change |
后端根本就没存 cookie 的 csrf ,只会单纯傻傻的比较前端请求里的cookie csrf 和请求体 csrf 参数值是不是一样的
所以,我们假如能 header 注入的话随便改一个 csrf 的值为 123 就行了,甚至不用登录自己的账号取值,这里就不用 302 了,看了题解给了个更好的直接一步到位,主要是用 img 触发 header 注入,然后自动提交 csrf 表单
1 | <img src="https://YOUR-LAB-ID.web-security-academy.net/?search=test%0d%0aSet-Cookie:%20csrf=123%3b%20SameSite=None" onerror="document.forms[0].submit();"/> |
完整 payload (移除自动提交<script>代码块并添加 img 来注入 cookie 并且提交表单)
1 | <html> |
Lab: SameSite Lax bypass via method override
This lab’s change email function is vulnerable to CSRF. To solve the lab, perform a CSRF attack that changes the victim’s email address. You should use the provided exploit server to host your attack.
You can log in to your own account using the following credentials:
wiener:peter
首先用 Burp 内置浏览器登录自己的账号,正常修改一次邮箱地址,让 Burp 抓到合法请求。
打开 Proxy > HTTP history,重点观察两个请求:
POST /my-account/change-email:检查这个请求的 body,发现它只包含 email 参数,没有任何不可预测的 CSRF token。这意味着只要能突破 SameSite 限制,它就可能被 CSRF 利用。
POST /login 的响应:查看服务器设置会话 cookie 的 Set-Cookie 头,发现网站没有显式指定任何 SameSite 属性。根据现代浏览器的行为,这种情况下 Chrome 会默认应用 Lax 限制级别。
由此得出关键判断:既然是 Lax,那么会话 cookie 会在跨站 GET 请求中被发送,只要这个请求伴随顶级导航(top-level navigation)。这就是整个攻击的突破口。
绕过 SameSite 限制
目标很明确:把一个原本是 POST 的修改邮箱请求,变成服务器仍能接受的 GET 请求,从而满足 Lax 放行 cookie 的条件。
第一步,把 POST /my-account/change-email 请求发送到 Burp Repeater。
第二步,在 Repeater 中右键选择 Change request method,Burp 会自动生成一个等价的 GET 请求。
第三步,发送这个 GET 请求,结果服务器返回错误——这个端点只接受 POST,纯 GET 不被允许。
第四步,这正是方法覆盖参数登场的时候。尝试在查询字符串中加入 _method 参数来覆盖路由方法:
1 | GET /my-account/change-email?email=foo%40web-security-academy.net&_method=POST HTTP/1.1 |
这里的逻辑是:HTTP 层面发送的是真正的 GET(满足 Lax 携带 cookie 的条件),而 _method=POST 让后端框架在路由时按 POST 处理(匹配端点真正接受的方法)。
第五步,发送请求,服务器接受了。
第六步,回到浏览器的账户页面刷新,确认邮箱已经成功修改。绕过验证成功。
构造攻击载荷
确认了攻击向量后,把它包装成一个能在受害者浏览器上自动触发的 exploit。
进入靶场提供的 exploit server,在 Body 区域写入 HTML/JavaScript 载荷。核心要求是必须触发顶级导航,否则会话 cookie 不会被带上。最简洁的写法是用 document.location 让整个页面跳转:
html
1 | <script> |
document.location 赋值会引发整页跳转,这是一次顶级导航,因此浏览器会把靶场的 Lax 会话 cookie 一并发送。
Lab: SameSite Strict bypass via client-side redirect
This lab’s change email function is vulnerable to CSRF. To solve the lab, perform a CSRF attack that changes the victim’s email address. You should use the provided exploit server to host your attack.
You can log in to your own account using the following credentials:
wiener:peter