Most laptops we come across in enterprise environments are loaded with software from different third-party vendors. Since a lot of the hardware components in laptops are from Intel, drivers and software services from Intel are a common sight in our engagements. In this post we document a Local Privilege Escalation bug we found in one of these services.
CVE-2019-0086 is found in Intel Dynamic Application Loader (DAL). DAL is a component of multiple Intel products and is responsible for loading signed Java code into a secure firmware-based environment. The Host Interface service is the layer between host applications and the DAL firmware component. On Windows it can be seen as the SYSTEM process jhi_service.exe. The service is found in a lot of default Windows installations from major hardware vendors as it is part of the Intel ME software package. The API available for the Host Interface service is presented over a local TCP port, requires no authentication and both the service and code to test the API is available on GitHub.
While the firmware aspect looks very interesting from a security viewpoint, the bug we found does not involve the firmware layer. Instead it is a simple example of the default inherited permissions in ProgramData causing problems during privileged file operations. We often find this kind of vulnerabilities by running Procmon while exercising whatever API is available to unprivileged users and looking for file operations by SYSTEM processes. While the bug could have been found with code review, Procmon can often reveal these issues much faster.
When the Host Interface service is asked to load a Java module into the firmware environment, a temporary copy of the module file is created in the folder “%ProgramData%\Intel\DAL\Applets”. This folder is writable by any user and the check if the Java module is properly signed is performed after the copy. These conditions line up perfectly for an attacker to use a symbolic link to redirect the write into another file. A lot of the tricks to exploit these situations have been found by James Forshaw and are well-documented several places.
In the following steps, we use a target called c:\windows\system32\target.dll. This file must be created by an administrative user first. In a real exploitation scenario, we will of course be using another existing DLL that will be loaded by a SYSTEM process later.
$filename = "C:\Windows\system32\target.dll" $file = [System.IO.File]::Open($filename, 'Open', 'Read' , 'ReadWrite')
createsymlink.exe "c:\programdata\intel\dal\applets\PENDING-D1DE41D82B844FeAA7FA1E4322F15DE1.dalp" "c:\windows\system32\target.dll"
After this, the file c:\windows\system32\target.dll should be a copy of your malicious DLL.
All of the used code from the downloaded applications can of course be compiled into a single executable.
The issue was reported in December 2018, and Intel issued an advisory and, I assume, a patched version on May 15 2019. I have not looked into their patch, but looking through the Github repository, a change was submitted already in January that addresses the issue.
As seen in the image above, the target folder of the privileged file operation is simply changed from %%ProgramData%%\Intel\DAL\Applets to %%LOCALAPPDATA%%\Intel\DAL\Applet. For the SYSTEM user, %LOCALAPPDATA% is expanded to “C:\Windows\System32\config\systemprofile\AppData\Local”, a folder not writable by unprivileged users.
I assume that the same change is present in the currently deployed version of the service.