kevinmel2000 / google-security-research

Automatically exported from code.google.com/p/google-security-research
0 stars 0 forks source link

Adobe Reader: NtSetInformationFile Rename Check Bypass Elevation of Privilege #406

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
Adobe Reader: NtSetInformationFile Rename Check Bypass Elevation of Privilege
Platform: Windows
Version: Acrobat Reader DC 15.007.20033.2203 (11.X not tested)
Class: Elevation of Privilege

Summary:
The NtSetInformationFile hook in the Reader sandbox checks the source file 
handle against policy. It’s possible to bypass this check allowing a file 
hard link to be renamed into a permitted directory which can be used to elevate 
privileges. 

Description:

The NtSetInformationFile hook in the Reader sandbox performs two main checks on 
the arguments it’s passed from the sandboxed process. It verifies that write 
access it allowed to the destination path and that write access is also granted 
to the renaming file handle location. However the policy check for the file 
handle fails open, specifically if we can’t get the full path from the handle 
it will do the real NtSetInformationFile call anyway. The code is roughly:

if (get_handle_path(hFile, &path) && path.size() && !check_policy(path, 
GENERIC_WRITE)) {
    return ACCESS_DENIED;
} else {
   NtSetInformationFileReal(...);
}

The code which gets the full path uses the GetFinalPathNameByHandle API, if 
that API fails then the error will be propagated up the stack, causing the 
check to fail open. The trick therefore is find a way to cause the API call to 
fail. As we’re sharing the handle between the sandboxed and broker process 
one thing we can do is to rename the file, this in turn will change the path 
returned by the API. If we do the rename repeatedly we can cause the logic in 
the API to fail leading to an error being returned which will allow the check 
to be bypassed. There’s a second similar issue in the sandbox code itself. 
Even if the internals of the API don’t fail you can produce a similar effect 
by making a file longer than MAX_PATH, this bypasses an initial API call. The 
code will then allocate a larger buffer for the file path, if the size of the 
path changes between the two calls then this second call will also fail and the 
error will be returned.  Ultimately these calls can’t be trusted to work 
correctly and the sandbox should err on the side of caution and fail if it’s 
unable to get the path. 

You’d need to be able to get DELETE access to a file to rename and you’d 
also need to be able to add new directory entries to the rename location in 
order to perform the attack. Fortunately there’s a few places on a default 
install of Windows 8.1 which you can write to when running in the reader 
sandbox, such as C:\ProgramData\Microsoft\PlayReady. Of course this doesn’t 
seem immediately useful, what use is renaming a file you need to have write 
access to another location you also have write access via the broker? Well one 
thing you can do is create a hardlink to a file you have read access to but not 
write access. Contrary to the CreateHardlink API which requires the linked to 
file to be writable, you can create a link to a file with any access rights 
such as SYNCHRONIZE or READ_CONTROL. You can then rename the hard link to the 
destination folder and get the broker to open it for write access. This could 
be used for example write to an existing file in the reader Privileged 
directory which is normally Read Only which might facilitate an escape. As a 
hardlink isn’t a reparse point all checks will pass, the broker will believe 
the file exists in the target directory even though it’s cross-linked against 
another file. 

So to exploit this you perform the following operations:

1. Create a hard link in a directory that can be written to directly. 
2. Start a thread, renaming the file to two different length file names 
repeatedly. 
3. In another thread repeatedly call the NtSetInformationFile hook until 
successful.
4. The renamed file can now be written to using the broker. 

Proof of Concept:

1) Extract the PoC to a location on a local hard disk which is readable (but 
not writeable) by the sandboxed reader process (such as directory in the root 
of the drive)
2) Start Acrobat Reader and find the PID of the AcroRd32.exe sandboxed process
3) Run injectdll <PID> example.dll from the command prompt
4) You should find a file, test.txt in %TEMP%\acrord32_sbx which links to the 
example.txt in the poc folder with specific contents. 

Expected Result:
The NtSetInformationFile call in the broker should fail with 
STATUS_ACCESS_DENIED.

Observed Result:
The rename succeeds.

This bug is subject to a 90 day disclosure deadline. If 90 days elapse
without a broadly available patch, then the bug report will automatically
become visible to the public.

Original issue reported on code.google.com by fors...@google.com on 22 May 2015 at 1:09

Attachments:

GoogleCodeExporter commented 8 years ago

Original comment by fors...@google.com on 23 May 2015 at 9:00

GoogleCodeExporter commented 8 years ago

Original comment by cev...@google.com on 5 Jul 2015 at 4:58

GoogleCodeExporter commented 8 years ago
Fixed in https://helpx.adobe.com/security/products/acrobat/apsb15-15.html

Original comment by fors...@google.com on 14 Jul 2015 at 8:01

GoogleCodeExporter commented 8 years ago
Opening issue

Original comment by fors...@google.com on 22 Jul 2015 at 5:00