Visual Studio Code Jupyter Notebook RCE
2022年10月27日 - 作者:Luca Carettoni
我在过去周末抽出了几个小时研究Justin Steven于2021年8月发现的Visual Studio Code .ipynb Jupyter Notebook漏洞利用。
Justin发现了一个影响VSCode内置Jupyter Notebook (.ipynb)文件支持的跨站脚本(XSS)漏洞。
|
|
他的分析详细说明了这个问题,并展示了一个概念验证,可以从磁盘读取任意文件并将其内容泄露到远程服务器,但这并不是一个完整的RCE利用。
我找不到利用这个XSS原语实现任意代码执行的方法,但更擅长Electron利用的人可能能够做到。[…]
鉴于我们对ElectronJs(以及许多其他Web技术)的关注,我决定研究潜在的利用途径。
作为第一步,我查看了应用程序的整体设计,以识别VSCode使用的每个BrowserWindow/BrowserView/Webview的配置。借助ElectroNG,可以观察到应用程序使用了一个nodeIntegration:on的单个BrowserWindow。
这个BrowserWindow使用vscode-file协议加载内容,该协议类似于file协议。不幸的是,我们的注入发生在一个嵌套的沙盒iframe中,如下图所示:
![架构图]
特别是,我们的沙盒iframe使用以下属性创建:
allow-scripts allow-same-origin allow-forms allow-pointer-lock allow-downloads
默认情况下,沙盒使浏览器将iframe视为来自另一个源,即使其src指向同一站点。由于有allow-same-origin属性,这个限制被解除。只要webview中加载的内容也托管在本地文件系统(在应用程序文件夹内),我们就可以访问顶层窗口。这样,我们可以简单地使用类似top.require('child_process').exec('open /System/Applications/Calculator.app')
的代码执行命令。
那么,我们如何将任意HTML/JS内容放置在应用程序安装文件夹中? 或者,我们可以引用该文件夹外部的资源吗?
答案来自我最近在Black Hat USA 2022简报会上观看的一个演示。在利用CVE-2021-43908时,TheGrandPew和s1r1us使用路径遍历来加载VSCode安装路径之外的任意文件。
vscode-file://vscode-app/Applications/Visual Studio Code.app/Contents/Resources/app/..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F/somefile.html
与他们的利用类似,我们可以尝试利用postMessage的回复来泄露当前用户目录的路径。实际上,我们的有效载荷可以放置在恶意仓库中,与触发XSS的Jupyter Notebook文件一起。
经过几个小时的试错,我发现可以通过在onload事件期间强制执行来获取触发XSS的img标签的引用。
![示意图]
有了这些,所有成分都准备好了,我终于可以组装最终的利用代码。
|
|
为了在.ipynb文件中传递这个有效载荷,我们仍然需要克服最后一个限制:当前的实现会导致格式错误的JSON。注入发生在JSON文件(双引号)内,而我们的Javascript有效载荷包含引号字符串以及用作提取路径的正则表达式分隔符的双引号。
经过一些调整,最简单的解决方案涉及对所有JS字符串使用反引号`字符而不是引号。
最终的pocimg.ipynb文件如下:
|
|
通过打开包含此文件的恶意仓库,我们最终可以触发代码执行。
内置的Jupyter Notebook扩展选择退出Visual Studio Code 1.57中引入的工作区信任功能提供的保护,因此不需要进一步的用户交互。记录一下,这个问题在VSCode 1.59.1中修复,Microsoft为其分配了CVE-2021-26437。