Поделиться через


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

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

Запуск calc.exe при низкой целостности

  1. Создайте копию c:\Windows\system32\calc.exe во временную папку.

  2. Используйте программу icacls, чтобы установить низкий уровень целостности временного файла lowcalc.exe с помощью команды icacls:

    icacls lowcalc.exe /setintegritylevel Low

  3. Запустите версию calc.exe с низкой целостностью.

На следующем рисунке показаны шаги по запуску Калькулятора Windows в процессе низкой целостности.

Рис. 9. Запуск калькулятора Windows при низкой целостности

Вы можете использовать Обозреватель процесса, чтобы убедиться, что файл изображения, lowcalc.exe, действительно работает с низкой целостностью. Столбец Уровень целостности находится в правой части изображения.

Рис. 10. Низкий процесс калькулятора

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

Используйте полезные средства, такие как монитор процессов из Sysinternals.com, чтобы получить представление о том, какие файлы и ресурсы реестра приложение в настоящее время использует для доступа на запись, который будет завершаться сбоем при низкой целостности.

Хотя можно изменить приложение для работы полностью с низкой целостностью, некоторые функции приложения могут правильно работать только в том случае, если они реализованы в процессе средней целостности. Приложение, работающее с низкой целостностью, может иметь одну часть приложения в процессе низкой целостности, например для обработки недоверенных данных из Интернета. Другая часть приложения может быть реализована в процессе "брокера" со средним уровнем целостности для обработки небольшого набора действий, инициированных пользователем. Взаимодействие между процессами с низкой и средней целостностью в приложении можно обрабатывать с помощью различных механизмов IPC. Часть приложения со средним уровнем целостности должна предполагать, что все данные и код в процессе низкой целостности являются ненадежными.

Защищенное интернет-Обозреватель — это приложение, которое переработано для запуска в процессе с низкой целостностью. Дополнительные сведения о защищенном режиме Обозреватель Интернета см. в разделе Общие сведения и работа в защищенном режиме Обозреватель Интернета (https://go.microsoft.com/fwlink/?LinkId=90931).

Ниже приведены main разделы по проектированию приложения, которое будет работать с низкой целостностью.

  • Запуск дочернего процесса с низкой целостностью
  • Доступные для записи расположения для приложений с низкой целостностью
  • Взаимодействие между низкой целостностью и процессами более высокого уровня

Запуск процесса с низкой целостностью

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

Запуск процесса с низкой целостностью

  1. Дублируйте дескриптор текущего процесса, который находится на среднем уровне целостности.

  2. Используйте SetTokenInformation, чтобы задать низкий уровень целостности в маркере доступа.

  3. Используйте CreateProcessAsUser, чтобы создать новый процесс, используя дескриптор маркера доступа с низкой целостностью.

CreateProcessAsUser обновляет дескриптор безопасности в новом дочернем процессе и дескриптор безопасности, чтобы маркер доступа соответствовал уровню целостности маркера доступа с низкой целостностью.

Этот процесс демонстрируется в следующем примере кода.

void CreateLowProcess()
{
 
    BOOL                  fRet;
    HANDLE                hToken        = NULL;
    HANDLE                hNewToken     = NULL;
    PSID                  pIntegritySid = NULL;
    TOKEN_MANDATORY_LABEL TIL           = {0};
    PROCESS_INFORMATION   ProcInfo      = {0};
    STARTUPINFO           StartupInfo   = {0};

 // Notepad is used as an example
 WCHAR wszProcessName[MAX_PATH] =
   L"C:\\Windows\\System32\\Notepad.exe";

 // Low integrity SID
 WCHAR wszIntegritySid[20] = L"S-1-16-1024";
 PSID pIntegritySid = NULL;

    fRet = OpenProcessToken(GetCurrentProcess(),
                            TOKEN_DUPLICATE |
                              TOKEN_ADJUST_DEFAULT |
                              TOKEN_QUERY |
                              TOKEN_ASSIGN_PRIMARY,
                            &hToken);

    if (!fRet)
    {
        goto CleanExit;
    }

    fRet = DuplicateTokenEx(hToken,
                            0,
                            NULL,
                            SecurityImpersonation,
                            TokenPrimary,
                            &hNewToken);

    if (!fRet)
    {
        goto CleanExit;
    }

    fRet = ConvertStringSidToSid(wszIntegritySid, &pIntegritySid);

    if (!fRet)
    {
        goto CleanExit;
    }

    TIL.Label.Attributes = SE_GROUP_INTEGRITY;
    TIL.Label.Sid        = pIntegritySid;

    //
    // Set the process integrity level
    //

    fRet = SetTokenInformation(hNewToken,
                               TokenIntegrityLevel,
                               &TIL,
                               sizeof(TOKEN_MANDATORY_LABEL) + GetLengthSid(pIntegritySid));

    if (!fRet)
    {
        goto CleanExit;
    }

    //
    // Create the new process at Low integrity
    //

    fRet  = CreateProcessAsUser(hNewToken,
                                NULL,
                                wszProcessName,
                                NULL,
                                NULL,
                                FALSE,
                                0,
                                NULL,
                                NULL,
                                &StartupInfo,
                                &ProcInfo);

CleanExit:

    if (ProcInfo.hProcess != NULL)
    {
        CloseHandle(ProcInfo.hProcess);
    }

    if (ProcInfo.hThread != NULL)
    {
        CloseHandle(ProcInfo.hThread);
    }

    LocalFree(pIntegritySid);

    if (hNewToken != NULL)
    {
        CloseHandle(hNewToken);
    }

    if (hToken != NULL)
    {
        CloseHandle(hToken);
    }

    return fRet;
}

Доступные для записи расположения с низкой целостностью

Windows Vista имеет определенные расположения файлов и реестров, которым назначены низкие обязательные метки, чтобы обеспечить доступ к приложениям с низким уровнем целостности для записи. В таблице 10 показаны эти доступные для записи расположения.

Таблица 10 Расположения, доступные для записи для низких обязательных меток

Расположение Записываемая область

Реестр

Процессы с низким уровнем целостности могут выполнять запись в подразделы и создавать их в HKEY_CURRENT_USER\Software\AppDataLow

Файловая система

Процессы с низким уровнем целостности могут записывать и создавать вложенные папки в папке %USER PROFILE%\AppData\LocalLow.

Понижение обязательной метки ресурса

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

Примечание

Приложения, которые принимают входные данные или совместно используют ресурсы с процессами с более низкой целостностью, должны предполагать, что данные, предоставляемые процессами с более низкой целостностью, не могут быть доверенными, и затем должны выполнить соответствующую проверку. Например, в защищенном режиме интернет-Обозреватель отображается диалоговое окно Сохранить как из процесса Internet Обозреватель User Broker. Это позволяет пользователям подтвердить, что они хотят сохранить файл с помощью процесса, который выполняется с более высокими правами, чем защищенный режим интернета Обозреватель.

Так как приложения с низким уровнем целостности могут выполнять запись только в ресурсы с низким уровнем целостности, необходимо снизить уровень целостности общих ресурсов.

Снижение уровня целостности общих ресурсов

  1. Создайте дескриптор безопасности SDDL, который определяет низкую обязательную метку.

  2. Преобразуйте строку SDDL в дескриптор безопасности.

  3. Назначьте дескриптору безопасности атрибут низкой целостности.

  4. Назначьте дескриптор безопасности общему ресурсу.

Этот процесс показан в следующем примере кода.

#include <sddl.h>
#include <AccCtrl.h>
#include <Aclapi.h>

void SetLowLabelToFile()
{
 // The LABEL_SECURITY_INFORMATION SDDL SACL to be set for low integrity 
 #define LOW_INTEGRITY_SDDL_SACL_W L"S:(ML;;NW;;;LW)"
 DWORD dwErr = ERROR_SUCCESS;
 PSECURITY_DESCRIPTOR pSD = NULL;  

 PACL pSacl = NULL; // not allocated
 BOOL fSaclPresent = FALSE;
 BOOL fSaclDefaulted = FALSE;
 LPCWSTR pwszFileName = L"Sample.txt";

 if (ConvertStringSecurityDescriptorToSecurityDescriptorW(
     LOW_INTEGRITY_SDDL_SACL_W, SDDL_REVISION_1, &pSD, NULL)) 
 {
  if (GetSecurityDescriptorSacl(pSD, &fSaclPresent, &pSacl, 
     &fSaclDefaulted))
  {
   // Note that psidOwner, psidGroup, and pDacl are 
   // all NULL and set the new LABEL_SECURITY_INFORMATION
   dwErr = SetNamedSecurityInfoW((LPWSTR) pwszFileName, 
         SE_FILE_OBJECT, LABEL_SECURITY_INFORMATION, 
         NULL, NULL, NULL, pSacl);
  }
  LocalFree(pSD);
 }
}

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

Взаимодействие между процессами с низкой целостностью и более высоким уровнем целостности

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

Некоторые формы IPC доступны для процессов с низкой целостностью для взаимодействия с процессами более высокого уровня целостности. Компоненты в Windows Vista блокируют следующие типы взаимодействия.

  • Большинство сообщений окон и обработчиков процессов блокируются UIPI.

  • Открытие процесса и использование CreateRemoteThread блокируется обязательной меткой для объектов процесса.

  • Открытие раздела общей памяти для доступа на запись заблокировано.

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

  • Привязка к работающему экземпляру службы COM является блоком.
    Однако можно использовать и другие типы обмена данными между процессом с низкой целостностью и процессом с более высоким уровнем целостности. Ниже приведены типы взаимодействия, которые можно использовать.

  • Буфер обмена (копирование и вставка)

  • Удаленный вызов процедур (RPC)

  • Сокеты

  • Сообщения окна, которые процессу с более высоким уровнем целостности было явно разрешено получать из процессов с более низкой целостностью путем вызова ChangeWindowMessageFilter

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

    Важно!

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

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

  • Именованные каналы, где создатель явно задает обязательную метку в канале, чтобы разрешить доступ к процессам с более низкой целостностью.

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

Общее руководство по проектированию интерфейсов, которые будет вызывать процесс с низкой целостностью, — никогда не доверять вызывающему объекту или входным данным. Брокер средней целостности может предоставить интерфейс для создания файла по заданному пути и разрешения приложению с низкой целостностью вызывать интерфейс. Однако это не повнимает цель запуска приложения при низкой целостности. Более лучшая схема заключается в том, чтобы процесс с низкой целостностью вызывал интерфейс, который запрашивает приложение со средним уровнем целостности, чтобы представить пользователю общий диалог файла, который процесс с низкой целостностью не может управлять с помощью оконных сообщений. Таким образом, пользователь может просматривать и выбирать файл для открытия или создания, а процесс обеспечения средней целостности выполняет все операции с файлами. Этот тип сценария "Сохранить как" является примером того, как защищенный режим интернет-Обозреватель использует собственный процесс брокера для сохранения веб-страницы в профиле пользователя.

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