CSRF的攻击与防御
基本概念
CSRF(Cross-Site Request Forgery),跨站请求伪造,是指利用受害者尚未失效的身份认证信息(cookie、会话等),诱骗其点击恶意链接或者访问包含攻击代码的页面,在受害人不知情的情况下以受害者的身份向相关对应服务器发送请求,从而完成非法操作。
攻击原理
以银行转账示例:
1.用户A登录银行网站,通过身份验证,浏览器生成了身份验证信息。
2.用户A点击了黑客B构造的恶意转账链接,在不知情的情况下将转账请求连同认证信息发送到银行网站。
3.银行网站看到身份认证信息,认为请求时用户A的合法操作,处理转账请求。
4.用户A事后会发现自己的金钱被盗取,悲痛不已。
与XSS的区别以及关系
1.区别:
XSS是跨站脚本,产生原因是对用户输入没有正确过滤,需要借助JavaScript等脚本来修改页面内容。CSRF是跨站请求伪造,产生原因是采用了隐式的验证方式。通过API来实现非法操作,对于GET请求,可以构造URL进行攻击,不依赖脚本。
2.关系:
①如果一个网站存在XSS,很有可能也存在CSRF。
②两者都是利用用户的会话执行某些操作。
③CSRF的恶意代码可能位于第三方站点,过滤用户输入可以防御XSS,但不能防御CSRF。
攻击实例
1.使用burpsuit中的Generate CSRF Pox模块完成DVWA的CSRF
分析源代码:
<?php if( isset( $_GET[ ‘Change‘ ] ) ) { // Get input $pass_new = $_GET[ ‘password_new‘ ]; $pass_conf = $_GET[ ‘password_conf‘ ]; // Do the passwords match? if( $pass_new == $pass_conf ) { // They do! $pass_new = mysql_real_escape_string( $pass_new ); $pass_new = md5( $pass_new ); // Update the database $insert = "UPDATE `users` SET password = ‘$pass_new‘ WHERE user = ‘" . dvwaCurrentUser() . "‘;"; $result = mysql_query( $insert ) or die( ‘<pre>‘ . mysql_error() . ‘</pre>‘ ); // Feedback for the user echo "<pre>Password Changed.</pre>"; } else { // Issue with passwords matching echo "<pre>Passwords did not match.</pre>"; } mysql_close(); } ?>
从代码可以审计出只是判断了两次输入的密码是否相等,然后就进行了数据库的更新操作,对CSRF没有进行有效的防御。
使用burpsuite抓取修改密码的数据包:
在burpsuite中右键点击选择Engagement tools中的Generate CSRF PoC模块,修改value的值为想要修改的密码:
点击Copy HTML,保存为HTML文档,诱惑受害者点击。
点击"Submit request"之后,可以发现密码成功被更改。
2.phpMyAdmin 4.7.x XSRF/CSRF(PMASA-2017-9)
使用VulnSpy的在线靶机:https://www.vulnspy.com/?u=pmasa-2017-9
使用root/toor,登录
创建Poc
http://12542bdadc49caab6a1377d34f96639d.n1.vsgo.cloud:10616/pma/sql.php?db=mysql&table=user&sql_query=SET%20password%20=%20PASSWORD(%27Son01%27)
URL太长,生成短链接方便利用:
可以看到,语句成功执行:
防范
1.验证HTTP Referer字段
根据HTTP协议,在HTTP头中有一个Referer字段,记录了该HTTP请求的来源地址。通过Referer字段可以来规定受限页面的请求必须来自同一个网站。但是Referer的值有可能被篡改,并且还可能会泄露内网中的敏感信息。
2.在请求中加入Token并验证
在HTTP请求中加入相关算法生成的Token,并在服务端进行验证。如果请求中没有Token或者Token内容不正确,则认为可能是CSRF攻击而拒绝该请求。但是要防止黑客获得Token进行构造利用。
3.在HTTP头中自定义属性
该方法是将Token加在HTTP头中自定义的属性里。通过XMLHttpRequest类,可以一次性给所有请求加上csrftoken这个HTTP头属性,并把Token值放在其中。同时这个类的请求的地址不会被记录到浏览器的地址栏,不用担心Token会通过Referer泄露到其他网站。
4.添加验证码并验证
在每次用户提交内容时,都要求其在表单中填写图片上的随机验证码,通过强制用户和应用进行交互,来有效遏制CSRF攻击。iyong