Tuesday, September 13, 2016

Announcing the Project Zero Prize

Posted by Natalie Silvanovich, Exploit Enthusiast

Despite the existence of vulnerability rewards programs at Google and other companies, many unique, high-quality security bugs have been discovered as a result of hacking contests. Hoping to continue the stream of great bugs, we’ve decided to start our own contest: The Project Zero Prize.

The goal of this contest is to find a vulnerability or bug chain that achieves remote code execution on multiple Android devices knowing only the devices’ phone number and email address. Successful submissions will be eligible for the following prizes.

First Prize

$200,000 USD, awarded to the first winning entry.   

Second Prize

$100,000 USD, awarded to the second winning entry.

Third Prize

At least $50,000 USD awarded by Android Security Rewards, awarded to additional winning entries.

In addition, participants who submit a winning entry will be invited to write a short technical report on their entry, which will be posted on the Project Zero Blog.

Contest Structure

This contest will be structured a bit differently than other contests. Instead of saving up bugs until there’s an entire bug chain, and then submitting it to the Project Zero Prize, participants are asked to report the bugs in the Android issue tracker. They can then be used as a part of submission by the participant any time during the six month contest period. Only the first person to file a bug can use it as a part of their submission, so file early and file often! Of course, any bugs that don’t end up being used in a submission will be considered for Android Security Rewards and any other rewards program at Google they might be eligible for after the contest has ended.

In addition, unlike other contests, the public sharing of vulnerabilities and exploits submitted is paramount. Participants will submit a full description of how their exploit works with their submission, which will eventually be published on the Project Zero blog. Every vulnerability and exploit technique used in each winning submission will be made public.


So why are we doing yet another hacking contest? Our main motivation is to gain information about how these bugs and exploits work. There are often rumours of remote Android exploits, but it’s fairly rare to see one in action. We’re hoping this contest will improve the public body of knowledge on these types of exploits. Hopefully this will teach us what components these issues can exist in, how security mitigations are bypassed and other information that could help protect against these types of bugs.

Also, we’re hoping to get dangerous bugs fixed so they don’t impact users. Contests often lead to types of bugs that are less commonly reported getting fixed, so we’re hoping this contest leads to at least a few bugs being fixed in Android.

Finally, we hope that this contest will give us another data point on the availability of these types of exploits. There is fairly limited public information about this subject, and we might be able to glean some useful data from the number of submissions. Of course, a contest can never truly replicate the market conditions within which vulnerabilities are bought and sold, but it still provides at least some interesting information.  If the first prize is won in thirty seconds, we learn something. If there are no submissions, we learn something. But we’re expecting we’ll get something in between.

Interested? See the full contest rules and frequently asked questions for more information, including how to submit. The contest starts today!

Happy Hunting!

Wednesday, September 7, 2016

Return to libstagefright: exploiting libutils on Android

Posted by Mark Brand, Invalidator of Unic�o�d�e

I’ve been investigating different fuzzing approaches on some Android devices recently, and this turned up the following rather interesting bug (CVE 2016-3861 fixed in the most recent Android Security Bulletin), deep in the bowels of the usermode Android system. It’s an extremely serious bug, since the vulnerable code path is accessible from many different attack vectors, and it can be leveraged both for remote code execution and for local privilege elevation into the highly privileged system_server selinux domain. I’m a big fan of single bug chains [1] [2].

The bug is quite straightforward, and since it’s quite readily fuzzable, it’s interesting that it’s been undiscovered for so long. The vulnerable code is in libutils, and is in the conversion between UTF16 and UTF8. This code is used in many places, including the android::String8(const android::String16&) constructor.

The Bug

There are two functions in libutils/Unicode.cpp that need to match up; the first, utf16_to_utf8_length is used to compute the size of buffer needed to hold the UTF8 string that will be the result of converting the source UTF16 string, and utf16_to_utf8 performs the conversion. These functions are intended to be used together, to first allocate a buffer of the required size and then convert, and so it is obviously important that they agree on how many bytes of output are needed…

So, there is obviously some difference in behaviour between the functions; and we can fairly easily construct some input that will produce different behaviour in each. If you can’t see one easily, try walking through the logic in each function with the input string:



This will be seen by utf16_to_utf8_length as a string consisting of two invalid surrogate pairs, requiring 0 bytes of output to encode.

(0xd801, 0xd802),  (0xdc03), (0x0000)

It will however be seen by utf16_to_utf8 as a string starting with an invalid surrogate pair, followed by a valid surrogate pair; which encodes to 4 bytes of output.

(0xd801, 0xd802), (0xd802, 0xdc03), (0x0000)

This gives quite a nice exploitation primitive; by creating a string containing valid UTF16, we can control the size of the allocation; and we control the size of the overflow, with the limitation that it must be a multiple of 4 bytes larger than the allocation. The only significant limitation is that the data that we overflow with needs to be valid UTF8, which will prove slightly annoying later on.

Attack Vectors

We need to identify a nice attack vector we can use to exploit this issue. Now, as I said earlier, this bug was found by fuzzing - can’t we just use the fuzz case? Well, it was found by fuzzing some OEM-specific code (the vendor isn’t relevant). We can find some core Android attack surface, and write an exploit that targets all Android devices instead.

The first nice place I found is the following piece of code (in Parcel.cpp), which is interesting because the generated code for every* system service on an Android device calls this function on every parcel it receives. So, this should give us a privilege escalation from the untrusted_app context into any binder service we fancy; there are plenty of choices, but since there are so many inside system_server, why go anywhere else?

* Except the service_manager implements this logic itself, and probably some OEMS are rolling their own, but to all intents and purposes, this statement is true.

Anyway, I wanted a remote exploit, and it seemed likely that this code was being called in other places that were accessible remotely; maybe WiFi or Bluetooth, or DNS? Anyway, I looked around a bit, but the most obvious places were usually using the (completely distinct) libcutils implementations, and it was all a bit frustrating. Then I remembered, of course, mediaserver!

Sure enough, in the processing of ID3 tags, we sometimes need to handle unicode conversions.

This is kind of convenient, since I’ve already done a lot of legwork understanding how to exploit libstagefright bugs. Producing a minimal crash PoC was straightforward, although slightly annoying since libstagefright doesn’t appear to parse the same ID3v2 format I found documentation for… The file is attached to the bug report, but it looks like this:

00000000: 0000 0014 6674 7970 6973 6f6d 0000 0001  ....ftypisom....
00000010: 6973 6f6d 0000 182f 7472 616b 0000 1827  isom.../trak...'
00000020: 4944 3332 4141 4141 4141 4944 3302 0200  ID32AAAAAAID3...
00000030: 0000 300f 5441 4c00 1809 0165 6e67 00fe  ..0.TAL....eng..
00000040: ff41 d841 d841 dc41 d841 d841 dc41 d841  .A.A.A.A.A.A.A.A
00001830: d841 d841 dc41 d841 d841 dc41 d841 d841  .A.A.A.A.A.A.A.A
00001840: dc00 00                                  ...

A very simple file; just enough to get an ID3 tag read and processed that will trigger a large overflow out of a very small allocation. I’ve highlighted the first instance of the bad UTF16 sequence that will trigger the overflow; this sequence is just repeated many many times.

Mitigating Mitigations

My previous stagefright exploit was very crude; I was lazy and the only reason that I was writing the exploit at all was that I couldn’t bear to have another person ask me if the bug was at all exploitable on the latest Android versions. I was happy to stop working the minute I had something that worked and was plausible; but it wasn’t up to the usual standards I hold myself to…

So, anyway, this time, with a better bug and with a few of the shortcuts I took previously mitigated in the latest Android versions, it’s time to return to stagefright and do things properly this time. There’s been a fair amount of additional work in the public building on my PoC exploit; one reliable exploit that I’ve seen privately, and the exploit by NorthBit detailed here.

I’m not going to go into any real detail on the heap-grooming used here in this blog post; it’s already going to be a long post… Hopefully the exploit code and a debugger can teach you everything you need to know; I think the previous post and papers on stagefright exploitation probably cover everything but the precise specifics in this case, so I’ll just outline the steps that the exploit takes instead.

First things first, we need to solve the ASLR problem. The technique I originally considered to do this was implemented already by NorthBit, using the metadata returned to the browser to construct an information leak; this seems to be the simplest way. Another possibility would be to corrupt the objects used for communication with the remote HTTP server; the mediaserver process makes HTTP requests to retrieve the media file, and we could perhaps modify the headers to leak information; but I did not follow this route.

I looked at using the metadata corruption technique they implemented, but it seemed somewhat impractical to me. Even if we can predict “fairly reliably” a safe address to read from, there is another issue - Android have enabled the ubsan integer-overflow checking in their libstagefright builds; and the duration field has several arithmetic operations performed on it; and if any of those operations overflow, we don’t just lose bits of information, we abort!

So, we can’t practically use the duration. There are two more fields that can be retrieved from Chrome; the width and height of the video. These fields fit our needs perfectly; they’re pointer-sized, and they’re inline in the heap allocation for the metadata. Let’s see how we can use them to get all the information we need.

Step 1 - Heap pointer leak

Our first step in bypassing ASLR is a partial bypass; we’d like to get data we control at an address that we know. We can do this using the video height to leak the address of some of the data parsed from our media file. For this, we need two things to line up nicely; the allocation that we will overflow out of needs to land directly in front of the SharedBuffer object that is providing the backing data store for the KeyedVector that stores the entries in the MetaData for one of our tracks.

The key realisation here is that the ‘hvcC’ chunks that I used in the heap groom for the previous exploit store a pointer to data we control inside the MetaData object; so by corrupting the backing vector we can instead make this pointer into the height of our video, letting us read it back from inside Chrome.

So, let’s attach a debugger to mediaserver and see what happens during the first part of the exploit.

So to leak the address of the allocation caused by the ‘hvcC’ chunk, we just need to use the overflow to move the height entry down by a row, so that the height is instead the pointer!

This value will then be handed back to Chrome as the height of the video, and we can read it back from javascript. This is a powerful primitive; and we’ll use this multiple times in the final exploit. First though, we just need to load this file repeatedly until we get an address that we can safely encode using UTF8; we’ll need a valid address that we can write using the overflow for the next step.

Step 2 - Module pointer leak

So, we have an address on the heap, next we need to leak the address of some executable code. This is going to be much more fiddly than the previous step; and we’ll actually have to trigger the same vulnerability twice in the same MP4 to achieve our goal.

If we look a bit more carefully at the object we are overflowing, another possibility opens up:

Instead of overwriting the contents of the SharedBuffer, we can corrupt the metadata and change the capacity of the SharedBuffer, so that it extends to include the next allocation as well. When more track information is parsed and stored in the MetaData object, the KeyedVector backing the MetaData will expect that it needs to resize the backing storage; and will request the SharedBuffer to allocate more data; the SharedBuffer will think it has plenty of space and just carry on.

So, as we know, we can only practically use this to leak things which are aligned in the last column of our hexdump; and this is not normally where we’d expect to find a vtable pointer; so we have to investigate the layout of all the objects we can create in the hope that we can find one that will place a useful pointer at an offset we can leak. As it happens, there is one such object; the SampleTable.

Allocating a SampleTable after the corrupted SharedBuffer will give us the following:

As you can see from the labels, there are a few things of note; the SampleTable vtable pointer is of no consequence to us - we can safely dispose of the SampleTable without calling any methods on it, just as long as we never decrement it’s refcount to 0; but the mWeakRefs pointer inherited from RefBase is a serious problem for us; this needs to be a pointer to somewhere that can be safely decremented and not result in a 0 refcount. Here’s where we will reuse the valid UTF8 pointer we leaked above.

Finally, we can see the target pointer; a vtable pointer in libmedia.so. It’s quite a long way down the allocation; and the number of entries in the KeyedVector is stored out-of-line; so we need to perform the following steps:

Here’s what everything looks like after the second overflow is completed;

There are a few bits of cleanup we need to do at the end of this file; adding a second sample table to the track prevents the other from being referenced, and then we need to add a couple of entries back to the MetaData to ensure the file finishes parsing correctly and the pointer we want will get returned to Chrome!

Step 3, 4, 5, 6 - An exercise for the reader

Well, we have two powerful primitives; the ability to leak the address of a block of data whose contents we control, and we know the base address of a relatively large and generously gadget-full module, libmedia.so. It’s no major stress from here to getting ROP execution in the mediaserver process using the same technique as my previous exploit; and from there to shellcode on Android M is simply a case of calling mprotect; which is even imported by libmedia.so. The provided exploit performs this on several recent Android versions for the Nexus 5x; and is both reliable and fast in my testing. It would also be possible to make the exploit faster by directly generating the exploit files in javascript, reducing the unnecessary network round-trips retrieving identical mp4 files. The exploit code is attached to the bug tracker here.

A slightly useful quirk that will make your ROPing life easier is the reference to mprotect in BnOMX::onTransact - it seems to be there for security reasons.

Final thoughts

I started working on this exploit on a build of the upcoming Android N release, and anyone sitting near my desk will testify to the increased aggravation this caused me. A lot of general hardening work has gone into N, and the results are impressive. That’s not to say that exploiting this bug was impossible on N - but a full chain would be significantly more complex. The initial steps to get control of the program are identical; the only significant change is that instead of mediaserver, the target process is a new one - mediaextractor, which runs in a more restrictive sandbox and no longer has the ‘execmem’ privilege, ruling out the mprotect route to shellcode, and meaning that a privilege elevation direct from ROP would be required.

A day or two later I had a fairly complicated self-modifying ROP chain to make the necessary C++ virtual calls to interact with other services from the new, heavily sandboxed, mediaextractor and I was ready to start working on the privilege elevation into system_server. However, every time I tested, attempts to lookup the system_server services failed - and looking in the logs I realised that I’d misunderstood the selinux policy. While the mediaextractor was allowed to make binder calls; it wasn’t permitted to lookup any other binder services! Privilege elevation on N would instead require exploiting an additional, distinct vulnerability.

As a sidenote - my original stagefright exploit used the fact that Chrome on Android provides the build-id in the useragent; an unnecessary weakness that makes fingerprinting versions from the browser completely trivial. It’s still a “feature” of the Android WebView and Chrome browser - hopefully this will be changed soon.

And like last time, new mitigations that could be set in place to make the Android exploitation process harder also came out of this research; and hopefully they’ll be making it into an Android release soon.

Tuesday, August 16, 2016

A Shadow of our Former Self

Posted by James Forshaw of Google Project Zero

“Necessity is the Mother of Invention” as it’s said, and this is no more true than when looking for and exploiting security vulnerabilities. When new exploit mitigations are introduced, either a way of bypassing the mitigation is needed or an alternative approach must be found. I’ve described in the past some of the fun tricks you could do with symbolic links on Windows, and also how Microsoft made them difficult to use from sandboxes. I wanted to a find a way to bypass these mitigations and in the process found a new technique introduced in Windows 8 to get back some symbolic link capability in sandboxes.

This post describes the exploitation technique which allowed me to recover some of the mitigated functionality to exploit file planting or TOCTOU attacks from a sandbox, how it could be used to exploit an example vulnerably CVE-2016-3219, and a quick overview of the fix Microsoft have introduced in MS16-092 to block the trick in a sandbox.

Shadow Object Directories

While I was delving deep into the object manager I noticed a new system call for creating object directories, NtCreateDirectoryObjectEx. Compared to the old NtCreateDirectoryObject system call the Ex variant took an additional two parameters, a HANDLE to a directory object and some additional flags. Curious about what the additional HANDLE was for I spent a short bit of time reverse engineering it resulting in the following:

NTSTATUS NtCreateDirectoryObjectEx(
   _Out_     PHANDLE Handle,
   _In_      ACCESS_MASK DesiredAccess,
   _In_      POBJECT_ATTRIBUTES ObjectAttributes,
   _In_opt_  HANDLE ShadowDirectoryHandle,
   _In_      ULONG Flags) {

 OBJECT_DIRECTORY* ShadowDirectory = nullptr;
 if (ShadowDirectoryHandle) {
       ObpDirectoryObjectType, &ShadowDirectory);
 OBJECT_DIRECTORY* NewDirectory = nullptr;
 ObCreateObject(ObpDirectoryObjectType, ObjectAttributes, &NewDirectory);    
 if (ShadowDirectory) {
   NewDirectory->ShadowDirectory = ShadowDirectory;

 // ...

This got me intrigued, what was the purpose of this Shadow Directory Handle? Was it even used? A quick way to find out is to just place a breakpoint on the function in a kernel debugger and see who’s calling it.

kd> bp nt!NtCreateDirectoryObjectEx
kd> g
... Wait some time
Breakpoint 1 hit
823a86b8 8bff            mov     edi,edi

kd> kc
00 nt!NtCreateDirectoryObjectEx
01 nt!KiSystemServicePostCall
02 ntdll!KiFastSystemCallRet
03 ntdll!NtCreateDirectoryObjectEx
04 KERNELBASE!BasepCreateLowBoxObjectDirectories
05 KERNELBASE!BasepCreateLowBox
06 KERNELBASE!CreateProcessInternalW
07 KERNELBASE!CreateProcessAsUserW

Interesting, seems like it’s something to do with Low Box/AppContainer process creation. Let’s look at the ShadowDirectoryHandle to see where it’s pointing to:

kd> !handle poi(@esp+10) 1
0264: Object: 8f33ef50  GrantedAccess: 00020003

kd> !object 8f33ef50 21
Object: 8f33ef50  Type: (84d4ccb8) Directory
   ObjectHeader: 8f33ef38 (new version)
   HandleCount: 12  PointerCount: 353
   Directory Object: 8f33e728  Name: \Sessions\1\BaseNamedObjects

So the shadow directory is pointing to our session’s BaseNamedObjects directory. Let’s see where it’s creating the new directory.

kd> !obja poi(@esp+c)
Obja +061be0b8 at 061be0b8:
Name is S-1-15-2-3624051433-2125758914-1423191267-1740899205-1073925389-...

kd> !handle poi(poi(@esp+c)+4) 2
0a8c: Object: 8f2362d8  GrantedAccess: 0000000f Entry: a74cf518

kd> !object 8f2362d8 21
Object: 8f2362d8  Type: (84d4ccb8) Directory
   ObjectHeader: 8f2362c0 (new version)
   HandleCount: 2  PointerCount: 39
   Directory Object: 8f33e728  Name: \Sessions\1\AppContainerNamedObjects

So that all correlates with the stack trace. We’re creating the Low Box object directories for an AppContainer process, and the shadow is pointing at the main session BaseNamedObjects. It would seem likely that this directory is used as a fallback if a resource can’t be found in the Low Box specific directory, to ensure global resources could be accessed between normal applications and the AppContainer process. This isn’t particularly surprising functionality, I’ve mentioned a number of times in the past that this is the same behaviour used for the per-user DOS device directory. To erase all doubt we can look at where this gets used, the handily named ObpGetShadowDirectory.

   return Directory->ShadowDirectory;
 DEVICE_MAP* device_map = Directory->DeviceMap;
 if (device_map)
   return device_map->GlobalDosDevicesDirectory;
 return nullptr;

Clearly this is a generalization of the original DOS devices fallback, in fact if you look at Windows 7 ObpGetShadowDirectory exists but it only returns the Global DOS devices directory. So the behaviour is going to be the same. When creating a new resource inside the directory it will write to the target directory (if it’s allowed by the DACL of course) even if there exists the same object in the shadow. When opening a resource it will first lookup the name in the directory, if it’s not found it will look into the shadow instead.

Shadow Directories (2).png

Ultimately we can abuse this to create object directory symbolic links. Even more importantly if we look back at the implementation of NtCreateDirectoryObjectEx we’ll notice it only requests read permissions on the shadow directory handle, this means we can point it almost anywhere in the object manager hierarchy.

There are some limitations to this technique however. First it requires that the resource be accessed by the privileged application using an object manager path. This isn’t usually a problem if you can specify a full path and the \\?\ prefix to escape into the object manager namespace. Secondly like with NTFS Mount Points you can use this to control the name of the final resource, you can only affect its lookup. So it’s not as good as the old symbolic links but you have to make do. Let’s see it in action to exploit CVE-2016-3219.

Double Trouble

The vulnerability is Issue 779 in the Project Zero issue tracker, and is an issue with the verification of a font path when the Windows 10 Custom Font Disable Mitigation Policy is enabled. This mitigation policy is supposed to block loading custom fonts into the kernel, which might have exploitable vulnerabilities. The offending code in the Win32k driver looks something like the following:

int WIN32K::bLoadFont(...) {
 int load_option = GetCurrentProcessFontLoadingOption();
 bool system_font = true;
 if (load_option) {
   HANDLE hFile = hGetHandleFromFilePath(FontPath);
   BOOL system_font = bIsFileInSystemFontsDir(hFile);
   if (!system_font) {
     if (load_option != CUSTOM_FONT_LOG_ONLY)
       return 0;
 // Reopen path here
 HANDLE hFont = hGetHandleFromFilePath(FontPath);
 // Map font as section

What this code does is open the path to the font file (which is provided verbatim by the user process). It then checks that the file is within the \Windows\Fonts path on the system drive by opening the path and querying the file object’s name. If this check passes it then closes the file handle. The code then reopens the original font path to pass it to the font processing code. There’s an obvious race between the font file path being checked and it being used as the actual file. As we can’t easily use other types of symbolic links we’ll exploit it using the directory shadows.

The key thing to understand about how to use the shadow directories to exploit TOCTOU vulnerabilities is the lookup order, namely that you can place an object in the top directory which aliases one in the shadow with no ill effect, however when you remove that object the lookup process will fall through to the shadow. So let’s say we want to construct a path such that when it’s first opened the kernel will open the file C:\Windows\Fonts\somefont.ttf but after the check it opens a totally unrelated font which is the one we control. Assuming we can write to a path C:\ABC (it doesn’t need to be the root, but it makes our paths smaller for this example) we can construct something like the following:

Shadow Process.png

Notice we’ve got two shadow directories set up, both pointing to \Devices. The devices directory contains the device nodes for the hard drive volumes, for example in this case the C: drive is mapped to HarddiskVolume1. It’ll be important that we use paths with no special character such as a colon for reasons that we’ll see in a minute. Now we can request Win32k to load our font using our object manager path. The kernel will follow the hierarchy of object manager directories until it gets to ABC, at this point it tries to lookup HarddiskVolume1 but it doesn’t exist. It therefore falls back to the shadow. As the shadow does have HarddiskVolume1 it’s now finished and the kernel asks the file system to look up file \Windows\Fonts\somefont.ttf. This can be verified as being inside the Windows system fonts directory. Note that from the kernel’s perspective all the previous path information is lost when the file is opened. This ensures that when querying the name it only sees what we want it to see.

Now for the exploit. We can use an oplock on the system font file so we get signaled when Win32k is trying to open the file for its initial check. Again by this point the original path is lost and the file system driver is committed to opening the system font, so when we get signaled we can manipulate the object manager directory hierarchy to change which font is opened. In this case we can just delete the HarddiskVolume1 directory inside SWITCH. This results in the following:

Shadow Process - After Exploit.png

Now when the kernel looks up the path it reaches SWITCH but there’s no longer the HarddiskVolume1 directory to follow. So it’ll drop to looking in the shadow directory where it does indeed find a device with that name. This results in the kernel requesting the path \ABC\HarddiskVolume1\Windows\Fonts\somefont.ttf from the file system driver. This is clearly a different path and as we specified we control the directory \ABC we can build a chain of file system directories to satisfy the remaining path. This is why we had to avoid special characters. The colon can be used in NTFS to separate a stream name, however a stream name can’t contain backslashes.

The end result is the kernel opens a system font file to check whether it’s allowed to load the font but then opens a user controlled font when it goes to actually use it, this bypasses the process mitigation policy and it’s job done.

Behavioural Changes

In the July Updates Microsoft issued a fix, MS16-092, which blocked using these tricks to get privilege escalation from a sandbox. Like the fixes for the Object Manager symbolic links, shadow directories can still be created however a flag will be set if being created under a sandbox token which is checked when looking up the shadow directory. By doing this a privileged application (even if just normal user privilege) will not follow the shadow directory, in theory preventing this being abused.

                                       BOOLEAN InSandbox)
   if (!(Directory->Flags & DIRECTORY_FLAG_SANDBOX) || InSandbox)
     return Directory->ShadowDirectory;
 // ...

There’s no denying that a substantial amount of code went into Windows 8 to add support for AppContainers. While Microsoft’s SDL has gone some way towards eliminating common security mistakes (though clearly not as well as we’d like) it’s sometimes hard to fully understand the security implications of a decision until after it’s shipped. It’s understandable that when the shadow directories were designed there was no obvious security implication. It only became a problem after the other avenues of creating symbolic links in sandboxes were eliminated. There’s no good reason to use them to elevate privileges if you already have normal object manager symbolic links.