CSRF漏洞
CSRF
csrf的原理与危害
CSRF (Cross Site Request Forgery),中文全称跨站点请求伪造。
攻击者盗用了受害者的身份,以受害者的名义发送恶意请求,对服务器来说这个请求是完全合法的,但是却完成了攻击者所期望的一个操作。
以两个例子说明,
案例一:
一个银行站点存在一个csrf漏洞,用户A转账给B用户2000元,执行转账操作后会对银行发送一次请求:http://www.bank.com/money?user=A&num=2000&transfer=B
,然后A用户就会把自己的2000元转到B的账户下。在发送这个请求给银行服务器时,服务器首先会验证这个请求是否为一个合法的session,并且用户A确认登陆才可以验证通过。
如果此时有一个恶意用户C想把A用户的钱转到自己的账户下,那么他可以构造 http://www.bank.com/money?user=A&num=2000&transfer=C
这个请求,但是这个请求必须有A用户发出才可以生效,此时恶意用户C可以搭建一个自己的网站,在网站中写入如下代码 <img src="http://www.bank.com/money?user=A&num=2000&transfer=C">
,之后诱导A用户访问自己的网站,当A访问这个网站时,这个网站就会把img标签里的URL发给银行服务器,而此时除了这个请求以外,还会把A用户的cookie一起发到服务器,如果此时A用户的浏览器与银行的session没有过期,那么就会在A用户毫不知情的情况下执行转账给C的操作。
案例二:
一个cms系统的管理后台,可以发送一个post请求添加一个管理员,由于没有加token或者验证码限制,恶意攻击者可以在自己的服务器evil.com上建立一个a.html的文件,a.html文件是一个添加管理员账户的表单,上面写入需要添加的账户用户名及密码,当网站管理员打开evil.com/a.html的时候,并且管理员的session没有失效,那么此时a.html就会请求受攻击网站,在管理员毫不知情的情况下添加一个后台账户。
通过以上两个案例可以得出结论,csrf会根据业务功能场景的不用而利用起来也不同,这些请求都是跨域发起的,而且是在受害者的session没有失效通过身份认证的情况下发生的。
使用用户的登陆凭证,让用户自己在不知情的情况下,进行修改数据的操作。
但是查询数据的地方却不需要保护,因为csrf是借助受害者的cookie来进行攻击者需要的恶意操作的,攻击者并不能拿到受害者cookie,对于服务器返回的结果也无法解析查看,攻击者唯一可以做的就是让服务器执行自己的操作命令,或者说改变网站数据,而查询操作即不会改变数据也不会把结果返回给攻击者,所以并不需要保护。
危害
1、对网站管理员进行攻击
2、修改受害网站上的用户账户和数据
3、账户劫持
4、传播CSRF蠕虫进行大规模攻击
5、利用csrf进行拖库
6、利用其他漏洞进行组合拳攻击
7、针对路由器的csrf攻击
检测
直接判断
1、GET类型的CSRF的检测
如果有token等验证参数,先去掉参数尝试能否正常请求。如果可以,即存在CSRF漏洞。
2、POST类型的CSRF的检测
如果有token等验证参数,先去掉参数尝试能否正常请求。如果可以,再去掉referer参数的内容,如果仍然可以,说明存在CSRF漏洞,可以利用构造外部form表单的形式,实现***。如果直接去掉referer参数请求失败,这种还可以继续验证对referer的判断是否严格,是否可以绕过。
3、特殊情况的POST类型的CSRF检测
如果上述post方式对referer验证的特别严格,有的时候由于程序员对请求类型判断不是很严格,可以导致post请求改写为get请求,从而CSRF。直接以get请求的方式进行访问,如果请求成功,即可以此种方式绕过对referer的检测,从而CSRF。
bp抓包
·找到抓取到提交表单的post包
三、伪造请求
·右键选择Engagement tools – Generate CSRF PoC
修改提交的参数—生成CSRF的HTML—在浏览器中测试
打钩后下次点击在浏览器中测试则默认复制CSRFHTML
点击copy后,直接在浏览器上的地址栏右键粘贴,回车
点击提交请求
但这不是重点,重点是查看刚才提交的信息是否成功被修改了或是成功新增了数据。
四、检查是否成功提交
信息被修改,或成功新增表单,则说明可以成功伪造请求进行操作,存在CSRF漏洞。
若无被修改/新增或在粘贴地址栏回车时页面出现错误,无法提交,则不存在CSRF漏洞
防御
对于CSRF的防御通常有以下三种方法:
1、使用验证码
csrf攻击一般都是在受害者不知情的情况下进行发起的,使用验证码可以有效的防止攻击,但是每次请求都要输入验证码会影响用户体验,所以通常只在用户登陆注册,还有一些特定业务场景下使用,比如银行转账。如何使用验证码要根据业务和场景来决定。
2、验证http Referer
http头中的referer字段记录了请求来源地址,比如从 http://www.test.com 点击链接到 http://m.test.com 之后,那么referer就是 http://www.test.com 这个地址。攻击者在对受害者进行攻击的时候,是在攻击者自己的服务器上构建自己的恶意脚本,诱骗受害者点击,所以此时的referer值就是攻击者自己的URL地址。
通过以上可知,csrf攻击都是跨域发起的,所以在服务端针对referer字段验证是否属于安全可靠的域名,可在一定程度上有效防御此类攻击。
但是此类方法并非万无一失,在低版本存在漏洞的浏览器中,黑客可以篡改referer值。另一种情况是csrf结合xss进行攻击,此时就不需要跨域发起,也可以绕过referer验证。
3、使用token
在说token如何防御csrf攻击之前,我们先了解下token的工作原理。
当用户第一次进行登陆的时候,客户端会通过用户名和密码去请求服务器登陆,服务端在收到请求后会验证客户端传来的用户名和密码,如果验证通过,服务器就会签发一个token发给客户端,并且将token放到session中,客户端收到token后存储到本地,以后客户端只要每次请求服务器就要带上token,经过服务器验证通过后才会返回响应数据,否则报错。
csrf攻击成功的前提条件是攻击者可以完全伪造出受害者的所有请求,而且请求中的验证信息都在cookie中,黑客只要使用用户的cookie通过安全验证就可以完成攻击。了解了这些之后,想要防止csrf攻击,就要在http请求中放置黑客不可以伪造的信息,而且该信息不可以存在于cookie中,否则就无效。而token令牌最大的特点就是随机性,不可预测,并且不存在于cookie当中。
对于GET请求,请求参数直接在URL当中,这样token的形式就为 http://xxx.com?csrftoken=tokenvalue ,但是这种方式把请求参数都放在URL中,会导致在referer中泄露,不仅如此,设想另一种场景,一个在内网系统的员工,从内部敏感系统在点击对外部提供服务的网站链接,此时就会把内网敏感信息通过referer泄漏出去。而对于POST请求,token是以隐藏表单存在,<input type=”hidden” name=”csrftoken” value=”tokenvalue”/>
。最后注意一点,如果在同域下存在xss漏洞,那么这种使用token的防御将形同虚设。