20222420 2024-2025-1 《網路與系統攻防技術》實驗八實驗報告

SAltria發表於2024-12-06

1.實驗內容

1.1 近期學習內容簡述

(1)學習了Web前後端的語言的簡介
(2)學習了SQL隱碼攻擊的多個例項,知道了SQL隱碼攻擊的原理
(3)學習了XSS跨站指令碼攻擊的原理和示例
(4)瞭解了CSRF的原理和防範方法
(5)瞭解了Burpsuite等工具

1.2 實驗內容簡述

  • (1)Web前端HTML
    能正常安裝、啟停Apache。理解HTML,理解表單,理解GET與POST方法,編寫一個含有表單的HTML
  • (2)Web前端javascipt
    理解JavaScript的基本功能,理解DOM
    在(1)的基礎上,編寫JavaScript驗證使用者名稱、密碼的規則。在使用者點選登陸按鈕後回顯“歡迎+輸入的使用者名稱”
    嘗試注入攻擊:利用回顯使用者名稱注入HTML及JavaScript
  • (3)Web後端:MySQL基礎:正常安裝、啟動MySQL,建庫、建立使用者、修改密碼、建表
  • (4)Web後端:編寫PHP網頁,連線資料庫,進行使用者認證
  • (5)最簡單的SQL隱碼攻擊,XSS攻擊測試
  • (6)安裝DVWA或WebGoat平臺,並完成SQL隱碼攻擊、XSS、CSRF攻擊

2.實驗過程

2.1 Web前端HTML(能正常安裝、啟停Apache。理解HTML,理解表單,理解GET與POST方法,編寫一個含有表單的HTML)

(1)正常安裝、啟停Apache

  • 使用sudo apt install apache2命令自動安裝配置Apache(由於kali自帶,這裡就不展示了)

  • 使用sudo systemctl start apache2命令啟動Apache,使用sudo systemctl status apache2命令檢視Apache狀態
    可知已經啟動

  • 瀏覽器瀏覽localhost
    可再次確定Apache啟動成功

  • 使用sudo systemctl stop apache2命令關閉Apache,使用sudo systemctl status apache2命令檢視Apache狀態
    可知已經關閉

(2)理解HTML,理解表單,理解GET與POST方法,編寫一個含有表單的HTML

  • /var/www/html/建立檔案Get_method.html

    • 建立一個html檔案在桌面,然後使用命令sudo mv Get_method.html /var/www/html/Get_method.html將其移動到/var/www/html/
    • Get_method.html中寫入Get方法的html程式碼
    • 訪問http://localhost/Get_method.html並提交資料
      可知,Get方法提交後,資料在URL中可見

  • /var/www/html/建立檔案Post_method.html

    • 建立一個html檔案在桌面,然後使用命令sudo mv Post_method.html /var/www/html/Post_method.html將其移動到/var/www/html/

    • Post_method.html中寫入Post方法的html程式碼

    • 訪問http://localhost/Post_method.html並提交資料
      可知,Post方法提交後,資料在URL中不可見,因為資料放在HTTP請求的主體部分(body),不會顯示在URL中。

    • 但是抓包還是能抓到明文資料,使用https就會安全很多

(3)總結 GET 方法和 POST 方法

區別 GET 方法 POST 方法
請求目的 從指定的資源請求資料 向指定的資源提交資料以進行處理(例如,建立/更新資源)
請求引數位置 引數附加在URL的末尾(查詢字串) 引數包含在HTTP請求的主體中
資料可見性 引數在URL中可見,可能會被快取和記錄在伺服器日誌中 引數在HTTP請求主體中,相對不那麼容易被直接訪問或記錄
資料大小限制 通常受限於URL長度和伺服器配置(較短) 無嚴格限制,取決於伺服器配置(較長)
安全性 不太安全,因為引數在URL中可見 相對更安全,因為引數不在URL中,但需要使用HTTPS來確保資料傳輸的安全性
瀏覽器書籤 可以將請求URL書籤化 無法直接書籤化POST請求的URL
快取 瀏覽器和某些中介軟體可能會快取GET請求的響應 POST請求的響應通常不會被快取
使用場景 適用於請求資料而不改變伺服器狀態的操作(例如,搜尋查詢) 適用於提交資料以改變伺服器狀態的操作(例如,表單提交)

2.2 Web前端javascipt(理解JavaScript的基本功能,理解DOM;在(1)的基礎上,編寫JavaScript驗證使用者名稱、密碼的規則。在使用者點選登陸按鈕後回顯“歡迎+輸入的使用者名稱”;嘗試注入攻擊:利用回顯使用者名稱注入HTML及JavaScript)

  • /var/www/html/建立檔案Post_JS.html

  • Post_JS.html中寫入Post方法的html程式碼

點選檢視程式碼
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Register: POST JS 20222420</title>
    <style>
        /* 簡單的樣式,用於顯示歡迎資訊 */
        #welcomeMessage {
            color: green;
            font-weight: bold;
            margin-top: 20px;
        }
    </style>
</head>
<body>
    <h1>Register: POST JS 20222420 </h1>
    <form id="myForm" action="/submit" method="post">
        <label for="username">Username:</label>
        <input type="text" id="username" name="username" required>
        <br><br>
        <label for="password">Password:</label>
        <input type="password" id="password" name="password" required>
        <br><br>
        <button type="submit">Submit</button>
    </form>
    <p id="welcomeMessage"></p> <!-- 用於顯示歡迎資訊的元素 -->

    <script>
        // 獲取表單元素
        const form = document.getElementById('myForm');
        const usernameInput = document.getElementById('username');
        const passwordInput = document.getElementById('password');

        // 新增事件監聽器
        form.addEventListener('submit', function(event) {
            // 阻止表單的預設提交行為
            event.preventDefault();

            // 獲取使用者輸入
            const username = usernameInput.value.trim();
            const password = passwordInput.value.trim();

            // 驗證使用者名稱和密碼
            const usernameValid = username.length >= 5;
            const passwordValid = password.length >= 8 && /\d/.test(password);

            // 如果驗證透過
            if (usernameValid && passwordValid) {
                // 顯示歡迎資訊
                document.write('歡迎' + username);

            } else {
                // 如果驗證失敗
                alert('使用者名稱必須至少包含5個字元,密碼必須至少包含8個字元且包含至少一個數字。');
            }
        });
    </script>
</body>
</html>

  • 驗證“JavaScript驗證使用者名稱、密碼格式”的功能。驗證在使用者點選按鈕後回顯“歡迎+輸入的使用者名稱”的功能。

    • 使用者名稱符合,但密碼未含數字
      我只設定了一個提示資訊,所以使用者名稱和密碼均提醒了
    • 使用者名稱長度不夠,密碼符合
      我只設定了一個提示資訊,所以使用者名稱和密碼均提醒了
    • 使用者名稱、密碼格式均符合,回顯“歡迎+輸入的使用者名稱”
  • 注入攻擊:利用回顯使用者名稱注入HTML及JavaScript
    使用者名稱輸入<script>alert('你被20222420攻擊了!')</script> <h1>你被20222420攻擊了</h1>

    • JavaScript效果
    • HTML效果

2.3 Web後端(MySQL基礎:正常安裝、啟動MySQL,建庫、建立使用者、修改密碼、建表)

(1)安裝

使用sudo apt install mariadb-server命令自動安裝配置即可,mariadb-server適用於需要儲存和管理大量資料的場景。由於kali自帶了mariadb,這裡就不展示了

(2)啟動並驗證,並登入

  • 使用systemctl start mysql啟動,systemctl status mysql驗證
    disable是指未設定開機自啟動,但其是啟動了的、在執行的

  • 登入,使用sudo mysql -uroot -p,輸入mysql的密碼時直接輸入“回車”

(3)建庫並驗證

使用create database test;建立名為test的資料庫例項,然後使用show databases;驗證

(4)建立使用者並驗證

使用CREATE USER 'test'@'%' IDENTIFIED BY 'test';,還可以將test資料庫例項的許可權授予test使用者

(5)修改密碼

使用ALTER USER 'test'@'%' IDENTIFIED BY 'change';

(6)建表並使用、驗證

  • 使用CREATE TABLE testTable (id INT AUTO_INCREMENT PRIMARY KEY,name VARCHAR(255) NOT NULL);可以建立一個表並設定了主鍵

  • 新增資料到表,只需要新增到name,主鍵會自動遞增新增
    INSERT INTO testTable (name) VALUES ('Alice');
    `INSERT INTO testTable (name) VALUES ('Bob');``

  • 檢視、驗證表
    使用select * from testTable;,可知表建立成功併成功新增了資料

2.4 Web後端:編寫PHP網頁,連線資料庫,進行使用者認證

  • root使用者建立user_auth資料庫例項,並建立表users、插入資料

    • 建立user_auth資料庫例項

    • 進入例項,建立表usersCREATE TABLE users (id INT AUTO_INCREMENT PRIMARY KEY,username VARCHAR(50) NOT NULL,password VARCHAR(50) NOT NULL);

    • 修改root密碼,使其不為空(否則後續連不上),並給予其user_auth的許可權(雖然預設root建立者有許可權)

    • 插入資料,INSERT INTO users (username, password) VALUES ('testuser', 'testpassword');

  • 編寫PHP網頁

點選檢視程式碼
<?php
session_start();
 
// 資料庫連線引數
$servername = "localhost";
$dbusername = "root";
$dbpassword = "root";
$dbname = "user_auth";
 
// 建立資料庫連線
$conn = new mysqli($servername, $dbusername, $dbpassword, $dbname);
 
// 檢查連線是否成功
if ($conn->connect_error) {
    die("連線失敗: " . $conn->connect_error);
}
 
// 如果表單已提交
if ($_SERVER["REQUEST_METHOD"] == "POST") {
    $inputUsername = $_POST['username'];
    $inputPassword = $_POST['password'];
 
    // 查詢資料庫中的使用者
    $result = $conn->query("SELECT * FROM users WHERE username = '$inputUsername' AND password = '$inputPassword'");
 
    if ($result->num_rows > 0) {
    
    
        // 如果使用者存在,獲取其資訊
        $row = $result->fetch_assoc();

        $_SESSION['loggedin'] = true;
        $_SESSION['username'] = $inputUsername;
        echo "登入成功!";
            // 這裡可以重定向到其他頁面
            // header("Location: protected_page.php");
            // exit();
        
    } else {
        echo "使用者名稱不存在,或密碼錯誤。";
    } 
 
    // 關閉結果集
    $result->close();
}
 
// 關閉資料庫連線
$conn->close();
?>
 
<!DOCTYPE html>
<html>
<head>
    <title>使用者登入</title>
</head>
<body>
    <h2>登入 made by 20222420</h2>
    <form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">
        使用者名稱: <input type="text" name="username" required><br>
        密碼: <input type="password" name="password" required><br>
        <input type="submit" value="登入">
    </form>
</body>
</html>

  • 登入,驗證“使用者認證”功能
    • 使用者不存在或密碼錯誤示例
      我沒有區分具體是使用者不存在還是密碼錯誤

    • 驗證,登入成功示例

2.5 最簡單的SQL隱碼攻擊,XSS攻擊測試

使用2.4中的資料庫和php網頁

  • SQL隱碼攻擊
    使用' or 1=1; -- 作為使用者名稱,注意一定要在--後新增空格否則會卡死在相關語句。密碼可以隨便填
    這樣sql語句變為SELECT * FROM users WHERE username = '' or 1=1; -- AND password = '$inputPassword'。WHERE中一定為真,並且-- 後的語句被註釋掉了導致不需要密碼

  • XSS攻擊

    • 首先需要修改一下php網頁,使其可以回顯使用者輸入的賬戶名,否則攻擊語句無法執行
      如圖,修改程式碼,使其可以在登入失敗時回顯輸入的使用者名稱

    • 驗證,輸入<script>alert("20222420XSS")</script>
      如圖,利用網站沒有對使用者提交資料進行轉義處理或者過濾的缺點,新增了html程式碼,嵌入到web頁面中去

2.6 安裝DVWA或WebGoat平臺,並完成SQL隱碼攻擊、XSS、CSRF攻擊

(1)DVWA平臺

  • 完成SQL隱碼攻擊

    • 首先輸入' or 1=1; -- 進行測試
      可以,SQL隱碼攻擊已經成功,輸出了全表的內容。還可知顯示的id並不是表中的id而是直接返回了我輸入的內容。
    • 進一步進行SQL隱碼攻擊,獲取更多資訊
      使用' or 1=1 union select version(),database(); --
      如下圖,可知,不僅顯示了人名,還透過union顯示了資料庫的版本號為“5.7.26”,及當前資料庫名“dvwa”
  • 完成XSS攻擊

    • 題目如圖

    • 這一題中,只能選擇語言並提交。透過仔細觀察和反覆嘗試,可知點選提交後會在URL中出現default=並顯示所選擇的語言。
      可以分析出,該網頁使用的是GET來傳遞引數

    • 改變default=後的內容,實現XSS攻擊
      改為<script>alert("20222420XSS")</script>,由下圖可知成功

  • 完成CSRF攻擊

    • 分析該題
      該題可以更改自己的密碼,然後可以驗證修改後的密碼

    • 測試後發現,引數直接透過URL傳遞

    • 準備CSRF攻擊
      透過burp攔截,我就得到了一個傳送的包,然後透過burp中的工具直接便捷得生成CSRF攻擊用的html

    • 修改一下生成的html中的密碼的值,使其變為我想要攻擊他人時使其密碼改變為的值,如6666,然後複製生成的URL

    • 這樣,當他人在登陸著http://127.0.0.1/DVWA-master/vulnerabilities/csrf/時,若點選了我的危險網站(即上面生成的URL,或包含該URL的其他看似正常的網站),他的密碼就會被我改變
      如下圖所示

    • 測試
      由下圖可知,成功了

(2)WebGoat平臺

  • 完成SQL隱碼攻擊

    • Login_Count輸入1 or 1=1; -- 進行測試
      但顯示無法解析我的輸入到一個數字

    • 檢視題目得知,只有一個空對於SQL隱碼攻擊是脆弱的,看來應該是下面一個空
      User_Id輸入1 or 1=1,在Login_Count輸入正常的數字。如下可知注入成功。

  • 完成XSS攻擊
    直接輸入<script>alert("20222420XSS")</script>

  • 完成CSRF攻擊

    • 這道題需要從傳送評論,但必須從其他地方傳送
      只需要用burp攔截獲取包的格式,然後生成CSRF的html,再修改一下生成的html即可,如下圖,我想傳送的評論是test星級為4

    • 複製得到的URL

    • 驗證
      當登陸著http://127.0.0.1:8080/WebGoat/csrf/review的人點選了該URL,就會傳送該評論(test,星級為4
      驗證過程如下面三圖,可知我(即被攻擊者)已經成功從其他位置傳送了該評論


3.問題及解決方案

  • 問題1:無法將建立的檔案放入/var/www/html/
  • 問題1解決方案:利用sudo mv命令就有許可權了
  • 問題2:SQL隱碼攻擊時一直不成功
  • 問題2解決方案:詢問AI,本來AI是不會給相關的答案的。但換一種方式問,問我這樣能否透過,AI就給出了回答。然後我就得知原來--後需要空格才能起到註釋的效果,這樣我就解決了問題。
  • 問題3:我寫的網頁先用SQL語句驗證了使用者名稱,然後用$row['password'] === $inputPassword驗證密碼。但只有使用者名稱能使用SQL隱碼攻擊,這導致我無法用SQL隱碼攻擊登入。
  • 問題3解決方案:更改程式碼,像課件裡的一樣用SQL語句同時驗證使用者名稱和密碼即可直接透過SQL隱碼攻擊登入。
  • 問題4:php連線不上資料庫
  • 問題4解決方案:經過檢查,程式碼是沒問題的,資料庫也沒問題。可能是因為資料庫的root使用者沒有設定密碼,且$dbpassword = "";不代表沒有密碼,導致連線不上資料庫。設定密碼後便解決了。

4.學習感悟、思考等

在這次實驗中,我體會了Web開發中的前端與後端技術是如何協同工作的。透過安裝和配置Apache伺服器以及MySQL資料庫,我學會了如何在伺服器端搭建一個Web環境。編寫HTML表單和JavaScript驗證邏輯,讓我對前端技術有了更深入的理解,特別是在處理使用者輸入和表單提交方面。同時,我也認識到了前端驗證的重要性,但它並不能替代後端驗證,因為前端驗證可以被繞過。此外,透過編寫PHP網頁和進行使用者認證,我進一步瞭解前端和後端mysql的協同。在測試SQL隱碼攻擊、XSS攻擊、CSRF攻擊的過程中,我也深刻認識到了Web安全的複雜性。

參考資料

  • 《Java程式設計與資料結構教程(第二版)》
  • 《Java程式設計與資料結構教程(第二版)》學習指導
  • ...

相關文章