Trustwave's 2024 Financial Services Threat Reports Highlight Alarming Trends in Insider Threats & Phishing-as-a-Service. Learn More
Get access to immediate incident response assistance.
Get access to immediate incident response assistance.
Trustwave's 2024 Financial Services Threat Reports Highlight Alarming Trends in Insider Threats & Phishing-as-a-Service. Learn More
SpiderLabs investigates a number of suspicious binary files on a daily basis. A week ago we came across a PDF file which had two different vulnerabilities, a remote-code-execution vulnerability in Adobe Reader and a new escalation-of-privileges vulnerability in Windows Kernel.
Just recently we confirmed that the new escalation-of-privileges zero day (CVE-2013-5065) has been delivered in the wild using CVE-2013-3346 as a container. Our goal in this blog post is to raise the public awareness by describing the technical details behind this recent kernel zero-day. We've tested the zero day on Windows XP and Server 2003 only.
These days, Adobe Reader is more safe to use because Adobe did a good job implementing an additional layer of security – the sandbox.
Any code in the recent versions of Adobe Reader renderer will be sandboxed and enforced by a policy. This means that even after a successful exploitation of the renderer, the injected code will be contained and the attacker's shellcode will run under limited privileges (e.g. one can't launch a new process using the shellcode). More details about the Adobe Reader Sandbox can be found here.
At this time, the sandbox can be bypassed in one of the following ways:
The investigated sample exploited CVE-2013-3346 (Adobe Reader ToolButton Remote Code Execution Vulnerability) using heapspray and ROP, in order to gain code execution in the context of Adobe Reader. The shellcode proceeds to exploit the kernel zero-day in order to bypass the sandbox and deliver the final payload (Trojan/virus executable).
First, let's outline the stages of this attack:
Back To User Mode:
Decode the <<obj 4 0>> in the PDF file to an executed binary, and then save it to the %temp% folder.
What is TAPI? From the Microsoft Developer Network, "[Telephony Application Programming Interface (TAPI)] is a set of APIs that simplify and abstract the details of making telephony connections between two or more devices."
NDProxy is a system-provided driver, which allows us to perform various network operations with devices capable of Telephony operations. Essentially NDProxy is the user interface for Telephone operations. As such, it is possible to invoke the DeviceIoControl WinAPI with a handle to NDProxy in order to perform TAPI operations.
When invoking the DeviceIoControl API with a handle to NDProxy driver, the kernel will trigger the NDProxy!PxIODispatch function inside the driver. As the name suggests, the function is responsible for Dispatching I/O instructions (PxTapiLineBusy, PxTapiDial, PxTapiAnswer, etc.).
The DeviceIoControl Function:
BOOL WINAPI DeviceIoControl(
_In_ HANDLE hDevice,
_In_ DWORD dwIoControlCode,
_In_opt_ LPVOID lpInBuffer,
_In_ DWORD nInBufferSize,
_Out_opt_ LPVOID lpOutBuffer,
_In_ DWORD nOutBufferSize,
_Out_opt_ LPDWORD lpBytesReturned,
_Inout_opt_ LPOVERLAPPED lpOverlapped
);
First, to get to the vulnerable flow, we'll have to instruct the kernel to perform a TAPI operation. This can be achieved by invoking DeviceIoControl API with the value of 0x8fff23c8 as its dwIoControlCode:
To determine which TAPI operation to execute, the function PxIODispatch will rely on the lpInBuffer structure – supplied by DeviceIoControl. Considering this fact we have to build a buffer structure with the value of 0x7030125 in its 0x14 offset.
Let's take a look at the PxIODispatch instructions that will determine which PxTapi function to execute:
mov eax, [esi+14h] ; 0x7030125 (lpBuffer+0x14) |
Some Math:
eax+eax*2=eax+2*eax=3eax
Therefore: (3*(0x7030125-0x7030101))*4 = 0x1B0;
This result is then used as an index to a static function table to decide which PxTapi function will be executed.
A snippet from that table(starts at 0x18188):
The address at [functionTable+0x1B0] is out of the table boundaries and therefore points to a pointer with the value of 0x38:
Eventually, the code tries to execute a function from the table by the given index (0x1b0 – the math result from above):
The above call will resolve the pointer at 0x18338(table+0x1B0) which points to 0x38(instead of a valid pxTapi function), then execute the code at 0x00000038.
Here you can see the stack trace of the crash reproduced in our lab environment:
Remember what the PDF shellcode already did? As described in "The Shellcode" paragraph above, the shellcode already allocated an address space and filled the memory at 0x38 with NOPs sled followed by some opcodes.
These opcodes are specially designed to run in ring 0 and the execution of these bytes will utilize the high privileges of the kernel context to elevate AcroRd32.exe (renderer) privileges using the following stages:
At this point, the sandbox has been bypassed and the execution goes back to the user-mode context (AcroRd32.exe) to execute the embedded (obj4) Trojan/virus.
Here's a C++ snippet, for those of you who want to see for yourself:
Trustwave's Secure Web Gateway blocks this attack out-of-the-box using its generic protection engine and did so without any additional updates.
Microsoft offers a solution for this issue here:
http://blogs.technet.com/b/msrc/archive/2013/11/27/microsoft-releases-security-advisory-2914486.aspx
Trustwave is a globally recognized cybersecurity leader that reduces cyber risk and fortifies organizations against disruptive and damaging cyber threats. Our comprehensive offensive and defensive cybersecurity portfolio detects what others cannot, responds with greater speed and effectiveness, optimizes client investment, and improves security resilience. Learn more about us.
Copyright © 2024 Trustwave Holdings, Inc. All rights reserved.