Advisories

Windows Media Foundation Integer Overflow Vulnerability

CVE ID

CVE-2021-33760

Tested Versions

  • mfsrcsnk.dll 10.0.18362.836

Description of the vulnerability

An integer overflow leads to OOB read when parsing MP3 header. The crash can be trigger by navigating into the folder containing the POC file.

Technical Details

The crash happens inside mfsrcsnk.dll when parsing MP3 header. Stack trace.

(582c.420c): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
mfsrcsnk!CMPEGFrame::DeSerializeFrameHeader+0x42:
00007ffa`88140492 418b0e          mov     ecx,dword ptr [r14] ds:00000264`bf9f527f=????????
0:000> k
 # Child-SP          RetAddr           Call Site
00 00000084`61afe770 00007ffa`881408a8 mfsrcsnk!CMPEGFrame::DeSerializeFrameHeader+0x42
01 00000084`61afe7f0 00007ffa`8814128c mfsrcsnk!CMP3MediaSourcePlugin::ReadMPEGFrameHeader+0x78
02 00000084`61afe860 00007ffa`8813f62c mfsrcsnk!CMP3MediaSourcePlugin::DoReadFrameHeader+0x5c
03 00000084`61afe8e0 00007ffa`8813fefa mfsrcsnk!CMP3MediaSourcePlugin::ParseHeader+0x1cc
04 00000084`61afe9c0 00007ffa`8813fd60 mfsrcsnk!CMFMP3PropertyHandler::FeedNextBufferToPlugin+0x12e
05 00000084`61afea60 00007ffa`88137763 mfsrcsnk!CMFMP3PropertyHandler::FeedBuffersToPlugin+0x9c
06 00000084`61afeb20 00007ffa`881492e4 mfsrcsnk!CMFMP3PropertyHandler::InternalInitialize+0x103
07 00000084`61afebf0 00007ffa`f1885451 mfsrcsnk!CMFPropHandlerBase::Initialize+0x84
08 00000084`61afec50 00007ffa`f188241b windows_storage!InitializeFileHandlerWithStream+0x175
09 00000084`61afed10 00007ffa`f1913fc5 windows_storage!CFileSysItemString::HandlerCreateInstance+0x2c7
0a 00000084`61afee00 00007ffa`f1878fd6 windows_storage!CFileSysItemString::_PropertyHandlerCreateInstance+0xad
0b 00000084`61afeeb0 00007ffa`f190a680 windows_storage!CFileSysItemString::LoadHandler+0x1aa
0c 00000084`61aff000 00007ffa`f1876ab5 windows_storage!CFSFolder::LoadHandler+0xe0
0d 00000084`61aff360 00007ffa`f18772a2 windows_storage!CFSPropertyStoreFactory::_GetFileStore+0x165
0e 00000084`61aff430 00007ffa`f1876c12 windows_storage!CFSPropertyStoreFactory::_GetPropertyStore+0x20e
0f 00000084`61aff520 00007ffa`f189d024 windows_storage!CFSPropertyStoreFactory::GetPropertyStore+0x22
10 00000084`61aff560 00007ffa`f189f18b windows_storage!CShellItem::_GetPropertyStoreWorker+0x384
11 00000084`61affaa0 00007ffa`f3b36ddb windows_storage!CShellItem::GetPropertyStore+0xdb
*** WARNING: Unable to verify checksum for metadata.exe
12 00000084`61affd70 00007ff7`0fc710ac SHELL32!SHGetPropertyStoreFromParsingName+0x5b
13 00000084`61affde0 00007ff7`0fc7117c metadata+0x10ac
14 00000084`61affe70 00007ff7`0fc713a4 metadata+0x117c
15 00000084`61affea0 00007ffa`f26a7bd4 metadata+0x13a4
16 00000084`61affee0 00007ffa`f452ce51 KERNEL32!BaseThreadInitThunk+0x14
17 00000084`61afff10 00000000`00000000 ntdll!RtlUserThreadStart+0x21
0:000> !heap -p -a @r14
    address 00000264bf9f527f found in
    _DPH_HEAP_ROOT @ 264bf911000
    in free-ed allocation (  DPH_HEAP_BLOCK:         VirtAddr         VirtSize)
                                264bf913af8:      264bf9f5000             2000
    00007ffaf45c51c4 ntdll!RtlDebugFreeHeap+0x000000000000003c
    00007ffaf4575670 ntdll!RtlpFreeHeap+0x0000000000073d90
    00007ffaf4500790 ntdll!RtlpFreeHeapInternal+0x0000000000000790
    00007ffaf44ffb91 ntdll!RtlFreeHeap+0x0000000000000051
    00007ffaf4199cfc msvcrt!free+0x000000000000001c
    00007ffa88140f2b mfsrcsnk!CID3Frame::`vector deleting destructor'+0x000000000000005b
    00007ffa8814d34a mfsrcsnk!CMP3Base::Release+0x000000000000003a
    00007ffa881346d9 mfsrcsnk!ComSmartPtr<Windows::Foundation::Collections::IMap<HSTRING__ * __ptr64,IInspectable * __ptr64> >::~ComSmartPtr<Windows::Foundation::Collections::IMap<HSTRING__ * __ptr64,IInspectable * __ptr64> >+0x0000000000000019
    00007ffa88140db0 mfsrcsnk!CID3Header::ReadFrames+0x0000000000000134
    00007ffa881512c1 mfsrcsnk!CID3Header::DeSerializeFrameBody+0x0000000000000071
    00007ffa8814b918 mfsrcsnk!CMP3MediaSourcePlugin::DoReadHeaderBody+0x0000000000000060
    00007ffa8813f896 mfsrcsnk!CMP3MediaSourcePlugin::ParseHeader+0x0000000000000436
    00007ffa8813fefa mfsrcsnk!CMFMP3PropertyHandler::FeedNextBufferToPlugin+0x000000000000012e
    00007ffa8813fd60 mfsrcsnk!CMFMP3PropertyHandler::FeedBuffersToPlugin+0x000000000000009c
    00007ffa88137763 mfsrcsnk!CMFMP3PropertyHandler::InternalInitialize+0x0000000000000103
    00007ffa881492e4 mfsrcsnk!CMFPropHandlerBase::Initialize+0x0000000000000084
    00007ffaf1885451 windows_storage!InitializeFileHandlerWithStream+0x0000000000000175
    00007ffaf188241b windows_storage!CFileSysItemString::HandlerCreateInstance+0x00000000000002c7
    00007ffaf1913fc5 windows_storage!CFileSysItemString::_PropertyHandlerCreateInstance+0x00000000000000ad
    00007ffaf1878fd6 windows_storage!CFileSysItemString::LoadHandler+0x00000000000001aa
    00007ffaf190a680 windows_storage!CFSFolder::LoadHandler+0x00000000000000e0
    00007ffaf1876ab5 windows_storage!CFSPropertyStoreFactory::_GetFileStore+0x0000000000000165
    00007ffaf18772a2 windows_storage!CFSPropertyStoreFactory::_GetPropertyStore+0x000000000000020e
    00007ffaf1876c12 windows_storage!CFSPropertyStoreFactory::GetPropertyStore+0x0000000000000022
    00007ffaf189d024 windows_storage!CShellItem::_GetPropertyStoreWorker+0x0000000000000384
    00007ffaf189f18b windows_storage!CShellItem::GetPropertyStore+0x00000000000000db
    00007ffaf3b36ddb SHELL32!SHGetPropertyStoreFromParsingName+0x000000000000005b
    00007ff70fc710ac metadata+0x00000000000010ac
    00007ff70fc7117c metadata+0x000000000000117c
    00007ff70fc713a4 metadata+0x00000000000013a4
    00007ffaf26a7bd4 KERNEL32!BaseThreadInitThunk+0x0000000000000014
    00007ffaf452ce51 ntdll!RtlUserThreadStart+0x0000000000000021

@r14 points to an invalid location on the heap.

Vulnerability Discovery/Analysis

At mfsrcsnk.dll+F774 (function CMP3MediaSourcePlugin::ParseHeader), CMP3MediaSourcePlugin::DoScanForFrameHeader store an offset (0x38d7) into the input buffer at @rbp-0x19.

      v11 = CMP3MediaSourcePlugin::DoScanForFrameHeader(
              v18,
              OOB,
              SZ,
              &OOB_OFFSET);

At mfsrcsnk.dll+f66b the REMAINING_SZ and MFBuffer is updated.

LABEL_30:
    LODWORD(v28) = OOB_OFFSET;
    REMAINING_SZ -= OOB_OFFSET; //0x03946 - 0x38d7 = 0x6f
    MFBuffer.buffer += OOB_OFFSET;
    goto LABEL_31;
  }

Then at mfsrcsnk.dll+F739 CMP3MediaSourcePlugin::DoReadFirstFrameBody is invoked with the new BUF, REMAINING_SZ, and OOB_OFFSET. CMP3MediaSourcePlugin::DoReadFirstFrameBody return 0. OOB_OFFSET is not updated and remains 0x38d7.

    v32 = CMP3MediaSourcePlugin::DoReadFirstFrameBody(v18, BUF, REMAINING_SZ, &OOB_OFFSET);
    v11 = v32;
    if ( v32 == 0xC00D3E86 )
    {
      v11 = 0;
      v28 = *((_QWORD *)v109 + 15) - v111;
      OOB_OFFSET = v28;
      v33 = &v15[v28];
    }

At mfsrcsnk.dll+f753 REMAINING_SZ and MFBuffer is updated again but this time REMAINING_SZ becomes negative and MFBuffer points to an invalid heap region.

      LODWORD(v28) = OOB_OFFSET;
      REMAINING_SZ -= OOB_OFFSET; //0x6f - 0x38d7 = 0xffffc798
      v33 = &MFBuffer.buffer[OOB_OFFSET];
    }
    MFBuffer.buffer = v33;

At mfsrcsnk.dll+f5b6 a check is performed (unsigned comparision). Since REMAINING_SZ is now very large the check is passed.

    if ( REMAINING_SZ < bytes_required )
    {
      *a6 = 1;
      *a5 = -1i64;
      if ( (unsigned __int8)byte_1B098B < 8u )
        goto LABEL_38;
      v57 = 37i64;
      goto LABEL_150;

The execution flow continues and crashes inside CMPEGFrame::DeSerializeFrameHeader trying to access invalid MFBuffer pointer.

Conclusion

This vulnerability might result in code execution if it is in use with other vulnerabilities.

Timeline

  • 2021-02-27 Reported to Vendor
  • 2021-06-18 Vendor assign CVE

Credit

Discovered by Phan Thanh Duy, Brandon Chong and Cao Yi Tian