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虚拟机,配置如下
    屏幕截图 2025-11-24 194850

实验过程

一、实践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查看服务状态确保已启动
    屏幕截图 2025-11-25 122111
  • 启动服务后访问http://localhost,可看到Kali默认的Apache欢迎页。
    屏幕截图 2025-11-25 122201

(二)编写含有表单的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文件。
    屏幕截图 2025-11-25 122656
  • POST方法是HTTP协议中用于向服务器提交数据的请求方式。当表单通过POST提交时,数据会被封装在HTTP请求体中(而非暴露在URL里),不仅能传输更大量的数据,也更安全,示例如下:
    屏幕截图 2025-11-25 123022

3、使用GET方式提交表单的HTML

  • 进入kali的/var/www/html/目录下打开终端,创建使用GET方法提交表单的HTML文件。
    屏幕截图 2025-11-25 122709
  • 当表单用GET提交时,数据会以键值对形式拼接在URL末尾(如?keyword=20232311),可见性高且有URL长度限制,但不适合提交密码等私密信息,示例如下:
    屏幕截图 2025-11-25 122818

二、实践操作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 位)做格式验证并显示对应错误提示;验证通过后回显欢迎用户名的信息,同时在输入框聚焦时自动隐藏错误提示
    屏幕截图 2025-11-25 150317
    屏幕截图 2025-11-25 150301

2、查看网页

  • 非空校验会提示用户填写用户名/密码,密码长度校验会检查是否符合6-16位要求,均校验通过的话表单信息合规后回显“欢迎 [用户名]”的登录成功提示
    屏幕截图 2025-11-25 124739
    屏幕截图 2025-11-25 124748
    屏幕截图 2025-11-25 124758
    屏幕截图 2025-11-25 124806

(三)尝试注入攻击

1、利用回显用户名注入HTML

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

2、利用回显用户名注入JavaScript

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

三、实践操作WEB后端之MySQL实践

安装启动MySQL,建库、创建用户、修改密码、建表

  • 使用指令systemctl start mysql启动kali自带的MySQL并使用指令systemctl status mysql查看服务状态确保已启动
    屏幕截图 2025-11-25 130435
  • 在终端输入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;

屏幕截图 2025-11-25 131511
屏幕截图 2025-11-25 131809

四、实践操作WEB后端之编写PHP网页

(一)编写PHP文件

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

(二)用户认证登录

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

五、实践简单的SQL注入,XSS攻击测试

(一)SQL注入

  • 在用户名框输入' UNION SELECT '123' #,密码输入123,拼接后的SQL语句是:SELECT password FROM user_auth WHERE username = '' UNION SELECT '123' #' UNION SELECT '123'会额外返回一行数据,伪造一条“密码为123”的查询结果;代码会取这行数据的password,和输入的123对比,直接提示“登录成功”。这样就能同时绕过用户名和密码,直接登录成功~
    屏幕截图 2025-11-25 134257

(二)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漏洞触发了恶意脚本执行,最终完成攻击。
    屏幕截图 2025-11-25 141922

六、安装DVWA或WebGoat平台,并完成SQL注入、XSS、CSRF攻击

(一)安装DVWA

  • 使用指令sudo apt install dvwa安装DVWA,安装完成使用命令dvwa-start打开DVWA,初始用户名密码为admin,password
    屏幕截图 2025-11-25 142333
  • 在DVMA Security处更改为low
    屏幕截图 2025-11-25 142935

(二)SQL注入部分

  • 参考教程SQL注入教程1SQL注入教程2
  • 步骤1:正常提交payload为1(基础测试)
    • 操作在User ID输入框填1,点击提交;
    • 结果:页面返回First name: admin Surname: admin;
    • 目的:确认正常查询逻辑:输入合法ID时,后台能正确执行SQL并返回数据,为后续注入测试做基准。
      屏幕截图 2025-11-25 143418
  • 步骤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语句的逻辑运算(即是否存在注入漏洞)。
      屏幕截图 2025-11-25 143604
      屏幕截图 2025-11-25 143624
  • 步骤3:字段判断(确定联合查询的列数)
    • 操作:输入1' order by 2#,页面正常;输入1' order by 3#,页面报错;
    • 目的:order by N是按第N列排序,报错说明不存在第3列,因此确定后台SQL查询的结果只有2列;
    • 为什么要做这个:后续用UNION SELECT(联合查询)时,要求前后查询的列数必须一致,否则SQL会报错,这是联合注入的前提。
      屏幕截图 2025-11-25 143654
      屏幕截图 2025-11-25 143714
  • 步骤4:获取数据库名(第一步拿关键信息)
    • 操作:输入1' UNION SELECT 1,database() from information_schema.schemata#;
    • 结果:页面返回Surname: dvwa(dvwa就是数据库名);
    • 原理:UNION SELECT是联合查询,会把两个查询结果合并返回;1是占位符(因为第一列是first_name,填任意值即可),database()是 MySQL 函数,返回当前数据库名;information_schema是 MySQL 的系统数据库,存储着所有数据库的元数据(库名、表名、列名等)。
      屏幕截图 2025-11-25 143755
  • 步骤5:获取表名(从数据库中找用户表)
    • 操作:输入1' UNION SELECT 1,table_name from information_schema.tables where table_schema='dvwa'#;
    • 结果:页面返回guestbook和users表名;
    • 目的:找到存储用户数据的表(显然users表是目标),table_schema='dvwa'指定只查dvwa数据库的表。
      屏幕截图 2025-11-25 143812
  • 步骤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)的字段,为最终获取数据做准备。
      屏幕截图 2025-11-25 143914
  • 步骤7:获取字段中的数据
    • 操作:输入1' union select user,password from users#
    • 结果:返回用户名与密码数据
    • 经md5验证admin的密码确为password
      屏幕截图 2025-11-25 144219
      屏幕截图 2025-11-25 144314

(三)XSS攻击部分

1、XSS(DOM)

  • 通过修改URL参数将default的值改为<script>alert('231XSS')</script>注入恶意脚本,页面会直接解析URL中的参数并在DOM中执行。
    屏幕截图 2025-11-25 144505
  • 页面弹出了包含“231XSS”的提示框,说明DOM型XSS漏洞利用成功。
    屏幕截图 2025-11-25 144558

2、XSS(reflected)

  • 反射型XSS是将输入的name参数直接拼接到页面响应中,未做过滤。所以只需在URL的name参数中填入恶意脚本<script>alert('231XSS')</script>,提交后页面会执行这段脚本。
    屏幕截图 2025-11-25 144626
  • 提交恶意脚本后,页面弹出了包含“231XSS”的提示框,说明反射型XSS漏洞利用成功,输入的脚本被页面直接执行。
    屏幕截图 2025-11-25 144653

3、XSS(stored)

  • 存储型XSS会将用户输入(Message)永久存储到服务器,后续所有访问该页面的用户都会触发恶意脚本。所以在Message输入框中填入<script>alert('231XSS')</script>并提交,脚本会被存储,访问页面时就会执行。
    屏幕截图 2025-11-25 144842
  • 尝试在name框输入恶意脚本,但发现有输入限制,不能完整输入恶意脚本
    屏幕截图 2025-11-25 144929
    • 查看页面前端代码,定位到name框的代码段,发现在前端代码中对输入长度做了限制,将这里的maxlength改为100即可完整输入恶意脚本进行尝试
      屏幕截图 2025-11-25 145115
      屏幕截图 2025-11-25 145322
    • XSS攻击成功,脚本被触发弹出提示框
      屏幕截图 2025-11-25 145355

(四)CSFR攻击部分

  • 首先进行正常的密码修改进行正常登录,密码为123456
    屏幕截图 2025-11-25 145723
  • 构造恶意URL,将password_new=20232311&password_conf=20232311&Change=Change这一段替换上图原来这一部分,让登录状态下的自己点击构造的恶意URL,这样服务器会默认这是管理员的合法操作,执行密码修改;
    屏幕截图 2025-11-25 145822
  • 再次测试登录,使用原密码123456发现已经登陆失败了,使用恶意URL参数中的密码20232311发现登陆成功,说明密码被成功篡改,CSRF攻击生效。
    屏幕截图 2025-11-25 145833
    屏幕截图 2025-11-25 145847

问题及解决方案

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

学习感悟、思考

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