Privilege Escalation vulnerability in CrashPlan

CVE-2019-11552

Posted by Vetle Økland on Fri, Jun 21, 2019
In Bug Hunting
Tags pentesting, hacking, windows, crashplan, exploit, cve, privesc

Recently, I enountered a vulnerability in the CrashPlan clients for Windows, Mac (and possibly Linux, but I didn’t bother to test it there) that allows for privilege escalation.

The vulnerability is in the handling of Proxy Auto-Config (PAC) files. PAC-files are used for automatic proxy-configuration and is widely deployed in various software and operating systems. In short, PAC-files are JavaScript-files with a function whose return-value dictates the URL to the relevant proxy server. In CrashPlan, the JavaScript runtime, Rhino, allow for bridging JavaScript into Java, or “Scripting Java” as Mozilla calls it. Ultimately, this means that if we introduce a line of code into this file with new java.lang.ProcessBuilder["(java.lang.String[])"](["cmd.exe"], ["/c \"SomeCommand\""]).start(); we can execute arbitrary commands in the context of CrashPlan’s service, which is running as SYSTEM.

Exploitation

This vulnerability can be exploited from any user on the system, regardless of weather that user has CrashPlan configured or not. I will explain step-by-step how to exploit it on a limited user without CrashPlan configured. The flow of this exploit resets the CrashPlan configuration to factory defaults.

This is a PoC for Windows, exploitation on macOS and Linux will differ in implementation, but the techniques are the same.

Creating the PAC-file

First of all, we need to create a PAC-file that will somehow elevate our privileges. I chose to execute the command net localgroup Administrators limited /add which will add user limited to the Administrators group. Contents of PAC-file will thus be:

function FindProxyForURL(url, host) {
    new java.lang.ProcessBuilder["(java.lang.String[])"](["cmd.exe"], ["/c \"net localgroup Administrators limited /add\""]).start();

    return "DIRECT";
}

In PAC-files the FindProxyForURL-function will automatically be called when the process is trying to automatically configure proxy. As CrashPlan is using Mozilla’s Rhino JavaScript runtime/interpreter, we can tie (or bridge) native Java code. Since Rhino is automatically exposing most Java classes to us, we can just call ProcessBuilder. In this case we’re adding our user limited to the Administrators-group.

Getting CrashPlan to load the file

Users logged in to the CrashPlan desktop UI can configure a custom URL to load PAC-files from, but unauthenticated users can not. Thus, if you have CrashPlan installed and you’re authenticated to the desktop UI, you can set the PAC-URL to any path with your exploit code, local or remote, skipping any other potential necessary steps.

By default, CrashPlan attempts to load the PAC-file from C:\ProgramData\CrashPlan\conf\service.pac. This path is writable for any user on the system, thus if the file does not exist already we can create that file. Then, next time CrashPlan attempts to load this file it will execute our code. Normally, CrashPlan does not attempt to load this file very often, it seems to be at certain checkpoints or when the service is initially loaded.

Forcing CrashPlan to load the file

Forcing a restart of the system would make CrashPlan reload the file (limited users can’t reload the service, so a system restart would force the reload of the service), but not all systems allow for limited users to restart the machine. We’re not all out of luck though, because CrashPlan runs a Windows service as SYSTEM and a desktop UI client running as the current logged in user. For inter-process communication, the SYSTEM service runs a somwhat RESTful HTTPS server on localhost at port 4244. Through this RESTful API we are able to execute some commands.

The CrashPlan service API also does not allow unauthenticated users to restart the service, however at https://127.0.0.1:4244/v1/ResetService it does allow unauthorized users to reset the service to factory defaults. Right before resetting the settings, CrashPlan loads our PAC-file before it deletes it.

Also note that even if a file already exists at C:\ProgramData\CrashPlan\conf\service.pac, we can force CrashPlan to delete it and then we can create our file there again.

Timeline

April 1, 2019: Reported to CrashPlan.

April 4, 2019: CrashPlan has successfully reproduced the vulnerability and has started working on a remediation plan.

April 11, 2019: CrashPlan confirms they have a fix for the vulnerability and that it will be a part of next update (version 6.9.4)

April 16, 2019: Patched version 6.9.4 is released.

April 24, 2019: CrashPlan says they will backport the fix to the 6.8.x and 6.7.x clients, but this will take some extra time.

April 26, 2019: CrashPlan reports CVE-2019-11552 is reserved for this vulnerability.

May 24, 2019: CrashPlan confirms they have finished backporting the fixes to 6.8.x and 6.7.x.

Windows PoC Code

This PoC code will exploit CrashPlan < 9.6.4. Adds current user to local administrators group.