Misdirected security vulnerability: Malformed file results in memory corruption

A security vulnerability report arrived that went something like this:

Subject: An Exploitable Vunerability in dwrite.dll (stack hash 0x6b6f6f4c.0x4654d7441)

The file dwrite.dll allows an attacker to execute arbitrary code or trigger a denial of service by a crafted corrupted PNG file. This vulnerability can be reproduced by using LitWare Publisher 2.0, clicking Insert Image and then selecting the attached PNG file. Debugger output follows:

ModLoad: 00060000 0009f000   litware.exe
ModLoad: 77df0000 77f47000   ntdll.dll
ModLoad: 76dd0000 76ea0000   C:\WINDOWS\SysWOW64\KERNEL32.DLL
ModLoad: 71e40000 71e59000   C:\Windows\SysWOW64\dwrite.dll

(1788.17ec): Access violation - code c0000005 (first chance)
eax=00000000 ebx=0039d82c ecx=0000000a edx=00000000 esi=006c6608 edi=36363636
eip=767b997e esp=003afb44 ebp=003afb54 iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010246
767b997e f3aa rep stos byte ptr es:[edi]

0:004> k
ChildEBP RetAddr
003afb54 74db8b92 msvcrt!_VEC_memzero+0x6a
003afb8c 68f41cbf COMCTL32!Progress_Paint+0x4c
003afba8 68ff6fbb COMCTL32!Progress_UpdatePosition+0x6b
003afbbc 690c3dea COMCTL32!Progress_Update+0x46
003afc48 756377d8 COMCTL32!Progress_WndProc+0x14bfdc
003afc74 756378cb USER32!InternalCallWinProc+0x23
003afcf0 7563f139 USER32!UserCallWinProcCheckWow+0x100
003afd58 75648fce USER32!SendMessageWorker+0x656
003afd80 0006e7db USER32!SendMessageA+0x8b
003afdbc 00080688 litware+0xe7db
003afde0 00092061 litware+0x20688
003affa8 0007ff75 litware+0x32061
003affc4 0008fe12 litware+0x1ff75
003b00ec 00074066 litware+0x2fe12
003b1760 756377d8 litware+0x14066
003b2d40 756378cb USER32!InternalCallWinProc+0x23
003b2d6c 7563f139 USER32!UserCallWinProcCheckWow+0x100
003b2de8 75648fce USER32!SendMessageWorker+0x656
003b2e50 00e949db USER32!SendMessageA+0x8b
003b2e78 00e9546f litware+0x1849db
003b2ec8 0108a800 litware+0x18546f
003b307c 77a7850d litware+0x37a800
003b30c8 77e4bf39 KERNEL32!BaseThreadInitThunk+0xe
003b30d4 77e4bf0c ntdll!__RtlUserThreadStart+0x72
003b3118 00000000 ntdll!_RtlUserThreadStart+0x1b

0:004> !exploitable

Exploitability Classification: EXPLOITABLE
Recommended Bug Title: Exploitable - User Mode Write AV
    starting at msvcrt!_VEC_memzero+0x000000000000006a
    (stack hash 0x6b6f6f4c.0x4654d7441)

User mode write access violations that are not near NULL are exploitable.

Okay, let's look at what we were given. We have a stack trace, where the code is trying to zero out a block of memory, but the address of that block of memory is 0x36363636, which is invalid and awfully suspicious. This was classified by the !exploitable debugger extension as exploitable because the bad address is used control a write.

Great, now let's look at the analysis by the submitter.

The submitter says that the vulnerability is in dwrite.dll. It's not clear from the stack trace why dwrite.dll is getting the blame. After all, there is no dwrite code anywhere on the stack.

The only appearance of dwrite in the debugger output is the fact that dwrite.dll was the DLL most recently loaded by the process. I guess the submitter decided that this was enough to pin the blame on dwrite.dll. "The most recent person to enter the room is responsible for everything bad that happens."

(Note that they quite pointedly took the bug title that the !exploitable debugger extension recommended and changed the name of the DLL, while keeping the rest the same, including the stack hash!)

What more likely happened is that loading the malformed PNG file caused LitWare to corrupt some memory that Progress_Paint was using, and then when LitWare finally got around to updating the progress control, the Progress_Paint function crashed because its pointer to some internal data structure got corrupted.

This is a case of somebody knowing just enough to be dangerous. They found the !exploitable debugger extension, but they didn't understand how to use it.

Yes, they found a vulnerability. But they didn't understand how to assign the blame, so they blamed Microsoft!

This issue needs to go to the publishers of LitWare. Their program is the one that is corrupting memory in response to the malformed PNG file.

Bonus chatter: This conclusion took some time to verify, because it's possible that LitWare Publisher uses a component provided by Microsoft (such as the Windows Imaging Component) to decode PNG files, in which case the vulnerability could be in that component rather than in LitWare itself. But we were able to confirm that the memory corruption was coming from LitWare's own custom PNG decoder.

This last step is important, because if you had simply redirected the report without investigating it, and the problem really was in, say, the Windows Imaging Component, then you are in the unenviable position of having been informed of a security vulnerability and blown it off. And then when the vulnerability makes the front page of the news, everybody's going to say, "What a bunch of idiots over there at Microsoft. They received the vulnerability report months ago and rejected it as not their bug!"

Bonus chatter: Turns out that the finder was using an old version of LitWare. The problem doesn't exist in the latest version of LitWare, so presumbly LitWare already found and fixed the problem on their side.

Comments (17)

  1. Martin says:

    I understand, that MS employees handling security issues have difficult work. However they should treat each message more politely. I reported an issue, where simple program run under standard account will crash Windows Biometric Service causing DOS (users cannot login using biometry until reboot). I attached source code of the program and described what is happening. The issue was immediately closed. I understand, that this was not a typical security problem, however this was a bug for sure.
    Now I have much less motivation to report any problem to MS.

    1. shawn says:

      If it’s a non-security bug, I believe the correct place to document it is the feedback app. Then it’s triaged according to how many people have the issue. Did 1000 people each encounter this bug once? Did one person encounter the bug 1000 times? Was it some kind of mix between the two? How severe is it? Does it lead to data loss or security issue, or is it just an annoyance? Depending on the answers to these and hundreds of other questions, the issue will be assigned a priority and assigned to someone to work on coding a solution, and it won’t “just get closed”. I’d start there.

      1. Stefan Kanthak says:

        1. “Denial of service” is a vulnerability.
        2. which feedback app?
        There is no such app on Windows Embedded POSReady 2009, Windows Server 2008 [R2] and Windows 7, and there was none on Windows XP and Windows Vista.

    2. But to be fair, I think we can all imagine the amount of feedback Microsoft is receiving each day.

    3. The_Assimilator says:

      Martin, that’s unfortunate, but posts like this one hopefully help you to understand how and why Microsoft support gets a little jaded.

    4. Harry Johnston says:

      I would guess that Microsoft do not consider local denial of service attacks to count as security vulnerabilities, presumably on the grounds that a local user can inevitably DoS the system using much simpler techniques, e.g., a fork bomb.

      … and I would further guess that the security team have been instructed in no uncertain terms not to do anything about bug reports that don’t represent security vulnerabilities, because otherwise they’d be quickly overwhelmed by them.

    5. Darran Rowe says:

      Remember, while he showed that there was a bug in the application, he didn’t successfully show where it was. The dwrite.dll doesn’t actually decode png files, all it does is read fonts and draw them either to a Direct2D surface or a GDI HDC.
      Even then, it is hard to pin it down to a particular component, since WIC does actually decode png files, but unless there is an indication of WIC being used (like windowscodecs.dll being loaded) then there is just as much of a chance that libpng or a hand written png decoder was used, and do you expect Microsoft to fix bugs in libraries that they don’t own?

  2. DWalker07 says:

    “User mode write access violations that are not near NULL are exploitable.”

    What is “… not near NULL”? How can something be near NULL? If it’s very tiny perhaps?

    1. Joshua says:

      0x00000008 is just a DoS not an exploitable crash.

    2. M Hotchin says:

      Think structure offsets, etc. If your structure pointer is NULL, and you access anything other than the first element, then you will have pointer values ‘near’ null. Windows / x64 use all bits zero as the NULL pointer, so these would have values like ‘memory at address 14’.

      I think 64K is mapped as inaccessible for this reason.

      1. DWalker07 says:

        Thanks for the info. “Not near address zero” might be more understandable.

  3. Gee Law says:

    It can be brain twisting when reading stories anonymised by replacing a company with a fictional Microsoft company name, because, after all, Litware is Microsoft.

  4. Max says:

    My experience with dealing with the bug-reporting sides of various teams has been similarly bad, and seeing the same bug being improperly closed every six months or so isn’t much fun. But that’s not Raymond’s fault – that’s something that goes up the management chain.

  5. Joshua says:

    Well to be fair, sometimes it took publishing the vulnerabilities to get MS to respond to them. At least the policy is well and thoroughly fixed even though the practice isn’t quite. I suspect that catching on that a kernel privilege exploit that’s only reachable by corrupting an NTFS filesystem first is a real security bug would take a long time.

    I wonder how long before KPTI does wonders for the MPAA.

  6. Brian says:

    Thank you for sharing these fascinating behind-the-scenes stories. Are you able to share how many man-hours this sort of bug typically ends up wasting?

  7. Ray Koopa says:

    I almost messed up thinking you listed a real company name here, mistaking LitWare for Leadtools.

  8. quiret says:

    Thank you for professionally handling all kinds of reports, Raymond. Your blog is always a good read to me :-)

Skip to main content