12
返回列表 发新帖
楼主: Rukia
收起左侧

[可疑文件] 一个漏洞驱动

[复制链接]
图钉鱼
发表于 3 天前 | 显示全部楼层
本帖最后由 图钉鱼 于 2025-8-31 02:02 编辑

https://nvd.nist.gov/vuln/detail/CVE-2020-14979
https://www.ijinshan.com/info/202003201525.shtml
https://ti.qianxin.com/blog/arti ... lready-been-cut-off

WinRing0x64.sys 驱动程序

WinRing0x64.sys这是一个被广泛使用的硬件访问库的内核驱动程序,许多合法的PC硬件监控和风扇控制软件(如雷蛇、赛睿、EVGA的产品)都使用它来访问I/O端口、MSR和PCI总线。

该驱动程序存在一个公开披露的安全漏洞,编号为 CVE-2020-14979。
漏洞描述:该漏洞允许本地用户,甚至是低完整性级别的进程,读取和写入任意内存位置。通过IDA分析发现的可通过IOCTL直接控制MmMapIoSpace函数参数的行为完全一致。
利用后果:攻击者可利用此漏洞将权限提升至最高级别的 NT AUTHORITY\SYSTEM 。
检测与定性:正因为这个已知的漏洞,会将其标记为威胁并进行隔离。

WinRing0x64.sys是漏洞驱动(BYOVD)攻击中的一个典型例子。攻击者在获得初始访问权限(如管理员权限)后,会将这个有合法签名但存在漏洞的驱动程序安装到受害者系统中,以此作为获取内核级权限的跳板。
具体的攻击实例是:在利用JetBrains TeamCity的漏洞(CVE-2024-27198)后,攻击者会植入XMRig加密货币挖矿程序,该挖矿程序会附带并利用WinRing0x64.sys来访问CPU的MSR以执行挖矿操作。在国内被勒索木马利用,金山和奇安信有介绍。
雷蛇已更新其Synapse软件,新版本不再包含此驱动程序。



导入表分析 :
IoCreateDevice, IoCreateSymbolicLink: 驱动会创建一个设备,并创建一个符号链接,使得用户空间的程序可以通过这个名称打开设备句柄,并与其通信。这是与驱动交互的入口,也是漏洞利用的起点。
MmMapIoSpace, MmUnmapIoSpace: (高危) 这组函数允许将任意物理内存地址映射到内核空间。如果用户能够控制传递给 MmMapIoSpace 的物理地址和长度参数,就能实现任意物理内存读写。这是一个可以完全接管系统的顶级漏洞。
HalGetBusDataByOffset, HalSetBusDataByOffset: (高危) 这组函数用于读写总线数据,例如PCI(e)设备的配置空间。如果用户能够控制总线类型、偏移和写入的数据,就可以修改硬件配置,可能导致系统不稳定(蓝屏),甚至在某些情况下,通过操纵DMA控制器实现任意内存访问。
KeBugCheckEx: (中危) 此函数用于主动触发蓝屏(BSOD)。如果驱动的输入验证不充分,攻击者可能通过发送一个畸形的IOCTL请求来触发这个函数,导致一个简单的拒绝服务(DoS)漏洞。
IofCompleteRequest: 用于完成来自用户空间的I/O请求(IRP)。


  1. NTSTATUS __stdcall DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
  2. {

  3.   RtlInitUnicodeString(&DeviceName, L"\\Device\\rwdrv");
  4.   Status = IoCreateDevice(DriverObject, 0, &DeviceName, 0x22u, 0, 0, &DeviceObject);

  5.   RtlInitUnicodeString(&SymbolicLinkName, L"\\DosDevices\\rwdrv");
  6.   Status = IoCreateSymbolicLink(&SymbolicLinkName, &DeviceName);

  7.   DriverObject->MajorFunction[IRP_MJ_CREATE] = (PDRIVER_DISPATCH)DispatchCreateClose;
  8.   DriverObject->MajorFunction[IRP_MJ_CLOSE] = (PDRIVER_DISPATCH)DispatchCreateClose;
  9.   DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = (PDRIVER_DISPATCH)DispatchDeviceControl;
  10.   DriverObject->DriverUnload = (PDRIVER_UNLOAD)DriverUnload;

  11.   return Status;
  12. }
复制代码
DispatchDeviceControl 函数是所有潜在漏洞的入口。深入分析这个函数,查明它如何处理不同的IOCTL控制码,以及它是否将用户输入不安全地传递给了API (MmMapIoSpace, HalSetBusDataByOffset, KeBugCheckEx)。
设备名称: 驱动创建了一个名为 \\Device\\rwdrv 的设备对象。
符号链接: 驱动创建了一个名为 \\DosDevices\\rwdrv 的符号链接。
IOCTL处理函数: 所有发送到该设备的IOCTL请求(IRP_MJ_DEVICE_CONTROL)都由一个名为 DispatchDeviceControl 的函数处理。

  1. NTSTATUS __stdcall DispatchDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
  2. {
  3.   PIO_STACK_LOCATION IrpStack;
  4.   ULONG IoControlCode;
  5.   PVOID InputBuffer;
  6.   ULONG InputBufferLength;
  7.   PVOID OutputBuffer;
  8.   ULONG OutputBufferLength;
  9.   NTSTATUS Status;

  10.   IrpStack = IoGetCurrentIrpStackLocation(Irp);
  11.   IoControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode;
  12.   InputBuffer = Irp->AssociatedIrp.SystemBuffer;
  13.   InputBufferLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
  14.   OutputBuffer = Irp->AssociatedIrp.SystemBuffer;
  15.   OutputBufferLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;

  16.   Status = STATUS_SUCCESS;

  17.   switch ( IoControlCode )
  18.   {
  19.     case 0x80002008:
  20.       if ( InputBufferLength >= 8 )
  21.       {
  22.         PHYSICAL_ADDRESS PhysicalAddressToMap = *(PHYSICAL_ADDRESS*)InputBuffer;
  23.         ULONG MappingSize = *(ULONG*)((char*)InputBuffer + 4);
  24.         

  25.         PVOID MappedAddress = MmMapIoSpace(PhysicalAddressToMap, MappingSize, MmNonCached);
  26.         
  27.         if (MappedAddress)
  28.           *(PVOID*)OutputBuffer = MappedAddress;
  29.         else
  30.           Status = STATUS_INSUFFICIENT_RESOURCES;
  31.       }
  32.       else
  33.       {
  34.         Status = STATUS_INVALID_PARAMETER;
  35.       }
  36.       break;

  37.     case 0x80002010: // 对应 KeBugCheckEx (蓝屏)
  38.       // 漏洞: 无条件触发蓝屏
  39.       KeBugCheckEx(0xDEADBEEF, 1, 2, 3, 4);
  40.       break;

  41. ....
复制代码

任意物理内存映射 (权限提升)

IOCTL控制码: 0x80002008
当用户程序使用此IOCTL时,驱动程序会从输入缓冲区中直接读取一个64位的物理地址和一个32位的映射大小。驱动完全没有对这两个值进行任何验证,就将它们传递给了 MmMapIoSpace 函数。
攻击者可以构造一个请求,将任何物理内存区域(例如,包含进程令牌、内核代码或其他敏感数据结构)映射到内核空间。驱动随后会将映射后的内核虚拟地址返回给攻击者。这是一个严重的权限提升漏洞。

拒绝服务 (DoS)
IOCTL控制码: 0x80002010
当用户程序使用此IOCTL时,驱动程序会无条件地调用 KeBugCheckEx 函数。
任何能够打开 \\.\rwdrv 设备句柄的程序(就是低权限用户)都可以发送这个IOCTL请求,立即导致目标系统蓝屏死机(BSOD)。这是一个非常直接且稳定的拒绝服务漏洞。


漏洞利用:
权限提升: 攻击者发送 IOCTL 0x80002008,并提供一个精心挑选的物理地址。驱动程序将此物理内存映射后,攻击者便获得了读写该区域的能力,从而可以修改关键数据结构(如进程令牌)以将自身权限提升至SYSTEM。
拒绝服务: 攻击者发送 IOCTL 0x80002010,直接导致系统蓝屏崩溃。

驱动的漏洞源于对用户输入完全缺乏验证。盲目地相信从用户空间传递来的地址和大小参数,并直接在内核模式下使用。



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?快速注册

x

评分

参与人数 1人气 +2 收起 理由
Rukia + 2 感谢解答: )

查看全部评分

wowocock
发表于 前天 10:57 | 显示全部楼层
_int64 __fastcall sub_11504(__int64 a1, int a2, void *a3, unsigned int a4, unsigned int *a5)
{
  __int64 v8; // rax
  __int64 v9; // rcx
  SIZE_T v10; // rbp
  PVOID v11; // rax
  char v12; // r12
  __int64 v13; // rcx
  _DWORD *v14; // rdi
  _DWORD *v15; // rsi
  __int64 v16; // rcx
  _WORD *v17; // rdi
  _WORD *v18; // rsi

  if ( a2 != 16 )
    return 0xC000000Di64;
  v8 = (unsigned int)(*(_DWORD *)(a1 + 8) * *(_DWORD *)(a1 + 12));
  if ( a4 < (unsigned int)v8 )
    return 0xC000000Di64;
  v9 = *(_QWORD *)a1;
  if ( v9 < 786432 )
    return 0xC000000Di64;
  v10 = (unsigned int)v8;
  if ( v9 + v8 - 1 > 0xFFFFF )
    return 0xC000000Di64;
  v11 = MmMapIoSpace((PHYSICAL_ADDRESS)v9, (unsigned int)v8, MmNonCached);
  v12 = 0;
  switch ( *(_DWORD *)(a1 + 8) )
  {
    case 1:
      qmemcpy(a3, v11, *(unsigned int *)(a1 + 12));
      break;
    case 2:
      v16 = *(unsigned int *)(a1 + 12);
      v17 = a3;
      v18 = v11;
      while ( v16 )
      {
        *v17++ = *v18++;
        --v16;
      }
      break;
    case 4:
      v13 = *(unsigned int *)(a1 + 12);
      v14 = a3;
      v15 = v11;
      while ( v13 )
      {
        *v14++ = *v15++;
        --v13;
      }
      break;
    default:
      v12 = 1;
      break;
  }
  MmUnmapIoSpace(v11, v10);
  if ( v12 )
    return 0xC000000Di64;
  *a5 = a4;
  return 0i64;
}
这个驱动里只有任意内存读,没有任意内存写,所以相对来说危险性好点,不过依然是漏洞。
您需要登录后才可以回帖 登录 | 快速注册

本版积分规则

手机版|杀毒软件|软件论坛| 卡饭论坛

Copyright © KaFan  KaFan.cn All Rights Reserved.

Powered by Discuz! X3.4( 沪ICP备2020031077号-2 ) GMT+8, 2025-9-3 09:20 , Processed in 0.120046 second(s), 15 queries .

卡饭网所发布的一切软件、样本、工具、文章等仅限用于学习和研究,不得将上述内容用于商业或者其他非法用途,否则产生的一切后果自负,本站信息来自网络,版权争议问题与本站无关,您必须在下载后的24小时之内从您的电脑中彻底删除上述信息,如有问题请通过邮件与我们联系。

快速回复 客服 返回顶部 返回列表