原理
从上图可以看出,要完成一次CSRF攻击,受害者必须依次完成两个步骤:
1.登录受信任网站A,并在本地生成Cookie。
2.在不登出A的情况下,访问危险网站B。
看到这里,也许会说:“如果我不满足以上两个条件中的一个,我就不会受到CSRF的攻击”。是的,确实如此,但不能保证以下情况不会发生:
1.不能保证登录了一个网站后,不再打开一个tab页面并访问另外的网站。
2.不能保证你关闭浏览器了后,你地的Cookie立刻过期,上次的会话已经结束。
3.上图中所谓的攻击网站,可能是一个存在其他漏洞的可信任的经常被人访问的网站。
寻找目标
抓取一个正常请求的数据包,去掉Referer字段后再重新提交,如果该提交还有效,那么基本上可以确定存在CSRF漏洞。
尝试
回合一:
1.某小说网,csrf漏洞在修改密码处,无验证码
2.BP抓包,不能怪人家,也许用户太少了吧,懒得搞安全
3.生成PoC
PoC通常是由攻击者或安全研究人员进行开发,然后发布出来,从而来验证某个安全漏洞的存在以及如何利用这个漏洞。在一些案例中,黑客通过发布PoC来推动对应产品厂商开发修复加固补丁。
使用Burpsuite可以生成PoC,但是必须专业版,当然土豪可以直接购买,有志之士可以下个破解版。
可以参考:http://ximcx.cn/post-110.html
4.使用其他浏览器打开这个PoC的html文件,会弹出密码修改成功的画面,即构造的CSRF触发成功。
5.用js自动触发就不用受害者点击Submit提交表单哦,别人点击连接就可以直接触发csrf!如果知道管理员账号,还可修改其密码。
回合二:
1.使用CSRFTester半自动化检测,其下载网址为https://www.owasp.org/index.php/File:CSRFTester-1.0.zip
2.下载完成后,将其放在jre文件夹下
并修改run.bat,将JAVA_HOME修改为jre位置
3.双击bat文件进行运行:
可以看到,系统正在监听8008端口。
4.按照以前使用Burpsuite的经验,我们进行浏览器代理的设置。这里展示qq浏览器的代理设置:
5.点击start recording即可开启记录
6.
没有验证码的修改,永远会被别人修改。当然啦,添加书到书架,关注别人等一系列的操作更是不在话下。
7.
抓取该请求后,在Step属性中添加请求,然后将Form Parameter中的密码改动一下,然后单击Generate HTML按钮来产生CSRF攻击脚本。
8.
9.攻击完成后,用户在网页刷新后就会退出,重新登录,使用修改后的密码qqwwee,无法登录。
(不知道怎么搞的,后来我加了1也登不上了。。。但是可以自豪地说)攻击成功。
防御
1. 尽量使用POST,限制GET
GET接口太容易被拿来做CSRF攻击,只要构造一个img标签,而img标签又是不能过滤的数据。接口最好限制为POST使用,GET则无效,降低攻击风险。
当然POST并不是万无一失,攻击者只要构造一个form就可以,但需要在第三方页面做,这样就增加暴露的可能性。
2. 浏览器Cookie策略
IE6、7、8、Safari会默认拦截第三方本地Cookie(Third-party Cookie)的发送。但是Firefox2、3、Opera、Chrome、Android等不会拦截,所以通过浏览器Cookie策略来防御CSRF攻击不靠谱,只能说是降低了风险。
PS:Cookie分为两种,Session Cookie(在浏览器关闭后,就会失效,保存到内存里),Third-party Cookie(即只有到了Exprie时间后才会失效的Cookie,这种Cookie会保存到本地)。
PS:另外如果网站返回HTTP头包含P3P Header,那么将允许浏览器发送第三方Cookie。
3. 加验证码
验证码,强制用户必须与应用进行交互,才能完成最终请求。在通常情况下,验证码能很好遏制CSRF攻击。但是出于用户体验考虑,网站不能给所有的操作都加上验证码。因此验证码只能作为一种辅助手段,不能作为主要解决方案。
4. Referer Check
Referer Check在Web最常见的应用就是“防止图片盗链”。同理,Referer Check也可以被用于检查请求是否来自合法的“源”(Referer值是否是指定页面,或者网站的域),如果都不是,那么就极可能是CSRF攻击。
但是因为服务器并不是什么时候都能取到Referer,所以也无法作为CSRF防御的主要手段。但是用Referer Check来监控CSRF攻击的发生,倒是一种可行的方法。
5. Anti CSRF Token
现在业界对CSRF的防御,一致的做法是使用一个Token(Anti CSRF Token)。
例子:
1. 用户访问某个表单页面。
2. 服务端生成一个Token,放在用户的Session中,或者浏览器的Cookie中。
3. 在页面表单附带上Token参数。
4. 用户提交请求后, 服务端验证表单中的Token是否与用户Session(或Cookies)中的Token一致,一致为合法请求,不是则非法请求。
这个Token的值必须是随机的,不可预测的。由于Token的存在,攻击者无法再构造一个带有合法Token的请求实施CSRF攻击。另外使用Token时应注意Token的保密性,尽量把敏感操作由GET改为POST,以form或AJAX形式提交,避免Token泄露。
注意:
CSRF的Token仅仅用于对抗CSRF攻击。当网站同时存在XSS漏洞时候,那这个方案也是空谈。所以XSS带来的问题,应该使用XSS的防御方案予以解决。