20232412 2025-2026-1 《网络与系统攻防技术》实验八实验报告
1.实验内容
- (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攻击。
实验通过搭建完整的Web应用环境(Apache+PHP+MySQL),系统学习Web安全攻防原理。前端实现表单提交与JS验证,后端实现用户认证,重点演示SQL注入和XSS攻击的实际利用过程。通过DVWA平台实践,深入理解输入验证不足导致的安全漏洞,掌握防御措施,建立安全编程意识。
2.实验过程
2.1 Web前端HTML
在虚拟机中输入systemctl start apache2,启动Kali中自带的Apache服务,输入systemctl enable apache2,设置Apache服务开机自启,可以通过systemctl status apache2.service来确认Apache服务的状态。

在kali的浏览器中输入localhost,可以看到Apache的欢迎页面,说明Apache服务启动成功。

HTML是构建网页的基础骨架,它使用标签(tags)来定义网页的结构和内容,它是一种标记语言,不是编程语言,用标签描述内容,元素结构为<标签名 属性="值">内容</标签名>,由声明,包含、、三大部分。
这里我们输入cd /var/www/html,进入/var/www/html目录下,创建两个简单的提交表单信息的HTML文件,分别采用GET方法和POST方法。
20232412_get.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>GET表单提交</title>
</head>
<body>
<form method="get" action="">
用户名: <input type="text" name="username" required><br>
密码: <input type="password" name="password" required><br>
<input type="submit" value="提交">
</form>
</body>
</html>
20232412_post.html
<!DOCTYPE html>
<html>
<head>
<title>POST表单提交</title>
</head>
<body>
<form method="post" action="">
用户名: <input type="text" name="username" required><br>
密码: <input type="password" name="password" required><br>
<input type="submit" value="提交">
</form>
</body>
</html>
查看两种表单的实际效果,提交信息,GET方法的数据会在URL中显示,即数据直接拼接在URL中,而POST方法下数据不会在URL中显示,数据藏在请求体中。


两种方法的具体区别见下图

2.2 Web前端javascipt
JavaScript 是一种高级、解释型的编程语言,主要用于为网页添加交互性和动态行为。它最初被设计为在浏览器中运行,但现在也可在服务器端等多种环境中运行。
它的核心功能包括:
-
操作网页内容:动态更改HTML元素的内容、属性或样式
-
事件处理:响应用户操作(如点击、鼠标移动、键盘输入等)
-
数据计算与处理: 执行数学运算、逻辑判断、字符串处理等
DOM 是浏览器将HTML文档解析成的一个树形结构模型,每个HTML标签(元素、属性、文本等)都是树中的一个节点。它允许JavaScript访问和操作网页的内容、结构和样式,通过DOM提供的API,JavaScript 可以动态地查询、选择元素;修改元素属性、内容或 CSS 样式;添加或删除元素;绑定事件监听器。
修改2.1中采用GET方法的提交表单信息的HTML文件,编写JavaScript验证用户名、密码的规则。在用户点击登陆按钮后回显“欢迎+输入的用户名”。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>GET表单提交</title>
</head>
<body>
<form id="loginForm" method="get" action="">
用户名: <input type="text" name="username" id="username" required><br>
密码: <input type="password" name="password" id="password" required><br>
<input type="submit" value="登录">
</form>
<div id="message"></div>
<script>
document.getElementById('loginForm').addEventListener('submit', function(event) {
event.preventDefault(); // 阻止表单默认提交
var username = document.getElementById('username').value.trim(); // 去除首尾空格
var password = document.getElementById('password').value;
// 用户名验证:不能为空
if (username === '') {
document.getElementById('message').innerHTML = '用户名不能为空';
document.getElementById('message').style.color = 'red';
return;
}
// 密码验证:6-30个字符,至少包含一个字母和一个数字
var passwordRegex = /^(?=.*[A-Za-z])(?=.*\d).{6,30}$/;
if (!passwordRegex.test(password)) {
document.getElementById('message').innerHTML = '密码必须为6-30个字符,且包含字母和数字';
document.getElementById('message').style.color = 'red';
return;
}
document.getElementById('message').innerHTML = '欢迎 ' + username + '!';
document.getElementById('message').style.color = 'black';
});
</script>
</body>
</html>
输入用户名和密码后,能正确回显“欢迎+输入的用户名”

用户名、密码不符合格式会提示。

尝试注入攻击:利用回显用户名注入HTML及JavaScript:
在用户名一栏输入<span style="color:red;font-size:24px;font-weight:bold;">HACKED</span>,将显示显示红色、大字体的"HACKED",而不是正常用户名,说明HTML注入攻击成功。

在用户名一栏输入<img src="x" onerror="alert('XSS攻击成功')">,进行事件处理器攻击,因为图片加载失败,触发onerror事件,执行JavaScript,弹出弹窗,JavaScript注入攻击成功。

2.3 Web后端:MySQL基础:正常安装、启动MySQL,建库、创建用户、修改密码、建表
输入systemctl start mysql启动MySQL,并通过systemctl status mysql确认已启动。

输入以下内容,进行建库、创建用户、修改密码、建表
sudo mysql -u root -p
-- 创建数据库
CREATE DATABASE db_20232412;
-- 查看所有数据库
SHOW DATABASES;
-- 使用创建的数据库
USE db_20232412;
-- 创建用户
CREATE USER 'user_20232412'@'localhost' IDENTIFIED BY '20232412';
-- 查看用户
SELECT user, host FROM mysql.user;
-- 授予用户对数据库的所有权限
GRANT ALL PRIVILEGES ON db_20232412.* TO 'user_20232412'@'localhost';
FLUSH PRIVILEGES;
-- 使用ALTER USER修改密码
ALTER USER 'user_20232412'@'localhost' IDENTIFIED BY 'NewPassword20232412';
-- 创建学生表
CREATE TABLE students (
id INT PRIMARY KEY AUTO_INCREMENT,
student_id VARCHAR(20) NOT NULL,
name VARCHAR(50) NOT NULL,
age INT,
class VARCHAR(50)
);
-- 插入学生数据
INSERT INTO students (student_id, name, age, class) VALUES
('111', '张三', 20, '一班'),
('222', '李四', 21, '二班'),
('333', '王五', 19, '三班');
-- 查看所有表
SHOW TABLES;
-- 查询数据
SELECT * FROM students;
部分截图如下:
建库:

创建用户:

修改密码:

建表:

2.4 Web后端:编写PHP网页,连接数据库,进行用户认证
建立用户表,输入SELECT * FROM users;,查看表中信息。

创建数据库配置文件check.php
<?php
$host = 'localhost';
$dbname = 'db_20232412';
$user = 'user_20232412';
$password = 'NewPassword20232412';
// 连接数据库
$conn = new mysqli($host, $user, $password, $dbname);
// 检查连接是否成功
if ($conn->connect_error) {
die("数据库连接失败: " . $conn->connect_error);
}
// 获取 GET 数据
$username = $_GET['username'];
$password_input = $_GET['password'];
// 使用查询语句进行查询(修改表名和字段名)
$sql = "SELECT * FROM users WHERE username='$username' AND password='$password_input'";
$result = $conn->query($sql);
// 检查是否有匹配的记录
if ($result->num_rows > 0) {
echo "欢迎登录: " . $username . "!";
} else {
echo "用户名或密码错误";
}
// 关闭结果集
$result->close();
// 关闭数据库连接
$conn->close();
?>
根据2.2中的HTML文件,将action属性改为PHP文件路径,新建login.html
<!DOCTYPE html>
<html>
<head>
<title>GET表单提交</title>
<meta charset="UTF-8">
</head>
<body>
<form method="get" action="check.php" onsubmit="return validateForm()">
用户名: <input type="text" name="username" id="username" required><br>
密码: <input type="password" name="password" id="password" required><br>
<input type="submit" value="登录">
<div id="greeting"></div>
</form>
<script>
function validateForm() {
const username = document.getElementById('username').value.trim();
const password = document.getElementById('password').value;
// 用户名验证:不能为空
if (username === '') {
alert('错误:用户名不能为空!');
document.getElementById('username').focus();
return false;
}
// 密码验证:长度6-30个字符
if (password.length < 6 || password.length > 30) {
alert('错误:密码长度必须为6-30个字符!');
document.getElementById('password').focus();
return false;
}
// 密码验证:至少包含一个字母和一个数字
const hasLetter = /[a-zA-Z]/.test(password);
const hasNumber = /\d/.test(password);
if (!hasLetter || !hasNumber) {
alert('错误:密码必须包含至少一个字母和一个数字!');
document.getElementById('password').focus();
return false;
}
// 所有验证通过
alert('验证通过,正在提交表单...');
return true;
}
</script>
</body>
</html>
输入的用户名和密码符合规范,能弹出弹窗,用户名和密码正确时,能正确回显“欢迎+输入的用户名”


输入错误时,会提示错误

2.5 最简单的SQL注入,XSS攻击测试
在登录表单中尝试输入用户名:admin_20232412' OR '1'='1,密码为任意值,能构造成SELECT * FROM users WHERE username='admin_20232412' OR '1'='1' AND password='test',绕过密码验证。

在登录表单中尝试以下输入用户名:<script>alert("XSS attack.");</script>,密码为' OR '1'='1,网页弹出窗口实现简单的XSS攻击。

2.6 安装DVWA或WebGoat平台,并完成SQL注入、XSS、CSRF攻击
在主机上安装dvwa,默认用户名和密码是admin和password,在DVWA Security中将难度改为Low。
(1)完成SQL注入攻击
输入1' UNION SELECT null,CONCAT('学号:[20232412]',user,':',password) FROM users-- ,提交后页面会显示数据库中的用户名密码,这是因为进行了SQL注入,最终执行的SQL为SELECT id, name FROM students WHERE id = '1' UNION SELECT null, CONCAT('学号:[20232412]',user,':',password) FROM users--'

(2)完成XSS攻击
在输入框中输入<script>alert('XSS-[20232412]');</script>提交后会有弹窗,完成反射型XSS攻击

在留言板(Name/Message)中输入<svg onload=alert('StoredXSS-[20232412]')>,提交后会有弹窗,完成存储型XSS攻击

(3)完成CSRF攻击
修改密码时,可以看到URL中会显示修改内容,可以判断是GET方法。

在URL中修改,password_new中输入123456,在password_conf中输入20232412,按下回车会提示Passwords did not match.。

直接在URL中作修改,将password_conf也改为123456,可以看到密码修改成功,攻击成功

3.问题及解决方案
- 问题1:HTML文件里的中文在kali浏览器打开时会变成乱码
- 问题1解决方案:在HTML文件的头部(head)部分添加,指定文档使用UTF-8字符编码,能确保多语言字符正确显示,避免乱码问题。
- 问题2:不了解HTML和php文件的编写
- 问题2解决方案:通过查询AI,学会了HTML的跳转,并且基本明白了如何与数据库进行连接并比对数据。
4.学习感悟、思考等
通过本次实验,我深刻认识到Web安全的重要性。从HTML表单、JavaScript验证到PHP连接数据库的完整流程,让我理解了前后端协同工作原理。在SQL注入测试中,简单的' OR '1'='1可以绕过认证,这警示我参数化查询的必要性。XSS攻击实验更直观展示了未过滤用户输入的危害——恶意脚本能被直接执行。利用DVWA平台学习攻击,我既掌握了攻击手段,也在反思如何避免受到攻击,必须始终坚持永“不信任用户输入”的原则,对所有输入进行严格验证和转义。本次实验将理论知识转化为实践认知,强化了我的安全编码意识,让我更加重视了网络安全。

浙公网安备 33010602011771号