驱动实现降权保护

2.1 实现的意义

阻止进程被调试,使进程无法被挂载,无法读取到被保护进程的内存空间

2.2 实现原理

OpenProcess 是一个三环的函数,但是其本质是调用了内核层的 NTOpenProcess,Windows 会在调用这个函数的时候,检查这个函数的回调函数有没有被注册,这个回调函数分两种,一种是在 openprocess 执行之前调用,一种是在执行之后调用

只需要在执行之前调用的回调函数中检查被申请打开的进程,是不是需要被保护的进程,检查请求的权限,如果是敏感权限就把权限降到最低

2.3 过掉降权保护的方法初探

TODO

2.4 实现过程

回调注册: 在DriverEntry函数中,通过填充OB_CALLBACK_REGISTRATION和OB_OPERATION_REGISTRATION结构体,然后调用ObRegisterCallbacks函数来注册回调

回调函数: 通过PsLookupProcessByProcessId获取要保护的进程对象 检查当前操作是否是创建句柄操作 检查被操作的对象是否是我们要保护的进程 如果是,则将DesiredAccess设为0,即移除所有访问权限

权限控制: 通过修改OperationInformation->Parameters->CreateHandleInformation.DesiredAccess,我们可以控制其他进程能够获得的权限。将其设为0意味着其他进程无法获得任何有效的访问权限

2.5 代码如下(降权保护)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
//修改里面的g_pid可以实现对不同进程进行降权保护,直观效果是加载驱动后,被保护的进程无法被CE附加
// 注:要注册回调函数需要 release 编译,在链接器命令行中添加如下指令 /INTEGRITYCHECK,否则驱动无法加载
#include <ntifs.h>
#include <ntddk.h>


PVOID g_callBack_Handle = 0;
HANDLE g_pid = (HANDLE)6776;

void uninstall(PDRIVER_OBJECT DriverObjec) {
	UNREFERENCED_PARAMETER(DriverObjec);
	if (g_callBack_Handle != 0) {
		ObUnRegisterCallbacks(g_callBack_Handle);
	}

}
// 前回调和后回调是不同的结构体,这边注册的是前回调函数
OB_PREOP_CALLBACK_STATUS ObProceeCallBack(PVOID RegistrationContext, POB_PRE_OPERATION_INFORMATION OperationInformation) {
	UNREFERENCED_PARAMETER(RegistrationContext);
	PEPROCESS process{ 0 };
	PsLookupProcessByProcessId(g_pid, &process);
	if (OperationInformation->Operation == OB_OPERATION_HANDLE_CREATE) {
		if (OperationInformation->Object == process) {

			OperationInformation->Parameters->CreateHandleInformation.DesiredAccess = 0;
		}
	}
	return OB_PREOP_SUCCESS;

}

EXTERN_C NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegisterPath) {
	UNREFERENCED_PARAMETER(RegisterPath);

	OB_CALLBACK_REGISTRATION callBackReg{ 0 };
	OB_OPERATION_REGISTRATION callbackOper{ 0 };


	callBackReg.Version = OB_FLT_REGISTRATION_VERSION;
	callBackReg.OperationRegistrationCount = 1;
	callBackReg.Altitude = RTL_CONSTANT_STRING(L"371113.121"); //随便填一个值
	callBackReg.RegistrationContext = nullptr;
	callBackReg.OperationRegistration = &callbackOper;
	callbackOper.ObjectType = PsProcessType;
	callbackOper.Operations = OB_OPERATION_HANDLE_CREATE;
	callbackOper.PreOperation = ObProceeCallBack;
	callbackOper.PostOperation = nullptr;
	DriverObject->DriverUnload = uninstall;


	return ObRegisterCallbacks(&callBackReg, &g_callBack_Handle);
}