December 28, 2013

Hardcoded Pointers

Use of hardcoded pointer could enable the attacker to bypass ASLR. In this draft I'm describing potential methods to find a hardcoded pointer in your target.

When exploiting particular vulnerabilities it is fundamental to read/write or jump to predictable memory location in the process' address space. ASLR randomizes the memory locations of various key locations including addresses of libraries. Even though we see that some high profile applications still load libraries with ASLR disabled, we have high hopes they will fix the problem soon.

That wouldn't solve the problem overall though. Applying ASLR to all libraries does not mean there is not easily predictable locations in the process' address space. There are API functions that accept address to allocate memory at that address. These functions can be used to hardcode memory address, and so to assign a fixed address to a pointer (CWE-587). As a consequence, it gives an attacker a chance to read/write or jump to known address to bypass ASLR.

For these functions you can specify the desired starting address that you want to allocate. When doing security audit it's worth checking if the functions are called with hardcoded addresses.
VirtualAlloc
VirtualAllocEx
VirtualAllocExNuma
MapViewOfFileEx
MapViewOfFileExNuma
The following functions accept address to read as parameter. These are not appear to be useful but leave them for potential future use.
UnmapViewOfFile, WriteProcessMemory, ReadProcessMemory, FlushViewOfFile, FlushInstructionCache, Toolhelp32ReadProcessMemory, GetWriteWatch, ResetWriteWatch, ReadProcessMemoryProc64, VirtualUnlock, MapUserPhysicalPages, VirtualProtect, VirtualProtectEx, VirtualQueryEx, GetFrameSourceAddress, CompareFrameDestAddress, VirtualFree, VirtualFreeEx, FindNextFrame, WSPStringToAddress, CompareAddresses, AddressToString

It's also worth checking if the application you audit uses shared memory as some application map the memory at fixed address, and even boost library supports the use of this insecure method.
The use of relative pointers is less efficient than using raw pointers, so if a user can succeed mapping the same file or shared memory object in the same address in two processes, using raw pointers can be a good idea. To map an object in a fixed address, the user can specify that address in the mapped region's constructor:
mapped_region region ( shm                         //Map shared memory
                     , read_write                  //Map it as read-write
                     , 0                           //Map from offset 0
                     , 0                           //Map until the end
                     , (void*)0x3F000000           //Map it exactly there
                     );
When auditing source code for hardcoded address it's worth looking for constant starting with 0x ending with 0000 as some might indicate hardcoded memory address. I wrote a simple batch script for that.

The another batch script I have is for binary code. I recommend to use if you don't find a bug using other methods. To use it you need to execute dasmdir.py on the binary file to produce disassembly, and you may run the batch script on it to get the immediate values filtered.

This is interesting. Here is an example of someone asking how to allocate memory at fixed address unintentionally making his software less secure.

December 11, 2013

Flash Player Unloading Vulnerability II

UPDATED 20/February 2014: This vulnerability is CVE-2013-5332 and technical details were publicly announced on 10th December 2013 after the vendor patch was released to end users. On 19th of February 2014 I unexpectedly received an e-mail from HackerOne saying "The Internet Bug Bounty has awarded you a $2000.00 bounty for Flash memory corruption vulnerability could lead to code execution".

Adobe has notified me that it addressed the Flash Player Unloading vulnerability I reported them earlier. The patch is now released to end users and the security bulletin is published which contains the nature of the vulnerability.

In this post, I describe the technical details of the vulnerability in the hope that software developers can learn from it.

In the Windows version of Safari, when a Flash file is opened, the browser initiates to load the Flash Player into the process address space. When the Flash file is no longer opened the browser initiates to unload the Flash Player.

The Flash Player can display a dialog box using MessageBox API. While the dialog box is active, an other thread can unload the Flash Player module from the address space. When the execution returns back from the MessageBox call to the Flash Player module, which is already unloaded, the instruction dereferences freed memory causing data execution prevention exception.

This is a use-after-free vulnerability and it is same in nature to the one I reported Adobe earlier however this time the vulnerability is triggered via a different code path. The crash state looks like below, and it suggests the issue is most likely exploitable for code execution.
(3860.37ec): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=523bb781 ebx=00000001 ecx=006f0d68 edx=00000000 esi=523bb781 edi=00000000
eip=523bb781 esp=001deb90 ebp=001debb8 iopl=0         nv up ei pl nz na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00210206
<Unloaded_NPSWF32_11_7_700_224.dll>+0x20b781:
523bb781 ??              ???
0:000> |.
.  0          id: 3860               attach    name: C:\Program Files (x86)\Safari\Apple Application Support\WebKit2WebProcess.exe
One possible fix would be to synchronize the DLL unloading thread with the code calling MessageBox.

The vulnerability I reported Adobe earlier is same in nature to this one. Also, if a developer purely adds a new MessageBox call he has a high probability to inherently create a new vulnerability that can be reached in the same way described in this post. Therefore, for Adobe, it would be beneficial to review the entire code base for unsafe dialog box calls.

Also, for Microsoft, hardening on OS level is worthy to consider which may involve to crash in a not exploitable manner when a bug is triggered. The problem looks to be more ubiquitous than the public vulnerability reports suggest. The approach to discover these issues is to identify dialog box and DLL unloading code fragments that can be manually attacked.

Since there may be many bugs that could end up dereferencing unloaded Flash Player, Mozilla long time back fixed the problem by permanently keeping the plugin in the memory in Firefox process.

I'm currently working on tools to identify attack surfaces. It involves to identify DLLs calling MessageBox, and identify ways to unload MessageBox DLLs from the process address space.

I created a sample implementation to represent the vulnerability including how the freed memory gets dereferenced. It is a good exercise for developers to think about how to make the code secure without removing the thread creation.
// This is the EXE file.
// Main thread loads the DLL file to call ShowMessageBox() export that calls MessageBox().
// Secondary thread frees DLL but the dialog box is still visible.
// When OK is clicked the freed memory is dereferenced.
#include <Windows.h>

static HMODULE handle;

DWORD WINAPI Thread(LPVOID lpParam)
{
   printf("[Thread] Waiting 5 seconds.\n");
   Sleep(5000);
   FreeLibrary(handle);
   printf("[Thread] FreeLibrary() called. Click OK to dereference freed memory.\n");
   return 0;
}

int _tmain(int argc, _TCHAR* argv[])
{
   typedef void (WINAPI *FUNC)(void);
   FUNC ShowMessageBox;

   handle = LoadLibrary(L"DialogDLL.dll");
   printf("LoadLibrary() called.\n");

   ShowMessageBox = (FUNC)GetProcAddress(handle, "ShowMessageBox");

   CreateThread(NULL, 0, Thread, NULL, NULL, NULL);
   printf("Thread created for FreeLibrary().\n");

   printf("MessageBox pops up.\n");
   ShowMessageBox();
   return 0;
}


// This is the DLL file.
// It has an export that calls MessageBox()
extern "C" __declspec( dllexport ) void ShowMessageBox();

void ShowMessageBox()
{
    MessageBox(NULL, L"...shown by the DLL that can be unloaded while this dialog box is still visible.\n\nThe unloaded DLL
can be dereferenced when OK is clicked.", L"This is a dialog box...", MB_OK);
}
The complete source code for Visual C++ 2010 can be downloaded from here. When executing the program it looks like below.

When OK is clicked the instruction dereferences freed memory.
Just a note that the control transfer instruction to dereference freed memory is not call that can be seen in v-table bugs but ret.
  This blog is written and maintained by Attila Suszter. Read in Feed Reader.