You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
390 lines
12 KiB
C++
390 lines
12 KiB
C++
#include "dcontrol.hpp"
|
|
|
|
namespace dcontrol
|
|
{
|
|
// Toggles windows tamper protection
|
|
//
|
|
void toggle_tamper(bool enable)
|
|
{
|
|
HKEY hkey;
|
|
|
|
if (reg::create_registry(L"SOFTWARE\\Microsoft\\Windows Defender\\Features", hkey))
|
|
{
|
|
if (enable)
|
|
{
|
|
if (!reg::set_keyval(hkey, L"TamperProtection", 5))
|
|
std::cout << "failed to write to TamperProtection" << std::endl;
|
|
}
|
|
else
|
|
{
|
|
if (!reg::set_keyval(hkey, L"TamperProtection", 0))
|
|
std::cout << "failed to write to TamperProtection" << std::endl;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Ends the smart screen process
|
|
//
|
|
void kill_smartscreen()
|
|
{
|
|
auto pid = util::get_pid("smartscreen.exe");
|
|
auto proc = OpenProcess(PROCESS_TERMINATE, FALSE, pid);
|
|
|
|
// TODO: Create a better solution to terminate smartscreen
|
|
// https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-terminateprocess
|
|
// The state of global data maintained by dynamic-link libraries
|
|
// (DLLs) may be compromised if TerminateProcess is used rather than ExitProcess.
|
|
// e.g. Injecting code to execute ExitProcess and manually unloaded everything
|
|
|
|
TerminateProcess(proc, 0);
|
|
|
|
if (proc)
|
|
CloseHandle(proc);
|
|
}
|
|
|
|
// TODO: create a single function
|
|
|
|
bool manage_security_service(bool enable, std::string service_name)
|
|
{
|
|
auto sc_manager = OpenSCManagerA(0, 0, SC_MANAGER_CONNECT);
|
|
|
|
if (!sc_manager)
|
|
return false;
|
|
|
|
auto service = OpenServiceA(
|
|
sc_manager,
|
|
service_name.c_str(),
|
|
enable ? SERVICE_ALL_ACCESS :
|
|
(SERVICE_CHANGE_CONFIG | SERVICE_STOP | DELETE)
|
|
);
|
|
|
|
if (!service)
|
|
{
|
|
CloseServiceHandle(sc_manager);
|
|
return false;
|
|
}
|
|
|
|
if (enable)
|
|
{
|
|
// Change to auto-start
|
|
if (!ChangeServiceConfigA(
|
|
service,
|
|
SERVICE_NO_CHANGE,
|
|
SERVICE_AUTO_START,
|
|
SERVICE_NO_CHANGE,
|
|
0, 0, 0, 0, 0, 0, 0
|
|
))
|
|
{
|
|
throw std::runtime_error("Failed to modify " + service_name + " " + std::to_string(GetLastError()));
|
|
return false;
|
|
}
|
|
|
|
// Start the service
|
|
if (!StartServiceA(service, 0, NULL))
|
|
{
|
|
throw std::runtime_error("Failed to start " + service_name);
|
|
return false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Stop the service
|
|
SERVICE_STATUS scStatus;
|
|
if (!ControlService(service, SERVICE_CONTROL_STOP, &scStatus))
|
|
{
|
|
auto last_error = GetLastError();
|
|
|
|
if (last_error == ERROR_SERVICE_NOT_ACTIVE)
|
|
return true;
|
|
|
|
throw std::runtime_error(
|
|
"Failed to stop " + service_name + " " + std::to_string(last_error)
|
|
);
|
|
return false;
|
|
}
|
|
|
|
// Change to DEMAND
|
|
if (!ChangeServiceConfigA(
|
|
service,
|
|
SERVICE_NO_CHANGE,
|
|
SERVICE_DEMAND_START,
|
|
SERVICE_NO_CHANGE,
|
|
0, 0, 0, 0, 0, 0, 0
|
|
))
|
|
{
|
|
throw std::runtime_error(
|
|
"Failed to modify " + service_name + " " + std::to_string(GetLastError())
|
|
);
|
|
|
|
return false;
|
|
}
|
|
|
|
// Allow time for service to stop
|
|
// TODO: Handle this automatically
|
|
Sleep(3000);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
// Stop or run security center (wscvc)
|
|
// The default value is autostart
|
|
//
|
|
bool manage_security_center(bool enable)
|
|
{
|
|
// handle registry calls
|
|
// https://superuser.com/questions/1199112/how-to-tell-the-state-of-a-service-from-the-registry
|
|
// https://stackoverflow.com/questions/291519/how-does-currentcontrolset-differ-from-controlset001-and-controlset002
|
|
// https://web.archive.org/web/20110514163940/http://support.microsoft.com/kb/103000
|
|
//
|
|
|
|
// auto ret = manage_security_service(enable, "wscsvc");
|
|
|
|
HKEY hkey;
|
|
if (reg::create_registry(L"SYSTEM\\CurrentControlSet\\Services\\wscsvc", hkey))
|
|
{
|
|
if (enable)
|
|
{
|
|
if (!reg::set_keyval(hkey, L"Start", 2)) // Automatic
|
|
{
|
|
printf("failed to write to wscsvc\n");
|
|
return false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (!reg::set_keyval(hkey, L"Start", 4)) // Disabled
|
|
{
|
|
printf("failed to write to wscsvc\n");
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
// Stop or run the windefend service
|
|
//
|
|
bool manage_windefend(bool enable)
|
|
{
|
|
return manage_security_service(enable, "WinDefend");
|
|
}
|
|
|
|
// Disables window defender
|
|
//
|
|
bool disable_defender()
|
|
{
|
|
HKEY hkey;
|
|
|
|
// DisableAntiSpyware
|
|
if (reg::create_registry(L"SOFTWARE\\Policies\\Microsoft\\Windows Defender", hkey))
|
|
{
|
|
if (!reg::set_keyval(hkey, L"DisableAntiSpyware", 1))
|
|
printf("failed to write to DisableAntiSpyware\n");
|
|
}
|
|
else
|
|
printf("Failed to access Policies\n");
|
|
|
|
// SecurityHealth
|
|
if (reg::create_registry(
|
|
L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\StartupApproved\\Run",
|
|
hkey))
|
|
{
|
|
if (!reg::set_keyval_bin(hkey, L"SecurityHealth", 3))
|
|
printf("Failed to write to SecurityHealth\n");
|
|
}
|
|
else
|
|
printf("Failed to access CurrentVersion\n");
|
|
|
|
// Protected by anti-tamper
|
|
if (reg::create_registry(L"SOFTWARE\\Microsoft\\Windows Defender", hkey))
|
|
{
|
|
if (!reg::set_keyval(hkey, L"DisableAntiSpyware", 1))
|
|
printf("Failed to write to DisableAntiSpyware");
|
|
}
|
|
else
|
|
printf("Failed to access Windows Defender\n");
|
|
|
|
// Protected by anti-tamper
|
|
// Start (3 off) (2 on)
|
|
if (reg::create_registry(L"SYSTEM\\CurrentControlSet\\Services\\WinDefend", hkey))
|
|
{
|
|
reg::set_keyval(hkey, L"Start", 3);
|
|
}
|
|
else
|
|
printf("Failed to access CurrentControlSet\n");
|
|
|
|
// Protected by anti-tamper
|
|
if (reg::create_registry(L"SOFTWARE\\Microsoft\\Windows Defender\\Real-Time Protection", hkey))
|
|
{
|
|
if (!reg::set_keyval(hkey, L"DisableRealtimeMonitoring", 1))
|
|
printf("Failed to write to DisableRealTimeMonitoring\n");
|
|
}
|
|
else
|
|
printf("Failed to access Real-Time Protection");
|
|
|
|
auto helper = new wmic::helper(
|
|
"Root\\Microsoft\\Windows\\Defender",
|
|
"MSFT_MpPreference",
|
|
"Set"
|
|
);
|
|
|
|
if (auto error = helper->get_last_error())
|
|
{
|
|
printf("Error has occured: %d\n", error);
|
|
return false;
|
|
}
|
|
|
|
// string types
|
|
helper->execute("EnableControlledFolderAccess", "Disabled");
|
|
helper->execute("PUAProtection", "disable");
|
|
|
|
// bool types
|
|
helper->execute<BOOL>("DisableRealtimeMonitoring", wmic::variant_type::t_bool, TRUE);
|
|
helper->execute<BOOL>("DisableBehaviorMonitoring", wmic::variant_type::t_bool, TRUE);
|
|
helper->execute<BOOL>("DisableBlockAtFirstSeen", wmic::variant_type::t_bool, TRUE);
|
|
helper->execute<BOOL>("DisableIOAVProtection", wmic::variant_type::t_bool, TRUE);
|
|
helper->execute<BOOL>("DisablePrivacyMode", wmic::variant_type::t_bool, TRUE);
|
|
helper->execute<BOOL>("SignatureDisableUpdateOnStartupWithoutEngine", wmic::variant_type::t_bool, TRUE);
|
|
helper->execute<BOOL>("DisableArchiveScanning", wmic::variant_type::t_bool, TRUE);
|
|
helper->execute<BOOL>("DisableIntrusionPreventionSystem", wmic::variant_type::t_bool, TRUE);
|
|
helper->execute<BOOL>("DisableScriptScanning", wmic::variant_type::t_bool, TRUE);
|
|
helper->execute<BOOL>("DisableAntiSpyware", wmic::variant_type::t_bool, TRUE);
|
|
helper->execute<BOOL>("DisableAntiVirus", wmic::variant_type::t_bool, TRUE);
|
|
|
|
// values
|
|
helper->execute<uint8_t>("SubmitSamplesConsent", wmic::variant_type::t_uint8, 2);
|
|
helper->execute<uint8_t>("MAPSReporting", wmic::variant_type::t_uint8, 0);
|
|
helper->execute<uint8_t>("HighThreatDefaultAction", wmic::variant_type::t_uint8, 6);
|
|
helper->execute<uint8_t>("ModerateThreatDefaultAction", wmic::variant_type::t_uint8, 6);
|
|
helper->execute<uint8_t>("LowThreatDefaultAction", wmic::variant_type::t_uint8, 6);
|
|
helper->execute<uint8_t>("SevereThreatDefaultAction", wmic::variant_type::t_uint8, 6);
|
|
helper->execute<uint8_t>("ScanScheduleDay", wmic::variant_type::t_uint8, 8);
|
|
|
|
delete helper;
|
|
|
|
return true;
|
|
}
|
|
|
|
// Enables defender, assumes we have TrustedInstaller permissions
|
|
bool enable_defender()
|
|
{
|
|
HKEY hkey;
|
|
|
|
// DisableAntiSpyware
|
|
if (reg::create_registry(L"SOFTWARE\\Policies\\Microsoft\\Windows Defender", hkey))
|
|
{
|
|
if (!reg::set_keyval(hkey, L"DisableAntiSpyware", 0))
|
|
printf("failed to write to DisableAntiSpyware\n");
|
|
}
|
|
else
|
|
printf("Failed to access Policies\n");
|
|
|
|
// SecurityHealth
|
|
if (reg::create_registry(
|
|
L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\StartupApproved\\Run",
|
|
hkey))
|
|
{
|
|
if (!reg::set_keyval_bin(hkey, L"SecurityHealth", 2))
|
|
printf("Failed to write to SecurityHealth\n");
|
|
}
|
|
else
|
|
printf("Failed to access CurrentVersion\n");
|
|
|
|
// Protected by anti-tamper
|
|
if (reg::create_registry(L"SOFTWARE\\Microsoft\\Windows Defender", hkey))
|
|
{
|
|
if (!reg::set_keyval(hkey, L"DisableAntiSpyware", 0))
|
|
printf("Failed to write to DisableAntiSpyware");
|
|
}
|
|
else
|
|
printf("Failed to access Windows Defender\n");
|
|
|
|
// Protected by anti-tamper
|
|
// Start (3 off) (2 on)
|
|
if (reg::create_registry(L"SYSTEM\\CurrentControlSet\\Services\\WinDefend", hkey))
|
|
reg::set_keyval(hkey, L"Start", 2);
|
|
else
|
|
printf("Failed to access CurrentControlSet\n");
|
|
|
|
// Protected by anti-tamper
|
|
if (reg::create_registry(L"SOFTWARE\\Microsoft\\Windows Defender\\Real-Time Protection", hkey))
|
|
{
|
|
if (!reg::set_keyval(hkey, L"DisableRealtimeMonitoring", 0))
|
|
printf("Failed to write to DisableRealTimeMonitoring\n");
|
|
}
|
|
else
|
|
printf("Failed to access Real-Time Protection");
|
|
|
|
auto helper = new wmic::helper(
|
|
"Root\\Microsoft\\Windows\\Defender",
|
|
"MSFT_MpPreference",
|
|
"Set"
|
|
);
|
|
|
|
if (auto error = helper->get_last_error())
|
|
{
|
|
printf("Error has occured: %d\n", error);
|
|
return false;
|
|
}
|
|
|
|
// BSTR types
|
|
helper->execute("EnableControlledFolderAccess", "Enabled");
|
|
helper->execute("PUAProtection", "enable");
|
|
|
|
auto helper_disable = [](wmic::helper* h, const char* name) {
|
|
h->execute<BOOL>(name, wmic::variant_type::t_bool, FALSE);
|
|
};
|
|
|
|
// BOOL types
|
|
helper_disable(helper, "DisableRealtimeMonitoring");
|
|
helper_disable(helper, "DisableBehaviorMonitoring");
|
|
helper_disable(helper, "DisableBlockAtFirstSeen");
|
|
helper_disable(helper, "DisableIOAVProtection");
|
|
helper_disable(helper, "DisablePrivacyMode");
|
|
helper_disable(helper, "SignatureDisableUpdateOnStartupWithoutEngine");
|
|
helper_disable(helper, "DisableArchiveScanning");
|
|
helper_disable(helper, "DisableIntrusionPreventionSystem");
|
|
helper_disable(helper, "DisableScriptScanning");
|
|
helper_disable(helper, "DisableAntiSpyware");
|
|
helper_disable(helper, "DisableAntiVirus");
|
|
|
|
// Cleanup
|
|
delete helper;
|
|
|
|
manage_windefend(true);
|
|
manage_security_center(true);
|
|
|
|
return true;
|
|
}
|
|
|
|
// Returns true if RealTimeMonitoring is activated
|
|
//
|
|
bool check_defender(uint32_t flags)
|
|
{
|
|
// Unreliable method if anti-tamper is enabled.
|
|
//return REG::read_key(
|
|
// L"SOFTWARE\\Microsoft\\Windows Defender\\Real-Time Protection",
|
|
// L"DisableRealtimeMonitoring") == 0;
|
|
|
|
auto helper = new wmic::helper(
|
|
"Root\\Microsoft\\Windows\\Defender",
|
|
"MSFT_MpPreference",
|
|
"Set"
|
|
);
|
|
|
|
if (auto error = helper->get_last_error())
|
|
{
|
|
// Throw error instead
|
|
printf("Error has occured: %d\n", error);
|
|
delete helper;
|
|
return true;
|
|
}
|
|
|
|
bool result = false;
|
|
helper->get<bool>("DisableRealtimeMonitoring", wmic::variant_type::t_bool, result);
|
|
delete helper;
|
|
return (!result);
|
|
}
|
|
} |