CSRF漏洞原理:
CSRF是跨站请求伪造,不攻击网站服务器,而是冒充用户在站内的正常操作。通常由于服务端没有对请求头做严格过滤引起的。CSRF会造成密码重置,用户伪造等问题,可能引发严重后果。
我们知道,绝大多数网站是通过cookie等方式辨识用户身份,再予以授权的。所以要伪造用户的正常操作,最好的方法是通过XSS或链接欺骗等途径,让用户在本机(即拥有身份cookie的浏览器端)发起用户所不知道的请求。CSRF攻击会令用户在不知情的情况下攻击自己已经登录的系统。
CSRF攻击的目的是滥用基本的Web功能。如果该网站可以使服务器上的状态变化,如改变受害者的电子邮件地址或密码,或购买的东西,强迫受害人检索数据等等。CSRF攻击会修改目标状态。在这一过程中,受害者会代替攻击者执行这些攻击,攻击者中不会收到响应,受害者会代替攻击者执行这些攻击。
在跨站点请求伪造(CSRF)攻击中,攻击者经由用户的浏览器注入网络请求来破坏用户与网站的会话的完整性。浏览器的安全策略允许网站将HTTP请求发送到任何网络地址。此策略允许控制浏览器呈现的内容的攻击者使用此用户控制下的其他资源。
需要对页面参数做修改时,可以使用burpsuite生成的csrf poc,从而进行poc测试,测试完成之后一定要验证,浏览器执行了我们生成的poc测试,令数据产生变化。
csrf可以和XSS联系在一起,XSS获取cookie,CSRF伪造跨站请求完成指令。
漏洞利用重点:
1、CSRF的攻击建立在浏览器与web服务器的会话中
2、欺骗用户访问URL
攻击场景:
CSRF攻击(GET):
这种类型的CSRF一般由于程序员的安全意识不强造成的。GET类型的CSRF利用非常简单,只需要一个HTTP请求,所以,一般会这样利用:<img src=http://test.com/csrf?xx=11 />
在访问含有这个img的页面后,成功向http://test.com/csrf?xx=11 发出了一次HTTP请求。
假如微博存在CSRF漏洞,有一个GET请求让别人点击后关注我,这时可以做一些诱惑性的博客。
假如想让每个用户都帮助自己转发微博,制造一次蠕虫攻击,找到转播文章的页面与关注我的页面,写一个POC,用<iframe>标签来加载URL,加载两条URL,这时当用户点击会关注并且自动转发。
CSRF攻击(POST):构造form表单,利用javascript提交。
读取型CSRF:
什么是读取型CSRF,如下的漏洞可以归纳进读取型CSRF,因为这些漏洞的利用手法都跟CSRF是一样的:
- JSONP劫持
- Flash跨域劫持
- CORS跨域资源读取
...等等,还有一些Sliverlight跨域这些。
浏览器Cookie机制:
cookie的两种表现形式:一种是本地Cookie,又称持久性Cookie;
一种是临时Cookie,又称Session Cookie;
检测CSRF漏洞:
1、手工检测如:http://www.test.com/test?id=1 通过此id可以删除指定的用户。可以编写一个POC get方式。
2、半自动检测:工具CSRFTester,另外burpsuite scanner模块也支持检测CSRF漏洞。
3、全自动检测:主要是插件。
预防跨站请求伪造:
其实现在有关CSRF漏洞防护已经是比较成熟了,其主要防护的思路就是需要在进行后台数据修改操作的过程中,添加对当前用户身份的有效验证措施,而不能仅限于cookie的识别。
(1)来源校验
使用http请求头中的referer来源,对客户端源身份校验,此方法早期使用较多,但是仍然容易被绕过,所以这里并不建议使用。
(2)用户token校验
添加基于当前用户身份的有效tokens随机验证机制,即在向后端提交数据操作请求时,添加基于当前用户的随机token校验值,此种校验方法当前使用比较多;(xss和csrf漏洞同时存在时token校验生效)
(3)当前用户密码验证
在修改关键信息时,要当前用户输入其自身的密码,以验证当前用户身份的真伪,防止未授权的恶意操作;
(4)添加验证机制
在请求数据提交前,需填写验证码信息提交,以增加对用户来源的有效验证,防止恶意未授权的操作产生。
绕过防御的经验:
相信大家在很多时候抓包一看有token或者删除referer重新发包报错了就会觉得这里不会有csrf漏洞了,可实际情况可不一定。还有一种常见情况就是使用验证码,目前识别验证码的方法都无法直接利用到绕过CSRF防御上来,所以不考虑用户体验的话,验证码是防御CSRF攻击最有效的方法。
情况A:
无token无referer验证这种情况现在比较少了,一般出现在一些新上线的业务。一般测试时都是用firefox的live Http Headers插件先抓取一个正常请求的数据包,如果没token的话,先去掉referer字段再重新提交看返回值。如果没报错的话,那就可以直接写一个表单(POST型)或者构造个链接(GET型)重新测试了,一般都会成功;但有些通过ajax提交的是行不通的,因为ajax无法跨域。
情况B:
无token有referer验证这种情况比较常见,也许我们抓包发现无token正庆幸时,删除referer重新提交一看发现报错了,难道就这样放弃了吗?
(1)可以试试空的referer:即删除header中的referer的值,如果服务器只是验证了是否存在referer没验证referer值的话,重新提交会发现一个CSRF漏洞又被发现了,因为所有跨域协议传递的请求都不会送referer的
(2)可以试试修改referer的值:如果原referer值为Referer:t.qq.com/xxxx话,我们可以试试修改为Referer:t.qq.com.baidu.com/xxx。如果服务器只是验证了referer是否存在qq.com或者t.qq.com等关键词的话,针对前一种情况,我们可以再腾讯某子站点(http://xx.qq.com)发个帖子将图片地址修改为我们构造的csrf链接或者写好CSRF表单后将地址发布在微博上等待其它用户点击,针对后一种情况我们可以建立个t.qq.com.yourdomain.com的域名存放CSRF表单来绕过REFERER检测。