微软字体解析服务远程代码执行漏洞分析

3月23日,微软公司发布了一份编号ADV200006的紧急漏洞通告,通告表示有在野攻击行动使用了位于Adobe Type Manager Library中的两个远程代码执行0Day漏洞,由于漏洞严重,发布该通告指导用户在补丁发布前规避风险。

4月15日的补丁日中,微软发布了针对此风险通告的补丁外,还对一个字体库漏洞CVE-2020-0687进行修复,诺亚实验室第一时间对补丁进行了比对分析,并确认了漏洞的利用性,两个漏洞均属于高危远程代码执行漏洞,由于CVE-2020-0938/CVE2020-1020已有安全团队验证并形成POC,本文将会着笔于vincss报告的CVE-2020-0687进行简要技术分析。

根本原因

漏洞产生于字体处理库fontsub.dll的ReadTableIntoStructure中,由于循环逻辑中读取数据赋值检查不严格,在数据拷贝到目的堆后超过原申请的堆内存大小,形成堆溢出漏洞。

补丁细节分析

通过补丁比对,我们很快确认了问题函数

__int64 __fastcall ReadTableIntoStructure(__int16 *a1, _WORD *a2, unsigned __int16 *a3)

通过前后差异判别,可以看出补丁代码将while循环的一个返回条件放到了循环入口处,其目的是为了防止当变量v5中的变量大于v3[4]中保存的的变量时,会执行一次while循环的第一句赋值代码。

故原始漏洞代码中存在判断不严谨的情况,将会导致ReadGeneric中读取到的4字节数据,放入至一个结构体数组中:

通过跟踪v3和v5返回上层调用函数可知,v3在上层函数MergeEblcEbdtTables中,是作为一个从新申请的堆内存的大小参数进行传递的;而v5则是作为ReadTableIntoStructure中第三个参数,可以理解为一个类似Table大小的变量。

而此处的堆空间大小则是由v92来决定,根据跟踪的情况,v92将由漏洞触发函数中的v3[4]确定:

由于漏洞触发点的while循环语句中首句代码作用是向这个堆数组添加从ReadGeneric读取的数据,若我们控制v5变量大于v3[4]时,将会导致拷贝到目的堆中数据超过申请堆内存的最大值+16,ReadGeneric中所读取的数据将会覆盖到已申请堆空间后置位+16个字节中的4个字节数据,从而形成明显的堆溢出。

构造思路

我们通过跟踪漏洞触发函数可以发现,该触发所属模块用于处理MergeFonts字体,通过对应的table类型(EblcEbdt Tables)也可以轻松找到漏洞触发函数路径。

通过查阅MergeFonts结构信息,可精心构造相应字体控制上述覆盖,形成常规堆溢出利用。

修复

如上图示,微软的修复方案是通过判断v5和v3[4]的比值大小,避免ReadGeneric读取值覆盖。

漏洞影响

该漏洞影响面极大,以下为漏洞影响的操作系统版本:

Windows 10 for 32-bit Systems
Windows 10 for x64-based Systems Windows 10 Version 1607 for 32-bit Systems
Windows 10 Version 1607 for x64-based Systems
Windows 10 Version 1709 for 32-bit Systems
Windows 10 Version 1709 for ARM64-based Systems
Windows 10 Version 1709 for x64-based Systems
Windows 10 Version 1803 for 32-bit Systems
Windows 10 Version 1803 for ARM64-based Systems
Windows 10 Version 1803 for x64-based Systems
Windows 10 Version 1809 for 32-bit Systems
Windows 10 Version 1809 for ARM64-based Systems
Windows 10 Version 1809 for x64-based Systems
Windows 10 Version 1903 for 32-bit Systems
Windows 10 Version 1903 for ARM64-based Systems
Windows 10 Version 1903 for x64-based Systems
Windows 10 Version 1909 for 32-bit Systems
Windows 10 Version 1909 for ARM64-based Systems
Windows 10 Version 1909 for x64-based Systems
Windows 7 for 32-bit Systems Service Pack 1
Windows 7 for x64-based Systems Service Pack 1
Windows 8.1 for 32-bit systems
Windows 8.1 for x64-based systems
Windows RT 8.1
Windows Server 2008 for 32-bit Systems Service Pack 2
Windows Server 2008 for 32-bit Systems Service Pack 2 (Server Core installation)
Windows Server 2008 for Itanium-Based Systems Service Pack 2
Windows Server 2008 for x64-based Systems Service Pack 2
Windows Server 2008 for x64-based Systems Service Pack 2 (Server Core installation)
Windows Server 2008 R2 for Itanium-Based Systems Service Pack 1
Windows Server 2008 R2 for x64-based Systems Service Pack 1
Windows Server 2008 R2 for x64-based Systems Service Pack 1 (Server Core installation)
Windows Server 2012
Windows Server 2012 (Server Core installation)
Windows Server 2012 R2
Windows Server 2012 R2 (Server Core installation)
Windows Server 2016
Windows Server 2016 (Server Core installation)
Windows Server 2019
Windows Server 2019 (Server Core installation)
Windows Server, version 1803 (Server Core Installation)
Windows Server, version 1903 (Server Core installation)
Windows Server, version 1909 (Server Core installation)

修复建议

由于该漏洞还涉及到已经停止服务的win7系统,我们建议Windows用户及早进行修复,相关建议如下:

通过微软补丁页面寻找对应操作系统的补丁,进行手工修复
https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2020-0687
https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2020-0938
https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2020-1020

或通过360安全卫士实现对应操作系统补丁自动修复。

http://www.360.cn/brain_of_security/