DLL (Dynamic Link Library) Side-Loading is not a new technique but does require significant effort for threat actors. Many adversarial groups that utilize this technique have affiliations with government entities, as the more sophisticated the obfuscation, the more complex and time-consuming the development. Most recently, this technique has been used by the threat actors behind 3CX’s security vulnerability involving their desktop application.

What is DLL Side-Loading?

When an executable runs, it will call libraries and functions it needs to operate. This attack makes use of legitimate software to call the malicious DLL and often, the malicious code is packaged alongside the software. In some cases, it may be that the software is hosted on a site where the user is made to believe they are accessing premium software for free, but in the cases where a nation state backing is present, we often find the DLL has been introduced at the supplier level, thus a supply chain attack.

On March 22, 2023, SentinelOne started taking block actions against suspicious 3CXDesktopApp instances and on March 29, 2023, CrowdStrike put an alert out stating that malicious activities were being seen on hosts running the 3CXDesktopApp on both Windows and Mac. This was further supported by 3CX on March 30, 2023, detailing that the Windows App versions 18.12.407 and 18.12.416, distributed as part of Update 7, were compromised along with 18.11.1213, 18.12.402, 18.12.407 and 18.12.416 on Mac.

Analysis

The infection process begins with 3CXDesktopApp launching and running its update executable. Update.exe is then responsible for pulling the first malicious payload, ffmpeg.dll. Then, the ffmpeg.dll library will then acquire the d3dcompiler_47.dll (Figure 1).

 

Figure 1: Side-Loading Process Flow

Figure 1: Side-loading process flow

 

The ffmpeg.dll is a normal component of the 3CXDesktopApp containing functions related to audio visual processing. It is a library that is used by several different software pieces such as Skype, Teams, WhatsApp, and Discord. A great tool for comparing different instances of what appears to be the same file is PE Tree developed by Tom Bonner and released by Blackberry . The immediate comparison between the benign instance of ffmpeg.dll (Figure 2) and the uncovered malicious sample (Figure 3) does not show anything immediately alarming.

 

Figure 2: Benign ffmpeg.dll

Figure 2: Benign ffmpeg.dll

 

Figure 3: Malicious ffmpeg.dll

Figure 3: Malicious ffmpeg.dll

What does look suspicious is the missing debug information alongside the slightly larger size of the library file. When threat actors side-load a library, they usually attempt to obfuscate the library as much as possible—keeping it the same size is one method (Figure 4).

 

Figure 4: Benign to Malicious File Header

Figure 4: Benign to malicious file header

 

When looking through the number of sections, the malicious instance of the file only had 10 sections versus the 11 that the benign contained. In addition, the malicious instance contained no checksum information and only the benign instance of ffmpeg.dll was signed by 3CX. Normally, the DllMain function of ffmepg.dll would match the image in Figure 5.

 

Figure 5: Benign DllMain – ffmepg.dll

Figure 5: Benign DllMain – ffmepg.dll

 

In this instance, we can see an immediate difference. The malicious instance contains a call to a new function (Figure 6) which we renamed “AVMonitorRefreshEvent” to match the status it sets at the start of the function.

 

Figure 6: Malicious DllMain

Figure 6: Malicious DllMain

 

Analysis of this function shows reference to the d3dcompiler_47.dll (Figure 7), which is located alongside ffmpeg.dll. While signed with an out-of-date certificate (Figure 8), ffmpeg.dll contains the secondary payload.

 

Figure 7: d3dcompiler.dll

Figure 7: d3dcompiler.dll

 

Figure 8: Out-of-date certificate

Figure 8: Out-of-date certificate

 

The ffmpeg.dll looks for “FE ED FA CE” (0xCEFAEDFE) to denote where in the d3dcompiler.dll the shellcode is located (Figure 9).

 

Figure 9: Payload location

Figure 9: Payload location

 

When found, the shellcode will be loaded into memory by ffmpeg.dll and decrypted using the key “3jB(2bsG#@c7)” (Figure 10). Analysis of the decryption loop shows it to be RC4.

 

Figure 10: Decryption key

Figure 10: Decryption key

 

Once decrypted, the function we named “AVMonitorRefreshEvent” will call VirtualProtect before calling the decrypted shellcode (Figure 11).

 

Figure 11: Decrypted payload

Figure 11: Decrypted payload

 

As is common with many malicious payloads, function calls are dynamically mapped (Figure 12). Going through the shellcode, there are a number of libraries loaded that are related to external communications, for example “wininet.dll.”

 

Figure 12: Dynamically mapped function calls

Figure 12: Dynamically mapped function calls

 

Continuing the analysis of the shellcode shows there to be another DLL embedded within (Figure 13), which is loaded into memory using VirtualAlloc.

 

Figure 13: DLL embedded within

Figure 13: DLL embedded within

 

The DLL contains a Sleep function that will be called continuously over a random period of seven to 28 days, for a period of eight milliseconds. This aligns with what the industry has seen when they have uncovered the malicious payloads but did not uncover any follow-on actions (Figure 14).

 

Figure 14: Malicious payload without follow-on actions

Figure 14: Malicious payload without follow-on actions

 

When the conditions for the Sleep loop are met and the execution continues, the DLL will request a number of ICO files from https[:]//raw.githubusercontent[.]com/IconStorages/images/main/icon%d.ic where %d ranges from zero to 15. Fortunately, this domain and the files hosted are no longer available.

The call to this function is in two locations. After the first call, the DLL enters an iterative loop where a decryption function is called for the ICO files. This occurs because these ICO files contain, at their end, a Base64 encoded C2 that is further encrypted with AES and GCM (Figure 15).

 

Figure 15: Base64 encoded C2

Figure 15: Base64 encoded C2

 

While the C2 servers are also no longer available, the C2 is known to respond with a JSON blob containing an encrypted data stream that is executed directly on the victim’s device. Based on information within the security community, the purpose is to harvest sensitive information and credentials from browsers on the endpoint as well as system information.

Conclusion

Thankfully, the response actions taken to this attack have been swift by all security vendors. Supply chain attacks represent a significant investment of time and resources by threat actors. While 3CX has reacted quickly thanks to CrowdStrike, this goes to demonstrate how easy it is for threat actors to hide their activity behind sophisticated attacks. At this moment in time, it is best to follow the advice published by 3CX and use their PWA Web App rather than the Desktop version, as well as reset any browser-stored credentials on the machines running 3CXDesktopApp.

Read our preceding threat notices from March 29 and March 30.

Indicators of Compromise

IOC table

Want something new to listen to?

Check out our podcast, The Unfair Fight, where you can hear industry insights from Blackpoint Cyber leadership and our special guests firsthand.