0
点赞
收藏
分享

微信扫一扫

进程强杀初探

SDKB英文 03-15 17:00 阅读 10


前言

我们知道在windows操作系统里面有ring0跟ring3的概念(ring1、ring2在windows中并未使用),因为ring0的特权级别是比ring3高的,那么我们肯定不能在ring3调用windows提供的api杀死ring0特权级别的进程,那么这时候我们就需要使用的ring0的函数来强行结束一些处于ring0级别的进程。

测试


我们首先打开​​PCHunter32.exe​​​看一下,应用层是不能够访问的,我们知道可以在cmd里面使用​​taskkill​​命令来结束进程,但这种方式对ring0特权级别的程序并不适用。


进程强杀初探_ico



看一下​​PCHunter32.exe​​​的PID,尝试使用​​taskkill​​命令关闭发现拒绝访问


进程强杀初探_ico_02


用任务管理器也是同样拒绝访问


进程强杀初探_d3_03


ZwTerminateProcess


ZwTerminateProcess例程终止一个进程​及其​所有线程,它是一个ring0函数,结构及参数如下


NTSYSAPI NTSTATUS ZwTerminateProcess(
[in, optional] HANDLE ProcessHandle,
[in] NTSTATUS ExitStatus
);

进程强杀初探_ico_04


在这个函数里面只需要传入进程句柄和NTSTATUS值就可以杀死一个进程,但是这里又有一个问题,如果我们想利用这个函数去kill掉一个杀软,那么杀软就直接让我们宰割吗,当然不会。


我们能知道这个内核的函数,那么杀软肯定也知道,所以在ring0层面下,杀软将这个内核函数hook掉,如果发现有调用这个函数kill掉自己的企图,还是会拒绝。


PspTerminateProcess


这个函数就有意思了,在msdn里面居然没有找到这个函数,那么是不是我们搞错了呢?


进程强杀初探_内核模块_05


遇事不决找Windbg老师看一下有没有这个结构就知道了,当然是有这个函数的,那为什么在msdn里面找不到呢?


进程强杀初探_ico_06


WDK说明文档中只包含了内核模块导出的函数,对于未导出的函数,则不能直接使用。

如果要使用未导出的函数,则有两种方法来使用:



  1. 暴力搜索,提取该函数的特征码,全盘搜索。
  2. 如果有已文档化的函数调用了PspTerminateProcess,那我们就可以通过指针加偏移的方式获取到他的地址,同样可以调用。


那么我们要想全盘搜索,肯定要先找到内核模块,每个内核模块都有一个对应的结构体,来描述这个模块在内核中的:位置、大小、名称等等。​​DriverEntry​​ 的第一个参数就是这个结构体。

主要关注​DriverSize​​​和​​DriverName​​​这两个参数,​​DriverSize​​​主要是表示驱动的大小,​​DriverName​​为驱动的名称


进程强杀初探_内核模块_07


编写一个驱动输出​​driver​​的地址


#include <ntddk.h>


VOID DriverUnload(PDRIVER_OBJECT driver)
{
DbgPrint("Driver unload successfully!\r\n");
}

NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path)
{
DbgPrint("注册表路径:%wZ 地址:%x Hello world!", reg_path, driver);

DbgPrint("%x", driver);

driver->DriverUnload = DriverUnload;
return STATUS_SUCCESS;
}

部署一下得到地址为85e17030


进程强杀初探_d3_08


然后在​​DRIVER_OBJECT​​结构后面加上地址即可得到我们自己驱动的详细信息

kd> dt _DRIVER_OBJECT 85e17030



进程强杀初探_ico_09


通过 ​​_DRIVER_OBJECT​​​ 结构体中 0x014的偏移有一个成员,​​DriverSection​​​ 则可以实现对内核模块的遍历。DriverSection 是一个指针,实际上是对应着一个结构体:​​_LDR_DATA_TABLE_ENTRY​


看一下​​_LDR_DATA_TABLE_ENTRY​​的结构


kd> dt _LDR_DATA_TABLE_ENTRY


进程强杀初探_d3_10


加上地址即可得到模块的详细信息


进程强杀初探_ico_11


通过​​InLoadOrderLinks​​可以查询到其他内核模块的信息。依此类推,可以获取到其他所有的内核模块。


进程强杀初探_d3_12


进程强杀初探_d3_13


说完了怎样搜寻模块,再来看看怎么找特征码,首先定位到函数。这种mov、push指令因为可能每个模块都会有,所以不能当作特征码,也不能够选重定位的数据当作特征码。


进程强杀初探_ico_14


从中挑选如下代码

805d3487 56              push    esi
805d3488 64a124010000 mov eax,dword ptr fs:[00000124h]
805d348e 8b7508 mov esi,dword ptr [ebp+8]
805d3491 3b7044 cmp esi,dword ptr [eax+44h]
805d3494 7507 jne nt!PspTerminateProcess+0x1b (805d349d)
805d3496 b80d0000c0 mov eax,0C000000Dh
805d349b eb5a jmp nt!PspTerminateProcess+0x75 (805d34f7)
805d349d 57 push edi
805d3487 56              push    esi


提取出的相应特征码如下

UCHAR szSpecialCode[] = {0x56, 0x64, 0xA1, 0x24, 0x01, 0x00, 0x00, 0x8B, 
0x75, 0x08, 0x3B, 0x70, 0x44, 0x75, 0x07, 0xB8,
0x0D, 0x00, 0x00, 0xC0, 0xEB, 0x5A, 0x57 };
UCHAR szSpecialCode[] = {0x56, 0x64, 0xA1, 0x24, 0x01, 0x00, 0x00, 0x8B,


那么编写代码,通过特征码定位到​​PspTerminateProcess​​函数来杀死进程

#include <ntifs.h>

typedef struct _LDR_DATA_TABLE_ENTRY
{
LIST_ENTRY InLoadOrderLinks;
LIST_ENTRY InMemoryOrderLinks;
LIST_ENTRY InInitializationOrderLinks;
PVOID DllBase;
PVOID EntryPoint;
UINT32 SizeOfImage;
UNICODE_STRING FullDllName;
UNICODE_STRING BaseDllName;
UINT32 Flags;
UINT16 LoadCount;
UINT16 TlsIndex;
LIST_ENTRY HashLinks;
PVOID SectionPointer;
UINT32 CheckSum;
UINT32 TimeDateStamp;
PVOID LoadedImports;
PVOID EntryPointActivationContext;
PVOID PatchInformation;
} LDR_DATA_TABLE_ENTRY, * PLDR_DATA_TABLE_ENTRY;

typedef NTSTATUS(*pfnPspTerminateProcess)(PEPROCESS pEprocess, NTSTATUS ExitCode);

VOID DriverUnload(IN PDRIVER_OBJECT driverObject); //卸载驱动
PVOID SearchFunction(PUCHAR DllBase, UINT32 SizeOfImage); // 查找模块中匹配特征码

ULONG g_uPID = 1492; // 要关闭的进程PID

// 特征码
UCHAR g_szSpecialCode[] = {
0x56, 0x64, 0xA1, 0x24, 0x01, 0x00, 0x00, 0x8B,
0x75, 0x08, 0x3B, 0x70, 0x44, 0x75, 0x07, 0xB8,
0x0D, 0x00, 0x00, 0xC0, 0xEB, 0x5A, 0x57 };
// 特征码长度
UINT32 g_uSpecialCodeLen = sizeof(g_szSpecialCode);

NTSTATUS DriverEntry(IN PDRIVER_OBJECT driverObject, IN PUNICODE_STRING registryPath)
{
NTSTATUS status = STATUS_SUCCESS;
PLDR_DATA_TABLE_ENTRY pLdrDataTableEntry = NULL;
pfnPspTerminateProcess pPspTerminateProcess = NULL;
PEPROCESS pEprocess = NULL;

DbgPrint("驱动加载完成\r\n");

pLdrDataTableEntry = (PLDR_DATA_TABLE_ENTRY)driverObject->DriverSection;
pLdrDataTableEntry = CONTAINING_RECORD(pLdrDataTableEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
pLdrDataTableEntry = (PLDR_DATA_TABLE_ENTRY)pLdrDataTableEntry->InLoadOrderLinks.Flink;

do
{
pLdrDataTableEntry = CONTAINING_RECORD(pLdrDataTableEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);

// 如果存在则搜索特征码
if (pLdrDataTableEntry->DllBase)
{
pPspTerminateProcess = (pfnPspTerminateProcess)
SearchFunction((PUCHAR)pLdrDataTableEntry->DllBase, pLdrDataTableEntry->SizeOfImage);
}

if (pPspTerminateProcess)
break;

// 遍历
pLdrDataTableEntry = (PLDR_DATA_TABLE_ENTRY)pLdrDataTableEntry->InLoadOrderLinks.Flink;

} while ((UINT32)pLdrDataTableEntry != (UINT32)driverObject->DriverSection);

if (pPspTerminateProcess)
{
status = PsLookupProcessByProcessId((HANDLE)g_uPID, &pEprocess);
if (NT_SUCCESS(status))
{
status = pPspTerminateProcess(pEprocess, 0);

if (NT_SUCCESS(status))
{
DbgPrint("使用 PspTerminateProcess 关闭进程成功, PID = %d\r\n", g_uPID);
}
}
else
{
DbgPrint("PsLookupProcessByProcessId Error 0x%X\r\n", status);
}
}

driverObject->DriverUnload = DriverUnload;
return STATUS_SUCCESS;
}

VOID DriverUnload(IN PDRIVER_OBJECT driverObject)
{
DbgPrint("驱动卸载完成\r\n");
}

PVOID SearchFunction(PUCHAR DllBase, UINT32 SizeOfImage)
{
DbgPrint("Here is MemorySearch , length is : %d\r\n", SizeOfImage);

PVOID pFuncAddr = NULL;
UINT32 uEnd = (UINT32)DllBase + SizeOfImage - g_uSpecialCodeLen; // 减去特征码后的长度
UINT32 i = 0;
BOOLEAN bOk = TRUE;

while ((UINT32)DllBase <= uEnd)
{
bOk = TRUE;
for (i = 0; i < g_uSpecialCodeLen; i++)
{
if (!MmIsAddressValid(&DllBase[i]) || DllBase[i] != g_szSpecialCode[i])
{
bOk = FALSE;
break;
}
}

if (bOk)
{
pFuncAddr = (PVOID)(DllBase - 5);
DbgPrint("找到特征码,内存地址为%p\r\n", pFuncAddr);
break;
}
DllBase++;
}

return pFuncAddr;
}
#include <ntifs.h>


举报

相关推荐

强引用(强持有)

狼人杀小游戏

免杀原理与实践

JVM初探

Python shellcode免杀

编码直接免杀

UnityVuforia初探

AJAX初探

0 条评论