KeServiceDescriptorTable/register-callbacks-manual-mapped
GitHub: KeServiceDescriptorTable/register-callbacks-manual-mapped
该项目演示了如何在手动映射的驱动中通过修补内核内存来绕过系统验证,进而成功注册进程和对象回调。
Stars: 0 | Forks: 0
# 在手动映射的驱动上注册回调
```
PspSetCreateProcessNotifyRoutine:loc_799AB4 call MmVerifyCallbackFunctionCheckFlags
PsSetCreateThreadNotifyRoutineEx+20 call MmVerifyCallbackFunctionCheckFlags
ObRegisterCallbacks+106 call MmVerifyCallbackFunctionCheckFlags
ObRegisterCallbacks+945CB call MmVerifyCallbackFunctionCheckFlags
// not included
MmVerifyCallbackFunction+9 call MmVerifyCallbackFunctionCheckFlags -> KeRegisterBoundCallback+14 call MmVerifyCallbackFunction
```
# 信息
PsSetCreateThreadNotifyRoutine 直接调用 PspSetCreateThreadNotifyRoutine,后者会在不检查函数的情况下注册回调。
PsSetCreateThreadNotifyRoutineEx 调用 MmVerifyCallbackFunctionCheckFlags,该函数会检查函数。(PsSetCreateThreadNotifyRoutineEx)相当没用,直接使用 PsSetCreateThreadNotifyRoutine 即可。这是微软的一个小疏忽。
# 代码
```
#include
#include
void create_process_routine(PEPROCESS process, HANDLE process_id,
PPS_CREATE_NOTIFY_INFO create_info) {
DbgPrint("create process routine");
}
OB_PREOP_CALLBACK_STATUS pre_process_handle_callback(void* context, POB_PRE_OPERATION_INFORMATION information) {
DbgPrint("pre process handle callback");
return OB_PREOP_CALLBACK_STATUS::OB_PREOP_SUCCESS;
}
void post_process_handle_callback(void* context, POB_POST_OPERATION_INFORMATION information) {
DbgPrint("post process handle callback");
}
OB_PREOP_CALLBACK_STATUS pre_thread_handle_callback(void* context, POB_PRE_OPERATION_INFORMATION information) {
DbgPrint("pre thread handle callback");
return OB_PREOP_CALLBACK_STATUS::OB_PREOP_SUCCESS;
}
void post_thread_handle_callback(void* context, POB_POST_OPERATION_INFORMATION information) {
DbgPrint("post process handle callback");
}
NTSTATUS FxDriverEntry() {
auto* ntoskrnl = system::get_system_module(L"ntoskrnl.exe");
if (!ntoskrnl)
return STATUS_UNSUCCESSFUL;
auto mm_verify_callback_function_check_flags = memory::virtual_memory::pattern_scan({ (std::uint64_t)ntoskrnl->DllBase, ntoskrnl->SizeOfImage }, "\x48\x89\x5C\x24\x00\x48\x89\x6C\x24\x00\x48\x89\x74\x24\x00\x57\x48\x83\xEC\x00\x8B\xFA\x48\x8B\xF1",
"xxxx?xxxx?xxxx?xxxx?xxxxx");
if (!mm_verify_callback_function_check_flags)
return STATUS_UNSUCCESSFUL;
const std::uint8_t shellcode[] = { 0x48, 0xC7, 0xC0, 0x01, 0x00, 0x00, 0x00, 0xC3 };
std::uint8_t original_instructions[sizeof(shellcode)] = {};
memcpy(original_instructions, (void*)mm_verify_callback_function_check_flags,
sizeof(original_instructions));
auto mapped = memory::physical_memory::map(
memory::physical_memory::get_physical_for_virtual(mm_verify_callback_function_check_flags),
sizeof(original_instructions)
);
if (!mapped)
return STATUS_UNSUCCESSFUL;
memcpy((void*)mapped, shellcode,
sizeof(shellcode));
PsSetCreateProcessNotifyRoutineEx((PCREATE_PROCESS_NOTIFY_ROUTINE_EX)create_process_routine, false);
OB_OPERATION_REGISTRATION ob_operation_registration[2] = {};
ob_operation_registration[0].ObjectType = PsProcessType;
ob_operation_registration[0].Operations = OB_OPERATION_HANDLE_CREATE | OB_OPERATION_HANDLE_DUPLICATE;
ob_operation_registration[0].PostOperation = post_process_handle_callback;
ob_operation_registration[0].PreOperation = pre_process_handle_callback;
ob_operation_registration[1].ObjectType = PsThreadType;
ob_operation_registration[1].Operations = OB_OPERATION_HANDLE_CREATE | OB_OPERATION_HANDLE_DUPLICATE;
ob_operation_registration[1].PostOperation = post_thread_handle_callback;
ob_operation_registration[1].PreOperation = pre_thread_handle_callback;
OB_CALLBACK_REGISTRATION ob_callback_registration = {};
ob_callback_registration.Version = OB_FLT_REGISTRATION_VERSION;
ob_callback_registration.OperationRegistrationCount = sizeof(ob_operation_registration) / sizeof(ob_operation_registration[0]);
ob_callback_registration.Altitude = RTL_CONSTANT_STRING(L"1969.69");
ob_callback_registration.OperationRegistration = ob_operation_registration;
void* handle = nullptr;
ObRegisterCallbacks(&ob_callback_registration, &handle);
memcpy((void*)mapped, original_instructions,
sizeof(original_instructions));
memory::physical_memory::unmap(mapped, sizeof(original_instructions));
return STATUS_SUCCESS;
}
```
标签:0day挖掘, MmVerifyCallbackFunction, Network, ObRegisterCallbacks, PsSetCreateThreadNotifyRoutine, PsSetCreateThreadNotifyRoutineEx, Windows内核, 内核回调, 内核安全, 内核注入, 内核编程, 句柄回调, 回调注册, 回调绕过, 手动映射, 白帽子, 线程回调, 绕过检测, 网络安全监控, 进程回调, 驱动开发, 驱动隐藏