Как создать новый процесс с более низким уровнем целостности (IL)?
Похоже, что начиная с Windows Vista, процессы с более низким уровнем целостности (IL) не могут отправлять сообщения процессам с более высоким уровнем целостности. Это имеет смысл с точки зрения безопасности, но нарушает некоторые наши межпроцессные взаимодействия.
У нас есть унаследованное приложение (Процесс A), которое, к сожалению, должно работать с повышенными привилегиями "администратора" (это достигается установкой его ярлыка, который всегда запускается от имени администратора). Иногда требуется создать отдельное приложение (Процесс B). В результате процесс B наследует те же повышенные привилегии (и IL), что и процесс A. В этом и заключается проблема. Могут существовать другие независимые экземпляры процесса B, которые не имеют повышенных привилегий, и все эти экземпляры процесса B должны иметь возможность отправлять сообщения друг другу. Это, очевидно, дает сбой, если один экземпляр процесса B повышен, а другой - нет.
Я знаю, что мы можем открыть дыры в фильтре сообщений UIPI, используя ChangeWindowMessageFilter
Метод API, но это не похоже на идеальное решение. Вместо этого я бы предпочел, чтобы процесс A порождал процесс B с ограниченными привилегиями, в частности, чтобы он мог взаимодействовать с другими экземплярами процесса B. Я думаю, что по умолчанию другие экземпляры Процесса B работают на "Среднем" IL, поэтому я бы хотел, чтобы Процесс A порождал экземпляры Процесса B с этим же IL.
Мои поиски привели меня к CreateProcessAsUser
а также CreateRestrictedToken
Методы API, но, несмотря на эту документацию, все различные аспекты токенов и дескрипторов безопасности и так далее меня очень смущают.
Я также сталкивался здесь с некоторыми потоками ( Запуск процесса с минимально возможными привилегиями в winapi и Dropping привилегиями в C++ в Windows), но я не могу найти хороших примеров с кодом.
Может ли кто-нибудь предоставить мне простой, но "правильный" код, который поможет мне порождать дочерние процессы, используя соответствующий Windows IL? В частности, я хотел бы привести пример того, как взять существующий токен Process A и преобразовать его, чтобы он имел уменьшенные привилегии (я уверен, что смогу выяснить остальное). Мне действительно неясно, нужно ли мне дублировать токен процесса перед его изменением.
3 ответа
Предупреждение! Хотя этот подход, вероятно, был более или менее приемлемым для оригинального плаката, в целом это не очень хорошая идея. В частности, обратите внимание (согласно ветке комментариев), что искусственно манипулированные токены вызывают проблемы в более сложных приложениях, поэтому, если вы их используете, обязательно придерживайтесь базового Win32 API. Конечно, есть и потенциальные последствия для безопасности.
В большинстве сценариев, аналогичных сценариям OP, вероятно, было бы предпочтительнее заменить ярлык, запускающий приложение с повышенными правами, на приложение запуска. Затем модуль запуска может оставаться запущенным до тех пор, пока запущено приложение с повышенными правами, и предоставить естественный ограниченный токен для приложения с повышенными правами, которое можно использовать для запуска процессов без повышенных прав.
Код для запуска процесса с низким уровнем целостности, аналогичный вашему случаю, содержится в статье " Разработка приложений для запуска с низким уровнем целостности" в MSDN.
Во-первых, вы дублируете токен процесса, поскольку вы не можете (или, по крайней мере, не должны) связываться с токеном, который уже используется. Затем вы используете SetTokenInformation с классом TokenIntegrityLevel, чтобы установить уровень целостности. Кажется, что в примере кода есть ошибка, так как правильный SID для низкого уровня целостности - S-1-16-4096, а не S-1-16-1024, но в любом случае вам нужен средний уровень целостности, то есть S-1-16-8192. Их можно найти здесь.
После того, как вы это заработаете (то есть, когда вы сможете запускать процессы средней целостности из вашего процесса высокой целостности), вам следует попробовать использовать CreateRestrictedToken для создания нового токена вместо DuplicateToken и удаления токена Администраторов и всех привилегий (кроме SeChangeNotifyPrivilege), В противном случае новые процессы будут иметь среднюю целостность, но при этом будут обладать правами администратора, что может упростить для любого вредоносного кода, который может быть запущен в том же сеансе, повышение своих привилегий.
Я использовал подход, описанный здесь, чтобы достичь этого. Основная идея заключается в том, чтобы попросить Explorer запустить для вас процесс B. Поскольку Explorer обычно работает на среднем уровне целостности, это дает вам то, что вы хотите.
http://brandonlive.com/2008/04/26/getting-the-shell-to-run-an-application-for-you-part-1-why/ http://brandonlive.com/2008/04/ 27 / посаживание в скорлупе и работайте-ан-приложения для вы-части-2-хау /
Первая ссылка, по крайней мере, даст вам хороший фон.
У нас есть унаследованное приложение (Процесс A), которое, к сожалению, должно работать с повышенными привилегиями "администратора" (это достигается установкой его ярлыка, который всегда запускается от имени администратора).
Более чистый способ сделать это - установить требуемый уровень выполнения в манифест.
Возможно, я не отвечаю на ваш полный вопрос, но, как вы упомянули о CreateProcessAsUser и CreateRestrictedToken. У меня есть код, который работает с этим API. Код, который я написал, был написан на основе следующего:
источник:[Windows Vista для разработчиков - Часть 4 - Контроль учетных записей пользователей] ( http://weblogs.asp.net/kennykerr/Windows-Vista-for-Developers-_1320_-Part-4-_1320_-User-Account-Control)!
Код доступен по следующей ссылке.
Пример кода: http://pastebin.com/XMUAehF9