找回密码
 立即注册
注册 登录
×
热搜: 活动 交友 discuz
查看: 110|回复: 1

CVE-2013-3660提权漏洞学习笔记

[复制链接]

1

主题

1

帖子

3

积分

新手上路

Rank: 1

积分
3
发表于 2022-9-20 07:57:22 | 显示全部楼层 |阅读模式
本文为看雪论坛优秀文章
看雪论坛作者ID:1900

一、前言


1.漏洞描述

在对win32k.sys进行压力测试时候发现的漏洞,该漏洞的是因为Windows系统在对Path子系统进行相关操作的时候,对申请用以操作的内存存在不进行初始化造成的。通过频繁地申请与释放内存,导致系统在执行win32k的bFlatten函数时,使用了未初始化的内存,而用户可以有一定的概率成功控制这块内存,导致可以让函数之后的读写操作指向非法内存引发BSOD,或指向目标函数来实现提权。

2.实验环境


  • 操作系统:Win7 x86 sp1 专业版
  • 编译器:Visual Studio 2017
  • 调试器:IDA Pro,WinDbg


二、Path子系统


1.关键结构体

Windows的Path子系统是一个关于绘制图形曲线的系统,在EPATHOBJ结构体中的pPath成员指向了用于该子系统的PATH结构体指针:
typedef struct _PATHOBJ {
  FLONG  fl;
  ULONG  cCurves;
} PATHOBJ, *PPATHOBJ;

typedef struct _EPATHOBJ
{
  PATHOBJ  po;
  PPATH   pPath;
} EPATHOBJ, *PEPATHOBJ;
PATH结构体的定义如下,主要包括了指向PATHALLOC和PATHRECORD结构体的指针:
typedef struct _PATH
{
   int iUnKnown[4];     // 0x10大小的未知成员
   PATHALLOC *ppachain;     // 指向PATHALLOC结构体
   PATHRECORD *pprfirst;    // 指向第一个PATHRECORD
   PATHRECORD *pprlast;     // 指向最后一个PATHRECORD
}PATH, *PPATH;
PATHALLOC是分配PATHRECORD的容器,该结构体定义如下:
typedef struct _PATHALLOC
{
    struct _PATHALLOC *ppanext;       // 指向下一个PATHALLOC结构体
    struct _PATHRECORD *pprfreestart;   // 指向新分配的PATHRECORD结构体
    ULONG siztPathAlloc;                // 当前PATHALLOC结构体大小
    PATHRECORD pathRecord[0];           // PATHRECORD数组
}PATHALLOC, *PPATHALLOC;
PATHRECORD是Path子系统的主要结构体,对其进行直线化操作就是对PATHRECORD结构体进行操作,该结构体定义如下:
typedef struct _PATHRECORD
{
    struct _PATHRECORD *pprnext;  // 指向下一个PATHRECORD
    struct _PATHRECORD *pprprev;        // 指向上一个PATHRECORD
    DWORD flags;               // 类型
    DWORD numPoints;               // points数组元素个数
    POINT points[0];               // POINT数组,记录坐标点
}PATHRECORD, *PPATHRECORD
其中,flags成员指明了该结构体的类型,如,PD_BEZIERS就指明其未贝塞尔自由绘制曲线:
#define PD_BEZIERS        0x00000010
PATH,PATHALLOC,PATHRECORD结构体的关系如下图所示:



2.PATHALLOC的分配与释放

系统分配PATHRECORD结构体是通过PATHALLOC结构体实现的,freepathalloc和newpathalloc分别是用来释放和分配PATHALLOC结构体的函数。

freepathalloc函数实现如下,由该实现可以看出,在PATHALLOC中有一个freelist链表,该链表可以用来保存释放的PATHALLOC结构体,其中,cFree成员用来指定保存在freelist链表中的PATHALLOC结构体的数量。当freelist链表中保存的PATHALLOC结构体数量少于4时,释放的PATHALLOC结构体会被加入到链表中,否则直接调用ExFreePoolWithTag释放内存。



newpathalloc函数的实现如下,该函数首先判断freelist中是否存在可用的PATHALLOC结构体,如果有,则直接从freelist链表中分配,否则就会在第二处调用PALLOCMEM函数来分配内存,函数最终会将分配的内存地址赋给res,作为返回值。



在该函数中,在分配完内存以后只在LABEL_7初始化了PATHALLOC结构体前面三个成员,而之后的PATHRECORD结构体数组没有进行初始化。因此,如果是从第一处的freelist链表中分配PATHALLOC结构体,该结构体中的PATHRECORD结构体数组就会是之前释放PATHALLOC结构体时保存的数据。如果是第二处的PATLLOCMEM函数分配内存则不存在该问题,因为该函数会将内存初始化为0。



其中Win32AllocPool函数直接调用ExAllocatePoolWithTag来申请PagedPoolSession类型的内存:



三、漏洞分析


触发漏洞的函数为bFlatten,该函数实现如下,函数从PATH->pprfirst开始遍历查找所有的PATHRECORD结构体,对PD_BEZIERS类型的PATHRECORD结构体调用pprFlaaenRec函数。



pprFlattenRec函数首先会调用newpathrec函数申请一块PATHRECORD结构体,该结构体保存在第二个参数first_pathRecord中,对于新分配的PATHRECORD结构体,函数将其pprprev赋值为调用pprFlattenRec时,传入的PATHRECORD结构体参数的pprprev,然后将参数的pprprev指向的PATHRECORD结构体的pprnext赋值为新申请PATHRECORD结构体。



之后函数可能会多次调用newpathrec分配新的PATHRECORD结构体,然后将上面分配的PATHRECORD结构体的pprnext指向新分配的PATHRECORD结构体,同时会移动pprNew指针。



在pprFlattenRec函数的最后,函数会将pprNew的pprnext赋值为调用pprFlattenRec函数时传入的PATHRECORD参数的pprnext。



申请PATHRECORD结构体的newpathrec函数实现如下,函数首先从PATH->ppachain->pprfreestart指向的地址开始查找是否有足够的空间分配一个PATHRECORD结构体,如有则以pprfreestart指向的地址分配新PATHRECORD。否则,函数会调用newpathalloc函数先分配一个新的PATHALLOC结构体连入ppachain指向的链表的比链表头,在从新的PATHALLOC里的pprfreestart所指地址分配PATHRECORD。



newpathalloc在上面分析过了,如果是从freelist链表中分配的PATHALLOC结构体,该结构体的PATHRECORD结构体数组就会是未初始化的。因此,newpathrec返回的PATHALLOC中的PATHRECORD结构体数组很有可能是未初始化的。

而pprFlattenRec函数在函数最后才会对第一次调用newpathrec申请的PATHRECORD结构体的pprnext成员进行赋值,可是在第二次调用newpathrec函数的时候,如果此次调用,内存空间不够,该函数就会执行失败,返回的就不会是1,这样pprFlattenRec函数也会提前返回,最后对第一次申请的PATHRECORD结构体的pprnext成员进行赋值的代码也不会得到执行,这块PATHRECORD结构体的pprnext成员就没有被赋值的机会,保存的就会是这块内存原来的数值。

而bFlatten函数会通过PATHRECORD->pprnext来查找下一个PATHRECORD结构体,将其作为参数调用pprFlattenRec,如果可以想办法让此时的pprnext指向指定的内存,此时就会以指定的内存调用pprFlattenRec。

完整阅读请点击:CVE-2013-3660提权漏洞学习笔记
回复

使用道具 举报

0

主题

5

帖子

6

积分

新手上路

Rank: 1

积分
6
发表于 半小时前 | 显示全部楼层
专业抢沙发的!哈哈
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋| 黑客通

GMT+8, 2025-10-12 04:17 , Processed in 0.117915 second(s), 23 queries .

Powered by Discuz! X3.4

Copyright © 2020, LianLian.

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