Docker Desktop Local Privilege Escalation (CVE-2020-10665)
Docker is a tool designed to make it easier to create, deploy, and run applications by using containers. Containers allow a developer to package an application with all of the parts it needs, such as libraries and dependencies, then deploy it as one package. By doing so, thanks to the container, the developer can rest assured that the application will run on any other machine regardless of any customized settings that machine might have which could differ from the machine used for writing and testing the code. Docker Desktop is used for building and sharing containerized applications and microservices for Mac and Windows machines.
During the process of analyzing the latest version of Docker Desktop for Windows at the time, we’ve found that the diagnostics functionality executes privileged operations under a folder that is controllable by standard users who are members of the docker-users group, leading to an arbitrary DACL permissions overwrite.
Let’s start by kicking off diagnostics data collection while Process Monitor is running in the background. Please note all of the below operations were performed under the NT AUTHORITY\SYSTEM context with no user impersonation.
1. com.docker.diagnose.exe process creates a Globally Unique Identifier (GUID) folder under the current logged-on user AppData folder. For those of you who don’t know, Windows applications often store their data and settings in an AppData folder, and each Windows user account has its own.
2. com.docker.diagnose.exe process creates a 14-digit zip file under the newly created folder with the following format <year><month><day><hour><minute><second>.zip.
3. com.docker.diagnose.exe process starts gathering diagnostics data and then writes the results to the zip file.
4. com.docker.diagnose.exe process finishes writing to the zip file and closes the handle to it.
5. com.docker.service process grants full control permissions for the everyone group to the zip file among other operations.
In essence, we have privileged processes that perform several operations on a file under a folder that is controllable by a standard non-privileged user, leading to an arbitrary DACL permissions overwrite. From a high-level overview, the following are the steps needed to exploit this vulnerability.
Start the diagnostics data collection to allow for the Globally Unique Identifier (GUID) folder creation.
Cancel the diagnostics data collection.
Although not required, delete all files under the newly created folder.
Perform hardlinks spraying where you have up to 1023 hardlinks targeting a system file of your liking (according to MSDN, the maximum number of hardlinks that can be created is 1023 per file. See the link here).
Start the diagnostics data collection again, the newly created zip file should match one of the hardlinks sprayed earlier.
Once the diagnostics data collection is finished (this may take a while) the everyone group should have full control over the target system file.
In our case, we’ve created 60 hardlinks (one per second) all pointing to C:\Windows\System32\DriverStore\FileRepository\prnms003.inf_amd64_e4ff50d4d5f8b2aa\Amd64\PrintConfig.dll system DLL (please be wary the file location may vary based on the Windows version). Once the permissions were modified, we used the method discovered by Andrea Pierini here to achieve elevation of privileges. It’s worth mentioning, that we can trigger the diagnostics data collection from the command line as mentioned in Docker documentation.
However, the process will run under the context of the invoking user which leaves us no choice other than using the GUI.
Please note that we need to wait a few minutes for the data collection to complete as mentioned in the exploitation steps above before DACL permissions overwrite takes place.
At this point, we reported the vulnerability to the Docker security team and the patch was released on March 13, 2020 addressing this vulnerability. Furthermore, Microsoft added hardlink mitigation to Windows 10 in the March cumulative update. After installing this update, Windows will require write access on the target file; otherwise, the hardlink will fail.
Lastly, we would like to thank Andrea Pierini, Ruben Boonen, and James Forshaw for their prior work and tools that made this finding possible. Feel free to reach out to labs@activecyber.us if you have any questions. Also, see the link here for a complete list of ACTIVELabs advisories.
Affected Products
Docker Desktop Enterprise before 2.1.0.9
Docker Desktop for Windows Stable before 2.2.0.4
Docker Desktop for Windows Edge before 2.2.2.0
Disclosure Timeline
02-03-20: ACTIVELabs contacted Docker via security@docker.com requesting PGP key
02-05-20: Docker security team provided PGP key
02-05-20: ACTIVELabs submitted vulnerability report and requested timeline for the patch
02-12-20: ACTIVELabs requested an update
02-12-20: Docker security team responded that they are investigating the issue still
02-27-20: ACTIVELabs requested an update
03-02-20: Docker Desktop for Windows Edge 2.2.2.0 was released
03-06-20: ACTIVELabs informed Docker security team that fully reliable exploit is now available and requested an update
03-06-20: Docker security team responded that patch was released in Desktop Edge releases and they are in the process of pushing it to stable releases
03-13-20: Docker Desktop Enterprise 2.1.0.9 and Docker Desktop for Windows Stable 2.2.0.4 was released
03-15-20: ACTIVELabs asked Docker security team whether an advisory can be made public at this point
03-18-20: Docker security team responded that we can proceed with publication
03-18-20: ACTIVELabs publishes an advisory
03-18-20: ACTIVELabs request CVE from MITRE
03-18-20: CVE-2020-10665 assigned
03-25-20: ACTIVELabs publishes this blog post