Дескриптор безопасности канала с низкой или средней / высокой целостностью - PullRequest
6 голосов
/ 06 марта 2012

У меня проблемы с настройкой дескриптора безопасности при создании NamedPipe. Я хочу, чтобы канал, созданный в службе Windows (высокая целостность), был открыт из процессов средней и низкой целостности.

Я работаю на Windows 7 x64. Я не совсем понимаю, что я здесь делаю, но вот код, который я использую для создания дескриптора безопасности для каналов, которые я создаю. Следующий код не позволяет мне открывать каналы, созданные как с высокой, так и средней целостностью, в результате процессов с низкой целостностью:



    PSID psidWorldSid = NULL, pAdminSID = NULL, pLowSID = NULL, pHighSID = NULL;
    WCHAR wszIntegritySid[] = L"S-1-16-4096";
    WCHAR wszSystemSid[] = L"S-1-16-16384";
    PACL pACL = NULL;
    PSECURITY_DESCRIPTOR pSD = NULL;
    SECURITY_ATTRIBUTES sa;
    SID_IDENTIFIER_AUTHORITY SIDAuthNT = SECURITY_NT_AUTHORITY;
    SID_IDENTIFIER_AUTHORITY siaWorldSidAuthority = SECURITY_WORLD_SID_AUTHORITY;
    EXPLICIT_ACCESS ea[4];

    //  Create a security descriptor for the log file that allows
    //  access from both the privileged service and the non-privileged
    //  user mode programs

    AllocateAndInitializeSid(&siaWorldSidAuthority, 1,
        SECURITY_WORLD_RID,
        0, 0, 0, 0, 0, 0, 0,
        &psidWorldSid);

    ZeroMemory(&ea, sizeof(ea));
    ea[0].grfAccessPermissions = FILE_ALL_ACCESS | GENERIC_WRITE | GENERIC_READ;
    ea[0].grfAccessMode = SET_ACCESS;
    ea[0].grfInheritance= NO_INHERITANCE;
    ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
    ea[0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
    ea[0].Trustee.ptstrName  = (LPTSTR) psidWorldSid;

    // Create a SID for the BUILTIN\Administrators group.
    AllocateAndInitializeSid(&SIDAuthNT, 2,
        SECURITY_BUILTIN_DOMAIN_RID,
        DOMAIN_ALIAS_RID_ADMINS,
        0, 0, 0, 0, 0, 0,
        &pAdminSID);

    // Initialize an EXPLICIT_ACCESS structure for an ACE.
    // The ACE will allow the Administrators group full access to
    // the key.
    ea[1].grfAccessPermissions = FILE_ALL_ACCESS | GENERIC_WRITE | GENERIC_READ;
    ea[1].grfAccessMode = SET_ACCESS;
    ea[1].grfInheritance= NO_INHERITANCE;
    ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
    ea[1].Trustee.TrusteeType = TRUSTEE_IS_GROUP;
    ea[1].Trustee.ptstrName  = (LPTSTR) pAdminSID;

    AllocateAndInitializeSid(&siaWorldSidAuthority, 1,
        SECURITY_MANDATORY_LOW_RID,
        0,
        0, 0, 0, 0, 0, 0,
        &pLowSID);

    ea[2].grfAccessPermissions = FILE_ALL_ACCESS | GENERIC_WRITE | GENERIC_READ;
    ea[2].grfAccessMode = SET_ACCESS;
    ea[2].grfInheritance= NO_INHERITANCE;
    ea[2].Trustee.TrusteeForm = TRUSTEE_IS_SID;
    ea[2].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
    ea[2].Trustee.ptstrName  = (LPTSTR) pLowSID;

    AllocateAndInitializeSid(&siaWorldSidAuthority, 1,
        SECURITY_MANDATORY_HIGH_RID,
        0,
        0, 0, 0, 0, 0, 0,
        &pHighSID);

    ea[3].grfAccessPermissions = FILE_ALL_ACCESS | GENERIC_WRITE | GENERIC_READ;
    ea[3].grfAccessMode = SET_ACCESS;
    ea[3].grfInheritance= NO_INHERITANCE;
    ea[3].Trustee.TrusteeForm = TRUSTEE_IS_SID;
    ea[3].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
    ea[3].Trustee.ptstrName  = (LPTSTR) pHighSID;

    SetEntriesInAcl(4, ea, NULL, &pACL);

    pSD = (PSECURITY_DESCRIPTOR)LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH); 
    InitializeSecurityDescriptor( pSD, SECURITY_DESCRIPTOR_REVISION);
    SetSecurityDescriptorDacl( pSD, TRUE, pACL, FALSE );
    ZeroMemory( &sa, sizeof(SECURITY_ATTRIBUTES));


    sa.nLength              = sizeof(SECURITY_ATTRIBUTES);
    sa.lpSecurityDescriptor = pSD;
    sa.bInheritHandle       = FALSE;

    m_hPipe = CreateNamedPipeA(
                m_szName.c_str(),
                PIPE_ACCESS_DUPLEX,
                PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | BlockFlag,
                PIPE_UNLIMITED_INSTANCES,
                BUFFER_SIZE,
                BUFFER_SIZE,
                NMPWAIT_USE_DEFAULT_WAIT,
                &sa
                );

    if (psidWorldSid) 
        FreeSid(psidWorldSid);
    if (pAdminSID) 
        FreeSid(pAdminSID);
    if (pLowSID) 
        FreeSid(pLowSID);
    if (pHighSID) 
        FreeSid(pHighSID);
    if (pACL) 
        LocalFree(pACL);
    if (pSD) 
        LocalFree(pSD);

Кажется, что он работает почти нормально, когда я создаю дескриптор безопасности из строки:

ConvertStringSecurityDescriptorToSecurityDescriptorW( L"S:(ML;;NW;;;LW)", SDDL_REVISION_1, &pSD, NULL);

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

Спасибо за любые предложения.

С уважением, Kuba

Ответы [ 2 ]

5 голосов
/ 16 марта 2012

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

Я решил эту проблему, установив SDDL следующим образом: S:(ML;;NW;;;LW)D:(A;;0x12019f;;;WD) Это установит права доступа для пользователя Everyone, позволяющего ему открывать, писать, читать канал. Я проверил, и теперь к каналу можно получить глобальный доступ с любого уровня целостности и с любого аккаунта.

Лучше было бы настроить 0x12019b разрешения для «Все», поскольку это даст всем пользователям доступ к каналу без разрешений на добавление новых экземпляров в канал. Тогда вам нужно будет добавить разрешения 0x12019f только для пользователя, который создает каналы, но я понятия не имел, как получить идентификатор текущего пользователя.

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

Надеюсь, этот вопрос поможет кому-то еще.

Роджер, уйди!

5 голосов
/ 11 марта 2012

Код, который вы показываете, похоже, создает дескриптор безопасности и настраивает его список контроля доступа (DACL). DACL не имеет никакого отношения к механизму контроля целостности.

Чтобы процессы с низкой целостностью открывали дескриптор, с помощью которого можно писать в именованный канал, объект именованного канала должен быть помечен как «Низкая целостность» в его Обязательной метке целостности. Эта метка находится в системном списке контроля доступа (SACL), а не в DACL. Вот что означает префикс S:(... в строковом представлении SDDL дескриптора безопасности, который вы использовали для создания SD с помощью ConvertStringSecurityDescriptorToSecurityDescriptorW.

Если вы хотите сделать это длинной рукой, не начиная с представления SDDL, вам нужно создать ACE правильного типа, SYSTEM_MANDATORY_LABEL_ACE, инициализированный с SID для низкой целостности (S-1-16-4096) и соответствующую политику целостности (например, SYSTEM_MANDATORY_LABEL_NO_WRITE_UP), а затем поместите ее в SACL через SetSecurityDescriptorSacl.

...