Pull to refresh
161.35
Бастион
Проводим пентесты, проектируем защищенные системы

Исследование безопасности десктопных приложений на основе Electron

Level of difficultyEasy
Reading time15 min
Views3.8K


Electron — фреймворк с открытым исходном кодом для создания кросс-платформенных десктопных приложений с помощью JavaScript, HTML и CSS. Это крутая технология, но с ней связаны многие ИБ-риски.


В статье я разберу основы безопасной работы с этим фреймворком и расскажу:


  • как анализировать структуру десктоп-приложений на Electron и находить в них уязвимости;
  • какие распространенные ошибки допускают при работе с фреймворком и насколько он защищен.

Начнем с инструментов и методов, с помощью которых я провожу анализ кода приложений. Затем продемонстрирую конкретные примеры эксплуатации уязвимостей на примере специальных приложений-мишеней: DVEA, Electro-xxs и Notable.


Привет, Хабр! Меня зовут Александр, я работаю специалистом по информационной безопасности. Эта статья подготовлена на основе доклада, который я делал на программе стажировки, организованной компанией Бастион.

Atom, Visual Studio Code, WordPress Desktop, Github Desktop, Basecamp3, Mattermost — лишь несколько примеров приложений, созданных с использованием Electron. В основе фреймворка лежит сочетание Chromium (обеспечивает отображение контента с использованием HTML5, CSS3 и JavaScript) и Node.js (предоставляет среду выполнения для JavaScript, открывая разработчикам доступ к серверным функциям). Это дает фреймворку целый ряд преимуществ.


Особенности Electron
Кросс-платформенность Работа приложений возможна на ОС Windows, macOS и Linux.
Веб-технологии Для создания пользовательского интерфейса и логики приложения разработчик может использовать HTML, CSS и JavaScript.
Безопасность Можно применять различные инструменты и рекомендации для минимизации рисков, связанных с исполнением внешнего кода.
Поддержка сторонних библиотек и плагинов Для расширения функциональности приложений можно интегрировать сторонние библиотеки и плагины.

В то же время Electron наследует ряд проблем безопасности 1.97 256GB, характерных для обычных веб-приложений, и при этом обладает куда большими возможностями. Фреймворк имеет доступ к файловой системе, пользовательским скриптам и т. д. Взять, например, приложение, в котором есть несколько вкладок или окон. Возможен сценарий, когда вредоносный код выполняется на одной вкладке или в одном окне и приводит к негативным последствиям в других вкладках или приложениях.


Для решения этой проблемы в Electron используется мультипроцессорная модель. Она включает в себя два основных типа процессов:


  • Main Process, управляющий основными аспектами приложения;
  • Renderer Process, отвечающий за рендеринг содержимого в окнах приложения и выполнение кода JavaScript.

Разделение процессов обеспечивает изоляцию и независимость между различными компонентами приложения, что повышает уровень безопасности и предотвращает нежелательное взаимодействие между вкладками. По сути, main process может создавать renderer process, обеспечивая тем самым контролируемую и безопасную среду выполнения для каждого окна.




Примерно так выглядит связь между renderer process и окном браузера в Electron:


  1. Renderer Process загружает и отображает страницу или HTML-контент в окне приложения;
  2. В окне браузера отображается визуальный интерфейс приложения (например, если стартовой страницей является index.html, в окне браузера будет выводиться содержимое из файла index.html).



Для гибкой настройки Electron существуют webPreferences — параметры, связанные с определением различных характеристик веб-страницы.



Пример webPreferences. nodeIntegration: true — страница имеет доступ к Node.js API


Среди них есть параметры, которые дают новые возможности для renderer process. Так, для nodeIntegration дает разрешение на использование Node.js внутри процесса отображения, а contextIsolation отвечает за управление прямым доступом к API Node.js из кода страницы. Посмотрите, как Electro-XSS меняет поведение в зависимости от настроек webPreferences.



Активный доступ к Node.js API, который дает nodeIntegration в сочетании с XSS в renderer process, открывает возможность для Remote Code Execution дистанционного выполнения кода, несмотря на мультипроцессорную модель Electron.

nodeIntegration + XSS в renderer process = RCE


Инструменты и методы анализа


Для автоматизированного анализа кода и поиска подобных ошибок в Electron широко используют популярные статические и динамические анализаторы.


Статический анализ
ESLint и TSLint Проверка кода на соответствие стилю, выявление потенциальных ошибок и улучшение читаемости.
SonarQube Непрерывный мониторинг качества кода и обнаружение различных уязвимостей.
CodeQL Создание запросов для поиска уязвимостей в коде, например SQL-инъекций или проблем с памятью.
asar -> decompile -> read Source code Извлечение исходного кода из архивного файла в формате asar.
Динамический анализ
DevTools Отслеживание выполнения кода в реальном времени и профилирование производительности через встроенные средства разработчика в браузере.
BurpSuits Тестирование безопасности веб-приложений через перехват и изменение трафика между клиентом и сервером, анализ сеансов или интеграции с другими фреймворками.

Однако существуют и менее известные, но более узкоспециализированные утилиты, как консольные, так и снабженные графическим интерфейсом.


Electronegativity


Этот инструмент предназначен для выявления неправильных конфигураций и антипаттернов безопасности в приложениях.


Мажорные релизы Electronegativity можно установить из хранилища пакетов NPM при помощи консольной команды: $ npm install @doyensec/electronegativity -g


Затем, чтобы проверить приложение на на наличие уязвимостей, введите: $ npm audit


Пример запуска сканирования: electronegativity -i DVEA


Electronegativity представляет структуру кода в древовидном формате и анализирует его иерархическую структуру, проверяет структуру веб-страницы (DOM) и формирует подробный отчет.



Кроме того, стоит обратить внимание на ElectroNG — специализированный сканер безопасности, разработанный создателями Electronegativity для проведения автоматизированных проверок.


NodeJsScan


Это бесплатный и открытый сканер статического кода. Он способен выявлять небезопасные паттерны в коде Node.js и HTML-шаблонах и предоставляет удобный веб-интерфейс для управления обнаруженными проблемами безопасности. Одно из его преимуществ — легкая интеграция с различными CI/CD конвейерами: Github Actions, Gitlab CI/CD, Travis и т. д.



Запуск инструмента выглядит следующим образом:


  1. Загрузка последней версии образа Nodejsscan из Docker Hub.
    docker pull opensecurity/nodejsscan:latest
  2. Запуск контейнера (порт 9090) для веб-интерфейса Nodejsscan.
    docker run -it -p 9090:9090 opensecurity/nodejsscan:latest
  3. Переход на страницу Nodejsscan.
    http://localhost:9090

Протестируем Nodejsscan на примере уязвимого приложения Damn Vulnerable ElectronJS App (DVEA).



Сканер выдает развернутый отчет:




Выбрав интересующую нас уязвимость через Hide Code, можно получить детальную информацию, об ее особенностях:



Njsscan (CLI)


Этот статический анализатор обнаруживает уязвимости, при помощи сопоставления паттернов из библиотеки libsast.


Для установки введите команду: pip install njsscan


Njsscan использует семантический поиск шаблонов кода с помощью инструмента semgrep.



Команды semgrep запускаются с различными конфигурациями (rulesets), которые определяют, какие конкретные проверки и тесты будут выполнены.


Например:

$ semgrep --config=r/javascript.browser.security.insufficient-postmessage-origin-validation.insufficient-postmessage-origin-validation --config=r/javascript.lang.security.audit.incomplete-sanitization.incomplete-sanitization --config=r/javascript.browser.security.dom-based-xss.dom-based-xss --config=r/typescript.react.security.audit.react-css-injection.react-css-injection --config=r/typescript.react.security.audit.react-href-var.react-href-var --config=p/owasp-top-ten __CODE_DIRECTORY__


Snyk CLI


Snyk представляет собой облачный инструмент безопасности, предназначенный для поиска потенциальных уязвимостей в коде приложения в режиме реального времени. Умеет он и обнаруживать ошибки в образах контейнеров Kubernetes, а также небезопасные конфигурации Terraform и Kubernetes.


Snyk CLI устанавливается при помощи npm: sudo npm install snyk@latest -g


Проверка работоспособности Snyk CLI выполняется через команду: snyk --help


Чтобы начать использовать Snyk CLI, необходимо произвести аутентификацию с помощью: snyk auth


Затем можно начинать сканировать проект:



Например, перейдем по ссылке со snapshot:



Результат сканирования немного предсказуем:



Попробуем другое демонстрационное приложение — Electro-XSS:



Здесь Snyk также находит уязвимости:


Особенности ручного тестирования приложений на основе Electron


Общий порядок действий при тестировании десктопных Electron-приложений разбивается на три этапа.


Декомпиляция Модификация и перекомпиляция Настройка каналов связи
Для анализа необходимо извлечь исходный код. Этот этап важен для того, чтобы добавить дополнительную отладку в код или обойти какие-либо средства управления на стороне клиента. Этот процесс необходим для тестирования API на стороне сервера.

Попробуем подробнее рассмотреть эту последовательность.


Декомпиляция


Ручное тестирование приложения начинается с распаковки файлов в формате .asar. Их можно обнаружить в каталоге resources. Если у вас установлен NodeJS, используйте команду npm, чтобы убедиться в корректности работы менеджера пакетов Node.


Для этого используйте команду npm install --engine-strict asar, которая отвечает за установку приложения asar при помощи менеджера пакетов npm.



Команда npm install -g asar отвечает за установку asar глобально.



С помощью команды asar extract app.asar app извлеките исходный код из архива.


Модификация и перекомпиляция


Если нужно модифицировать исходный код и применить изменения в момент запуска приложения, повторно упакуйте файл app.asar.



Я модифицировал функцию createWindow, добавив новую отладочную строку, как показано на скрине.



Настройка каналов связи


Чтобы осуществить захват трафика и затем модифицировать какой-либо запрос в процессе работы приложения, потребуется настроить прокси через Burp Suite. Здесь можно действовать двумя путями.


  1. Проксирование на уровне ОС


    Такой подход полезен, когда вам нужно видеть HTTP/HTTPS-запросы, выдаваемые целевым приложением. В этом случае добавляется электронный аргумент командной строки. Если мы вернемся к функции createWindow, то увидим уже два примера:




createWindow — функция, показывающая commandLine.appendSwitch. В 58 строке находится уже добавленный переключатель: app.commandLine.appendSwitch('proxyserver','127.0.0.1:8080');
Далее папка app снова упаковывается в файл app.asar, и Electron загружает chromium (не забудьте установить сертификат CA certificate Burp, как показано здесь).


После настройки прокси вы увидите, как весь HTTP/HTTPS-трафик переходит в burp, и сможете заняться запросами на стороне сервера.


  1. Проксирование на уровне приложения


    Реализация этого подхода будет зависеть от архитектуры конкретного приложения и используемых в нем технологий. Рассмотрим процесс настройки прокси-сервера для перехвата трафика Windows-машины в Burp Suite.



Первым делом необходимо настроить системный прокси с помощью команды: netsh winhttp set proxy proxy-server="http=127.0.0.1:8080;https=127.0.0.1:8080" bypass-list="*.local"


Так вы установите системный прокси-сервер для HTTP и HTTPS трафика на адрес 127.0.0.1 (localhost) и порт 8080. Файлы *.local будут обходить прокси. Чтобы убедиться, что настройки были применены, выполните: netsh winhttp show proxy В выводе вы должны увидеть настроенные параметры прокси.


Затем убедитесь, что прокси-сервер в Burp Suite запущен и настроен на прослушивание того же порта (в данном случае, 8080).



Экспортируйте сертификат Burp и откройте Консоль с помощью команды mmc.


Перейдите в меню «Файл->Добавить/удалить оснастку...», а затем — в раздел «Сертификат -> Добавить -> Учетная запись компьютера -> Далее».



Выберите «Локальный компьютер», нажмите кнопку «Готово» и подтвердите выбор сертификата:



Перейдите в раздел «Сертификаты -> Все задачи -> Импорт». Выберите путь к импортированному сертификату Burp и нажмите кнопку «Далее».



Выберите «Разместить все сертификаты в следующих хранилищах» и нажмите кнопку «Далее». Нажмите «Finish».



Наконец, убедитесь, что сертификат BurpSuite был установлен.



И запустите перехват трафика.



Виды атак и примеры эксплуатации уязвимостей


При разработке и тестировании приложений следует учитывать возможность возникновения целой россыпи различных проблем.


Уязвимости npm-зависимостей При использовании Electron.js, который включает в себя разнообразные npm-пакеты, существует потенциальная угроза наследования уязвимостей.
Удаленные запросы Electron.js-приложения по умолчанию разрешают удаленные запросы с доступом к системным ресурсам. Это создает потенциальный риск выполнения вредоносного кода с удаленного сервера на устройстве пользователя.
Уязвимости Web-контента Если Electron.js-приложение отображает веб-контент из ненадежных источников, существует риск эксплуатации XSS-уязвимостей.
Утечки данных Использование Node.js в Electron.js для доступа к ресурсам ОС может привести к возможным утечкам данных. Необходимо внимательно обращаться с данными и предпринимать меры для предотвращения утечек.
Уязвимости Node.js-пакетов Некоторые Node.js-пакеты, используемые в Electron.js, могут содержать уязвимости. Важно следить за обновлениями безопасности и оперативно применять исправления уязвимостей.
Уязвимости XSS Внедрение вредоносного JavaScript-кода в приложение выполняется в контексте других пользователей или приложений, что может привести к краже данных пользователей или выполнению вредоносных действий от их имени.
Remote Code Execution Приложения Electron.js могут загружать удаленный код с сервера. Без должных мер безопасности злоумышленник может подделать или внедрить вредоносный код, который будет выполнен на машине пользователя.
Denial of Service, DoS Атаки DoS направлены на перегрузку ресурсов приложения, делая его недоступным для других пользователей.
Атака на файловую систему Некорректная обработка файлов приложением Electron.js может позволить злоумышленнику использовать поддельные или вредоносные файлы для доступа к файловой системе пользователя или выполнения вредоносных операций.
Привилегированное выполнение кода Приложения на Electron.js могут иметь прямой доступ к системным ресурсам.

Рассмотрим некоторые из них подробнее


Cross Site Scripting


Этот вид атак представляет собой внедрение вредоносного кода в приложение. Cross-Site Scripting XSS-атаки на приложения на основе Electron в целом напоминают атаки на веб-приложения. Однако есть некоторые отличия в механизмах передачи вредоносного кода. Обозначим их.


  1. В десктоп-приложениях обычно отсутствует отдельная строка ввода URL, как в веб-браузерах. Как описано в разделе методологии, можно использовать DevTools Desktop-приложения для взаимодействия с API.
  2. Electron позволяет приложениям взаимодействовать с локальной файловой системой пользователя. Если входные данные из файловой системы недостаточно защищены, это может привести к возникновению патчей XSS.
  3. Работа с протоколами: Electron поддерживает основные протоколы (например, HTTP, HTTPS), а также позволяет создавать собственные протоколы. Если эти протоколы не защищены должным образом, они также могут стать причиной возникновения XSS-уязвимостей.

Эти атаки могут привести к краже данных пользователей, сеансов аутентификации, перенаправлению на вредоносные сайты, внедрению вредоносных скриптов и другим нежелательным последствиям. Предотвращение XSS включает в себя фильтрацию и экранирование ввода данных, использование безопасных API и регулярные обновления политик безопасности.


Запуск сценария эксплуатации процесса в поле ввода выглядит следующим образом:


<img src=x onerror=alert(1) />

Этот код будет выполняться в desktop-приложении пользователя, если оно некорректно обрабатывает или экранирует поступающие данные. В этом конкретном примере тег используется для вставки изображения, и при возникновении ошибки загрузки изображения (атрибут onerror) выполняется JavaScript-код alert(1), который отобразит диалоговое окно с сообщением "1".


XSS to RCE


Примеры payload'ов для RCE в данном контексте:


  • Для Linux и MacOS

<img src=x onerror=alert(require('child_process').execSync('gnome-calculator')); />

  • Для Windows

<img src=x onerror="alert(require('child_process').execSync('calc').toString());">

В обоих случаях используется тег и событие onerror, которое вызывает require('child_process').execSync() для выполнения команд в системном шелле. Подобные команды могут быть использованы злоумышленниками для выполнения произвольного кода на стороне клиента и создают серьезную угрозу для безопасности приложения.


Для защиты рекомендуется правильно настраивать политику безопасности контента (Content Security Policy, CSP) и ограничивать использование nodeIntegration.


Вот как это выглядит на практике:



Примеры полезных нагрузок для демонстрации возможного удаленного выполнения кода (RCE) через уязвимость XSS:
  • Пример payload для Windows:
    <img src=x onerror="alert(require('child_process').execSync('calc').toString());">
  • Примеры payload'ов для Linux и MacOS:
    <img src=x onerror="alert(require('child_process').execSync('/System/Applications/Calculator.app/Contents/MacOS/Calculator').toString());">
    <img src=x onerror="alert(require('child_process').execSync('id').toString());">
    <img src=x onerror="alert(require('child_process').execSync('ls -l').toString());">
    <img src=x onerror="alert(require('child_process').execSync('uname -a').toString());">```

Эксплуатация XSS и RCE на примере DVEA


Damn Vulnerable ElectronJS App — уязвимое приложение ElectronJS, разработанное специально для обучения ИБ-специалистов и разработчиков. Оно спроектировано так, чтобы демонстрировать основные уязвимости, характерные для среды ElectronJS.


Чтобы запустить DVEA, используйте следующую команду:


cd DVEA
npm i
electron .

Запуск с использованием npm:


npm install yarn
npm start

DVEA позволяет увидеть примеры уязвимостей, включая XSS. Например, внутри приложения можно использовать такой payload:


<img src=x onerror=alert(1) />


Этот код выведет окно с предупреждением, содержащим произвольный текст. Тут же, если ввести правильную полезную нагрузку в renderer process DVEA, можно реализовать RCE-атаку:


<img src=x onerror=alert(require('child_process').execSync('mate-calc')); />


Демонстрация атак на примере Electro-XSS


Как следует из названия, это приложение-мишень предназначено уже для демонстрации уязвимостей на основе XSS.



Посмотрим на сценарий эксплуатации XSS, когда нужно внедрить код JavaScript в поле ввода страницы. Такой код может использоваться для атак на пользователя, например, в целях кражи сессионных данных.



Запустим сценарий эксплуатации процесса: XSS: <img src=x onerror=alert(1) />



RCE: <img src=x onerror=alert(require('child_process').execSync('gnomecalculator'));/>

При выполнении этого JavaScript-кода запустится калькулятор GNOME. Такие сценарии могут использоваться для атак на приложение, особенно в случае, если параметр nodeIntegration установлен в true, что позволяет выполнять код Node.js в процессе отображения.


RCE на примере Notable


XSS-атаки позволяют злоумышленникам внедрять и запускать свой код на стороне клиента. Например, в случае использования Node.js в приложении, построенном на Electron, может возникнуть угроза удаленного выполнения кода RCE (Remote Code Execution). Пример XSS-пейлоада, с помощью которого можно внедрить в уязвимое приложение команду на запуск калькулятора:


<img src=x onerror=alert(require('child_process').execSync('mate-calc')); />


При отсутствии фильтрации или ограничений ввода злоумышленник может внедрять произвольные команды в различные поля приложения. Например, использование команды ls позволяет просмотреть содержимое текущего каталога и получить дополнительную информацию о файловой системе.



Чтобы увидеть, как это происходит, на практике, запустим приложение Notable version 1.5.0 и введем полезную нагрузку.



После выхода из режима редактирования автоматически запустится команда полезной нагрузки. Останется только произвести эксплуатацию уязвимости:



Методология пентеста Desktop-приложений


Анализ логики работы десктопного приложения перед началом тестирования играет ключевую роль в оценке его безопасности.


Reversing Electron Application — это метод, направленный на получение доступа к исходному коду приложения, который дает возможность более глубокого и детального анализа. Построение методологии пентеста в значительной степени зависит от этого этапа, поскольку доступ к исходному коду позволяет определить поток работы приложения, выявить логические цепочки и понять его поведение и внутреннее устройство.


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



Методология пентеста на примере Notable


Для того, чтобы попрактиковаться и провести детальное исследование, используем notable версии 1.5.0 и скачаем файл Notable-1.5.0.dmg и Notable-1.8.4.AppImage. Не забудьте дать права на использование этого приложения:



Смонтируем образ приложения (во временную папку):



И откроем эту папку:



В этой папке уже можно видеть файлы и ресурсы приложения.



Далее необходимо скопировать файл app.asar в рабочую папку и изменить формат файла .dmg (для этой цели подойдет приложение HFSleuth).



Нам необходимо запустить эту программу с указанием двоичного файла Notable-1.5.0.dmg.



Найдем файл Notable.app.



И попробуем войти в него.



Загрузим файл app.asar (архив, содержащий исходный код для electron-приложения), записав его во временную папку.


Command: asar extract app.asar dest-folder


Для того чтобы провести реверс-инжиниринг файла необходимо:




Файл будет извлечен в обратном порядке. Далее потребуется запустить Sublime-text, чтобы просмотреть содержимое файлов:



Если требуется найти уязвимые места в зависимостях, пригодится npm audit.



Чтобы решить эту проблему, необходимо отключить блокировку пакетов:




  • package.json содержит различные метаданные, а также сведения о зависимостях и версиях;
  • The main process выступает в качестве точки входа в приложение;
  • Index.html — это фронтенд приложения.

    Методология пентеста на примере Electro-XSS


Теперь посмотрим на работу по анализу уязвимостей на примере Electro-XSS.



Развернув приложение, запустим Sublime-text, чтобы просмотреть его файлы:



Здесь можно увидеть точку входа в приложение:



В файле package.json можно увидеть поле main и найти точку входа.


Мы уже знаем, что параметры webPreferences отвечают за настройку веб-страницы. Когда параметр nodeIntegration установлен в true, Node.js API становится доступен. Если в приложении существует уязвимость типа Cross-Site Scripting (XSS), успешная атака позволит злоумышленнику выполнить произвольный код на стороне клиента, осуществив Remote Code Execution (RCE). В таких случаях рекомендуется использовать contextIsolation вместе с preload для предварительной загрузки скриптов:


const mainWindow = new BrowserWindow({
  width: 800,
  height: 600,
  webPreferences: {
    contextIsolation: true,
    preload: path.join(__dirname, 'preload.js'),
  },
});

Для примера попробуем изменить параметр nodeIntegration на false:



npm install 
npm run eletro-xss


С помощью Ctrl+Shift+I откроем Devtools:



И попробуем через консоль получить доступ к API интерфейсу узлов.



Поскольку получить доступ не удается, попробуем отключить приложение и использовать nodeIntegration, а затем отправим команду на перезапуск. Наша задача здесь — вызвать API interfaces node, что позволит удаленно выполнять любой код (RCE):



Попытка успешна. Смысл такой интеграции узлов состоит в том, чтобы вызвать API interfaces node для эксплуатации RCE.


Вместо вывода: Security Electron.js


Для обеспечения безопасности Electron-приложений стоит строго следовать рекомендациям по безопасности из репозитория Electron на github.


Ключевые шаги включают:


  • значение nodeIntegration в false и contextIsolation в true;
  • валидацию ввода в полях форм;
  • контроль над процессом создания новых окон (или их блокировка, если они не нужны);
  • использование актуальной версии Electron.js;
  • проверку всех параметров безопасности, установленных по умолчанию (особенно при использовании сторонних фреймворков);
  • контроль интеграций с Node.js.

Дополнительной мерой может служить блокировка лишних привилегий, предоставленных приложению. Это уменьшит поверхность атаки и предотвратит нежелательный доступ к системным ресурсам.

Tags:
Hubs:
Total votes 20: ↑20 and ↓0+20
Comments0

Articles

Information

Website
bastion-tech.ru
Registered
Founded
2014
Employees
101–200 employees
Location
Россия
Representative
Игорь Santry