CSRF(Cross-site request forgery)
CSRF,全称Cross-site request forgery,翻译过来就是跨站请求伪造,是指利用受害者尚未失效的身份认证信息(cookie、会话等),诱骗其点击恶意链接或者访问包含攻击代码的页面,在受害人不知情的情况下以受害者的身份向(身份认证信息所对应的)服务器发送请求,从而完成非法操作(如转账、改密等)。CSRF与XSS最大的区别就在于,CSRF并没有盗取cookie而是直接利用。在2013年发布的新版OWASP Top 10中,CSRF排名第8。
CSRF漏洞CSR表示跨站请求是受害者构造的,F表示forgery伪造是攻击者构造的
受害者角度:
用户在当前已登录的Web应用程序上执行非本意的操作
攻击者角度:
攻击者欺骗浏览器,让其以受害者名义执行自己想要的操作
比如在一个站点中利用csrf漏洞去修改该网站的密码:
修改密码--》直接输入新密码
下面对不同级别的代码进行分析。
服务器端核心代码
' . mysql_error() . '
' );
// Feedback for the user
echo "Password Changed."; } else { // Issue with passwords matching echo "
Passwords did not match."; } mysql_close(); } ?>
可以看到,服务器收到修改密码的请求后,会检查参数password_new与password_conf是否相同,如果相同,就会修改密码,并没有任何的防CSRF机制(当然服务器对请求的发送者是做了身份验证的,是检查的cookie,只是这里的代码没有体现= =)。
1、构造链接
A) 最基础的:
http://192.168.2.92/DVWA/vulnerabilities/csrf/?password_new=test&password_conf=test&Change=Change#
当受害者点击了这个链接,他的密码就会被改成password(这种攻击显得有些拙劣,链接一眼就能看出来是改密码的,而且受害者点了链接之后看到这个页面就会知道自己的密码被篡改了)
我们需要对链接做一些处理以使用短链接来隐藏URL(点击短链接,会自动跳转到真实网站):因为没有域名所以没有成功,这里不能使用IP
如http://dwz.cn/****
2、构造HTML
把构造的csrf.html方法phpstudy的WWW目录下,诱骗受害者点击,这里是LOW等级的方法
服务器端核心代码
服务器端核心代码
' . mysql_error() . '
' );
// Feedback for the user
echo "Password Changed."; } else { // Issue with passwords matching echo "
Passwords did not match."; } } else { // Didn't come from a trusted source echo "
That request didn't look correct."; } mysql_close(); } ?>
相关函数说明
int eregi(string pattern, string string)
检查string中是否含有pattern(不区分大小写),如果有返回True,反之False。
可以看到,Medium级别的代码检查了保留变量 HTTP_REFERER(http包头的Referer参数的值,表示来源地址)中是否包含SERVER_NAME(http包头的Host参数,及要访问的主机名,这里是192.168.2.92),希望通过这种机制抵御CSRF攻击。
过滤规则是http包头的Referer参数的值中必须包含主机名(这里是192.168.153.130)
我们可以将攻击页面命名为192.168.153.130.html(页面被放置在攻击者的服务器里,这里是127.0.0。1)就可以绕过了
也可以在网站下以IP名称新建一个文件夹,然后把csrf.html放在下面,诱骗用户去点击
服务器端核心代码
' . mysql_error() . '
' );
// Feedback for the user
echo "Password Changed."; } else { // Issue with passwords matching echo "
Passwords did not match."; } mysql_close(); } // Generate Anti-CSRF token generateSessionToken(); ?>
可以看到,High级别的代码加入了Anti-CSRF token机制,用户每次访问改密页面时,服务器会返回一个随机的token,向服务器发起请求时,需要提交token参数,而服务器在收到请求时,会优先检查token,只有token正确,才会处理客户端的请求。攻击思路是当受害者点击进入这个页面,脚本会通过一个看不见框架偷偷访问修改密码的页面,获取页面中的token,并向服务器发送改密请求,以完成CSRF攻击。然而理想与现实的差距是巨大的,这里牵扯到了跨域问题,而现在的浏览器是不允许跨域请求的。
知识扩展:
1、先来说说什么是源
• 源(origin)就是协议、域名和端口号。
以上url中的源就是:http://www.company.com:80
若地址里面的协议、域名和端口号均相同则属于同源。
以下是相对于 http://www.a.com/test/index.html 的同源检测
• http://www.a.com/dir/page.html ----成功
• http://www.child.a.com/test/index.html ----失败,域名不同
• https://www.a.com/test/index.html ----失败,协议不同
• http://www.a.com:8080/test/index.html ----失败,端口号不同
2.什么是同源策略?
同源策略是浏览器的一个安全功能,不同源的客户端脚本在没有明确授权的情况下,不能读写对方资源。所以a.com下的js脚本采用ajax读取b.com里面的文件数据是会报错的。
• 不受同源策略限制的:
1、页面中的链接,重定向以及表单提交是不会受到同源策略限制的。
2、跨域资源的引入是可以的。但是js不能读写加载的内容。如嵌入到页面中的,,,
跨域
1、什么是跨域
受前面所讲的浏览器同源策略的影响,不是同源的脚本不能操作其他源下面的对象。想要操作另一个源下的对象是就需要跨域。
通过对比发现多了一个user_token,在研究暴力破解时就发现存在user_tokern,它是来自上一次的响应包中,所以上面的抓包改包或者新建host文件都不可以利用了
利用方法:结合XSS漏洞获取页面中的user_token参数
CSRF防御:CSRF Token我们称这种类型的随机参数为csrf token它保证了
攻击者无法猜测的所有参数
因为构造HTTP请求的人不一样,暴力破解的攻击者是当前用户,受害者是
其他用户CSRF的攻击者是其他用户,受害者是当前用户
校验Refer:虽然有防御功能,但是它只验证了域名host可以绕过
随机Token:随机生成的字符串是业界使用最多的防御方法
验证码:虽然有限防御但是牺牲了用户体验