Digging Into the Sandbox-Escape Technique of the Recent PDF Exploit

As promised in our previous blog entry for the recent Adobe Reader PDF zero-day attack, we now offer more technical details on this Reader “sandbox-escape” plan. In order to help readers understand what’s going on there, we first need to provide some background.

Adobe Reader’s Sandbox Architecture

The Adobe Reader sandbox consists of two processes: a high-privilege broker process and a sandboxed renderer process; the latter is responsible for rendering the PDF document. Please see Adobe’s ASSET blog for an illustration of the sandbox architecture.

The renderer process has restricted read/write access to the file system, registry, and named objects. Most of the native OS API calls will go through the interprocess communication (IPC) mechanism to the broker process. For example, a native API call (CreateFile) originates from the sandbox process and the broker process eventually takes over as a proxy.


Actually, the Reader sandbox’s IPC is implemented based on Google Chrome’s IPC shared-memory mechanism. The broker process creates a 2MB shared memory for IPC initialization, the handle of the shared memory is duplicated and transferred to the sandboxed process, and all the communications leverage this shared memory.

The API call request from the sandboxed process is stored in an IPC channel buffer (also called CrossCallParams or ActuallCallParams). The structure of the buffer is defined as the following format (from crosscall_params.h):


Here are some explanations for the fields:

  • The first 4 bytes, the “tag,” is the opcode for which function is being called
  • “IsOnOut” describes the data type of the “in/out” parameter
  • “Call return” has 52 bytes. It’s a buffer used to fill the returning data from the IPC server.
  • “Params count” indicates the number of the parameters
  • The parameter type/offset/size info indicate the actual parameters

The parameter type is an enum type, s defined as follows:



Escaping the Sandbox

The sandbox escape in this zero-day exploit is due to a heap-based overflow vulnerability that occurs when the broker process handles the call request of the native API “GetClipboardFormatNameW.” The tag id for this API is 0×73. Here is the ActuallCallParams (IPC channel buffer) memory structure for the request in the exploit:


As marked by different colors above, the first DWORD is the tag id (0×73), and there are only two parameters for this API call (as indicated by the blue DWORD). The yellow DWORDs are the parameter types: Type 6 means INOUTPTR_TYPE and type 2 means ULONG_TYPE. The red DWORDs are the sizes for these parameters, so the first parameter has 0x9c bytes with the “in/out ptr” type and the second parameter has 4 bytes with the “long” type.

Let’s take a look at the definition of the parameters for the GetClipboardFormatNameW API.


According to the preceding definition, the GetClipboardFormatNameW call would look like this:

GetClipboardFormatNameW(0xc19a, “BBBBBBBBBB……”, 0x9c);

At first sight, this function call looks normal, with nothing malicious. Unfortunately, there are two issues that will lead to a heap overflow condition. First, Adobe Reader allocates the heap memory based on “cchMaxCount,” while the correct size should be “cchMaxCount * sizeof(WCHAR)” as this is a Unicode API. In our case, the allocation size is only 0x9c; that is incorrect. Second, the lower-level native API NtUserGetClipboardFormatName() called by GetClipboardFormatNameW() is using cchMaxCount*sizeof(WCHAR) as its “length” parameter when copying a string to the heap buffer. At this point the heap overrun happens!

There is a trick to trigger this heap overflow: Just pay attention to the first parameter. From the MSDN description, the parameter “format” is used to retrieve the type of the format. So if we can pass in advance a format ID that requires a longer buffer space, then later when the broker calls the GetClipboardFormatNameW() to retrieve the format, it will trigger the overflow.

In this sandbox-escaping exploit, the malware calls RegisterClipboardFormatW() to register a different format name, which is much longer than 0x9c bytes. Finally, an object (vtable) on heap will be overwritten. However, the story is not over yet. In order to achieve reliable exploitation, a heap spray inside the broker process is needed. The attacker did this in a very smart way, he or she leveraged the “HttpSendRequestA” function (tag id 0x5d). See the following dumped memory for this function call request.


Because the fourth parameter (lpOptional) has the type VOIDPTR_TYPE (its address and size are highlighted in red) in the exploit, the attacker passes the buffer size 0x0c800000 (the second red section). Because the size is huge, when the IPC server calls ReadProcessMemory API to read the buffer, the broker process’ heap memory will be sprayed with attacker-controlled data at a predictable memory location.

The ASLR- and DEP-bypassing part is very easy because the module base addresses of the broker process and the sandboxed process are same. The attacker can directly use the ROP code chain to defeat both ASLR and DEP.

Adobe has now released the official patch for these critical vulnerabilities. As always, we strongly suggest that users apply the patch as soon as possible. For McAfee customers, you’ll find our solutions in our previous post.

Thanks again to Bing Sun, Chong Xu, and Haifei Li for their help with this analysis.

Dev site behind Apple, Facebook hacks didn’t know it was booby-trapped

iPhoneDevSDK—the site apparently responsible for the hacks at Facebook, Apple, and Twitter—says it was not aware it was being used to attack visitors until it read press reports this week. In a news post (do not click if you're wary of security breaches) on Wednesday, site admins said they had no knowledge of the breach and were not contacted by any of the affected companies. Though, iPhoneDevSDK is now working with Facebook's security team in order to share information about what happened.

"We were alerted through the press, via an AllThingsD article, which cited Facebook. Prior to this article, we had no knowledge of this breach and hadn't been contacted by Facebook, any other company, or any law enforcement about the potential breach," wrote iPhoneDevSDK admin iseff.

"What we've learned is that it appears a single administrator account was compromised. The hackers used this account to modify our theme and inject JavaScript into our site. That JavaScript appears to have used a sophisticated, previously unknown exploit to hack into certain user's computers," he went on. "We're still trying to determine the exploit's exact timeline and details, but it appears as though it was ended (by the hacker) on January 30, 2013."

Read 6 remaining paragraphs | Comments

How Anonymous accidentally helped expose two Chinese hackers

How did security firm Mandiant put names to two previously unknown Chinese hackers who, it says, steal American corporate secrets for the Chinese government? With a little inadvertent help from Anonymous.

Mandiant's 74-page report covers a particular hacking group referred to as "APT1" and contends that the group works for or under the direction of the Chinese government as part of the military's secretive "Unit 61398." The report ties a huge string of hacks over the last few years to Unit 61398 and goes on to show the building where the hacks might be hatched. The report is stuffed with detail uncommon in these types of stories, and even includes a translated Chinese document showing a local telecom company agreeing to Unit 61398's request for additional fiber optic connections in the name of state security.

The Mandiant researchers then tried to go one step further, putting at least a few real names to the coders involved. (BusinessWeek recently did something similar, with fascinating results.) Mandiant began with a malware coder who goes by the name "UglyGorilla"—a name which is left repeatedly in code tied to the APT1 group.

Read 7 remaining paragraphs | Comments