浅析CSRF漏洞的利用与防御机制

2019-08-06 约 182 字 预计阅读 1 分钟

声明:本文 【浅析CSRF漏洞的利用与防御机制】 由作者 ghtwf01 于 2019-08-06 07:27:00 首发 先知社区 曾经 浏览数 31 次

感谢 ghtwf01 的辛苦付出!

CSRF(跨站请求伪造)原理介绍

原理:利用目标用户的合法身份,以用户的名义执行某些非法操作
XSS与CSRF区别:

1.XSS是利用站点信任用户盗取cookie

2.CSRF是通过伪装成站点信任用户请求受信任的网站
例如简单转账案例

初始化链接:http://www.xxx.com/pay.php?user=xx&money=100
构造恶意链接:http://www.xxx.com/pay.php?user=恶意用户&money=10000

CSRF漏洞代码分析:

<?php 
    //会话验证(验证是该合法用户已登录) 
    $user=$_GET["user"]; 
    $money=$GET_["money"]; 
    //转账操作 
?>

由此可得出CSRF成功利用条件:

1.用户已经登陆系统

2.用户访问对应URL

例如利用CSRF修改目标用户密码
首先修改一次自己的密码得到修改密码的URL,根据URL可以知道密码修改为了hack

保证用户在已经登陆时发送该恶意URL链接,将URL中密码该为自己想该的,如

这样目标用户的密码就被改成了123

无防护的CSRF漏洞利用

1.GET型CSRF利用:

上面简单转账案例就是一个GET型CSRF利用
4种GET型CSRF利用方式
a.链接利用(a标签)

b.iframe利用
注意:可以设置iframe的style为display:none,以此来不显示iframe加载的内容

c.img标签利用
img标签内的内容会随着页面加载而被请求,以此src指向的位置会在页面加载过程中进行请求

d.CSS中background利用
可以利用CSS中background样式中的url来加载远程机器上的内容,从而对url中的内容发送HTTP请求

2.POST型CSRF利用

例如一个新建用户界面,通过表单提交新用户账号密码,查看网页源代码得到表单提交内容,然后自己可以编写一个html文件,里面也是表单提交,属性用hidden,比如

这样就达成了目的

CSRF漏洞探测

手动探测原理:探测web应用程序是否具有防止CSRF的措施

几种防御措施:

1.HTTP referer头

2.设置Token

3.HTTP自定义头

4.二次验证(比如在转账时会执行一个JS脚本弹框问是否将执行转账,这个时候是否执行就取决于用户,难以利用成功)

5.验证码防御

如果没有上述防御措施那么很大可能存在CSRF漏洞

利用自动化探测工具CSRFTester或者burp自带CSRF POC

1.CSRFTester设置浏览器代理:127.0.0.1:8008,bp是8080

2.登录web应用程序,提交表单,在CSRF工具中修改表单内容,查看是否更改,如果更改就存在CSRF漏洞

3.生成POC
一个wordpress博客为例就存在一个CSRF漏洞
创建用户,bp抓包,修改添加用户的账号密码

发送到CSRF POC

以html形式保存下来,发送给目标用户欺骗他打开,成功创建一个新账户

CSRF漏洞防御机制

1.CSRF漏洞Token防御

CSRF漏洞实质:服务器无法准确判断当前请求是否是合法用户的自定义操作
漏洞修补逻辑分析:如果服务器在用户登录之后给予用户一个唯一合法令牌,每一次操作过程中,服务器都会验证令牌是否正确,如果正确那么执行操作,不正确不执行操作。
一般情况下,给予的令牌写入表单隐藏域的value中,随着表单内容进行提交
Token防御代码分析

代码的意思是hello加上当前时间进行md5编码,当然hello可以改为其它复杂的字符串,这样不容易被破解出来,每一秒的值都会发生变化,如

实例使用Token进行CSRF防御

1.登陆验证成功之后,在会话SESSION["user_token"]中保存Token

2.在后台操作中,增删改表单中添加隐藏域hidden,设置value为Token

3.提交之后验证Token是否正确

附上代码

<?php
    session_start();
    function token_generate()
    {
        $salt = "hello".date("h:i:s");
        $token = md5($salt);
        return $token;
    }
    $token = token_generate();
    $_SESSION["user_token"] = $token;
?>
<html>
    <head>
        <meta charset="utf-8">
        <title>CSRF_TOKEN</title>
    </head>
    <body>
    <h1>CSRF_TOKEN</h1>
        <form action="check.php" method="post">
            <input type="text" value="111">
            <input type="hidden" name="user_token" value="<?php echo $token;?>">
            <input type="submit" name="submit" value="提交">
        </form>
    </body>
</html>

再附上check.php验证脚本代码

<?php
    session_start();
    $user_token = $_POST["user_token"];
    if($_SESSION["user_token"] == $user_token)
    {
        echo $_SESSION["user_token"];
        echo "<br>";
        echo "$user_token";
        echo "<br>";
        echo "successful";
    }
    else
    {
        echo "fail";
    }
?>

2.refer防御CSRF

Referer防御CSRF原理:HTTP Referer是header的一部分,当浏览器向web服务器发送请求的时候,一般会带上Referer,告诉服务器我是从哪个页面链接过来的,服务器基于此可以获得一些信息用于处理
当用户点击被构造好的CSRF利用页面,那么在执行用户对应操作时,提交的HTTP请求中就有对应的Referer值,此时服务端判断Referer值是否与服务器的域名信息有关,如果不想管则不执行操作
Refer防御代码编写
在PHP中使用$_SERVER['HTTP_REFERER']获取页面提交请求中的Referer值
这里需要用到一个strpos函数,用法参考https://www.w3school.com.cn/php/func_string_strpos.asp
附上防御代码:

strpos函数里面的意思也就是在获取的Referer值里面是否包含xx.com这个域名,如果包含了说明是正确的,没包含就可能是恶意的

3.验证码防御CSRF

验证码防御被认为是对抗CSRF最简单而且有效的防御方法,CSRF在用户不知情的情况下完成对应操作,而验证码强制用户与应用程序交互,才能最终完成操作,可以被认为是二次验证,但是出于对用户体验考虑,不可能每一次操作都加入验证码。所以验证码只是一种辅助手段,不能作为防御CSRF的主要解决方案

一些绕过方法

Token泄露

1.GET型Token泄露

例如页面包含

<img src="http://www.evil.com/"/>

2.POST型Token泄露

利用XSS漏洞获取其Cookie,查看存储在其中的Token
Referer绕过
参考https://blog.csdn.net/skythesea/article/details/81366086

关键词:[‘安全技术’, ‘WEB安全’]


author

旭达网络

旭达网络技术博客,曾记录各种技术问题,一贴搞定.
本文采用知识共享署名 4.0 国际许可协议进行许可。

We notice you're using an adblocker. If you like our webite please keep us running by whitelisting this site in your ad blocker. We’re serving quality, related ads only. Thank you!

I've whitelisted your website.

Not now