Connect to a named pipe in the same network without Administrator rights

-2

I created a named pipe server and granted full access rights to Everyone. I tried to connect to the named pipe server from different machine on the same network but I get an error says the login failed - ERROR_LOGON_FAILURE.

I read about NullSessionPipes and I compiled the example from MSDN. However, I need an administration right to register the NullSessionPipe in the registry which I'm trying to avoid.

How does CreateFile actually do the login to the remote named pipe? Do I need to run my client in a specific context to make this works? (e.g Guest).

server code:

DWORD dwRes, dwDisposition;
PSID pEveryoneSID = NULL, pAdminSID = NULL;
PACL pACL = NULL;
PSECURITY_DESCRIPTOR pSD = NULL;
EXPLICIT_ACCESS ea[2];
SID_IDENTIFIER_AUTHORITY SIDAuthWorld =
    SECURITY_WORLD_SID_AUTHORITY;
SID_IDENTIFIER_AUTHORITY SIDAuthNT = SECURITY_NT_AUTHORITY;
SECURITY_ATTRIBUTES sa;
LONG lRes;
HKEY hkSub = NULL;

// Create a well-known SID for the Everyone group.
if (!AllocateAndInitializeSid(&SIDAuthWorld, 1,
    SECURITY_WORLD_RID,
    0, 0, 0, 0, 0, 0, 0,
    &pEveryoneSID))
{
    return false;

}

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

// Create a new ACL that contains the new ACEs.
dwRes = SetEntriesInAcl(1, ea, NULL, &pACL);
if (ERROR_SUCCESS != dwRes)
{
    return false;
}

// Initialize a security descriptor.  
pSD = (PSECURITY_DESCRIPTOR)LocalAlloc(LPTR,
    SECURITY_DESCRIPTOR_MIN_LENGTH);
if (NULL == pSD)
{
    return false;

}

if (!InitializeSecurityDescriptor(pSD,
    SECURITY_DESCRIPTOR_REVISION))
{
    return false;
}

// Add the ACL to the security descriptor. 
if (!SetSecurityDescriptorDacl(pSD,
    TRUE,     // bDaclPresent flag   
    pACL,
    FALSE))   // not a default DACL 
{
    return false;
}

// Initialize a security attributes structure.
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = pSD;
sa.bInheritHandle = FALSE;

// create named pipe
auto NamedPipe = CreateNamedPipeA(namedPipeName,
                                    PIPE_ACCESS_DUPLEX,
                                    PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_NOWAIT | PIPE_ACCEPT_REMOTE_CLIENTS,
                                    PIPE_UNLIMITED_INSTANCES,
                                    NAMED_PIPE_SIZE,
                                    NAMED_PIPE_SIZE,
                                    NMPWAIT_USE_DEFAULT_WAIT, 
                                    &sa);
c++
c
windows
winapi
asked on Stack Overflow Oct 14, 2018 by user1341970 • edited Oct 14, 2018 by user1341970

1 Answer

3

how do this task described in How to create an anonymous pipe that gives access to everyone

the error ERROR_LOGON_FAILURE say that client code not makes a connection to a network resource. really need call WNetAddConnection2 (or analog api before call CreateFile on remote pipe)

The client opens the pipe with a call to the CreateFile function. If an error occurs, the client checks if it is a logon failure error, an access denied error, or a bad password error. If an error occurs, perform an anonymous logon by calling the WNetAddConnection2 function and passing an empty string as user name and password. When the null session is established, the client calls the CreateFile function again.

so client code must look like:

    NETRESOURCE nr = {};
    nr.dwUsage = RESOURCEUSAGE_CONNECTABLE|RESOURCEUSAGE_CONTAINER;
    nr.lpRemoteName = L"\\\\server\\IPC$";

    WNetAddConnection2W(&nr, L"", L"",0);

    HANDLE hFile = CreateFileW(L"\\\\?\\UNC\\server\\PIPE\\MyPipe",
        FILE_GENERIC_READ|FILE_GENERIC_WRITE, 
        0, 0, OPEN_EXISTING, 0, 0);

from server side need not only set 0 in place DACL (this allow any access) or add allowed ACE for WinAnonymousSid (this is != WinWorldSid aka everyone) but also set untrusted mandatory label. this is slipped in code example, because i think code yet pre vista.

    SECURITY_DESCRIPTOR sd;
    BOOL fOk = InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION) &&
        SetSecurityDescriptorDacl(&sd, TRUE, 0, FALSE);

    if (fOk)
    {
        RTL_OSVERSIONINFOW ovi = { sizeof(ovi) };
        if (0 > RtlGetVersion(&ovi))
        {
            fOk = FALSE;
        }
        else
        {
            if (ovi.dwMajorVersion > 5)
            {
                fOk = FALSE;
                ULONG cb = GetSidLengthRequired(1);
                PSID UntrustedLabelSid = alloca(cb);
                if (CreateWellKnownSid(WinUntrustedLabelSid, 0, UntrustedLabelSid, &cb))
                {
                    PACL Sacl = (PACL)alloca(cb += sizeof(ACL) + sizeof(ACE_HEADER) + sizeof(ACCESS_MASK));
                    fOk = InitializeAcl(Sacl, cb, ACL_REVISION) &&
                        AddMandatoryAce(Sacl, ACL_REVISION, 0, SYSTEM_MANDATORY_LABEL_NO_WRITE_UP, UntrustedLabelSid) &&
                        SetSecurityDescriptorSacl(&sd, TRUE, Sacl, FALSE);
                }
            }
        }
    }
answered on Stack Overflow Oct 14, 2018 by RbMm

User contributions licensed under CC BY-SA 3.0