SeeSeeYouExec: Windows Session Hijacking via CcmExec
Mandiant
Written by: Andrew Oliveau
Over the last several years, the security community has witnessed an uptick in System Center Configuration Manager (SCCM)-related attacks. From extracting network access account (NAA) credentials to deploying malicious applications to targeted devices, SCCM attacks have aided in accomplishing complex objectives and evading existing detections. Mandiant's Red Team has utilized SCCM technology to perform novel attacks against mature clients where conventional methodology was not possible. One such SCCM attack is introduced in this blog post.
There was a time when red teamers with elevated privileges on a Windows system could effortlessly inject shellcode into an unsuspecting user's processes. This allowed red teamers to carry out post-exploitation activities within that new process, such as keylogging or accessing LDAP as the affected user. However, as endpoint detection and response (EDR) systems have improved, remote process injection has turned into a risky operation, pushing red teamers to seek alternative methods to hijack a user's session.
Enter CcmExec, a service native to SCCM Windows clients that has an interesting design that is useful for red teamers. In this blog post, we delve into how the CcmExec service can be utilized for session hijacking and introduce CcmPwn, a tool designed to facilitate this technique. Finally, we will discuss detection strategies for security teams.
AppDomainManager Injection
Before diving into CcmExec, it is important to understand the intricacies of AppDomainManager injection, a loader hijacking technique used by attackers to execute arbitrary code within a .NET application. In essence, the .NET framework provides a way to manage application domains, which are isolated environments where .NET applications can run code. The AppDomainManager class is a key part of this infrastructure, responsible for creating and managing these application domains. However, if an attacker were to override the AppDomainManager class constructor, they could force the hosting application to run attacker-defined behavior when creating an application domain.
The most common method to perform AppDomainManager injection is through a .config
file. This approach involves modifying the application's configuration file to specify a custom dynamic-link library file (DLL) and AppDomainManager to be executed by the .NET application. Here's how it's done:
-
Create a custom AppDomainManager: Develop a class that derives from AppDomainManager and includes malicious code. Compile this class into a DLL.
-
Create a configuration file: Modify or create the application's
.config
file (e.g., "application.exe.config
") and add the following XML elements to specify the custom DLL and AppDomainManager:<configuration> <runtime> <appDomainManagerAssembly value="YourDLL, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" /> <appDomainManagerType value="YourAppDomainManager" /> </runtime> </configuration>
- Execute the application: When the .NET application is executed, the .NET runtime reads the
.config
file located in the same folder and loads the specified custom AppDomainManager. The code within the AppDomainManager is then executed within the context of the application.
Hijacking CcmExec
When analyzing the CcmExec service's process, CcmExec.exe
, with a process analyzing tool such as Process Explorer, a couple of things immediately stand out. The first thing that catches the eye is that the process spawns the C:\Windows\CCM\SCNotification.exe
process for every interactive session on the Windows system, as shown in Figure 1. SCNotification.exe
is a component of the SCCM client responsible for displaying notifications to the user, such as software installation prompts or restart notifications.
Figure 1: CcmExec.exe child processes
Upon further inspection, it turns out that the SCNotification.exe
file is a .NET application, which comes with its application configuration file at C:\Windows\CCM\SCNotification.exe.config
. Do you see where this is going?
By having administrator privileges on a Windows system configured as an SCCM client, we could modify the configuration file to instruct the .NET application to load a malicious DLL and obtain code execution on behalf of every logged-in user! The attack is simple:
-
Upload a malicious DLL to the target system: This DLL contains the AppDomainManager code to be executed in the user's session.
-
Modify the SCNotification.exe.config configuration file: Point to the malicious DLL within this file.
-
Restart the CcmExec service: This action causes the
CcmExec.exe
process to restart and runSCNotification.exe
for every logged-in user.
This technique provides a stealthy way to execute code across multiple user sessions without having to rely on remote shellcode injection.
Weaponizing Session Hijacking with CcmPwn
Weaponizing this technique is straightforward. Using the Impacket library, we developed CcmPwn to execute the aforementioned attack and hijack user sessions. CcmPwn is equipped with various modules. The exec
module uploads a custom configuration and DLL file to the target system, remotely restarts the CcmExec service, and then reuploads the original configuration file. An example is illustrated in Figure 2 and Figure 3, where using CcmPwn provided us with Cobalt Strike beacons for the hijacked sessions.
Figure 2: CcmPwn exec module
Figure 3: Cobalt Strike beacon for every logged-in user
Additionally, CcmPwn features a coerce
module, which coerces an SMB or HTTP authentication request for every logged-in user. Red teamers can leverage these coerced authentications to attempt password cracking or conduct relay attacks. This module does not require a DLL, as it simply uploads a malicious configuration file to the target. This file instructs SCNotification.exe
to load a file from an attacker-controlled file share, as shown in Figure 4 and Figure 5.
Figure 4: CcmExec coerce module
Figure 5: Obtaining coerced password hashes
Defensive Considerations
Depending on the security information and event management (SIEM) or EDR solution in use, this attack can be detected in a variety of ways. The following defensive measures are recommended:
- Monitor for 1026 Events for SCNotification.exe: Event ID 1026 is associated with .NET runtime errors. When using CcmPwn's
coerce
module,SCNotification.exe
attempts to load a non-existent DLL from an attacker-controlled file share. Since the DLL cannot be found, the application produces aSystem.IO.FileLoadException
error. An example of this behavior is shown in Figure 6.
Figure 6: .NET Runtime error for SCNotification.exe
- Monitor for 7036 Events and Remote Logon Type 3: The 7036 event corresponds to the starting and stopping of services. By monitoring this event, security teams can detect suspicious restarts of the CcmExec service, which may indicate an attempt to hijack user sessions. When using CcmPwn, a logon type 3 (network logon) event will occur at the same time as the service stop, followed by a 20-second delay before the service is started again. Monitoring for this pattern can help triage these service events and provide context around potentially malicious activity.
- Monitor File Modification and Configuration Strings: Since attackers need to modify the
SCNotification.exe.config
file to execute this attack, monitoring for changes to this file can provide an early warning. Additionally, the presence of the "AppDomainManagerType
" string in the configuration file should be scrutinized, as it is used in AppDomainManager injection attacks. Security teams should investigate any unexpected occurrences of this string inSCNotification.exe.config
.
By implementing these defensive measures and adapting them to the specific capabilities of their SIEM or EDR solutions, organizations can enhance their ability to detect and respond to session hijacking attacks via the CcmExec service.