Skip to content

游侠安全网

关注网络与数据安全

Primary Menu
  • 业界
  • 安全
  • 网络
  • 办公
  • 厂商
  • 培训
  • 应用
  • 影音
  • 数码
  • 文摘
  • 猎头
  • 程序
  • 站长
  • 系统
  • 随笔
  • 业界
  • 安全

Microsoft Windows内核提权漏洞原理分析与利用(CVE-2016-3308 / ZDI-16-453)

CloverSec Labs成员bear13oy在七月中旬也发现该内核漏洞,由于当时比较忙,本想在八月微软的补丁周过后再对其进行分析和利用,不巧的是微软八月份的补丁修复了该漏洞。再次撞洞!
四叶草安全实验室 2016年9月12日 3 minutes read

1、漏洞简介

漏洞公告相关链接: ZDI-16-453  CVE-2016-3308

CloverSec Labs成员bear13oy在七月中旬也发现该内核漏洞,由于当时比较忙,本想在八月微软的补丁周过后再对其进行分析和利用,不巧的是微软八月份的补丁修复了该漏洞。再次撞洞!

附上当时精简后的poc代码截图:

findwindow-11

 

bsod_poc-2

内核崩溃后栈回溯信息截图:

stack-3

2、漏洞原理

由于函数win32k!xxxInsertMenuItem在处理新增菜单插入时,获得了错误的插入偏移,导致函数在计算MenuItem内核数据长度时发生错误,进而在调用memmove移动MenuItem数据时,发生越界操作。

win32k!xxxInsertMenuItem函数在调用memmove移动MenuItem内核数据前,两次调用函数win32k!MNLookUpItem来获取相关Item数据的内存地址。在此漏洞中,第一次调用win32k!MNLookUpItem时,由于传入的wIndex不存在,函数会返回NULL,于是win32k!xxxInsertMenuItem会默认把新Item数据放到原Item数组的末尾,并把wIndex更新为新Item数据在原Item数组中的偏移。相关代码如下所示:

...
        if (w == MFMWFP_NOITEM)
            w = pMenu->cItems;
        w--;
        pItemWalk = pMenu->rgItems + w;
    #ifdef MEMPHIS_MENUS
        while (w && (pItemWalk->hbmp) && (pItemWalk->hbmp < (HBITMAP)MENUHBM_MAX))
    #else // MEMPHIS_MENUS
        while (w && (pItemWalk->fType & MFT_BITMAP) && (pItemWalk->hTypeData < (HANDLE)MENUHBM_MAX))
    #endif // MEMPHIS_MENUS
        {
            wIndex = w--;
            pItemWalk--;
        }
...

在调用AppendMenuA函数后,Menu中的Item数据刚好达到了8个,而由下面的代码可以看出,内核中Item数据的分配刚好是以8个Item为分配粒度的。于是如下代码中的pMenu->cItems >= pMenu->cAlloced的条件正好成立,于是win32k!MNLookUpItem会被再次调用,在新分配的Item数据中通过wIndex偏移找到需要插入的内存地址并保存在pItem中。

	#define CMENUITEMALLOC 8
   ...
   ...
   if (pMenu->cItems >= pMenu->cAlloced) {
        if (pMenu->rgItems) {
            pNewItems = (PITEM)DesktopAlloc(pMenu->head.rpdesk->hheapDesktop,
			(pMenu->cAlloced + CMENUITEMALLOC) * sizeof(ITEM));
		...
        } else {
            pNewItems = (PITEM)DesktopAlloc(pMenu->head.rpdesk->hheapDesktop,
                    sizeof(ITEM) * CMENUITEMALLOC);
        }
        ...
        pMenu->cAlloced += CMENUITEMALLOC;
        pMenu->rgItems = pNewItems;
        ...
        /*
         * Now look up the item again since it probably moved when we realloced the
         * memory.
         */
        if (wIndex != MFMWFP_NOITEM)
            pItem = MNLookUpItem(pMenu, wIndex, fByPosition, &pMenuItemIsOn);
    }
    

然而win32k!MNLookUpItem函数会在所有的Item以及子菜单的Item中递归寻找,由于之前已经有7个Item数据存在,在调用InsertMenuA函数后wIndex被改写为7,而此时由于notepad的第一个File的子菜单中的最后一个Item(Exit)的id正好是7,于是win32k!MNLookUpItem函数遍会把此Item的内核地址返回。之后在计算memmove移动长度时便会出现不可预料的情况,并在移动数据时发生访问异常。

notepad-44

...
memmove(pItem + 1, pItem, (pMenu->cItems - 1) *
		sizeof(ITEM) - ((char *)pItem - (char *)pMenu->rgItems));
...
typedef struct tagITEM
{
	UINT fType;
	UINT fState;
	UINT wID;
	struct tagMENU* spSubMenu; /* Pop-up menu. */
	HANDLE hbmpChecked;
	HANDLE hbmpUnchecked;
	USHORT* lpstr; /* Item text pointer. */
	ULONG cch;
	DWORD_PTR dwItemData;
	ULONG xItem;   /* Item position. left */
	ULONG yItem;   /*     "          top */
	ULONG cxItem;  /* Item Size Width */
	ULONG cyItem;  /*     "     Height */
	ULONG dxTab;   /* X position of text after Tab */
	ULONG ulX;     /* underline.. start position */
	ULONG ulWidth; /* underline.. width */
	HBITMAP hbmp;  /* bitmap */
	INT cxBmp;     /* Width Maximum size of the bitmap items in MIIM_BITMAP state */
	INT cyBmp;     /* Height " */
} ITEM, *PITEM;

从上面代码可以看出,win32k!xxxInsertMenuItem中触发漏洞的memmove所用到的pItem地址正好是之前win32k!MNLookUpItem函数返回的内存地址。结合内存数据和PITEM数据结构可以看出,此时的pItem地址所指向的是notepad中File的子菜单中的最后一个Item(Exit)(数据结构如上图红色所示),而pMenu->rgItems为DesktopAlloc新分配的内存地址指针,这两个地址分别属于不同的Item数组中,所以相减的值是不可预料的,精确操作内核堆分配可控制memmove长度,从而控制特定的内存区域。

esp-5

3、漏洞利用

漏洞利用主要用到两个数据结构如下:

typedef struct tagPROPLIST {
		UINT cEntries;
		UINT iFirstFree;
		tagPROP aprop[1];
} PROPLIST, *PPROPLIST;
typedef struct tagMENU
{
	...
	UINT cItems;              /* Number of items in the menu \*/
	...
	PITEM rgItems;            /* Array of menu items \*/
	...
} MENU, *PMENU;

通过构造数据覆盖tagPROPLIST中的cEntries和iFirstFree便可以实现对tagPROPLIST结构之后的一段数据进行控制。

漏洞触发过程中tagPROPLIST在内存中的变化:

漏洞触发前
fce2f240  00000002 00000002 fb10afe0 0001c033   tagPROPLIST
fce2f250  00000000 0002c04a 00010002 08000004
fce2f260  00410041 00000041 00010002 08000002
fce2f270  00410041 00000041 00010002 08000002
fce2f280  00410041 00000041 00010002 08000002
fce2f290  00410041 00000041 00010002 08000002
fce2f2a0  00410041 00000041 00010002 08000002
fce2f2b0  00410041 00000041 00010002 08000002

漏洞触发后
fce2f240  08000002 88888888 88888888 88888888   tagPROPLIST
fce2f250  88888888 88888888 88888888 88888888
fce2f260  88888888 88888888 88888888 88888888
fce2f270  88888888 88888888 88888888 88888888
fce2f280  88888888 88888888 88888888 88888888
fce2f290  88888888 88888888 88888888 88888888
fce2f2a0  00008888 00010004 0800000d 00000002
fce2f2b0  00000002 fb10afe0 0001c033 00000000

漏洞利用过程大概可以分为如下步骤:

a. 构造数据覆盖tagPROPLIST中的cEntries和iFirstFree;

b. 通过SetProp函数对tagPROPLIST对分布在其后的tagMENU结构中的cItems和rgItems字段进行控制;

c. 通过SetMenuItemInfo实现对任意地址的写操作;

d. 改写内核HalDispatchTable+4的数据实现EIP控制。

4、漏洞演示

测试环境: Windows 7 SP1 x86 (更新于2016-07-16)

record-4

四叶草安全实验室官网链接:http://lab.seclover.com/

相关内容:

  • 硬刚勒索病毒:微软免费杀软Defender获AV-TEST测试满分
  • Microsoft Defender网络安全应用在Windows、macOS、iOS和Android上推出
  • 4400万个微软帐户使用泄露的密码
  • 四叶草安全获6700万元A轮融资 公司战略全面升级
  • 自动更新 Office for Mac
  • 微软Outlook被曝高危漏洞,可绕过保护视图远程执行任意代码
Tags: CVE-2016-3308 ZDI-16-453 二进制 内核提权漏洞

Post navigation

Previous: 有漏洞:20万部僵尸手机就能攻陷美国911报警系统
Next: 钉钉第三方加密惊艳亮相 澡堂模式升级为澡堂密聊

相关资讯

20260610151411914452
  • 安全
  • 随笔

WinLog Insight —— 让Windows日志分析,一键到位!

网路游侠 2026年6月10日
20260610043908045002
  • 业界

法国政府加密通讯平台 Tchap 遭黑客入侵,官方宣称加密聊天记录未泄露

网路游侠 2026年6月10日
20260530155614841775
  • 安全
  • 随笔

写了一款记录U盘插拔、文件操作,并给操作人拍照的软件

网路游侠 2026年5月30日

最近更新

  • WinLog Insight —— 让Windows日志分析,一键到位!
  • 法国政府加密通讯平台 Tchap 遭黑客入侵,官方宣称加密聊天记录未泄露
  • 告别繁琐代码!WordPress 网站添加统计代码的终极解决方案
  • 写了一款记录U盘插拔、文件操作,并给操作人拍照的软件
  • 快速入门FreeFileSync:免费开源,数据同步备份神器
  • 免费日志审计软件 GreenLogAudit 发布 v1.0.5
  • 网络安全检查清单(2026版)|等保合规自查必备Checklist
  • 什么是 nDPI?开源深度包检测引擎 nDPI 全面解析
  • Windows日志采集工具:从NXLog到Winlogbeat,国产免费客户端只有WinLogAgent
  • 强迫症狂喜:WinLogAgent 1.0.3 升级:目录只有1个exe啦!

可能错过

20260610151411914452
  • 安全
  • 随笔

WinLog Insight —— 让Windows日志分析,一键到位!

网路游侠 2026年6月10日
20260610043908045002
  • 业界

法国政府加密通讯平台 Tchap 遭黑客入侵,官方宣称加密聊天记录未泄露

网路游侠 2026年6月10日
20260609180436920351
  • 站长

告别繁琐代码!WordPress 网站添加统计代码的终极解决方案

网路游侠 2026年6月10日
20260530155614841775
  • 安全
  • 随笔

写了一款记录U盘插拔、文件操作,并给操作人拍照的软件

网路游侠 2026年5月30日
  • 业界
  • 安全
  • 网络
  • 办公
  • 厂商
  • 培训
  • 应用
  • 影音
  • 数码
  • 文摘
  • 猎头
  • 程序
  • 站长
  • 系统
  • 随笔
陕ICP备11003551号-2 Copyright YouXia.ORG(游侠安全网)© All rights reserved. | MoreNews by AF themes.