CreateMutex терпит неудачу после олицетворения

Вот код, где я пытаюсь выдать себя за пользователя, а затем создать мьютекс. Мьютекс не создается. Я получаю ошибку ERROR_ACCESS_DENIED.

void Impersonate()
{
DWORD logonType = LOGON32_LOGON_INTERACTIVE;
DWORD logonProvider = LOGON32_PROVIDER_DEFAULT;
HANDLE userToken;
HANDLE hMutex;
DWORD err;

LPSTR user = "zoom"; // the user I created myself on my machine.
// It has Administrator privileges, and my account,
// from which I start the app, is Admin too
LPSTR password = "zoom";
LPSTR domain = ".";
hMutex = NULL;

LogonUserA(user, domain, password, logonType, logonProvider,&userToken);

// just to make sure that mutexes are created fine before impersonation
hMutex = CreateMutexA( NULL, FALSE, "mutex_good" );

ImpersonateLoggedOnUser(userToken);

hMutex = CreateMutexA( NULL, FALSE, "mutex_797" ); // I can set any
// random name, no difference
if( hMutex == NULL )
{
err = GetLastError();
// here err is ERROR_ACCESS_DENIED
}

CloseHandle(userToken);
}

Я нашел несколько похожих тем, но все они обсуждали создание мьютекса с тем же именем из двух разных пользовательских контекстов, то есть мьютекс «MUTEX_1» уже был создан до олицетворения и пытался вызвать CreateMutex с тем же именем, но из олицетворенного сбой пользователя из-за отсутствия привилегий.

Это не тот случай, так как я совершенно уверен, что перед этим кодом не создается мьютекс с тем же именем (или вообще каким-либо мьютексом).

Я думаю, что я должен передать что-то ненулевое в CreateMutex, но что именно?

Я не очень хорош в безопасности Windows. Я понимаю, что передача NULL в качестве первого параметра CreateMutex означает, что будут использоваться атрибуты безопасности по умолчанию. В этом случае это будут параметры безопасности, связанные с потоком, то есть с имитируемым пользователем.

Я прав с моими предположениями?

4

Решение

прежде всего вам нужно понять Пространства имен NT и использовать WinObj инструмент.

это как небольшая файловая система в памяти с папками и разными «файлами» (здесь под «файлами» подразумеваются разные типы объектов — Event, Mutant(Мьютекс), Section, Device…) каждый раз, когда вы создаете именованный объект — он помещается в какую-то папку в Пространства имен NT. папки здесь (например, папки в NTFS) имеют дескрипторы безопасности. В результате не каждый может создать объект в любой папке.

Перефразируя то, что вы делаете на языке файловой системы (возможно, это будет более понятно):

я (John) попробуйте создать файл «mutex_good» под %USERPROFILE%\Documents и это нормально. потому что это моя личная папка, и у меня есть доступ для записи в нее.

тогда я вхожу (подражаю) как zoom и попробуйте создать файл «mutex_797» снова под %USERPROFILE%\Documents (%USERPROFILE% в обоих случаях расширяться по тому же пути, скажем c:\Users\John подражание не влияет на это)

а также zoom не удалось создать файл. Зачем ? просто у него нет прав на это. только John, Administartors, SYSTEM иметь доступ к записи c:\Users\John но нет zoom,

теперь давай вернемся к Пространства имен NT. когда мы звоним CreateMutexA( NULL, FALSE, "mutex_797" ); где "mutex_797" будет размещен?

если ты не appcontainer и не запускается в системе session 0 — ты бегаешь в каком-то пользователе session <N> и ваши именованные объекты будут помещены в \Sessions\<N>\BaseNamedObjects каталог, где N = 1,2 ..

так зовите CreateMutexA( NULL, FALSE, "mutex_797" );

попробуйте создать мьютекс в \Sessions\<N>\BaseNamedObjects\mutex_797

Однако в \Sessions\<N>\BaseNamedObjects существуют следующие SymbolicLinks (это как в файловой системе NTFS):

Global -> \BaseNamedObjects
Local  -> \Sessions\<N>\BaseNamedObjects
Session -> \Sessions\BNOLINKS

так сказать, если вы позвоните CreateMutexA( NULL, FALSE, "Global\\mutex_797" );

Диспетчер объектов попробуйте разместить свой мьютекс под \BaseNamedObjects\mutex_797

для получения дополнительной информации об этом прочитать Пространства имен объектов ядра

и конечно надо понимать Как работает AccessCheck

Для объектов каталога определены следующие права доступа:

//
// Object Manager Directory Specific Access Rights.
//

#define DIRECTORY_QUERY                 (0x0001)
#define DIRECTORY_TRAVERSE              (0x0002)
#define DIRECTORY_CREATE_OBJECT         (0x0004)
#define DIRECTORY_CREATE_SUBDIRECTORY   (0x0008)

Также можете больше прочитать об этом на DirectoryObject DesiredAccess Флаги

нам нужно DIRECTORY_CREATE_OBJECT доступ (Доступ для создания имени к объекту каталога) для создания мьютекса (или события, или любого объекта) в каталоге

Теперь для понимания, почему вы можете создать мьютекс в \Sessions\<N>\BaseNamedObjects но zoom нельзя — нужно искать Security Descriptor для этой папки. я бросаю это:

T FL AcessMsK Sid
0 00 000F000F S-1-5-90-0-1 DWM-1
0 00 000F000F S-1-5-18 SYSTEM
0 0B 10000000 S-1-5-18 SYSTEM
0 0B 10000000 S-1-3-0 CREATOR OWNER
0 00 000F000F S-1-5-21-4026734978-3280735129-2412320105-1001 John
0 0B 10000000 S-1-5-5-0-294807 LogonSessionId_0_294807
0 00 0002000F S-1-5-5-0-294807 LogonSessionId_0_294807
0 00 0002000F S-1-5-32-544 Administrators
0 02 00000003 S-1-1-0 Everyone
0 00 00000002 S-1-5-12 RESTRICTED
17 00 00000001 S-1-16-4096 Low Mandatory Level

так у кого DIRECTORY_CREATE_OBJECT (4) здесь? DWM-1, SYSTEM, Administrators, текущие пользователи сеанса входа в систему (LogonSessionId_0_294807 ), текущий пользователь (John) — и все. zoom нет такого доступа.

например Everyone иметь (3) — DIRECTORY_QUERY|DIRECTORY_TRAVERSEName lookup а также Query но нет Name creation

Вы можете спросить, где в этом случае я могу создать мьютекс после подражания? нужно использовать \BaseNamedObjects ( глобальное пространство имен )ИЛИ ЖЕ \BaseNamedObjects\Restricted каталог — я проверяю его дескриптор безопасности и результат:

за \BaseNamedObjects

T FL AcessMsK Sid
0 00 0002000F S-1-1-0 Everyone
0 00 00000002 S-1-5-12 RESTRICTED
0 00 000F000F S-1-5-90-0-0
0 00 000F000F S-1-5-18 SYSTEM
17 00 00000001 S-1-16-4096 Low Mandatory Level

за \BaseNamedObjects\Restricted

T FL AcessMsK Sid
0 00 0002000F S-1-1-0 Everyone
0 00 0002000F S-1-5-12 RESTRICTED
0 00 000F000F S-1-5-90-0-0
0 00 000F000F S-1-5-18 SYSTEM
17 00 00000001 S-1-16-4096 Low Mandatory Level

так как вы можете просматривать Everyone здесь есть 2000F — все необходимые доступ. надежда zoom является членом Everyone ? следующий код, я уверен, будет работать

CreateMutexA(0, 0, "Global\\mutex_797");

за \BaseNamedObjects (глобальное пространство имен) существует одно исключение:

Создание объекта сопоставления файлов в глобальном пространстве имен
используя CreateFileMapping, из сеанса, отличного от нулевого сеанса, является
привилегированная операция. Из-за этого приложение работает в
произвольный сеанс сервера Узел сеансов удаленных рабочих столов (Узел сеансов удаленных рабочих столов)
должен быть включен SeCreateGlobalPrivilege для создания
объект сопоставления файлов в глобальном пространстве имен успешно.
проверка привилегий ограничивается созданием объектов сопоставления файлов,
и не распространяется на открытие существующих. Например, если услуга
или система создает объект сопоставления файлов, любой процесс, выполняющийся в
любой сеанс может получить доступ к этому объекту сопоставления файлов при условии, что пользователь
имеет необходимый доступ.

но для Mutex или, скажем, Event — не нужно SeCreateGlobalPrivilege включен


Вы также можете сказать, но zoom является учетной записью администратора и Administrator иметь доступ к \Sessions\<N>\BaseNamedObjects — так почему это не работает? потому что с LOGON32_LOGON_INTERACTIVE а также UAC система присваивается zoom фильтрованный токен Administrator Группа (S-1-5-32-544) существует в токене но с SE_GROUP_USE_FOR_DENY_ONLY только атрибут — в результате он игнорирует ACE с разрешенным доступом для SID.
а также zoom есть другой LogonSessionId_0_XXX SID — как результат и ERROR_ACCESS_DENIED

как отметил @ Гарри Джонстон — если мы будем использовать LOGON32_LOGON_BATCH вместо LOGON32_LOGON_INTERACTIVE — мы получили повышенный токен — здесь Administrator Группа будет с SE_GROUP_ENABLED атрибут — включен для проверок доступа для разрешенных ACE доступа

или как я предложил — используйте Global\ префикс перед именем — для объекта размещения \BaseNamedObjects где Everyone иметь полный доступ

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

первый параметр — указатель на SECURITY_ATTRIBUTES Позволяет переписать дескриптор безопасности по умолчанию для нового объекта. это контроль, кто будет иметь доступ к нему. но это не дает вам более или менее доступ к каталогу, где вы пытаетесь разместить объект — вы должны иметь DIRECTORY_CREATE_OBJECT доступ предоставлен, и мы не можем повлиять на это SECURITY_ATTRIBUTES — это влияет на новый объект но не в существующем каталоге

и, наконец, некоторая визуализация NT Namespace
введите описание изображения здесь

4

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]