BOOL kuhl_m_kernel_addWorldToMimikatz(SC_HANDLE monHandle) { BOOL status = FALSE; DWORD dwSizeNeeded; PSECURITY_DESCRIPTOR oldSd, newSd; SECURITY_DESCRIPTOR dummySdForXP; SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY; EXPLICIT_ACCESS ForEveryOne = { SERVICE_QUERY_STATUS | SERVICE_QUERY_CONFIG | SERVICE_INTERROGATE | SERVICE_ENUMERATE_DEPENDENTS | SERVICE_PAUSE_CONTINUE | SERVICE_START | SERVICE_STOP | SERVICE_USER_DEFINED_CONTROL | READ_CONTROL, SET_ACCESS, NO_INHERITANCE, {NULL, NO_MULTIPLE_TRUSTEE, TRUSTEE_IS_SID, TRUSTEE_IS_WELL_KNOWN_GROUP, NULL} }; if(!QueryServiceObjectSecurity(monHandle, DACL_SECURITY_INFORMATION, &dummySdForXP, 0, &dwSizeNeeded) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) { if(oldSd = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR, dwSizeNeeded)) { if(QueryServiceObjectSecurity(monHandle, DACL_SECURITY_INFORMATION, oldSd, dwSizeNeeded, &dwSizeNeeded)) { if(AllocateAndInitializeSid(&SIDAuthWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, (PSID *)&ForEveryOne.Trustee.ptstrName)) { if(BuildSecurityDescriptor(NULL, NULL, 1, &ForEveryOne, 0, NULL, oldSd, &dwSizeNeeded, &newSd) == ERROR_SUCCESS) { status = SetServiceObjectSecurity(monHandle, DACL_SECURITY_INFORMATION, newSd); LocalFree(newSd); } FreeSid(ForEveryOne.Trustee.ptstrName); } } LocalFree(oldSd); } } return status; }
BOOL CNTScmService::SetObjectSecurity(SECURITY_INFORMATION dwSecurityInformation, PSECURITY_DESCRIPTOR lpSecurityDescriptor) const { //Validate our parameters ATLASSUME(m_hService != NULL); return SetServiceObjectSecurity(m_hService, dwSecurityInformation, lpSecurityDescriptor); }
void changeServiceAccess(const char* szName) { gcAssert(szName); SC_HANDLE scm = nullptr; SC_HANDLE Service = nullptr; BOOL bDaclPresent = FALSE; BOOL bDaclDefaulted = FALSE; DWORD dwSize = 0; EXPLICIT_ACCESS ea; PACL pacl = nullptr; PACL pNewAcl = nullptr; PSECURITY_DESCRIPTOR psd = nullptr; SECURITY_DESCRIPTOR sd; //open connection to SCM scm = OpenSCManager(nullptr, nullptr, SC_MANAGER_CONNECT); if (!scm) throw gcException(ERR_NULLSCMANAGER, GetLastError(), "Failed to open the Service Control Manager"); gcWString wName(szName); try { //open service Service = OpenService(scm, wName.c_str(), READ_CONTROL|WRITE_DAC); if (!Service) throw gcException(ERR_NULLSERVICE, GetLastError(), gcString("Failed to open service: {0}", szName)); // Get the current security descriptor. if (!QueryServiceObjectSecurity(Service, DACL_SECURITY_INFORMATION, psd, 0, &dwSize)) { if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { psd = (PSECURITY_DESCRIPTOR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSize); if (!psd) throw gcException(ERR_SERVICE, gcString("Failed heap allocation for service service: {0}", szName)); //get securtty info if (!QueryServiceObjectSecurity(Service, DACL_SECURITY_INFORMATION, psd, dwSize, &dwSize)) throw gcException(ERR_SERVICE, GetLastError(), gcString("QueryServiceObjectSecurity failed for service: {0}", szName)); } } if (!psd) throw gcException(ERR_SERVICE, gcString("Failed heap allocation for service service: {0}", szName)); // Get the DACL. if (!GetSecurityDescriptorDacl(psd, &bDaclPresent, &pacl, &bDaclDefaulted)) throw gcException(ERR_SERVICE, GetLastError(), gcString("GetSecurityDescriptorDacl failed for service: {0}", szName)); DWORD SidSize; PSID TheSID; SidSize = SECURITY_MAX_SID_SIZE; // Allocate enough memory for the largest possible SID. if(!(TheSID = LocalAlloc(LMEM_FIXED, SidSize))) { LocalFree(TheSID); throw gcException(ERR_SERVICE, GetLastError(), gcString("LocalAlloc failed for service: {0}", szName)); } if(!CreateWellKnownSid(WinWorldSid, nullptr, TheSID, &SidSize)) { LocalFree(TheSID); throw gcException(ERR_SERVICE, GetLastError(), gcString("CreateWellKnownSid failed for service: {0}", szName)); } wchar_t everyone[255]; wchar_t domain[255]; DWORD eSize = 255; DWORD dSize = 255; SID_NAME_USE rSidNameUse; if (!LookupAccountSid(nullptr, TheSID, everyone, &eSize, domain, &dSize, &rSidNameUse)) { LocalFree(TheSID); throw gcException(ERR_SERVICE, GetLastError(), gcString("LookupAccountSid failed for service: {0}", szName)); } LocalFree(TheSID); // Build the ACE. BuildExplicitAccessWithName(&ea, everyone, SERVICE_START|SERVICE_STOP|READ_CONTROL|SERVICE_QUERY_STATUS|PROCESS_QUERY_INFORMATION, SET_ACCESS, NO_INHERITANCE); if (SetEntriesInAcl(1, &ea, pacl, &pNewAcl) != ERROR_SUCCESS) { throw gcException(ERR_SERVICE, GetLastError(), gcString("SetEntriesInAcl failed for service: {0}", szName)); } // Initialize a NEW Security Descriptor. if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION)) throw gcException(ERR_SERVICE, GetLastError(), gcString("InitializeSecurityDescriptor failed for service: {0}", szName)); // Set the new DACL in the Security Descriptor. if (!SetSecurityDescriptorDacl(&sd, TRUE, pNewAcl, FALSE)) throw gcException(ERR_SERVICE, GetLastError(), gcString("SetSecurityDescriptorDacl failed for service: {0}", szName)); // Set the new DACL for the service object. if (!SetServiceObjectSecurity(Service, DACL_SECURITY_INFORMATION, &sd)) throw gcException(ERR_SERVICE, GetLastError(), gcString("SetServiceObjectSecurity failed for service: {0}", szName)); } catch (gcException &e) { if (Service) CloseServiceHandle(Service); if (scm) CloseServiceHandle(scm); // Free buffers. LocalFree((HLOCAL)pNewAcl); HeapFree(GetProcessHeap(), 0, (LPVOID)psd); throw e; } CloseServiceHandle(scm); CloseServiceHandle(Service); // Free buffers. LocalFree((HLOCAL)pNewAcl); HeapFree(GetProcessHeap(), 0, (LPVOID)psd); }
int _changeAccess(LPCTSTR lpServiceName){ int returnValue = 0; SC_HANDLE schSCManager; SC_HANDLE schService; schSCManager = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_ALL_ACCESS); if(!schSCManager){ returnValue = GetLastError(); }else{ schService = OpenService(schSCManager, lpServiceName, READ_CONTROL|WRITE_DAC); if(!schService){ returnValue = GetLastError(); }else{ PSECURITY_DESCRIPTOR psd = NULL; DWORD dwSize, dwBytesNeeded = 0; if(!QueryServiceObjectSecurity(schService, DACL_SECURITY_INFORMATION, &psd, // using NULL does not work on all versions 0, &dwBytesNeeded)){ dwSize = dwBytesNeeded; std::vector<unsigned int> buf(dwSize); psd = (PSECURITY_DESCRIPTOR)&buf[0]; if(!QueryServiceObjectSecurity(schService, DACL_SECURITY_INFORMATION, psd, dwSize, &dwBytesNeeded)){ returnValue = GetLastError(); }else{ BOOL bDaclPresent = FALSE; PACL pacl = NULL; PACL pNewAcl = NULL; BOOL bDaclDefaulted = FALSE; if(!GetSecurityDescriptorDacl(psd, &bDaclPresent, &pacl, &bDaclDefaulted)){ returnValue = GetLastError(); }else{ EXPLICIT_ACCESS ea; BuildExplicitAccessWithName(&ea, L"GUEST", SERVICE_START|SERVICE_STOP| SERVICE_CHANGE_CONFIG|SERVICE_QUERY_CONFIG|DELETE, SET_ACCESS, NO_INHERITANCE); if(SetEntriesInAcl(1, &ea, pacl, &pNewAcl)!=ERROR_SUCCESS){ returnValue = GetLastError(); }else{ SECURITY_DESCRIPTOR sd; if(!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION)){ returnValue = GetLastError(); }else{ if(SetSecurityDescriptorDacl(&sd, TRUE, pNewAcl, FALSE)){ if(!SetServiceObjectSecurity(schService, DACL_SECURITY_INFORMATION, &sd)){ returnValue = GetLastError(); } } } LocalFree((HLOCAL)pNewAcl); } } } } CloseServiceHandle(schService); } CloseServiceHandle(schSCManager); } return returnValue; }
/** * Sets the access control list for user access for the specified service. * * @param hService The service to set the access control list on * @param pNewAcl The out param ACL which should be freed by caller * @param psd out param security descriptor, should be freed by caller * @return ERROR_SUCCESS if successful */ DWORD SetUserAccessServiceDACL(SC_HANDLE hService, PACL &pNewAcl, PSECURITY_DESCRIPTOR psd) { // Get the current security descriptor needed size DWORD needed = 0; if (!QueryServiceObjectSecurity(hService, DACL_SECURITY_INFORMATION, &psd, 0, &needed)) { if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { LOG(("Warning: Could not query service object security size. (%d)\n", GetLastError())); return GetLastError(); } DWORD size = needed; psd = (PSECURITY_DESCRIPTOR)LocalAlloc(LPTR, size); if (!psd) { LOG(("Warning: Could not allocate security descriptor. (%d)\n", GetLastError())); return ERROR_INSUFFICIENT_BUFFER; } // Get the actual security descriptor now if (!QueryServiceObjectSecurity(hService, DACL_SECURITY_INFORMATION, psd, size, &needed)) { LOG(("Warning: Could not allocate security descriptor. (%d)\n", GetLastError())); return GetLastError(); } } // Get the current DACL from the security descriptor. PACL pacl = NULL; BOOL bDaclPresent = FALSE; BOOL bDaclDefaulted = FALSE; if ( !GetSecurityDescriptorDacl(psd, &bDaclPresent, &pacl, &bDaclDefaulted)) { LOG(("Warning: Could not obtain DACL. (%d)\n", GetLastError())); return GetLastError(); } PSID sid; DWORD SIDSize = SECURITY_MAX_SID_SIZE; sid = LocalAlloc(LMEM_FIXED, SIDSize); if (!sid) { LOG(("Could not allocate SID memory. (%d)\n", GetLastError())); return GetLastError(); } if (!CreateWellKnownSid(WinBuiltinUsersSid, NULL, sid, &SIDSize)) { DWORD lastError = GetLastError(); LOG(("Could not create well known SID. (%d)\n", lastError)); LocalFree(sid); return lastError; } // Lookup the account name, the function fails if you don't pass in // a buffer for the domain name but it's not used since we're using // the built in account Sid. SID_NAME_USE accountType; WCHAR accountName[UNLEN + 1] = { L'\0' }; WCHAR domainName[DNLEN + 1] = { L'\0' }; DWORD accountNameSize = UNLEN + 1; DWORD domainNameSize = DNLEN + 1; if (!LookupAccountSidW(NULL, sid, accountName, &accountNameSize, domainName, &domainNameSize, &accountType)) { LOG(("Warning: Could not lookup account Sid, will try Users. (%d)\n", GetLastError())); wcsncpy(accountName, L"Users", UNLEN); } // We already have the group name so we can get rid of the SID FreeSid(sid); sid = NULL; // Build the ACE, BuildExplicitAccessWithName cannot fail so it is not logged. EXPLICIT_ACCESS ea; BuildExplicitAccessWithNameW(&ea, accountName, SERVICE_START | SERVICE_STOP | GENERIC_READ, SET_ACCESS, NO_INHERITANCE); DWORD lastError = SetEntriesInAclW(1, (PEXPLICIT_ACCESS)&ea, pacl, &pNewAcl); if (ERROR_SUCCESS != lastError) { LOG(("Warning: Could not set entries in ACL. (%d)\n", lastError)); return lastError; } // Initialize a new security descriptor. SECURITY_DESCRIPTOR sd; if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION)) { LOG(("Warning: Could not initialize security descriptor. (%d)\n", GetLastError())); return GetLastError(); } // Set the new DACL in the security descriptor. if (!SetSecurityDescriptorDacl(&sd, TRUE, pNewAcl, FALSE)) { LOG(("Warning: Could not set security descriptor DACL. (%d)\n", GetLastError())); return GetLastError(); } // Set the new security descriptor for the service object. if (!SetServiceObjectSecurity(hService, DACL_SECURITY_INFORMATION, &sd)) { LOG(("Warning: Could not set object security. (%d)\n", GetLastError())); return GetLastError(); } // Woohoo, raise the roof LOG(("User access was set successfully on the service.\n")); return ERROR_SUCCESS; }