
Can we please welcome Kam presenting on breaking composure journey to hunting windows com vulnerabilities. Thank you. Okay. So hello everyone and welcome to my talk and today I will be talking about breaking composer a journey to hunting windows comp vulnerabilities and this presentation focus on what is com component and how to find vulnerability in windows com component and before starting the presentation I will introduce myself and my name is Byan Gang as is called you can call me kang and I'm from South Korea and I majored in computer science at South Korea and my main interests are Windows bug hunting and system bug hunting like anything. So what can you expect from today's talk? Here's the agenda. We will start
with the basics. What exactly are Windows com components? After that we will dive into what kinds of com vulnerabilities have been found in the past. Then comes the main part of the talk. I will share my personal journey of finding a vulnerability. Uh to wrap things up, I will talk about future research possibilities in this area and then we can open it uh for questions. And first, Windows comp is a core component of the operating system designed by Microsoft to enable seamless communication between different software components. Acting like a universal translator come allows for interoperability between programs written in different language such as C++, C or and Python. This capability is why many window functions including embedding an Excel
file into a word document or communicating with a printer driver and all built on the com. In a sense, com serves as the key technology that connects various applications and operating system components within the Windows environment, allowing disparate software to work together as a cohesive whole. Now that we understand why com is and why it's so important, let's talk about how it components are actually structured and how they run. This is a crucial distinction that affects how developers build and use com objects. Essentially, com components fall into two main categories. First one is the improcess component model and second one is out of process component model. Let's break down what each of these means and
why the difference matters. First improcess come is a high performance model where the same where the client and com server run within the same process sharing the same memory space and communicating through direct function calls. While the direct communication offers minimal performance overhead, it pose a sec secret risk because the com server enhance the client's privileges and operating with the same level of access as the user. This means any code executed in the com component runs with the authenticated users permissions and making this model unsuitable for our secret research. And second one is out of process comp. Specifically the local servers models operates by running the comp server as a separate standalone process like.exe files from the client application. This
architecture enhances system stability as a server crash does not affect to the client. From a security security standpoint, this separation is where the primary risk lies. The com server often runs with elevated privileges such as system. Even if the client application is running with standard user privileges, this privilege dispro makes out process come a critical area for secret research. An attacker can exploit vulnerabilities in the highly privileged come server from a low privilege client. If successful, this can lead to privilege escalation where the attacker gains control of the server process and by extension is high level permissions. This type of attack is a classic and valuable vector for malicious sectors and making the making this com model a
key target for security researchers. And next one is the numerous servercom model also known as the extends the outprocess architecture by allowing a client and server to communicate over a network typically use TCP IP. This enables a client with low privileges to interact with a highly privileged com server on a different machine. Similar to the local server model, but the primary security concern is privilege escalation. An attacker can send malicious data over the network to exploit vulnerabilities in the sorry in the remote server. This network based attack vector is significant because it allows a low privilege user to gain high level permission on the remote machine making a historical critical tech target for remote code
execution and privilege escalation attacks. Indeed, a critical similarity between the local server and remote server both rely on cross process communication where a low privilege client sends data to or separate on often highly privileges server process. This shared architecture which use process and stops to measure data across a trust boundary creates a prime opportunity for security exploitation. The server running with elevated pre permissions must robustly handle all incoming data. If it fails to properly process mformed or unexpected data from the less trusted client, a vulnerability can lead to a crash or more critically like arbitrary code execution. This makes both model attractive target for privilege escalation on a local machine and remote code execution across the
network. as the core attack vector is the same exploiting data handling across the trust boundary. So does this mean we can simply send malicious data to a remote com server and get it to crash? Well, the short answer is no. It's not that easy. Microsoft has built security validation into the com object model to prevent that very thing from happening. So what kind of security validations are we talking about? Let's find out. And first tab is launch permissions or a core com security feature that controls who can create a instance of a com object. Before a client can even get a reference to an object, the com runtime checks these permissions. If the client doesn't have the necessary rights to
create creation fails, this acts as a crucial first line of defense completely blocking unauthorized clients from interacting with the object interfaces and preventing potential attacks from ever starting. It's great to see how the two tire security model works. Think of it as a two-step process. You need to get through both gates to interact with the com object. The first gate is launch permissions which is the initial check that determines if a user is allowed to even start the com server process. The client's coate instance call is validated and if the user has the right to launch the service the process begins but even after this they haven't gained control. That's where the second gate access permission comes in. This check
determines whether the client is allowed to actually call the object method and interact with its interface. This two-part system is a powerful defense mechanism and as a user might have the permission to start a process but not to use its functions effectively stopping an attack from a low privileged user before it can exploit a highly privileged user. The com security model is a two-part system that use both launch permission and access permission to protect COM objects. The first layer launch permission determines whether a user can start the com object process. If a user is granted launch privileges, the process begins. The second layer access permissions then then controls who can actually interact with the learning
object and call its functions. This dual layer approach prevents a user from exploiting a privileged service even if they can get it to learn making it a crucial aspects to securing cross process com communication. All right, we have covered the what of come and now let's get into the how. The central problem is how a com client can call a method in a separate process or on a different machine. Since the operating system isolates process for security, the solution to this is found in the proxy and the stop. These two components acts as a bridge and translator facilitating cross process communication. They perform a crucial function called mering which is the process of package data and method
calls. So they can be sent from one process to another. This enables seamless interaction between the client and server despite their physical separation. The proxy and stops are two essential components that enable com communication. The pro the proxy located within the client's process performs mering to package the method name and parameters for transfer. When a client makes a call, this package data is then sent across the process boundary via communication channel like RPC. Next one, the ST is located in the service process, receives the data and performs a machine to rec reconstruct into a unusable format before making the actual call to the comvers method. When the server complete its task, the researcher measured by the steps and sends back
throughout the proxy and finally returned to the client. This transportate system allows to seamless communication even though the client and server are separate separate. Standard marshalling is the default and most common method for data transfer between a comp proxy and stop. It's a key convenience for developers because it is automatically handled by the system for universally recognized com interfaces like I unknown and I dispatch. This means developers do not have to create their own proxy and step components as there is necessary code is provided by core windows system libraries like oiler 2.dll. This built in approach simplifies development, ensures consistency and enhances security as the code has been rigorously tested. As a result, developers can focus on their
applications logic there rather than lowle communication protocols. And let's move on to the second type of machineing custom maching. This method is used when a come object utilize non-standard interface requiring the developer to define the entire communication process. This is done using an interface definition file which acts as a blueprint specifying how data should be packaged and unpacked for the proxy and stop. Developers use a midl compiler to automatically generate the proxy and stops DLS from the IDL file. While this method gives developers the flexibility to create unique come objects, it is a prime target for security researchers because any errors in the custom defined ideal or the generate code can more hurt to ground for security
research compared to standard machineing. Okay, let's talk about con threading models. The single thread opertment model is a com threading model designed for simplicity and stability. Its core rule is that a com object can only be called by a single dedicated thread. This means the object does not have to manage the complexities or of multi- threading such as race conditions or deadlocks. All calls from other threads are automatically serialized by the com routine uh and ensuring that only one call is processed at one time. This simplifies the development of the com object as it can be written as if it only ever receives synchronous or sing single thread calls. Then multi- thread or partman model is a
threading model designed to allow multiple threads to call a come object simultaneously. In the in this model, the com object itself is responsible for ensuring thread safety. Developers must use synchronization primitives like mutexes or seapors to protect shared data from being accessed by multiple thread at once. This makes the MTA model a prime target for security researchers. If a developer fails to correctly implement thread safe code, a race condition can occur where the outcome depends on the execution order of multiff thread. This can lead to data corruption or exploitable crashes. Therefore, unlike the STA model where the come runtime handle serialization, the MTA model place the burden of security of the developer implementation making it a key area for finding
potential vulnerabilities. To recap what we have covered about come, first we learned about the three come times in process come locer and remote. Second, we saw that Microsoft implemented secret validation including access and launch permissions as a research researchers need to check both permissions during their analysis. Third, we look at how process and steps enable a client to call a service method indirectly. Finally, we covered how can mach data either using standard machuling for default interface via OLE2.dll DLL or custom mushling for non-standard interface based on an ideal file. Now that you know all these details about come, you might be asking yourself why should I care? Why is a come good target for bug hunting? It's a fair
questions especially with so many other areas to focus on in security. Well, the answer is simple yet incredibly powerful. COM is a gold mine for privilege escalation in Microsoft Windows. Com is a critical attack vector because it provides a communication channel between a low privileged clients and high privileged com servers. An attacker or researcher can use a client running with a normal user to find and exploit vulnerability in a com server. For instance, by leveraging a flow in data processing or logic, they can gain control of or a crash or high priv privileged process which is a direct path to privilege escalation on a Windows system. This same principle applies to sandbox escapes where a
client within a restrict sandbox can exploit a comulability to break out and gain a higher level of system access. The security landscape is const constantly changing and we are seeing a clear thread. Windows zero day exploits are on the rise and at the same time they are getting tougher to find. The lowhanging fruit has largely been picked and attackers and researchers alike are having to work harder to discover a path to a high impact bug. So for those of us who [snorts] are serious about v vulnerability research, the big question remains where do we look for the next generation of vulnerabilities? We need to find something that others might not be focused on. We need to look
at the older more foundational part of the operating system that are still in use today. These areas are often overlooked but they remain a key part of the attack surface and this is exactly where CM comes in. By diving into the deep often neglected word of com we can uncover new and powerful attack vectors that others have missed it. And let's see the previous research of come. A study presentated at comra race at eenics in 2022 successfully detect race condition books by focusing on the MTA com object model. This research is highly relevant as it found several vulnerabilities by targeting a b class that is notoriously difficult to find. It serves as an excellent example of how
a focused methodology can yield significant research and provide it the groundwork for my own research. And let's look at one more relevant research paper also from eenics 2023. This is one is titled dete detecting union type confusion. While the previous paper focused on the race conditions, this one is all about a completely different different type of type confusion. The researchers discovered that if developers improperly use a fundamental C++ concept like union types or the various strct in their com objects, it can create a vulnerability. This is very interesting find because it shows a completely different way that come can be exploited. Instead of focusing on concurrency issues, this research highlights how a simple mistake in data handling can lead to a serious
security flow. This is a great example of how even basic programming errors can have huge security implications in a complex system in Lycom. Now let's check out the real world example of combox to see how these concepts play out in practice. This first one is CV 20201362, a bug that was discovered in the Windows wallet service. For those who might not be familiar with it, this service is a core component of Windows uh that is responsible for handling a user sensitive payment and credit card information. The com object found in the wireless service.l library is not a standal standalone program. Instead, it runs with high privilege as an out of process server hosted by SBChost.exe.
This setup allows a low privilege client to interact with a high privilege server creating a dangerous scenario. A vulnerability was found in the wallet vector interface which provides a direct path for privilege escalation by exploiting a flow in how it handles data. The vulnerability is located in set group function of the wallet custom property class. A logical flow exist where setting the argument A4 to a value other than minus one bypasses security and validation checks. This bypass allows a attacker to achieve an arbitrary right per primitive where they can control both of data and to be writen and the memory address. This highly dangerous capability can be used to override critical data or hijack program execution and ultimately lead to
privilege escalation or remote code executions. This [snorts] vulnerability provides an attacker with a path to privilege escalation by allowing a low privileged client process to crash a com server running with system privileges. The core of the issue is a right whatware primitive which gives an attacker to ability the right arbitrary data to any memory location within the higher privileged process. While converting these primitive into a reliable exploit to achieve full code execution can be challenging, the ability to override critical data, modify function pointers or inject malicious code makes this a critical and dangerous vulnerability for privilege escalation on Windows systems. Then there is a second bug we can examine CV 20201404 found in the capability access server
service. This is a classic example of a race condition bug. The capability access server itself is a window service that has a various interfaces and the vulnerability was discovered in the Windows UI start screenile interface. The capability of the server service and its Windows UI start screen secondary tile interface are configured to use the MTA threading model. This is a crucial detail as it confirms that multiple threads are allowed to access this com interface simultaneously in the MTA model. As we have discussed, it's up to the dis developer to ensure thread safety. The com runtime doesn't enforce a queue or serialized calls. Instead, it allows concurrent access to the objects method. This design choice while excellent for per performance
creates the perfect environment for a race condition boat. If the develop developer failed to use proper synchronization to protect your data, multiple thread trying to assess the data at the same time can cause a chaotic and unpredictable state. One thread might read a value just as another thread is in the middle of writing to it leading to data corruption or a crash. This is precisely the type of bug that can occur in an MTA interface. And in the case of CB 2020 140, it led to a serious secret vulnerability in a core Windows service. And let's deep dive to capability access server. The start screen has various interface among those a specific valability was found in the I secondary tile 2
interface. We can look at the IDL file for this interface and see that it has 12 different method. Okay, let's get practical. How do we find their interface? We can use a decompiler to look at the com servers binary file. When we load the DLL into a decompiler, we can navigate to the R data section. The R data section of a binary holds read only initialized data. This is where you will often find crucial information about the COM interfaces including their GO ids and the V table pointers. By examining the section, we can ident identify all the COM interface the service implements. [snorts] The decompiler helps us trace these pointers and match them to the
actual code that implements the method. The vulnerability starts in the puttic name method which calls the save h string function. Since this happens in a multiple thread approachment environment where multiple threads can access share resource simultaneously, a race condition can occur. The analysis must focus on this this pointer which acts as a shared pointer in the multi thread appertment model. In this environment a race condition B can easily occur when shared resource are used incorrectly and the save h string calls the initialize function using this pointer. Within the initialize function, we find the critical area for a race condition. A call to free and assign on success. This is a major red flag for a bug
hunter. The free and assign on success function is calling the Windows delete delete string API which is a standard window function used to free memory allocated for a string. You might be thinking, but isn't this function supposed to just handle the free something? Yes, you're right. is supposed to free a string that has already been created. The problem is what happens right after that. The code then calls free assign on success. This is the core issue. What's missing here? The code has no locking mechanism or any sort of value value routine. There's nothing to ensure that another thread isn't trying to assess or use the string as the first thread has already freed it. So what's happening the race condition
thread A calls freeze to release the string memory before the operation is complete thread B tries to use the same thing pointer because the memory is being deallocated thread B's attempt to use it will lead to a success violation a crash and a potential Daniel of service the worst case scenario is that an attacker can control the timing of these two threads to create a predictive bubble crash which could then be used as a stepping stone to a full-blown exploit. This lack of proper synchronization and validation in a multi thread environment is the fundamental flow that leads to a race condition. It's a classic example of a bug that wouldn't exit in a single thread model but becomes a critical
vulnerability in an emptycom object. The research finding demonstrate that comm is a highly effective octave vector. A significant number of the vulnerabilities discovered could be used for privilege escalation or escape sandbox to system level privileges. This proves that com is not just a theoretical attack surface but a p practically and valable path to bypass and boxes and achieve a full system compromise. The complexity of K particularly its out of process and remote server models and their reliance on crossprocess communication creates a rich hunting ground for security researchers confirming that understanding these architecture nons can lead to a full system compromise given the vast number of come objects within the Windows ecosystem. The research we have discussed is a powerful
starting point not the conclusion. The the findings from other researchers confirm that privileged out of process components particularly does using custom machineing are a rich source of critical vulner vulnerabilities. This provides a clear methodology for finding new bugs. The sure side of the Windows operating system means that the attack surface remains too best to be fully explored confirming that com is a still a fertile and exciting area for security researcher. Now how do we actually find these com objects? Simply knowing they exist is isn't enough. We need a way to enimulate and expect them. The first step in any com research is to use a tool that can show us everything that's out there on
their system. One great tool for this oil review.net which was developed by secretary research James for show oil view.net acts like a powerful explorer for all the all the com objects on your computer. It reads information directly from the Windows registry where com objects are registered and present it in a clear organized interface. This allows you to see the class ID like CLS ID, interface ID and other crucial details for every COM object. One of its most useful features is its filtering capability. You can easily filter the massive list of com objects to focus on what you are specifically looking for. For example, you can filter by threading model or by server type. This allows you to quickly narrow down
your search to privilege it out of process server likes the very type of components we have identified as prime targets for privilege escalation box. It's an incredibly helpful tool to begin with, providing the essential map you need before you start digging into the code. To find a bug in a com object, you have two main options. Manual code auditing or fuzzing. While auditing can be effective for finding logical flows, it's often too main to time consuming. Fing an automated technique that feeds a program with random data to find vulnerabilities is a more efficient alternative to be effective. More than folders are coverage guidedly meaning they track which code path are executed and then create new inputs to explore on
which areas. Getting this coverage information for a com server which often get coverage in runtime process. It can be difficult. This is the core challenge. How can we get reliable coverage data without the complexity of transition method? There is example of getting a coverage in runtime processed by cyber arc. But isn't it there has the easy way I see two main options for our con object budging approach. One is the KFL and next one is the what the fuzz. KFL is a powerful hardware assisted fuzzer that use interprocess trace for efficient low overhead code coverage. This makes it idle for fing complex privilege process like those in SVChost.net net where [snorts] it's hardware level visibility is a
significant advantage and the what the fuzz on the other hand is a more versatile general purpose fger that use softwarebased in instrumentation. It's easier to set up and is a great choice for wider range of users and corner mode targets on both Windows and Linux without requiring specific hardware features. Let me introduce greater for this KFL. It's a fast guided folder that's built for virtual machine which makes it perfect for anything running as Cremeo or KVM guest. This is a crucial advantage when fudging privileged Windows services as it allows us to isolate the target in a controlled environment. So what makes KFL so useful for us? It gets code coverage by counting instruction hits at a target
address inside the Windows VM. This is a very efficient and low overhead way to monitor execution. Instead of relying on slow software instrumentation, KFL leverage hardware features like Intel PT to get real time hardware level visibility into the code being executed. This means we can tell the KFL agent which runs on the host to focus specifically on the com service process in the guest VM. It can then trace the coverage without a problem even if the process is highly privileged or protected by the operating system. That's why it's such a powerful solution. It bypasses the traditional difficult of getting code coverage in protective process making it an idle choice for hunting com bugs in the
Windows corner and user space. Now for a tricky problem, how do we find the correct virtual address inside the guest VM image? Things get complicated when there are many processes with the same name as our com server. For instance, SV.host.exe exe can run dozens of different service each in its own process. So how do we write our fer harness to handle this? We need a smart way to make sure we are always targeting the right processes no matter how many are running. The solution lies in identifying a unique characteristic of our target conserver that allows us to distinguish it from all the other similarity name process. The first step is to enimilate all processes in the guest VM using the
create tool help search to snapshot function within our harness. Since the harness runs inside the guest VM, it can retrive the addresses of all processes including the com server we are targeting. From there, we can get the base addresses and names all of the modules such as DLS for each process. This allows us to iterate throughout the entire process list, find our target process and then inspect all the DLS it has loaded. This is the crucial steps that provides us with a map of the target memory space. We can find our specific servers DL and get its base address which is the starting point for calculating the address of the functions we want to fudge.
Once we have all the modules names, we just need to compare them to our target COM object module. We can get the DL name for our target COM object by looking it up in the Windows registry using its unique CLS ID. Then we can program our harness to iterate throughout all the modules in our target process looking for a mechan matching name. When we find the match, we calculate the exact address of that process and tell our agent where to start in collecting coverage data. And just like that, we have successfully map the code of our target com server and can begin fuzzing it to look for vulnerabilities. It's a simple yet powerful approach that bypasses the
complex complexities of traditional coverage method. The second what the fuzz is a user mode f designed by windows application making it idle for target com object unlike hardware assisted tools like KFL what the first simplifies the fudging process by eliminating the need for a virtual machine or VM setup. This allows researchers to quickly and directly test the running process streaming line bug discovery. What the furs is a snapshot based buzzer that captures and enimilates a program state to achieve code coverage by emulating the process in a controlled environment. It can accurately track which code has been executed. This allows it to generate new inputs that explore on riches code path offering a powerful alternative to hardware based
pling for user mode application. What the f doesn't need to struggle with finding the target server's address. This is because it can dump the necessary information when the ferness reaches the target server. Therefore, water fuzz makes it easier to f come servers eliminating the complex task of finding the server's address. You can simplify fuzz without the struggle. I started fudging various C object and it didn't take long [clears throat] before and it suddenly crashed. The first bug was discovered in the UPMP host service specifically within the UPMP host.dl file. This library exposed several com interfaces but the one containing the vulnerability was the UPMP description manager interface. This interface is responsible for managing device description on the network and a
process incoming data. The specific flow was found in the process description template function of the C description manager class. Interestingly, this function first performs a check to ensure the connection is locker before calling the vulnerable remove description function. The this looker only check significantly limits the attack surface. The remote description function which cleans a registry and tires for your PMP devices is part of a gloable connection. It calls HR remote presentation virtual di which then calls HR remove while remove description itself might appear safe. The real vulnerability is a logical flow hiden inside the finer function HR remove v root. This is where an attacker can trigger the boat. The vulnerability exist in the HR remote
vroot function which use a global variable GP vers when calling the remote voot method. Although GP vers can ma can be manipulated to cause an unexpected state change in the program. The function itself lacks a direct write primitive. This means an attacker cannot control what data is writen or where it's written making it difficult to achieve a reliable exploit. Due to the lack of fine grain control needed to hijack program execution, Microsoft classified this bug as a Daniel of service rather than a privilege escalation. Moving on to the next vulnerability. I found it in the MCP management come interface. This interface has eight interface. This in this interface has eight different method. But I decide to
edit the get authorization header silent a sync function. This function calls an internal function name get authorization header internal. What happens inside the function is a bit tricky and present a classic race condition scenario. The function takes the value of a shared variable and puts it into a local variable 12. This shared variable is the key to the variability. Then the code calls internal release on that value. This is where things getting interesting. Internal release frees the memory associate with B12. Now let's look at the get authorization header or sync. Does this sound familiar? It should because this function also calls get authorization header internal. It's the same internal function we just talked about and that's
exactly what caught my attention. This is a crucial finding for a burger hunter. The fact that two different public facing method get authorization header silent a sync and get authorization header as sync both call the same intern function get authorization header internal is significant. Two separate functions. Get authorization header silent a sync and get authorization header a sync. Both call the same internal internal release memory management routine without the proper locking mechanism leading to a classic race condition in a MTA model. When multiple thread try to access the shared pointer, one thread can free the memory while another is still trying to use it. Researching in a use after free relability that cause a crash and a
Daniel of service recognizing this familiar pattern of security researcher then create a proof of concept to validate the extent of the bug and demonstrate the crash and it's a demo type. First check the latest Windows version
and start the our target process and check the PD and attach the debugger to target process
and run the PC code. So wait lately [snorts] there will be crash on the target server on running in system privileges and that it can be lead to priv privilege escalation settings. Okay. Based on analysis, we can confidentally conclude that the bug we found which is assigned the number 202529841 is a significant race condition and use after free vulnerability. This discover validates our systematic systematic bug hunting methodology which combines the deep understanding of architecture of focus on high polish targets and the use of sophisticated finger complex vulnerabilities in well vetted system service. Now let's look at the fun future of this research. A key next step is to automate the entire fudging process to make it
more efficient. This involves writing a script to purse IDL files and automatically generate intelligent mutate inputs based on the method and arguments defined within them. This target approach is more effective than sending random data. Additionally, we can build a feedback loop into the fger so it can automatically switch to a different method if a current one fails to increase code coverage. This dynamic and adaptive strategies maximize the chance of finding new vulnerabilities without wasting time on that ends leading to a full automated and highly effective composers. And thank you for your time and attention. is a pleasure sharing my journey with you and someone has the Q&A. >> Thank you. >> So before you speak access control and
like us object >> yes >> once you are connected to a object standard user is more granular like this user can only call these functions or is it like a general like admin or you're not an admin? Sir, can you speak one more time? >> Sorry. Um, so when you've got like when you connect to an object as a low privilege. >> Yes. >> Um, is there any situations where you can only pull a subset >> of all functions? >> Yes. >> Does that answer like do you understand? >> So, >> so can't do the >> um if you're if you're like >> Yes. And the com object might have 20 functions. >> Yes. >> Is there any situations where you can
only call some of those but not all? >> Yes. Not all. >> That's it. >> So can you can you limit what it uses can call? >> No. The the we can call the any functions of the list of the components. So that is the researchers one to anything. So that's not limit. >> Yes. >> Is it all right? Thank you. >> Anyone else? Yes.
>> CBSS like that. >> Yes. >> Um is there any reason why this can't be done remotely >> like CV 2025? I found it. >> Yeah. No. >> Why would why would it not be able to access a computer or a VM or whatever and execute it? uh my my bug is only uh only attack to in the local so that can be lead to remote code execution. So and my target code object has only local process environment not on the dump so it can be lead to only local privilege escalation then Microsoft to lead to adjust the local privilege escalation too. Thank you. Anyone else? Okay, nobody has the Q&A, so thank you for your attention and time. Thank you.