lovesuae / google-security-research

Automatically exported from code.google.com/p/google-security-research
0 stars 0 forks source link

Windows Kernel ATMFD.DLL read/write-what-where in LOAD and STORE operators #177

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
The "Type 2 Charstring Format" specification from 5 May 1998 specified two 
storage operators which were later removed from the document: `store` and 
`load`. These operators were responsible for copying data between the transient 
array (also known as the BuildCharArray) and the so-called "Registry object" 
(also deprecated by now, but still supported by Adobe implementations).

As the specs state:

"""
    The Registry provides more permanent storage for a number of items that have predefined meanings. The items stored in the Registry do not persist beyond the scope of rendering a font. Registry items are selected with an index, thus:

    0 Weight Vector
    1 Normalized Design Vector
    2 User Design Vector

    The result of selecting a Registry item with an index outside this list is undefined.
"""

However, the parameter sanity checking implemented for both operators - 
although present - is flawed. There is an off-by-one error in the verification 
of the Registry index, allowing for index 3 to be used:

---
.text:0003CA35                 cmp     eax, 3
.text:0003CA38                 ja      loc_3BEC4       ; jumptable 0003BF69 
case 2

---

Internally, the Registry is implemented as a three-item array of structures 
similar to the following:

---
struct REGISTRY_ITEM {
  int32 size;
  void *data;
} Registry[3];

---

Accessing the 4th element of the array results in a reference to uninitialized 
memory from the Session Paged Pool. If the value of the "size" field happens to 
be positive, the "data" pointer is used as the "source" parameter of a "memcpy" 
call in case of the `load` instruction, and as "dest" in case of `store`.

With the ability to perform kernel pool massaging, it is possible to transform 
the bug into a read/write-what-where primitive by controlling the contents of 
the uninitialized memory used as source/destination addresses, which then 
easily leads to elevation of privileges and full system security compromise.

The issue is reproducible with Type1 and OTF fonts -- attached are reproducers 
for both formats, which can be opened in the standard Windows Font Viewer 
utility to trigger a bugcheck. Please note that in order for the system to 
crash, the "size" field must be positive and the "data" pointer must point into 
kernel-mode memory (ATMFD.DLL silently catches exceptions caused by invalid 
user-mode references), so it might require a few attempts. On the other hand, a 
local exploit is believed to be able to take advantage of the vulnerability 
with near 100% reliability.

If the kernel pool is sprayed such that size=0x55555555 and data=0xaaaaaaaa, 
the following bugcheck is triggered on a fully patched Windows 8.1 32-bit:

---
PAGE_FAULT_IN_NONPAGED_AREA (50)
Invalid system memory was referenced.  This cannot be protected by try-except,
it must be protected by a Probe.  Typically the address is just plain bad or it
is pointing at freed memory.
Arguments:
Arg1: aaaaaaaa, memory referenced.
Arg2: 00000001, value 0 = read operation, 1 = write operation.
Arg3: 994f8c00, If non-zero, the instruction address which referenced the bad 
memory
    address.
Arg4: 00000002, (reserved)

---

A full crash log can be found in "crash.txt".

This bug is subject to a 90 day disclosure deadline. If 90 days elapse without 
a broadly available patch, then the bug report will automatically become 
visible to the public.

Original issue reported on code.google.com by mjurc...@google.com on 19 Nov 2014 at 12:10

Attachments:

GoogleCodeExporter commented 9 years ago

Original comment by mjurc...@google.com on 4 Dec 2014 at 4:37

GoogleCodeExporter commented 9 years ago

Original comment by mjurc...@google.com on 11 Dec 2014 at 10:18

GoogleCodeExporter commented 9 years ago

Original comment by mjurc...@google.com on 24 Mar 2015 at 10:07

GoogleCodeExporter commented 9 years ago

Original comment by cev...@google.com on 1 Apr 2015 at 12:11

GoogleCodeExporter commented 9 years ago

Original comment by mjurc...@google.com on 20 Apr 2015 at 2:07

GoogleCodeExporter commented 9 years ago

Original comment by mjurc...@google.com on 12 Jun 2015 at 4:03