存储型XSS,顾名思义,就是会传入数据库,长久的使用,常见为留言板,用户信息资料。

LOW

审计源码

<?php
// 是否提交 btnSign
if( isset( $_POST[ 'btnSign' ] ) ) {
// 获取输入的mtxMessage和txtName
// trim() 首位去空
$message = trim( $_POST[ 'mtxMessage' ] );
$name = trim( $_POST[ 'txtName' ] ); // stripslashes() 将特殊字符前加入 \ 转义
// mysqli_real_escape_string() 转义特殊字符 NUL (ASCII 0),\n,\r,\,',"
// 对 message 特殊字符转义
$message = stripslashes( $message );
$message = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $message ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : "")); // 对 name的特殊字符进行转义
$name = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $name ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : "")); // 将message 和 name 写入到 guestbook 表中 comment 和 name 字中
$query = "INSERT INTO guestbook ( comment, name ) VALUES ( '$message', '$name' );";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' ); //mysql_close();
} ?>

对传入的messagename进行了转义,防止了SQL注入,对于XSS来说,这些转义没什么用

message内容中输入<script>alert(document.cookie)</script>

Nmae随便输入一个



点击提交



可以看到弹窗成功,这样每次刷新都会进行弹窗,为了方便我们测试,弹窗之后点击Clear Gueskbook

清楚之前的弹窗



进行清空数据

这是这是测试,反弹cookie可见另一篇博客:DVWA-XSS (DOM) DOM型跨站脚本攻击

Medium

审计源码

<?php
// 查看是否提交 btnSing
if( isset( $_POST[ 'btnSign' ] ) ) {
// 获取传入的 mtxMessage 和 txtName
// trim() 首位区控
$message = trim( $_POST[ 'mtxMessage' ] );
$name = trim( $_POST[ 'txtName' ] ); // 过滤传入 message
// addslashes() 使用反斜线引用字符串
// strip_tags() 去除HTML标签
$message = strip_tags( addslashes( $message ) );
$message = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $message ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
// 对 message 中的 HTML 标签进行实例化操作
$message = htmlspecialchars( $message ); // 对 name 进行过滤
// str_replace() 替换 <script> 为空
$name = str_replace( '<script>', '', $name );
$name = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $name ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : "")); // 跟新数据库
$query = "INSERT INTO guestbook ( comment, name ) VALUES ( '$message', '$name' );";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' ); //mysql_close();
} ?>

这里对message进行了严格的过滤,首选去除了其中的HTMl标签,让后又使用htmlspecialchars函数message进行了实例化操作

这里转到name传参,过滤了<script>标签,根据str_replace函数特性,只会过滤一次,所以这里可以进行双写绕过

测试

<scr<script>ipt>alert(document.cookie)</script>



发现只能输入10个字符,在前段做了限制,检查找到name输入框



maxlength="10"改为100



再次测试<scr<script>ipt>alert(document.cookie)</script>



可以输入,提交查看



成功弹出cookie

High

审计源码

<?php
// 判断传入的 btnSign
if( isset( $_POST[ 'btnSign' ] ) ) {
// 获取传入的 mtxMessage、txtName
$message = trim( $_POST[ 'mtxMessage' ] );
$name = trim( $_POST[ 'txtName' ] ); // 跟上次一样的过滤,message已经被封死了
$message = strip_tags( addslashes( $message ) );
$message = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $message ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
$message = htmlspecialchars( $message ); // 使用 preg_replace 正则匹配 <script> 标签
$name = preg_replace( '/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '', $name );
$name = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $name ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : "")); // 更新数据库
$query = "INSERT INTO guestbook ( comment, name ) VALUES ( '$message', '$name' );";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' ); //mysql_close();
} ?>

代码只有对name过滤的规则发生了变化,使用preg_replace<script>进行了严格的过滤

.*除了换行匹配所有,/i为不区分大小写,所以这次双写绕过也无法使用

使用<img />标签src属性自动请求特性,进行弹窗

首先修改name输入的长度



name输入<img src=1 onerror=alert(document.cookie) />



提交查看



成功弹窗

Impossible

审计源码

<?php
// 是否传入 btnSign
if( isset( $_POST[ 'btnSign' ] ) ) {
// 检查 user_token
checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' ); // 获取传入的 mtxMessage、txtName
$message = trim( $_POST[ 'mtxMessage' ] );
$name = trim( $_POST[ 'txtName' ] ); // 对message中的标签进行实例化
$message = stripslashes( $message );
$message = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $message ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
$message = htmlspecialchars( $message ); // 对name中的标签进行实例化
$name = stripslashes( $name );
$name = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $name ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
$name = htmlspecialchars( $name ); // 使用PDO方法更新数据库
$data = $db->prepare( 'INSERT INTO guestbook ( comment, name ) VALUES ( :message, :name );' );
$data->bindParam( ':message', $message, PDO::PARAM_STR );
$data->bindParam( ':name', $name, PDO::PARAM_STR );
$data->execute();
} // 生成user_token
generateSessionToken();

message和name进行了HTML实例化,检查了了user_token,使用PDO方法进行数据库查询,经典的防御

DVWA-XSS (Stored) 存储型XSS的更多相关文章

  1. 富文本存储型XSS的模糊测试之道

    富文本存储型XSS的模糊测试之道 凭借黑吧安全网漏洞报告平台的公开案例数据,我们足以管中窥豹,跨站脚本漏洞(Cross-site Script)仍是不少企业在业务安全风险排查和修复过程中需要对抗的“大 ...

  2. 风炫安全WEB安全学习第二十一节课 存储型XSS讲解

    风炫安全WEB安全学习第二十一节课 存储型XSS讲解 存储型XSS演示 存储型XSS,持久化,代码是存储在服务器中的,如在个人信息或发表文章等地方,加入代码,如果没有过滤或过滤不严,那么这些代码将储存 ...

  3. DVWA 黑客攻防演练(十一) 存储型 XSS 攻击 Stored Cross Site Scripting

    上一篇文章会介绍了反射型 XSS 攻击.本文主要是通过 dvwa 介绍存储型 XSS 攻击.存储型 XSS 攻击影响范围极大.比如是微博.贴吧之类的,若有注入漏洞,再假如攻击者能用上一篇文章类似的代码 ...

  4. DVWA之Stored XSS(存储型XSS)

    目录 Low Medium High Impossible Low 源代码: <?php if( isset( $_POST[ 'btnSign' ] ) ) { // Get input $m ...

  5. DVWA(七):XSS(stored)存储型XSS攻击

    存储型XSS : 存储XSS,会把攻击者的数据存储在服务器端,攻击行为将伴随着攻击数据一直存在.提交JS攻击代码存储到数据库然后再输出. low: 观察源码: <?php if( isset( ...

  6. 存储型XSS

    DVWA系列(二)存储型XSS https://www.imooc.com/article/284686 网络安全:存储型XSS https://blog.csdn.net/qq_41500251/a ...

  7. 利用mysql对特殊字符和超长字符会进行截断的特性 进行存储型XSS攻击——WordPress <4.1.2 & <=4.2 存储型xss

    转自:Baidu Security LabXteam http://xteam.baidu.com/?p=177 漏洞概述 本次漏洞出现两个使用不同方式截断来实现的存储型xss,一种为特殊字符截断,一 ...

  8. Coremail邮件系统存储型XSS两个

    (1):Coremail邮件系统存储型XSS之一 给受害者发送主题如下的邮件: <svg onload='img=new Image();img.src="//x55.me/geo.p ...

  9. 小白日记49:kali渗透测试之Web渗透-XSS(三)-存储型XSS、DOM型XSS、神器BEFF

    存储型XSS与DOM型XSS [XSS原理] 存储型XSS 1.可长期存储于服务器端 2.每次用户访问都会被执行js脚本,攻击者只需侦听指定端口 #攻击利用方法大体等于反射型xss利用 ##多出现在留 ...

  10. Java Web开发 - 持久型/存储型XSS漏洞

    Java Web开发 - 持久型/存储型XSS漏洞 1.什么是XSS漏洞攻击? XSS是跨站脚本攻击(Cross Site Scripting)的简称,之所以叫XSS而不是CSS相比大家都能明白了吧, ...

随机推荐

  1. XML报文解析

    /** * XML报文解析 * @param docStr */ private Map<String, Object> analysisXmlStr(String xmlStr) { t ...

  2. 杭电 oj 第几天?

    Problem Description 给定一个日期,输出这个日期是该年的第几天.   Input 输入数据有多组,每组占一行,数据格式为YYYY/MM/DD组成,具体参见sample input , ...

  3. Jmeter添加Base64Img函数支持图片转换为Base64编码

    将JmeterBase64-1.0-SNAPSHOT放置到\lib\ext下即可: 直接使用即可. 制作方式: Jar包通过IntelliJ IDEA创建maven工程后,导出package:

  4. 1903021126 申文骏 Java 第三周作业 编写代码及运行

    项目 内容 课程班级博客链接 19级信计班(本) 作业要求链接 第三周作业要求 博客名称 1903021126 申文骏 Java 第三周作业 编写代码及运行 要求 每道题要有题目,代码(使用插入代码, ...

  5. python中json的四个方法总结dumps、dump、loads、load

    json的四个方法总结dumps.dump.loads.load dump介绍 1 json .作用:将python内置类型序列化为json对象后写入文件.参数:要存储的数据以及可以用于存储的文件对象 ...

  6. vue-cli项目以script标签方式引入js的方法

    在public/index.html中强行添加script标签(可引入本地js和远程js,本地js需放在public内,不能放assets内) 在要使用这个js的地方,将相关对象添加到eslint的全 ...

  7. element-ui的确认消息弹框校验;$prompt校验

    this.$prompt('请输入您的姓名', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', inputPattern: /^.+$ ...

  8. Springboot中使用枚举

    枚举映射数据库字段 配置枚举包扫描路径 mybatis-plus: # 扫描通用枚举 type-enums-package: com.xx.**.enums 方法一:@EnumValue 和 @Jso ...

  9. 使用Jquery的.css('border')在火狐不兼容

    改成如下就可以兼容火狐.IE.谷歌(border-left-color.border-left-width等)

  10. 【Unity】检测目标是否在视线范围内(附视线范围扇形画法)

    检测目标是否在视线范围内(附视线范围扇形画法) using UnityEngine; public class Test_CanSeeTarget : MonoBehaviour { public G ...