20232402 2025-2026-1 《网络与系统攻防技术》实验八实验报告
1.实验内容
1.1 Web 前端 HTML
完成 Apache 服务的安装与启停操作,理解 HTML 表单及 GET、POST 提交方法的区别,并编写包含登录表单的 HTML 页面;
1.2 Web 前端 JavaScript
掌握 JavaScript 基本功能与 DOM 操作,在上述 HTML 表单基础上编写用户名、密码的验证规则(如非空、长度限制等),实现点击登录按钮后回显 “欢迎 + 用户名” 的效果,并尝试通过回显用户名注入 HTML、JavaScript 代码,测试前端 XSS 漏洞;
1.3 Web 后端 MySQL 基础
完成 MySQL 的安装与启动,实操数据库、用户的创建,密码修改及数据表的新建等基础操作;
1.4 Web 后端 PHP 开发
编写 PHP 网页,实现与 MySQL 数据库的连接,并完成用户账号密码的后端认证功能;
1.5 基础漏洞测试
针对编写的 PHP 认证页面,开展最简单的 SQL 注入、XSS 攻击测试;
1.6 漏洞平台实操
安装 DVWA 或 WebGoat 漏洞测试平台,在平台内完成 SQL 注入、XSS、CSRF 三类常见 Web 漏洞的复现测试。
2.实验过程
2.1 Web前端
2.1.1 HTML前置准备
# 创建目标目录
mkdir -p /var/www/websec/{html,logs,config}
# 注:若系统无/var/www目录,先创建:mkdir -p /var/www
cd /var/www/websec/html
# 设置目录权限
chmod -R 755 /var/www/http/websec
chown -R www-data:www-data /var/www/http/websec
确保 Kali 网络正常,更新依赖:
apt update && apt upgrade -y
2.1.2 安装并启停 Apache
apt install apache2 -y
核心操作命令:
启动 Apache:systemctl start apache2
停止 Apache:systemctl stop apache2
重启 Apache:systemctl restart apache2
设置开机自启:systemctl enable apache2
查看运行状态:systemctl status apache2
(显示active (running)即为正常运行)
验证 Apache 服务可用性
打开浏览器访问以下地址之一:
本地访问:http://127.0.0.1 或 http://localhost
局域网访问:http://Kali本机IP
看到 Apache 默认欢迎页面,说明服务正常。

2.1.3 编写含表单的 HTML 文件
创建login.html:
vim /var/www/websec/html/login.html
写入以下代码(支持 GET/POST 切换,表单提交到自身后续结合 JS/PHP 处理):
<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><title>用户登录</title><style>.form-item { margin: 10px 0; }label { display: inline-block; width: 80px; }.error { color: red; }</style>
</head>
<body><h1>用户登录</h1><div class="error" id="errorMsg"></div> <!-- 错误提示区域 --><!-- 表单:默认POST方法,提交到自身(后续PHP会接管处理) --><form id="loginForm" method="POST" action="login.html"><div class="form-item"><label>用户名:</label><input type="text" name="username" id="username" required placeholder="请输入用户名"></div><div class="form-item"><label>密码:</label><input type="password" name="password" id="password" required placeholder="请输入密码"></div><!-- 可选:切换GET/POST方法(用于理解两种提交方式差异) --><div class="form-item"><label>提交方式:</label><input type="radio" name="method" value="POST" checked> POST<input type="radio" name="method" value="GET"> GET</div><div class="form-item"><button type="submit" id="loginBtn">登录</button></div></form><!-- 后续JS代码会插入此处 -->
</body>
</html>
2.1.4 测试 HTML 表单访问
浏览器访问:http://127.0.0.1/websec/html/login.html
能看到登录表单,此时点击登录会因无后端处理而刷新页面,后续步骤完善功能

2.2 Web 前端 JavaScript
2.2.1 理解 JavaScript 核心功能
表单验证:检查用户名 / 密码格式合法性(前端基础校验)
DOM 操作:获取输入框值、修改页面元素(如错误提示、登录回显)
提交方式切换:根据单选框切换表单的 GET/POST 方法
2.2.2 编写代码(为了方便回退2.1的代码,我新建了login2.html)
<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><title>用户登录</title><style>.form-item { margin: 10px 0; }label { display: inline-block; width: 80px; }.error { color: red; font-weight: bold; }.welcome { color: green; margin-top: 20px; }</style>
</head>
<body><h1>用户登录</h1><div class="error" id="errorMsg"></div> <!-- 错误提示区域 --><!-- 表单:action暂时留空,先完成前端验证演示 --><form id="loginForm" method="POST" action=""><div class="form-item"><label>用户名:</label><input type="text" name="username" id="username" required placeholder="3-10位字符"></div><div class="form-item"><label>密码:</label><input type="password" name="password" id="password" required placeholder="6-16位字符"></div><div class="form-item"><label>提交方式:</label><input type="radio" name="method" value="POST" checked> POST<input type="radio" name="method" value="GET"> GET</div><div class="form-item"><button type="submit" id="loginBtn">登录</button></div></form><script>// 等待整个DOM加载完成后再执行JS(避免找不到元素)document.addEventListener('DOMContentLoaded', function() {// 获取表单元素(提前获取,避免重复查询DOM)const loginForm = document.getElementById('loginForm');const usernameInput = document.getElementById('username');const passwordInput = document.getElementById('password');const errorMsg = document.getElementById('errorMsg');// 监听表单提交事件loginForm.addEventListener('submit', function(e) {e.preventDefault(); // 阻止表单默认提交(前端演示无需提交)// 1. 获取并清理输入值const username = usernameInput.value.trim();const password = passwordInput.value.trim();const selectedMethod = document.querySelector('input[name="method"]:checked').value;// 2. 清空之前的错误提示和欢迎信息errorMsg.textContent = '';const oldWelcome = document.querySelector('.welcome');if (oldWelcome) oldWelcome.remove(); // 移除之前的回显,避免重复// 3. 表单验证规则let isValid = true;if (username === '') {errorMsg.textContent = '用户名不能为空!';isValid = false;} else if (username.length < 3 || username.length > 30) {errorMsg.textContent = '用户名必须为3-30位字符!';isValid = false;}if (isValid && password === '') {errorMsg.textContent = '密码不能为空!';isValid = false;} else if (isValid && (password.length < 6 || password.length > 16)) {errorMsg.textContent = '密码必须为6-16位字符!';isValid = false;}// 4. 验证通过:显示欢迎信息(保留XSS漏洞用于测试)if (isValid) {// 创建欢迎容器,添加样式类const welcomeDiv = document.createElement('div');welcomeDiv.className = 'welcome'; // 用于后续移除重复回显// 直接插入HTML(存在XSS漏洞,后续测试用)welcomeDiv.innerHTML = `<h3>欢迎,${username}!提交方式:${selectedMethod}</h3>`;loginForm.after(welcomeDiv);}});});</script>
</body>
</html>
保存后,浏览器访问:http://localhost/websec/login2.html

输入合法用户名与密码


POST与GET两种方式均登录成功。
2.2.3 HTML 注入
之前的 JS 代码用 welcomeDiv.innerHTML = 用户名 渲染内容,并未过滤特殊字符,因此直接输入 HTML 标签或 JS 代码会被浏览器当作合法代码执行,这就是 XSS 注入。
用户名框输入<h1>篡改成功</h1>
密码框输入合法值,如 123456
点击「登录」


页面显示「篡改成功」大标题,注入生效~
2.2.4 JS 注入
用户名框输入<img src=x onerror=alert(1)>
密码框输入 123456;
点击「登录」

浏览器弹出「1」提示框


JS 注入成功。
2.3 Web 后端:MySQL
2.3.1 启用Kali 默认预装 MariaDB(MySQL 分支)
# 启动MariaDB(等同于MySQL)
systemctl start mariadb
# 设置开机自启
systemctl enable mariadb
# 查看状态(active running为正常)
systemctl status mariadb

2.3.2 初始化 MySQL
执行安全脚本,按提示配置:
mysql_secure_installation
配置流程:
初始 root 密码为空,直接按回车;
询问 “是否设置 root 密码”,输入Y,设置密码
后续询问 “是否移除匿名用户”“是否禁止 root 远程登录”“是否删除 test 数据库”,全部输入Y(生产环境推荐配置);
最后输入Y保存配置。
2.3.3 MySQL 基础操作
登录 MySQL
mysql -u root -p

登录成功后,命令行提示符变为MariaDB [(none)]>
创建数据库(websec_db)
CREATE DATABASE IF NOT EXISTS websec_db CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
验证:SHOW DATABASES;

能看到websec_db,说明创建成功
创建数据库用户(websec_user)
创建用于 PHP 连接的用户(避免直接使用 root):
-- 创建本地用户(仅允许127.0.0.1访问),密码websec@123
CREATE USER 'websec_user'@'127.0.0.1' IDENTIFIED BY 'websec@123';
-- 授予用户对websec_db的所有权限
GRANT ALL PRIVILEGES ON websec_db.* TO 'websec_user'@'127.0.0.1';
-- 刷新权限生效
FLUSH PRIVILEGES;
验证:SELECT user, host FROM mysql.user;

能看到websec_user,说明创建成功
切换数据库并创建用户表(users)
USE websec_db; # 切换到目标数据库
-- 创建用户表(存储用户名和密码)
CREATE TABLE IF NOT EXISTS users (id INT PRIMARY KEY AUTO_INCREMENT, # 自增ID(主键)username VARCHAR(50) NOT NULL UNIQUE, # 用户名(唯一,不可重复)password VARCHAR(255) NOT NULL, # 密码(后续存储加密后的字符串)create_time DATETIME DEFAULT CURRENT_TIMESTAMP # 创建时间(默认当前时间)
);

验证:DESCRIBE users;

能看到表结构,说明创建成功。
插入测试数据,用于后续 PHP 认证
-- 插入测试用户(密码123456,后续PHP中会用MD5加密存储,此处先存加密后的值)
INSERT INTO users (username, password) VALUES ('testuser', MD5('123456'));
验证:SELECT * FROM users;

能看到testuser和对应的 MD5 加密密码,说明创建成功
为websec_user用户授予从localhost访问websec_db数据库的全部权限,并指定密码
# 授权websec_user从localhost访问websec_db数据库
GRANT ALL PRIVILEGES ON websec_db.* TO 'websec_user'@'localhost' IDENTIFIED BY 'websec@123';
# 刷新权限生效
FLUSH PRIVILEGES;

退出 MySQL
EXIT; # 或 Ctrl+D

2.4 Web 后端:PHP 连接 MySQL 实现用户认证
2.4.1 安装 PHP 及 MySQL 扩展
Kali 默认可能未安装 PHP,执行以下命令安装(适配 Apache+MySQL):
apt install php libapache2-mod-php php-mysql -y
# 重启Apache使PHP模块生效
systemctl restart apache2

2.4.2 编写 PHP 认证文件(login.php)
创建login.php(处理表单提交,连接 MySQL 验证用户):
vim /var/www/http/websec/html/login.php
写入以下代码(注意:初始版本为有 SQL 注入漏洞的代码,用于后续测试):
<?php
// 1. 接收表单提交的数据(POST/GET)
$username = $_REQUEST['username'] ?? ''; // 同时支持POST和GET
$password = $_REQUEST['password'] ?? '';
$method = $_REQUEST['method'] ?? 'POST';// 2. 过滤空值
if (empty($username) || empty($password)) {echo "<script>alert('用户名或密码不能为空!');history.back();</script>";exit;
}// 3. 连接MySQL数据库
$conn = mysqli_connect('127.0.0.1', // 数据库地址(本地)'websec_user', // 步骤3创建的数据库用户'websec@123', // 数据库用户密码'websec_db' // 数据库名
);// 检查连接错误
if (!$conn) {die("数据库连接失败:" . mysqli_connect_error());
}// 4. 用户认证(危险:未过滤输入,存在SQL注入漏洞)
// 原始SQL(拼接用户输入,漏洞根源)
$sql = "SELECT * FROM users WHERE username='$username' AND password=MD5('$password')";
$result = mysqli_query($conn, $sql);// 5. 验证结果处理
if (mysqli_num_rows($result) === 1) {// 认证成功:获取用户信息并回显$user = mysqli_fetch_assoc($result);echo "<h1>欢迎," . $user['username'] . "!登录成功!</h1>";echo "<p>提交方式:" . $method . "</p>";
} else {// 认证失败echo "<script>alert('用户名或密码错误!');history.back();</script>";
}// 6. 关闭数据库连接
mysqli_close($conn);
?>
保存退出。
2.4.3 修改 HTML 表单提交目标(为了方便回退2.2的代码,我新建了login4.html)
<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><title>用户登录</title><style>.form-item { margin: 10px 0; }label { display: inline-block; width: 80px; }.error { color: red; font-weight: bold; }</style>
</head>
<body><h1>用户登录</h1><!-- 仅保留错误提示容器(由后端控制提示) --><div class="error" id="errorMsg"></div> <!-- 表单直接提交到后端login.php,仅保留核心输入项 --><form id="loginForm" method="POST" action="login.php"><div class="form-item"><label>用户名:</label><input type="text" name="username" id="username" required placeholder="3-10位字符"></div><div class="form-item"><label>密码:</label><input type="password" name="password" id="password" required placeholder="6-16位字符"></div><div class="form-item"><label>提交方式:</label><input type="radio" name="method" value="POST" checked> POST<input type="radio" name="method" value="GET"> GET</div><div class="form-item"><button type="submit" id="loginBtn">登录</button></div></form><script>// 仅保留必要的DOM加载监听,移除所有前端验证逻辑document.addEventListener('DOMContentLoaded', function() {const loginForm = document.getElementById('loginForm');// 仅阻止默认提交后直接提交到后端(无前端验证/回显)loginForm.addEventListener('submit', function(e) {e.preventDefault(); // 阻止默认提交,统一提交逻辑// 直接提交表单到后端,所有验证由login.php处理this.submit();});});</script>
</body>
</html>
修改点:
(1)将表单的action改为login.php(让 PHP 处理提交):