dvwa XSS存储型(Stored)

存储型XSS

攻击者事先将恶意代码上传或储存到漏洞服务器中,只要受害者浏览包含此恶意代码的页面就会执行恶意代码。这就意味着只要访问了这个页面的访客,都有可能会执行这段恶意脚本,因此储存型XSS的危害会更大。因为存储型XSS的代码存在于网页的代码中,可以说是永久型的。存储型 XSS 一般出现在网站留言、评论、博客日志等交互处,恶意脚本存储到客户端或者服务端的数据库中。

 

DVWA中存储型XSS分四个等级, 分别是low、middle、high、impossible

 

首先有些标签限制了输入长度,可以修改标签里面maxlength属性修改输入限制

如:

 

 

 

Low:

先观察源码

这个级别对输入进行了部分特殊字符校验,没有对script标签校验。使用mysqli_real_escape_string转义部分特殊字符,影响\x00\n\r\'"\x1a。

可以看到最终是存储到mysql数据库中

 1 <?php
 2 
 3 if( isset( $_POST[ 'btnSign' ] ) ) {
 4     // Get input
 5     $message = trim( $_POST[ 'mtxMessage' ] );
 6     $name    = trim( $_POST[ 'txtName' ] );
 7 
 8     // Sanitize message input
 9     $message = stripslashes( $message );
10     // mysqli_real_escape_string转义部分特殊字符,影响\x00、\n、\r、\、'、"、\x1a
11     $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)) ? "" : ""));
12 
13     // Sanitize name input
14     // mysqli_real_escape_string转义部分特殊字符,影响\x00、\n、\r、\、'、"、\x1a
15     $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)) ? "" : ""));
16 
17     // Update database
18     $query  = "INSERT INTO guestbook ( comment, name ) VALUES ( '$message', '$name' );";
19     $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>' );
20 
21     //mysql_close();
22 }
23 
24 ?>

 

实践: 也就是说可以放心使用script注入代码

如注入代码: <script>alert(document.domain)</script> 获取域名

 

 

 

Middle:

老规矩先看源码:

其中message修改了3点:

1、strip_tags()函数剥去字符串中的HTML、XML以及PHP的标签,但允许使用标签。

2、addslashes() 函数返回在预定义字符(单引号、双引号、反斜杠、NULL)之前添加反斜杠的字符串。

3、htmlspecialchars()函数是使用来把一些预定义的字符转换为HTML实体,&转换为&amp;, "转换为&quot;, <转换为&lt;>, 转换为&gt;

 

而 name 只是简单的对<script>标签做了限制,存在注入点 

 1 <?php
 2 
 3 if( isset( $_POST[ 'btnSign' ] ) ) {
 4     // Get input
 5     $message = trim( $_POST[ 'mtxMessage' ] );
 6     $name    = trim( $_POST[ 'txtName' ] );
 7 
 8     // Sanitize message input
 9     // 函数剥去字符串中的HTML、XML以及PHP的标签,但允许使用标签。addslashes() 函数返回在预定义字符(单引号、双引号、反斜杠、NULL)之前添加反斜杠的字符串。
10     $message = strip_tags( addslashes( $message ) );
11     $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)) ? "" : ""));
12     // &转换为&amp;, "转换为&quot;, <转换为&lt;>, 转换为&gt;
13     $message = htmlspecialchars( $message );
14 
15     // Sanitize name input
16     // 简单过滤了<script>标签,存在注入点
17     $name = str_replace( '<script>', '', $name );
18     $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)) ? "" : ""));
19 
20     // Update database
21     $query  = "INSERT INTO guestbook ( comment, name ) VALUES ( '$message', '$name' );";
22     $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>' );
23 
24     //mysql_close();
25 }
26 
27 ?>

 

实践:

1、将name标签中maxlength属性改大(原10个字符长度, 修改为100)

 

 2、构造js代码<scr<script>ipt>alert(document.cookie)</script> 或者<ScriPt>alert(document.cookie)</script>, 多重标签或大小写绕过

 

 

High:

老规矩先看源码:

message 的代码与middle级别一致,没做修改

name 也对<script>标签严格过滤,但是其他标签没做过滤。毕竟其他标签也是可以写js的

 1 <?php
 2 
 3 if( isset( $_POST[ 'btnSign' ] ) ) {
 4     // Get input
 5     $message = trim( $_POST[ 'mtxMessage' ] );
 6     $name    = trim( $_POST[ 'txtName' ] );
 7 
 8     // Sanitize message input
 9     // 函数剥去字符串中的HTML、XML以及PHP的标签,但允许使用标签。
10     $message = strip_tags( addslashes( $message ) );
11     $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)) ? "" : ""));
12     // &转换为&amp;, "转换为&quot;, <转换为&lt;>, 转换为&gt;
13     $message = htmlspecialchars( $message );
14 
15     // Sanitize name input
16     // 对script做了严格校验
17     $name = preg_replace( '/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '', $name );
18     $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)) ? "" : ""));
19 
20     // Update database
21     $query  = "INSERT INTO guestbook ( comment, name ) VALUES ( '$message', '$name' );";
22     $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>' );
23 
24     //mysql_close();
25 }
26 
27 ?>

 

1、将name标签中maxlength属性改大(原10个字符长度, 修改为100)

 2、构造标签代码<img > <iframe>等, 例如:<img src=1 onerror="alert(document.cookie)" style="display:none" /> 和<iframe src=1 onload="alert(document.cookie)" style="display:none" />。 style中display:none 为不显示,可以降低被发现的机率。

 

 

 

Impossible:

查看源码:

message和name的校验代码与middle级别修改一致。暂无法注入。

如果有哪位老兄想到了方法,还请不吝在评论留言。

posted @ 2020-05-17 22:44  PerilongGideon  阅读(730)  评论(0编辑  收藏  举报