一、所用靶场
1. 靶场地址
这里使用的是易锦网校自己的 XSS 靶场,靶场地址: http://lab.yijincc.com:50008/?lesson=6
2. 靶场玩法

2.1 漏洞简述
这个区域下面的文字是对当前关卡的描述,如果题目比较难的话,出题人会在这里给一些暗示(大概是怕被骂吧)。
2.2 导致漏洞的代码

这个区域贴出来的 JavaScript 代码用于处理你输入的内容,这些内容经过处理才会渲染到子页面里面去,所有造成漏洞和过滤内容的代码都在这里有所体现。
但其实只有关键代码,而不是全部代码,如果过多的话会,干扰你的阅读(是不是很贴心)。
2.3 payload 输入区域

当你在一个 CTF 靶场中看到一个输入框,该干什么就不用多言了吧。
2.4 处理后的代码

你输入的内容经过处理之后的样子,渲染到子页面的内容就是长这个样子的,仔细观察你的输入对这里输出内容的影响,可以得出通关的关键。
2.5 渲染出来的页面

为了判定你是否通关,需要把内容渲染出来,这个区域就是一个专门用来渲染输出之后的内容的子页面。
如果你嫌子页面太小看不清楚的话可以点“全屏”按钮把它放大,再点击“退出全屏”按钮退出来。
2.6 通关条件
子页面里面的 window.alert 函数已经被改写,只要你成功地执行了 alert 函数,页面就会判定你通关。通关之后,页面上方的标题右边会渲染一个“下一关”按钮,点击按钮即可进入下一关。

3. 本文描述的是第六关
由于前面几个关卡都比较简单,所以这里我就不写题解了,如果你在中间的哪一个关卡遇到麻烦了,一定要多动脑筋、多百度,这样才能加深你的印象。
如果你连这些都尝试了还是不行的话,就去问问你的答疑老师。
二、解题描述
1. 阅读描述
……Markdown 通常会被生成为 HTML,然后直接渲染到网页,这就导致了:即便使用了框架,也很难规避其中的 XSS 代码隐患。
👆从这里我们可以得知一个事实:这个漏洞与 markdown 有关系,在这一篇锦囊中我们大致科普了一下 markdown 语法,所以本篇不再赘述。
2. 查看代码
我知道对于大部分人而言,阅读代码是非常麻烦乃至于困难的事情,不过出题人显然不希望被你们骂到狗血淋头,所以在代码的关键地方都加了注释:

👆可以看出来这里使用的是标准 markdown 语法,随便百度一下都可以搜到的。
但是我么经常用来构造闭合的 <'" 都已经被提前替换了,所以破题的关键肯定就是 markdown 语法的部分。
3. 尝试一下
分别尝试一下链接语法和图片语法
[易锦网校](ke.yijincc.com)

可以看到,正常渲染👇

👆但是渲染出了我们梦寐以求的双引号,只要找到方法加以利用,事儿就成了!
4. 正则表达式一生之敌——嵌套
上面的代码使用了正则表达式来匹配并替换代码,但是正则表达式的缺点就是不能嵌套解析,所以首先考虑嵌套使用语法。
如果你不知道什么是正则表达式,也不用担心——总而言之,CTF 中凡是遇到奇怪的解析规则的时候,先用嵌套试探一下解析器的底线准没错。
所以我们尝试在图片语法里面链接一个图片语法:
 ](http://lab.yijincc.com:50008/logo192.png)
👆上面的红色部分是外面的图片语法,白色部分是套在里面的链接语法,如果你没领会到我的意思,把里面白色部分删除,换成数字 1 ,就明白了。
处理之后的代码有点奇怪:

👆可以看到 a 标签被“吞”进了 img 标签里面,说明我们的嵌套语法威力无穷。
5. 确定 payload 的插入点
老办法,我们先看一下双引号的配对情况,通常而言,属性 payload 应该放在最后一对引号后面某个位置(位置不对可以使用空格来调整),我们先数一下有哪些引号是成双成对的:

👆可以发现有两对,最后一个双引号落了单,经过检查,“落单的”引号对应的内容是链接语法的地址,也就是 [](2) 这句代码的 2 ,那么我们就在里面换成 onerror 属性以带入 alert:
) ](http://lab.yijincc.com:50008/logo192.png)
然而奇迹并没有如约而至:

6. 总算到本篇重点了——不使用括号执行 alert
仔细观察我们输入的东西,你会发现罪魁祸首是 alert() 里面的圆括号,因为图片语法和链接语法都需要识别圆括号,一旦你加了一个圆括号,就会重新破坏它们的结构——所以我们需要把 payload 中的括号先去掉。
7. 两个全新的知识点
- JS 中的 setTimeout 可以把紧跟其后的字符串当成代码来执行;
- 上述方法执行的代码可以使用 \x 编码,右括号的编码是 \x29。
8. 决战时刻
基于上面两个全新的知识点,我们修改一下 payload :
 ](http://lab.yijincc.com:50008/logo192.png)
但是效果并没有出来,其实这是因为 payload 后面紧跟着一个双引号造成了语法错误:

这个问题很好解决,在 payload 尾巴上加一个空格就搞定了:
 ](http://lab.yijincc.com:50008/logo192.png)

怎么回事?还是没有反应?——不要慌张,因为我们这里使用的是一个可以加载的图片,所以应该把 onerror 改成 onload ,通关!
 ](http://lab.yijincc.com:50008/logo192.png)
