Skip to content

Research by: Tejaswini Sandapolla, Pratik Jeware and Karthickkumar K

 

Supply chain attacks have increased in recent years. A watershed incident occurred in December 2020 when SolarWinds customers were infiltrated through malicious code snuck into the software. The 3CX desktop apps for Windows and macOS—used for voice and video conferencing—are the targets of a recent similar attack that affected millions of users worldwide.

 

In this attack the threat actor employed a DLL side-loading technique to target the legitimate 3CXDesktopApp signed binary. The attack has been observed on Windows and macOS systems.

 

The attackers use the DLL side-loading method to execute malicious code and to evade detection mechanisms. This technique involves loading a malicious DLL file through a legitimate process, allowing the attacker to bypass security measures and execute their code. This technique is a popular tactic among advanced threat actors and poses a significant risk to organizations if not properly addressed.

 

This article will examine how the attacker infected both Windows and macOS operating systems using dynamic linked libraries (DLL/Dylib). For Uptycs customers, we list hunting queries and YARA rules to inventory affected systems and identify historical activity at the bottom of this post.

 

Stay informed with the latest Threat Bulletin from Uptycs: 

Read the Threat Bulletin →

 

Windows Platform

Infection Flow

Figure 1 below illustrates the malicious operation on the Windows platform.

 

Fig1_win

Figure 1 - Infection flow on Windows

 

Technical Analysis

Once the user executes the 3CXDesktopApp MSI file installer it will begin to install all the associated files on the targeted machine in the directory C:\Users\<username>\AppData\Local\Programs\3CXDesktopApp, as shown in Figure 2.

 

Fig2_win

Figure 2 - Installed location of MSI execution

 

The folder named "app" contains the malicious DLLs as shown in Figure 3. 

 

Fig3_win

Figure 3 - Folder with malicious DLLs

 

When the file named "3CXDesktopApp.exe" is executed, it first loads a malicious file called "ffmpeg.dll". This DLL file contains an RC4 key and decryption loop. Then, it loads a second malicious DLL file named "d3dcompiler_47.dll", which contains encrypted data.

 

The attacker then uses the RC4 algorithm to decrypt the data from the "d3dcompiler_47.dll" file. This results in the retrieval of a shellcode and a binary called "Payload1".

 

Fig4_win

Figure 4 - RC4 algorithm used to decrypt data from the DLL

 

Payload1

The DLL binary is a 64-bit file with a single export function name “DllGetClassObject”.

 

System information

The attacker obtains the MachineGuid by using the RegQueryValueExA function and examining the registry path SOFTWARE\Microsoft\Cryptography.

 

Fig5_win

Figure 5 - Gathering MachineGuid

 

Payload1 is designed to download an icon file from a Git project.

 

Fig6_win

Figure 6 - Download request

 

At the time of analysis, the GitHub files were no longer available on Git. However, we were able to obtain the icon file from open-source. Upon examining the icon file, it was discovered that the attacker had appended base64-encoded and AES-GCM encrypted data at the end of the downloaded icon image. This appended data after decryption might connect to a C2 domain which would further download payload2.

 

Fig7_win

Figure 7 - Icon image at the end

 

Payload2

We also investigated the subsequent payload (payload2). This payload is a 64-bit DLL binary file that contains only one export function named "DllGetClassObject".

 

It has been designed to retrieve the HostName, DomainName, and OS version information from the victim's machine using the NetWkstaGetInfo() and RtlGetVersion() Windows APIs.

 

Fig8_win

Figure 8 - Grabbed system information

 

The stealer has been observed targeting popular web browsers such as Chrome, Microsoft Edge, Brave, and Firefox with the goal of extracting sensitive data from the victim's browsing history and the “places.sqlite” database.

 

In order to achieve this, the stealer runs a specific query to retrieve the latest 500 browsing details from the victim's machine. All the collected information is shared with the attacker server.

SQL query:

SELECT url, title FROM urls ORDER BY id DESC LIMIT 500

SELECT url, title FROM moz_places ORDER BY id DESC LIMIT 500

 

Fig9_win

Figure 9 - Reading browser information

 

The attackers had also infected the macOS 3CX app. The analysis below details the macOS version of compromised 3CXDesktopApp.

 

macOS Platform

 

Infection flow

The Figure 10 below illustrates the malicious operation on the macOS platform.

 

Fig10_mac

Figure 10 - RC4 algorithm

 

After the installation of 3CXDesktopApp the application is installed on path “/Applications/3CX Desktop App.app/Contents/MacOS/3CX Desktop App”

The malicious library is located on the following path: “/Applications/3CX Desktop App.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Libraries/libffmpeg.dylib” 

 

Fig11_mac

Figure 11 - Malicious library in the folder

 

The entrypoint of the libffmpeg.dylib module includes a reference to the "run_avcodec" export function, which is responsible for creating a new “pthread with the thread entry point located at virtual address (loc_48430) as shown in Figure 12 below.

 

Fig12_mac

Figure 12 - Pthread creation

 

All the strings are hardcoded and every time the file XORs it with “0x7a” to get the decrypted strings. The XOR decryption results in file path "~/Library/Application Support/3CX Desktop App/” which is then concatenated with the string “.session-lock '' to create a file location "~/Library/Application Support/3CX Desktop App/.session-lock". The program then attempts to open this file.

 

Fig13_mac

 Figure 13 - Decryption of path and ”.session-lock” file open code

 

All the strings are hardcoded and every time the file XORs it with “0x7a” to get the decrypted strings.

It then fetches the product version info by reading below plist file:

/System/Library/CoreServices/SystemVersion.plist ”

It tries to create a file named “.main_storage and UpdateAgent”

It decrypts the User Agent which is also hardcoded via XOR.

 

Fig14_mac

Figure 14 - Hardcoded User Agent bytes

 

The decryption loop (XOR) is shown in Figure 15 below.

 

Fig15_mac

Figure 15 - Decryption of hardcoded bytes to get UserAgent 
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.5359.128 Safari/537.36

 

We also observed that it adds various HTTP headers and it then tries to connect with C2 domains which are also obtained by decoding hardcoded bytes with XOR “0x7a”. 

 

In the macOS version we observed that all the C2 domains are hardcoded inside the malicious dylib and whereas in the Windows version there is an extra stage to get the C2 domains.

 

Once the payload has been downloaded from the C2 server, it makes the payload executable.

 

Below Figure 16 illustrates how the payload bytes are written into the file location by using “fopen()” function with “wb” mode. After that, the payload executable permission is changed via chmod.

 

Fig16_mac

 Figure 16 - Second Payload Execution

 

At the time of this analysis, the C2 domains were down, so we could not acquire the second stage payload. However, our team is actively monitoring the situation and will update the blog as we find more details.

 

Hunting queries and YARA rules for Uptycs customers are provided below, along with the IOCs for Windows and macOS.

 

IOCs

 

Details of the hash, agent, and URL for the analyzed Windows sample were obtained.

 

  File name

MD5

  MSI

0eeb1c0133eb4d571178b2d9d14ce3e9

  3CXDesktopApp.exe

9833a4779b69b38e3e51f04e395674c6

  ffmpeg.dll

74bc2d0b6680faa1a5a76b27e5479cbc

  d3dcompiler_47.dll

82187ad3f0c6c225e2fba0c867280cc9

  payload1

cea0696d7552b819f1481d8d82735239

  Icon

71d5b9bfd6bf37ff5aa9752b2b6d5af1

  Payload2

7faea2b01796b80d180399040bb69835  

 

 User Agent

 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)     3CXDesktopApp/18.11.1197 Chrome/102.0.5005.167 Electron/19.1.9 Safari/537.36

  URL

  https://raw.githubusercontent.com/IconStorages/images/main/icon%d.ico

 

Details of the hashes and URLs for the analyzed macOS sample were obtained.



  File Name

MD5

  3CX Desktop App.dmg

d5101c3b86d973a848ab7ed79cd11e5a

  3CXDesktopApp-18.11.1213.dmg

5729fb29e3a7a90d2528e3357bd15a4b

 

Related Hashes

 

  Md5

Platform

  9833a4779b69b38e3e51f04e395674c6

Windows  

  bb915073385dd16a846dfa318afa3c19

Windows

  f3d4144860ca10ba60f7ef4d176cc736

Windows

  d5101c3b86d973a848ab7ed79cd11e5a

macOS

  ca8c0385ce2b8bdd19423c8b98a5924b

macOS

  5729fb29e3a7a90d2528e3357bd15a4b

macOS

  3703770e32820397c6e7e1e1221e6d0d

macOS

 

Domain/URLs

 

  akamaicontainer[.]com

msstorageboxes[.]com

  akamaitechcloudservices[.]com

officeaddons[.]com

  azuredeploystore[.]com

officestoragebox[.]com

  azureonlinecloud[.]com

pbxcloudeservices[.]com

  azureonlinestorage[.]com

pbxphonenetwork[.]com

  dunamistrd[.]com

pbxsources[.]com

  glcloudservice[.]com

qwepoi123098[.]com

  journalide[.]org

sbmsa[.]wiki

  msedgepackageinfo[.]com

sourceslabs[.]com

  msstorageazure[.]com

visualstudiofactory[.]com  

  zacharryblogs[.]com

 

 

Hunting Queries

 

The following queries will help Uptycs customers determine whether the 3CXDesktopApp is running in their environment.

 

Uptycs Process Events hunting query to discover 3CXDesktopApp in the environment. Further investigation is required to determine if the malicious 3CXDesktopApp is being used when this query returns results:

 

  • select * from process_events where path like '%3CXDesktopApp%' order by time desc

Uptycs DNS Lookup Events hunting query to search for the IOCs in historical data:

 SELECT * FROM

  dns_lookup_events

 WHERE

    (question LIKE '%akamaicontainer.com%'

    OR question LIKE '%akamaitechcloudservices.com%'

    OR question LIKE '%azuredeploystore.com%'

    OR question LIKE '%azureonlinecloud.com%'

    OR question LIKE '%azureonlinestorage.com%'

    OR question LIKE '%dunamistrd.com%'

    OR question LIKE '%glcloudservice.com%'

    OR question LIKE '%journalide.org%'

    OR question LIKE '%msedgepackageinfo.com%'

    OR question LIKE '%msstorageazure.com%'

    OR question LIKE '%msstorageboxes.com%'

    OR question LIKE '%officeaddons.com%'

    OR question LIKE '%officestoragebox.com%'

    OR question LIKE '%pbxcloudeservices.com%'

    OR question LIKE '%pbxphonenetwork.com%'

    OR question LIKE '%pbxsources.com%'

    OR question LIKE '%qwepoi123098.com%'

    OR question LIKE '%sbmsa.wiki%'

    OR question LIKE '%sourceslabs.com%'

    OR question LIKE '%visualstudiofactory.com%'

    OR question LIKE '%zacharryblogs.com%'

   )

 

YARA Hunting Queries:

Windows

Query to scan for malicious DLLs

select * from yara where count > 0 and path like 'C:\Users\%\AppData\Local\Programs\3CXDesktopApp\app\%%' and rule = 'rule Uptycs_3cxTrojanLoader_windows

{

meta:

malware_name = "3cxTrojanLoader"

description = "3cxTrojanLoader is a trojan that covertly attaches itself to legitimate executable files and activates when the file is launched on the victim computer."

author = "Uptycs Inc"

version = "1"

md5 = "74bc2d0b6680faa1a5a76b27e5479cbc"

 

strings:

$string_rc4alogrithm = {8A 94 04 50 03 00 00 00 D1 02 8C 04 50 04 00 00 44 0F B6 C1 46 8A 8C 04 50 03 00 00 42 88 94 04 50 03 00 00 44 88 8C 04 50 03 00 00 48 FF C0 48 3D 00 01 00 00}

$string_xor = {46 8A 94 0C 50 03 00 00 45 00 D0 45 0F B6 D8 42 8A AC 1C 50 03 00 00 46 88 94 1C 50 03 00 00 42 88 AC 0C 50 03 00 00 42 02 AC 1C 50 03 00 00 44 0F B6 CD 46 8A 8C 0C 50 03 00 00 45 30 0C 0E 48 FF C1 48 39 C8 75 95}

$string_rc4key = "3jB(2bsG#@c7"  ascii wide

 

condition:

all of them

}'

 

macOS

 

Query to Scan for Malicious dylib File

select * from yara where count > 0 and path like '/Applications/3CX Desktop App.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Libraries/%%' and rule = 'rule Uptycs_3CXDropper

{

meta:

malware_name = "3CXDropper"

description = "3CXDropper is a malicious Dynamic Library which is loaded into 3CXDesktopApp and downloads payload from C2."

author = "Uptycs Inc"

version = "1"

md5 = "660ea9b8205fbd2da59fefd26ae5115c"

platform = "macOS"

date = "31-03-2023"

 

strings: 

$3CXDropper_0 = {80 B4 04 30 13 00 00 7A 48 FF C0 48 83 F8 75 75 EF} //XOR with 7a 

$3CXDropper_1 = {49 89 EE 48 89 44 24 10 0F 28 05 E4 17 1C 00 0F 29 84 24 90 13 00 00 0F 28 05 C5 17 1C 00 0F 29 84 24 80 13 00 00 0F 28 05 A6 17 1C 00 0F 29 84 24 70 13 00 00 0F 28 05 87 17 1C 00 0F 29 84 24 60 13 00 00 0F 28 05 68 17 1C 00 0F 29 84 24 50 13 00 00 0F 28 05 49 17 1C 00 0F 29 84 24 40 13 00 00 0F 28 05 2A 17 1C 00 0F 29 84 24 30 13 00 00 48 B8 55 4F 49 4D 54 49 4C 7A 48 89 84 24 9D 13 00 00 31 C0} //XOR

$3CXDroppertwo_2 = {37 15 00 13 16 16 1B 55 4F 54 4A 5A 52 2D 13 14 1E 15 0D 09 5A 34 2E 5A 4B 4A 54 4A 41 5A 2D 13 14 4C 4E 41 5A 02 4C 4E 53 5A 3B 0A 0A 16 1F 2D 1F 18 31 13 0E 55 4F 49 4D 54 49 4C 5A 52 31 32 2E 37 36 56 5A 16 13 11 1F 5A 3D 1F 19 11 15 53 5A 39 12 08 15 17 1F 55 4B 4A 42 54 4A 54 4F 49 4F 43 54 4B 48 42 5A 29 1B 1C 1B 08 13 55 4F 49 4D 54 49 4C 7A}

// Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.5359.128 Safari/53

$3CXDroppertwo_3 = {55 29 03 09 0e 1f 17 55 36 13 18 08 1b 08 03 55 39 15 08 1f 29 1f 08 0c 13 19 1f 09 55 29 03 09 0e 1f 17 2c 1f 08 09 13 15 14 54 0a 16 13 09 0e}

// System/Library/CoreServices/SystemVersion.plist 

$3CXDroppertwo_4 = {25 25 0e 0f 0e 17 1b 47}

// __tutma=



condition:

all of ($3CXDropper_*) and 1 of ($3CXDroppertwo_*)

}'