Tuesday, September 13, 2016

Announcing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Project Zero Prize

Posted by Natalie Silvanovich, Exploit Enthusiast


Despite cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 existence of vulnerability rewards programs at Google and ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r companies, many unique, high-quality security bugs have been discovered as a result of hacking contests. Hoping to continue cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 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 cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 devices’ phone number and email address. Successful submissions will be eligible for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following prizes.

First Prize

$200,000 USD, awarded to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 first winning entry.   

Second Prize

$100,000 USD, awarded to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 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 cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir entry, which will be posted on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Project Zero Blog.

Contest Structure


This contest will be structured a bit differently than ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r contests. Instead of saving up bugs until cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re’s an entire bug chain, and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n submitting it to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Project Zero Prize, participants are asked to report cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 bugs in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Android issue tracker. They can cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n be used as a part of submission by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 participant any time during cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 six month contest period. Only cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 first person to file a bug can use it as a part of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir 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 ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r rewards program at Google cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y might be eligible for after cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 contest has ended.

In addition, unlike ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r contests, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 public sharing of vulnerabilities and exploits submitted is paramount. Participants will submit a full description of how cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir exploit works with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir submission, which will eventually be published on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Project Zero blog. Every vulnerability and exploit technique used in each winning submission will be made public.

Motivation


So why are we doing yet anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r hacking contest? Our main motivation is to gain information about how cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se 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 cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 public body of knowledge on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se types of exploits. Hopefully this will teach us what components cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se issues can exist in, how security mitigations are bypassed and ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r information that could help protect against cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se types of bugs.

Also, we’re hoping to get dangerous bugs fixed so cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y 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 anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r data point on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 availability of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se types of exploits. There is fairly limited public information about this subject, and we might be able to glean some useful data from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 number of submissions. Of course, a contest can never truly replicate cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 market conditions within which vulnerabilities are bought and sold, but it still provides at least some interesting information.  If cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 first prize is won in thirty seconds, we learn something. If cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re are no submissions, we learn something. But we’re expecting we’ll get something in between.

Interested? See cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 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 cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following racá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r interesting bug (CVE 2016-3861 fixed in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 most recent Android Security Bulletin), deep in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 bowels of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 usermode Android system. It’s an extremely serious bug, since cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 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 cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 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 cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 conversion between UTF16 and UTF8. This code is used in many places, including cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 android::String8(const android::String16&) constructor.

The Bug

There are two functions in libutils/Unicode.cpp that need to match up; cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 first, utf16_to_utf8_length is used to compute cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 size of buffer needed to hold cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 UTF8 string that will be cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 result of converting cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 source UTF16 string, and utf16_to_utf8 performs cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 conversion. These functions are intended to be used togecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r, to first allocate a buffer of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 required size and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n convert, and so it is obviously important that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y agree on how many bytes of output are needed…

So, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re is obviously some difference in behaviour between cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 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 cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 logic in each function with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 input string:

‘\x01\xd8\x02\xd8\x03\xdc\x00\x00’

Selection_003.png

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 cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 size of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 allocation; and we control cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 size of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 overflow, with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 limitation that it must be a multiple of 4 bytes larger than cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 allocation. The only significant limitation is that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 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 cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 fuzz case? Well, it was found by fuzzing some OEM-specific code (cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 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 cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following piece of code (in Parcel.cpp), which is interesting because cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 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 cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 untrusted_app context into any binder service we fancy; cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re are plenty of choices, but since cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re are so many inside system_server, why go anywhere else?

* Except cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 service_manager implements this logic itself, and probably some OEMS are rolling cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir 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 ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r places that were accessible remotely; maybe WiFi or Bluetooth, or DNS? Anyway, I looked around a bit, but cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 most obvious places were usually using cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 (completely distinct) libcutils implementations, and it was all a bit frustrating. Then I remembered, of course, mediaserver!

Sure enough, in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 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 cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same ID3v2 format I found documentation for… The file is attached to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 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 cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 first instance of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 bad UTF16 sequence that will trigger cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 overflow; this sequence is just repeated many many times.

Mitigating Mitigations

My previous stagefright exploit was very crude; I was lazy and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 only reason that I was writing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 exploit at all was that I couldn’t bear to have anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r person ask me if cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 bug was at all exploitable on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 latest Android versions. I was happy to stop working cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 minute I had something that worked and was plausible; but it wasn’t up to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 usual standards I hold myself to…

So, anyway, this time, with a better bug and with a few of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 shortcuts I took previously mitigated in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 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 cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 public building on my PoC exploit; one reliable exploit that I’ve seen privately, and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 exploit by NorthBit detailed here.

I’m not going to go into any real detail on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 heap-grooming used here in this blog post; it’s already going to be a long post… Hopefully cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 exploit code and a debugger can teach you everything you need to know; I think cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 previous post and papers on stagefright exploitation probably cover everything but cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 precise specifics in this case, so I’ll just outline cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 steps that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 exploit takes instead.

First things first, we need to solve cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ASLR problem. The technique I originally considered to do this was implemented already by NorthBit, using cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 metadata returned to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 browser to construct an information leak; this seems to be cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 simplest way. Anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r possibility would be to corrupt cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 objects used for communication with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 remote HTTP server; cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 mediaserver process makes HTTP requests to retrieve cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 media file, and we could perhaps modify cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 headers to leak information; but I did not follow this route.

I looked at using cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 metadata corruption technique cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y implemented, but it seemed somewhat impractical to me. Even if we can predict “fairly reliably” a safe address to read from, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re is anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r issue - Android have enabled cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ubsan integer-overflow checking in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir libstagefright builds; and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 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 cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 duration. There are two more fields that can be retrieved from Chrome; cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 width and height of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 video. These fields fit our needs perfectly; cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y’re pointer-sized, and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y’re inline in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 heap allocation for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 metadata. Let’s see how we can use cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m to get all cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 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 cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 video height to leak cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 address of some of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 data parsed from our media file. For this, we need two things to line up nicely; cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 allocation that we will overflow out of needs to land directly in front of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 SharedBuffer object that is providing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 backing data store for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 KeyedVector that stores cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 entries in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 MetaData for one of our tracks.

The key realisation here is that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ‘hvcC’ chunks that I used in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 heap groom for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 previous exploit store a pointer to data we control inside cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 MetaData object; so by corrupting cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 backing vector we can instead make this pointer into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 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 cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 first part of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 exploit.



So to leak cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 address of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 allocation caused by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ‘hvcC’ chunk, we just need to use cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 overflow to move cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 height entry down by a row, so that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 height is instead cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 pointer!


This value will cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n be handed back to Chrome as cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 height of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 video, and we can read it back from javascript. This is a powerful primitive; and we’ll use this multiple times in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 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 cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 overflow for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 next step.

Step 2 - Module pointer leak

So, we have an address on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 heap, next we need to leak cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 address of some executable code. This is going to be much more fiddly than cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 previous step; and we’ll actually have to trigger cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same vulnerability twice in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same MP4 to achieve our goal.

If we look a bit more carefully at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 object we are overflowing, anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r possibility opens up:


Instead of overwriting cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 contents of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 SharedBuffer, we can corrupt cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 metadata and change cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 capacity of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 SharedBuffer, so that it extends to include cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 next allocation as well. When more track information is parsed and stored in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 MetaData object, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 KeyedVector backing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 MetaData will expect that it needs to resize cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 backing storage; and will request cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 SharedBuffer to allocate more data; cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 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 cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 last column of our hexdump; and this is not normally where we’d expect to find a vtable pointer; so we have to investigate cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 layout of all cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 objects we can create in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 hope that we can find one that will place a useful pointer at an offset we can leak. As it happens, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re is one such object; cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 SampleTable.

Allocating a SampleTable after cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 corrupted SharedBuffer will give us cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following:


As you can see from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 labels, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re are a few things of note; cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 SampleTable vtable pointer is of no consequence to us - we can safely dispose of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 SampleTable without calling any methods on it, just as long as we never decrement it’s refcount to 0; but cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 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 cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 valid UTF8 pointer we leaked above.

Finally, we can see cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 target pointer; a vtable pointer in libmedia.so. It’s quite a long way down cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 allocation; and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 number of entries in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 KeyedVector is stored out-of-line; so we need to perform cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following steps:




Here’s what everything looks like after cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 second overflow is completed;

There are a few bits of cleanup we need to do at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 end of this file; adding a second sample table to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 track prevents cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r from being referenced, and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n we need to add a couple of entries back to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 MetaData to ensure cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 file finishes parsing correctly and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 pointer we want will get returned to Chrome!

Step 3, 4, 5, 6 - An exercise for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 reader

Well, we have two powerful primitives; cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ability to leak cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 address of a block of data whose contents we control, and we know cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 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 cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 mediaserver process using cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same technique as my previous exploit; and from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re 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 cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Nexus 5x; and is both reliable and fast in my testing. It would also be possible to make cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 exploit faster by directly generating cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 exploit files in javascript, reducing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 unnecessary network round-trips retrieving identical mp4 files. The exploit code is attached to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 bug tracker here.

A slightly useful quirk that will make your ROPing life easier is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 reference to mprotect in BnOMX::onTransact - it seems to be cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re for security reasons.

Final thoughts

I started working on this exploit on a build of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 upcoming Android N release, and anyone sitting near my desk will testify to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 increased aggravation this caused me. A lot of general hardening work has gone into N, and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 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 cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 program are identical; cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 only significant change is that instead of mediaserver, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 target process is a new one - mediaextractor, which runs in a more restrictive sandbox and no longer has cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ‘execmem’ privilege, ruling out cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 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 cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 necessary C++ virtual calls to interact with ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r services from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 new, heavily sandboxed, mediaextractor and I was ready to start working on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 privilege elevation into system_server. However, every time I tested, attempts to lookup cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 system_server services failed - and looking in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 logs I realised that I’d misunderstood cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 selinux policy. While cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 mediaextractor was allowed to make binder calls; it wasn’t permitted to lookup any ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r binder services! Privilege elevation on N would instead require exploiting an additional, distinct vulnerability.

As a sidenote - my original stagefright exploit used cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 fact that Chrome on Android provides cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 build-id in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 useragent; an unnecessary weakness that makes fingerprinting versions from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 browser completely trivial. It’s still a “feature” of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 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 cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Android exploitation process harder also came out of this research; and hopefully cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y’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 cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Mocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r 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, eicá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r a way of bypassing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 mitigation is needed or an alternative approach must be found. I’ve described in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 past some of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 fun tricks you could do with symbolic links on Windows, and also how Microsoft made cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m difficult to use from sandboxes. I wanted to a find a way to bypass cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se mitigations and in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 process found a new technique introduced in Windows 8 to get back some symbolic link capability in sandboxes.


This post describes cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 exploitation technique which allowed me to recover some of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 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 cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 fix Microsoft have introduced in MS16-092 to block cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 trick in a sandbox.

Shadow Object Directories

While I was delving deep into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 object manager I noticed a new system call for creating object directories, NtCreateDirectoryObjectEx. Compared to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 old NtCreateDirectoryObject system call cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Ex variant took an additional two parameters, a HANDLE to a directory object and some additional flags. Curious about what cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 additional HANDLE was for I spent a short bit of time reverse engineering it resulting in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 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) {
   ObReferenceObjectByHandle(ShadowDirectoryHandle,
       DIRECTORY_QUERY | DIRECTORY_TRAVERSE,
       ObpDirectoryObjectType, &ShadowDirectory);
 }
 
 OBJECT_DIRECTORY* NewDirectory = nullptr;
 ObCreateObject(ObpDirectoryObjectType, ObjectAttributes, &NewDirectory);    
 if (ShadowDirectory) {
   NewDirectory->Flags = DIRECTORY_FLAG_SHADOW_PRESENT;
   NewDirectory->ShadowDirectory = ShadowDirectory;
 }

 // ...
}


This got me intrigued, what was cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 purpose of this Shadow Directory Handle? Was it even used? A quick way to find out is to just place a breakpoint on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 function in a kernel debugger and see who’s calling it.


kd> bp nt!NtCreateDirectoryObjectEx
kd> g
... Wait some time
Breakpoint 1 hit
nt!NtCreateDirectoryObjectEx:
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 cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 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 cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 shadow directory is pointing to our session’s BaseNamedObjects directory. Let’s see where it’s creating cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 new directory.


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


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 cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 stack trace. We’re creating cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Low Box object directories for an AppContainer process, and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 shadow is pointing at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 main session BaseNamedObjects. It would seem likely that this directory is used as a fallback if a resource can’t be found in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Low Box specific directory, to ensure global resources could be accessed between normal applications and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 AppContainer process. This isn’t particularly surprising functionality, I’ve mentioned a number of times in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 past that this is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same behaviour used for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 per-user DOS device directory. To erase all doubt we can look at where this gets used, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 handily named ObpGetShadowDirectory.


OBJECT_DIRECTORY* ObpGetShadowDirectory(OBJECT_DIRECTORY *Directory)
{
 if (Directory->Flags & DIRECTORY_FLAG_SHADOW_PRESENT)
   return Directory->ShadowDirectory;
 
 DEVICE_MAP* device_map = Directory->DeviceMap;
 if (device_map)
   return device_map->GlobalDosDevicesDirectory;
 
 return nullptr;
}


Clearly this is a generalization of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 original DOS devices fallback, in fact if you look at Windows 7 ObpGetShadowDirectory exists but it only returns cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Global DOS devices directory. So cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 behaviour is going to be cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same. When creating a new resource inside cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 directory it will write to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 target directory (if it’s allowed by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 DACL of course) even if cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re exists cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same object in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 shadow. When opening a resource it will first lookup cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 name in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 directory, if it’s not found it will look into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 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 cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 implementation of NtCreateDirectoryObjectEx we’ll notice it only requests read permissions on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 shadow directory handle, this means we can point it almost anywhere in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 object manager hierarchy.


There are some limitations to this technique however. First it requires that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 resource be accessed by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 privileged application using an object manager path. This isn’t usually a problem if you can specify a full path and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 \\?\ prefix to escape into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 object manager namespace. Secondly like with NTFS Mount Points you can use this to control cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 name of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 final resource, you can only affect its lookup. So it’s not as good as cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 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 cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Project Zero issue tracker, and is an issue with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 verification of a font path when cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Windows 10 Custom Font Disable Mitigation Policy is enabled. This mitigation policy is supposed to block loading custom fonts into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel, which might have exploitable vulnerabilities. The offending code in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Win32k driver looks something like cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following:


int WIN32K::bLoadFont(...) {
 int load_option = GetCurrentProcessFontLoadingOption();
 bool system_font = true;
 if (load_option) {
   HANDLE hFile = hGetHandleFromFilePath(FontPath);
   BOOL system_font = bIsFileInSystemFontsDir(hFile);
   ZwClose(hFile);
   if (!system_font) {
     LogFontLoadAttempt(FontPath);
     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 cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 path to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 font file (which is provided verbatim by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 user process). It cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n checks that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 file is within cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 \Windows\Fonts path on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 system drive by opening cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 path and querying cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 file object’s name. If this check passes it cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n closes cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 file handle. The code cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n reopens cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 original font path to pass it to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 font processing code. There’s an obvious race between cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 font file path being checked and it being used as cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 actual file. As we can’t easily use ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r types of symbolic links we’ll exploit it using cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 directory shadows.


The key thing to understand about how to use cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 shadow directories to exploit TOCTOU vulnerabilities is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 lookup order, namely that you can place an object in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 top directory which aliases one in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 shadow with no ill effect, however when you remove that object cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 lookup process will fall through to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 shadow. So let’s say we want to construct a path such that when it’s first opened cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel will open cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 file C:\Windows\Fonts\somefont.ttf but after cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 check it opens a totally unrelated font which is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 one we control. Assuming we can write to a path C:\ABC (it doesn’t need to be cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 root, but it makes our paths smaller for this example) we can construct something like cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following:


Shadow Process.png


Notice we’ve got two shadow directories set up, both pointing to \Devices. The devices directory contains cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 device nodes for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 hard drive volumes, for example in this case cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 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 cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 hierarchy of object manager directories until it gets to ABC, at this point it tries to lookup HarddiskVolume1 but it doesn’t exist. It cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365refore falls back to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 shadow. As cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 shadow does have HarddiskVolume1 it’s now finished and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel asks cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 file system to look up file \Windows\Fonts\somefont.ttf. This can be verified as being inside cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Windows system fonts directory. Note that from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel’s perspective all cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 previous path information is lost when cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 file is opened. This ensures that when querying cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 name it only sees what we want it to see.


Now for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 exploit. We can use an oplock on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 system font file so we get signaled when Win32k is trying to open cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 file for its initial check. Again by this point cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 original path is lost and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 file system driver is committed to opening cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 system font, so when we get signaled we can manipulate cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 object manager directory hierarchy to change which font is opened. In this case we can just delete cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 HarddiskVolume1 directory inside SWITCH. This results in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following:


Shadow Process - After Exploit.png


Now when cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel looks up cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 path it reaches SWITCH but cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re’s no longer cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 HarddiskVolume1 directory to follow. So it’ll drop to looking in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 shadow directory where it does indeed find a device with that name. This results in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel requesting cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 path \ABC\HarddiskVolume1\Windows\Fonts\somefont.ttf from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 file system driver. This is clearly a different path and as we specified we control cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 directory \ABC we can build a chain of file system directories to satisfy cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 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 cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel opens a system font file to check whecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r it’s allowed to load cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 font but cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n opens a user controlled font when it goes to actually use it, this bypasses cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 process mitigation policy and it’s job done.

Behavioural Changes

In cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 July Updates Microsoft issued a fix, MS16-092, which blocked using cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se tricks to get privilege escalation from a sandbox. Like cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 fixes for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 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 cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 shadow directory. By doing this a privileged application (even if just normal user privilege) will not follow cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 shadow directory, in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ory preventing this being abused.


OBJECT_DIRECTORY* ObpGetShadowDirectory(OBJECT_DIRECTORY *Directory,
                                       BOOLEAN InSandbox)
{
 if (Directory->Flags & DIRECTORY_FLAG_SHADOW_PRESENT)
   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 cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 security implications of a decision until after it’s shipped. It’s understandable that when cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 shadow directories were designed cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re was no obvious security implication. It only became a problem after cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r avenues of creating symbolic links in sandboxes were eliminated. There’s no good reason to use cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m to elevate privileges if you already have normal object manager symbolic links.