ACA Token中文网

栏目分类
ContentBox中文网
ContentBox中文网
驱动向应用层(R0-R3) 创建线程的一种实现-编程技术-看雪-安全社区|安全招聘|kanxue.com
发布日期:2025-01-04 15:15    点击次数:129
在网上找了很长时间也没找到驱动向应用层创建线程的方法,于是自己研究了一份,现在把研究的结果共享给大家。1.获取NtCreateThreadEx接口的地址NtCreateThreadEx是未导出函数,需要我们手动获取地址。对于各位大手子来说在驱动里获取一个未导出接口的地址肯定不是难事,这里不多赘述。2.构造NtCreateThreadEx的参数NtCreateThreadEx函数的定义NTSTATUS NtCreateThreadEx(     OUT PHANDLE ThreadHandle,     IN ACCESS_MASK DesiredAccess,     IN POBJECT_ATTRIBUTES ObjectAttributes,     IN HANDLE ProcessHandle,     IN PVOID StartRoutine,     IN PVOID Argument,     IN ULONG CreateFlags,     IN SIZE_T ZeroBits,     IN SIZE_T StackSize,     IN SIZE_T MaximumStackSize,     OUT PPS_ATTRIBUTE_LIST AttributeList);构造ObjectAttributes参数OBJECT_ATTRIBUTES objAttr; CLIENT_ID clientId; InitializeObjectAttributes(&objAttr, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);构造 shellcode,也就是线程的启动地址。这里我用的是FreeLibrary 函数作为启动地址,当然具体的函数参数(RCX)和函数地址都是动态的,需要执行的时候进行赋值。UCHAR opcodes[] = {     0x48, 0x83, 0xEC, 0x28, // sub rsp, 0x28     0x48, 0x31, 0xC9, // xor rcx, rcx     0x48, 0x31, 0xc0,// xor rax, rax     0x48, 0xb9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,//mov rcx, ModuleBase     0x48, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,//mov rax, func_FreeLibrary     0xff, 0xd0,//call   rax     0x48, 0x83, 0xC4, 0x28, // add rsp, 0x28     0xc3,//ret};3.在应用程序中分配内存并创建线程这里采用附加读写的方式进行内存分配 KAPC_STATE ApcState = { 0 }; KeStackAttachProcess(TargetProcess, &ApcState); //设置当前线程运行在用户模式 _KTHREAD->PreviousMode = UserMode //给shellcode分配内存 PVOID codeBuffer = 0;     ZwAllocateVirtualMemory(ZwCurrentProcess(), &codeBuffer, 0, &Size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);     RtlZeroMemory(codeBuffer, Size);     memcpy(codeBuffer, opcodes, sizeof(opcodes)); //设置当前线程运行在内核模式并创建线程 _KTHREAD->PreviousMode = KernelMode  NTSTATUS status;  HANDLE hThread;  status = NtCreateThreadEx(&hThread,         THREAD_ALL_ACCESS,         &objAttr,         NtCurrentProcess(),         (PVOID)codeBuffer,         (PVOID)NULL,         0,         0,         0x1000,         0x1000,         NULL); //重新设置为用户模式,并等待线程执行完毕 _KTHREAD->PreviousMode = UserMode     if (NT_SUCCESS(status)) {         // 延迟 60s         LARGE_INTEGER Timeout = { 0 };         Timeout.QuadPart = -(60ll * 10 * 1000 * 1000);         status = ZwWaitForSingleObject(hThread, TRUE, &Timeout);         NtClose(hThread);     } //释放分配的内存 status = ZwFreeVirtualMemory(NtCurrentProcess(), &codeBuffer, &Size, MEM_RELEASE);   //恢复原来的运行模式 _KTHREAD->PreviousMode = oldMode; KeUnstackDetachProcess(&ApcState);以上就是内核向用户层创建线程的全部思路,如果有问题可以在评论区留言。 [竞赛]2024 KCTF 大赛征题截止日期08月10日!

友情链接:

Powered by ACA Token中文网 @2013-2022 RSS地图 HTML地图

Copyright Powered by365建站 © 2013-2024