Burp Web Academy CSRF 跨站请求伪造
0x01. PortSwigger Web Security Academy
PortSwigger Web Security Academy 是 Burp Suite 官方推出的免费 Web 安全学习靶场,在学习 Web 安全知识的同时,还可以练习 Burp Suite 的实战技能。
本篇文章讲解 Web Security Academy 之中的跨站请求伪造(CSRF,Cross-site request forgery)章节。
0x02. CSRF
2.1 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
使用测试账号登录,尝试修改 E-mail,发现只是简单发了一个 POST 请求,没有类似 CSRF Token 之类的保护机制。
1 | POST /my-account/change-email |
尝试在 Exploit Server 构造如下页面发送 POST 请求:
1 | <form action=https://0a120044041b586fb06d46f6004400bb.web-security-academy.net/my-account/change-email method=POST> |
注意,Hint 提示一个 E-mail 只能绑定给一个用户,而且测试的域名用来做邮箱好像不行。
2.2 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:
1 | <form class="login-form" name="change-email-form" action="/my-account/change-email" method="POST"> |
根据提示,可能支持 GET 请求更新 E-mail 并且没有保护机制,测试确认确实如此。
1 | GET /my-account/change-email?email=hello@test.com |
直接在 Exploit Server 构造如下 HTML 代码:
1 | <img src="https://0a35009e036a3fe281eadaf6000a00a1.web-security-academy.net/my-account/change-email?email=test@gmail.com"> |
2.3 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
POST 表单存在隐藏的 CSRF Token,但如果提交时没有 csrf
字段也能成功,利用方式和第一个相同。
1 | <form action=https://0a0d00a903fab13f80b2588700fd00ba.web-security-academy.net/my-account/change-email method=POST> |
2.4 Lab: CSRF where token is not tied to user session
This lab’s email change functionality is vulnerable to CSRF. It uses tokens to try to prevent CSRF attacks, but they aren’t 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:peter
carlos:montoya
测试发现,CSRF Token 和用户 Session 并没有绑定关系,也就是说,可以使用其他用户的合法 Token 来发起 CSRF 攻击。
1 | <form action=https://0ac300cd04435066804aadda0071004a.web-security-academy.net/my-account/change-email method=POST> |
2.5 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:peter
carlos:montoya
测试发现,CSRF Token 是和 Cookie 里面的 csrfKey
绑定的,即 csrfKey
决定了 CSRF Token 是什么。
1 | Cookie: csrfKey=rlG9KHbQT5wln8M4Nuz1ZhOQFxDLjfnr; session=8RCz89erDttASpS8kWYHw5zuEkGHie37 |
但这里涉及到一个问题:如何设置受害者的 Cookie?使用搜索功能,发现关键字出现在了 Set-Cookie
中:
1 | GET /?search=test |
1 | 200 OK |
因此,可以尝试 Cookie 注入,尝试搜索 test; csrfKey=rlG9KHbQT5wln8M4Nuz1ZhOQFxDLjfnr
,发现如下代码并不能修改 Cookie:
1 | 200 OK |
查看关于 Set-Cookie
的说明,发现每次只能设置一个 Cookie 字段,如果要设置多个字段,需要多次调用才行:
The HTTP
Set-Cookie
response header is used to send a cookie from the server to the user agent, so that the user agent can send it back to the server later. To send multiple cookies, multipleSet-Cookie
headers should be sent in the same response.
尝试新的注入 Payload(基于回车换行实现):可以成功修改 Cookie
1 | GET /?search=test%0d%0aSet-Cookie%3A%20csrfKey%3DrlG9KHbQT5wln8M4Nuz1ZhOQFxDLjfnr%3B |
利用代码:
1 | <form action=https://0a2900e304c8544380424e1d00750061.web-security-academy.net/my-account/change-email method=POST> |
利用 <img>
实现触发 GET 请求,同时利用 onerror
回调实现触发 POST 请求。
2.6 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
CSRF Token 在 Cookie 中保存了一份副本:
1 | Cookie: csrf=rebnlY1JEQ1tZjuGmqdWMW8C8TRKDNuP; session=jDe5boZyJSRIYjJad0mwTgfe2yqAmZkF |
前面搜索接口改写 Cookie 的漏洞还在:
1 | 200 OK |
因此,可以将特定的 CSRF Token 写入 Cookie,然后提交 POST 表单来修改 E-mail 地址。
利用代码:
1 | <form action=https://0a6c006003b0d45381bdd0400091006a.web-security-academy.net/my-account/change-email method=POST> |
如果不加 SameSite=None
,则很难利用漏洞,具体后面解释。
0x03. Cookie 属性
Set-Cookie
语法如下:
1 | Set-Cookie: <cookie-name>=<cookie-value> |
相关解释:
- HttpOnly
- 阻止 JavaScript 通过
document.cookie
属性访问 Cookie。注意,设置了HttpOnly
的 Cookie 仍然会通过 JavaScript 发起的请求发送。 - 用于抵抗 XSS 攻击。
- 阻止 JavaScript 通过
- Secure
- 表示仅当请求通过
https
协议(localhost 不受此限制)发送时才会将该 Cookie 发送到服务器,因此其更能够抵抗中间人攻击。
- 表示仅当请求通过
- SameSite
- 控制 Cookie 是否随跨站请求一起发送,这样可以在一定程度上防范跨站请求伪造攻击(CSRF)
Strict
- 这意味浏览器仅对同一站点的请求发送 Cookie,即请求来自设置 Cookie 的站点。如果请求来自不同的域名或协议(即使是相同域名),则携带有
SameSite=Strict
属性的 Cookie 不会被发送。
- 这意味浏览器仅对同一站点的请求发送 Cookie,即请求来自设置 Cookie 的站点。如果请求来自不同的域名或协议(即使是相同域名),则携带有
Lax
- 这意味着 Cookie 不会在跨站请求中被发送,如:加载图像或框架(frame)的请求。但 Cookie 在用户从外部站点导航到源站时,Cookie 也会被发送(例如,访问一个链接)。这是
SameSite
属性未被设置时的默认行为。
- 这意味着 Cookie 不会在跨站请求中被发送,如:加载图像或框架(frame)的请求。但 Cookie 在用户从外部站点导航到源站时,Cookie 也会被发送(例如,访问一个链接)。这是
None
- 这意味着浏览器在跨站和同站请求中均会发送 Cookie。在设置这一属性值时,必须同时设置
Secure
属性,就像这样:SameSite=None; Secure
。
- 这意味着浏览器在跨站和同站请求中均会发送 Cookie。在设置这一属性值时,必须同时设置
可以看出,未显示设置 SameSite=None
时,SameSite
属性默认为 Lax
,导致跨站发送请求时 Cookie 不能正常发送。
0x04. 小结
- 不同类型的 CSRF 触发方法,GET 简单,POST 要提交表单稍微复杂点
- GET 可以使用
<img>
或者<iframe>
之类的 - 组合漏洞利用场景下,利用
<img src
触发 GET 请求,利用<img onerror
触发 POST 请求
- GET 可以使用
- 对于同样的功能,可以尝试测试不同的 HTTP 请求方法
- 校验不严格场景
- 仅 CSRF Token 存在时才能起到防御效果
- CSRF Token 未与用户 Session 绑定
- CSRF Token 绑定的是非 Session Cookie
- 了解 Cookie 的属性