candyToy_422
НОВОРЕГИ! РАБОТАТЬ ЧЕРЕЗ ГАРАНТА!
Доброго времени суток, форумчане.
Если вы проводили время за администрированием системы Windows после Vista, то наверняка сталкивались с группой TrustedInstaller (TI), для которой большинство системных файлов и ключей реестра имеют ACL-режим. Если, например, вы посмотрите на безопасность файла в System32, то заметите, что только TI может удалять и изменять файлы (даже группа администраторов не имеет права), а владелец также является TI, поэтому вы не можете напрямую изменить безопасность.
Однако если вы заглянете в приложение Local Users and Groups, то не найдете там ни пользователя, ни группы TI. Эта статья посвящена тому, что на самом деле представляет собой группа TI, и, что более важно, с помощью PowerShell и модуля NtObjectManager вы можете стать TI, чтобы делать все, что вам нужно.
Где находится TrustedInstaller?
Если TI - это не пользователь или группа, тогда что это? Возможно, более тщательное изучение ACL даст нам некоторое представление. Вы можете использовать команду Get-Acl для чтения дескриптора безопасности из файла, и мы сможем перечислить TI ACE.
Мы видим в члене IdentityReference, что у нас есть группа TI, и она имеет префикс домена «NT SERVICE». Таким образом, это SID службы Windows. Это функция, добавленная в Vista, чтобы позволить каждой запущенной службе иметь группы, которые они могут использовать для проверки доступа, без необходимости добавлять отдельные реальные группы в локальную систему.
Сам SID генерируется на лету как SHA1-хэш заглавной версии имени сервиса. Например, следующий код вычислит фактический SID:
Конечно, вам не нужно этого делать, в NTDLL есть функция RtlCreateServiceSid, а LSASS преобразует имя службы в SID и наоборот. В любом случае, вернемся к сути. Это означает, что существует служба под названием TrustedInstaller, которая должна быть запущена при изменении системных ресурсов. И это именно то, что мы обнаруживаем при запросе с помощью утилиты SC.
Достаточно предыстории, предположим, что мы являемся администратором, как мы можем использовать возможности TrustedInstaller?
Становимся TrustedInstaller
Если вы поищете в Интернете, как удалить ресурсы, принадлежащие TI, то, как правило, найдете статьи, в которых предлагается вручную получить право собственности на файл или ключ, а затем изменить DACL, чтобы добавить группу администраторов. Это связано с тем, что даже обычно послушный COM-объект IFileOperation UAC не сделает этого автоматически, в результате чего вы получите следующее диалоговое окно.
Изменение прав доступа к системным файлам - не самая лучшая идея. Если вы сделаете это неправильно, то легко откроете часть системы для EoP-проблем, особенно с каталогами. Проводник может легко случайно заменить настройки безопасности всех вложенных папок и файлов, причем вернуть исходные значения практически невозможно. Разумеется, цель TI - не дать вам сделать все это в первый раз, но некоторым людям почему-то очень хочется это сделать.
Вы можете предположить, что можно просто добавить текущего пользователя в группу TI и все? К сожалению, LSASS API, такие как NetLocalGroupAddMembers, принимают имя группы, а не SID, и передача «NT SERVICE\TrustedInstaller» не работает, поскольку это не настоящая группа, а созданная синтетически. Возможно, существует магическое заклинание для этого, или, по крайней мере, низкоуровневый вызов RPC, но я не думаю, что это стоит усилий.
Поэтому быстрым и грязным способом будет изменение конфигурации службы TI для запуска другого двоичного файла. Странно, но даже если TI делает систему более сложной для вмешательства, он не защищает собственную конфигурацию службы от изменения обычным администратором. Поэтому вы можете выполнить команду, подобную следующей, чтобы удалить произвольный файл из TI:
Запустите службу TI и бац файл исчез. Еще одна причина, по которой это работает, заключается в том, что TI не является защищенным процессом (Protected Process Light, PPL), что странно, поскольку группа TI имеет специальные разрешения на остановку и удаление служб PPL. Я указал на это MSRC (и Алекс Ионеску сделал это в 2013 году, и очевидно, что я не потрудился прочитать это), но они ничего не сделали, чтобы исправить это, поскольку независимо от того, что они делают вид, что PPL не является границей безопасности, ну, пока она не является границей безопасности.
Это все еще кажется хаком, вам придется восстановить службу TI в исходное состояние, иначе такие вещи, как Windows Update, быстро станут недовольными. Поскольку у службы TI есть токен с нужными группами, как насчет того, чтобы просто запустить службу, а затем «позаимствовать» у нее токен для создания нового процесса или для имперсонации?
Как у администратора у нас есть привилегия SeDebugPrivilege, поэтому мы можем просто открыть процесс TI и открыть его токен. Затем мы можем делать с ним все, что захотим. Все очень просто, давайте попробуем.
Обычно в случае с UAC вы указываете явный маркер для назначения новому процессу. Однако если вы не укажете маркер, новый процесс будет наследоваться от назначенного родителя, единственное требование для этого - хэндл процесса, который мы используем в качестве родителя, должен иметь право доступа PROCESS_CREATE_PROCESS. Поскольку у нас есть SeDebugPrivilege, мы можем получить полный доступ к процессу TI, включая право создавать из него новые дочерние процессы. В качестве дополнительного бонуса код создания процесса ядра даже назначит правильный идентификатор сессии для вызывающего, так что мы можем создавать интерактивные процессы. Мы используем это поведение для создания произвольного процесса, работающего как токен службы TI на текущем рабочем столе, используя команду New-Win32Process и передавая объект процесса в параметре -ParentProcess.
Было бы полезно имперсонифицировать токен, не создавая новый процесс. Есть ли способ добиться этого? Конечно, мы можем использовать API NtImpersonateThread, который позволяет вам захватить контекст имперсонации из существующего потока и применить его к другому. Контекст имперсонализации работает следующим образом: сначала ядро попытается захватить токен имперсонализации для потока. Если такого маркера нет, то будет взята копия первичного маркера процесса, связанного с потоком, и выдан за него. И вся прелесть API NtImpersonateThread в том, что для установки родительского процесса не требуется разрешение на доступ к токену, а требуется только доступ THREAD_DIRECT_IMPERSONATION к потоку, который мы можем получить благодаря SeDebugPrivilege. Поэтому мы можем получить поток имперсонации без нового процесса, выполнив следующие действия:
1. Откройте процесс с доступом хотя бы к PROCESS_QUERY_INFORMATION, чтобы получить список его потоков.
2. Откройте первый поток в процессе с доступом THREAD_DIRECT_IMPERSONATION. Будем считать, что этот поток не выдает себя за какого-то низкого пользователя.
3. Call NtImpersonateThread to steal an impersonation token.
Теперь, пока что-то другое не установит токен имперсонации главного потока (и вы ничего не делаете в отдельном потоке), ваша консоль PS будет вести себя так, как будто у нее включена группа TI. Удобно :-)
Если вы проводили время за администрированием системы Windows после Vista, то наверняка сталкивались с группой TrustedInstaller (TI), для которой большинство системных файлов и ключей реестра имеют ACL-режим. Если, например, вы посмотрите на безопасность файла в System32, то заметите, что только TI может удалять и изменять файлы (даже группа администраторов не имеет права), а владелец также является TI, поэтому вы не можете напрямую изменить безопасность.
Однако если вы заглянете в приложение Local Users and Groups, то не найдете там ни пользователя, ни группы TI. Эта статья посвящена тому, что на самом деле представляет собой группа TI, и, что более важно, с помощью PowerShell и модуля NtObjectManager вы можете стать TI, чтобы делать все, что вам нужно.
Где находится TrustedInstaller?
Если TI - это не пользователь или группа, тогда что это? Возможно, более тщательное изучение ACL даст нам некоторое представление. Вы можете использовать команду Get-Acl для чтения дескриптора безопасности из файла, и мы сможем перечислить TI ACE.
Мы видим в члене IdentityReference, что у нас есть группа TI, и она имеет префикс домена «NT SERVICE». Таким образом, это SID службы Windows. Это функция, добавленная в Vista, чтобы позволить каждой запущенной службе иметь группы, которые они могут использовать для проверки доступа, без необходимости добавлять отдельные реальные группы в локальную систему.
Сам SID генерируется на лету как SHA1-хэш заглавной версии имени сервиса. Например, следующий код вычислит фактический SID:
Код:
$name = "TrustedInstaller"
# Calculate service SID
$bytes = [Text.Encoding]::Unicode.GetBytes($name.ToUpper())
$sha1 = [System.Security.Cryptography.SHA1]::Create()
$hash = $sha1.ComputeHash($bytes)
$rids = New-Object UInt32[] 5
[Buffer]::BlockCopy($hash, 0, $rids, 0, $hash.Length)
[string]::Format("S-1-5-80-{0}-{1}-{2}-{3}-{4}", `
$rids[0], $rids[1], $rids[2], $rids[3], $rids[4])
Конечно, вам не нужно этого делать, в NTDLL есть функция RtlCreateServiceSid, а LSASS преобразует имя службы в SID и наоборот. В любом случае, вернемся к сути. Это означает, что существует служба под названием TrustedInstaller, которая должна быть запущена при изменении системных ресурсов. И это именно то, что мы обнаруживаем при запросе с помощью утилиты SC.
Достаточно предыстории, предположим, что мы являемся администратором, как мы можем использовать возможности TrustedInstaller?
Становимся TrustedInstaller
Если вы поищете в Интернете, как удалить ресурсы, принадлежащие TI, то, как правило, найдете статьи, в которых предлагается вручную получить право собственности на файл или ключ, а затем изменить DACL, чтобы добавить группу администраторов. Это связано с тем, что даже обычно послушный COM-объект IFileOperation UAC не сделает этого автоматически, в результате чего вы получите следующее диалоговое окно.
Изменение прав доступа к системным файлам - не самая лучшая идея. Если вы сделаете это неправильно, то легко откроете часть системы для EoP-проблем, особенно с каталогами. Проводник может легко случайно заменить настройки безопасности всех вложенных папок и файлов, причем вернуть исходные значения практически невозможно. Разумеется, цель TI - не дать вам сделать все это в первый раз, но некоторым людям почему-то очень хочется это сделать.
Вы можете предположить, что можно просто добавить текущего пользователя в группу TI и все? К сожалению, LSASS API, такие как NetLocalGroupAddMembers, принимают имя группы, а не SID, и передача «NT SERVICE\TrustedInstaller» не работает, поскольку это не настоящая группа, а созданная синтетически. Возможно, существует магическое заклинание для этого, или, по крайней мере, низкоуровневый вызов RPC, но я не думаю, что это стоит усилий.
Поэтому быстрым и грязным способом будет изменение конфигурации службы TI для запуска другого двоичного файла. Странно, но даже если TI делает систему более сложной для вмешательства, он не защищает собственную конфигурацию службы от изменения обычным администратором. Поэтому вы можете выполнить команду, подобную следующей, чтобы удалить произвольный файл из TI:
Код:
sc config TrustedInstaller binPath= "cmd.exe /C del path\to\file"
Запустите службу TI и бац файл исчез. Еще одна причина, по которой это работает, заключается в том, что TI не является защищенным процессом (Protected Process Light, PPL), что странно, поскольку группа TI имеет специальные разрешения на остановку и удаление служб PPL. Я указал на это MSRC (и Алекс Ионеску сделал это в 2013 году, и очевидно, что я не потрудился прочитать это), но они ничего не сделали, чтобы исправить это, поскольку независимо от того, что они делают вид, что PPL не является границей безопасности, ну, пока она не является границей безопасности.
Это все еще кажется хаком, вам придется восстановить службу TI в исходное состояние, иначе такие вещи, как Windows Update, быстро станут недовольными. Поскольку у службы TI есть токен с нужными группами, как насчет того, чтобы просто запустить службу, а затем «позаимствовать» у нее токен для создания нового процесса или для имперсонации?
Как у администратора у нас есть привилегия SeDebugPrivilege, поэтому мы можем просто открыть процесс TI и открыть его токен. Затем мы можем делать с ним все, что захотим. Все очень просто, давайте попробуем.
Обычно в случае с UAC вы указываете явный маркер для назначения новому процессу. Однако если вы не укажете маркер, новый процесс будет наследоваться от назначенного родителя, единственное требование для этого - хэндл процесса, который мы используем в качестве родителя, должен иметь право доступа PROCESS_CREATE_PROCESS. Поскольку у нас есть SeDebugPrivilege, мы можем получить полный доступ к процессу TI, включая право создавать из него новые дочерние процессы. В качестве дополнительного бонуса код создания процесса ядра даже назначит правильный идентификатор сессии для вызывающего, так что мы можем создавать интерактивные процессы. Мы используем это поведение для создания произвольного процесса, работающего как токен службы TI на текущем рабочем столе, используя команду New-Win32Process и передавая объект процесса в параметре -ParentProcess.
Было бы полезно имперсонифицировать токен, не создавая новый процесс. Есть ли способ добиться этого? Конечно, мы можем использовать API NtImpersonateThread, который позволяет вам захватить контекст имперсонации из существующего потока и применить его к другому. Контекст имперсонализации работает следующим образом: сначала ядро попытается захватить токен имперсонализации для потока. Если такого маркера нет, то будет взята копия первичного маркера процесса, связанного с потоком, и выдан за него. И вся прелесть API NtImpersonateThread в том, что для установки родительского процесса не требуется разрешение на доступ к токену, а требуется только доступ THREAD_DIRECT_IMPERSONATION к потоку, который мы можем получить благодаря SeDebugPrivilege. Поэтому мы можем получить поток имперсонации без нового процесса, выполнив следующие действия:
1. Откройте процесс с доступом хотя бы к PROCESS_QUERY_INFORMATION, чтобы получить список его потоков.
2. Откройте первый поток в процессе с доступом THREAD_DIRECT_IMPERSONATION. Будем считать, что этот поток не выдает себя за какого-то низкого пользователя.
3. Call NtImpersonateThread to steal an impersonation token.
Теперь, пока что-то другое не установит токен имперсонации главного потока (и вы ничего не делаете в отдельном потоке), ваша консоль PS будет вести себя так, как будто у нее включена группа TI. Удобно :-)