20232402 2025-2026-1 《网络与系统攻防技术》实验八实验报告
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 处理提交):
浙公网安备 33010602011771号