20232311 2025-2026-1 《网络与系统攻防技术》实验八实验报告
实验内容
- 安装启停Apache,理解GET与POST方法相关知识并编写含表单的HTML
- 理解JavaScript基本功能,用JS验证表单回显用户名,尝试回显注入攻击
- 安装启动MySQL,完成建库、建表等基础操作
- 编写PHP网页,实现数据库连接与用户认证功能
- 进行最简单的SQL注入和XSS攻击测试
- 安装DVWA/WebGoat,完成SQL注入、XSS、CSRF三种攻击测试
实验目的
- 掌握Apache、MySQL的基础安装与配置操作,理解HTML表单、JavaScript DOM操作及PHP与数据库的交互原理,能够编写简单的前端表单页面和后端用户认证程序;
- 通过实操SQL注入、XSS、CSRF等常见攻击手段,以及在DVWA或WebGoat专业平台上开展攻击测试,深入理解Web应用中存在的安全漏洞,提升对Web安全威胁的认知与防范意识。
实验环境
- 安装有kali镜像的VMware虚拟机,配置如下

实验过程
一、实践Web前端HTML
(一)安装、启停Apache
1、kali中apache简介
- 在Kali Linux中,Apache是默认预装的开源Web服务器软件,常用于搭建本地Web服务、测试Web应用或部署网页,也是Web安全实验的核心工具之一,具体特点与操作如下:
- systemctl status apache2:查看服务状态,正常显示“active (running)”则表示已启动。
- systemctl start apache2:启动
- systemctl stop apache2:停止
- systemctl restart apache2:重启
- 网站根目录:/var/www/html/(存放HTML/PHP等网页文件)
- 常用场景
- 存放前端HTML/JS文件:将编写的表单页面放入/var/www/html/,即可通过浏览器访问测试。
- 配合PHP运行:Kali的Apache已集成PHP环境,可直接运行后端PHP脚本(如数据库连接程序)。
- 安全测试:用于搭建测试靶机,模拟Web服务环境开展SQL注入、XSS等攻击实验。
- 优势轻量稳定、配置灵活,与Kali的安全工具链高度兼容,是Web前后端开发与安全测试的基础环境。
2、安装Apache
- 使用指令
systemctl start apache2启动Apache并使用指令systemctl status apache2查看服务状态确保已启动

- 启动服务后访问http://localhost,可看到Kali默认的Apache欢迎页。

(二)编写含有表单的HTML
1、理解HTML与表单
- HTML是构建网页的基础语言,它通过一系列标签定义网页的结构和内容,比如用
<html>包裹整个页面、<head>存放元信息、<body>承载可见内容(文字、图片、链接等)。它不是编程语言,而是标记语言,通过标签的嵌套和属性设置,让浏览器能解析并呈现出结构化的网页界面,是Web前端的基石。 - 表单(
<form>标签)是HTML中实现用户与网页交互的核心组件,它能收集用户输入的信息(如用户名、密码、选择项等)并提交到服务器。表单内包含各类表单控件,比如<input type="text">用于输入文本、<input type="password">用于密码输入、<button>用于提交按钮,还能通过method属性指定GET或POST提交方式,action属性定义数据提交的目标地址,是实现登录、注册、信息提交等功能的关键。
2、使用POST方式提交表单的HTML
- 进入kali的/var/www/html/目录下打开终端,创建使用POST方法提交表单的HTML文件。

- POST方法是HTTP协议中用于向服务器提交数据的请求方式。当表单通过POST提交时,数据会被封装在HTTP请求体中(而非暴露在URL里),不仅能传输更大量的数据,也更安全,示例如下:

3、使用GET方式提交表单的HTML
- 进入kali的/var/www/html/目录下打开终端,创建使用GET方法提交表单的HTML文件。

- 当表单用GET提交时,数据会以键值对形式拼接在URL末尾(如?keyword=20232311),可见性高且有URL长度限制,但不适合提交密码等私密信息,示例如下:

二、实践操作WEB前端JavaScript
(一)理解JavaScript的基本功能,理解DOM
- JavaScript是Web前端的核心脚本语言,具备多种基础功能:它能实现页面的动态交互,比如表单验证(检查用户名密码格式)、响应用户操作(点击按钮触发事件);可动态修改页面内容和样式,如实时更新数据、切换元素显示状态;还能发送异步请求(AJAX)与服务器交互,无需刷新页面即可获取数据,让网页从静态变为动态可交互。
- DOM(文档对象模型)是JavaScript操作HTML页面的接口,它将HTML文档转化为树形结构的对象模型,每个HTML元素都是树上的“节点”。JavaScript通过DOM API(如getElementById()、innerHTML)能精准定位、读取或修改这些节点的内容、属性和样式,比如获取输入框的值、动态添加新元素,正是借助DOM,JavaScript才能与HTML页面“对话”并实现交互逻辑。
(二)利用JavaScript完善上一步完成的网页
1、完善交互
- HTML仅能构建网页的静态结构和展示内容,无法实现动态交互逻辑,比如无法校验表单输入的合法性(如密码长度是否合规)、无法响应用户操作(如点击按钮后实时反馈)、无法动态修改页面内容(如登录后回显用户名);而JavaScript作为脚本语言,能通过DOM操作HTML元素、处理事件、实现数据校验与动态交互,让网页从“静态展示”变为“可交互的动态应用”,弥补了HTML只能“呈现”不能“交互”的短板,满足用户对网页实时响应、数据验证、动态更新的需求。
- 先通过DOM获取表单及相关元素,绑定表单提交与输入框聚焦事件;对用户名(非空)、密码(6-16 位)做格式验证并显示对应错误提示;验证通过后回显欢迎用户名的信息,同时在输入框聚焦时自动隐藏错误提示


2、查看网页
- 非空校验会提示用户填写用户名/密码,密码长度校验会检查是否符合6-16位要求,均校验通过的话表单信息合规后回显“欢迎 [用户名]”的登录成功提示




(三)尝试注入攻击
1、利用回显用户名注入HTML
- 使用innerHTML来渲染回显的用户名,而innerHTML会将输入的内容作为HTML代码解析执行。当在用户名输入框中填入
<h2 style="color:red;">20232311</h2>这HTML代码时,程序未对输入内容进行转义处理,直接将其插入到页面中,从而触发了HTML注入。 - 输入的HTML代码被页面解析执行,原本应作为纯文本显示的用户名,被渲染成了红色的
<h2>标题样式,导致回显区域出现了自定义样式的“20232311”文字。

2、利用回显用户名注入JavaScript
- 通过innerHTML渲染回显用户名,而innerHTML会解析并执行包含的JavaScript代码。当在用户名输入框填入
<img src="x" onerror="alert('20232311XSS注入成功!')">时,程序未对输入做转义过滤,直接将这段包含JS代码的内容插入页面:的src无效会触发onerror事件,进而执行其中的alert弹窗代码,实现了XSS注入。
- 登录后页面执行了注入的JavaScript代码,弹出了“20232311XSS 注入成功!”的提示框

三、实践操作WEB后端之MySQL实践
安装启动MySQL,建库、创建用户、修改密码、建表
- 使用指令
systemctl start mysql启动kali自带的MySQL并使用指令systemctl status mysql查看服务状态确保已启动

- 在终端输入
mysql即可进入数据库进行后续操作:
-- 尝试创建数据库20232311(因语法错误失败,后修正)
CREATE DATABASE IF NOT EXISTS 20232311 DEFAULT CHARACTER SET utf8mb4;
-- 修正后创建数据库20232311_db,指定字符集为utf8mb4
CREATE DATABASE IF NOT EXISTS 20232311_db DEFAULT CHARACTER SET utf8mb4;
-- 切换到20232311_db数据库
USE 20232311_db;
-- 创建用户'2311user',密码为'20232311'
CREATE USER '2311user' IDENTIFIED BY '20232311';
-- 授予'2311user'对20232311_db数据库的所有权限
GRANT ALL PRIVILEGES ON 20232311_db.* TO '2311user';
-- 刷新权限使授权生效
FLUSH PRIVILEGES;
-- 修改'2311user'的密码为'new20232311'
ALTER USER '2311user' IDENTIFIED BY 'new20232311';
-- 再次刷新权限
FLUSH PRIVILEGES;
-- 创建user_info表(含id、用户名、年龄等字段),指定字符集
CREATE TABLE IF NOT EXISTS user_info (
id INT PRIMARY KEY AUTO_INCREMENT COMMENT '主键ID,自增',
username VARCHAR(50) NOT NULL UNIQUE COMMENT '用户名,唯一',
age TINYINT COMMENT '年龄',
create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 向user_info表插入2条用户数据
INSERT INTO user_info (username, age)
VALUES
('wangwu', 28),
('zhaoliu', 32);
-- 查询user_info表的所有数据
SELECT * FROM user_info;
-- 创建user_auth表(含主键、用户名、密码等字段)
CREATE TABLE IF NOT EXISTS user_auth (
id INT PRIMARY KEY AUTO_INCREMENT COMMENT '主键ID',
username VARCHAR(50) NOT NULL UNIQUE COMMENT '用户名(唯一)',
password VARCHAR(255) NOT NULL COMMENT '密码(建议加密存储)',
create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 向user_auth表插入2条用户账号数据便于下一步实验操作(用户名+密码)
INSERT INTO user_auth (username, password) VALUES
('zhangsan', 'zs123'),
('lisi', 'ls123');
-- 查询user_auth表的所有数据,查看插入结果
SELECT * FROM user_auth;


四、实践操作WEB后端之编写PHP网页
(一)编写PHP文件
- 使用PHP代码完成从表单接收用户登录数据、连接MySQL数据库并进行身份认证的全流程:首先通过$_POST获取前端提交的用户名和密码,接着使用mysqli_connect连接指定数据库,然后构造SQL查询语句从user_auth表中匹配用户名对应的密码,最后根据查询结果判断用户名是否存在、密码是否正确,并返回对应的登录提示,同时在页面中回显用户输入的信息,形成完整的登录交互逻辑。

(二)用户认证登录
- 当输入数据库中存在的用户名及正确密码时,页面提示“登录成功”并回显用户名;输入不存在的用户名“2311”时,系统反馈“用户名不存在”;输入正确用户名但错误密码时,则提示“密码错误”,实现基础的用户身份校验逻辑,根据数据库中的账号信息返回对应的登录结果。



五、实践简单的SQL注入,XSS攻击测试
(一)SQL注入
- 在用户名框输入
' UNION SELECT '123' #,密码输入123,拼接后的SQL语句是:SELECT password FROM user_auth WHERE username = '' UNION SELECT '123' #'UNION SELECT '123'会额外返回一行数据,伪造一条“密码为123”的查询结果;代码会取这行数据的password,和输入的123对比,直接提示“登录成功”。这样就能同时绕过用户名和密码,直接登录成功~

(二)XSS攻击
- 在用户名框输入
' UNION SELECT '123' #<script>alert('XSS')</script>、密码框输入123 - 首先,代码会把输入的用户名拼接到SQL语句里,原本的SQL是
SELECT password FROM user_auth WHERE username = '$username',拼接后变成SELECT password FROM user_auth WHERE username = '' UNION SELECT '123' #<script>alert('XSS')</script>'。这里的UNION SELECT '123'会让SQL查询额外返回一行“密码为123”的结果,#又注释掉后面多余的内容,所以代码会误以为查到了合法用户,且对应的密码是123;接着密码框输入的也是123,代码对比密码后判定登录成功,就会把整个用户名(包括后面的)拼接到提示信息msg里并输出到页面。页面渲染时会执行这段JS代码,弹出“XSS”警告框,既通过SQL注入绕过了用户和密码校验,又利用XSS漏洞触发了恶意脚本执行,最终完成攻击。

六、安装DVWA或WebGoat平台,并完成SQL注入、XSS、CSRF攻击
(一)安装DVWA
- 使用指令
sudo apt install dvwa安装DVWA,安装完成使用命令dvwa-start打开DVWA,初始用户名密码为admin,password

- 在DVMA Security处更改为low

(二)SQL注入部分
- 参考教程SQL注入教程1和SQL注入教程2
- 步骤1:正常提交payload为1(基础测试)
- 操作在User ID输入框填1,点击提交;
- 结果:页面返回First name: admin Surname: admin;
- 目的:确认正常查询逻辑:输入合法ID时,后台能正确执行SQL并返回数据,为后续注入测试做基准。

- 步骤2:注入点判断(确认漏洞类型),这一步是为了搞清楚后台的SQL语句是怎么拼接的,决定后续怎么构造恶意payload:
- 测试1 and 1=1#:页面返回正常;
- 测试1 and 1=2#:页面仍返回正常;
- 说明不是数字型注入(如果是数字型,1 and 1=2会让条件不成立,应该无结果)。
- 测试1' and 1=1#:页面返回正常;
- 测试1' and 1=2#:页面无结果;
- 说明是字符型注入,且需要用单引号'闭合SQL语句中的字符串。
- 核心原理:#是SQL注释符,会把语句后面的内容注释掉,避免语法错误;通过and 1=1/1=2的真假,判断输入是否参与了SQL语句的逻辑运算(即是否存在注入漏洞)。


- 步骤3:字段判断(确定联合查询的列数)
- 操作:输入
1' order by 2#,页面正常;输入1' order by 3#,页面报错; - 目的:order by N是按第N列排序,报错说明不存在第3列,因此确定后台SQL查询的结果只有2列;
- 为什么要做这个:后续用UNION SELECT(联合查询)时,要求前后查询的列数必须一致,否则SQL会报错,这是联合注入的前提。


- 操作:输入
- 步骤4:获取数据库名(第一步拿关键信息)
- 操作:输入
1' UNION SELECT 1,database() from information_schema.schemata#; - 结果:页面返回Surname: dvwa(dvwa就是数据库名);
- 原理:UNION SELECT是联合查询,会把两个查询结果合并返回;1是占位符(因为第一列是first_name,填任意值即可),database()是 MySQL 函数,返回当前数据库名;information_schema是 MySQL 的系统数据库,存储着所有数据库的元数据(库名、表名、列名等)。

- 操作:输入
- 步骤5:获取表名(从数据库中找用户表)
- 操作:输入
1' UNION SELECT 1,table_name from information_schema.tables where table_schema='dvwa'#; - 结果:页面返回guestbook和users表名;
- 目的:找到存储用户数据的表(显然users表是目标),table_schema='dvwa'指定只查dvwa数据库的表。

- 操作:输入
- 步骤6:获取列名(从用户表中找关键字段)
- 操作:输入
1' UNION SELECT 1,column_name from information_schema.columns where table_schema='dvwa' and table_name='users'#; - 结果:页面返回user_id、first_name、user、password等列名;
- 目的:找到users表中存储账号(user)和密码(password)的字段,为最终获取数据做准备。

- 操作:输入
- 步骤7:获取字段中的数据
- 操作:输入
1' union select user,password from users# - 结果:返回用户名与密码数据
- 经md5验证admin的密码确为password


- 操作:输入
(三)XSS攻击部分
1、XSS(DOM)
- 通过修改URL参数将default的值改为
<script>alert('231XSS')</script>注入恶意脚本,页面会直接解析URL中的参数并在DOM中执行。

- 页面弹出了包含“231XSS”的提示框,说明DOM型XSS漏洞利用成功。

2、XSS(reflected)
- 反射型XSS是将输入的name参数直接拼接到页面响应中,未做过滤。所以只需在URL的name参数中填入恶意脚本
<script>alert('231XSS')</script>,提交后页面会执行这段脚本。

- 提交恶意脚本后,页面弹出了包含“231XSS”的提示框,说明反射型XSS漏洞利用成功,输入的脚本被页面直接执行。

3、XSS(stored)
- 存储型XSS会将用户输入(Message)永久存储到服务器,后续所有访问该页面的用户都会触发恶意脚本。所以在Message输入框中填入
<script>alert('231XSS')</script>并提交,脚本会被存储,访问页面时就会执行。

- 尝试在name框输入恶意脚本,但发现有输入限制,不能完整输入恶意脚本
- 查看页面前端代码,定位到name框的代码段,发现在前端代码中对输入长度做了限制,将这里的maxlength改为100即可完整输入恶意脚本进行尝试


- XSS攻击成功,脚本被触发弹出提示框

- 查看页面前端代码,定位到name框的代码段,发现在前端代码中对输入长度做了限制,将这里的maxlength改为100即可完整输入恶意脚本进行尝试
(四)CSFR攻击部分
- 首先进行正常的密码修改进行正常登录,密码为123456

- 构造恶意URL,将
password_new=20232311&password_conf=20232311&Change=Change这一段替换上图原来这一部分,让登录状态下的自己点击构造的恶意URL,这样服务器会默认这是管理员的合法操作,执行密码修改;

- 再次测试登录,使用原密码123456发现已经登陆失败了,使用恶意URL参数中的密码20232311发现登陆成功,说明密码被成功篡改,CSRF攻击生效。


问题及解决方案
- 问题1:在进行简单的XSS攻击的实践过程中,发现直接填写恶意脚本语句并不能出现攻击成功的现象,而是提示登陆失败的报错
- 问题1解决方案:测试的自制网页有用户名和密码校验,直接输入的XSS代码
<script>alert('XSS')</script>并不是数据库中存在的用户名,所以直接输入会被第一层校验拦截提示“用户名不存在”。所以要先通过SQL注入绕过用户名校验:让代码“误以为”这个包含XSS的字符串是“数据库中存在的用户名”;同时让返回的密码和输入的密码一致,通过密码校验,最终让XSS代码被回显执行。 - 问题2:在使用markdown撰写博客的时候,写到一半预览的时候发现博客园误执行了编辑页面的XSS代码。

- 问题2解决方案:将报告中的XSS代码加上“添加代码”注释掉
学习感悟、思考
- 通过这次Web安全实验,我深刻体会到Web安全是“攻击”“防御”的动态博弈。从编写含表单的HTML页面,到用JavaScript实现交互逻辑,再到PHP连接数据库完成用户认证,我一步步搭建起基础的Web应用;但随后的SQL注入、XSS攻击测试,又让我看到亲手搭建的系统中潜藏的致命漏洞,仅仅因为SQL语句直接拼接用户输入、页面输出未做转义处理,攻击者就能轻松绕过认证、篡改页面甚至窃取数据。这让我意识到,Web开发绝不能只关注功能实现,必须将安全意识融入每一行代码:比如用参数化查询防范SQL注入,用textContent替代innerHTML避免XSS,这些看似细微的细节,正是抵御攻击的关键“盾牌”。而攻击测试的过程,则让我学会站在攻击者视角审视系统,理解漏洞的成因与利用逻辑,这种“矛”与“盾”的思维碰撞,让我对Web安全的认知从“被动防范”升级为“主动构建安全体系”。
- 在进行DVWA的练习的时候,起初是没有头绪的,不知所措,但是好在网络上的相关博客教程比较多,通过做中学帮助理解了相关内容,是一个非常好的方法

浙公网安备 33010602011771号