Initial commit - KVC Framework v1.0.1

This commit is contained in:
wesmar
2025-09-17 21:46:05 +02:00
commit 736a8eb685
60 changed files with 14401 additions and 0 deletions

750
kvc/Kvc.cpp Normal file
View File

@@ -0,0 +1,750 @@
/*******************************************************************************
_ ____ ______
| |/ /\ \ / / ___|
| ' / \ \ / / |
| . \ \ V /| |___
|_|\_\ \_/ \____|
The **Kernel Vulnerability Capabilities (KVC)** framework represents a paradigm shift in Windows security research,
offering unprecedented access to modern Windows internals through sophisticated ring-0 operations. Originally conceived
as "Kernel Process Control," the framework has evolved to emphasize not just control, but the complete **exploitation
of kernel-level primitives** for legitimate security research and penetration testing.
KVC addresses the critical gap left by traditional forensic tools that have become obsolete in the face of modern Windows
security hardening. Where tools like ProcDump and Process Explorer fail against Protected Process Light (PPL) and Antimalware
Protected Interface (AMSI) boundaries, KVC succeeds by operating at the kernel level, manipulating the very structures
that define these protections.
-----------------------------------------------------------------------------
Author : Marek Wesołowski
Email : marek@wesolowski.eu.org
Phone : +48 607 440 283 (Tel/WhatsApp)
Date : 04-09-2025
*******************************************************************************/
#include "common.h"
#include "Controller.h"
#include "ServiceManager.h"
#include "HelpSystem.h"
#include <string_view>
#include <charconv>
#include <signal.h>
#include <unordered_map>
#include <algorithm>
// Forward declarations for utility functions
std::optional<DWORD> ParsePid(std::wstring_view pidStr) noexcept;
bool IsNumeric(std::wstring_view str) noexcept;
bool IsHelpFlag(std::wstring_view arg) noexcept;
std::optional<TrustedInstallerIntegrator::ExclusionType> ParseExclusionType(std::wstring_view typeStr) noexcept;
void CleanupDriver() noexcept;
// Global state for signal handling and cleanup
volatile bool g_interrupted = false;
std::unique_ptr<Controller> g_controller = nullptr;
// Signal handler for graceful Ctrl+C cleanup preventing system instability
void SignalHandler(int signal)
{
if (signal == SIGINT && !g_interrupted)
{
g_interrupted = true;
std::wcout << L"\n[!] Ctrl+C detected - emergency cleanup..." << std::endl;
if (g_controller)
{
try
{
g_controller->StopDriverService();
std::wcout << L"[+] Emergency cleanup completed" << std::endl;
}
catch (...)
{
std::wcout << L"[-] Emergency cleanup failed" << std::endl;
}
}
ExitProcess(130);
}
}
// Parse exclusion type from string for enhanced Defender management
std::optional<TrustedInstallerIntegrator::ExclusionType> ParseExclusionType(std::wstring_view typeStr) noexcept
{
static const std::unordered_map<std::wstring, TrustedInstallerIntegrator::ExclusionType> typeMap = {
{L"paths", TrustedInstallerIntegrator::ExclusionType::Paths},
{L"processes", TrustedInstallerIntegrator::ExclusionType::Processes},
{L"extensions", TrustedInstallerIntegrator::ExclusionType::Extensions},
{L"ipaddresses", TrustedInstallerIntegrator::ExclusionType::IpAddresses}
};
std::wstring lowerType(typeStr);
std::transform(lowerType.begin(), lowerType.end(), lowerType.begin(), ::towlower);
auto it = typeMap.find(lowerType);
return (it != typeMap.end()) ? std::make_optional(it->second) : std::nullopt;
}
// Main application entry point with comprehensive command handling
int wmain(int argc, wchar_t* argv[])
{
signal(SIGINT, SignalHandler);
// Service mode detection - MUST BE FIRST to handle NT service startup
if (argc >= 2) {
std::wstring_view firstArg = argv[1];
if (firstArg == L"--service") {
return ServiceManager::RunAsService();
}
}
// Display help if no arguments or help flag provided
if (argc < 2)
{
HelpSystem::PrintUsage(argv[0]);
return 1;
}
std::wstring_view firstArg = argv[1];
if (IsHelpFlag(firstArg))
{
HelpSystem::PrintUsage(argv[0]);
return 0;
}
// Initialize controller for kernel operations
g_controller = std::make_unique<Controller>();
std::wstring_view command = firstArg;
try
{
// Service management commands for advanced deployment scenarios
if (command == L"install")
{
wchar_t exePath[MAX_PATH];
if (GetModuleFileNameW(nullptr, exePath, MAX_PATH) == 0) {
ERROR(L"Failed to get current executable path");
return 1;
}
INFO(L"Installing Kernel Vulnerability Capabilities Framework service for advanced scenarios...");
bool success = ServiceManager::InstallService(exePath);
return success ? 0 : 1;
}
else if (command == L"uninstall")
{
INFO(L"Uninstalling Kernel Vulnerability Capabilities Framework service...");
bool success = ServiceManager::UninstallService();
return success ? 0 : 1;
}
else if (command == L"service")
{
if (argc < 3) {
ERROR(L"Missing service command. Usage: service <start|stop|status>");
return 1;
}
std::wstring_view serviceCmd = argv[2];
if (serviceCmd == L"start") {
INFO(L"Starting Kernel Vulnerability Capabilities Framework service...");
bool success = ServiceManager::StartServiceProcess();
if (success) {
SUCCESS(L"Service started successfully");
return 0;
} else {
ERROR(L"Failed to start service");
return 1;
}
}
else if (serviceCmd == L"stop") {
INFO(L"Stopping Kernel Vulnerability Capabilities Framework service...");
bool success = ServiceManager::StopServiceProcess();
if (success) {
SUCCESS(L"Service stopped successfully");
return 0;
} else {
ERROR(L"Failed to stop service");
return 1;
}
}
else if (serviceCmd == L"status") {
// Enhanced service status checking with detailed output
INFO(L"Checking Kernel Vulnerability Capabilities Framework service status...");
const bool installed = IsServiceInstalled();
const bool running = installed ? IsServiceRunning() : false;
std::wcout << L"\n";
INFO(L"Service Information:");
INFO(L" Name: %s", ServiceManager::SERVICE_NAME);
INFO(L" Display Name: %s", ServiceManager::SERVICE_DISPLAY_NAME);
std::wcout << L"\n";
// Status display with appropriate color coding
if (installed) {
SUCCESS(L"Installation Status: INSTALLED");
if (running) {
SUCCESS(L"Runtime Status: RUNNING");
SUCCESS(L"Service is operational and ready for kernel operations");
INFO(L"The service can be controlled via SCM or kvc commands");
} else {
ERROR(L"Runtime Status: STOPPED");
ERROR(L"Service is installed but not currently running");
INFO(L"Use 'kvc service start' to start the service");
}
} else {
ERROR(L"Installation Status: NOT INSTALLED");
ERROR(L"Service is not installed on this system");
INFO(L"Use 'kvc install' to install the service first");
}
std::wcout << L"\n";
return 0;
}
else {
ERROR(L"Unknown service command: %s", serviceCmd.data());
return 1;
}
}
// Sticky keys backdoor management using IFEO technique
else if (command == L"shift")
{
INFO(L"Installing sticky keys backdoor with Defender bypass...");
return g_controller->InstallStickyKeysBackdoor() ? 0 : 2;
}
else if (command == L"unshift")
{
INFO(L"Removing sticky keys backdoor...");
return g_controller->RemoveStickyKeysBackdoor() ? 0 : 2;
}
// Memory dumping operations with automatic privilege escalation
else if (command == L"dump")
{
if (argc < 3)
{
ERROR(L"Missing PID/process name argument for dump command");
return 1;
}
std::wstring_view target = argv[2];
std::wstring outputPath;
// Use provided output path or default to Downloads folder
if (argc >= 4)
outputPath = argv[3];
else
{
wchar_t* downloadsPath;
if (SHGetKnownFolderPath(FOLDERID_Downloads, 0, NULL, &downloadsPath) == S_OK)
{
outputPath = downloadsPath;
outputPath += L"\\";
CoTaskMemFree(downloadsPath);
}
else
{
outputPath = L".\\";
}
}
// Handle numeric PID or process name with pattern matching
if (IsNumeric(target))
{
auto pid = ParsePid(target);
if (!pid)
{
ERROR(L"Invalid PID format: %s", target.data());
return 1;
}
return g_controller->DumpProcess(pid.value(), outputPath) ? 0 : 2;
}
else
{
std::wstring processName(target);
return g_controller->DumpProcessByName(processName, outputPath) ? 0 : 2;
}
}
// Process information commands with color-coded output
else if (command == L"list")
{
return g_controller->ListProtectedProcesses() ? 0 : 2;
}
else if (command == L"get")
{
if (argc < 3)
{
ERROR(L"Missing PID/process name argument for protection query");
return 1;
}
std::wstring_view target = argv[2];
if (IsNumeric(target))
{
auto pid = ParsePid(target);
if (!pid)
{
ERROR(L"Invalid PID format: %s", target.data());
return 1;
}
return g_controller->GetProcessProtection(pid.value()) ? 0 : 2;
}
else
{
std::wstring processName(target);
return g_controller->GetProcessProtectionByName(processName) ? 0 : 2;
}
}
else if (command == L"info")
{
if (argc < 3)
{
ERROR(L"Missing PID/process name argument for detailed information");
return 1;
}
std::wstring_view target = argv[2];
DWORD targetPid = 0;
std::wstring targetProcessName;
bool protectionResult = false;
// Get process info and analyze dumpability with comprehensive reporting
if (IsNumeric(target))
{
auto pid = ParsePid(target);
if (!pid)
{
ERROR(L"Invalid PID format: %s", target.data());
return 1;
}
targetPid = pid.value();
targetProcessName = Utils::GetProcessName(targetPid);
protectionResult = g_controller->GetProcessProtection(targetPid);
}
else
{
targetProcessName = std::wstring(target);
auto match = g_controller->ResolveNameWithoutDriver(targetProcessName);
if (match)
{
targetPid = match->Pid;
targetProcessName = match->ProcessName;
protectionResult = g_controller->GetProcessProtection(targetPid);
}
else
{
return 2;
}
}
// Additional dumpability analysis with detailed reasoning
if (protectionResult && targetPid != 0)
{
auto dumpability = Utils::CanDumpProcess(targetPid, targetProcessName);
if (dumpability.CanDump)
{
SUCCESS(L"Process is dumpable: %s", dumpability.Reason.c_str());
}
else
{
ERROR(L"Process is NOT dumpable: %s", dumpability.Reason.c_str());
}
}
return protectionResult ? 0 : 2;
}
// Event log clearing with administrative privileges
else if (command == L"evtclear")
{
return g_controller->ClearSystemEventLogs() ? 0 : 2;
}
// Process protection commands with atomic driver operations
else if (command == L"set" || command == L"protect")
{
if (argc < 5)
{
ERROR(L"Missing arguments: <PID/process_name> <PP|PPL> <SIGNER_TYPE>");
return 1;
}
std::wstring_view target = argv[2];
std::wstring level = argv[3];
std::wstring signer = argv[4];
bool result = false;
if (IsNumeric(target))
{
auto pid = ParsePid(target);
if (!pid)
{
ERROR(L"Invalid PID format: %s", target.data());
return 1;
}
// 'set' forces protection regardless of current state, 'protect' only protects unprotected processes
result = (command == L"set") ?
g_controller->SetProcessProtection(pid.value(), level, signer) :
g_controller->ProtectProcess(pid.value(), level, signer);
}
else
{
std::wstring processName(target);
result = (command == L"set") ?
g_controller->SetProcessProtectionByName(processName, level, signer) :
g_controller->ProtectProcessByName(processName, level, signer);
}
return result ? 0 : 2;
}
else if (command == L"unprotect")
{
if (argc < 3)
{
ERROR(L"Missing PID/process name argument for unprotection");
return 1;
}
std::wstring_view target = argv[2];
// Handle special 'all' keyword for mass unprotection
if (target == L"all")
{
return g_controller->UnprotectAllProcesses() ? 0 : 2;
}
// Handle comma-separated list of targets for batch operations
std::wstring targetStr(target);
if (targetStr.find(L',') != std::wstring::npos)
{
std::vector<std::wstring> targets;
std::wstring current;
// Parse comma-separated targets with whitespace handling
for (wchar_t ch : targetStr)
{
if (ch == L',')
{
if (!current.empty())
{
targets.push_back(current);
current.clear();
}
}
else if (ch != L' ' && ch != L'\t')
{
current += ch;
}
}
if (!current.empty())
targets.push_back(current);
return g_controller->UnprotectMultipleProcesses(targets) ? 0 : 2;
}
// Handle single target (PID or process name)
if (IsNumeric(target))
{
auto pid = ParsePid(target);
if (!pid)
{
ERROR(L"Invalid PID format: %s", target.data());
return 1;
}
return g_controller->UnprotectProcess(pid.value()) ? 0 : 2;
}
else
{
std::wstring processName(target);
return g_controller->UnprotectProcessByName(processName) ? 0 : 2;
}
}
// System integration commands with TrustedInstaller privileges
else if (command == L"trusted")
{
if (argc < 3)
{
ERROR(L"Missing command argument for elevated execution");
return 1;
}
// Combine all remaining arguments into full command with proper escaping
std::wstring fullCommand;
for (int i = 2; i < argc; i++)
{
if (i > 2) fullCommand += L" ";
fullCommand += argv[i];
}
return g_controller->RunAsTrustedInstaller(fullCommand) ? 0 : 2;
}
else if (command == L"install-context")
{
return g_controller->AddContextMenuEntries() ? 0 : 1;
}
// Enhanced Windows Defender exclusion management with type specification
else if (command == L"add-exclusion")
{
if (argc < 3) {
ERROR(L"Missing arguments for exclusion. Usage: add-exclusion [TYPE] <value> or add-exclusion <path>");
return 1;
}
// New syntax with type specification: kvc add-exclusion Processes malware.exe
if (argc >= 4) {
std::wstring_view typeStr = argv[2];
std::wstring value = argv[3];
auto exclusionType = ParseExclusionType(typeStr);
if (!exclusionType) {
ERROR(L"Invalid exclusion type: %s. Valid types: Paths, Processes, Extensions, IpAddresses", typeStr.data());
return 1;
}
return g_controller->AddDefenderExclusion(exclusionType.value(), value) ? 0 : 1;
}
// Legacy syntax for backward compatibility: kvc add-exclusion C:\file.exe
else {
std::wstring filePath = argv[2];
return g_controller->AddToDefenderExclusions(filePath) ? 0 : 1;
}
}
else if (command == L"remove-exclusion")
{
if (argc < 3) {
ERROR(L"Missing arguments for exclusion removal. Usage: remove-exclusion [TYPE] <value> or remove-exclusion <path>");
return 1;
}
// New syntax with type specification: kvc remove-exclusion Processes malware.exe
if (argc >= 4) {
std::wstring_view typeStr = argv[2];
std::wstring value = argv[3];
auto exclusionType = ParseExclusionType(typeStr);
if (!exclusionType) {
ERROR(L"Invalid exclusion type: %s. Valid types: Paths, Processes, Extensions, IpAddresses", typeStr.data());
return 1;
}
return g_controller->RemoveDefenderExclusion(exclusionType.value(), value) ? 0 : 1;
}
// Legacy syntax for backward compatibility: kvc remove-exclusion C:\file.exe
else {
std::wstring filePath = argv[2];
return g_controller->RemoveFromDefenderExclusions(filePath) ? 0 : 1;
}
}
// DPAPI secrets extraction commands with comprehensive browser support
else if (command == L"export")
{
if (argc < 3)
{
ERROR(L"Missing subcommand for export. Usage: export secrets [output_path]");
return 1;
}
std::wstring_view subCommand = argv[2];
if (subCommand == L"secrets")
{
std::wstring outputPath;
// Use provided output path or default to Downloads folder
if (argc >= 4)
{
outputPath = argv[3];
}
else
{
wchar_t* downloadsPath;
if (SHGetKnownFolderPath(FOLDERID_Downloads, 0, NULL, &downloadsPath) == S_OK)
{
outputPath = downloadsPath;
CoTaskMemFree(downloadsPath);
}
else
{
outputPath = L".\\";
}
}
INFO(L"Exporting secrets using TrustedInstaller privileges...");
return g_controller->ShowPasswords(outputPath) ? 0 : 2;
}
else
{
ERROR(L"Unknown export subcommand: %s. Available: secrets", subCommand.data());
return 1;
}
}
// Browser passwords extraction with kvc_pass integration
else if (command == L"browser-passwords" || command == L"bp")
{
std::wstring browserType = L"chrome"; // Default to Chrome
std::wstring outputPath = L"."; // Current directory
// Parse arguments
for (int i = 2; i < argc; i++) {
std::wstring arg = argv[i];
if (arg == L"--chrome") {
browserType = L"chrome";
} else if (arg == L"--brave") {
browserType = L"brave";
} else if (arg == L"--edge") {
browserType = L"edge";
} else if (arg == L"--output" || arg == L"-o") {
if (i + 1 < argc) {
outputPath = argv[++i];
} else {
ERROR(L"Missing path for --output argument");
return 1;
}
} else {
ERROR(L"Unknown argument: %s", arg.c_str());
return 1;
}
}
if (browserType == L"edge") {
// First run kvc_pass (cookies / logins)
if (!g_controller->ExportBrowserData(outputPath, browserType)) {
ERROR(L"Failed to export Edge cookies/logins");
}
// Then run DPAPI (KVC) Edge passwords from registry
INFO(L"Extracting Edge passwords via KVC DPAPI...");
g_controller->ShowPasswords(outputPath);
return 0;
} else {
// Chrome, Brave only kvc_pass
if (!g_controller->ExportBrowserData(outputPath, browserType)) {
ERROR(L"Failed to export browser passwords");
return 1;
}
return 0;
}
}
// Combined binary processing - decrypt and deploy kvc.dat components
else if (command == L"setup")
{
INFO(L"Loading and processing kvc.dat combined binary...");
return g_controller->LoadAndSplitCombinedBinaries() ? 0 : 2;
}
else
{
ERROR(L"Unknown command: %s", command.data());
HelpSystem::PrintUsage(argv[0]);
return 1;
}
}
catch (const std::exception& e)
{
std::string msg = e.what();
std::wstring wmsg(msg.begin(), msg.end());
ERROR(L"Exception occurred: %s", wmsg.c_str());
CleanupDriver();
return 3;
}
catch (...)
{
ERROR(L"Unknown exception occurred during execution");
CleanupDriver();
return 3;
}
CleanupDriver();
return 0;
}
// Emergency cleanup for driver resources
void CleanupDriver() noexcept
{
if (g_controller)
{
g_controller->StopDriverService();
}
}
// Robust PID parsing with validation
std::optional<DWORD> ParsePid(std::wstring_view pidStr) noexcept
{
if (pidStr.empty()) return std::nullopt;
// Convert wide string to narrow for std::from_chars
std::string narrowStr;
narrowStr.reserve(pidStr.size());
for (wchar_t wc : pidStr)
{
if (wc > 127) return std::nullopt; // Non-ASCII character
narrowStr.push_back(static_cast<char>(wc));
}
DWORD result = 0;
auto [ptr, ec] = std::from_chars(narrowStr.data(),
narrowStr.data() + narrowStr.size(),
result);
return (ec == std::errc{} && ptr == narrowStr.data() + narrowStr.size()) ?
std::make_optional(result) : std::nullopt;
}
// Check if string contains only digits
bool IsNumeric(std::wstring_view str) noexcept
{
if (str.empty()) return false;
for (wchar_t ch : str)
{
if (ch < L'0' || ch > L'9')
return false;
}
return true;
}
// Recognize various help flag formats
bool IsHelpFlag(std::wstring_view arg) noexcept
{
if (arg == L"/?" || arg == L"/help" || arg == L"/h")
return true;
if (arg == L"-?" || arg == L"-help" || arg == L"-h")
return true;
if (arg == L"--help" || arg == L"--h")
return true;
if (arg == L"help" || arg == L"?")
return true;
return false;
}