基于句柄降权的进程保护机制详解

技术原理

安全软件,反作弊软件经常会有自保护策略,其中的一种常用策略是使用ObRegisterCallbacks()注册进程对象操作回调,指定回调函数为PreOperationCallback(),在回调函数中对创建要保护进程句柄的操作进行拦截,并且取消句柄的终止进程权限,以此达到防止进程被终止的目的。

源码展示

以下代码基于上述方法实现了一个针对”cmd.exe”的保护驱动(测试时需要管理员运行bcdedit /set testsigning on,开启测试模式)

#include <ntddk.h>
#define PROCESS_TERMINATE 0x0001
DRIVER_INITIALIZE DriverEntry;
NTKERNELAPI UCHAR* PsGetProcessImageFileName(__in PEPROCESS Process);
PVOID RegistrationHandle = NULL;
OB_PREOP_CALLBACK_STATUS PreOperationCallback(
_In_ PVOID RegistrationContext,
_In_ POB_PRE_OPERATION_INFORMATION OperationInformation
) {
UNREFERENCED_PARAMETER(RegistrationContext);
// filter by process name "cmd.exe"
PUCHAR name = PsGetProcessImageFileName((PEPROCESS)OperationInformation->Object);
if (strcmp((const char*)name, "cmd.exe") != 0) {
return OB_PREOP_SUCCESS;
}
// filter operation "OB_OPERATION_HANDLE_CREATE", and remove "PROCESS_TERMINATE"
if (OperationInformation->Operation == OB_OPERATION_HANDLE_CREATE) {
KdPrintEx((DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,
"ProcessProtect: callback remove [%s] PROCESS_TERMINATE\n", name));
OperationInformation->Parameters->CreateHandleInformation.DesiredAccess &= ~PROCESS_TERMINATE;
}
return OB_PREOP_SUCCESS;
}
VOID OnUnload(_In_ PDRIVER_OBJECT DriverObject) {
UNREFERENCED_PARAMETER(DriverObject);
// unregister callbacks
if (RegistrationHandle != NULL) {
ObUnRegisterCallbacks(RegistrationHandle);
RegistrationHandle = NULL;
}
KdPrintEx((DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "ProcessProtect: unload driver\n"));
}
NTSTATUS DriverEntry(
_In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath
) {
OB_OPERATION_REGISTRATION OperationRegistrations = { 0 };
OB_CALLBACK_REGISTRATION ObRegistration = { 0 };
UNICODE_STRING Altitude = { 0 };
NTSTATUS Status = STATUS_SUCCESS;
UNREFERENCED_PARAMETER(RegistryPath);
KdPrintEx((DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "ProcessProtect: driver entry\n"));
// register unload function
DriverObject->DriverUnload = OnUnload;
// setup the ObRegistration calls
OperationRegistrations.ObjectType = PsProcessType;
OperationRegistrations.Operations = OB_OPERATION_HANDLE_CREATE;
OperationRegistrations.PreOperation = PreOperationCallback;
RtlInitUnicodeString(&Altitude, L"1000");
ObRegistration.Version = OB_FLT_REGISTRATION_VERSION;
ObRegistration.OperationRegistrationCount = 1;
ObRegistration.Altitude = Altitude;
ObRegistration.RegistrationContext = NULL;
ObRegistration.OperationRegistration = &OperationRegistrations;
Status = ObRegisterCallbacks(&ObRegistration, &RegistrationHandle);
if (!NT_SUCCESS(Status)) {
KdPrintEx((DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,
"ProcessProtect: ObRegisterCallbacks failed status 0x%x\n", Status));
return Status;
}
return STATUS_SUCCESS;
}
#include <ntddk.h>  


#define PROCESS_TERMINATE 0x0001  


DRIVER_INITIALIZE DriverEntry;
NTKERNELAPI UCHAR* PsGetProcessImageFileName(__in PEPROCESS Process);
PVOID RegistrationHandle = NULL;


OB_PREOP_CALLBACK_STATUS PreOperationCallback(
_In_ PVOID RegistrationContext,
_In_ POB_PRE_OPERATION_INFORMATION OperationInformation
) {
UNREFERENCED_PARAMETER(RegistrationContext);


// filter by process name "cmd.exe"  
PUCHAR name = PsGetProcessImageFileName((PEPROCESS)OperationInformation->Object);
if (strcmp((const char*)name, "cmd.exe") != 0) {
return OB_PREOP_SUCCESS;
}


// filter operation "OB_OPERATION_HANDLE_CREATE", and remove "PROCESS_TERMINATE"  
if (OperationInformation->Operation == OB_OPERATION_HANDLE_CREATE) {
KdPrintEx((DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,
"ProcessProtect: callback remove [%s] PROCESS_TERMINATE\n", name));
OperationInformation->Parameters->CreateHandleInformation.DesiredAccess &= ~PROCESS_TERMINATE;
}
return OB_PREOP_SUCCESS;
}


VOID OnUnload(_In_ PDRIVER_OBJECT DriverObject) {
UNREFERENCED_PARAMETER(DriverObject);


// unregister callbacks  
if (RegistrationHandle != NULL) {
ObUnRegisterCallbacks(RegistrationHandle);
RegistrationHandle = NULL;
}


KdPrintEx((DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "ProcessProtect: unload driver\n"));
}


NTSTATUS DriverEntry(
_In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath
) {
OB_OPERATION_REGISTRATION OperationRegistrations = { 0 };
OB_CALLBACK_REGISTRATION ObRegistration = { 0 };
UNICODE_STRING Altitude = { 0 };
NTSTATUS Status = STATUS_SUCCESS;


UNREFERENCED_PARAMETER(RegistryPath);


KdPrintEx((DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "ProcessProtect: driver entry\n"));


// register unload function  
DriverObject->DriverUnload = OnUnload;


// setup the ObRegistration calls  
OperationRegistrations.ObjectType = PsProcessType;
OperationRegistrations.Operations = OB_OPERATION_HANDLE_CREATE;
OperationRegistrations.PreOperation = PreOperationCallback;


RtlInitUnicodeString(&Altitude, L"1000");


ObRegistration.Version = OB_FLT_REGISTRATION_VERSION;
ObRegistration.OperationRegistrationCount = 1;
ObRegistration.Altitude = Altitude;
ObRegistration.RegistrationContext = NULL;
ObRegistration.OperationRegistration = &OperationRegistrations;


Status = ObRegisterCallbacks(&ObRegistration, &RegistrationHandle);
if (!NT_SUCCESS(Status)) {
KdPrintEx((DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,
"ProcessProtect: ObRegisterCallbacks failed status 0x%x\n", Status));
return Status;
}


return STATUS_SUCCESS;
}
#include <ntddk.h>   #define PROCESS_TERMINATE 0x0001   DRIVER_INITIALIZE DriverEntry; NTKERNELAPI UCHAR* PsGetProcessImageFileName(__in PEPROCESS Process); PVOID RegistrationHandle = NULL; OB_PREOP_CALLBACK_STATUS PreOperationCallback( _In_ PVOID RegistrationContext, _In_ POB_PRE_OPERATION_INFORMATION OperationInformation ) { UNREFERENCED_PARAMETER(RegistrationContext); // filter by process name "cmd.exe"   PUCHAR name = PsGetProcessImageFileName((PEPROCESS)OperationInformation->Object); if (strcmp((const char*)name, "cmd.exe") != 0) { return OB_PREOP_SUCCESS; } // filter operation "OB_OPERATION_HANDLE_CREATE", and remove "PROCESS_TERMINATE"   if (OperationInformation->Operation == OB_OPERATION_HANDLE_CREATE) { KdPrintEx((DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "ProcessProtect: callback remove [%s] PROCESS_TERMINATE\n", name)); OperationInformation->Parameters->CreateHandleInformation.DesiredAccess &= ~PROCESS_TERMINATE; } return OB_PREOP_SUCCESS; } VOID OnUnload(_In_ PDRIVER_OBJECT DriverObject) { UNREFERENCED_PARAMETER(DriverObject); // unregister callbacks   if (RegistrationHandle != NULL) { ObUnRegisterCallbacks(RegistrationHandle); RegistrationHandle = NULL; } KdPrintEx((DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "ProcessProtect: unload driver\n")); } NTSTATUS DriverEntry( _In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath ) { OB_OPERATION_REGISTRATION OperationRegistrations = { 0 }; OB_CALLBACK_REGISTRATION ObRegistration = { 0 }; UNICODE_STRING Altitude = { 0 }; NTSTATUS Status = STATUS_SUCCESS; UNREFERENCED_PARAMETER(RegistryPath); KdPrintEx((DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "ProcessProtect: driver entry\n")); // register unload function   DriverObject->DriverUnload = OnUnload; // setup the ObRegistration calls   OperationRegistrations.ObjectType = PsProcessType; OperationRegistrations.Operations = OB_OPERATION_HANDLE_CREATE; OperationRegistrations.PreOperation = PreOperationCallback; RtlInitUnicodeString(&Altitude, L"1000"); ObRegistration.Version = OB_FLT_REGISTRATION_VERSION; ObRegistration.OperationRegistrationCount = 1; ObRegistration.Altitude = Altitude; ObRegistration.RegistrationContext = NULL; ObRegistration.OperationRegistration = &OperationRegistrations; Status = ObRegisterCallbacks(&ObRegistration, &RegistrationHandle); if (!NT_SUCCESS(Status)) { KdPrintEx((DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "ProcessProtect: ObRegisterCallbacks failed status 0x%x\n", Status)); return Status; } return STATUS_SUCCESS; }

核心代码

回调函数实现

OB_PREOP_CALLBACK_STATUS PreOperationCallback(
_In_ PVOID RegistrationContext,
_In_ POB_PRE_OPERATION_INFORMATION OperationInformation
) {
// 获取进程名称
PUCHAR name = PsGetProcessImageFileName(
(PEPROCESS)OperationInformation->Object
);
// 仅处理cmd.exe进程
if (strcmp((const char*)name, "cmd.exe") != 0) {
return OB_PREOP_SUCCESS;
}
// 移除进程终止权限
if (OperationInformation->Operation == OB_OPERATION_HANDLE_CREATE) {
OperationInformation->Parameters->CreateHandleInformation
.DesiredAccess &= ~PROCESS_TERMINATE;
}
return OB_PREOP_SUCCESS;
}
OB_PREOP_CALLBACK_STATUS PreOperationCallback(  
    _In_ PVOID RegistrationContext,  
    _In_ POB_PRE_OPERATION_INFORMATION OperationInformation  
) {  
    // 获取进程名称  
    PUCHAR name = PsGetProcessImageFileName(  
        (PEPROCESS)OperationInformation->Object  
    );  

    // 仅处理cmd.exe进程  
    if (strcmp((const char*)name, "cmd.exe") != 0) {  
        return OB_PREOP_SUCCESS;  
    }  

    // 移除进程终止权限  
    if (OperationInformation->Operation == OB_OPERATION_HANDLE_CREATE) {  
        OperationInformation->Parameters->CreateHandleInformation  
            .DesiredAccess &= ~PROCESS_TERMINATE;  
    }  

    return OB_PREOP_SUCCESS;  
}
OB_PREOP_CALLBACK_STATUS PreOperationCallback( _In_ PVOID RegistrationContext, _In_ POB_PRE_OPERATION_INFORMATION OperationInformation ) { // 获取进程名称 PUCHAR name = PsGetProcessImageFileName( (PEPROCESS)OperationInformation->Object ); // 仅处理cmd.exe进程 if (strcmp((const char*)name, "cmd.exe") != 0) { return OB_PREOP_SUCCESS; } // 移除进程终止权限 if (OperationInformation->Operation == OB_OPERATION_HANDLE_CREATE) { OperationInformation->Parameters->CreateHandleInformation .DesiredAccess &= ~PROCESS_TERMINATE; } return OB_PREOP_SUCCESS; }

驱动入口函数

NTSTATUS DriverEntry(
_In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath
) {
// 注册卸载函数
DriverObject->DriverUnload = OnUnload;
// 配置对象回调注册信息
OB_OPERATION_REGISTRATION OperationRegistrations = { 0 };
OperationRegistrations.ObjectType = PsProcessType;
OperationRegistrations.Operations = OB_OPERATION_HANDLE_CREATE;
OperationRegistrations.PreOperation = PreOperationCallback;
// 执行回调注册
ObRegisterCallbacks(&ObRegistration, &RegistrationHandle);
return STATUS_SUCCESS;
}
NTSTATUS DriverEntry(  
    _In_ PDRIVER_OBJECT DriverObject,  
    _In_ PUNICODE_STRING RegistryPath  
) {  
    // 注册卸载函数  
    DriverObject->DriverUnload = OnUnload;  

    // 配置对象回调注册信息  
    OB_OPERATION_REGISTRATION OperationRegistrations = { 0 };  
    OperationRegistrations.ObjectType = PsProcessType;  
    OperationRegistrations.Operations = OB_OPERATION_HANDLE_CREATE;  
    OperationRegistrations.PreOperation = PreOperationCallback;  

    // 执行回调注册  
    ObRegisterCallbacks(&ObRegistration, &RegistrationHandle);  

    return STATUS_SUCCESS;  
}
NTSTATUS DriverEntry( _In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath ) { // 注册卸载函数 DriverObject->DriverUnload = OnUnload; // 配置对象回调注册信息 OB_OPERATION_REGISTRATION OperationRegistrations = { 0 }; OperationRegistrations.ObjectType = PsProcessType; OperationRegistrations.Operations = OB_OPERATION_HANDLE_CREATE; OperationRegistrations.PreOperation = PreOperationCallback; // 执行回调注册 ObRegisterCallbacks(&ObRegistration, &RegistrationHandle); return STATUS_SUCCESS; }

保护效果展示

 

请登录后发表评论

    • pen7st的头像-学技术网软件安全逆向VIPpen7st等级-LV1-学技术网作者0