存储型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. 关于Windows系统TCP参数修改

    在做压测时,往往会因为TCP连接数较少,导致并发数上不去就报错,下面我们一起看看如何修改Windows的TCP参数 1.本地注册表 打开注册表快捷键:Windows+R建,输入regedit,按下键盘 ...

  2. centos7编译安装LNMP服务架构

    CentOS7.4 源码编译安装LNMP  1.基于CentOS7.4源码编译安装得lnmp 系统环境CentOS 7.4 系统最小化安装,只安装了一些常用包(vim.lirzs.gcc*.wget. ...

  3. PHP myadmin 无路径getshell

    PHP>5 & MySQl>5 环境:windows下常规的集成环境如 phpstudy,wamp,xampp等. 条件:当已经用弱口令或者爆破登录myadmin以后,没登录进入就 ...

  4. mongodb地理位置坐标加了索引,操作时报错 Location object expected, location array not in correct format

    别犹豫了,将坐标中的数据改为数字类型即可,如: location:[113.45,34,191]

  5. postgresql--column must appear in the group by clause or be used in an aggregate function

    我想得到大于男女平均年龄的人 原表: 在gauss200下执行以下语句: SELECT stname,age,gender,AVG(age) FROM att_test01 GROUP BY gend ...

  6. infoq上看视频1(持续更新)

    打破工程师思维 http://www.infoq.com/cn/presentations/break-engineer-thinking 百姓网人: 从技术走向产品的那点儿事 http://www. ...

  7. 作业三:CART回归树算法

    作业三:CART回归树算法 班级:20大数据(3)班 学号:201613341 题目一 表1为拖欠贷款人员训练样本数据集,使用CART算法基于该表数据构造决策树模型,并使用表2中测试样本集确定剪枝后的 ...

  8. html-list

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  9. VS2019创建WebAPI,本地发布WebAPI

    一.创建WebAPI 1.打开VS2019->创建新项目 2.ASP.NET Web应用程序->下一步 3.注意:.NET Framework版本必须高于4.0以上 4.选择"W ...

  10. C#使用JSON相关

    一.Json字符串转换为Dictionary /// <summary> /// JSON字符串转为 Dictionary /// </summary> /// <typ ...