==============================ModuleL===================================== | | | The program examples' source codes have been arranged in the same | | order that appeared in the Tutorial. This is unedited and unverified | | compilation. Published as is basis for educational, reacretional and | | brain teaser purposes. All trademarks, copyrights and IPs, wherever | | exist, are the sole property of their respective owner and/or | | holder. Any damage or loss by using the materials presented in this | | tutorial is USER responsibility. Part or full distribution, | | reproduction and modification is granted to any body. | | Copyright 2003-2005 © Tenouk, Inc. All rights reserved. | | Distributed through http://www.tenouk.com | | | | | =========================================================================== Compiled using VC++/VC++ .Net.....unmanaged... // Playing with SID format // For Win Xp #define _WIN32_WINNT 0x0501 #include #include #include #include int main() { DWORD SidSize, SidSize2; PSID TheSID = NULL; LPTSTR pSid = ""; SidSize = SECURITY_MAX_SID_SIZE; printf("Create a well known \"WinLocalSystemSid\" SID.\n"); printf("--------------------------------------------\n"); // Allocate enough memory for the largest possible SID. if(!(TheSID = LocalAlloc(LMEM_FIXED, SidSize))) { printf("Could not allocate memory, error %u.\n", GetLastError()); // Just exit exit(1); } else printf("Memory allocated successfully.\n"); // Create a SID for the Local system on the local computer. if(!CreateWellKnownSid( WinLocalSystemSid, // Well known Local system SID NULL, // Domain SID, NULL for local computer TheSID, // Pointer to memory for new SID &SidSize // Pointer in DWORD the number of byte of TheSid )) { printf("CreateWellKnownSid() error %u.\n\n", GetLastError()); } else { printf("CreateWellKnownSid() for Local system is OK.\n\n", GetLastError()); printf("Convert the \"WinLocalSystemSid\" SID to string SID.\n"); printf("--------------------------------------------------\n"); // Get the string version of the SID (S-R-I-I...) if(!(ConvertSidToStringSid( TheSID, // Pointer to the SID structure to be converted &pSid))) // Pointer to variable that receives the null-terminated SID string { printf("ConvertSidToStringSid() error %u\n", GetLastError()); exit(1); } else { printf("ConvertSidToStringSid() is OK.\n"); printf("The SID string for WinLocalSystemSid is: %s\n", pSid); } } if(IsValidSid(TheSID)) printf("The SID is valid\n"); else printf("The SID is not valid!\n"); //********************************************************** // TODO: Then, use the string SID as needed. // ... // When done, don't forget to release the memory used. //********************************************************** if(LocalFree(TheSID) == NULL) printf("Memory is freed up...\n"); //************************************************************ LPTSTR StringSid = "S-1-5-18"; // or "SY" - a well known Local System PSID TheSID2 = NULL; SidSize2 = SECURITY_MAX_SID_SIZE; // S-R-5-18 and equal to... // SECURITY_NT_AUTHORITY\\SECURITY_LOCAL_SYSTEM_RID // But they are stored as in binary format in a SID structure printf("\nConvert the \"S-1-5-18\" string SID to SID and then reconvert.\n"); printf("------------------------------------------------------------\n"); if(!(TheSID2 = LocalAlloc(LMEM_FIXED, SidSize2))) { printf("Could not allocate memory, error %u.\n", GetLastError()); exit(1); } else printf("Memory allocated successfully.\n"); //************************************************* if(!ConvertStringSidToSid( StringSid, // Pointer to a null-terminated string // containing the string-format SID to convert &TheSID2)) // Pointer to a variable that receives a pointer to the converted SID { printf("ConvertStringSidToSid() for Local system error %u\n", GetLastError()); exit(1); } else { printf("ConvertStringSidToSid() for Local system is OK.\n"); } if(!(ConvertSidToStringSid( TheSID2, // Pointer to the SID structure to be converted &StringSid))) // Pointer to variable that receives the null-terminated SID string { printf("Reconversion-ConvertSidToStringSid() error %u\n", GetLastError()); exit(1); } else { printf("Reconversion-ConvertSidToStringSid() is OK.\n"); printf("The SID string for WinLocalSystemSid is: %s\n", pSid); } if(IsWellKnownSid(TheSID2, WinLocalSystemSid)) printf("The SID is a well known SID.\n"); else printf("It is non well known SID, error %u.\n", GetLastError()); //************************************************** if(IsValidSid(TheSID2)) printf("The SID is valid.\n"); else printf("The SID is not valid!, error %u\n", GetLastError()); if(LocalFree(TheSID2) == NULL) printf("Memory is freed up...\n"); return 0; } ------------------------------------------------------------------------------------------------------- // Getting the Logon SID // For Win Xp #define _WIN32_WINNT 0x0501 #include #include #include #include //************************************************************ void Cleanup(PTOKEN_GROUPS ptgrp) { // Release the buffer for the token groups. if(ptgrp != NULL) HeapFree(GetProcessHeap(), 0, (LPVOID)ptgrp); } //*************************************************************** //************************************************************** // Get the logon SID and convert it to SID string... BOOL GetLogonSID(HANDLE hToken, PSID ppsid) { BOOL bSuccess = FALSE; DWORD dwIndex; DWORD dwLength = 0; PTOKEN_GROUPS ptgrp = NULL; // Again, dummy initialization... LPTSTR pSid = ""; // Verify the parameter passed in is not NULL. // Although we just provide an empty buffer... if(ppsid == NULL) { printf("The ppsid pointer is NULL lol!\n"); Cleanup(ptgrp); } else printf("The ppsid pointer is OK.\n"); // Get the required buffer size and allocate the TOKEN_GROUPS buffer. if(!GetTokenInformation( hToken, // handle to the access token TokenGroups, // get information about the token's groups (LPVOID) ptgrp, // pointer to TOKEN_GROUPS buffer 0, // size of buffer &dwLength // receives required buffer size )) { if(GetLastError() != ERROR_INSUFFICIENT_BUFFER) Cleanup(ptgrp); else ptgrp = (PTOKEN_GROUPS)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwLength); if(ptgrp == NULL) Cleanup(ptgrp); else printf("Buffer for TOKEN_GROUPS is OK.\n"); } else printf("GetTokenInformation()-Getting all the buffer and their size is OK\n"); // Get the token group information from the access token. if(!GetTokenInformation( hToken, // handle to the access token TokenGroups, // get information about the token's groups (LPVOID) ptgrp, // pointer to TOKEN_GROUPS buffer dwLength, // size of buffer &dwLength // receives required buffer size )) { Cleanup(ptgrp); } else printf("GetTokenInformation()-Getting the group info is OK\n"); // Loop through the groups to find the logon SID. for(dwIndex = 0; dwIndex < ptgrp->GroupCount; dwIndex++) if((ptgrp->Groups[dwIndex].Attributes & SE_GROUP_LOGON_ID) == SE_GROUP_LOGON_ID) { // If the logon SID is found then make a copy of it. dwLength = GetLengthSid(ptgrp->Groups[dwIndex].Sid); // Allocate a storage ppsid = (PSID) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwLength); // and verify again... if(ppsid == NULL) Cleanup(ptgrp); else printf("The ppsid pointer is OK.\n"); // If Copying the SID fails... if(!CopySid(dwLength, ppsid, // Destination ptgrp->Groups[dwIndex].Sid)) // Source { HeapFree(GetProcessHeap(), 0, (LPVOID)ppsid); Cleanup(ptgrp); } else printf("CopySid() is OK lol!\n"); //******************************************************* // Convert the logon sid to SID string format if(!(ConvertSidToStringSid( ppsid, // Pointer to the SID structure to be converted &pSid))) // Pointer to variable that receives the null-terminated SID string { printf("ConvertSidToStringSid() error %u\n", GetLastError()); Cleanup(ptgrp); exit(1); } else { printf("ConvertSidToStringSid() is OK.\n"); printf("The logon SID string is: %s\n", pSid); } } // If everything OK, returns a clean slate... bSuccess = TRUE; return bSuccess; } // The following function release the buffer allocated // by the GetLogonSID() function. BOOL FreeLogonSID(PSID ppsid) { HeapFree(GetProcessHeap(), 0, (LPVOID)ppsid); return TRUE; } int main() { // Handle to token HANDLE hToken; // Just a dummy initial size of SID to avoid a NULL pointer BYTE sidBuffer[256]; PSID ppsid = (PSID)&sidBuffer; // Open a handle to the access token for the calling process // that is the currently login access token if(!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &hToken)) { printf("OpenProcessToken()-Getting the handle to access token failed: %u\n", GetLastError()); } else printf("OpenProcessToken()-Getting the handle to access token is OK\n"); // Call the GetLogonSID() if(GetLogonSID(hToken, ppsid)) printf("GetLogonSID() is OK. Error if any: %u\n\n", GetLastError()); else printf("GetLogonSID() is not OK, error %u\n\n", GetLastError()); // Release the allocation for ppsid if(FreeLogonSID(ppsid)) printf("The ppsid has been freed...\n"); // Close the handle lol if(CloseHandle(hToken)) printf("The handle to the process is closed.\n"); return 0; } ------------------------------------------------------------------------------------------------------- // Log a user on to the local computer. This computer // is logged on as Mike, user with Administrators group, then // this program try to log on a restricted user named "testuser". // For Win Xp #define _WIN32_WINNT 0x0501 #include #include int main() { // "testuser" is restrictive user created in // the XP machine that runs this program LPTSTR lpszUsername = "testuser"; // Local account database LPTSTR lpszDomain = "."; LPTSTR lpszPassword = "testuser"; DWORD dwLogonType = LOGON32_LOGON_INTERACTIVE; DWORD dwLogonProvider = LOGON32_PROVIDER_WINNT50; // Some dummy to avoid the NULL pointer of the phToken PVOID myhandle; PHANDLE phToken = (PHANDLE)&myhandle; if(LogonUser( lpszUsername, // Username lpszDomain, // Domain or server where the Username is reside lpszPassword, // Plaintext password dwLogonType, // Type of logon dwLogonProvider, // The logon provider phToken // Pointer to handle that received the token )) printf("Well, \"%s\" user logged on to this machine successfully!\n", lpszUsername); else { printf("%s failed to log on to this machine! error %u\n", lpszUsername, GetLastError()); exit(-1); } PVOID hToken = (PVOID)phToken; if(CloseHandle(hToken) != 0) printf("The handle that received the token has been closed.\n"); else printf("Something wrong, the handle cannot be closed! error: %u\n", GetLastError()); // Arrgghhh the handle cannot be closed, time for you to solve. The CloseHandle() accept // HANDLE to an object, but here phToken is a pointer to HANDLE... return 0; } ------------------------------------------------------------------------------------------------------- // For Win Xp #define _WIN32_WINNT 0x0501 #include #include int main() { // Handle to token HANDLE hToken; // Open a handle to the access token for the calling process // that is the currently login access token if(!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &hToken)) { printf("OpenProcessToken()-Getting the handle to access token failed: %u\n", GetLastError()); } else printf("OpenProcessToken()-Getting the handle to access token is OK\n"); // Lets the calling process impersonate the security context of a logged-on user. if(ImpersonateLoggedOnUser(hToken)) printf("ImpersonateLoggedOnUser() is OK.\n"); else { printf("ImpersonateLoggedOnUser() is not OK, error %u.\n", GetLastError()); exit(-1); } // Do other tasks // ... // Terminates the impersonation of a client. if(RevertToSelf()) printf("Impersonation is terminated.\n"); // Close the handle if(CloseHandle(hToken)) printf("Handle to an access token closed.\n"); return 0; } ------------------------------------------------------------------------------------------------------- // Creating a security descriptor for a new object, // a registry key... #include #include #include // Buffer clean up routine void Cleanup(PSID pEveryoneSID, PSID pAdminSID, PACL pACL, PSECURITY_DESCRIPTOR pSD, HKEY hkSub) { if(pEveryoneSID) FreeSid(pEveryoneSID); if(pAdminSID) FreeSid(pAdminSID); if(pACL) LocalFree(pACL); if(pSD) LocalFree(pSD); if(hkSub) RegCloseKey(hkSub); } int main() { DWORD dwRes, dwDisposition; PSID pEveryoneSID = NULL, pAdminSID = NULL; PACL pACL = NULL; PSECURITY_DESCRIPTOR pSD = NULL; // An array of EXPLICIT_ACCESS structure 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)) { printf("AllocateAndInitializeSid() error %u\n", GetLastError()); Cleanup(pEveryoneSID, pAdminSID, pACL, pSD, hkSub); } else printf("AllocateAndInitializeSid() for the Everyone group is OK\n"); // 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 = KEY_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) pEveryoneSID; // Create a SID for the BUILTIN\Administrators group. if(!AllocateAndInitializeSid(&SIDAuthNT, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &pAdminSID)) { printf("AllocateAndInitializeSid() error %u\n", GetLastError()); Cleanup(pEveryoneSID, pAdminSID, pACL, pSD, hkSub); } else printf("AllocateAndInitializeSid() for the BUILTIN\\Administrators group is OK\n"); // Initialize an EXPLICIT_ACCESS structure for an ACE. // The ACE will allow the Administrators group full access to the key. ea[1].grfAccessPermissions = KEY_ALL_ACCESS; 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; // Create a new ACL that contains the new ACEs. dwRes = SetEntriesInAcl(2, ea, NULL, &pACL); if(dwRes != ERROR_SUCCESS) { printf("SetEntriesInAcl() error %u\n", GetLastError()); Cleanup(pEveryoneSID, pAdminSID, pACL, pSD, hkSub); } else printf("SetEntriesInAcl() for the Administrators group is OK\n"); // Initialize a security descriptor. pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH); if(pSD == NULL) { printf("LocalAlloc() error %u\n", GetLastError()); Cleanup(pEveryoneSID, pAdminSID, pACL, pSD, hkSub); } else printf("LocalAlloc() is OK\n"); if(!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION)) { printf("InitializeSecurityDescriptor Error %u\n", GetLastError()); Cleanup(pEveryoneSID, pAdminSID, pACL, pSD, hkSub); } else printf("InitializeSecurityDescriptor() is OK\n"); // Add the ACL to the security descriptor. if(!SetSecurityDescriptorDacl(pSD, TRUE, // bDaclPresent flag pACL, FALSE)) // not a default DACL { printf("SetSecurityDescriptorDacl() Error %u\n", GetLastError()); Cleanup(pEveryoneSID, pAdminSID, pACL, pSD, hkSub); } else printf("SetSecurityDescriptorDacl() is OK\n"); // Initialize a security attributes structure. sa.nLength = sizeof (SECURITY_ATTRIBUTES); sa.lpSecurityDescriptor = pSD; sa.bInheritHandle = FALSE; // Use the security attributes to set the security descriptor // when you create a registry key. lRes = RegCreateKeyEx(HKEY_CURRENT_USER, // handle to an open key "mytestkey", // name of the subkey 0, // Reserved "", // class or object type of this key, may be ignored 0, // Options KEY_READ | KEY_WRITE, // Access right for the key &sa, // Pointer to security attribute structure, can be inherited // or not. NULL is not inherited &hkSub, // variable that receives a handle to the opened or created // key &dwDisposition); // variable that receives: // REG_CREATED_NEW_KEY - create new key (non-exist) // REG_OPENED_EXISTING_KEY - just open the existing key // (already exist) // If successful if(lRes == 0) { printf("The value of the \'&dwDisposition\': %u\n", dwDisposition); printf("HKEY_CURRENT_USER\\mytestkey successfully created.\n"); } else printf("Creating and opening HKEY_CURRENT_USER\\mytestkey is failed.\n"); return 0; } ------------------------------------------------------------------------------------------------------- // Don't have time to complete this example :o( // Have to dig more on pipe story... // Tips to complete and make this example useable: // Fill up all the ImpersonateAndCheckAccess() parameters. #include #include #include void Cleanup(HANDLE hToken) { RevertToSelf(); if(hToken != INVALID_HANDLE_VALUE) CloseHandle(hToken); } BOOL ImpersonateAndCheckAccess( HANDLE hNamedPipe, // handle of pipe to impersonate PSECURITY_DESCRIPTOR pSD, // security descriptor to check DWORD dwAccessDesired, // access rights to check PGENERIC_MAPPING pGeneric, // generic mapping for object PDWORD pdwAccessAllowed // returns allowed access rights ) { HANDLE hToken; PRIVILEGE_SET PrivilegeSet; DWORD dwPrivSetSize = sizeof(PRIVILEGE_SET); BOOL fAccessGranted=FALSE; // Impersonate the client. if(!ImpersonateNamedPipeClient(hNamedPipe)) return FALSE; // Get an impersonation token with the client's security context. if(!OpenThreadToken(GetCurrentThread(), TOKEN_ALL_ACCESS, TRUE, &hToken)) Cleanup(hToken); // Use the GENERIC_MAPPING structure to convert any // generic access rights to object-specific access rights. MapGenericMask(&dwAccessDesired, pGeneric); // Check the client's access rights. if(!AccessCheck( pSD, // security descriptor to check hToken, // impersonation token dwAccessDesired, // requested access rights pGeneric, // pointer to GENERIC_MAPPING &PrivilegeSet, // receives privileges used in check &dwPrivSetSize, // size of PrivilegeSet buffer pdwAccessAllowed, // receives mask of allowed access rights &fAccessGranted )) // receives results of access check Cleanup(hToken); return fAccessGranted; } int main() { // TODO: Call ImpersonateAndCheckAccess() with appropriate // parameters. return 0; } ======================================================================================================