首页 > 其他分享 >一文深入了解CSRF漏洞

一文深入了解CSRF漏洞

时间:2023-05-08 11:36:36浏览次数:58  
标签:令牌 浏览器 一文 用户 漏洞 CSRF 攻击者 请求

1.1. 定义

跨站请求伪造(英语:Cross-site request forgery),也被称为 one-click attack 或者 session riding,通常缩写为 CSRF 或者 XSRF, 是一种挟制用户在当前已登录的Web应用程序上执行非本意的操作的攻击方法。跟跨站脚本(XSS)相比,XSS 利用的是用户对指定网站的信任,CSRF 利用的是网站对用户网页浏览器的信任。

跨站请求伪造攻击,是攻击者通过一些技术手段欺骗用户的浏览器去访问一个用户自己曾经认证过的网站并执行一些操作(如发邮件,发消息,甚至财产操作如转账和购买商品)。由于浏览器曾经认证过,所以被访问的网站会认为是真正的用户操作而去执行。这利用了web中用户身份验证的一个漏洞:简单的身份验证只能保证请求是发自某个用户的浏览器,却不能保证请求本身是用户自愿发出的

Note

简单来说就是你点击我构造的恶意链接,我就可以以你的名义去发起一个http请求

1.2. 举例

  1. 假如X银行用以执行转账操作的URL地址如下

     https://bank.example.com/withdraw?amount=1000&to=PayeeName
    
  2. 一个恶意攻击者在另一个网站中https://evil.com/中放置如下代码

     <img src="https://bank.example.com/withdraw?amount=1000&to=Bob" />
    
  3. 如果有登陆了X银行的用户访问恶意站点https://evil.com/,那么就会携带cookie去请求对应的转账URL,向Bob转账1000元

Note

这种恶意的网址可以有很多种形式,藏身于网页中的许多地方,只要能让受害者发起对应的请求即可,如上述中的转账请求。

攻击者也不需要控制放置恶意代码的网站,例如他可以将这种地址藏在各大论坛,博客等任何用户生成内容的网站中,这意味着如果服务端没有合适的防御措施的话,用户即使访问熟悉的可信网站也有受攻击的危险

通过例子也能够看出,攻击者并不能通过CSRF攻击来直接获取用户的账户控制权,也不能直接窃取用户的任何信息。他们能做到的,是欺骗用户的浏览器,让其以用户的名义执行操作

1.3. 攻击流程

image.png

具体的攻击流程如下:

  1. 用户正常登录web服务,并一直保持在线
  2. 服务器返回用户凭证Session ,并将其保存在Cookie中
  3. 攻击者生成payload,并放置在用户可访问的地方
  4. 攻击者诱导用户点击在第3步放置的链接,此时用户一直在线,且是用同一浏览器打开(保证Cookie未失效)
  5. 用户点击恶意链接
  6. 恶意链接向服务器请求,由于用户Cookie未失效,就携带用户Cookie访问服务器
  7. 服务器收到请求,此时用户Cookie 未失效,并判定为“用户”发起的正常请求,并做出响应

1.4. 分类

1.4.1. GET型

这种是最容易利用的,相比于POST型来说,攻击面也大很多,比如上述CSRF转账例子中就是GET型的

在web应用中,很多接口通过GET进行数据的请求和存储,如果未对来源进行校验,并且没有token保护,攻击者可以直接通过发送含有payload的链接进行诱导点击;亦可以通过评论区或类似功能处发布图片,通过修改img地址的方式保存至页面,用户访问便会进行自动加载造成攻击

<!-- 不论什么手段,只要能让受害者访问一个链接即可 -->
<img src="https://bank.example.com/withdraw?amount=1000&to=Bob" />

1.4.2. POST-表单型

相比于GET型,这种就要多很多,因为很多开发在提交数据的功能点时都会采用POST,如创建用户、创建文章、发消息等,利用起来也相对麻烦点

Note

测试时,为了扩大危害,可以尝试将POST数据包转换成GET数据包,后端采用如@RequestMaping("/")这种同时接受POST和GET请求的话,就可以成功

利用起来无非也是构造一个自动提交的表单,然后嵌入到页面中,诱导受害者访问,受害者访问后会自动提交表单发起请求

<form action=http://bank.example.com/csrf method=POST>
<input type="text" name="amount" value="1000" />
</form>
<script> document.forms[0].submit(); </script>

1.4.3. POST-JSON型

现在越来越多的系统都采用RESTful风格开发,前后端分离,ajax请求后端获取数据再到前端渲染,所以上述表单型也越来越少了

如果我们发现请求头中的Content-Type值是application/json,基本上就可以确定采用了前后端分离了

image-20220107104042244

这种一般有4⃣️种利用手法:

  1. json转param
  2. 闭合JSON
  3. ajax发起请求
  4. flash+307跳转

json转param

部分网站可能同时支持json和表单格式,所以我们可以尝试进行转换,也算是一个小tips吧

如把 {"a":"b"} 转换为 a=b,服务端可能也会解析


闭合JSON

这种要求对Content-Type没有限制,比如传输的数据为 {"a":"b"},那么我们就可以构造一个表单

<form action=http://test.example.com/csrf method=POST>
    <!-- 重点是下面这一行 -->
    <input type="hidden" name='{"a":"' value='b"}' />
</form>
<script> document.forms[0].submit(); </script>

这样自动提交表单的时候,提交的data就是 {"a":"=b"},闭合成了json

Note

实际环境中本人没遇到过,基本上遇到的都是强制要求Content-Type为json


ajax发起请求

当跨域影响用户数据HTTP请求(如用XMLHttpRequest发送get/post)时,浏览器会发送预检请求(OPTIONS请求)给服务端征求支持的请求方法,然后根据服务端响应允许才发送真正的请求。

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Access-Control-Allow-Origin: http://localhost:63342
Access-Control-Allow-Credentials: true
Access-Control-Max-Age: 1800
Access-Control-Allow-Methods: POST
Access-Control-Allow-Headers: content-type,access-control-request-headers,access-control-request-method,accept,origin,x-requested-with
Content-Length: 0
Date: Wed, 11 Mar 2015 05:16:31 GMT

然而如果服务端对Content-Type进行校验,则不会响应这个OPTIONS请求,从而利用失败。但是更多的情况下服务端可能不会校验Content-Type,或者不会严格校验Content-Type是否为application/json,所以很多情况下这是可用的

<script>
  windows.onload = () => {
    var xhr = new XMLHttpRequest()
    xhr.open("POST", "http://test.example.com/csrf")
    xhr.setRequestHeader("Accept", "*/*")
    xhr.setRequestHeader("Accept-Language", "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3")
    xhr.setRequestHeader("Content-Type", "application/json; charset=utf-8")
    xhr.withCredentials = true // 携带cookie
    xhr.send(JSON.stringify({"a":"b"})
  }
</script>

flash+307跳转

利用Flash的跨域与307跳转来绕过http自定义头限制,307跟其他3XX HTTP状态码之间的区别就在于,HTTP 307可以确保重定向请求发送之后,请求方法和请求主体不会发生任何改变。HTTP 307会将POST body和HTTP头重定向到我们所指定的最终URL,并完成攻击

详情参考该系列我的另一片文章:一次XSS和CSRF的组合拳进攻(CSRF+JSON)

1.5. 挖掘

算是一些挖掘经验吧,很多小伙伴都知道这个漏洞,但是不知道如何挖掘。

1.5.1. 应用场景

其实所有需要登陆认证且存在操作的地方,都可能存在CSRF;比如修改个人信息、发送邮件、创建管理员用户等等,只能查看的功能不考虑,因为不能算真正利用

1.5.2. 如何快速验证

Tip

观察数据包,如果header头和data中都没有token,然后尝试删除referer,还是能成功发送请求的话,就可以确定存在CSRF漏洞了

为了保险起见,在时间充足的情况下,还是需要尽量通过POC验证下,一般不需要2个账号进行验证,一个账号即可(2个只能说更保险)

非json的情况下,使用burp可以快速生成POC,也可以自己写,反正原理都是发起请求即可

登陆账号的情况下去访问这个poc,如果能成功得到自己的结果,就是OK的。

image-20220107112455842

1.6. 防御

WEB的身份验证机制可以保证一个请求是来自于哪个用户的浏览器,但是却不能保证请求是否由本人发起的,所以修复和防御也是保证请求由用户本人发起即可。

Tip

简单来说,或者和客户沟通的情况下,直接说修复方法就是防止请求重放,他们开发也差不多都知道怎么修了

1.6.1. 令牌同步模式

令牌同步模式(英语:Synchronizer token pattern,简称STP)。

原理是:当用户发送请求时,服务器端应用将令牌(token:一个保密且唯一的值)嵌入HTML表格,并发送给客户端。客户端提交HTML表格时候,会将令牌发送到服务端,再由服务端对令牌进行验证。令牌可以通过任何方式生成,只要确保随机性和唯一性。这样确保攻击者发送请求时候,由于没有该令牌而无法通过验证。(没有token不能重放数据包)

<input type="hidden" name="_csrf_token" value="YidlXHhlMVx4YmJceDkxQFx4OTdceDg5a1x4OTJcbic=">

Note

STP能在HTML下运作顺利,但会导致服务端的复杂度升高,复杂度源于令牌的生成和验证。因为令牌是唯一且随机,如果每个表格都使用一个唯一的令牌,那么当页面过多时,服务器由于生产令牌而导致的负担也会增加。而使用会话(session)等级的令牌代替的话,服务器的负担将没有那么重。

1.6.2. 检查Referer字段

HTTP头中有一个Referer字段,这个字段用以标明请求来源于哪个地址。在处理敏感数据请求时,通常来说,Referer字段应和请求的地址位于同一域名下

以上文银行操作为例,Referer字段地址通常应该是转账按钮所在的网页地址,应该也位于bank.example.com之下。而如果是CSRF攻击传来的请求,Referer字段会是包含恶意网址的地址,不会位于bank.example.com之下,这时候服务器就能识别出恶意的访问。

image-20220107100706077

Warning

这种办法简单易行,工作量低,仅需要在关键访问处增加一步校验。

但这种办法也有其局限性,因其完全依赖浏览器发送正确的Referer字段;虽然http协议对此字段的内容有明确的规定,但并无法保证来访的浏览器的具体实现,亦无法保证浏览器没有安全漏洞影响到此字段,并且也存在攻击者攻击某些浏览器,篡改其Referer字段的可能。

1.6.3. 添加校验token

Note

提交不一定是在data里面提交,也可以在header里面

由于CSRF的本质在于攻击者欺骗用户去访问自己设置的地址,所以如果要求在访问敏感数据请求时,要求用户浏览器提供不保存在cookie中,并且攻击者无法伪造的数据作为校验,那么攻击者就无法再执行CSRF攻击。

这种数据通常是窗体中的一个数据项。服务器将其生成并附加在窗体中,其内容是一个伪随机数。当客户端通过窗体提交请求时,这个伪随机数也一并提交上去以供校验。正常的访问时,客户端浏览器能够正确得到并传回这个伪随机数,而通过CSRF传来的欺骗性攻击中,攻击者无从事先得知这个伪随机数的值,服务端就会因为校验token的值为空或者错误,拒绝这个可疑请求。

1.6.4. 一次一用验证码

在关键操作处添加一次一用的验证码,攻击者无法事先知道验证码的值,也就无法成功构造发起请求的数据包。

Attention

需要用户交互,如果很多地方都加上,用户体验极差,所以一般不建议这个

设置SameSite属性,需要根据需要设置

  1. 如果Samesite Cookie被设置为Strict,浏览器在任何跨域请求中都不会携带Cookie,新标签重新打开也不携带,所以说CSRF攻击基本没有机会;但是跳转子域名或者是新标签重新打开刚登陆的网站,之前的Cookie都不会存在。尤其是有登录的网站,那么我们新打开一个标签进入,或者跳转到子域名的网站,都需要重新登录。对于用户来讲,可能体验不会很好。
  2. 如果Samesite Cookie被设置为Lax,那么其他网站通过页面跳转过来的时候可以使用Cookie,可以保障外域连接打开页面时用户的登录状态。但相应的,其安全性也比较低。

图片

1.7. 个人预防

网站如果存在CSRF漏洞,个人一般要如何操作才能防止攻击到自己呢?

  1. 尽量每次使用隐私浏览器,因为其关闭后会清空所有的cookie
  2. 不要随便打开链接,一定要打开的情况下,可以使用隐私浏览器

标签:令牌,浏览器,一文,用户,漏洞,CSRF,攻击者,请求
From: https://www.cnblogs.com/initsec/p/17381133.html

相关文章

  • 一文梳理z-index和层叠上下文
    前言最近参与某前端项目架构改造,发现项目中滥用z-index,设置的值有几十种并且不统一。在对项目的z-index进行梳理和统一过程中也深入学习了一下z-index,并撰写成文,希望也能帮助到陌生的你。1、z-indexz-index属性是什么?这里可参考MDN:z-index属性设定了一个定位元素及其后代元......
  • Django操作session和中间件以及csrf跨站服务
    Django操作session#cookie保存在浏览器,数据不安全session可以将用户信息保存在服务端,基于cookie工作的1.用户信息认证2.生成随机字符串3.随机字符串和用户信息绑定一起,保存,默认在mysql4.把随机字符串返回到浏览器,将其保存,再次访问直接带其一起传输至服务端,服务端用其进......
  • csrf跨站请求伪造,相关校验,装饰器
    csrf跨站请求伪造钓鱼网站:模仿一个正规的网站让用户在该网站上做操作但是操作的结果会影响到用户正常的网站账户但是其中有一些猫腻 eg:英语四六级考试需要网上先缴费但是你会发现卡里的钱扣了但是却交到了一个莫名其妙的账户并不是真正的四六级官方账户模拟钓......
  • 软件测试|一文告诉你SQL到底是什么
    前言我们在学习数据库时,第一个要弄明白的东西就是,SQL是什么,SQL是StructuredQueryLanguage的缩写,字面意思为“结构化查询语言”,它可以用来进行数据的查询、插入、更新、删除等操作,也可以用于创建和管理数据库对象,如表、视图、存储过程、函数等。本篇文章我们就将对SQL进行系统......
  • 漏洞扫描工具学习
    1、Nessus漏洞扫描Nessus简介:Nessus号称是世界上最流行的漏洞扫描程序,全世界有超过75000个组织在使用它。该工具提供完整的电脑漏洞扫描服务,并随时更新其漏洞数据库。Nessus不同于传统的漏洞扫描软件,Nessus可同时在本机或远端上遥控,进行系统的漏洞分析扫描。对于渗透测试人员......
  • 浅谈联网汽车安全漏洞
    ​“智能网联汽车存在内生共性问题,即软硬件的漏洞后门,基于此进行的网络攻击可以直接带来勒索、盗窃、大规模车辆恶意操控风险,还有数据泄露等网络安全事件。如果内生的漏洞后门问题不解决,系统自身难保,很难谈系统安全之上的数据安全、应用安全。”——中国工程院院士邬江兴随着汽......
  • csrf跨站请求伪造与校验策略
    目录一、csrf跨站请求伪造概念引入概念讲解二、csrf校验策略概念讲解form表单操作csrf策略ajax请求csrf策略三、csrf相关装饰器一、csrf跨站请求伪造概念引入简介我们通过模仿一个钓鱼网站来提现csrf跨站请求伪造。钓鱼网站:模仿一个正规的网站让用户在该网站上做操作......
  • IM开发者的零基础通信技术入门(十二):上网卡顿?网络掉线?一文即懂!
    【来源申明】本文引用了微信公众号“鲜枣课堂”的《上网慢?经常掉线?这篇文章告诉你该怎么办!》文章内容。为了更好的内容呈现,即时通讯网在引用和收录时内容有改动,转载时请注明原文来源信息,尊重原作者的劳动。1、本文内容概述对于不太了解网络通信的人来说(包括开发者),可能会经常碰......
  • 一文讲明TCP网络编程、Socket套接字的讲解使用、网络编程案例
    文章目录1Socket讲解2基于Socket的TCP编程3客户端Socket的工作过程包含以下四个基本的步骤3.1客户端创建Socket对象4服务器程序的工作过程包含以下四个基本的步骤:4.1服务器建立`ServerSocket`对象5案例实现客户端和服务端通信5.1代码实现5.2实现结果6更多案例分析6.1客......
  • Vulhub 漏洞学习之:Gitlab
    Vulhub漏洞学习之:Gitlab目录Vulhub漏洞学习之:Gitlab1GitLab任意文件读取漏洞(CVE-2016-9086)1.1环境安装1.2漏洞利用过程2GitLab远程命令执行漏洞(CVE-2021-22205)2.1环境安装2.2漏洞利用过程2.2.1脚本复现2.2.2手动复现1GitLab任意文件读取漏洞(CVE-2016-9086)GitLab......