dvwa存储型XSS

存储型XSS:会把用户输入的数据“存储”在服务器端,一般出现在需要用户可以输入数据的地方,比如网站的留言板、评论等地方,当网站这些地方过滤不严格的时候,就会被黑客注入恶意攻击代码,存储在服务器端,每当用户加载该页面时,都会受到攻击,所以这种攻击行为也称为“持久型XSS(Persistent XSS)”。

漏洞测试

low级别

​​

在Name和Message输入框中分别输入一个String(admin)发现输入的数据会显示在当前页面中,同时可以知道数据提交是以POST请求的方式

查看源码:

<?php

if( isset( $_POST[ 'btnSign' ] ) ) {
// Get input
$message = trim( $_POST[ 'mtxMessage' ] );
$name = trim( $_POST[ 'txtName' ] ); // Sanitize message input
$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)) ? "" : "")); // Sanitize name input
$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)) ? "" : "")); // Update database
$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();
} ?>

代码审计发现,并不存在Protect,trim()函数、stripslashes()函数、mysqli_real_escape_string()函数等不会对JS代码进行过滤

trim(string,charlist) 函数移除字符串两侧的空白字符或其他预定义字符。

    string    必需。规定要检查的字符串。

    charlist  可选。规定从字符串中删除哪些字符。如果被省略,则移除以下所有字符:    

        "\0" - NULL
"\t" - 制表符
"\n" - 换行
"\x0B" - 垂直制表符
"\r" - 回车
" " - 空格 ######################################################################################## stripslashes(string) 函数删除由 addslashes() 函数添加的反斜杠。 string 必需。规定要检查的字符串。 提示:该函数可用于清理从数据库中或者从 HTML 表单中取回的数据。 ######################################################################################## addslashes(string) 函数返回在预定义字符之前添加反斜杠的字符串。 预定义字符是: 单引号(')
双引号(")
反斜杠(\)
NULL
string 必需。规定要转义的字符串。 提示:该函数可用于为存储在数据库中的字符串以及数据库查询语句准备字符串。 ######################################################################################## mysql_real_escape_string(string,connection) 函数转义 SQL 语句中使用的字符串中的特殊字符。 下列字符受影响: \x00
\n
\r
\
'
"
\x1a
如果成功,则该函数返回被转义的字符串。如果失败,则返回 false。 string 必需。规定要转义的字符串。
connection 可选。规定 MySQL 连接。如果未规定,则使用上一个连接。 提示:可使用本函数来预防数据库攻击。

构造payload,执行最简单的XSS攻击

POST data
txtName=admin&mtxMessage=<script>alert("_XSS_")</script>&btnSign=Sign+Guestbook

恶意代码被存入服务端,每当用户打开该网页都会受到攻击

服务端数据库文件已存入攻击者的恶意代码

进入该网页,触发恶意攻击

medium 级别

<?php

if( isset( $_POST[ 'btnSign' ] ) ) {
// Get input
$message = trim( $_POST[ 'mtxMessage' ] );
$name = trim( $_POST[ 'txtName' ] ); // Sanitize message input
$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 ); // Sanitize name input
$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)) ? "" : "")); // Update database
$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();
} ?>

经过代码审计,可以发现medium级别进行了Protect,对POST请求到的的内容进行过滤:

str_replace()函数 对 Name data进行<script>标签匹配置空

strip_tags()函数 对 message data进行标签匹配删除

str_replace(find,replace,string,count) 函数以其他字符替换字符串中的一些字符(区分大小写)。

该函数必须遵循下列规则:

如果搜索的字符串是数组,那么它将返回数组。
如果搜索的字符串是数组,那么它将对数组中的每个元素进行查找和替换。
如果同时需要对数组进行查找和替换,并且需要执行替换的元素少于查找到的元素的数量,那么多余元素将用空字符串进行替换
如果查找的是数组,而替换的是字符串,那么替代字符串将对所有查找到的值起作用。
注释:该函数区分大小写。请使用 str_ireplace() 函数执行不区分大小写的搜索。 参数 描述
find 必需。规定要查找的值。
replace 必需。规定替换 find 中的值的值。
string 必需。规定被搜索的字符串。
count 可选。对替换数进行计数的变量。 ########################################################################################### strip_tags(string,allow) 函数剥去字符串中的 HTML、XML 以及 PHP 的标签。 注释:该函数始终会剥离 HTML 注释。这点无法通过 allow 参数改变。 参数 描述
string 必需。规定要检查的字符串。
allow 可选。规定允许的标签。这些标签不会被删除。

分析可知要想利用XSS攻击,只有对Name data进行注入,利用<script>标签大小写进行绕过,但你会发现Name data length=10 受到限制

篡改数据,绕过length限制

构造payload

POST Name data
txtName=%3CScript%3Ealert%281111%29%3C%2FscriPt%3E&mtxMessage=admin&btnSign=Sign+Guestbook

Name data的绕过

服务端数据库文件已存入攻击者的恶意代码

在这里也可以使用<img>标签进行绕过:<img src=# onerror=alert("_XSS_")>

high 级别

<?php

if( isset( $_POST[ 'btnSign' ] ) ) {
// Get input
$message = trim( $_POST[ 'mtxMessage' ] );
$name = trim( $_POST[ 'txtName' ] ); // Sanitize message input
$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 ); // Sanitize name input
$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)) ? "" : "")); // Update database
$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();
} ?>

代码审计之后,发现high级别的Name data存在另外一种的Protect,利用preg_replace()函数进行匹配“< s r i p t”等字符,将其置为空,此时Name data里面的<script>标签是不能使用的,不管是大小进行区分写都不可以进行绕过

所以,就需要利用其它标签进行XSS攻击,此处可以利用 medium 级别 中提到的<img>标签进行绕过preg_replace()函数的Protect

构造payload

POST Name data
txtName=%3Cimg+src%3D%23+onerror%3Dalert%28%22_XSS_%22%29%3E&mtxMessage=Hello+admin&btnSign=Sign+Guestbook

<img>标签成功绕过preg_replace()

服务端数据库文件已存入攻击者的恶意代码

impossible 级别

<?php

if( isset( $_POST[ 'btnSign' ] ) ) {
// Check Anti-CSRF token
checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' ); // Get input
$message = trim( $_POST[ 'mtxMessage' ] );
$name = trim( $_POST[ 'txtName' ] ); // Sanitize message input
$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 ); // Sanitize name input
$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 ); // Update database
$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();
} // Generate Anti-CSRF token
generateSessionToken(); ?>

impossible 级别的Protect不能被绕过,由于Name data和Message data都受到htmlspecialchars()函数的保护作用

htmlspecialchars() 函数把预定义的字符转换为 HTML 实体。
预定义的字符是: & (和号)成为 &
" (双引号)成为 "
' (单引号)成为 '
< (小于)成为 <
> (大于)成为 > 它的语法如下:
htmlspecialchars(string,flags,character-set,double_encode)
其中第二个参数flags需要重要注意,很多开发者就是因为没有注意到这个参数导致使用htmlspecialchars()函数过滤XSS时被绕过。因为flags参数对于引号的编码如下: 可用的引号类型: ENT_COMPAT - 默认。仅编码双引号。
ENT_QUOTES - 编码双引号和单引号。
ENT_NOQUOTES - 不编码任何引号。
默认是只编码双引号的

因为输入的所有标签都被转义,所以此处不存在XSS攻击,但是要注意flags属性,使用不当过滤XSS时就会被绕过

XSS Stored 测试的更多相关文章

  1. XSS Reflected 测试

    由于最近在做XSS方面的测试,于是找到了DVWA平台进行实验测试,通过这三篇文章让大家了解XSS方面的大概内容,这三篇文章只是把你领进XSS的大门,要想真正深入的学习XSS,你还需要去学习很多东西来提 ...

  2. 如何在SAE搭建属于自己的黑盒xss安全测试平台

    Author:雪碧 http://weibo.com/520613815 此篇文章技术含量不高,大牛不喜勿喷,Thx!写这篇文章主要是为了各位小伙伴在SAE搭建XSSING平台的时候少走点弯路(同志们 ...

  3. DVWA XSS (Stored) 通关教程

    Stored Cross Site Scripting 存储型XSS,持久化,代码是存储在服务器中的,如在个人信息或发表文章等地方,加入代码,如果没有过滤或过滤不严,那么这些代码将储存到服务器中,用户 ...

  4. xss跨站脚本测试

    测试的时候会涉及到xss测试,下面简要整理下xss的知识 xss跨站脚本特点就是能注入恶意的HTML/JS代码到用户浏览器,劫持用户会话 常用alert来验证网站存在漏洞 如果确认存在漏洞,会随着注入 ...

  5. XSS DOM 测试

    dvwa DOM XSS DOM Based XSS:是基于DOM文档对象模型的操作,通过前端脚本修改页面的DOM节点形成的XSS,该操作不与服务器端进行交互,而且代码是可见的,从前端获取到DOM中的 ...

  6. OWASP出品:Xenotix XSS漏洞测试框架及简单使用

    OWASP Xenotix XSS Exploit Framework是一个高效的跨站脚本漏洞(XSS)检测和攻击测试框架.它通过特有的三大浏览器引擎(包括Trident, WebKit和Gecko) ...

  7. XSS攻击测试代码

    '><script>alert(document.cookie)</script>='><script>alert(document.cookie)&l ...

  8. 简单的XSS手动测试

    好吧,我也是初学者,写这个随笔,主要也是为了记录,自学到的点. 简单的案例,见http://www.cnblogs.com/trhimily/p/3898915.html 总结一下主要的点: 1. u ...

  9. 如何发起、防御和测试XSS攻击,我们用DVWA来学习(上)

    XSS 全称Cross Site Scripting 即‘跨站脚本攻击’. 从其中文释义我们能直观的知道,这是一种对网站的攻击方式. 其原理在于,使用一切可能手段,将可执行脚本(scripting)植 ...

随机推荐

  1. yum的一些命令使用方法

    yum 选项 参数 yum命令是在Fedora和RedHat以及SUSE中基于rpm的软件包管理器,它可以使系统管理人员交互和自动化地更细与管理RPM软件包,能够从指定的服务器自动下载RPM包并且安装 ...

  2. FTP连接虚拟主机响应220 Welcome to www.net.cn FTP service. (解决的一个问题)

    问题场景: 使用FTP客户端连接虚拟主机时,同样的账号密码在有的网络下可以连接成功,有的网络下却一直连接不上:ftp响应“220 Welcome to www.net.cn FTP service.” ...

  3. 记录opencv编译过程

    准备学习opencv,参考了几个网页终于完成.编辑器和opencv版本都选择最新的版本. 记录过程如下 1. 下载准备: 1)         Opencv源码, 下载地址: https://sour ...

  4. SpringBoot报错:Invalid bound statement (not found)

    错误原因: 没有发现Mybatis配置文件的路径 解决方法: 检查Mapper包名与xml文件标签的namespace数据名称是否相同 <mapper namespace="com.t ...

  5. centos为docker配置加速器

    国内拉去docker镜像慢得可怜,为了解决这个问题,可为docker配置加速器. 1.修改daemon配置文件 sudo mkdir -p /etc/dockervim /etc/docker/dae ...

  6. C# yield return 和 yield break

    yield关键字用于遍历循环中,yield return用于返回IEnumerable<T>,yield break用于终止循环遍历. 以下对比了使用yield return与不使用yie ...

  7. Centos7 编译安装 Nginx PHP Mariadb Memcached 扩展 ZendOpcache扩展 (实测 笔记 Centos 7.3 + Openssl 1.1.0e + Mariadb 10.1.22 + Nginx 1.12.0 + PHP 7.1.4 + Laravel 5.4 )

    环境: 系统硬件:vmware vsphere (CPU:2*4核,内存2G,双网卡) 系统版本:CentOS-7-x86_64-Minimal-1611.iso 安装步骤: 1.准备 1.0 查看硬 ...

  8. cadence PCB板级设计

    总结PCB板框设计,定位孔的放置,以及布线区域和元件放置区域的放置,最重要的是层叠结构的设计.

  9. ML-Framework:ML.NET 0.3 带来新组件

    ML.NET在今年微软在Build 2018 会议上宣布的机器学习框架现已正式推出0.3版本 https://github.com/dotnet/machinelearning/releases/ta ...

  10. 什么是shell和终端?

    目录 什么是shell? 什么是终端? 什么是shell? 当谈到命令时,我们实际上指的是shell.shell是一个接收由键盘输入的命令,并将其传递给操作系统来执行的程序.几乎所有的Linux发行版 ...