{
	"id": "6687840d-05ca-489f-bdc9-cedba45899e0",
	"created_at": "2026-04-06T00:16:57.228626Z",
	"updated_at": "2026-04-10T03:21:59.075587Z",
	"deleted_at": null,
	"sha1_hash": "3719b678ad2d5485ea41ee4efc0e44daf1dc0c6e",
	"title": "The COM Elevation Moniker - Win32 apps",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 91337,
	"plain_text": "The COM Elevation Moniker - Win32 apps\r\nBy stevewhims\r\nArchived: 2026-04-02 10:59:51 UTC\r\nThe COM elevation moniker allows applications that are running under user account control (UAC) to activate\r\nCOM classes with elevated privileges. For more information, see Focus on Least Privilege.\r\nWhen to Use the Elevation Moniker\r\nThe elevation moniker is used to activate a COM class to accomplish a specific and limited function that requires\r\nelevated privileges, such as changing the system date and time.\r\nElevation requires participation from both a COM class and its client. The COM class must be configured to\r\nsupport elevation by annotating its registry entry, as described in the Requirements section. The COM client must\r\nrequest elevation by using the elevation moniker.\r\nThe elevation moniker is not intended to provide application compatibility. For example, if you want to run a\r\nlegacy COM application such as WinWord as an elevated server, you should configure the COM client executable\r\nto require elevation, rather than activating the legacy application's class with the elevation moniker. When the\r\nelevated COM client calls CoCreateInstance using the legacy application's CLSID, the client's elevated state will\r\nflow to the server process.\r\nNot all COM functionality is compatible with elevation. The functionality that will not work includes:\r\nElevation does not flow from a client to a remote COM server. If a client activates a remote COM server\r\nwith the elevation moniker, the server will not be elevated, even if it supports elevation.\r\nIf an elevated COM class uses impersonation during a COM call, it might lose its elevated privileges\r\nduring the impersonation.\r\nIf an elevated COM server registers a class in the running object table (ROT), the class will not be\r\navailable to non-elevated clients.\r\nA process elevated by using the UAC mechanism does not load per-user classes during COM activations.\r\nFor COM applications, this means that the application's COM classes must be installed in the\r\nHKEY_LOCAL_MACHINE registry hive if the application is to be used both by non-privileged and\r\nprivileged accounts. The application's COM classes need only be installed in the HKEY_USERS hive if\r\nthe application is never used by privileged accounts.\r\nDrag and drop is not allowed from non-elevated to elevated applications.\r\nRequirements\r\nIn order to use the elevation moniker to activate a COM class, the class must be configured to run as the launching\r\nuser or the 'Activate as Activator' application identity. If the class is configured to run under any other identity, the\r\nhttps://msdn.microsoft.com/en-us/library/ms679687.aspx\r\nPage 1 of 8\n\nactivation returns the error CO_E_RUNAS_VALUE_MUST_BE_AAA.\r\nThe class must also be annotated with a \"friendly\" display name that is multilingual user interface (MUI)\r\ncompatible. This requires the following registry entry:\r\nHKEY_LOCAL_MACHINE\\Software\\Classes\\CLSID\r\n{CLSID}\r\nLocalizedString = displayName\r\nIf this entry is missing, the activation returns the error CO_E_MISSING_DISPLAYNAME. If the MUI file is\r\nmissing, the error code from the RegLoadMUIStringW function is returned.\r\nOptionally, to specify an application icon to be displayed by the UAC user interface, add the following registry\r\nkey:\r\nHKEY_LOCAL_MACHINE\\Software\\Classes\\CLSID\r\n{CLSID}\r\nElevation\r\nIconReference = applicationIcon\r\nIconReference uses the same format as LocalizedString:\r\n@pathtobinary,-resourcenumber\r\nIn addition, the COM component must be signed for the icon to be displayed.\r\nThe COM class must also be annotated as LUA-Enabled. This requires the following registry entry:\r\nHKEY_LOCAL_MACHINE\\Software\\Classes\\CLSID\r\n{CLSID}\r\nElevation\r\nEnabled = 1\r\nIf this entry is missing, then the activation returns the error CO_E_ELEVATION_DISABLED.\r\nNote that these entries must exist in the HKEY_LOCAL_MACHINE hive, not the HKEY_CURRENT_USER or\r\nHKEY_USERS hive. This prevents users from elevating COM classes that they did not also have the privileges to\r\nregister.\r\nThe Elevation Moniker and the Elevation UI\r\nIf the client is already elevated, using the elevation moniker will not cause the Elevation UI to display.\r\nHow to Use the Elevation Moniker\r\nhttps://msdn.microsoft.com/en-us/library/ms679687.aspx\r\nPage 2 of 8\n\nThe elevation moniker is a standard COM moniker, similar to the session, partition, or queue monikers. It directs\r\nan activation request to a specified server with the specified elevation level. The CLSID to be activated appears in\r\nthe moniker string.\r\nThe elevation moniker supports the following Run level tokens:\r\n1. Administrator\r\n2. Highest\r\nThe syntax for this is as follows:\r\nElevation:Administrator!new:{guid}\r\nElevation:Highest!new:{guid}\r\nThe preceding syntax uses the \"new\" moniker to return an instance of the COM class specified by guid. Note that\r\nthe \"new\" moniker internally uses the IClassFactory interface to obtain a class object and then calls\r\nIClassFactory::CreateInstance on it.\r\nThe elevation moniker can also be used to get a class object, which implements IClassFactory. The caller then\r\ncalls CreateInstance to get an object instance. The syntax for this is as follows:\r\nElevation:Administrator!clsid:{guid}\r\nSample code\r\nThe following code example shows how to use the elevation moniker. It assumes that you have already initialized\r\nCOM on the current thread.\r\nHRESULT CoCreateInstanceAsAdmin(HWND hwnd, REFCLSID rclsid, REFIID riid, __out void ** ppv)\r\n{\r\n BIND_OPTS3 bo;\r\n WCHAR wszCLSID[50];\r\n WCHAR wszMonikerName[300];\r\n StringFromGUID2(rclsid, wszCLSID, sizeof(wszCLSID)/sizeof(wszCLSID[0]));\r\n HRESULT hr = StringCchPrintf(wszMonikerName, sizeof(wszMonikerName)/sizeof(wszMonikerName[0]), L\"Elevation:A\r\n if (FAILED(hr))\r\n return hr;\r\n memset(\u0026bo, 0, sizeof(bo));\r\n bo.cbStruct = sizeof(bo);\r\n bo.hwnd = hwnd;\r\n bo.dwClassContext = CLSCTX_LOCAL_SERVER;\r\n return CoGetObject(wszMonikerName, \u0026bo, riid, ppv);\r\n}\r\nhttps://msdn.microsoft.com/en-us/library/ms679687.aspx\r\nPage 3 of 8\n\nBIND_OPTS3 is new in Windows Vista. It is derived from BIND_OPTS2.\r\nThe only addition is an HWND field, hwnd. This handle represents a window that becomes the owner of the\r\nElevation UI, if applicable.\r\nIf hwnd is NULL, COM will call GetActiveWindow to find a window handle associated with the current thread.\r\nThis case might occur if the client is a script, which cannot fill in a BIND_OPTS3 structure. In this case, COM\r\nwill try to use the window associated with the script thread.\r\nOver-The-Shoulder (OTS) Elevation\r\nOver-the-shoulder (OTS) elevation refers to the scenario in which a client runs a COM server with an\r\nadministrator's credentials rather than his or her own. (The term \"over the shoulder\" means that the administrator\r\nis watching over the client's shoulder as the client runs the server.)\r\nThis scenario might cause a problem for COM calls into the server, because the server might not call\r\nCoInitializeSecurity either explicitly (that is, programmatically) or implicitly (that is, declaratively, using the\r\nregistry). For such servers, COM computes a security descriptor that allows only SELF, SYSTEM, and\r\nBuiltin\\Administrators to makes COM calls into the server. This arrangement will not work in OTS scenarios.\r\nInstead, the server must call CoInitializeSecurity, either explicitly or implicitly, and specify an ACL that includes\r\nthe INTERACTIVE group SID and SYSTEM.\r\nThe following code example shows how to create a security descriptor (SD) with the INTERACTIVE group SID.\r\nBOOL GetAccessPermissionsForLUAServer(SECURITY_DESCRIPTOR **ppSD)\r\n{\r\n// Local call permissions to IU, SY\r\n LPWSTR lpszSDDL = L\"O:BAG:BAD:(A;;0x3;;;IU)(A;;0x3;;;SY)\";\r\n SECURITY_DESCRIPTOR *pSD;\r\n *ppSD = NULL;\r\n if (ConvertStringSecurityDescriptorToSecurityDescriptorW(lpszSDDL, SDDL_REVISION_1, (PSECURITY_DESCRIPTOR *)\r\n {\r\n *ppSD = pSD;\r\n return TRUE;\r\n }\r\n return FALSE;\r\n}\r\nThe following code example shows how to call CoInitializeSecurity implicitly with the SD from the previous\r\ncode example:\r\n// hKey is the HKCR\\AppID\\{GUID} key\r\nBOOL SetAccessPermissions(HKEY hkey, PSECURITY_DESCRIPTOR pSD)\r\nhttps://msdn.microsoft.com/en-us/library/ms679687.aspx\r\nPage 4 of 8\n\n{\r\n BOOL bResult = FALSE;\r\n DWORD dwLen = GetSecurityDescriptorLength(pSD);\r\n LONG lResult;\r\n lResult = RegSetValueExA(hkey,\r\n \"AccessPermission\",\r\n 0,\r\n REG_BINARY,\r\n (BYTE*)pSD,\r\n dwLen);\r\n if (lResult != ERROR_SUCCESS) goto done;\r\n bResult = TRUE;\r\ndone:\r\n return bResult;\r\n}\r\nThe following code example shows how to call CoInitializeSecurity explicitly with the above SD:\r\n// Absolute SD values\r\nPSECURITY_DESCRIPTOR pAbsSD = NULL;\r\nDWORD AbsSdSize = 0;\r\nPACL pAbsAcl = NULL;\r\nDWORD AbsAclSize = 0;\r\nPACL pAbsSacl = NULL;\r\nDWORD AbsSaclSize = 0;\r\nPSID pAbsOwner = NULL;\r\nDWORD AbsOwnerSize = 0;\r\nPSID pAbsGroup = NULL;\r\nDWORD AbsGroupSize = 0;\r\nMakeAbsoluteSD (\r\n pSD,\r\n pAbsSD,\r\n \u0026AbsSdSize,\r\n pAbsAcl,\r\n \u0026AbsAclSize,\r\n pAbsSacl,\r\n \u0026AbsSaclSize,\r\n pAbsOwner,\r\n \u0026AbsOwnerSize,\r\n pAbsGroup,\r\n \u0026AbsGroupSize\r\n);\r\nif (ERROR_INSUFFICIENT_BUFFER == GetLastError())\r\n{\r\nhttps://msdn.microsoft.com/en-us/library/ms679687.aspx\r\nPage 5 of 8\n\npAbsSD = (PSECURITY_DESCRIPTOR)LocalAlloc(LMEM_FIXED, AbsSdSize);\r\n pAbsAcl = (PACL)LocalAlloc(LMEM_FIXED, AbsAclSize);\r\n pAbsSacl = (PACL)LocalAlloc(LMEM_FIXED, AbsSaclSize);\r\n pAbsOwner = (PSID)LocalAlloc(LMEM_FIXED, AbsOwnerSize);\r\n pAbsGroup = (PSID)LocalAlloc(LMEM_FIXED, AbsGroupSize);\r\n if ( ! (pAbsSD \u0026\u0026 pAbsAcl \u0026\u0026 pAbsSacl \u0026\u0026 pAbsOwner \u0026\u0026 pAbsGroup))\r\n {\r\n hr = E_OUTOFMEMORY;\r\n goto Cleanup;\r\n }\r\n if ( ! MakeAbsoluteSD(\r\n pSD,\r\n pAbsSD,\r\n \u0026AbsSdSize,\r\n pAbsAcl,\r\n \u0026AbsAclSize,\r\n pAbsSacl,\r\n \u0026AbsSaclSize,\r\n pAbsOwner,\r\n \u0026AbsOwnerSize,\r\n pAbsGroup,\r\n \u0026AbsGroupSize\r\n ))\r\n {\r\n hr = HRESULT_FROM_WIN32(GetLastError());\r\n goto Cleanup;\r\n }\r\n}\r\nelse\r\n{\r\n hr = HRESULT_FROM_WIN32(GetLastError());\r\n goto Cleanup;\r\n}\r\n// Call CoInitializeSecurity .\r\nWindows Vista introduces the notion of mandatory access labels in security descriptors. The label dictates\r\nwhether clients can get execute access to a COM object. The label is specified in the system access control list\r\n(SACL) portion of the security descriptor. In Windows Vista, COM supports the\r\nSYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP label. SACLs in the COM permissions are ignored on\r\noperating systems prior to Windows Vista.\r\nAs of Windows Vista, dcomcnfg.exe does not support changing the integrity level (IL) in COM permissions. It\r\nmust be set programmatically.\r\nhttps://msdn.microsoft.com/en-us/library/ms679687.aspx\r\nPage 6 of 8\n\nThe following code example shows how to create a COM security descriptor with a label that allows\r\nlaunch/activation requests from all LOW IL clients. Note that the labels are valid for Launch/Activation and Call\r\npermissions. Thus, it is possible to write a COM server that disallows launch, activation or calls from clients with\r\na certain IL. For more information about integrity levels, see the section \"Understanding Windows Vista's Integrity\r\nMechanism\" in Understanding and Working in Protected Mode Internet Explorer.\r\nBOOL GetLaunchActPermissionsWithIL (SECURITY_DESCRIPTOR **ppSD)\r\n{\r\n// Allow World Local Launch/Activation permissions. Label the SD for LOW IL Execute UP\r\n LPWSTR lpszSDDL = L\"O:BAG:BAD:(A;;0xb;;;WD)S:(ML;;NX;;;LW)\";\r\n if (ConvertStringSecurityDescriptorToSecurityDescriptorW(lpszSDDL, SDDL_REVISION_1, (PSECURITY_DESCRIPTOR *)\r\n {\r\n *ppSD = pSD;\r\n return TRUE;\r\n }\r\n}\r\nBOOL SetLaunchActPermissions(HKEY hkey, PSECURITY_DESCRIPTOR pSD)\r\n{\r\n \r\n BOOL bResult = FALSE;\r\n DWORD dwLen = GetSecurityDescriptorLength(pSD);\r\n LONG lResult;\r\n lResult = RegSetValueExA(hkey,\r\n \"LaunchPermission\",\r\n 0,\r\n REG_BINARY,\r\n (BYTE*)pSD,\r\n dwLen);\r\n if (lResult != ERROR_SUCCESS) goto done;\r\n bResult = TRUE;\r\ndone:\r\n return bResult;\r\n};\r\nCoCreateInstance and Integrity Levels\r\nThe behavior of CoCreateInstance has changed in Windows Vista, to prevent Low IL clients from binding to\r\nCOM servers by default. The server must explicitly allow such bindings by specifying the SACL. The changes to\r\nCoCreateInstance are as follows:\r\n1. When launching a COM server process, the IL in the server process token is set to the client or server token\r\nIL, whichever is lower.\r\n2. By default, COM will prevent Low IL clients from binding to running instances of any COM servers. To\r\nallow the bind, a COM server's Launch/Activation security descriptor must contain a SACL that specifies\r\nhttps://msdn.microsoft.com/en-us/library/ms679687.aspx\r\nPage 7 of 8\n\nthe Low IL label (see the previous section for the sample code to create such a security descriptor).\r\nElevated Servers and ROT Registrations\r\nIf a COM server wishes to register in the running object table (ROT) and allow any client to access the\r\nregistration, it must use the ROTFLAGS_ALLOWANYCLIENT flag. An \"Activate As Activator\" COM server\r\ncannot specify ROTFLAGS_ALLOWANYCLIENT because the DCOM service control manager (DCOMSCM)\r\nenforces a spoof check against this flag. Therefore, in Windows Vista, COM adds support for a new registry entry\r\nthat allows the server to stipulate that its ROT registrations be made available to any client:\r\nHKEY_LOCAL_MACHINE\\Software\\Classes\\AppID\r\n{APPID}\r\nROTFlags\r\nThe only valid value for this REG_DWORD entry is:\r\nROTREGFLAGS_ALLOWANYCLIENT 0x1\r\nThe entry must exist in the HKEY_LOCAL_MACHINE hive.\r\nThis entry provides an \"Activate As Activator\" server with the same functionality that\r\nROTFLAGS_ALLOWANYCLIENT provides for a RunAs server.\r\nSecurity in COM\r\nUnderstanding and Working in Protected Mode Internet Explorer\r\nSource: https://msdn.microsoft.com/en-us/library/ms679687.aspx\r\nhttps://msdn.microsoft.com/en-us/library/ms679687.aspx\r\nPage 8 of 8",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"MITRE"
	],
	"references": [
		"https://msdn.microsoft.com/en-us/library/ms679687.aspx"
	],
	"report_names": [
		"ms679687.aspx"
	],
	"threat_actors": [],
	"ts_created_at": 1775434617,
	"ts_updated_at": 1775791319,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/3719b678ad2d5485ea41ee4efc0e44daf1dc0c6e.pdf",
		"text": "https://archive.orkl.eu/3719b678ad2d5485ea41ee4efc0e44daf1dc0c6e.txt",
		"img": "https://archive.orkl.eu/3719b678ad2d5485ea41ee4efc0e44daf1dc0c6e.jpg"
	}
}