Web Security Academy 跨站点伪造请求(CSRF)

笔者Burpsuite Web 安全学院的学习笔记

参考资料&Google翻译

Burpsuite Web 安全学院:Cross-site request forgery (CSRF)

跨站点伪造请求(CSRF)

在本节中,我们将解释什么是跨站点请求伪造,描述一些常见CSRF漏洞的示例,并解释如何防止CSRF攻击。

什么是CSRF?

跨站点请求伪造(也称为CSRF)是一个Web安全漏洞,攻击者可以利用该漏洞诱使用户执行他们不打算执行的操作。它允许攻击者部分规避同一原始策略,该策略旨在防止不同的网站相互干扰。
Web Security Academy 跨站点伪造请求(CSRF)

CSRF攻击有什么影响?

在成功的CSRF攻击中,攻击者会导致受害者用户无意中执行操作。例如,这可能是更改其帐户上的Email地址,更改其密码或进行资金转帐。根据操作的性质,攻击者可能会完全控制用户的帐户。如果受感染的用户在应用程序中具有特权角色,则攻击者可能能够完全控制所有应用程序的数据和功能。

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=wiener@normal-user.com

这符合CSRF所需的条件:

攻击者会对更改用户帐户上的Email地址的操作感兴趣。执行此操作后,攻击者通常将能够触发密码重置并完全控制用户的帐户。
该应用程序使用会话cookie来标识哪个用户发出了请求。没有其他令牌或机制来跟踪用户会话。
攻击者可以轻松确定执行操作所需的请求参数的值。
在满足这些条件的情况下,攻击者可以构建包含以下HTML的网页:

<html>
  <body>

    <form action="https://vulnerable-website.com/email/change" method="POST">
      <input type="hidden" name="email" value="pwned@evil-user.net" />
    </form>
    <script>
      document.forms[0].submit();
    </script>

  </body>
</html>

如果受害用户访问攻击者的网页,则会发生以下情况:

攻击者的页面将触发对目标网站的HTTP请求。
如果用户登录到易受攻击的网站,则其浏览器将自动在请求中包括其会话cookie(假设未使用SameSite cookie)。
目标网站将以正常方式处理请求,将其视为由受害者用户发出,并更改其邮件地址。
注意
尽管通常相对于基于cookie的会话处理来描述CSRF,但它也出现在应用程序自动向请求中添加一些用户凭据的其他情况下,例如HTTP Basic身份验证和基于证书的身份验证。

如何构造CSRF攻击

手动创建CSRF攻击所需的HTML可能很麻烦,特别是在所需的请求包含大量参数或请求中存在其他怪癖的情况下。构造CSRF漏洞最简单的方法是使用Burp Suite Professional内置的CSRF PoC生成器

  • 在Burp Suite Professional中的任意位置选择要测试或利用的请求。
  • 从右键单击上下文菜单中,选择“Engagement tools / Generate CSRF PoC”。
    Burp Suite将生成一些HTML,这些HTML会触发选定的请求(减去cookie,该cookie将由受害者的浏览器自动添加)。
  • 您可以在CSRF PoC生成器中调整各种选项,以微调攻击的各个方面。您可能需要在某些不常见的情况下执行此操作,以处理请求的古怪功能。
  • 将生成的HTML复制到网页中,在登录到易受攻击的网站的浏览器中查看它,并测试是否成功发出了预期的请求以及是否发生了所需的操作。

lab:未作任何防范造成的CSRF

  1. 登录账号carlos/ montoya,提交“change Email”表单,然后在代理历史记录中查找结果请求。

  2. 如果您使用的是Burp Suite Pro,请右键单击请求,然后从context菜单中选择“Engagement tools / Generate CSRF PoC”。启用包含自动提交脚本的选项,然后单击“Regenerate”。
    Web Security Academy 跨站点伪造请求(CSRF)

  3. 如果使用的是Burp Suite社区版,使用以下HTML模板并填写请求的方法,URL和正文参数。您可以通过右键单击并选择“Copy URL”来获取请求URL。

<form method="$method" action="$url">
     <input type="hidden" name="$param1name" value="$param1value">
</form>
<script>
      document.forms[0].submit();
</script>
  1. 转到漏洞利用服务器,将您的exploit HTML粘贴到“body”框中,然后单击“Store”。
  2. 要验证该漏洞利用是否有效,请单击“View exploit”并检查生成的HTTP请求和响应,进行尝试。

如何进行CSRF攻击

跨站点请求伪造攻击的传递机制与反射型XSS的传递机制基本相同。通常,攻击者会将恶意HTML放到他们控制的网站上,然后诱使受害者访问该网站。还可以通过邮件或社交媒体消息向用户提供指向网站的链接来完成。或者,如果将攻击置于流行的网站中(例如,在用户评论中),攻击者可能只需要等待用户访问该网站。

请注意,一些简单的CSRF漏洞利用GET方法,并且可以通过受害的网站上的单个URL完全自包含。在这种情况下,攻击者可能不需要使用外部站点,并且可以在易受攻击的域上直接向受害者提供恶意URL。在前面的示例中,如果可以使用GET方法执行更改Email地址的请求,则自包含式攻击将如下所示:

<img src="https://vulnerable-website.com/email/change?email=pwned@evil-user.net">

拓展阅读

XSS与CSRF

防范CSRF攻击

防范CSRF攻击的最可靠方法是在相关请求中包含CSRF token。token应为:

  • 通常来说,会话 token具有很高的熵,这是不可预测的。
  • 绑定到用户的会话。
  • 在执行相关操作之前,在每种情况下均经过严格验证。

拓展阅读

CSRF tokens

使用Burp Suite的web漏洞扫描器寻址CSRF漏洞

SameSite cookie是 对CSRF局部有效的另一种防御方法,可以与CSRF token结合使用。

常见的CSRF漏洞

最有趣的CSRF漏洞是由CSRF token验证中的错误引起的。

在前面的示例中,假设应用程序现在在更改用户密码的请求中包含CSRF token:

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=wiener@normal-user.com

这应该防止CSRF攻击,因为它违反了CSRF漏洞的必要条件:应用程序不再仅依赖Cookie进行会话处理,并且请求包含一个参数,攻击者无法确定其值。但是,可以通过多种方式来打破防御,这意味着该应用程序仍然容易受到CSRF的攻击。

更换http方法绕过token验证造成CSRF

当请求使用POST方法时,某些应用程序正确地验证了令牌,但是当使用GET方法时,跳过了验证。

在这种情况下,攻击者可以切换到GET方法来绕过验证并发送CSRF攻击:

GET /email/change?email=pwned@evil-user.net HTTP/1.1
Host: vulnerable-website.com
Cookie: session=2yQIDcpia41WrATfjPqvm9tOkDvkMvLm

lab:更换http方法绕过token验证造成CSRF

通过浏览器通过Burp Suite代理访问流量,登录帐户carlos/ montoya,提交“更改邮件”表单,然后在代理历史记录中查找结果请求。

将请求发送到Burp Repeater,观察到如果更改csrf参数的值,则该请求将被拒绝。

使用上下文菜单上的“Change request method”将其转换为GET请求,并注意不再验证CSRF token。

如果您使用的是Burp Suite Pro,请右键单击请求,然后从上下文菜单中选择“ Engagement tools / Generate CSRF PoC”。启用包含自动提交脚本的选项,然后单击“Regenerate”。

如果您使用的是Burp Suite社区版,请使用以下HTML模板并填写请求的方法,URL和正文参数。您可以通过右键单击并选择“Copy URL”来获取请求URL。

<form method="$method" action="$url">
     <input type="hidden" name="$param1name" value="$param1value">
</form>
<script>
      document.forms[0].submit();
</script>

转到漏洞利用服务器,将您的漏洞利用HTML粘贴到“body”框中,然后单击“store”。

要验证该漏洞利用是否有效,请单击“查看漏洞利用”并检查生成的HTTP请求和响应,进行尝试。

无token则不验证token造成CSRF

如果token存在,某些应用程序会正确验证token,但是如果省略token,则跳过验证。

在这种情况下,攻击者可以删除包含token的整个参数(而不仅仅是令牌的值),以绕过验证并进行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=pwned@evil-user.net

lab:无token则不验证token造成CSRF

完全删除csrf参数即可(&也要删掉),同上

CSRF token未绑定到用户会话

某些应用程序无法验证令牌与发出请求的用户属于同一会话。而是,应用程序维护已发出的全局令牌池,并接受该池中显示的所有令牌。

在这种情况下,攻击者可以使用自己的帐户登录应用程序,获取有效令牌,然后在其CSRF攻击中将该令牌提供给受害者用户。

lab:token未绑定到用户会话造成的CSRF

使用浏览器通过Burp Suite代理流量时,登录到您的帐户wiener/peter,提交“change Email”表格,并拦截结果请求。

记下CSRF token的值,然后删除请求

打开一个隐身浏览器窗口,登录到您的其他帐户carlos/ montoya,然后将更改邮件请求发送到Burp Repeater。

请注意,如果将CSRF令牌与另一个帐户中的交换,则该请求将被接受。然后再退出账号,像上一个lab生成poc,粘贴到exploit服务器,存储利用即可

注意
cookie设置行为甚至不必与CSRF漏洞存在于同一Web应用程序中。如果所控制的Cookie具有适当的范围,则可以利用同一总体DNS域中的任何其他应用程序在目标应用程序中设置Cookie。例如,staging.demo.normal-website.com可以利用Cookie设置功能来放置提交到的Cookie secure.normal-website.com.

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=wiener@normal-user.com

这种情况很难利用,但仍然很脆弱。如果该网站包含允许攻击者在受害者的浏览器中设置cookie的任何行为,则可能构成攻击。攻击者可以使用自己的帐户登录到应用程序,获取有效的令牌和关联的cookie,利用cookie的设置行为将其cookie置于受害者的浏览器中,并在CSRF攻击中将其令牌提供给受害者。

lab:token与非会话Cookie绑定造成的CSRF

将请求发送到Repeater,观察到更改cookie将使现在的session注销,但是更改csrf Keycookie只会导致CSRF令牌被拒绝。这表明csrfKey cookie可能并不严格地与session绑定。

点击search,将结果请求发送到Repeater,然后观察到搜索词在响应数据的Set-Cookie header中。由于搜索功能没有CSRF保护,因此您可以使用此功能将Cookie注入受害者用户的浏览器中。
Web Security Academy 跨站点伪造请求(CSRF)

cookie-injection-url:https://...../?search=test%0d%0aSet-Cookie:%20csrfKey=your-key
your-key就是修改邮箱的原始请求里的csrfKey
这里没必要把change email请求 drop
Generate CSRF POC,然后删除POC 中生成的script块 document.forms[0].submit();要完整删掉,包括<script>

加入以下代码以注入cookie(需要添加的cookie已高亮):

<img src="$cookie-injection-url" one rror="document.forms[0].submit()">

Web Security Academy 跨站点伪造请求(CSRF)
然后到exploit服务器存储html即可

Token在Cookie中被简单复制造成的CSRF

在上述漏洞的另一种变体中,某些应用程序不维护任何已发布token的服务器端记录,而是复制cookie和request参数中的每个token。当后续请求得到验证时,应用程序仅验证请求参数中提交的token是否与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攻击。在这里,攻击者无需获取自己的有效token。他们只是编造了一个token(如果被检测,则可能采用所需的格式),利用cookie设置行为将其cookie放置到受害者的浏览器中,并在CSRF攻击中将token提供给受害者。

lab:Token在Cookie中被简单复制造成的CSRF

描述

lab的更改Email功能容易受到CSRF的攻击。它尝试使用不安全的“双重提交” CSRF防御技术。

要解决此问题,请使用exploit 服务器托管HTML页面,页面使用CSRF攻击来修改查看者的Email地址。

帮助设计攻击的帐号凭据为:carlos/ montoya

Solution

登录帐号,提交“更改Email”表单,然后在HTTP history中查找请求结果。

将请求发送到Repeater,观察到csrfbody参数的值只是通过将其与csrfcookie进行比较而得到了验证。

搜索,把结果请求发送到Repeater,然后观察到搜索词已反映在Set-Cookie header中。由于搜索功能没有CSRF保护,因此您可以使用此功能将Cookie注入受害者用户的浏览器中。

创建一个利用漏洞的URL将伪造的csrfcookie注入受害者的浏览器中:

$cookie-injection-url 就是https://.....//?search=test%0d%0aSet-Cookie:%20csrf=fake

伪造一个CSRFtoken。从更改Email的请求中Generate CSRF POC。

删除<script>块,然后添加以下代码以注入cookie:

<img src="$cookie-injection-url" one rror="document.forms[0].submit();"/>

基于Referer防范造成CSRF

除了采用CSRF token的防御措施外,某些应用程序还使用HTTP Referer标头尝试防御CSRF攻击,通常是通过验证请求是否来自应用程序自己的域来进行。这种方法通常效果较差,并且经常会绕过。

Referer header

HTTP Referer header(在HTTP规范中无意中拼写错误)是一个可选的请求header,其中包含链接到所请求资源的网页的URL。通常,当用户触发HTTP请求时,浏览器会自动添加它,包括单击链接或提交表单。存在各种方法,允许链接页面保留或修改Referer header的值。这样做通常出于隐私原因。

header不存在则无Rerferer验证造成CSRF

某些应用程序会在请求中包含Referer header时对其进行验证,但是如果省略header,则跳过验证。

在这种情况下,攻击者可以以某种方式设计其CSRF攻击,使受害者用户的浏览器在结果请求中删除Referer标头。有多种方法可以实现此目的,但最简单的方法是在承载CSRF攻击的HTML页面中使用META标签:

<meta name="referrer" content="never">

lab:header不存在则无Rerferer验证造成CSRF

登录帐户,提交“change email”表单,然后在HTTP history中查找请求结果。

将请求发送到Burp Repeater,观察到如果更改了Referer HTTP header中的域,则请求将被拒绝。

完全删除Referer header,然后观察到请求已被接受。

在Generate CSRF POC生成的HTML加入以下的内容禁止Referer header:

<meta name="referrer" content="no-referrer">

Referer验证可绕过

某些应用程序以单纯可绕过的方式验证Referer header。例如,如果应用程序简单地验证Referer包含其自己的域名,则攻击者可以将所需的值放在URL中的其他位置:
http://attacker-website.com/csrf-attack?vulnerable-website.com

如果应用程序验证了Referer中的域以期望值开头,则攻击者可以将此域放置为自己域的子域:
http://vulnerable-website.com.attacker-website.com/csrf-attack

lab:CSRF的Referer验证无效

登录帐户,提交“change email”表单,然后在HTTP history中查找请求结果。

将请求发送到Burp Repeater,观察到如果更改了Referer HTTP header中的域,则请求将被拒绝。

将原始域复制到Referer的查询字符串中,然后观察到请求已被接受。

在Generate CSRF POC生成的HTML中的script块中加入以下JavaScript以更改URL和Referer:

history.pushState("", "", "/?$original-domain")

上一篇:UIViewController的生命周期及iOS程序执行顺序


下一篇:python Djanjo csrf说明与配置