XSS 进阶技巧之解析+渲染造成的漏洞,以类 markdown 语法为例
2022-11-28 19:49:02276浏览
时至如今,由于 React/Vue/Angular 之类的前端框架大行其道,而这些框架天生就自带 XSS 免疫属性,所以 XSS 漏洞的领地正在萎缩。 但也正是因为前端的能力的提升,许多新奇的应用也出现在了浏览器上,比如 markdown 编辑器。

一、 markdown 语法简介

1. 关于 markdown

markdown 语法是一种非常简洁的文档书写语法,它不像 word 文档那样需要安装指定的应用才能打开和书写,并且使用文本格式存储,因此基本不存在兼容性的问题。

用户在编辑器里面输入 markdown 语句,这些语句经过解析之后被程序识别,然后渲染出具体的样式来,例如链接、图片、引用、标题、斜体加粗……

2. 标准 markdown 语法(摘要)

markdown 的语法,你可以点击访问这个网站练习使用 markdown 语法。

需要注意的是这个网站的编辑器也是存在 XSS 漏洞的(截至2022年11月17日),但是和本文介绍的类型不一样(更简单),你可以试着挖掘一下。

2.1 链接渲染

markdown 的链接渲染语法如下:

[链接的文字](链接的地址)

例如这句代码

[易锦网校](ke.yijincc.com)

渲染出来就是

易锦网校

2.2 图片渲染

markdown 的图片渲染语法如下:

![图片的描述性文字](图片的链接地址)

例如这句代码

![百度的 LOGO](https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png)

渲染出来就是:

2.3 markdown 的语法没有严格约束

也就是说网站或者编辑器可能会自己发明别的语法,比如

[文字描述][链接地址]

或者

[文字描述|链接地址]

具体遇到的时候你根据网站的要求判断即可,这种自定义语法在 CTF 题目中最常见。

二、漏洞的产生

1. markdown 渲染出来的 HTML 用于在页面上展示出来

因为支持 markdown 的基本都是各种网站,因此很多时候都是直接在网站上渲染出来

2. 为了保留渲染的样式,渲染的时候不能过滤危险字符

我们都知道 XSS 的一大敌人就是过滤,一旦把我们热爱的 <>'" 等字符给过滤掉了,那我们也就无法带入 JS 并执行了。

但是如果对 markdown 的输出内容进行过滤的话,那么渲染好的样式也就没了,甚至会直接在用户面前显示 HTML 代码,干扰用户阅读。

三、漏洞例子

我们这里使用的例子是一个好玩的在线 XSS 靶场,靶场的地址: https://alf.nu/alert1?world=alert&level=alert5

1. 跋山涉水来见我

当然,由于这个漏洞在后面某一个关卡,所以你需要先把前几关过了,直到你看见右边是 “markdown” ,才表明你遇到了我们演示的这个靶场。

前面的几个关卡都很简单,我就直接把 payload 粘贴到这里了:


// Warmup:双引号闭合
");alert(1) //

// JSON :script 标签闭合
</script><script>alert(1)//

👆过了这两个关卡就到了。通过以上关卡之后,你就会来到本文所述的这一关了:

2. 出题人的意图

  • 如果这是一道 CTF 题目,那么我们需要仔细审题;
  • 如果这是一个真实的编辑器,那么我们需要了解具体使用方法。

这个靶场没有任何语言描述,好在它贴出了代码,这对于你而言可能有点困难,所以我总结了一下,它提供了两种语法:

2.1 链接语法

http://ke.yijincc.com

会被渲染成如下链接

http://ke.yijincc.com

2.2 图片语法

[[img123|Description]]

会被渲染成一张图片。

所以很显然,出题人希望我们从其对这两种语法的解析中找出漏洞的利用方式,把 payload 带入到渲染出来的 HTML 里面才能通关。

3. 第一轮尝试——中规中矩

我们按照它的正经玩法写两个语句,果然是可以正常渲染的:

http://ke.yijincc.com
[[img123|123123]]

4. 第二轮尝试——语法嵌套

通常来讲,markdown 语法应该支持嵌套,但是嵌套的语法解析比较难写,所以这一关里面直接使用了正则表达式,正则表达式是不支持嵌套的,所以我们不按常理出牌,上嵌套语法。

[[img123|http://ke.yijincc.com]]

👆在图片语法里面套一个链接语法,渲染效果如下:

👆这里的标签结构被破坏了,并且带入了我们梦寐以求的双引号,说明有戏!

5. 第三轮尝试——插入 payload

我们现在需要确定在什么地方插入 payload ,这时候我们要静下心来,研究一下 img 标签的双引号配对问题。

👆确实存在双引号配对的问题。但是 http 是连接语法的匹配特征,如果把 payload 放在这里,则无法达到上一步中破坏标签结构的效果。看来页面的 HTML 给的信息还不够多,我们需要审查一下 Test iframe 中的内容:

👆好家伙,双斜杠(//)在 HTML 属性中直接消失了,那么我们需要把 payload 放在双斜杠后面:

[[img123|http://onerror=alert(1)]]

6. 留心细节,直捣黄龙

上面的 payload 还是没有正确执行,浏览器控制台还报了语法错误——但这是一个好消息,因为语法错误是 JS 执行的迹象,只不过执行尚未达成目的而已

再次审查一下 iframe 的代码

👆这里多了一个双引号,导致语法错误。这种问题很好解决:使用双引号把后面的内容注释掉即可:

[[img123|http://onerror=alert(1)//]]

过关!

四、总结

1. 要多留意回显

不仅仅是 XSS 漏洞挖掘,而是在任何渗透测试场景中,我们都要尽可能搜集目标对 payload 的反馈,而不是一味地使用扫描器或者盲打。

这个靶场就做了一种很好的示范,它给出了 payload 本身、渲染出来的 HTML、控制台输出、渲染真实 HTML 的 iframe ,这么多信息汇聚于此,非常方便我们自己的分析。

那么假如靶场没有提供这么多东西呢?假如这是在做真实的渗透呢?答案当然是自己创造条件、获取更多的回显。

2. 要巩固基础

虽然我们是做渗透测试,但是你可能会发现,这个漏洞的利用方式需要有一定的 JS 经验——至少你要会审查 HTML 。

是的,这种情况下,你基础越稳固,第一个吃到螃蟹的可能性就越高。

友情链接: