Search

The Key to COMpromise – Part 2

Search

The Key to COMpromise – Part 2

January 29, 2025

The Key to COMpromise - Abusing a TOCTOU race to gain SYSTEM, Part 2

Recap

In the first post of this blog series, we explored the architectural design of various security products and demonstrated how COM hijacking can be leveraged to exploit them: We examined a vulnerability that allowed us to replay a modified message over a named pipe, highlighting a potential attack vector.

As discussed previously, many security products have frontend processes operating in the context of an unprivileged user, which are capable of initiating privileged actions – such as adding exclusions  – by interacting with a backend service running at higher privileges. To prevent abuse, most vendors implement mechanisms to ensure these actions originate from trusted processes and take steps to protect those processes from tampering.

However, because frontend processes execute with limited user privileges, COM hijacking presents an opportunity to load a malicious DLL into the process. In our research, we found that this attack vector was viable across all the products we targeted, allowing us to exploit the security product’s inherent trust in its own processes.

To capitalize on this trust relationship, we needed to reverse engineer the communication protocols between the frontend and backend processes. This helped us identify interactions that could be manipulated to escalate privileges.

In this post, we will delve into how we exploited this trust in AVG Internet Security (CVE-2024-6510 ) to gain elevated privileges. But before that, the next section will detail how we overcame an allow-listing mechanism that initially disrupted our COM hijacking attempts.

Figure 1: User Interface of the AVG Internet Security Solution
Alain Rödel and Kolja Grassmann

Consultants

Category
Date
Navigation

Circumventing an allow list

For this part of our research, we employed the same basic technique as before, but with one key difference: this time, the COM interface was triggered each time we opened a file dialog to block an application. However, we encountered a restriction – we could not load our DLL from just any folder.

When trying to load the DLL from our custom folder at C:\poc, we could not observe any successful DLL load in the Process Monitor. In contrast, the original DLL path worked without issue.
Through trial and error, we discovered that placing our DLL in the  C:\Windows\system32 directory allowed it to load successfully. This behavior revealed that the product validates the DLL’s directory against an allow list, likely as a defense against DLL hijacking attacks.

While loading from C:\Windows\system32 bypassed the allow list, this approach was impractical for our privilege escalation since an unprivileged user cannot write to this directory. However, based on our prior experience bypassing AppLocker configurations, we knew that some subdirectories within C:\Windows\system32 were writable by unprivileged users. One such directory is C:\Windows\System32\spool\drivers\color. By placing the DLL used for the COM hijacking in this writable subdirectory, we successfully bypassed the allow list and achieved code execution in the frontend process.

Figure 2: Schematic ACLs on specific folders in SYSTEM32

With this DLL injection method established, the next step was to analyze the communication with backend processes. In the following section, we will discuss how we leveraged this primitive to manipulate the trust relationship and escalate privileges.

Reverse engineering the RPC communication

Reverse Engineering RPC communication can be a daunting task, especially in the beginning. Fortunately, tools like RpcView are invaluable for enumerating and identifying RPC interfaces. However, the process ultimately requires in-depth reverse engineering efforts. For our work with AVG, we used the excellent Akamai Research RPC Toolkit to identify and analyze various RPC interfaces across the different AVG binaries.

Our focus was on RPC server interfaces, as these are the endpoints exposed by high-privileged processes. While the AVGSvc.exe executable does not contain RPC server bindings, we found that the ashServ.dll DLL, which is loaded by the service, does expose such interfaces!

The Akamai RPC Toolkit produced the following output: 

"ashServ.dll": {
// [...]
"908d4c23-138f-4ac5-af4a-08584ae7c67b": {
"number_of_functions": 22,
"functions_pointers": [
"0x1654e0700",
"0x1654e0790",
// [...]
],
"role": "server",
"flags": "0x6000000",
"interface_address": "0x165f96020",
// [...]
"eb915940-6276-11d2-b8e7-006097c59f07": {
"number_of_functions": 106,
"functions_pointers": [
"0x1655c8180",
"0x1655c8290",
// [...]
"role": "server",
"flags": "0x6000000",
"interface_address": "0x165fca670"
},
"1118fbbd-02ee-4910-9d86-9940537ee146": {
"number_of_functions": 23,
"functions_pointers": [
"0x1655c08d0",
"0x1655c6be0",
// [...]
],
"role": "server",
"flags": "0x6000000",
"interface_address": "0x165fccfb0"
}

From this output, we can observe three major interfaces with 22, 106, and 23 exposed endpoints. The largest interface is the [Aavm] RPC interface, which has been the subject of previous research and exploitation. Searching the interface GUID on the web reveals some other interesting blog posts back in the year 2015.

Reverse engineering and renaming the functions within the RPC interface is tedious but relatively straightforward.

Figure 3: Some renamed RPC functions of the Aavm RPC interface

Through this analysis, we discovered an RPC function named AavmRpcRunSystemComponent that uses the CreateProcess API without RPC impersonation:

.rdata:0000000165FCA550 dq offset sub_1655C5580
.rdata:0000000165FCA558 dq offset sub_1655C55D0
.rdata:0000000165FCA560 dq offset AavmRpcRunSystemComponent
.rdata:0000000165FCA568 dq offset DecryptData
.rdata:0000000165FCA570 dq offset AddNetAlert

When the RPC client is not impersonated, any new process spawned through this function will run with SYSTEM privileges, creating a critical opportunity for privilege escalation. However, before this process is initiated, a DSA_FileVerify check takes place:

__int64 __fastcall AavmRpcRunSystemComponent(__int64 a1, unsigned int whitelist_id, __int64 arguments, DWORD *out_pid)
{
// [...]
char out_string[32];
// [...]
v8 = GetFileById(out_string, whitelist_id); // [1]
// [...]
FileW = CreateFileW((LPCWSTR)out_string, 0x80000000, 1u, 0i64, 3u, 0x8000000u, 0i64);
v12 = FileW;
v21 = (__int64)FileW;
if ( FileW == (HANDLE)-1i64 )
{
// file not found
}
if ( !GetFinalPathNameByHandleW(FileW, szFilePath, 0x104u, 0) )
{
// File path could not be resolved
}
if ( whitelist_id != 2 && !(unsigned __int8)DSA_FileVerify(szFilePath, 0i64, 18i64) ) // [2]
{
LastError = 87; // ERROR_INVALID_PARAMETER
CloseHandle(v12);
return LastError;
}
// [...]
snprintf(combined_arguments, v15, L"%s %s", szFilePath, arguments); // [3]
// [...]
if ( CreateProcessW(szFilePath, combined_arguments, 0i64, 0i64, 0, 0, 0i64, 0i64, &StartupInfo, &ProcessInformation) ) // [4]
{
// Win ?

The DSA_FileVerify function performs several validations:

  1. Based on the integer argument in [1], it returns a filename. Most of the executable files in this list are repair or setup tools, such as aswOfferTool.exe, SupportTool.exe and AvEmUpdate.exe, which limits the options to those predefined binaries.
  2. A file signature verification is performed in [2] to ensure only trusted binaries can be executed. This check prevents an attacker from inserting their own malicious binary into the process.
  3.  Finally, the program arguments are constructed in [3], and the process is created with SYSTEM privileges in [4].

Although this function appears to be a promising privilege escalation vector, the constraints of the allow-listed binaries and file signature verification present significant roadblocks. Without the ability to exploit any of the allow-listed programs, this avenue may seem like a dead end.

To overcome this limitation, we decided to experiment with the RPC client bindings found in the aavmrpch.dll library. Using this approach, we began testing the functionality of various RPC interfaces, with particular emphasis on the AavmRpcRunSystemComponent function, to explore potential exploitation paths.

Abusing the update mechanism

The most promising target for exploitation was the AvEmUpdate.exe executable, which accepts a range of command-line arguments. This executable is responsible for installing updates provided as cab or DLL files. Since we could control the arguments passed to it, this presented a compelling opportunity for further exploration.

One particularly interesting argument was /applydll, which allows the process to load a specified DLL. Crucially, because the process runs with SYSTEM privileges, this argument could potentially be abused to escalate privileges. However, the update mechanism includes an additional safeguard: it verifies that the provided DLL is signed by the manufacturer. This signature check prevented us from directly supplying a custom DLL to gain SYSTEM privileges.

TOCTOU race

Despite this limitation, we were confident that we could bypass the integrity check by carefully analyzing and exploiting the logic of the process. We finally found a time of use vs time of check (TOCTOU) issue in the logic, which made the integrity checks bypassable. To exploit this reliably, we employed a combination of OpLocks (opportunistic locks) and junctions.

To control the timing of the file accesses during exploitation and exploit our race reliably we needed a way to put the update process in a waiting state. Here we used OpLock to block access to the DLL file and force the update process to wait for us releasing the OpLock. This works even on processes running as SYSTEM, while operating as an unprivileged user. This gives us time to prepare for the next step.

We also want to be able to switch out the DLL file while holding our OpLock. This is where junctions come in. Junctions are symbolic links that can redirect file system access to a different location. Since an unprivileged user can create junctions, we used this capability to redirect file accesses during the exploitation process while holding our OpLock. We can point the junction to an other location for the next file access and there precisely control which file is accessed for each single file access. For more information on OpLocks and junctions, refer to the code provided by James Forshaw and this article from ZDI.

Here’s how the exploit worked:

  1. The AvEmUpdate.exe process made multiple file accesses before loading the DLL, likely to verify its legitimacy.
  2. Using a junction, we redirected the process to a valid, signed DLL for the first three file access attempts.
  3.  On the fourth file access, when the process attempted to load the DLL, we redirected the junction to our malicious DLL containing the privilege escalation payload.

Because we were holding an OpLock on the initial three file accesses, we could dynamically change the target of the junction while the SYSTEM process was waiting for access to the previous file. After updating the junction’s target, we released the OpLock, allowing the process to move on to the next file. We repeated this until the fourth access successfully loaded our malicious DLL.

Figure 4: Visualization of the junction redirects

Note that the process always accesses the same file; however, using the junction, we change the files accessible under this path.

While this technique successfully allowed us to bypass the signature verification and load our malicious DLL, it wasn’t sufficient on its own to fully escalate privileges. In the next section, we will delve into the additional steps required to achieve high privileges on the system and the challenges we encountered along the way.

Disabling self-defence

Even after successfully executing the TOCTOU (time-of-check-to-time-of-use) race, our malicious DLL was not loaded into the process. Upon further investigation, we discovered that the process only loaded DLLs with valid signatures. This added layer of protection significantly complicated our exploitation attempts. We suspect this behavior was due to the process being launched as a PPL (Protected Process Light) process.

After some trial and error, we found that this restriction was enforced only when the product’s self-protection feature was enabled. Fortunately, we identified an RPC function, AavmRpcDisableSelfDefense, that could disable this self-protection mechanism. This function was exported by the same DLL (ashServ.dll) we had already interacted with in our previous RPC calls. By calling this function, we successfully disabled the product’s self-defense feature.

With self-defense disabled, our malicious DLL was successfully loaded into the process running with SYSTEM privileges, finally completing the privilege escalation.

To summarize, the exploitation in this case worked as follows:

1. Initial entry with COM hijacking:

  • We used COM hijacking to load a DLL into the frontend process.
  • To bypass the allow-listing mechanism, the DLL was placed in C:\Windows\System32\spool\drivers\color

2. Disabling self-defense:

  •  The loaded DLL then called the function AavmRpcDisableSelfDefense to deactivate the product’s self-protection feature.

3. Triggering the update mechanism:

  •  The DLL triggered an update by calling AavmRpcRunSystemComponent.
  • Using a junction in combination with OpLocks, we tricked the update process into loading an unsigned DLL.
  • This allowed us to escalate our privileges to SYSTEM.

Summary

In this blog post, we demonstrated how COM hijacking was leveraged to gain SYSTEM privileges for exploiting AVG Internet Security to gain privileges. Unlike the previous case, we encountered additional obstacles, namely an allow-listing mechanism, that initially blocked our DLL. We described how we bypassed this restriction by placing the DLL in a writable system directory. We detailed our reverse engineering of the product’s RPC calls, which uncovered functions that allowed us to disable self-protection and trigger the update mechanism. By combining a junction and OpLocks, we bypassed the signature check and successfully loaded an unsigned DLL, enabling us to escalate privileges to SYSTEM.

In the next post, we will explore two additional vulnerabilities related to COM hijacking and describe how we exploited them to achieve privilege escalation.

This article was written as part of joint research with Neodyme.

Further blog articles

Command-and-Control

Beacon Object Files for Mythic – Part 3

December 4, 2025 – This is the third post in a series of blog posts on how we implemented support for Beacon Object Files (BOFs) into our own command and control (C2) beacon using the Mythic framework. In this final post, we will provide insights into the development of our BOF loader as implemented in our Mythic beacon. We will demonstrate how we used the experimental Mythic Forge to circumvent the dependency on Aggressor Script – a challenge that other C2 frameworks were unable to resolve this easily.

Author: Leon Schmidt

Mehr Infos »
Command-and-Control

Beacon Object Files for Mythic – Part 2

November 27, 2025 – This is the second post in a series of blog posts on how we implemented support for Beacon Object Files (BOFs) into our own command and control (C2) beacon using the Mythic framework. In this second post, we will present some concrete BOF implementations to show how they are used in the wild and how powerful they can be.

Author: Leon Schmidt

Mehr Infos »
Command-and-Control

Beacon Object Files for Mythic – Part 1

November 19, 2025 – This is the first post in a series of blog posts on how we implemented support for Beacon Object Files into our own command and control (C2) beacon using the Mythic framework. In this first post, we will take a look at what Beacon Object Files are, how they work and why they are valuable to us.

Author: Leon Schmidt

Mehr Infos »
Red Teaming

The Key to COMpromise – Part 2

January 29, 2025 – In this post, we will delve into how we exploited trust in AVG Internet Security (CVE-2024-6510) to gain elevated privileges.
But before that, the next section will detail how we overcame an allow-listing mechanism that initially disrupted our COM hijacking attempts.

Author: Alain Rödel and Kolja Grassmann

Mehr Infos »
Red Teaming

The Key to COMpromise – Part 1

January 15, 2025 – In this series of blog posts, we cover how we could exploit five reputable security products to gain SYSTEM privileges with COM hijacking. If you’ve never heard of this, no worries. We introduce all relevant background information, describe our approach to reverse engineering the products’ internals, and explain how we finally exploited the vulnerabilities. We hope to shed some light on this undervalued attack surface.

Author: Alain Rödel and Kolja Grassmann

Mehr Infos »
Blog

Loader Dev. 4 – AMSI and ETW

April 30, 2024 – In the last post, we discussed how we can get rid of any hooks placed into our process by an EDR solution. However, there are also other mechanisms provided by Windows, which could help to detect our payload. Two of these are ETW and AMSI.

Author: Kolja Grassmann

Mehr Infos »
Blog

Loader Dev. 1 – Basics

February 10, 2024 – This is the first post in a series of posts that will cover the development of a loader for evading AV and EDR solutions.

Author: Kolja Grassmann

Mehr Infos »
Do you want to protect your systems? Feel free to get in touch with us.

TLPT: Bedroh­ungs­­­orientierte Penetra­tions­tests nach DORA

Search

TLPT: Bedroh­ungs­­­orientierte Penetra­tions­tests nach DORA

January 24, 2025

TLPT: Bedrohungs­orientierte Penetrations­tests nach DORA

This blog post is written in German as it is very specific to the implementation of DORA and TLPT in Germany. A summary is provided in English.

Summary

Since January 17, 2025, the Digital Operational Resilience Act (DORA) has been put into practice. One important aspect of DORA is the requirement of regularly performing threat-led penetration tests (TLPT). Only selected entities within the financial sector are required to conduct TLPTs. Even though TLPTs sound like a new concept, they have actually existed in Germany since 2020 in form of TIBER tests. This blog post describes the concepts behind TLPTs and how they are conducted. Furthermore, alternatives for targeted and budget-oriented red team assessments are given.

Wen betreffen DORA und TLPT?

Am 17.01.2025 trat der Digital Operational Resilience Act (DORA) der Europäischen Union in Kraft. Die Verordnung hat das Ziel, die digitale operationale Resilienz im Finanzsektor sicherzustellen und zu stärken. Dadurch soll der europäische Finanzmarkt bestmöglich gegen Angriffe und Risiken in der IT‑ und Informationssicherheit geschützt werden. Nach Aussage der BaFin sind so gut wie alle beaufsichtigten Institute und Unternehmen im Finanzsektor regulatorisch betroffen (Quelle BaFin).

Ein wesentliches Instrument von DORA ist die Durchführung bedrohungsorientierter Penetrationstests, kurz TLPT. Diese Abkürzung leitet sich aus dem Englischen ab und steht für Threat-led Penetration Test. Während DORA nahezu alle Unternehmen im Finanzsektor betrifft, müssen längst nicht alle diese Unternehmen auch TLPTs durchführen. Ob ein Unternehmen zur Durchführung dieser erweiterten, bedrohungsorientierten Penetrationstests verpflichtet ist, entscheidet die zuständige Aufsichtsbehörde auf Basis der in DORA, Artikel 26 festgelegten Kriterien (siehe Verordnung der Europäischen Union) und informiert betroffene Unternehmen.

„Die BaFin wird diesen Identifikationsprozess Ende 2024/Anfang 2025 das erste Mal durchführen und dann regelmäßig wiederholen. Separat davon wird die BaFin in Abstimmung mit der Bundesbank die jeweiligen Institute und Unternehmen über den konkreten individuellen Testbeginn (Testanordnung) informieren.“, so die BaFin.

Neben potenziellen kritischen Auswirkungen auf systemrelevante Dienstleistungen des Unternehmens sowie den europäischen Finanzmarkt ist insbesondere auch der Reifegrad in der IT‑ und Informationssicherheit bei der Auswahl relevant.

Was versteckt sich hinter TLPT genau?

Regelmäßig führen meine Kollegen und ich Gespräche mit unseren Kunden aus dem Finanzsektor zum Thema TLPT. Die Kernfrage der Unternehmen ist dabei stets, was denn nun unter TLPT zu verstehen sei.

Im Grunde ist TLPT nichts Neues. Bereits seit 2020 begleitet die Deutsche Bundesbank die Durchführung von TIBER-DE-Projekten. TIBER-DE ist die Umsetzung von TIBER-EU für Deutschland. TIBER steht dabei für Threat Intelligence-based Ethical Red Teaming und stellt somit eine bedrohungsgetriebene Form eines Red-Team-Assessments dar.

Bei einem Red-Team-Assessment handelt es sich um einen ganzheitlichen Ansatz zur Überprüfung der IT‑ und Informationssicherheit. Dabei werden unterschiedliche Angriffsvektoren und ‑szenarien auf technischer, prozessualer und organisatorischer Ebene überprüft. Diese Überprüfung erfolgt durch die Simulation gezielter Angriffe mit aktuellen und relevanten Angriffstechniken.

Bei TIBER wird die Auswahl der Angriffsszenarien sowie der Taktiken, Techniken und Verfahren (aus dem Englischen Tactics, Techniques and Procedures – TTPs) durch unternehmensspezifische Threat Intelligence getrieben. Konkret bedeutet das, dass gezielt auf Basis der aktuellen Bedrohungslage des betroffenen Unternehmens Angreifergruppen mit ihren jeweiligen TTPs simuliert und so die Widerstandsfähigkeit des Unternehmens geprüft wird (siehe dazu Informationen der Deutschen Bundesbank). Dementsprechend stellt TIBER eine spezialisierte und bedrohungsorientierte Form von Red-Team-Assessments dar und steht als konkretes Rahmenwerk für die Projektdurchführung zur Verfügung (siehe Deutsche Bundesbank).

Ein TLPT im Rahmen von DORA baut laut der BaFin auf diesem Rahmenwerk auf und intensiviert die Zusammenarbeit zwischen der BaFin und der Deutschen Bundesbank (siehe dazu Informationen der BaFin). Gemäß der BaFin ändern sich lediglich „kleinere Details in der operativen Durchführung eines TLPT im Vergleich zu dem etablierten TIBER-DE Rahmenwerk“ (siehe Deutsche Bundesbank). Man kann also festhalten, dass ein TLPT im Wesentlichen ein TIBER-Test ist.

Wie bei TIBER-DE-Projekten ist auch bei TLPTs die Deutsche Bundesbank in die gesamte Projektdurchführung involviert. Sie unterstützt bei der Durchführung, überwacht deren Konformität und attestiert diese abschließend. Ohne eine Involvierung der Deutschen Bundesbank geht es also nicht.

Bereits aus dieser kompakten Beschreibung lässt sich erahnen, dass es sich bei einem TLPT nicht um einen alltäglichen Penetrationstest handelt. Die folgende Grafik der BaFin veranschaulicht dies:

Michael Brügge

Leitender Berater

Category
Date
Navigation
Abbildung 1: TLPTs als seltene, dafür spezialisierte Penetrationstests

Konkret fordert DORA die Durchführung eines TLPT in regelmäßigen Abständen von drei Jahren. Unternehmen, die in der Vergangenheit bereits freiwillig eine offizielle Überprüfung nach TIBER-DE durchgeführt haben, können sich diese entsprechend anrechnen lassen (siehe BaFin).

Wie läuft ein TLPT ab?

An der Durchführung eines TLPT sind unterschiedliche Akteure beteiligt. Diese Teams und ihre Rollen sind in der folgenden Grafik der BaFin dargestellt:

Abbildung 2: Involvierte Akteure eines TLPT

Da ein TLPT auf TIBER-DE aufsetzt, lässt sich der Ablauf eines TLPT-Projekts gut anhand von TIBER-DE erläutern. Grundsätzlich gliedert sich das Projekt in die folgenden drei Phasen:

  • Vorbereitungsphase
  • Testphase
  • Abschlussphase

Jede diese Phasen gliedert sich wiederum in mehrere Teilschritte und involviert verschiedene Akteure. Die folgende Grafik der BaFin skizziert den gesamten Ablauf eines TLPT:

Abbildung 3: Involvierte Akteure eines TLPT

Wie Abbildung 3 zu entnehmen ist, identifiziert die zuständige Finanzaufsicht betroffene Finanzunternehmen, legt die Testfrequenz fest und validiert den Testumfang. Anschließend sind die betroffenen Unternehmen dafür verantwortlich, die passenden Dienstleister für die Durchführung auszuwählen. Hier ist bewusst nicht nur von einem Dienstleister die Rede, da TIBER-DE eine strikte Trennung zwischen dem Threat-Intelligence-Provider und dem Red-Team-Provider vorsieht, das heißt die Sammlung von Informationen und die Durchführung des Red-Team-Assessments dürfen explizit nicht vom selben Personenkreis durchgeführt werden. Zwar ist es grundsätzlich möglich, hierfür nur einen Anbieter zu wählen, jedoch empfiehlt die Deutsche Bundesbank klar die Auswahl jeweils spezialisierter Dienstleister. Eine Liste attestierter TLPT- bzw. TIBER-Dienstleister gibt es für Deutschland übrigens bislang nicht (siehe BaFin). Unter bestimmten Voraussetzungen erlaubt DORA im Vergleich zu TIBER-DE die interne Durchführung (siehe Deutsche Bundesbank).

In der Testphase erfolgen anschließend zunächst die Sammlung von Informationen und die Ableitung bedrohungsorientierter Angriffsszenarien. Zu diesem Zweck wird sowohl die allgemeine Bedrohungslage für den Finanzsektor als auch unternehmensspezifische Bedrohungen betrachtet. Stellt sich dabei beispielsweise heraus, dass ein bestimmter Threat Actor derzeit verstärkt deutsche Finanzinstitute angreift und dazu Malware über Vishing-Angriffe verteilt, so spiegelt dies ein valides und bedrohungsorientiertes Szenario für den TLPT wider. Gemeinsam mit dem Unternehmen, dem Threat-Intelligence- und dem Red-Team-Provider sowie der Deutschen Bundesbank werden anschließend mehrere Szenarien ausgewählt und konkret definiert. Diese stellen die Ausgangslage für das Red-Team dar und legen die Taktiken, Techniken und Verfahren der simulierten Angreifer fest. Die gesamte Testphase erstreckt sich dabei auf ca. 18 Wochen, wobei auf die Durchführung der Angriffe ca. 12 Wochen entfallen.

Abschließend erfolgt die Berichtserstellung. Dabei ist wichtig zu beachten, dass nicht nur das Red-Team, sondern auch das Blue-Team des betroffenen Unternehmens seine Erkenntnisse entsprechend strukturiert niederschreibt. In anschließenden Replay- und Purple-Team-Workshops wird der gesamte Test noch einmal rekapituliert und es können mögliche „Was wäre, wenn“-Fragen geklärt werden. Diese Workshops sind erfahrungsgemäß für alle Beteiligten stets sehr aufschlussreich und liefern neben den Abschlussberichten tiefgreifende Erkenntnisse zu technischen, prozessualen und organisatorischen Defiziten. Zudem bietet ein derartiger Test eine gute Gelegenheit, die Erkennungs‑ und Reaktionsfähigkeiten des Blue-Teams zu testen und zu trainieren. Alle identifizierten Defizite werden abschließend in einem Behebungsplan adressiert und mit Verantwortlichkeiten versehen. Schlussendlich erfolgt die Attestierung der konformen Durchführung des TLPT durch die Deutsche Bundesbank und ca. 3 Jahre später beginnt das Ganze von vorn.

Sollten Sie zur Durchführung eines TLPT verpflichtet sein, sprechen Sie uns gern an. Als professioneller Anbieter für Red-Team-Assessments und Penetrationstests bieten wir auch die anforderungskonforme Durchführung von TLPTs und TIBER-Tests an. Weitere Informationen finden Sie unter https://cirosec.de/leistungen/red-team-assessments/.

Es muss nicht immer TLPT oder TIBER sein

Falls Ihr Unternehmen zur Durchführung eines TLPT verpflichtet ist, führt kein Weg an einer anforderungskonformen Umsetzung vorbei. In vielen Fällen sind Unternehmen des Finanzsektors jedoch gar nicht von der verpflichtenden Durchführung betroffen. Dann ist möglicherweise eine kompaktere Form eines Red-Team-Assessments sinnvoll.

Mit TIBER bzw. TLPT haben die BaFin und die Deutsche Bundesbank zwar ein wichtiges und konkretes Rahmenwerk für die Durchführung ganzheitlicher bedrohungsorientierter Penetrationstests geschaffen und durch die konkreten Vorgaben lassen sich die Projekte strukturiert und umfassend durchführen. Allerdings ist damit auch ein entsprechend hoher Aufwand verbunden, sowohl bei der notwendigen Anzahl von Personentagen für die externe Durchführung durch einen Threat-Intelligence- und Red-Team-Provider als auch für die notwendigen Eigenleistungen.

cirosec war in der Vergangenheit bereits maßgeblich in die Durchführung von TIBER-Tests involviert und hat daher nicht nur die notwendigen Skills als professioneller Red-Team-Anbieter, sondern kennt auch die damit verbundenen Aufwände. Insbesondere wenn ein Unternehmen nicht von der verpflichtenden Durchführung betroffen ist oder bislang noch keine Erfahrungen in der Durchführung klassischer Red-Team-Assessments gesammelt hat, kann ein kompakterer Ansatz hilfreich sein. Aus unzähligen Gesprächen mit unseren Kunden wissen wir, dass nicht jedes Unternehmen die Kapazitäten oder den notwendigen Reifegrad für ein derartiges Projekt hat. Es muss daher nicht immer TLPT oder TIBER sein.

Dennoch halten wir den Ansatz eines ganzheitlichen, bedrohungsorientierten Penetrationstests für enorm wichtig. Nur so lassen sich Zusammenhänge und übergreifende Risiken erkennen und anschließend adressieren. Als etablierter Anbieter für professionelle Red-Team-Assessments und Penetrationstests haben wir stets den Anspruch, unseren Kunden auf ihre konkreten Bedürfnisse abgestimmte Angebote zu unterbreiten. Aus diesem Grund gibt es bei cirosec nicht das eine Red-Team-Assessment. Stattdessen ermitteln wir gemeinsam mit unseren Kunden ein passendes Gesamtpaket, das die Motivation und die Projektziele des Kunden verfolgt, ins Budget passt und sich nach dem jeweiligen Reifegrad richtet. Insbesondere für Unternehmen, die in Zukunft potenziell von der verpflichtenden Durchführung von TLPTs betroffen sind, bieten kompaktere Formen eine gute Gelegenheit, erste Erfahrungen mit ganzheitlichen bedrohungsorientierten Penetrationstests zu sammeln.

Sprechen Sie uns daher gern an, wenn Sie einen kompetenten Partner für die Durchführung individueller Red-Team-Assessments oder eines standardisierten TLPT brauchen.

Further blog articles

Blog

Loader Dev. 4 – AMSI and ETW

April 30, 2024 – In the last post, we discussed how we can get rid of any hooks placed into our process by an EDR solution. However, there are also other mechanisms provided by Windows, which could help to detect our payload. Two of these are ETW and AMSI.

Author: Kolja Grassmann

Mehr Infos »
Blog

Loader Dev. 1 – Basics

February 10, 2024 – This is the first post in a series of posts that will cover the development of a loader for evading AV and EDR solutions.

Author: Kolja Grassmann

Mehr Infos »
Do you want to protect your systems? Feel free to get in touch with us.

The Key to COMpromise – Part 1

Search

The Key to COMpromise – Part 1

January 15, 2025

The Key to COMpromise - Pwning AVs and EDRs by Hijacking COM Interfaces, Part 1

Introduction

Antivirus (AV) and Endpoint Detection and Response (EDR) products are critical in securing systems in enterprise environments or personal setups. These products are designed to protect devices, but their widespread use – particularly in enterprises – means vulnerabilities in these products can significantly impact overall security. We previously analyzed Wazuh and found vulnerabilities that would have allowed lateral movement in the organization’s network. In this series, we will discuss how we identified vulnerabilities in multiple security products that could, in theory, allow privilege escalation to SYSTEM on millions of devices, assuming initial access was gained. We will introduce the general design of the targeted security products to give you some background information on the mechanisms that allowed us to escalate our privileges.

Technical Background

All the security products we examined include a user interface, which typically allows users to perform actions such as triggering filesystem scans, initiating updates, or modifying settings like excluded files. For example, setting an exclusion should require high privileges to prevent malware from excluding itself from scans. However, the user interface usually operates in the context of the user executing it. Especially in an enterprise setting, this user often lacks high privileges, as granting such privileges would violate good security practices.

How does a low-privileged user change settings?

Since the user interface cannot directly perform privileged actions, such as setting exclusions, a separate system process with higher privileges is required to execute these changes on behalf of the user interface. In our analysis, we will refer to: * The user interface as the front-end process. * The highly privileged system process as the back-end process.

To coordinate actions, the front-end process must communicate with the back-end process. Depending on the product, this communication occurs through named pipes, Remote Procedure Calls (RPC), or Component Object Model (COM) interfaces. Across all products we examined, the back-end process ran with SYSTEM privileges.

Security risks in back-end communication

A natural concern arises: Could malware abuse this communication to perform privileged actions? If malicious software could directly interact with the back-end process, it could exploit this pathway to, for example, modify the registry or other sensitive settings.

To mitigate this, security products typically verify that actions initiated by the back-end process originate from a trusted source. For example, they might check the signature of the executable initiating communication.

However, this safeguard is insufficient on its own, as Windows lacks strict boundaries between processes running under the same user account. A process can read or write to the memory of other processes in the same user context. It can even execute code within those processes. As a result, malware could potentially hijack a trusted process to abuse its connection with the back-end process.

Protections against code injection

To address this risk, security vendors implement additional protections to secure the front-end process:

  • Filter Drivers: These intercept system calls and prevent handles with privileges that could allow code injection from being created for the front-end process. This measure blocks many common code injection techniques, often relying on acquiring such handles.
  • DLL Allowlist Validation: During our testing, we observed measures that verify the location of loaded DLLs against an allowlist to prevent loading of untrusted DLLs.

These defences significantly reduce the risk of untrusted code injection.

Communication between front-end and back-end processes

The diagram below illustrates the components involved in the communication between front-end and back-end processes:

Figure 1: Overview of the components involved in typical communication between different processes of an EDR
Alain Rödel and Kolja Grassmann

Consultants

Category
Date
Navigation

Communication with the back-end process remains an attractive attack surface. For example, attackers could exploit it to trigger privileged actions, such as modifying the registry, from an unprivileged context. Manufacturers are aware of these risks and have implemented safeguards to prevent direct communication with the back-end process. However, previously discovered vulnerabilities, such as those in Avast [1,2], have demonstrated that bypassing these protections is possible.

Exploiting back-end communication

To abuse back-end communication, an attacker must first establish a way to interact with the back-end process. There are two primary approaches:

  • Exploit validation logic flaws: Identify weaknesses in the logic used by the back-end process to verify that requests originate from the front-end process.
  • Inject code into the front-end process: Attackers can indirectly communicate with the back-end process by executing code within the trusted front-end process.

In our research, we pursued the second approach. Using COM hijacking, we successfully injected code into the front-end process, enabling us to communicate with the back-end process from within the trusted front-end.

COM hijacking

Component Object Model (COM) interfaces provide additional functionality to applications, offering a framework for interprocess communication and object reuse. For instance, Windows Runtime (WinRT) is implemented based on COM. A key advantage of COM is its abstraction: developers using COM interfaces do not need to understand the underlying implementation, which could be written in another language, executed in a separate process, or even reside on a remote server in the case of Distributed COM (DCOM).

Some COM interfaces implement their functionality through DLLs that are dynamically loaded into the calling process when the interface is invoked. Hijacking such a COM interface allows injecting a custom DLL into the calling process, enabling code execution within the process’s context.

To use a COM interface the developer invokes the CoCreateInstance with a GUID, which then leads to a search of the right COM interface and returns a COM object if the interface is found. The following graphic gives a high level overview of how this could work for the TaskScheduler interface:

Figure 2: Example COM lookup of the ITaskScheduler COM object

The core idea of COM hijacking is to exploit the registry’s search order for COM interface definitions. When a COM interface is accessed, the system first looks for its definition in the HKEY_CURRENT_USER (HKCU) registry hive before checking the HKEY_LOCAL_MACHINE (HKLM) hive. If the COM interface uses a DLL to provide its functionality, the registry entry will include the path to the implementing DLL. Since the HKCU hive belongs to the current user, it can be modified by processes running with that user’s privileges. This means that any process running in the user’s context — including the front-end process of an EDR product running in the context of our unprivileged user — will prioritize COM definitions in the HKCU hive and stop searching once a match is found. The following diagram shows the registry accesses before and after a COM hijack:

Figure 3: Overview of the involved components

COM hijacking is most often discussed as a persistence technique. For instance, attackers could hijack a COM interface known to be invoked, ensuring their payload is executed. In our research, however, we employed COM hijacking differently. Rather than using it solely for persistence, we specifically targeted the front-end process of EDR products to load a custom DLL. This allowed us to execute code within the process context, leveraging the elevated privileges of the back-end process during communication. Interestingly, this approach proved effective against many EDR products. There was similar research in the past, which abused COM hijacking to bypass the self defense of similar products [5]. Futhermore James Forshaw previously demonstrated its use against VirtualBox [3].

In all the EDR products we examined, COM interfaces were used in the front-end process. Most of these interfaces were located under the HKLM hive, so there was no need to overwrite any data. However, overwriting an interface in the HKCU hive would also have been possible.

After hijacking a COM interface, every invocation of the targeted interface in the user’s context would trigger our hijacked COM interface. For our purposes, this enabled us to load our custom DLL into the front-end process whenever specific actions were performed, such as opening a file dialogue in the user interface.

Now that we have discussed COM-hijacking in theory, the next question is how we identified COM interfaces of interest within the front-end process.

Identifying a hijackable COM interface

The initial step in all the vulnerabilities we discovered involved achieving code execution in a front-end process via COM hijacking. As this was similar across all the products we analyzed, we will outline the general process here instead of repeating it for each specific product.

We can see that each COM lookup is performed via a GUID that matches to an CLSID (Class ID). Now we can hunt for those GUIDs and figure out what COM objects are used by the product.

For each product, the first task was to identify a COM Interface used by the front-end process.

This required considering several factors:

  • When is the COM interface invoked?
    • During the start of the UI
    • When entering a specific menu
  • Is the COM interface used by other processes?
    • To avoid unintended consequences (e.g., disrupting explorer.exe), we ensured the interface was unique to the target process or could be safely used in parallel.

We used the Process Monitor from the SysInternals suit to identify relevant COM interfaces. We first identified the process we wanted to target. Then, we used a filter to view only events triggered by this process. Next, we created a filter for registry events where the path contained CLSID and InProcServer32, indicating that the process tries to load a DLL used for a COM interface.

The following screenshot demonstrates how explorer.exe queries the relevant registry keys, providing insight into the COM interfaces it accesses:

Figure 4: Accesses to COM interfaces by explorer.exe

After identifying a potential COM interface, the next step was to confirm if the front-end process loaded the referenced DLL. We monitored file interactions and filtered paths containing the DLL name to do this. If the DLL was loaded, it would trigger a load event for the DLL specified in the registry:

Figure 5: Loading a DLL related to COM

Once a suitable interface was identified, the next step was to hijack it.

Hijacking a COM interface

One registry key we targeted across multiple products was:

Computer\\HKEY_LOCAL_MACHINE\\SOFTWARE\\Classes\\CLSID\\{9FC8E510-A27C-4B3B-B9A3-BF65F00256A8}

This COM interface loads the dataexchange.dll into the calling process.
To hijack the DLL, we first exported it:

reg export "HKLM\\SOFTWARE\\Classes\\CLSID\\{9FC8E510-A27C-4B3B-B9A3-BF65F00256A8}" .\export.reg /reg:64

Then, we opened the exported file export.reg in a text editor and changed the paths to HKEY_CURRENT_USER. We also changed the file path to point to our custom DLL:

Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\\SOFTWARE\\Classes\\CLSID\\{9FC8E510-A27C-4B3B-B9A3-BF65F00256A8}]

[HKEY_CURRENT_USER\\SOFTWARE\\Classes\\CLSID\\{9FC8E510-A27C-4B3B-B9A3-BF65F00256A8}\\InProcServer32]
@="C:\\\\poc\\\\dataxchange.dll"
"ThreadingModel"="Both"

Next, we imported the modified registry export:

reg import .\export.reg /reg:64

With these modifications, all calls to this COM interface from the context of our unprivileged user would invoke our custom DLL. This might lead to problems with other processes, so we should remove the hijack when we are done with exploitation.

Our DLL must export the functions the original COM DLL would expose to ensure smooth operation. This can be achieved by proxying calls to the original DLL using a template such as:

#include <windows.h>
#include <combaseapi.h>

#pragma comment( linker, "/export:DllGetClassObject" )

#define ORIGINAL_COM_DLL_PATH "C:\\Windows\\System32\\dataxchange.dll"

void Go(void) {
// Our payload
}

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;
}

typedef HRESULT(WINAPI * tDllGetClassObject)(REFCLSID rclsid, REFIID riid, LPVOID* ppv);

STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID FAR* ppv) {
// Start our payload
Go();

// Load the original DLL and proxy the function call to it
tDllGetClassObject pDllGetClassObject;
HMODULE hOrigDLL = LoadLibrary(ORIGINAL_COM_DLL_PATH);
pDllGetClassObject = (tDllGetClassObject) GetProcAddress(hOrigDLL, "DllGetClassObject");
if (!pDllGetClassObject)
return S_FALSE;

HRESULT hRes = pDllGetClassObject(rclsid, riid, ppv);

return hRes;
}

At this point, we achieved code execution in the context of the targeted product. So, the next step was to analyze the communication between the front-end and back-end processes for the specific product to get an idea of how to abuse this primitive.

Named pipe communication

Named pipes are a common method for communication between a server and one or more clients. They are accessible using a unique name (as the name suggests) and often serve as a communication channel between security products’ front-end and back-end processes.

Figure 6: Typical Named Pipe Communication via the WinAPI

We found that the easiest way to find out if a product uses named pipes was to use IONinja’s Pipe Monitor feature. For this, you click “New Session”, select “Pipe Monitor” and enable “Run as administrator”. You can click the “Capture” button in the top-right corner to start capturing named pipe traffic:

Figure 7: Starting IONinja
Figure 8: Listening to named pipes with IONinja

With this, you can interact with the product’s user interface to generate pipe traffic and watch for captured named pipe traffic that corresponds to the interaction. In our experience, there should be little named pipe communication on a vanilla system, so identifying the relevant communication should be straightforward if you have installed the product on a dedicated system.

Having identified the communication in IONinja, we have a pipe name and a process that opens the named pipe or writes to it. We now need to identify the logic. For this, we can look for strings beginning with \\.\pipe\, used when creating a named pipe. The logic that interacts with the named pipe will likely reference this string. You will also see calls to the CreateNamedPipe and ConnectNamedPipe functions.

For our initial target, all of this turned out to be unnecessary: When capturing data over a named pipe, we observed plaintext communication, including what appeared to be a registry key:

Figure 9: Registry path in named pipe traffic

The next section will detail how we exploited this communication to gain high privileges.

Replaying a recorded message

As shown in the screenshot above, the traffic on the named pipe for our first target contained a registry path and was not obfuscated. This message was sent every time we opened the front-end process.

Using Process Monitor, we observed that the back-end process accessed the registry key running as SYSTEM. This seemed promising, as writing a registry key as SYSTEM could lead to privilege escalation…

To test this theory, we implemented the following steps:

1. Prepare the Payload: We wrote a small program and converted it into shellcode using [donut](https://github.com/TheWover/donut).

2. Inject the Payload: Using our previously via COM hijacking loaded DLL, we injected the shellcode into the process. In the shellcode, we unloaded the DLL after a short sleep and then sent the modified data. This approach bypassed logic in the target process that appeared to validate loaded DLLs. Although we didn’t confirm whether bypassing this validation was essential, avoiding an unsigned DLL during communication helped minimize suspicion.

3. Initial Testing: To confirm our ability to replay the message, we modified the registry path in the recorded message. The modified path was successfully written to the registry:

Figure 10: Modified registry key written

We discovered that our ability to write registry keys was restricted to locations under the manufacturer’s designated registry path. This limitation prevented us from writing keys like RunOnce, which could enable privilege escalation.

However, we identified a promising registry key named Application Path. This key pointed to an application folder under C:\Program Files (x86). By modifying this path to one writable by us, we hypothesized that any high-privilege process loading from this path could execute our files, granting high privileges.

So, we modified the message again, choosing a path that would fit into the message without modifying any offsets. After injecting our DLL into the process, we replayed the modified message to overwrite the Application Path. Following a system restart, we observed that one of the privileged EDR processes executed files from the modified Application Path. By placing our payload in this directory, we successfully gained SYSTEM privileges:

Figure 11: Processes being started from modified path as SYSTEM

Conclusion

This blog post explored the attack surface associated with the interaction between an AV/EDR’s front-end and back-end processes. Key takeaways are:

  • Breaking Trust Assumptions: Using COM hijacking, we demonstrated how the assumption that the front-end process is inherently trusted can be exploited.
  • Finding Hijackable Interfaces: We described our methodology for identifying and hijacking COM interfaces.
  • Privilege Escalation via Named Pipes: We detailed how one target product communicated via named pipes and how replaying recorded messages enabled us to escalate privileges to SYSTEM.

In the next blog post, we will explore reversing RPC via COM and present a more complex exploit to achieve SYSTEM privileges by targeting another security product.

This article was written as part of joint research with Neodyme.

Further blog articles

Command-and-Control

Beacon Object Files for Mythic – Part 3

December 4, 2025 – This is the third post in a series of blog posts on how we implemented support for Beacon Object Files (BOFs) into our own command and control (C2) beacon using the Mythic framework. In this final post, we will provide insights into the development of our BOF loader as implemented in our Mythic beacon. We will demonstrate how we used the experimental Mythic Forge to circumvent the dependency on Aggressor Script – a challenge that other C2 frameworks were unable to resolve this easily.

Author: Leon Schmidt

Mehr Infos »
Command-and-Control

Beacon Object Files for Mythic – Part 2

November 27, 2025 – This is the second post in a series of blog posts on how we implemented support for Beacon Object Files (BOFs) into our own command and control (C2) beacon using the Mythic framework. In this second post, we will present some concrete BOF implementations to show how they are used in the wild and how powerful they can be.

Author: Leon Schmidt

Mehr Infos »
Command-and-Control

Beacon Object Files for Mythic – Part 1

November 19, 2025 – This is the first post in a series of blog posts on how we implemented support for Beacon Object Files into our own command and control (C2) beacon using the Mythic framework. In this first post, we will take a look at what Beacon Object Files are, how they work and why they are valuable to us.

Author: Leon Schmidt

Mehr Infos »
Red Teaming

The Key to COMpromise – Part 2

January 29, 2025 – In this post, we will delve into how we exploited trust in AVG Internet Security (CVE-2024-6510) to gain elevated privileges.
But before that, the next section will detail how we overcame an allow-listing mechanism that initially disrupted our COM hijacking attempts.

Author: Alain Rödel and Kolja Grassmann

Mehr Infos »
Red Teaming

The Key to COMpromise – Part 1

January 15, 2025 – In this series of blog posts, we cover how we could exploit five reputable security products to gain SYSTEM privileges with COM hijacking. If you’ve never heard of this, no worries. We introduce all relevant background information, describe our approach to reverse engineering the products’ internals, and explain how we finally exploited the vulnerabilities. We hope to shed some light on this undervalued attack surface.

Author: Alain Rödel and Kolja Grassmann

Mehr Infos »
Blog

Loader Dev. 4 – AMSI and ETW

April 30, 2024 – In the last post, we discussed how we can get rid of any hooks placed into our process by an EDR solution. However, there are also other mechanisms provided by Windows, which could help to detect our payload. Two of these are ETW and AMSI.

Author: Kolja Grassmann

Mehr Infos »
Blog

Loader Dev. 1 – Basics

February 10, 2024 – This is the first post in a series of posts that will cover the development of a loader for evading AV and EDR solutions.

Author: Kolja Grassmann

Mehr Infos »
Do you want to protect your systems? Feel free to get in touch with us.

Vulnerability in Trend Micro Apex One (CVE-2024-55631)

Search

Vulnerability in Trend Micro Apex One (CVE-2024-55631)

Trend Micro Apex One Security Agent is endpoint protection software that is installed as part of the Trend Micro Apex One suite. It monitors the endpoint for threats such as malicious files and blocks or deletes them as appropriate. It is deployed on all systems enrolled in Trend Micro Apex One.

CVE-2024-55631: Local Privilege Escalation through Arbitrary File Delete

cirosec discovered a vulnerability in the Damage Cleanup Engine of the Security Agent that enables an unprivileged local attacker to escalate privileges. The vulnerability was disclosed to Trend Micro on October 27, 2023.

During scanning of the file system for malicious files, insecure file operations are performed in user-controlled directories, allowing a local attacker to delete almost arbitrary files on the system. By using publicly documented methods, an unprivileged local attacker can abuse this arbitrary file delete primitive to obtain SYSTEM privileges. Because no patch is available at the time of publication, cirosec is not releasing more technical details on the vulnerability until further notice.

CVSS Score
7.8 (CVSS v3) 

CVSS Vector String
AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H

Affected Version
The vulnerability has at least been present since Security Agent version 14.0.12737.

Fixed Version
Apex One Agent v14.0.14203

References
ZDI-Advisory: https://www.zerodayinitiative.com/advisories/ZDI-25-001/
Trend Micro: https://success.trendmicro.com/en-US/solution/KA-0018217

Credits
Frederik Reiter & Jan-Luca Gruber

Timeline

Do you want to protect your systems? Feel free to get in touch with us.
Search
Search