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

技术原理

安全软件,反作弊软件经常会有自保护策略,其中的一种常用策略是使用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;
}

核心代码

回调函数实现

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;  
}

保护效果展示

 

请登录后发表评论

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