Friday, December 4, 2015

Between a Rock and a Hard Link

Posted by James Forshaw, File System Enthusiast

In a previous blog post I described some of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 changes that Microsoft has made to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 handling of symbolic links from a sandboxed process. This has an impact on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 exploitation of privileged file overwrites for sandbox escapes. Windows does support anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r method of linking files togecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r, Hard Links, which have some similar properties to file level symbolic links but also some downsides. Hard Links were not originally banned from a sandbox so given cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 right vulnerability we can still develop an exploit. Of course in some circumstances Hard Links can also be useful for exploiting some types of system level privilege escalation. This short blog post describes cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 pros and cons of Hard Links as an exploitation primitive and demonstrates its use in a real world vulnerability CVE-2015-4481. Also I’ll quickly show what’s changed after cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 MS15-115 update, which breaks cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 attack from a sandboxed context.

NTFS Hard Links

Hard Links, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ability to logically link a single file to multiple names on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same file system togecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r, has been a feature of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Windows NTFS file system since it was originally designed. It was most likely added for POSIX compatibility. In Windows 2000 cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 CreateHardlink API was introduced to allow a program to create cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se links in an official way from Windows applications.

Why are hard links useful for local privilege escalation? One type of vulnerability is exploited by a file planting attack, where a privilege service tries to write to a file in a known location. The most flexible approach is to use symbolic links but creating cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se for single files reliably is tricky, especially now in sandboxed applications. To create file symbolic links on Windows you eicá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r need to control cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 entire directory to apply a Mount Point or you need to be an administrator to set a file level symbolic link. When you’re exploiting file writes to an arbitrary directory such as C:\ProgramData this is probably not achievable and if you already have administrator privileges it doesn’t really matter. So having cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ability to drop a file which links to anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r file is a very useful primitive. If you can cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n get a privileged service to overwrite cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 target file it’ll cause corruption or in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ideal case privilege escalation.

Fortunately it looks like we don’t even need to write our own tool; since cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 release of Vista cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 command shell has an inbuilt command, MKLINK, which will create a hard link. All you need to do is pass cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 /H option. If we try and use this command we immediately come across a problem as shown in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following screenshot.

hardlink.PNG

We can create a link to a file we already control but we can’t create a link to a file we don’t have write access to. This completely removes any utility from a local EoP perspective, if we can only overwrite files we can already write to it isn’t much of a concern. We could stop right here and give up, but where’s cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 fun in that. First let’s look at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 actual implementation of CreateHardlink to see what privileges it’s asking for.

BOOL CreateHardLinkW(LPCWSTR lpFileName, LPCWSTR lpExistingFileName) {
 NTSTATUS status;
 OBJECT_ATTRIBUTES ObjectAttributes;  
 UNICODE_STRING ntname;
 UNICODE_STRING target;
 HANDLE FileHandle;

 if (!RtlDosPathNameToNtPathName_U(lpExistingFileName, &ntname))
   return FALSE;
 InitializeObjectAttributes(&ObjectAttributes, &ntname, ...);
 
 status = NtOpenFile(&FileHandle, SYNCHRONIZE | FILE_WRITE_ATTRIBUTES,
                 &ObjectAttributes, ...);
 if (status < 0)
   return FALSE;

 if (!RtlDosPathNameToNtPathName_U(lpFileName, &target))
   return FALSE;
     
 PFILE_LINK_INFORMATION LinkInfo = RtlAllocateHeap(target.Length + 16);
       
 memmove(LinkInfo->FileName, target.Buffer, target.Length);
 LinkInfo->ReplaceIfExisting = FALSE;
 LinkInfo->RootDirectory =  NULL;
 LinkInfo->FileNameLength = target.Length;
 status = NtSetInformationFile(FileHandle, LinkInfo,
             target.Length + 16, FileLinkInformation);
 if ( status < 0 )
   return FALSE;      
   
 return TRUE;
}

When cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 target file is opened cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 desired access is requesting FILE_WRITE_ATTRIBUTES, this kind of makes some sense, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re’s a hard link count in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 file’s directory entry so perhaps we need to write to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 target file entry in some way? Still what would happen if we just open cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 file for read, would it still work? As cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 call to ZwSetInformationFile with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 FileLinkInformation class is documented let’s just reimplement cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 function but not request write permissions when opening cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 linked to file.

Spoiler, if we try cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 new function it works without needing write access to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 target file. This makes it much more useful. Of course if we’d just looked at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel implementation we’d have seen that we didn’t need any specific access rights to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 file. In ZwSetInformationFile a call is made to ObReferenceObjectByHandle to get cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 underlying file object. This takes a desired access parameter, which turns out to be 0 for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 FileLinkInformation information class. We don’t need to hold any access on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 target file at all, we just need a handle to it with any assigned permissions.

Not every case of file overwrite vulnerabilities can be exploited using hard links. The Win32 and standard C library APIs don’t provide many options to prevent cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 attack outside of requiring that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 file doesn’t already exist. The MoveFile API is secure (as long as you don’t pass cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 MOVEFILE_COPY_ALLOWED flag to MoveFileEx which would simulate a copy operation) as it always replaces cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 file entry.

So cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 pros and cons of Hard Links are:

Pros

  • Can create a new hard link at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 file level without privileges even in sandboxes (well, originally).

Cons

  • Must have write access to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 directory where cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 hard link will be placed, can’t just do it from a handle
  • Can only overwrite existing files which you can open for access, can’t create new files
  • Can’t redirect a MoveFile operation (except cross drive), but can redirect CopyFile.
  • Can only link to files on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same volume
  • Can’t link directories to each ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r

I’ve added an implementation of this technique to my Symbolic Link Testing Tools suite available in Github here.

Quick Exploit, Mozilla Maintenance Service

Let’s see this in a real world exploit; you can read up on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 issue in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Project Zero bug tracker here. The vulnerability was in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Mozilla Maintenance Service, which is installed by default. This is a system service which allows Mozilla applications such as Firefox to update without needing administrator privileges. One interesting feature of this service is it can be started by any user on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 system and takes command line arguments to specify cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 update process. This is in contrast to similar services for ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r products, which typically automatically update via cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Internet without cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 user account being involved.

When an update process is started by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 user application cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 service writes out a status log to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 directory C:\ProgramData\Mozilla\logs under cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 name maintenanceservice.log. This is interesting as ProgramData’s default permissions allow a normal user to create new files in its subdirectories. There is a problem, however: if we look at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 permissions on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 logs directory (shown below), while any user can create a new file only cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 owner, through cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 CREATOR OWNER SID, gets permission to delete it. This means we can’t just delete cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 log file and replace it with a hard link as cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 owner is SYSTEM.

Log Security (1).png
Fortunately if we look at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 code cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re’s a window of opportunity, before creating cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 log file a call is made to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 BackupOldLogs function. This function moves each log file to a new numbered log, this ends up freeing up cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 initial log directory entry for a brief window of time as shown below.  

Log Rotation.png
As we can create a new file in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 directory we can replace cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 log file directory entry with a hard link to an existing file we want to overwrite. The service will cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n open and write to that file entry as SYSTEM, which means we can overwrite many files on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 system. While we can’t completely control 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 file that gets written, we can inject commands through cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 service’s command line (it doesn’t check for new-lines etc.). This at least gives us cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ability to cause a local DoS on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 system by overwriting a critical file, or we can replace certain script files such as Powershell modules, which could get executed in a privileged context and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 parser doesn’t care so much about garbage in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 file. Ultimately in this case cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 real issue was that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 user could write to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 log directory, and this was changed to writing logs into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 service’s program files directory instead.

So What’s Changed?

I was originally going to describe this trick as a replacement for Symbolic Links inside a sandbox in my 44con presentation on Windows 10 security. Microsoft requested I send cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 slides, which I did for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir own interest. After reviewing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y felt cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 fact that this was usable from a sandboxed context effectively gets around some of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 restrictions cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y were adding regards Symbolic Links so asked me to not present cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 information. While I’d publicly disclosed this technique in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Maintenance Service issue (as well as a vulnerability in Adobe Reader CVE-2015-4446) and so pointed out cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 information was already available I did agree to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 redaction with a promise cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y would fix it in a security bulletin.

That bulletin, MS15-115, came out in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 November patch releases and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 fix is referenced as CVE-2015-6113. The fix adds cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following code to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel’s NtSetInformationFile function.

ACCESS_MASK RequiredAccess = 0;

if (FileInformationClass == FileLinkInformation) {
 if (RtlIsSandboxedToken()) {
   RequiredAccess |= FILE_WRITE_ATTRIBUTES;
 }
}

// Will return STATUS_ACCESS_DENIED if we don't have access
ObReferenceObjectByHandle(FileHandle, RequiredAccess, ...);

This mitigates cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 issue in sandboxed processes as it now requires FILE_WRITE_ATTRIBUTES permission on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 file handle, which matches with what cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 CreateHardLink function expects. This would fix cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 vulnerability in Adobe Reader but would do nothing for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Maintenance Service vulnerability.

Conclusions

Hopefully this blog at least gives you an idea of how to use Hard Links on Windows. It should also give you an impression that you should never trust cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 documented interfaces for an operating system to behave as documented. This technique can be used to exploit local system services that try and write known files to directories cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 user can create files in, including things like ProgramData and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Windows Temp folder. Almost certainly cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re are ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r similar vulnerabilities that you could find.

It’s good to see MSRC again taking a practical approach to improving sandbox security by closing off known attack techniques. Keep looking for more changes that use cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 RtlIsSandboxedToken API as time goes on.