[資安入門] 011 用 XAMPP 架設你的第一個「有漏洞」的網站:資安新手的後端安全實戰指南

適合對象:資安初學者、想了解後端程式語言與常見網站弱點的開發者
所需時間:約 2~3 小時(含環境建置與範例實作)
使用工具:XAMPP(Apache + MySQL + PHP)


為什麼資安新手要自己架網站?

學習網站安全最有效的方式,不是只讀理論,而是動手建一個「有弱點的網站」,然後親自嘗試攻擊與修補。XAMPP 提供了一個完整的本機伺服器環境,讓你無需租用主機或設定雲端服務,就能在自己的電腦上模擬真實的 Web 應用程式運作方式。

透過這篇文章,你將學會:

  • 安裝並啟動 XAMPP 本機伺服器
  • 理解 PHP 與 MySQL 在後端扮演的角色
  • 建立一個刻意包含 SQL Injection 與 XSS 弱點的登入頁面
  • 實際示範攻擊手法,並了解如何修補

⚠️ 重要聲明:本文所有範例僅供學習與研究用途,請務必在本機(localhost)環境操作,切勿用於攻擊他人系統,否則可能觸犯法律。


第一步:安裝 XAMPP

1.1 下載與安裝

前往 Apache Friends 官方網站 下載適合你作業系統的 XAMPP 版本(Windows / macOS / Linux 皆有支援)。

安裝完成後,開啟 XAMPP Control Panel,啟動以下兩個模組:

模組 用途
Apache Web 伺服器,負責處理 HTTP 請求並執行 PHP 程式
MySQL 資料庫伺服器,負責儲存使用者帳號、文章等資料

啟動後,打開瀏覽器輸入 http://localhost/,如果看到 XAMPP 歡迎頁面,表示環境已就緒。

1.2 認識專案目錄

XAMPP 預設的網頁根目錄位於:

  • WindowsC:\xampp\htdocs\
  • macOS/Applications/XAMPP/htdocs/
  • Linux/opt/lampp/htdocs/

你只要把 PHP 檔案放進這個資料夾,就能透過瀏覽器存取。


第二步:了解後端程式語言的角色

在開始寫有漏洞的程式之前,先快速理解「後端」在網站運作中扮演什麼角色。

2.1 前端 vs. 後端

層級 技術 職責
前端(Frontend) HTML、CSS、JavaScript 使用者在瀏覽器中看到、互動的畫面
後端(Backend) PHP、Python、Node.js 等 處理商業邏輯、驗證身份、讀寫資料庫
資料庫(Database) MySQL、PostgreSQL、SQLite 永久儲存資料(帳號、密碼、文章等)

2.2 為什麼 PHP 適合入門?

PHP 是最廣泛用於 Web 後端的語言之一,WordPress、Facebook 早期版本都以 PHP 建構。它語法直覺、與 HTML 可以混寫,而且 XAMPP 原生內建 PHP 直譯器,不需要額外安裝。

2.3 一段最基本的 PHP 程式

htdocs 底下建立 hello.php

<?php
  name = "資安新手";
  echo "<h1>你好," .name . "!歡迎來到後端世界。</h1>";
?>

打開 http://localhost/hello.php,你會在瀏覽器中看到一行標題。這就是後端程式語言最基本的運作——伺服器先執行 PHP,產生 HTML,再回傳給瀏覽器。


第三步:建立資料庫

3.1 使用 phpMyAdmin

XAMPP 內建 phpMyAdmin,在瀏覽器輸入 http://localhost/phpmyadmin/ 即可進入資料庫管理介面。

依照以下步驟建立練習用資料庫:

  1. 點擊左側「新增」,建立資料庫名稱 vuln_lab,編碼選 utf8mb4_general_ci
  2. 進入 vuln_lab 後,在 SQL 分頁執行以下指令:
CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(50) NOT NULL,
    password VARCHAR(255) NOT NULL,
    email VARCHAR(100)
);

INSERT INTO users (username, password, email) VALUES
('admin', 'admin123', '[email protected]'),
('guest', 'guest456', '[email protected]');

注意:這裡刻意使用明文密碼儲存,這本身就是一個常見的安全弱點。正式環境應使用 password_hash() 函式。

3.2 用 PHP 連線資料庫

htdocs 底下建立資料夾 vuln_lab,並新增 db.php

<?php
host = "localhost";user = "root";
pass = "";           // XAMPP 預設無密碼db   = "vuln_lab";

conn = new mysqli(host, user,pass, db);

if (conn->connect_error) {
    die("資料庫連線失敗:" . $conn->connect_error);
}
?>

第四步:建立有弱點的登入頁面

以下是本文的核心——一個刻意設計成「不安全」的登入系統,它同時包含 SQL InjectionReflected XSS 兩種經典弱點。

4.1 登入頁面(login.php)

vuln_lab/ 資料夾中建立 login.php

<?php
include 'db.php';
error = "";

if (_SERVER["REQUEST_METHOD"] === "POST") {
    username =_POST['username'];  // ❌ 未過濾使用者輸入
    password =_POST['password'];  // ❌ 未過濾使用者輸入

    // ❌ 弱點 1:直接將使用者輸入拼接進 SQL 查詢 → SQL Injection
    sql = "SELECT * FROM users WHERE username = 'username' AND password = 'password'";result = conn->query(sql);

    if (result &&result->num_rows > 0) {
        row =result->fetch_assoc();
        header("Location: welcome.php?user=" . row['username']);
        exit();
    } else {
        // ❌ 弱點 2:直接輸出使用者輸入 → Reflected XSSerror = "登入失敗,使用者 「" . username . "」 不存在或密碼錯誤。";
    }
}
?>
<!DOCTYPE html>
<html lang="zh-Hant">
<head>
    <meta charset="UTF-8">
    <title>漏洞實驗室 - 登入</title>
    <style>
        body { font-family: Arial, sans-serif; background: #1a1a2e; color: #eee; display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; }
        .login-box { background: #16213e; padding: 40px; border-radius: 10px; box-shadow: 0 0 20px rgba(0,0,0,0.5); width: 350px; }
        .login-box h2 { text-align: center; color: #e94560; margin-bottom: 25px; }
        .login-box input { width: 100%; padding: 12px; margin-bottom: 15px; border: 1px solid #0f3460; border-radius: 5px; background: #1a1a2e; color: #eee; box-sizing: border-box; }
        .login-box button { width: 100%; padding: 12px; background: #e94560; color: #fff; border: none; border-radius: 5px; cursor: pointer; font-size: 16px; }
        .login-box button:hover { background: #c81e45; }
        .error { color: #e94560; text-align: center; margin-bottom: 15px; font-size: 14px; }
        .warning { background: #533; border: 1px solid #e94560; padding: 10px; border-radius: 5px; margin-bottom: 20px; font-size: 12px; text-align: center; color: #faa; }
    </style>
</head>
<body>
    <div class="login-box">
        <div class="warning">⚠️ 此頁面包含刻意設計的安全弱點,僅供學習用途</div>
        <h2>🔓 漏洞實驗室</h2>
        <?php if (error): ?>
            <div class="error"><?php echo $error; // ❌ 未跳脫輸出 ?></div>
        <?php endif; ?>
        <form method="POST" action="">
            <input type="text" name="username" placeholder="使用者名稱" required>
            <input type="password" name="password" placeholder="密碼" required>
            <button type="submit">登入</button>
        </form>
    </div>
</body>
</html>

4.2 歡迎頁面(welcome.php)

<?php
// ❌ 弱點 3:直接從 URL 參數輸出,未經過濾 → Reflected XSS
user = isset(_GET['user']) ? _GET['user'] : '訪客';
?>
<!DOCTYPE html>
<html lang="zh-Hant">
<head>
    <meta charset="UTF-8">
    <title>歡迎</title>
    <style>
        body { font-family: Arial, sans-serif; background: #1a1a2e; color: #eee; display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; }
        .welcome { background: #16213e; padding: 40px; border-radius: 10px; text-align: center; }
        .welcome h1 { color: #4ecca3; }
    </style>
</head>
<body>
    <div class="welcome">
        <h1>歡迎回來,<?php echouser; ?>!</h1>
        <p>你已成功登入漏洞實驗室。</p>
        <a href="login.php" style="color: #e94560;">登出</a>
    </div>
</body>
</html>

第五步:實際攻擊示範

⚠️ 再次提醒:僅在 localhost 環境操作,切勿攻擊他人系統。

5.1 SQL Injection 攻擊

在登入頁面的「使用者名稱」欄位輸入:

' OR '1'='1' --

密碼隨便填。點擊登入後,你會發現不需要正確密碼就能登入

原理分析:後端組合出的 SQL 變成:

SELECT * FROM users WHERE username = '' OR '1'='1' --' AND password = '任意值'

'1'='1' 永遠為真,-- 後面是 SQL 註解,密碼檢查被完全略過。

5.2 Reflected XSS 攻擊

在使用者名稱欄位輸入:

<script>alert('XSS!')</script>

登入失敗時,錯誤訊息會直接輸出這段 HTML/JS,瀏覽器就會執行 alert()——這就是 Reflected XSS。

也可以直接在網址列測試 welcome.php 的弱點:

http://localhost/vuln_lab/welcome.php?user=<script>alert('XSS')</script>

現實危害:攻擊者可以把含有惡意 JS 的連結寄給受害者,當受害者點擊連結後,攻擊者便能竊取 Cookie、Session 或執行任意操作。


第六步:修補弱點

了解攻擊手法後,最重要的是學會如何修補。

6.1 修補 SQL Injection → 使用 Prepared Statement

// ✅ 安全寫法:參數化查詢
stmt =conn->prepare("SELECT * FROM users WHERE username = ? AND password = ?");
stmt->bind_param("ss",username, password);stmt->execute();
result =stmt->get_result();

Prepared Statement 會將使用者輸入視為「資料」而非「指令」,從根本上防止 SQL 注入。

6.2 修補 XSS → 使用 htmlspecialchars()

// ✅ 安全寫法:輸出時跳脫特殊字元
error = "登入失敗,使用者「" . htmlspecialchars(username, ENT_QUOTES, 'UTF-8') . "」不存在。";
// ✅ welcome.php 的安全寫法
user = htmlspecialchars(_GET['user'] ?? '訪客', ENT_QUOTES, 'UTF-8');

htmlspecialchars() 會將 <>" 等字元轉為 HTML 實體,瀏覽器就不會將其當作程式碼執行。

6.3 修補明文密碼 → 使用雜湊

// 註冊時:雜湊密碼後再儲存
hashed = password_hash(password, PASSWORD_BCRYPT);

// 登入時:用 password_verify() 比對
if (password_verify(inputPassword,row['password'])) {
    // 登入成功
}

第七步:延伸學習資源

當你完成上述練習後,可以進一步挑戰以下主題:

學習方向 推薦資源
更多弱點類型 OWASP Top 10 — Web 安全最權威的十大風險清單
進階靶機練習 DVWA(Damn Vulnerable Web Application)— 可直接部署在 XAMPP 上
滲透測試工具 Burp Suite Community Edition — 攔截與修改 HTTP 請求的利器
網站安全漏洞 PortSwigger Web Security Academy — 免費的互動式 Web 安全課程
後端語言深入 PHP 官方手冊中的安全章節

總結

用 XAMPP 在本機架設一個有漏洞的網站,是資安新手踏入 Web 安全領域最實際、最低門檻的方式。透過親手寫出不安全的程式碼,再一步步理解攻擊原理並修補,你能建立起比純讀理論深刻十倍的安全意識。

記住:理解攻擊是為了更好地防禦。 保持好奇心,持續練習,你就已經踏上成為資安專家的道路了。

飛飛
飛飛

講師學歷:臺科資工所、逢甲資工系畢業。
技術專長:OSINT、滲透測試、網站開發、專業易懂教育訓練。
證照書籍:OSCP、OSCE³、著《資安這條路:領航新手的 Web Security 指南》。
教學經驗:60+ 企業教學經驗、指導過上百位學員。
教學特色:新手友善、耐心指導、擅長圖解(流程圖、心智圖)引導學習。
社群經驗:目前經營全臺資安社群 CURA,曾任臺科資安社社長、逢甲黑客社社長。
社群交流:LINE 社群《飛飛的資安大圈圈》,即時分享經驗、鼓勵交流。
社群分享:FB 粉專《資安這條路,飛飛來領路》,分享文章與圖卡整理。
個人網站:feifei.tw 分享資安技術文章;pbtw.tw 分享 AI 相關應用;ssdlc.feifei.tw 分享軟體安全開發流程文章。