Talos Vulnerability Report

TALOS-2018-0644

Microsoft WindowsCodecs.dll SniffAndConvertToWideString information leak vulnerability

October 10, 2018
CVE Number

CVE-2018-8506

Summary

An exploitable memory leak vulnerability exists in the SniffAndConvertToWideString function of WindowsCodecs.dll 10.0.17134.1. A specially crafted JPEG file can cause the library to return uninitialized memory, resulting in an information leak. An a victim would have to interact with a malformed JPEG file to trigger this vulnerability.

Tested Versions

WindowsCodecs.dll 10.0.17134.1 (WinBuild.160101.0800)

Product URLs

https://www.microsoft.com

CVSSv3 Score

5.3 - CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N

CWE

CWE-125: Out-of-bounds Read

Details

This vulnerability is present in the WindowsCodecs DLL library, which is an implementation of the Windows Imaging Component (WIC) that provides an extensive framework for working with images and image metadata.

An attacker is able to leak heap memory due to improper string null termination after calling IWICImagingFactory::CreateDecoderFromFilename on a JPEG file with a malformed metadata field.

Here is a simple application that uses the WIC APIs that try to parse metadata from a malformed JPEG file:

//turn on full page heap for wic.exe
cmd> windbg.exe wic.exe malicious.jpeg

(48a4.42e8): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=089d5000 ebx=08a9ae18 ecx=0000d0d0 edx=089d4fea esi=00f3f3a8 edi=089d4fe8
eip=756b4192 esp=00f3f2a8 ebp=00f3f2f0 iopl=0         nv up ei ng nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010282
combase!PropVariantCopy+0xc2:
756b4192 668b08          mov     cx,word ptr [eax]        ds:002b:089d5000=????
0:000> kb
 # ChildEBP RetAddr  Args to Child              
00 00f3f2f0 6fa1577a 08a9ae18 00f3f3a8 08a9ae28 combase!PropVariantCopy+0xc2 [onecore\com\combase\util\propvar.cxx @ 628] 
01 00f3f31c 6f9774b5 00000000 08a9adf8 00000000 WindowsCodecs!CoerceStringVectors+0x59
02 00f3f33c 6f990b37 08a9adf8 00f3f3a8 08a9ae18 WindowsCodecs!CMetadataIFDReaderWriter::CoerceValueType+0x7ec6e
03 00f3f40c 6f93b2a4 08aa0f68 08a82b20 00000005 WindowsCodecs!CMetadataIFDReaderWriter::HrLoadEx+0x64b67
04 00f3f490 6f92d438 08a9aaec 08a9cff8 08a82b20 WindowsCodecs!CMetadataHandler::LoadEx+0x1a4
05 00f3f520 6f92c5ea 00f3f598 00000000 6f92bfd0 WindowsCodecs!CMetadataIFDReaderWriter::GetTagVariantValueForEmbeddedMetadata+0x26b
06 00f3f5ec 6f93b2a4 08a88f68 08a7cfb0 00000005 WindowsCodecs!CMetadataIFDReaderWriter::HrLoadEx+0x61a
07 00f3f670 6f92e636 08a82aec 08a84ff8 08a7cfb0 WindowsCodecs!CMetadataHandler::LoadEx+0x1a4
08 00f3f6ec 6f991f26 08a7cf78 00000000 00000000 WindowsCodecs!CMetadataApp1ReaderWriter::GetValue+0x346
09 00f3f764 6f93b2a4 08a7ef68 08180f80 00000005 WindowsCodecs!CMetadataApp1ReaderWriter::HrLoadEx+0x64256
0a 00f3f7e8 6f91bdfc 08a7cf7c 08194fb8 08180f80 WindowsCodecs!CMetadataHandler::LoadEx+0x1a4
0b 00f3f830 6f9231b8 080ddfe8 6f8d7cb0 08180f80 WindowsCodecs!CCodecFactory::CreateMetadataReaderFromContainer+0x17c
0c 00f3f8a0 6f935a2b 08180f94 00000000 00f3f8e8 WindowsCodecs!CJpegDecoderFrame::GetReaderByIndex+0x2f8
0d 00f3f8f4 6f9095b6 08177b90 080e7f90 00000001 WindowsCodecs!CDecoderBase::Initialize+0x23b
0e 00f3f9d4 6f91b48d 00000000 00000001 00f3fa00 WindowsCodecs!CCodecFactory::HrArbitrateDecoderList+0x2b4
0f 00f3fa48 6f91cbce 080e7f88 00000000 00000001 WindowsCodecs!CCodecFactory::HrCreateDecoderFromStreamInternalNew+0x365
10 00f3fa7c 6f91cc96 080e5fe8 080e7f90 00000000 WindowsCodecs!CCodecFactory::CreateDecoderFromStream+0x4e
11 00f3faa0 008f8798 080e5fe8 07f86fb8 00000000 WindowsCodecs!CCodecFactory::CreateDecoderFromFilename+0x76
12 00f3fc24 00903367 07eedfda 0d19cd57 00f3fe34 WIC!WIC::WIC+0xf8 [t:\projects\cpp\wic\wic\wic.cpp @ 42] 
13 00f3fd50 0090353d 07eedfda 008f11db 008f11db WIC!fuzzme+0x57 [t:\projects\cpp\wic\wic\wic.cpp @ 262] 
14 00f3fe34 00904e0e 00000002 07eedfa8 07dbdf38 WIC!main+0x7d [t:\projects\cpp\wic\wic\wic.cpp @ 300] 
15 00f3fe48 00904c90 0d19cea7 008f11db 008f11db WIC!invoke_main+0x1e [f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl @ 64] 
16 00f3fea0 00904b2d 00f3feb0 00904e28 00f3fec4 WIC!__scrt_common_main_seh+0x150 [f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl @ 259] 
17 00f3fea8 00904e28 00f3fec4 75fa8484 00dec000 WIC!__scrt_common_main+0xd [f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl @ 302] 
18 00f3feb0 75fa8484 00dec000 75fa8460 aea1b5f5 WIC!mainCRTStartup+0x8 [f:\dd\vctools\crt\vcstartup\src\startup\exe_main.cpp @ 17] 
19 00f3fec4 76f82fea 00dec000 807370b8 00000000 KERNEL32!BaseThreadInitThunk+0x24
1a 00f3ff0c 76f82fba ffffffff 76f9ec34 00000000 ntdll!__RtlUserThreadStart+0x2f
1b 00f3ff1c 00000000 008f11db 00dec000 00000000 ntdll!_RtlUserThreadStart+0x1b

As we can see, there is an out-of-bounds read during the Variant structure copy operation. Let's take a look at the PropVariantCopy function:

Line 1  HRESULT __stdcall PropVariantCopy(PROPVARIANT *pvarDest, const PROPVARIANT *pvarSrc)
Line 2  {
Line 3  (...)
Line 4  if ( Temp.vt == 31 )
Line 5  {
Line 6    begPtr = (__int16 *)v3;
Line 7    v77 = (void *)v3;
Line 8    if ( !v3 )
Line 9      goto LABEL_8;
Line 10   endPtr = v3 + 2;
Line 11   do
Line 12   {
Line 13     currPtr = *begPtr;
Line 14     ++begPtr;
Line 15   }
Line 16   while ( currPtr );
Line 17   strLen = 2 * (((signed int)begPtr - endPtr) >> 1) + 2;
Line 18   strLen_1 = 2 * (((signed int)begPtr - endPtr) >> 1) + 2;
Line 19   _Alloc = g_CMalloc.lpVtbl->Alloc;
Line 20   if ( _Alloc == CRetailMalloc_Alloc )
Line 21     strHeapBuffer = HeapAlloc(g_hHeap, 0, strLen);
Line 22   else
Line 23     strHeapBuffer = (void *)((int (__thiscall *)(void *(__stdcall *)(IMalloc *, unsigned int), CMalloc *, SIZE_T))_Alloc)(
Line 24                               _Alloc,
Line 25                               &g_CMalloc,
Line 26                               strLen);
Line 27   v3 = (unsigned int)strHeapBuffer;
Line 28   if ( strHeapBuffer )
Line 29     memcpy(strHeapBuffer, v77, strLen_1);

The out-of-bounds read operation appears at line 13. Based on the vt field value, which is 31 (line 4), we know that this PROPVARIANT contains a WideChar string. The loop where the OOB read occurs is executed to find the WideChar string null terminator, so it looks like PROPVARIANT contains an improperly terminated WideChar string. We land in the CMetadataIFDReaderWriter::GetTagVariantValueAtOffset method where the metadata field value is read directly from the file and is later converted to the string above after tracking the string.

Line 1 int __userpurge CMetadataIFDReaderWriter::GetTagVariantValueAtOffset@<eax>(CMetadataIFDReaderWriter *this@<ecx>, int a2@<esi>, struct IFD::FieldEntry *a3, struct tagPROPVARIANT *arg_tagDataVariant)
Line 2 {
Line 3 (...)
Line 4  v4 = IFD::FieldEntry::GetValueDataSize(a3, a2, &_tagDataLen);
Line 5 (...)
Line 6       tagData = (unsigned __int8 *)CoTaskMemAlloc(tagDataSize);
Line 7       if ( tagData )
Line 8       {
Line 9         v12 = ReadFullBufferFromStream(
Line 10                tagData,
Line 11                (CExternalStream *)(*((_DWORD *)v35 + 18) != 0 ? *((_DWORD *)v35 + 18) + 8 : 0),
Line 12                tagDataLen,
Line 13                internalStack,
Line 14                v31);
Line 15             
Line 16     (...)
Line 17          switch ( dataFormat )
Line 18          {
Line 19       (...)
Line 20            case 7:
Line 21              arg_tagDataVariant->vt = 65;
Line 22              arg_tagDataVariant->lVal = tagDataSize;
Line 23              arg_tagDataVariant->hVal.HighPart = (LONG)__strComment;
Line 24              __strComment = 0;
Line 25              if ( IFD::FieldEntry::IsCommentTag((IFD::FieldEntry *)a3) )
Line 26              {
Line 27                v20 = CMetadataIFDReaderWriter::ProcessCommentByteOrder(
Line 28                        v35,
Line 29                        (unsigned __int8 *)a3,
Line 30                        arg_tagDataVariant->blob.pBlobData,
Line 31                        tagDataSize);
Line 32                v21 = v20;         

In our case, the tag that causes the issue is located at offset : 0x19C and looks like this:

struct DIRENTRY dirEntry[9] Tag# = 0x1b (GPSProcessingMethod)
    enum GeoTag tagNumber   GPSProcessingMethod (27)
    enum DataFormat dataFormat  undefined (7)
    DWORD nComponent    18
    DWORD offsetData    515

where data related with that tag is at offset : 0x20F:

020Fh: 41 53 43 49 49 00 00 00 D3 AA AA AA AA AA AA AA ASCII...Óªªªªªªª 021Fh: AA AA ªª

According to the EXIF documentation, the GPSProcessingMethod tag can contain designated internal text encoding. That is why the data format is set to undefined and needs to be checked explicitly.

Also, the last sentence describing this tag says:

 Since the Type is not ASCII, NULL termination is not necessary.

Standard suggests that a NULL termination byte is not necessary and indeed our tag's data does not have it. Next, after the tag's data is read and assigned to the PROPVARIANT arg_tagDataVariant argument, we can see the following code inside the CMetadataIFDReaderWriter::GetValue method:

Line 1  int __thiscall CMetadataIFDReaderWriter::GetValue(CMetadataIFDReaderWriter *this, struct IFD::FieldEntry *a2, struct tagPROPVARIANT *tagDataVariant)
Line 2  {
Line 3  (...)
Line 4      v6 = CMetadataIFDReaderWriter::GetTagVariantValueAtOffset(v14, (int)tagData, (struct_a3_1 *)a2, tagData);
Line 5  (...)
Line 6    if ( IFD::FieldEntry::IsCommentTag(tagType) && tagDataVariant->vt == 65 )
Line 7    {
Line 8      v8 = ConvertCommentOnRead(tagDataVariant, &dstVariant);  

The ConvertCommentOnRead function is called when our tagData->vt is set to 65 (VT_BLOB) and tag type is 0x1B GPSProcessingMehotd which in our case is true. Note that dstVariant->vt will be explicitly set to 31 (VT_LPWSTR) in this case.

Line 1  int __fastcall ConvertCommentOnRead(const PROPVARIANT *srcVariant, PROPVARIANT *dstVariant)
Line 2  {
Line 3    v2 = srcVariant->hVal.HighPart;
Line 4    v4 = srcVariant->ulVal;
Line 5    *(_DWORD *)&dstVariant->vt = 0;
Line 6    *(_DWORD *)&dstVariant->wReserved2 = 0;
Line 7    dstVariant->hVal.QuadPart = 0i64;
Line 8    if ( v4 < 8 )
Line 9      return PropVariantCopy(dstVariant, srcVariant);
Line 10   if ( v2 == 'ASCII' || v2 == 'JIS' )
Line 11   {
Line 12     dstVariant->vt = 31;
Line 13     v13 = v4 - 8;
Line 14     result = SniffAndConvertToWideString((const char *)&dstVariant->bVal, v9, v11);
Line 15     if ( result < 0 )
Line 16       result = CoTaskMemAllocWithInit(v10, v12);
Line 17     return result;
Line 18   }

When encoding of our tagData is specified as ASCII or JIS, a conversion is made from that format to WideString inside the SniffAndConvertToWideString function and the resulting string is assigned to the dstVariant argument. To understand where problem appears we need to dive into the SniffAndConvertToWideString function and the function DetectStringCodePageAndMaxLength that it calls. Its pseudo code looks as follows:

Line 1 int DetectStringCodePageAndMaxLength(BYTE *srcString,DWORD srcStringSize,PDWORD dstStringSize,PWORD detectedCodePage)
Line 2 {
Line 3  *dstStringSize = MultiByteToWideChar(65001 /*Unicode (UTF-8)/*,MB_ERR_INVALID_CHARS,srcString,srcStringSize,0,0);
Line 4  if(*dstStringSize == 0)
Line 5  {
Line 6      if( GetLocaleInfoEx(0,0x20001004,detectedCodePage,2) > 0)
Line 7      {
Line 8          *dstStringSize = MultiByteToWideChar(65001 /*Unicode (UTF-8)/*,0,srcString,srcStringSize,0,0);
Line 9          if(*dstStringSize)
Line 10         {
Line 11             *dstStringSize += 1; 
Line 12         }
Line 13     }
Line 14 }
Line 15}

As its name states, this function is responsible for detecting the proper CodePage for srcString characters and the number of characters after conversion. At line 3 there is an atempt to obtain the amount of characters after conversion but the MultiByteToWideChar API has the MB_ERR_INVALID_CHARS flag set which means that if the srcStringSize contain s a bad character (a character that doesn't exist in the UTF-8 encoding table), theMultiByteToWideChar` API will fail.

A reminder of our string :

0217h: D3 AA AA AA AA AA AA AA AA AA                    Óªªªªªªªªª

0xD3 does not exist as a UTF-8 character but 0xD3 0xAA does and these two bytes will be count as a 1 character. Moving further we have the AA AA ... bytes chain which does not exist in UTF-8 in any possible sequence, so the MultiByteToWideChar API fails. The detectedCodePage variable is changed via a call to GetLocaleInfoEx line 6 from UTF-8 to (on testing machine) 1252 windows-1252 ANSI Latin 1; Western European (Windows). Later a call MultiByteToWideChar API is made but this time without MB_ERR_INVALID_CHARS flag set. This is the definition according the MSDN:

Starting with Windows Vista, the function does not drop illegal code points if the application does not set this flag, but instead replaces illegal sequences with U+FFFD (encoded as appropriate for the specified codepage).
Windows 2000 with SP4 and later, Windows XP:   If this flag is not set, the function silently drops illegal code points. A call to GetLastError returns ERROR_NO_UNICODE_TRANSLATION.

This implies that the illegal byte sequence will be replaced with 0xFFFD and count as a 1 character. In our case the number of characters detected is:

0xD3AA   = 1
0xAA * 8 = 8

So a call to MultiByteToWideChar at line 8 will set the dstStringSize variable to 9. At line 11 the authors took into a count NULL "byte" and add 1 to dstStringSize variable.

With this information, the srcString is finally converted inside SniffAndConvertToWideString which looks as follow:

Line 1  VOID SniffAndConvertToWideString(BYTE *srcString,DWORD srcStringSize,PWCHAR dstString,PDWORD dstStringSize)
Line 2  {   
Line 3      DetectStringCodePageAndMaxLength(srcString,srcStringSize,dstStringSize,detectedCodePage);
Line 4      DWORD wideCharBufferSize = *dstStringSize * 2;  
Line 5      dstString = CoTaskMemAllocWithInit(wideCharBufferSize); // alloc + memset(0)
Line 6      MultiByteToWideChar(detectedCodePage /*1252 ANSI Latin 1*/,0,srcString,srcStringSize,dstString,*dstStringSize); 
Line 7      (...)
Line 8  }

Notice that in our case detectedCodePage changed from UTF-8 to ANSI Latin1 because of the illegal characters in srcString. This is important because wqhen using that particular code page characters like 0xD3AA won't be treated as a one but two separates chars and generaly all bytes will be converted in the following way:

0xD3 -> 00 D3 _____ these 2 bytes inhabit 4 bytes using this code page instead of 2
0xAA -> 00 AA
(...)
0xAA -> 00 AA // last byte overwrites space for null byte

This ends up writing 1 extra character overwriting the terminating NULL byte. As a result, no termination character is set at the end of the newly created WideString.

Line 1  HRESULT __stdcall CMetadataIFDReaderWriter::CoerceValueType(struct IFD::FieldEntry *tagType, const struct tagPROPVARIANT *tagDataWideStringVariant, struct tagPROPVARIANT *pvarDest)
Line 2  {
Line 3    if ( IFD::FieldEntry::IsCommentTag(tagType) )
Line 4    {
Line 5      v8 = CoerceStringVectors(tagDataWideStringVariant, pvarDest);

Finally, we land inside the CMetadataIFDReaderWriter::CoerceValueType method, which calls the CoerceStringVectors function where the PropVariantCopy API will be called, this time on a tagPROPVARIANT variant object which contains a non-NULL-terminated WideString that causes an out-of-bounds read during the copy operation. An attacker can use this vulnerability to leak important heap memory and use it to bypass mitigations when exploiting another vulnerability.

Crash Information

(3d04.1b68): Access violation - code c0000005 (first/second chance not available)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
Time Travel Position: AED5:0
eax=216c3000 ebx=213aee18 ecx=0000d0d0 edx=216c2fea esi=001befb8 edi=216c2fe8
eip=756b4192 esp=001beeb8 ebp=001bef00 iopl=0         nv up ei ng nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000282
combase!PropVariantCopy+0xc2:
756b4192 668b08          mov     cx,word ptr [eax]        ds:002b:216c3000=????
0:000> !analyze -v 
*******************************************************************************
*                                                                             *
*                        Exception Analysis                                   *
*                                                                             *
*******************************************************************************


KEY_VALUES_STRING: 1


STACKHASH_ANALYSIS: 1

TIMELINE_ANALYSIS: 1

Timeline: !analyze.Start
    Name: <blank>
    Time: 2018-07-24T23:18:55.918Z
    Diff: 53393918 mSec

Timeline: Dump.Current
    Name: <blank>
    Time: 2018-07-24T08:29:02.0Z
    Diff: 0 mSec

Timeline: OS.Boot
    Name: <blank>
    Time: 2018-07-17T23:38:22.0Z
    Diff: 550240000 mSec


DUMP_CLASS: 2

DUMP_QUALIFIER: 2

FAULTING_IP: 
combase!PropVariantCopy+c2 [onecore\com\combase\util\propvar.cxx @ 628]
756b4192 668b08          mov     cx,word ptr [eax]

EXCEPTION_RECORD:  (.exr -1)
ExceptionAddress: 756b4192 (combase!PropVariantCopy+0x000000c2)
   ExceptionCode: c0000005 (Access violation)
  ExceptionFlags: 00000000
NumberParameters: 2
   Parameter[0]: 00000000
   Parameter[1]: 216c3000
Attempt to read from address 216c3000

FAULTING_THREAD:  00001b68

FOLLOWUP_IP: 
WindowsCodecs!CoerceStringVectors+59
6fa1577a 8bf0            mov     esi,eax

READ_ADDRESS:  216c3000 

ERROR_CODE: (NTSTATUS) 0xc0000005 - The instruction at 0x%p referenced memory at 0x%p. The memory could not be %s.

EXCEPTION_CODE: (NTSTATUS) 0xc0000005 - The instruction at 0x%p referenced memory at 0x%p. The memory could not be %s.

EXCEPTION_CODE_STR:  c0000005

EXCEPTION_PARAMETER1:  00000000

EXCEPTION_PARAMETER2:  216c3000

WATSON_BKT_PROCSTAMP:  5b56d496

WATSON_BKT_MODULE:  combase.dll

WATSON_BKT_MODSTAMP:  cdc43ef4

WATSON_BKT_MODOFFSET:  a4192

WATSON_BKT_MODVER:  10.0.17134.112

MODULE_VER_PRODUCT:  Microsoft® Windows® Operating System

BUILD_VERSION_STRING:  10.0.17134.1 (WinBuild.160101.0800)

MODLIST_WITH_TSCHKSUM_HASH:  4c44913b10bfe0d145860ff67ee36b06da41ced0

MODLIST_SHA1_HASH:  7cd93c0c95b46cda49925bc64bd9784cc34ad0df

NTGLOBALFLAG:  2000000

APPLICATION_VERIFIER_FLAGS:  0

PRODUCT_TYPE:  1

SUITE_MASK:  272

DUMP_TYPE:  fe

APPLICATION_VERIFIER_LOADED: 1

PROCESS_NAME:  unknown

ANALYSIS_SESSION_HOST:  DESKTOP-E4N8506

ANALYSIS_SESSION_TIME:  07-25-2018 01:18:55.0918

ANALYSIS_VERSION: 10.0.17712.1000 x86fre

THREAD_ATTRIBUTES: 
OS_LOCALE:  ENU

BUGCHECK_STR:  APPLICATION_FAULT_INVALID_POINTER_READ_AVRF

DEFAULT_BUCKET_ID:  INVALID_POINTER_READ_AVRF

PRIMARY_PROBLEM_CLASS:  APPLICATION_FAULT

PROBLEM_CLASSES: 

    ID:     [0n313]
    Type:   [@ACCESS_VIOLATION]
    Class:  Addendum
    Scope:  BUCKET_ID
    Name:   Omit
    Data:   Omit
    PID:    [Unspecified]
    TID:    [0x1b68]
    Frame:  [0] : combase!PropVariantCopy

    ID:     [0n285]
    Type:   [INVALID_POINTER_READ]
    Class:  Primary
    Scope:  DEFAULT_BUCKET_ID (Failure Bucket ID prefix)
            BUCKET_ID
    Name:   Add
    Data:   Omit
    PID:    [Unspecified]
    TID:    [0x1b68]
    Frame:  [0] : combase!PropVariantCopy

    ID:     [0n98]
    Type:   [AVRF]
    Class:  Addendum
    Scope:  DEFAULT_BUCKET_ID (Failure Bucket ID prefix)
            BUCKET_ID
    Name:   Add
    Data:   Omit
    PID:    [0x3d04]
    TID:    [0x1b68]
    Frame:  [0] : combase!PropVariantCopy

LAST_CONTROL_TRANSFER:  from 6fa1577a to 756b4192

STACK_TEXT:  
001bef00 6fa1577a 213aee18 001befb8 213aee28 combase!PropVariantCopy+0xc2
001bef2c 6f9774b5 00000000 213aedf8 00000000 WindowsCodecs!CoerceStringVectors+0x59
001bef4c 6f990b37 213aedf8 001befb8 213aee18 WindowsCodecs!CMetadataIFDReaderWriter::CoerceValueType+0x7ec6e
001bf01c 6f93b2a4 213b4f68 21396b20 00000005 WindowsCodecs!CMetadataIFDReaderWriter::HrLoadEx+0x64b67
001bf0a0 6f92d438 213aeaec 213b0ff8 21396b20 WindowsCodecs!CMetadataHandler::LoadEx+0x1a4
001bf130 6f92c5ea 001bf1a8 00000000 6f92bfd0 WindowsCodecs!CMetadataIFDReaderWriter::GetTagVariantValueForEmbeddedMetadata+0x26b
001bf1fc 6f93b2a4 2139cf68 21390fb0 00000005 WindowsCodecs!CMetadataIFDReaderWriter::HrLoadEx+0x61a
001bf280 6f92e636 21396aec 21398ff8 21390fb0 WindowsCodecs!CMetadataHandler::LoadEx+0x1a4
001bf2fc 6f991f26 21390f78 00000000 00000000 WindowsCodecs!CMetadataApp1ReaderWriter::GetValue+0x346
001bf374 6f93b2a4 21392f68 17b74f80 00000005 WindowsCodecs!CMetadataApp1ReaderWriter::HrLoadEx+0x64256
001bf3f8 6f91bdfc 21390f7c 17b88fb8 17b74f80 WindowsCodecs!CMetadataHandler::LoadEx+0x1a4
001bf440 6f9231b8 17ad1fe8 6f8d7cb0 17b74f80 WindowsCodecs!CCodecFactory::CreateMetadataReaderFromContainer+0x17c
001bf4b0 6f935a2b 17b74f94 00000000 001bf4f8 WindowsCodecs!CJpegDecoderFrame::GetReaderByIndex+0x2f8
001bf504 6f9095b6 17b6bb90 17adbf90 00000001 WindowsCodecs!CDecoderBase::Initialize+0x23b
001bf5e4 6f91b48d 00000000 00000001 001bf610 WindowsCodecs!CCodecFactory::HrArbitrateDecoderList+0x2b4
001bf65c 6f91cbce 17adbf88 00000000 00000001 WindowsCodecs!CCodecFactory::HrCreateDecoderFromStreamInternalNew+0x365
001bf690 6f91cc96 17ad9fe8 17adbf90 00000000 WindowsCodecs!CCodecFactory::CreateDecoderFromStream+0x4e
001bf6b4 008f8798 17ad9fe8 207f6fb8 00000000 WindowsCodecs!CCodecFactory::CreateDecoderFromFilename+0x76
001bf838 00903367 17ed3fda 978954f0 001bfa48 wicHeap!WIC::WIC+0xf8
001bf964 0090353d 17ed3fda 008f11db 008f11db wicHeap!fuzzme+0x57
001bfa48 00904e0e 00000002 17ed3fa8 17939f48 wicHeap!main+0x7d
001bfa5c 00904c90 97895720 008f11db 008f11db wicHeap!invoke_main+0x1e
001bfab4 00904b2d 001bfac4 00904e28 001bfad8 wicHeap!__scrt_common_main_seh+0x150
001bfabc 00904e28 001bfad8 75fa8484 00231000 wicHeap!__scrt_common_main+0xd
001bfac4 75fa8484 00231000 75fa8460 bc5ced93 wicHeap!mainCRTStartup+0x8
001bfad8 76f82fea 00231000 f6c5137f 00000000 KERNEL32!BaseThreadInitThunk+0x24
001bfb20 76f82fba ffffffff 76f9ec4e 00000000 ntdll!__RtlUserThreadStart+0x2f
001bfb30 00000000 008f11db 00231000 00000000 ntdll!_RtlUserThreadStart+0x1b

Timeline

2018-08-06 - Vendor Disclosure
2018-10-09 - Public Release

Credit

Marcin 'Icewall' Noga of Cisco Talos.