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; }
STDMETHODIMP CObjSecurity::SetSecurity(SECURITY_INFORMATION si, PSECURITY_DESCRIPTOR pSD) { if(!::IsValidSecurityDescriptor(pSD)) { return E_POINTER; } DWORD dwErr = 0; PSECURITY_DESCRIPTOR pParentSD = NULL; if (mp_NewSD) { LocalFree(mp_NewSD); mp_NewSD = NULL; } if (mhk_ParentRead != NULL) { dwErr = mp_Worker->GetKeySecurity(mhk_ParentRead, DACL_SECURITY_INFORMATION|SACL_SECURITY_INFORMATION, &pParentSD); } dwErr = CreateNewDescriptor(m_pOrigSD, // Old pParentSD, // Used for inheritance calculation, may be NULL si, pSD, // Changed (it must be merged with Old) &mp_NewSD, &m_SI); // Resultant if ((dwErr == 0) && (mhk_Write != NULL)) { //dwErr = SetKeySecurityWindows(mhk_Write, m_SI, mp_NewSD); dwErr = mp_Worker->SetKeySecurity(mhk_Write, m_SI, mp_NewSD); // сразу чистим дескриптор, независимо от того "успешно или нет" LocalFree(mp_NewSD); mp_NewSD = NULL; } if (pParentSD) LocalFree(pParentSD); return HRESULT_FROM_WIN32(dwErr); #if 0 TCHAR szDbgLabel[64]; wsprintf(szDbgLabel, _T("CObjSecurity::SetSecurity(0x%X)"), si); DumpSecurityDescriptor(pSD, si, szDbgLabel); PSID pNewOwner = NULL; BOOL lbOwnerDefaulted = FALSE; TRUSTEE *ptNewOwner = NULL, NewOwner = {NULL, NO_MULTIPLE_TRUSTEE, TRUSTEE_IS_SID, TRUSTEE_IS_UNKNOWN}; if (!dwErr && (si & OWNER_SECURITY_INFORMATION)) { if (::GetSecurityDescriptorOwner(pSD, &pNewOwner, &lbOwnerDefaulted)) { NewOwner.ptstrName = (LPTSTR)pNewOwner; ptNewOwner = &NewOwner; } else dwErr = GetLastError(); } PSID pNewGroup = NULL; BOOL lbGroupDefaulted = FALSE; TRUSTEE *ptNewGroup = NULL, NewGroup = {NULL, NO_MULTIPLE_TRUSTEE, TRUSTEE_IS_SID, TRUSTEE_IS_UNKNOWN}; if (!dwErr && (si & GROUP_SECURITY_INFORMATION)) { if (::GetSecurityDescriptorGroup(pSD, &pNewGroup, &lbGroupDefaulted)) { NewGroup.ptstrName = (LPTSTR)pNewGroup; ptNewGroup = &NewGroup; } else dwErr = GetLastError(); } PACL pNewDacl = NULL; BOOL lbDacl = FALSE, lbDaclDefaulted = FALSE; ULONG nDaclCount = 0; PEXPLICIT_ACCESS pDaclEntries = NULL; if (!dwErr && (si & DACL_SECURITY_INFORMATION)) { if (::GetSecurityDescriptorDacl(pSD, &lbDacl, &pNewDacl, &lbDaclDefaulted)) { dwErr = ::GetExplicitEntriesFromAcl(pNewDacl, &nDaclCount, &pDaclEntries); } else dwErr = GetLastError(); } PACL pNewSacl = NULL; BOOL lbSacl = FALSE, lbSaclDefaulted = FALSE; ULONG nSaclCount = 0; PEXPLICIT_ACCESS pSaclEntries = NULL; if (!dwErr && (si & SACL_SECURITY_INFORMATION)) { if (::GetSecurityDescriptorSacl(pSD, &lbSacl, &pNewSacl, &lbSaclDefaulted)) { dwErr = ::GetExplicitEntriesFromAcl(pNewSacl, &nSaclCount, &pSaclEntries); } else dwErr = GetLastError(); } PSECURITY_DESCRIPTOR pNewSD = NULL; ULONG nNewSize = 0; BOOL lbRc = FALSE; if (dwErr == 0) dwErr = BuildSecurityDescriptor(ptNewOwner, ptNewGroup, nDaclCount, pDaclEntries, nSaclCount, pSaclEntries, m_pOrigSD/*self-relative!*/, &nNewSize, &pNewSD); if (dwErr == 0) { DumpSecurityDescriptor(pNewSD, OWNER_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION|SACL_SECURITY_INFORMATION, _T("After BuildSecurityDescriptor")); if (pNewOwner) { if (!::SetSecurityDescriptorOwner(pNewSD, pNewOwner, lbOwnerDefaulted)) dwErr = GetLastError(); else DumpSecurityDescriptor(pNewSD, OWNER_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION|SACL_SECURITY_INFORMATION, _T("After SetSecurityDescriptorOwner")); } if (dwErr != 0) LocalFree(pNewSD); else { if (mp_NewSD) LocalFree(mp_NewSD); mp_NewSD = pNewSD; m_SI = si; } } else dwErr = GetLastError(); //BOOL lb1 = IsValidSecurityDescriptor((PSECURITY_DESCRIPTOR)m_ppSD); //BOOL lb2 = IsValidSecurityDescriptor(*m_ppSD); //DumpSecurityDescriptor(*m_ppSD, OWNER_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION, _T("Stored descriptor pointer")); //WARNING("BuildSecurityDescriptor"); //// она корректно выполнит //// builds the new security descriptor by merging the specified owner, group, access control, //// and audit-control information with the information in this security descriptor //// Наверное вообще не нужно со строками заморачиваться - сразу звать Build из SetSecurity. //// Ведь в m_pSD(новая!) уже лежит наша копия дескриптора. //// Ест-но в SetSecurity нужно проверить, что вернулось - если Absolute - звать MakeSelfRelativeSD //WARNING("Сделать OR на новую переменную масок - что юзер поменял"); // //if (si & DACL_SECURITY_INFORMATION) //{ // if (mp_DaclSD) // { // LocalFree(mp_DaclSD); // mp_DaclSD = NULL; // } // if (mpsz_DaclSD) // { // LocalFree(mpsz_DaclSD); // mpsz_DaclSD = NULL; // } // ULONG nLen = 0; // if (!ConvertSecurityDescriptorToStringSecurityDescriptor(pSD, SDDL_REVISION_1, DACL_SECURITY_INFORMATION, // &mpsz_DaclSD, &nLen)) // dwErr = GetLastError(); //} //if (si & OWNER_SECURITY_INFORMATION) //{ // if (mp_OwnerSD) // { // LocalFree(mp_OwnerSD); // mp_OwnerSD = NULL; // } // if (mpsz_OwnerSD) // { // LocalFree(mpsz_OwnerSD); // mpsz_OwnerSD = NULL; // } // ULONG nLen = 0; // if (!ConvertSecurityDescriptorToStringSecurityDescriptor(pSD, SDDL_REVISION_1, OWNER_SECURITY_INFORMATION, // &mpsz_OwnerSD, &nLen)) // dwErr = GetLastError(); // //DWORD nLen = GetSecurityDescriptorLength(pSD); // //if (nLen) // //{ // // mp_OwnerSD = LocalAlloc(LPTR, nLen); // // if (mp_OwnerSD) // // memmove(mp_OwnerSD, pSD, nLen); // //} // //else // //{ // // mp_OwnerSD = NULL; // //} // //PSID pOwner = NULL; BOOL lbOwnerDefaulted = FALSE; // //if (GetSecurityDescriptorOwner(pSD, &pOwner, &lbOwnerDefaulted)) // //{ // // if (SetSecurityDescriptorOwner(*m_ppSD, pOwner, lbOwnerDefaulted)) // // { // // DumpSecurityDescriptor(pSD, si, _T("CObjSecurity::SetSecurity Applied")); // // } // // else // // { // // dwErr = GetLastError(); // // } // //} // //else // //{ // // dwErr = GetLastError(); // //} //} #ifdef APPLY_SECURITY_TO_REG // // Assume that required privileges have already been enabled // //if (!SetPrivateObjectSecurity(si, pSD, m_ppSD, &ObjMap, mh_Token)) // dwErr = GetLastError(); if (mpsz_KeyPath && *mpsz_KeyPath) { HKEY hk; dwErr = RegOpenKeyExW(mhk_Root, mpsz_KeyPath, 0, mdw_RegFlags, &hk); if (dwErr == 0) { dwErr = RegSetKeySecurity(hk, DACL_SECURITY_INFORMATION, pSD); RegCloseKey(hk); } } else { dwErr = RegSetKeySecurity(mhk_Root, DACL_SECURITY_INFORMATION, pSD); } if (dwErr == 0) { DWORD dwLength = 0; // // Assume that required privileges have already been enabled // GetPrivateObjectSecurity(pSD, DACL_SECURITY_INFORMATION, NULL, 0, &dwLength); if (dwLength) { PSECURITY_DESCRIPTOR pNewSD = (PSECURITY_DESCRIPTOR)LocalAlloc(LPTR, dwLength); if (pNewSD && !GetPrivateObjectSecurity(pSD, DACL_SECURITY_INFORMATION, pNewSD, dwLength, &dwLength)) { dwErr = GetLastError(); LocalFree(pNewSD); pNewSD = NULL; } else { LocalFree((HLOCAL)*m_ppSD); *m_ppSD = pNewSD; } } else dwErr = GetLastError(); } #endif return HRESULT_FROM_WIN32(dwErr); #endif }