当前位置: 首页 > 科技观察

WindowsImageParsingFuzzing(1)-ColorProfile

时间:2023-03-12 03:27:26 科技观察

1.概述图像解析和渲染是任何现代操作系统(OS)的基本功能。同时,图像解析也是一个容易接近的攻击面。该特性可能导致远程代码执行或信息泄露风险,这对攻击者来说非常有价值。在本系列文章中,我将回顾Windows操作系统内置的图像解析器和相关文件格式,特别关注构建工具、查找语料库(Corpus)以及通过模糊测试(Fuzzing)发现漏洞的过程。在第一部分中,我们专注于分析颜色配置文件。这个文件不是图像格式本身,而是有规律地嵌入到图像中的颜色。2.ICCcolorprofile分析维基百科上给出了ICCcolorprofile的定义:“在色彩管理过程中,根据国际色彩委员会(ICC)发布的标准,ICCprofile是一组定义好的颜色输入并输出设备和颜色空间数据。配置文件通过定义设备源或目标颜色空间与配置文件连接空间(PCS)之间的映射来描述特定设备的颜色属性或预览要求。这里的PCS可以是CIELAB(L*a*b*),orCIEXYZ。可以使用定义Interpolation的表指定映射,也可以通过一系列参数转换。简而言之,ICC颜色配置文件是一个二进制文件,嵌入在图中分析了ICC支持的软件在处理图像时的情况3.ICC规范ICC规范ICC规范有100多页,比较容易浏览,通读规范可以更好的理解t文件格式、不同类型的颜色配置文件和颜色转换背后的数学原理。此外,了解文件格式的内部结构可以为我们更好地优化模糊测试提供信息,选择一个好的语料库,并为模糊测试准备字典。四、关于Windows色彩管理从Windows95开始,发布了ImageColorManagement(ICM)1.0版,从Windows98开始发布了2.0版。从WindowsVista开始,WindowsColorSystem(WCS)1.0版有了很大的改进。变了。ICC颜色配置文件是二进制文件,而WCS颜色配置文件使用XML作为其文件格式。在本文中,我们重点分析ICC颜色配置文件。微软公布了一份支持的WindowsAPI列表,其中包括一些名字很明显的API,比如OpenColorProfile,我们可以看到它是在MSCMS.dll中实现的。这个DLL是通用的入口点,支持加载微软的色彩管理模块(CMM)和第三方的色彩管理模块(比如Adobe的CMM)。Microsoft的CMM(又名ICM)可以在名为ICM32.dll的system32目录中找到。ICM32:Windows的CMM是在Windows95时代由第三方编写的,现在或多或少还保留着当时的代码,但经过几十年的安全修复。由于它是一个如此古老的模块,我们希望能在其中找到新的漏洞。然而,这也是一个非常小的模块,可能已经经过了包括内部产品安全团队和外部研究人员在内的多轮审计和模糊测试,这一事实在一定程度上打击了我们找到错误的希望。我们搜索最近发现的ICM32漏洞,发现ProjectZero和ZDI的研究人员在2017-2018年期间发现了多个漏洞,但自2019年以来就没有发现更多的研究成果。5.构建工具虽然MSDN上有ICMAPI列表,我们需要找到Windows用于所有ICC相关操作的API序列。找到API序列的一种方法是搜索WindowsDLL和EXE的反汇编并寻找使用的颜色配置文件API,另一种方法是寻找开源颜色管理系统(例如LittleCMS、LCMS)的工具。使用这两者,您最终会共同指向少数具有打开颜色配置文件和创建颜色转换功能的API。基于以上信息,我写了一个简单的初始工具:#include#include#include#pragmacomment(lib,"mscms.lib")intmain(intargc,char**argv){chardstProfilePath[]="sRGBColorSpaceProfile.icm";tagPROFILEdestinationProfile;HPROFILEhDstProfile=nullptr;destinationProfile.dwType=PROFILE_FILENAME;destinationProfile.pProfileData=dstProfilePath;destinationProfile.cbDataSize=(strlen(dstProfilePath)+1);hDstProfileA(OpenColorProfileA)&destinationProfile,PROFILE_READ,FILE_SHARE_READ,OPEN_EXISTING);if(nullptr==hDstProfile){return-1;}tagPROFILEsourceProfile;HPROFILEhSrcProfile=nullptr;HTRANSFORMhColorTransform=nullptr;DWORDdwIntent[]={INTENT_PERCEPTUAL,INTENT_PERCEPTUAL};HPROFILEd]hsourceProfileList[2]类型。=PROFILE_FILENAME;sourceProfile.pProfileData=argv[1];sourceProfile.cbDataSize=(strlen(argv[1])+1);hSrcProfile=OpenColorProfileA(&sourceProfile,PROFILE_READ,FILE_SHARE_READ,OPEN_EXISTING);if(nullptr==hSrcProfile){return-1;}hProfileList[0]=hSrcProfile;hProfileList[1]=hDstProfile;hColorTransform=CreateMultiProfileTransform(hProfileList,2,dwIntent,2,USE_RELATIVE_COLORIMETRIC|BEST_MODE,INDEX_DONT_CARE);if(nullptr==hColorTransform){return-1;}DeleteColorTransform(hColorTransform);关闭颜色配置文件(hSrcProfile);关闭颜色配置文件(hDstProfile);有许多包含颜色配置文件的图像文件,但需要一些工具将颜色配置文件转储到单独的文件中。简单地浏览规范,我们也可以保证语料库至少包含来自7个不同颜色配置文件的所有样本。将它与代码覆盖信息相结合,可以为模糊测试准备第一个语料库。我们可以在梳理规范的过程中创建一个唯一标签名称和对应值的列表,从而准备一个字典来帮助模糊测试工具找到其他代码路径。或者,可以在LCMS等开源模糊测试期间找到字典。7.模糊测试我使用16核主机对第一组语料进行模糊测试,同时使用MSCMS.dll和ICM32.dll的代码覆盖率信息作为我的模糊测试工具的反馈。几天后,崩溃开始出现。八、CVE-2020-1117:InitNamedColorProfileData中的堆溢出在尝试越界读取时,icm32!SwapShortOffset中发生了以下崩溃:0:000>rrax=0000023690497000rbx=0000000000000000rcx=00000000000000ffrdx=000000000000ffffrsi=0000023690496f00rdi=0000023690496feerip=00007ffa46bf3790rsp=000000c2a56ff5a8rbp=0000000000000001r8=0000000000000014r9=0000023690497002r10=0000000000000014r11=0000000000000014r12=000000c2a56ff688r13=0000023690492de0r14=000000000000000ar15=000000004c616220iopl=0nvupeingnzacpecycs=0033ss=002bds=002bes=002bfs=0053gs=002befl=00000293icm32!SwapShortOffset+0x10:00007ffa`46bf37900fb610movzxedx,byteptr[rax]ds:00000236`90497000=??0:000>!heap-p-a@raxaddress0000023690497000foundin_DPH_HEAP_ROOT@23690411000inbusyallocation(DPH_HEAP_BLOCK:UserAddrUserSize-VirtAddrVirtSize)23690412b60:23690496f00100-23690496000200000007ffa51644807ntdll!RtlDebugAllocateHeap+0x000000000000003f00007ffa515f49d6ntdll!RtlpAllocateHeap+0x0000000000077ae600007ffa5157babbntdll!RtlpAllocateHeapInternal+0x00000000000001cb00007ffa51479da0msvcrt!malloc+0x000000000000007000007ffa46bf3805icm32!SmartNewPtr+0x000000000000001100007ffa46bf37c8icm32!SmartNewPtrClear+0x000000000000001400007ffa46c02d05icm32!InitNamedColorProfileData+0x000000000000008500007ffa46bf6e39icm32!Create_LH_ProfileSet+0x0000000000004e1500007ffa46bf1973icm32!PrepareCombiLUTs+0x000000000000011700007ffa46bf1814icm32!CMMConcatInitPrivate+0x00000000000001f400007ffa46bf12a1icm32!CWConcatColorWorld4MS+0x000000000000007500007ffa46bf11f4icm32!CMCreateMultiProfileTransformInternal+0x00000000000000e800007ffa46bf1039icm32!CMCreateMultiProfileTransform+0x000000000000002900007ffa48f16e6cmscms!CreateMultiProfileTransform+0x000000000000024c00007ff774651191ldr+0x000000000000119100007ff7746514b4ldr+0x00000000000014b400007ffa505a7bd4KERNEL32!BaseThreadInitThunk+0x0000000000000001400007ffa515aced1ntdll!RtlUserThreadStart+0x0000000000000021icm32!SwapShortOffset读取无符号短值,bswap它们,并将它们存储在相同位置,这会导致读写原语崩溃反编译SwapShortOffset:unsigned__int16*__fastcallSwapShortOffset(void*sourceBuff,unsignedintoffset,unsignedintlen){unsigned__int16*endBuff;//r9unsigned__int16*result;//raxendBuff=(sourceBuff+len);for(result=(sourceBuff+offset);result*pBuffSize?SwapLongOffset((allocBuff+16),v12,v13);在CMConvIndexToNameProfile等两个函数中,我们发现了一个漏洞,并没有检查ncl2元素的最小长度,而offsetQuantities12和16是可以直接读写的。那么如果allocBuffer的大小小于12,就可以越界读写allocBuffer。由于Windows中没有使用这些功能的二进制文件,微软决定不立即修复这三个漏洞。此外,我们没有发现任何使用这些API的Windows软件或第三方软件。10.总结在本系列文章的第一部分,我们对颜色配置文件进行了深入分析,编写了工具并成功发现了多个漏洞。请继续关注第二部分。在第二部分,我们将分析一类鲜为人知的漏洞——未初始化内存漏洞。本文翻译自:https://www.fireeye.com/blog/threat-research/2020/09/fuzzing-image-parsing-in-windows-color-profiles.html如有转载请注明出处。