MS13-017 - The harmless silent patch...

Hi, in this blog post I'm going to discuss a silent patch published by Microsoft on 12th February 2013 (http://technet.microsoft.com/en-us/security/bulletin/ms13-017). Even though this bug was patched the previous patch Tuesday, I think that it is interesting to analyze and show the relationship between the ROM BIOS and Windows.

Diffing the Patch:

According to the Microsoft description, we are told that 3 vulnerabilities were addressed by this patch:

  • Kernel Race Condition Vulnerability - CVE-2013-1278
  • Kernel Race Condition Vulnerability - CVE-2013-1279
  • Windows Kernel Reference Count Vulnerability - CVE-2013-1280

The files that were modified are "ntoskrnl.exe" and "ntkrnlpa.exe".

In general, I always analyze the changes between Windows XP and Windows 7, because the changed functions aren't always the same.

When I did the binary diffing in Windows XP ( and also in Windows 2003 ) between the vulnerable version of "ntkrnlpa.exe" ( 5.1.2600.6284 ) and the patched version of "ntkrnlpa.exe" ( 5.1.2600.6335 ) I only found one change, the "VdmpInitialize" function. After looking at the binary diffing results and analyzing the changes made in this function, I realized that it was very different from what Microsoft reported...

The changed function:

As I said before, the changed function is "VdmpInitialize". This function is called when the "ntvdm.exe" process is invoked by the operating system when a 16 bit application is executed by a user. Essentially, this function is responsible for mapping part of the ROM BIOS in user space to the first megabyte of the "ntvdm.exe" process memory, creating the right context for a 16 bit process.

When a 16 bits process calls BIOS interrupts, the ROM BIOS code (now in the user space memory) is executed. An interesting detail of this is that the copied memory by the "VdmpInitialize" function is really the memory mapped in the physical address space located between c000:0000 to f000:ffff. It means that if the mapped code located in this memory address was modified, for example by a ROOTKIT, it could be executed by a 16 bit application when it is launched.

The bug:

The vulnerability is linked with a Windows registry key called "Configuration Data" located in "HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System". This key is used by Windows kernel through the "VdmpInitialize" function, looking at the key value through the "Modify Binary Data" option in regedit program, we can see something like this:

Regedit Output

In the selected area, there is a list with pair of values representing: ADDRESS - LENGTH

Among some values, we can see this:

VGA ROM:

00 00 0C 00 --> 0x000C0000 (BLOCK ADDRESS)

00 80 00 00 --> 0x00008000 (BLOCK LENGTH)

ROM BIOS:

00 00 0F 00 --> 0x000F0000 (BLOCK ADDRESS)

00 00 01 00 --> 0x00010000 (BLOCK LENGTH)

These values are loaded by "VdmpInitialize" function, finalizing the process with data copied from the PHYSICAL MEMORY (only accessible by kernel) to the memory space of the "ntvdm.exe" process. The destination address of the copied data is the same as the original ROM BIOS address but the difference is that it's virtual memory, NOT PHYSICAL MEMORY.

As example of this, we can see how the key values are used as parameters to copy memory from the VGA ROM BIOS:

--> memcpy (0xc0000, SOME_VIRTUAL_ADDRESS, 0x8000);

Now, if we look part of the patched function code:

 Function 1

 Function 2

We can see that the comparison "if (_VdmMapBiosRomReadWrite = 1)" was moved.

In the patched function, the code checks:

- if (BLOCK ADDRESS >= BASE_ROM_BIOS_ADDRESS (0xc0000))

- if (BASE_ROM_BIOS_ADDRESS - BLOCK ADDRESS > BLOCK ADDRESS)

If all is OK, the comparison "if (_VdmMapBiosRomReadWrite = 1)" is executed.

In the unpatched function, there are the same checks but they are only executed when the condition "if (_VdmMapBiosRomReadWrite = 1)" is TRUE.

It is because the "IF" sentence is put in a wrong place. So, if the comparison fails, checks will never be made. At least in my virtual machine, the value of the variable "_VdmMapBiosRomReadWrite" is FALSE.

The interesting detail of that is not exactly this bug, if not what the "VdmpInitialize" function does. Remember that the "VdmpInitialize" function uses value pairs (BLOCK ADDRESS - BLOCK LENGTH) to build the ntvdm.exe memory context and these value pairs are located in the Windows registry, so, they can be modified.

So, we can change the BLOCK ADDRESS value in the registry key and the function will read physical memory from another area. As example, we could read some parts of Windows KERNEL and map them in USER space memory, in this case in the "ntvdm.exe" process. On the other hand, if we change the LENGTH of the data to copy, we could read big quantities of physical memory.

Now, the only way to change the registry key value (unless I'm missing something) is as an administrator user, which it converts the bug in somewhat unattractive, because if we are an administrator user, why would we need more?

ROM BIOS and Windows:

Apparently, this bug doesn't represent any problem for users, but the access to the PHYSICAL MEMORY where the ROM BIOS is mapped has deeper implications.

A year ago, VMware published an advisory called "VMware High-Bandwidth Backdoor ROM Overwrite Privilege Elevation" (http://www.securityfocus.com/bid/52820).  In summary, the patch published by VMware allows us to modify the virtual machine ROM BIOS memory area in runtime and finish it with a privilege escalation exploit within the virtual machine.

If the ROM BIOS is modified, in this case could be the VGA ROM BIOS, the malicious code could be executed calling interruption number 0x10 ( INT 10h ). In Windows XP/Windows 2003, the BIOS interruption 10h can be invoked from a windows console changing de video mode to FULL-SCREEN. A possible result is malicious code running in VM86 mode (Virtual mode 8086) within of the CSRSS.EXE process.

Now, according to the VMware advisory and the tests that I carried out myself, it's possible to get away from the VM86 mode overwriting a table called "VDM TIB" located from the 1200h:0000h memory address (or 0x12000 linear value).

The complete exploitation process could be:

  1. Through a bug, to overwrite the memory area where the ROM BIOS is mapped (we could use the "INT 10h" handler). Modify part of the CSRSS.EXE process memory can produces the same results (only Windows XP/Windows 2003).
  2. Invoke the "INT 10h" handler changing the console video mode to FULL-SCREEN.
  3. Running in VM86 mode within CSRSS process, to modify the VDM TIB structure.
  4. When the "INT 10h" returns, take control of the CSRSS.EXE process jumping to 32 bits code.

Final thoughts:

Microsoft decided not to talk about this function and not to assign a CVE for this vulnerability, maybe because they determined that it is not a security vulnerability. However, they decided to patch function, I suppose that there must have been a reason – if anyone has any theories I would love to hear them.

- Nicolas Economou, Senior Exploit Writer, CORE Labs

http://www.coresecurity.com/penetration-testing-overview