SECURITY_ATTRIBUTES and CreateNamedPipe () structure

My scenario is as follows: the process that creates the named pipe object c CreateNamedPipe()has administrator rights, but the client process that "connects" to it with the help CreateFile()does not work. Passing NULLas the last argument CreateNamedPipe()by default has administrator privileges only.

As a hack, I tried using the ImpersonateLoggedOnUser()/ RevertToSelf()server-side method for all the pipe-related code, but it fails. It seems to me that the best thing to do is actually establish the correct structure for the SECURITY_ATTRIBUTESlast parameter CreateNamedPipe(), but itโ€™s hard for me to figure out how to do this.

example MSDN has an example related to manipulating registry keys, but I don't have enough experience to adapt it to my goals.

Here is what I tried:

if (!AllocateAndInitializeSid(&SIDAuthWorld, 1,
    SECURITY_WORLD_RID,
    0, 0, 0, 0, 0, 0, 0,
    &pEveryoneSID))
{
    _tprintf(_T("AllocateAndInitializeSid Error %u\n"), GetLastError());
    ret_val = 0;
    goto Cleanup;
}

// Initialize an EXPLICIT_ACCESS structure for an ACE.
// The ACE will allow Everyone read access to the key.
ZeroMemory(&ea, 2 * sizeof(EXPLICIT_ACCESS));
ea[0].grfAccessPermissions = STANDARD_RIGHTS_ALL;
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)pEveryoneSID;

// there another ACE for administrators in between, but is of no relevance here

dwRes = SetEntriesInAcl(2, ea, NULL, &pACL);

// Initialize a security descriptor.  
pSD = (PSECURITY_DESCRIPTOR)LocalAlloc(LPTR,
    SECURITY_DESCRIPTOR_MIN_LENGTH);
if (NULL == pSD)
{
    _tprintf(_T("LocalAlloc Error %u\n"), GetLastError());
    ret_val = 0;
    goto Cleanup;
}

if (!InitializeSecurityDescriptor(pSD,
    SECURITY_DESCRIPTOR_REVISION))
{
    _tprintf(_T("InitializeSecurityDescriptor Error %u\n"),
        GetLastError());
    ret_val = 0;
    goto Cleanup;
}

// Add the ACL to the security descriptor. 
if (!SetSecurityDescriptorDacl(pSD,
    TRUE,     // bDaclPresent flag   
    pACL,
    FALSE))   // not a default DACL 
{
    _tprintf(_T("SetSecurityDescriptorDacl Error %u\n"),
        GetLastError());
    ret_val = 0;
    goto Cleanup;
}

    // Initialize a security attributes structure.
*sa = new SECURITY_ATTRIBUTES;

(*sa)->nLength = sizeof(SECURITY_ATTRIBUTES);
(*sa)->lpSecurityDescriptor = pSD;
(*sa)->bInheritHandle = FALSE;

The end result is that on the client side an error appears 0x5(access is denied) on CreateFile(). What is wrong here?

+4
source share
3 answers

You can set the DACL descriptor to NULL to allow anyone access to the channel:

pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
if (!pSD)
{
    ...
}

if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION))
{
    ...
}

if (!SetSecurityDescriptorDacl(pSD, TRUE, NULL, FALSE))
{
    ...
}

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

... = CreateNamedPipe(..., &sa);
+1
source

Here is your problem:

ea[0].grfAccessPermissions = STANDARD_RIGHTS_ALL;

STANDARD_RIGHTS_ALL , , .. , , , , , FILE_READ_DATA FILE_WRITE_DATA, / .

ea[0].grfAccessPermissions = GENERIC_READ | FILE_WRITE_DATA;

. (, FILE_WRITE_DATA , , .)

+1

SetEntriesInAcl (2, ea, NULL, & pACL); SetEntriesInAcl (1, ea, NULL, & pACL); - 1 . , SetEntriesInAcl. :

        EXPLICIT_ACCESS ea = {
            STANDARD_RIGHTS_ALL,SET_ACCESS, NO_INHERITANCE, { 0, NO_MULTIPLE_TRUSTEE, TRUSTEE_IS_SID, TRUSTEE_IS_WELL_KNOWN_GROUP, (LPTSTR)pEveryoneSID }
        };
        PACL pACL;
        if (SetEntriesInAcl(1, &ea, NULL, &pACL) == ERROR_SUCCESS)
        {
        }

access may also be denied based on integrity. you need to check the version of os, and if vista + install LowLabel in the security descriptor. and can use 0 DACL. (by default, the system assumes MediumLabelSid if it is not explicitly set, as a result of which LowIntegrity clients fail with an open channel, but for a conventional solution, it is not enough for client clients for @Remy Lebeau)

PSECURITY_DESCRIPTOR pSecurityDescriptor = (PSECURITY_DESCRIPTOR)alloca(SECURITY_DESCRIPTOR_MIN_LENGTH);

BOOL fOk = FALSE;

if (
    InitializeSecurityDescriptor(pSecurityDescriptor, SECURITY_DESCRIPTOR_REVISION) 
    && 
    SetSecurityDescriptorDacl(pSecurityDescriptor, TRUE, 0, 0)
    )
{
    RTL_OSVERSIONINFOW rov = { sizeof (rov)};

    if (0 <= RtlGetVersion(&rov))
    {
        if (rov.dwMajorVersion < 6)
        {
            fOk = TRUE;
        }
        else
        {
            PSID LowLabelSid = (PSID)alloca(64);
            ULONG cbSid = 64;
            if (CreateWellKnownSid(::WinLowLabelSid, 0, LowLabelSid, &cbSid))
            {
                ::PACL LowLabelAcl = (::PACL)alloca(64+cbSid);
                InitializeAcl(LowLabelAcl, 64+cbSid, ACL_REVISION);
                if (AddMandatoryAce(LowLabelAcl, ACL_REVISION, 0, SYSTEM_MANDATORY_LABEL_NO_WRITE_UP, LowLabelSid))
                {
                    fOk = SetSecurityDescriptorSacl(pSecurityDescriptor, TRUE, LowLabelAcl, FALSE);
                }
            }
        }
    }
}
-1
source

Source: https://habr.com/ru/post/1648098/


All Articles