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.