前言
CSRF的全名是Cross Site Request Forgery,翻译成中文就是跨站点请求伪造。它是攻击者利用用户的身份操作用户账户的一种攻击方式。之前没有系统性的学习总结过该漏洞,最近看了几篇文章,发现其中的点还是不少的,所以来总结一下
预备知识点
有关cookie
cookie是什么
cookie是由服务器端生成,发送给user-agent,浏览器保存cookie,下次请求同一网站时会自动发送该cookie给服务器。
总的来说cookie就是一个小型文件,用来记录一些信息。服务器可以根据我们的cookie来直接取上一次取过的东西。(比如账户密码之类的)
cookie的分类
浏览器所持有的cookie有两种,一种是“Session Cookie”,又叫”临时Cookie“;另一种是“Third-party Cookie”,也称为“本地Cookie”。
两者的区别在于,Third-party Cookie是服务器在Set-Cookie时指定了Expire时间,只有到了Expire时间后Cookie才会消失,所以这种Cookie会保存在本地;而Session Cookie则没有指定Expire时间,所以浏览器关闭后,Session Cookie就消失了。Session Cookie保存在浏览器进程的内存空间中,而Third-party Cookie则保存在本地。
如果浏览器从一个域的页面中,要加载另一个域的资源,由于安全原因,某些浏览器会阻止Third-party Cookie的发送。
隐患点
如果CSRF攻击的目标需要使用cookie,那么则必须具备这两种cookie,部分浏览器处于安全考虑,默认禁止了浏览器在 <img>、<iframe>、<script>等标签中发送第三方cookie。但是还是有存在一些浏览器默认策略是允许发送第三方cookie的,这就有可能导致CSRF攻击成功。
有关P3P头
什么是P3P头
P3P(The Platform forPrivacy Prefrences Project)是一种被称为个人隐私安全平台项目的标准,能够保护在线隐私权,使Internet冲浪者可以在选择浏览网页时,是否被第三方收集利用自己的个人信息。
隐患点
设置了P3P头之后,对于cookie的影响会扩大到整个域中的所有页面。也就是说如果网站返回给浏览器的HTTP头中包含P3P头,将会允许浏览器发送第三方cookie
P3P头的介入可能会改变网站的隐私策略,使得<iframe>、<script>等标签在ie中不再拦截第三方cookie的发送,造成CSRF漏洞。
漏洞原理
利用目标用户的合法身份(其实就是coookie),以用户的名义执行某些非法操作(向服务器发送伪造请求)。
实现过程
- 用户在浏览器上登录自身信任网站a
- 浏览器获得了服务器传给自己的cookie并保存。
- 用户在网站a保持登录状态的情况下,打开了恶意网站b
- 恶意网站b返回给用户一些攻击性代码,伪造用户向a网站发送请求
- 携带着用户cookie信息的请求由网站b传给网站a,网站a接受到请求后以为是用户发起的请求,于是执行了恶意网站的恶意代码。
漏洞分类
GET型CSRF漏洞
利用超链接
1
<a herf="http://www.smallwolf.top/csrf.php?username=123&password=123">不点不是中国人</a>
利用iframe
1
<iframe src="http://www.smallwolf.top/csrf.php?username=123&password=123" style="display:none"></iframe>
利用img标签
img标签内的内容会随着页面加载而被请求,以此src指向的位置会在页面加载过程中进行请求
1
<img src="http://www.smallwolf.top/csrf.php?username=123&password=123">
POST型CSRF利用
可以在页面构造好一个form表单,然后使用js自动提交这个表单,攻击者甚至可以将这个页面隐藏在一个不可见的iframe窗口中,那么整个自动提交表单的过程对于用户也是不可见的
漏洞关键
该漏洞攻击利用的核心是进行伪造请求,所以关键在于请求的参数和参数值,如果攻击者无法得知url的所有参数和参数值,那么就无谈构造一个伪造的请求。
所以CSRF攻击成功的关键所在就在于重要操作的所有参数都是可以被猜测到的
绕过姿势
绕过CSRF的token保护
利用逻辑错误绕过
应用程序有可能会在token存在或不为空的情况下检测token的有效性,这种情况下我们发送的请求不包含token或token值为空是有可能绕过CSRF的防御的
利用检测不严格绕过
应用程序可能只检测token是否合法却不检测token是否与当前用户匹配,在难以获取受害者token值的情况下可以提交自己产生的token来绕过CSRF防御
利用session固定^1绕过
有时候站点使用一个双提交cookie作为一个CSRF的防御措施。这个表明这个请求需要包含一个cookie,其值为随机token值,且同时在请求参数中也有一个字段值为该随机token值。如果值相同,那么请求是合法的。这种防御形式是非常常见的。
如果一个双提交cookie用在了防御措施中,那么这个应用有可能没有将有效的token保存在服务器端。所以它没有办法指定token是否合法,并且也有可能很少检查cookie中的token值和参数中token值是不是一样的。这代表你可以发送一个假token,然后仍然可以有效实施CSRF攻击。
利用漏洞组合绕过
可以利用xss漏洞获取其cookie,查看存储在其中的token。
绕过CSRF的Referer保护
当Referer为空时
可以简单的移除referer字段,添加如下meta标签
1
<mata name = "referrer" content = "no-referrer">
利用一些伪协议如data:、ftp://等,使用这些伪协议时html页面向任何http站点提交请求的话,这些请求的referer都是空的。
针对白名单的绕过
判断referer是某域的情况下
可以尝试在referer的url中将受害者域名置于二级域名区域或url目录区域
判断referer是否存在某关键词
如果一个站点在referer字段中检测“smallwolf.top”字段,那么可以构造“smallwolf.top.hacker.com”或者“hacker.com/smallwolf.top”来绕过
CSRF的防御
添加验证码
CSRF的攻击过程往往是在用户不知情的情况下进行,如果我们通过在关键步骤上添加验证码检测的过程,就可以较好的遏制csrf攻击,比如在转账时我们通过会被要求输入图片验证码。不过缺点就是过于频繁的要求验证码会引起用户的不适。(12306这种恶心的验证码就更加如此)
检测Referer
CSRF的攻击一部分都是构造恶意网页来向用户访问的网站发送恶意请求,那么通过检测referer头的行为,发现了来自站外的请求就很有可能是CSRF攻击者在作祟。
使用CSRF token
采用token也是当下最主流的针对csrf漏洞的防御手段,新添加一个token参数,其中token的值是随机的,也就是说CSRF攻击者无法猜出来,于是攻击者就无法构造一个完整的url来实施csrf攻击。