
Local Privilege Escalation in HP Support Assistant
A local privilege escalation bug in HP Support Assistant by abusing hard link
Researcher: ManhNDd of Bkav
In HP Support Assistant GUI, when you click Check for updates and messages, the service HP Support Solution Framework will run some tasks, start HPSAObjUtil8.exe (run as SYSTEM) which changes the permission of all .xml files in C:\ProgramData\Hewlett-Packard\HP Support Framework\Logs\Temp\HPSA. In detail, HPSAObjUtil8.exe gives full controls over these .xml files to all users. Following is the vulnerable code in HPSAObjUtil8:
public static void AddTempLogsPermission()
{
string path = Environment.GetEnvironmentVariable("ProgramData") + "\\Hewlett-Packard\\HP Support Framework\\Logs\\Temp\\HPSA";
if (Directory.Exists(path))
{
string[] files = Directory.GetFiles(path, "*.xml");
if (files != null && files.Length != 0)
{
foreach (string fileOrFolderName in files)
{
Patches._utils.AddFileSecurity(fileOrFolderName);
}
}
}
}
A user can create a hardlink with name ???.xml in the folder C:\ProgramData\Hewlett-Packard\HP Support Framework\Logs\Temp\HPSA, and point it to a victim file of our choosing (all we need is read access), then let HPSAObjUtil8 modifies the permissions of it so that we have full permissions over the file (read/write/delete). So this bug allow us to get full permissions over system files => you can overwrite a system DLL to get system privileges. By the way, the CVSS 3.0 score of the bug sets Privileges Required High. This should be None, because I tested the bug successfully on non-admin user.
By reversing HPSF.exe and HPSupportSolutionsFrameworkService.exe, I figure out that the client HPSF.exe communicates with the service through the interface HP.SupportFramework.ServiceManager.Interfaces.IServiceInterface (defined in HP.SupportFramework.ServiceManager.dll). If the client calls the method IserviceInterface.RunAnalysis, the service will start HPSAObjUtil8 and trigger the bug.
ServiceInterface.Instance.RunAnalysis("en-US", true);
So you have to create a fake client and call RunAnalysis. However, the service validates its client before processing the request:
{
Process processById = Process.GetProcessById(\u0002);
string text = \u000E.\u0001(processById);
if (processById.MainModule.FileName.ToLowerInvariant() != text.ToLowerInvariant())
{
if (DebugLog.IsDebug)
{
DebugLog.LogDebugMessage("Invalid File detected: " + text, DebugLog.IndentType.None);
}
return false;
}
Process parent = processById.GetParent();
bool flag = true;
int num = 0;
while (parent != null && flag && num <= 5)
{
bool flag2;
flag = \u000E.\u0001(parent, out flag2);
if (!flag || flag2)
{
break;
}
num++;
parent = parent.GetParent();
}
return flag;
}
Let's bypass the client validation:
Now you need to find out an executable that can be the target for the hardlink. It should be an EXE or DLL that will be run as SYSTEM automatically some time, so that when you overwrite it, you get SYSTEM privileges. I see that when calling RunAnalysis, HPSupportSolutionsFrameworkService starts many processes as SYSTEM. You can overwrite those processes with your own executable. However, the service checks signatures of those EXEs before starting them, so you cannot create fake EXEs, but resort to DLLs loaded by those EXEs. There are many DLLs already loaded somewhere, and many .NET DLLs signature-checked before being loaded, so you cannot use them. Luckily, there are still some DLLs usable:
I tried to modify hputils64.dll and succeeded. I create a hardlink to hputils64.dll. When calling RunAnalysis, HPSAObjUtil8 changes the hputils64.dll's permissions, then a few seconds later Detect_BatteryFailure.exe starts (as LOCAL SYSTEM) and loads up hputils64.dll. Before hputils64 loaded, you can overwrite it, so that Detect_BatteryFailure.exe loads your malicious malicious DLL up and you finally get the SYSTEM right.
To write the exploit, I created:
The following is the exploitation steps in PrivHP4.py:
To test the PoC, just clone the repository and run PrivHP4.py.