
实验室入口:

查看页面源码

<script src="/resources/labheader/js/labHeader.js"></script>
的作用是在网页中引入一个名为 labHeader.js 的 JavaScript 文件。这个文件通常用于加载实验室(Lab)或网站的页眉(Header)部分
这个页面看不出什么问题,可以看看这个实验室的有没有子页面。

子页面有评论功能,可以尝试恶意执行语句
<img src=1 οnerrοr=alert(1)>


恶意代码是插入进去了但是onerror属性被删除了
我们查看源码进行分析

在这里有两个js引入
|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| <script src='/resources/js/domPurify-2.0.15.js'></script> 作用是在网页中引入 DOMPurify (版本 2.0.15 )库,这是一个用于 防御 XSS(跨站脚本攻击) 的安全工具。 |
| <script src='/resources/js/loadCommentsWithDomClobbering.js'></script> 作用是加载一个名为loadCommentsWithDomClobbering.js
的 JavaScript 文件,从文件名来看,它可能涉及 动态加载评论 功能,并可能涉及 DOM Clobbering(DOM 冲突/覆盖)相关的逻辑。 |
我们点开查看<script src='/resources/js/loadCommentsWithDomClobbering.js'></script>的js源码进行查看。对代码进行分析

-
创建一个
XMLHttpRequest
对象,用于发送 HTTP 请求。 -
监听请求状态的变化(
readyState
变化时触发)。 -
当请求成功时:
this.responseText
获取服务器返回的 JSON 字符串, 将其解析为 JavaScript 对象调用一个display**Comments
**函数 -
浏览器向
postCommentPath + window.location.search
发送 GET 请求。
对字符串中的特殊 HTML 字符进行转义 ,防止 XSS(跨站脚本攻击)漏洞。它会将 <
, >
, '
, "
等字符转换成对应的 HTML 实体编码,使其在页面上显示为普通文本,而不会被浏览器解析为 HTML 标签或 JavaScript 代码。
javascript
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);
}
}

-
作用:设置一个默认头像的配置。
-
首先检查是否有全局定义的头像配置(
window.defaultAvatar
) -
如果没有,则使用默认头像路径
/resources/images/avatarDefault.svg
-
确保后续代码总能获得一个包含
avatar
属性的对象
-
-
用途:提供兜底机制,避免因头像缺失导致显示异常。
这一段代码有问题,可以尝试是否可以进行dom破坏通过设置全局变量defaultAvatar,这样就可以对img的地址进行控制尝试写出<img src=1 οnerrοr=alert(1)>
开始实验
想法是第一步将图片地址写入,第二步再引用就可以顺利执行。
<a href="cid:"οnerrοr=alert(1)//" name="avatar" id="defaultAvatar"></a>

但是我发现找不到
原来这是个二层是window.defaultAvatar.avatar这种
就需要二层来锁定
<a id=defaultAvatar><a id=defaultAvatar name=avatar href="cid:"οnerrοr=alert(1)//">
这样就可以将window.defaultAvatar进行定义img的src
然后再写随便写点评论就可以直接调用img直接恶意代码直接执行
开始测试


写进去了
第二步


ok成功