CVE-2016-3220 : Detail

CVE-2016-3220

7.8
/
High
A01-Broken Access Control
68.44%V3
Local
2016-06-15
23h00 +00:00
2018-10-12
17h57 +00:00
Notifications for a CVE
Stay informed of any changes for a specific CVE.
Notifications manage

CVE Descriptions

atmfd.dll in the Adobe Type Manager Font Driver in Microsoft Windows Vista SP2, Windows Server 2008 SP2 and R2 SP1, Windows 7 SP1, Windows 8.1, Windows Server 2012 Gold and R2, Windows RT 8.1, and Windows 10 Gold and 1511 allows local users to gain privileges via a crafted application, aka "ATMFD.dll Elevation of Privilege Vulnerability."

CVE Informations

Related Weaknesses

CWE-ID Weakness Name Source
CWE-264 Category : Permissions, Privileges, and Access Controls
Weaknesses in this category are related to the management of permissions, privileges, and other security features that are used to perform access control.

Metrics

Metrics Score Severity CVSS Vector Source
V3.0 7.8 HIGH CVSS:3.0/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H

Base: Exploitabilty Metrics

The Exploitability metrics reflect the characteristics of the thing that is vulnerable, which we refer to formally as the vulnerable component.

Attack Vector

This metric reflects the context by which vulnerability exploitation is possible.

Local

A vulnerability exploitable with Local access means that the vulnerable component is not bound to the network stack, and the attacker's path is via read/write/execute capabilities. In some cases, the attacker may be logged in locally in order to exploit the vulnerability, otherwise, she may rely on User Interaction to execute a malicious file.

Attack Complexity

This metric describes the conditions beyond the attacker's control that must exist in order to exploit the vulnerability.

Low

Specialized access conditions or extenuating circumstances do not exist. An attacker can expect repeatable success against the vulnerable component.

Privileges Required

This metric describes the level of privileges an attacker must possess before successfully exploiting the vulnerability.

None

The attacker is unauthorized prior to attack, and therefore does not require any access to settings or files to carry out an attack.

User Interaction

This metric captures the requirement for a user, other than the attacker, to participate in the successful compromise of the vulnerable component.

Required

Successful exploitation of this vulnerability requires a user to take some action before the vulnerability can be exploited. For example, a successful exploit may only be possible during the installation of an application by a system administrator.

Base: Scope Metrics

An important property captured by CVSS v3.0 is the ability for a vulnerability in one software component to impact resources beyond its means, or privileges.

Scope

Formally, Scope refers to the collection of privileges defined by a computing authority (e.g. an application, an operating system, or a sandbox environment) when granting access to computing resources (e.g. files, CPU, memory, etc). These privileges are assigned based on some method of identification and authorization. In some cases, the authorization may be simple or loosely controlled based upon predefined rules or standards. For example, in the case of Ethernet traffic sent to a network switch, the switch accepts traffic that arrives on its ports and is an authority that controls the traffic flow to other switch ports.

Unchanged

An exploited vulnerability can only affect resources managed by the same authority. In this case the vulnerable component and the impacted component are the same.

Base: Impact Metrics

The Impact metrics refer to the properties of the impacted component.

Confidentiality Impact

This metric measures the impact to the confidentiality of the information resources managed by a software component due to a successfully exploited vulnerability.

High

There is total loss of confidentiality, resulting in all resources within the impacted component being divulged to the attacker. Alternatively, access to only some restricted information is obtained, but the disclosed information presents a direct, serious impact. For example, an attacker steals the administrator's password, or private encryption keys of a web server.

Integrity Impact

This metric measures the impact to integrity of a successfully exploited vulnerability. Integrity refers to the trustworthiness and veracity of information.

High

There is a total loss of integrity, or a complete loss of protection. For example, the attacker is able to modify any/all files protected by the impacted component. Alternatively, only some files can be modified, but malicious modification would present a direct, serious consequence to the impacted component.

Availability Impact

This metric measures the impact to the availability of the impacted component resulting from a successfully exploited vulnerability.

High

There is total loss of availability, resulting in the attacker being able to fully deny access to resources in the impacted component; this loss is either sustained (while the attacker continues to deliver the attack) or persistent (the condition persists even after the attack has completed). Alternatively, the attacker has the ability to deny some availability, but the loss of availability presents a direct, serious consequence to the impacted component (e.g., the attacker cannot disrupt existing connections, but can prevent new connections; the attacker can repeatedly exploit a vulnerability that, in each instance of a successful attack, leaks a only small amount of memory, but after repeated exploitation causes a service to become completely unavailable).

Temporal Metrics

The Temporal metrics measure the current state of exploit techniques or code availability, the existence of any patches or workarounds, or the confidence that one has in the description of a vulnerability.

Environmental Metrics

[email protected]
V2 6.9 AV:L/AC:M/Au:N/C:C/I:C/A:C [email protected]

EPSS

EPSS is a scoring model that predicts the likelihood of a vulnerability being exploited.

EPSS Score

The EPSS model produces a probability score between 0 and 1 (0 and 100%). The higher the score, the greater the probability that a vulnerability will be exploited.

EPSS Percentile

The percentile is used to rank CVE according to their EPSS score. For example, a CVE in the 95th percentile according to its EPSS score is more likely to be exploited than 95% of other CVE. Thus, the percentile is used to compare the EPSS score of a CVE with that of other CVE.

Exploit information

Exploit Database EDB-ID : 39991

Publication date : 2016-06-20 22h00 +00:00
Author : Google Security Research
EDB Verified : Yes

Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=785 The Adobe Type Manager Font Driver (ATMFD.DLL) responsible for handling PostScript and OpenType fonts in the Windows kernel provides a channel of communication with user-mode applications via an undocumented gdi32!NamedEscape API call. The nature of the channel is similar to IOCTLs [1] of type METHOD_BUFFERED [2], in that it also uses a 32-bit escape code (equivalent to control codes in IOCTL), and input and output buffers employed to pass data to the driver and receive information back. We suspect that this little known interface was originally designed to be more universal, but since ATMFD has remained the only third-party font driver in Windows for the past two decades, in reality it can only be used to interact with this single module. Considering that there hasn't been any public research into the security of ATMFD's NamedEscape handlers, it is likely that it hasn't been thoroughly audited since the creation of the code. The first public vulnerability disclosed in the interface was a 0-day pool corruption (stemming from a 16-bit signedness issue) discovered in Hacking Team's leaked data dump [3], and subsequently fixed by Microsoft in the MS15-077 bulletin [4]. That security issue motivated us to have a deeper look into the security posture of the code area. The main hurdle in approaching the NamedEscape attack surface is that Microsoft provides no symbols or other debugging information for the ATMFD.DLL library via the Microsoft Symbol Server, which means that all functionality needs to be reverse-engineered from the ground up, with no hints available whatsoever. At least that was what we believed until recently, when we discovered that the user-mode counterpart of ATMFD is ATMLIB.DLL -- a legacy library rarely used by the operating system nowadays, but which comes with debug symbols and implements many of its features by making NamedEscape calls to the kernel-mode driver. This lead to the further discovery of the "Adobe Type Manager Software API for Windows 95 and Windows NT 4" [5] and "Adobe Type Manager Software API: Windows" [6] documents, which greatly helped us understand the semantics of most of the escape codes, some of the underlying structures and other specifics of the code. All further analysis presented below is relevant to an ATMFD.DLL file found on Windows 7 32-bit, version 5.1.2.247, md5sum e85bed746bbddcd29ad63f6085e1ce78. The driver currently supports 13 different escape codes in the range of 0x2500 - 0x2514. The bug discussed in this report resides in the handler of code 0x250C, which we have named "ATMGetGlyphName", based on the observation of its behavior and how it is used in the ATMLIB!ATMGetGlyphListW function. Since the execution flow down the call stack is quite complex before we can reach the vulnerable condition, let's briefly summarize the major stages of execution: 1) The i/o buffer size is enforced to be exactly 48 bytes. 2) The ATMGetGlyphName handler function (atmfd+0x1F12) locates the font object based on its kernel-mode address provided at offset 4 of the i/o buffer. 3) The font is mapped into memory (?) by a function at atmfd+0x5AC6. 4) More logic follows depending on whether the font is a PostScript or OpenType one. We have found the PostScript-specific logic to be uninteresting, so we'll follow the OpenType one. 5) A function at atmfd+0xDF10 (we call it "FormatOpenTypeGlyphName") is called with a controlled 16-bit glyph index and a pointer to offset 8 of the i/o buffer (to copy the name there). 6) In order to retrieve the actual glyph name from the .OTF file, another function at atmfd+0x1A2D6 is invoked, we call it "GetOpenTypeGlyphName". Here, the interesting functionality begins. If the glyph id is between 0 and 390, the name is obtained from a hard-coded list of names. Otherwise, it is extracted from the .OTF file itself, by reading from the Name INDEX [7]. The core of the function is as follows (in pseudo-code): --- cut --- PushMarkerToStack(); int glyph_name_offset = ReadCFFEntryOffset(glyph_id); int next_glyph_name_offset = ReadCFFEntryOffset(glyph_id + 1); *pNameLength = next_glyph_name_offset - glyph_name_offset; EnsureBytesAreAvailable(next_glyph_name_offset - glyph_name_offset); PopMarkerFromStack(); --- cut --- The function addresses are as follows: +-------------------------+---------------+ | Function | Address | +-------------------------+---------------+ | PushMarkerToStack | inlined | | ReadCFFEntryOffset | atmfd+0x1994D | | EnsureBytesAreAvailable | atmfd+0x18D11 | | PopMarkerFromStack | atmfd+0x18B34 | +-------------------------+---------------+ The code construct is consistent with the general Name INDEX structure, which is as follows: +---------+------------------+------------------------------------------------+ | Type | Name | Description | +---------+------------------+------------------------------------------------+ | Card16 | count | Number of object stored in INDEX | | OffSize | offSize | Offset array element size | | Offset | offset [count+1] | Offset array (from byte preceding object data) | | Card8 | data[<varies>] | Object data | +---------+------------------+------------------------------------------------+ In order to extract any data from an index, it is necessary to read the offset of the interesting entry, and the next one (to calculate the length), which is what the function does. What are the PushMarkerToStack and PopMarkerFromStack functions, though? As it turns out, the font object being operated on has a 16-element stack (each element 32-bit wide). The ATMFD.DLL file contains multiple assertion strings, which show that the stack is internally named "HeldDataKeys", the element counter is "nHeldDataKeys", and a special -1 value pushed on the stack is "MARK": "fSetPriv->HeldDataKeys[ fSetPriv->nHeldDataKeys-1] == MARK" "fSetPriv->nHeldDataKeys >= 0" "fSetPriv->nHeldDataKeys > 0" "fSetPriv->nHeldDataKeys < MAXHELDDATAKEYS" It is generally important for memory safety to never go beyond the bounds of the HeldDataKeys array, as doing otherwise would result in overwriting adjacent fields of the font object structure, or adjacent pool allocations. Therefore, management of the nHeldDataKeys field must be performed very carefully. It appears to be safe in the GetOpenTypeGlyphName function, as only one element is pushed and subsequently popped. However, if we have a look into the EnsureBytesAreAvailable function, it turns out that if more bytes are requested than are found in the CFF table of the .OTF file, then an exception is generated and handled internally in the routine. One of the actions taken during the handling of the exception is a call to a function at atmfd+0x18C05, which pops all data from the stack until and including the first occurrence of -1. Since another element is also unconditionally popped at the end of GetOpenTypeGlyphName, two elements are popped for just one pushed, which corrupts the state of the nHeldDataKeys field and makes it possible to set it to a negative value. In this specific case, we fully control the Name INDEX being used. Since it is possible to set the offset size to 4 bytes (through the offSize field mentioned above), we can fully control both 32-bit return values of the ReadCFFEntryOffset calls, and thus also their difference, which is passed as an argument to EnsureBytesAreAvailable. In the simplest scenario, triggering the vulnerability in ATMGetGlyphName indefinitely will decrement the nHeldDataKeys field one by one, and overwrite earlier and earlier DWORDs on the pool with 0xffffffff (starting with the font object itself, and then moving onto adjacent pool allocations). This is sufficient to demonstrate pool corruption and a system crash; however, it is also possible to maintain a higher degree of control over what is written to the out-of-bounds memory region, by invoking other escape handlers which push more than just the marker, once nHeldDataKeys is already adjusted to where we want to write. This should enable easier and more reliable exploitation. Another potential obstacle in exploitation could be the fact that the font being operated on must be identified by its kernel-mode address. In practice, however, this is not a problem, as the address can be quickly brute-forced by testing addresses nearby the addresses of other GDI objects (whose locations are available to user-mode programs). This technique was used in the HackingTeam exploit for escape 0x2514. To make it even simpler, the provided proof-of-concept code just brute-forces the entire 32-bit kernel address space, which only takes a few seconds to locate the font object and trigger the bug. If we start an exploit which triggers the vulnerability 100 times on a system with Special Pools enabled, we should observe the following or similar bugcheck: --- cut --- SPECIAL_POOL_DETECTED_MEMORY_CORRUPTION (c1) Special pool has detected memory corruption. Typically the current thread's stack backtrace will reveal the guilty party. Arguments: Arg1: fe67ef50, address trying to free Arg2: fe67ee28, address where bits are corrupted Arg3: 006fa0b0, (reserved) Arg4: 00000023, caller is freeing an address where nearby bytes within the same page have been corrupted Debugging Details: ------------------ [...] BUGCHECK_STR: 0xC1_23 SPECIAL_POOL_CORRUPTION_TYPE: 23 DEFAULT_BUCKET_ID: VISTA_DRIVER_FAULT PROCESS_NAME: csrss.exe CURRENT_IRQL: 2 LAST_CONTROL_TRANSFER: from 82930dd7 to 828cc318 STACK_TEXT: 9f4963e4 82930dd7 00000003 c453df12 00000065 nt!RtlpBreakWithStatusInstruction 9f496434 829318d5 00000003 fe67e000 fe67ee28 nt!KiBugCheckDebugBreak+0x1c 9f4967f8 82930c74 000000c1 fe67ef50 fe67ee28 nt!KeBugCheck2+0x68b 9f496818 82938b57 000000c1 fe67ef50 fe67ee28 nt!KeBugCheckEx+0x1e 9f49683c 8293963d fe67ef50 fe67e000 fe67ef50 nt!MiCheckSpecialPoolSlop+0x6e 9f49691c 82973b90 fe67ef50 00000000 fe67ef50 nt!MmFreeSpecialPool+0x15b 9f496984 96a609cc fe67ef50 00000000 fe67ef60 nt!ExFreePoolWithTag+0xd6 9f496998 96b44ec1 fe67ef60 09fe969f 00000000 win32k!VerifierEngFreeMem+0x5b WARNING: Stack unwind information not available. Following frames may be wrong. 9f4969cc 96b43850 fe67ef68 09fe9553 00000000 ATMFD+0x14ec1 9f496a00 96b329ab 9f496a24 96b4a736 96b6f024 ATMFD+0x13850 9f496a08 96b4a736 96b6f024 fe744fc0 fe63ccf8 ATMFD+0x29ab 9f496a24 96b41516 fe744fb0 09fe952f fe63ccf8 ATMFD+0x1a736 9f496a7c 96b377e0 09fe95e7 96a60c8e 9f496b40 ATMFD+0x11516 9f496ab4 96b34196 09fe95b7 96a60c8e 9f496b40 ATMFD+0x77e0 9f496ae4 969ce0a1 fde3a898 fde3a898 9f496b80 ATMFD+0x4196 9f496b1c 969ce2c4 fde3a898 fde3a898 00000000 win32k!PDEVOBJ::DestroyFont+0x67 9f496b4c 96954607 00000000 00000000 00000001 win32k!RFONTOBJ::vDeleteRFONT+0x33 9f496b74 969561fe 9f496b98 fde3a898 00000000 win32k!PUBLIC_PFTOBJ::bLoadFonts+0x6fb 9f496ba4 96a1fcc4 00000001 ffbbc234 89a3f7f0 win32k!PFTOBJ::bUnloadWorkhorse+0x114 9f496bcc 96a29ae9 9f496c58 0000002b 00000001 win32k!GreRemoveFontResourceW+0xa0 9f496d14 8288ea16 00319768 0000002b 00000001 win32k!NtGdiRemoveFontResourceW+0x111 9f496d14 76dd70d4 00319768 0000002b 00000001 nt!KiSystemServicePostCall 0022fca4 76de6113 76de5e20 00000020 00000028 ntdll!KiFastSystemCallRet 0022fd84 76dd6078 00000000 00000000 00000090 ntdll!RtlpAllocateHeap+0xe68 0022fe14 76de60e4 76de6113 76ec93f1 75957040 ntdll!ZwQueryInformationProcess+0xc 003b0108 00000000 00000000 00000000 00000000 ntdll!RtlpAllocateHeap+0xab2 --- cut --- One could wonder if this issue could be triggered directly from within Internet Explorer, via an embedded .OTF font file and an .EMF image containing EMR_NAMEDESCAPE records. One obvious problem is that the font object needs to be identified by its kernel-mode address, which neither the EMF file or even the JavaScript code running in the browser knows. On 64-bit platforms, this address would have to be leaked into JS, which is not a trivial task since the value is not typically stored in the heap, and therefore impossible without using another vulnerability (e.g. an arbitrary read from the GDI handle table). On 32-bit platforms, it could actually be feasible to simply brute-force the address, by including an EMR_NAMEDESCAPE-based exploit chain for every location possible. This, while theoretically feasible, would blow the size of the EMF up to the orders of hundreds of megabytes, making a practical attack unrealistic. The other obstacle is some obscure reference counting problem with ATMFD. In order for the same object (which contains the HeldDataKeys stack) to persist between multiple calls to NamedEscape (which is what makes it possible to underflow the stack by more than 4 bytes), it is necessary to reference the font after loading it in the system, e.g. with functions such as TextOut() or GetTextMetrics(). However, Internet Explorer does not seem to interact with the font object in any way after loading it in the system, and since the loading itself takes place via a AddFontMemResourceEx API call, the font is private and non-enumerable, meaning that it is impossible to reference it except for the returned handle itself. Until now, we haven't found a way to trigger a large pool corruption from the context of a website, but it could still be possible. Attached you can find a proof of concept program, which together with the specially crafted .OTF font demonstrates a local pool corruption. 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. References: [1] https://msdn.microsoft.com/pl-pl/library/windows/desktop/aa363219%28v=vs.85%29.aspx [2] https://msdn.microsoft.com/pl-pl/library/windows/hardware/ff565356%28v=vs.85%29.aspx [3] https://bugs.chromium.org/p/project-zero/issues/detail?id=473 [4] https://technet.microsoft.com/library/security/ms15-077 [5] https://partners.adobe.com/public/developer/en/atm/5642.ATMWin95andNT.pdf [6] https://partners.adobe.com/public/developer/en/atm/5073.ATM.API_Win.pdf [7] https://partners.adobe.com/public/developer/en/font/5176.CFF.pdf Proof of Concept: https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/39991.zip

Products Mentioned

Configuraton 0

Microsoft>>Windows_10 >> Version -

Microsoft>>Windows_10 >> Version 1511

Microsoft>>Windows_7 >> Version *

Microsoft>>Windows_8.1 >> Version *

Microsoft>>Windows_rt_8.1 >> Version *

Microsoft>>Windows_server_2008 >> Version *

Microsoft>>Windows_server_2008 >> Version r2

Microsoft>>Windows_server_2012 >> Version -

Microsoft>>Windows_server_2012 >> Version r2

Microsoft>>Windows_vista >> Version *

References

https://www.exploit-db.com/exploits/39991/
Tags : exploit, x_refsource_EXPLOIT-DB
http://www.securitytracker.com/id/1036101
Tags : vdb-entry, x_refsource_SECTRACK