Как создать новый процесс с более низким уровнем целостности (IL)?

Похоже, что начиная с Windows Vista процессы с более низким уровнем целостности (IL) не могут отправлять сообщения процессам с более высокими уровнями целостности. Это имеет смысл с точки зрения безопасности, но это нарушает некоторые из наших межпроцессных коммуникаций.

У нас есть устаревшее приложение (Process A), которое, к сожалению, должно выполняться с повышенными привилегиями "admin" (выполняется путем установки его ярлыка для запуска всегда как администратор). Иногда ему необходимо создать экземпляр отдельного приложения (процесс B). В результате процесс B наследует те же повышенные привилегии (и IL), что и процесс A. В этом и заключается проблема. Могут быть другие независимые экземпляры процесса B, которые не имеют повышенных привилегий, и все эти экземпляры Process B должны иметь возможность отправлять сообщения друг другу. Это явно не удается, если один экземпляр процесса B повышен, а другой - нет.

Я знаю, что мы можем открывать отверстия в фильтре сообщений UIPI с помощью метода API ChangeWindowMessageFilter, но это не похоже на идеальное решение. Вместо этого я бы предпочел бы, чтобы Process A запускал процесс B с ограниченными правами, в частности, чтобы он мог общаться с другими экземплярами Process B. Я думаю, что по умолчанию другие экземпляры Process B выполняются на "Medium" IL, поэтому я хотел бы, чтобы Process A породил экземпляры Process B с этим же IL.

Мои поиски привели меня к CreateProcessAsUser и CreateRestrictedToken API, но, несмотря на эту документацию, все различные грани токенов и дескрипторов безопасности и т.д. все еще очень запутывают меня.

Здесь также встречаются некоторые темы (Выполнение процесса с наименьшими возможными привилегиями в winapi и Удаление привилегий в С++ в Windows), но я не могу найти хороших примеров с кодом.

Может ли кто-нибудь предоставить мне какой-то простой, но "правильный" код, который поможет мне порождать дочерние процессы с помощью соответствующего Windows IL? В частности, я хотел бы привести пример использования существующего токена процесса A и преобразовать его, чтобы он имел уменьшенные привилегии (я уверен, что смогу выяснить остальные). Я действительно не понимаю, нужно ли мне дублировать токен процесса, прежде чем изменять его.

Ответы

Ответ 1

Внимание! Хотя этот подход, вероятно, был более или менее нормальным для оригинального плаката, на самом деле это не очень хорошая идея. В частности, обратите внимание (в соответствии с комментарием), что, как сообщается, искусственно манипулируемые токены вызывают проблемы в более сложных приложениях, поэтому, если вы их используете, обязательно придерживайтесь базового API Win32. Разумеется, есть и потенциальные последствия для безопасности.

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


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

Во-первых, вы дублируете токен процесса, поскольку вы не можете (или, по крайней мере, не должны) путаться с токеном, который уже используется. Затем вы используете SetTokenInformation с классом TokenIntegrityLevel для установки уровня целостности. В коде примера появляется ошибка, так как правильный SID для низкого уровня целостности - это S-1-16-4096, а не S-1-16-1024, но вы все равно хотите, чтобы уровень целостности среды был равен S -1-16-8192. Их можно найти здесь.

Как только вы начнете работать (то есть, как только вы сможете запускать процессы обеспечения целостности из процесса высокой целостности), вы должны попробовать использовать CreateRestrictedToken для создания нового токена вместо DuplicateToken и удалить токен "Администраторы" и все привилегии ( кроме SeChangeNotifyPrivilege). В противном случае новые процессы будут иметь среднюю целостность, но при этом будут иметь привилегии администратора, что упростит любой вредоносный код, который может работать в одном сеансе, чтобы повысить его привилегии.

Ответ 2

Я использовал описанный здесь подход, чтобы выполнить это. Основная идея - попросить Проводника запустить процесс 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/getting-the-shell-to-run-an-application-for-you-part-2-how/

Первая ссылка по крайней мере даст вам хороший фон.

У нас есть устаревшее приложение (Process A), которое, к сожалению, должно выполняться с повышенными привилегиями администратора (выполняется путем установки его ярлыка для запуска всегда как администратор).

Более чистый способ сделать это - установить requestExecutionLevel в манифест.

Ответ 3

Возможно, я не отвечаю на ваш полный вопрос, но, как вы уже упоминали о CreateProcessAsUser и CreateRestrictedToken. У меня есть код, который работает с этим API. Код, который я написал, был написан на основе следующего типа.

источник: [Windows Vista для разработчиков - часть 4 - Контроль учетных записей пользователей] (http://weblogs.asp.net/kennykerr/Windows-Vista- для-разработчиков-1320-Part-4-1320-User-Account-Control)!

Код доступен по следующей ссылке.

Пример кода: http://pastebin.com/XMUAehF9