XSS | 存储型 XSS 攻击

关注这个漏洞的其他相关笔记:XSS 漏洞 - 学习手册-CSDN博客

0x01:存储型 XSS —— 理论篇

存储型 XSS 又称持久型 XSS,攻击脚本将被永久的存放在目标服务器的数据库或文件中,具有很高的隐蔽性。

常见的攻击方式: 这种攻击多见于论坛、博客、留言板,攻击者在发帖过程中,将恶意脚本连同正常信息一起注入帖子的内容中。随着帖子被服务器存储下来,恶意脚本也永久地被存放在服务器的后端存储器中。当其他用户浏览这个被注入了恶意脚本的帖子时,恶意脚本会在他们的浏览器中得到执行。

其攻击流程如下图所示:

从上面的攻击流程中,我们可以看到,存储型 XSS 的攻击方式能将恶意代码永久的嵌入一个页面中,所有访问这个页面的用户都将成为受害者。如果我们能够谨慎对待不明链接,那么反射型 XSS 攻击将没有多大作为,而存储型 XSS 则不同,由于它注入在一些我们信任的页面,因此无论我们多么小心,都难免会受到攻击(谁会一直打开浏览器的源码模式抓包呀)。

0x02:存储型 XSS —— 实战篇

实验工具准备

本次实验采用的是现成的 PIKACHU 靶场,该靶场的搭建流程参考上面的链接,这里就不多说了。

0x0201:存储型 XSS 攻击

在浏览器的导航栏中输入下面的网址,访问 PIKACHU 靶场中的存储型 XSS 漏洞地址:

 http://127.0.0.1/pikachu/vul/xss/xss_stored.php

可以看到是一个留言板,我们可以写几条留言看看:

从上图可以看出来,使用不同的浏览器,在不同的时刻去查看之前的留言,都是能看到相同的内容的。

我们鼠标右击页面,查看一下网页源码:

可以发现,我们传入的内容直接回显在了 <p> 标签中。那么我们尝试留言一个 JavaScript 脚本看看呢:

 <script>alert(/You've Been Tricked/)</script>

留言之后,点击 submit 页面直接弹窗了。此时,查看一下留言板的网页源码:

可以看到,我们之前留言的 JavaScript 脚本被成功嵌入到了前端页面中,此时我们使用另一个浏览器访问当前页面,模拟其他用户的登录操作:

可以看到,其他用户一访问这个存在存储型 XSS 漏洞的站点,就收到了弹窗,证明被 XSS 攻击了。至此,存储型 XSS 攻击的全流程演示完毕。

0x0202:存储型 XSS 代码分析

下面是触发存储型 XSS 漏洞的关键代码:

<?php
 $link = connect(); // 获取数据库连接对象
 $html = '';
 if (array_key_exists("message", $_POST) && $_POST['message'] != null) {
     // 如果 POST 请求中存在 message 字段,且 message 字段不为空
     $message = escape($link, $_POST['message']); // 对传入的数据进行转义,避免 SQL 注入漏洞
     $query = "insert into message(content,time) values('$message',now())"; 
     $result = execute($link, $query);// 执行 $query 中的内容,将客户端传递的留言插入到数据库中
     if (mysqli_affected_rows($link) != 1) {
         $html .= "<p>数据库出现异常,提交失败!</p>";
     }
 }
 ?>
 ​
 <div id="xsss_main">
     <p class="xsss_title">我是一个留言板:</p>
         <form method="post">
             // 用户留言的地方,在 textarea 中填写留言后,点击 submit 即可以 POST 方式提交到当前页面,后续会被直接插入到数据库中
             <textarea class="xsss_in" name="message"></textarea><br />
             <input class="xsss_submit" type="submit" name="submit" value="submit" />
         </form>
         <div id="show_message"><br /><br />
             <p class="line">留言列表:</p>
             <?php 
             echo $html;
             $query = "select * from message";
             $result = execute($link, $query); // 查询数据库中存放的所有留言
             while ($data = mysqli_fetch_assoc($result)) { 
                 // 遍历查询出来的结果,并拼接回显
                 echo "<p class='con'>{$data['content']}</p><a href='xss_stored.php?id={$data['id']}'>删除</a>"; // 将数据库中的留言渲染回页面
             }
             echo $html;
             ?>
         </div>
 </div>

用户在留言板中留言后,通过 <form> 表单,将数据传递给后端,后端接收到用户的数据后,使用自己编写的 escape() 函数对用户传入的内容进行了转义,从而避免了 SQL 注入攻击。转义完成后就将用户提交的内容插入到了数据库中。在接下来的逻辑中,目标将数据库中存储的内容直接回显回了页面,没有做任何的过滤,导致出现了 XSS 漏洞。

从上面的代码分析来看,目标只在将用户提交的信息插入数据库的时候做了一次过滤,我们看一下其过滤逻辑:

 //转义,避免fuck
 function escape($link,$data){
     if(is_string($data)){
         // 传入的如果是字符串,就直接使用 mysqli_real_escape_string() 进行转义
         return mysqli_real_escape_string($link,$data);
     }
     if(is_array($data)){
         // 传入的如果是数组,则对没个元素都使用 mysqli_real_escape_string() 进行转义
         foreach ($data as $key=>$val){
             $data[$key]=escape($link,$val);
         }
     }
     return $data;
 }

mysqli_real_escape_string() 函数的定义与用法如下图所示:

可以发现该函数只转义在 SQL 语句中使用的字符串中的特殊字符。并不包括我们在 XSS 中常用的 <> 这些特殊符号,所以目标后端只对输入时的 SQL 注入做了防范,但对 XSS 并未做防御。

所以,当用户在留言板中写入 <script>alert(/You've Been Tricked/)</script>时,数据库中的数据如下图所示:

当其他用访问该留言板时,页面回显并执行了 <script>alert(/You've Been Tricked/)</script>,导致弹窗。

0x03:参考文献

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SRC_BLUE_17

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值