RE: The 3CX VOIP supply chain attack, vendors have stated that macOS was also targeted - but I couldn't find any specific technical details (yet) ๐๐โ ๏ธ
One vendor stated, "we cannot confirm that the Mac installer is similarly trojanized"
...let's dive in! 1/n ๐งต
We'll start with 3CXDesktopApp-18.12.416.dmg
(SHA 1: 3DC840D32CE86CEBF657B17CEF62814646BA8E98)
It contains a *notarized* app ("3CX Desktop App.app") ...meaning Apple checked it for malware "and none was detected" ๐โ ๏ธ 2/n
This app is massive - 381mb ๐คฏ
...let's focus on libffmpeg.dylib
found in the App's /Contents/Frameworks/Electron\ Framework.framework/Versions/A/Libraries directory
Shady ya?
...and means static analysis is going to be painful, and thus not recommended! 5/n
So, let's debug it! ๐ฌ
Debugging a dylib is a bit tricky - so I wrote a simply loader that will dlopen it.
% lldb dlopen libffmpeg.dylib
We can then run the loader in a debugger and set a breakpoint the dlopen function ...which breaks when the libffmpeg.dylib is loaded 6/n
We can then just instruct the debugger to jump to and begin executing the shady thread function at 0x48430 by changing the $pc register.
(lldb) reg write $pc 0x100048430
Now we can start stepping through the code to coerce it to reveal its secrets ๐ค 7/n
First, it de-xors the following path: ~/Library/Application Support/3CX Desktop App/.session-lock
It then attempts to open this file. If it does not exist it bails (so you'll have to create it to keep debugging). 8/n
It then queries the host to get the OS version, computer name, etc, etc.
It appears to encrypt then write out this info another file in the same 3CX Desktop App directory, named ".main_storage": 9/n
After various anti-debugging logic (e.g. timing checks) it builds a URL to query. We can easily dump this in the debugger: https[://]pbxsources[.]com/queue
This URL is mentioned as an IOC by @Sophos, who performed analysis on the Windows version
After setting a static user-agent and adding host info, it connects out ๐ก
This may trigger an firewall alert (initially on the DNS resolution).
Note: alert will originate from the program hosting the malicious dylib (e.g. loader or "3CX Desktop App.app" ) 11/n
Unfortunately the URL (pbxsources[.]com) is now offline ...so the malware doesn't get the HTTP 200 OK it wants, and thus goes off to snooze ๐ฅฒ 12/n
Continued static analysis appears to show the malware expects to download a 2nd-stage payload.
This appears to be saved as "UpdateAgent" (in the Application Support/3CX Desktop App/ directory).
I don't have access to this binary, so what it does is a mystery!๐คท๐ฝโโ๏ธ 13/n
For IoCs, I don't know what "3CX Desktop App.app" normally does, but the malicious .dylib interacts w/ the following files (~/Library/Application Support/3CX Desktop App/):
Interested in learning more about Mac malware & analysis? ๐พ๐๐ฌ
You're in luck! I've written a whole book on this topic: taomm.org
It's 100% free online, while all royalties from sales of the printed version are donated to the Objective-See Foundation ๐
Better yet, I want to invite you to our Mac Security conference, "Objective by the Sea" (#OBTS) which will be held in Spain this October: objectivebythesea.org/v6/index.html
This attempts to open a file, config.json (found in ~/Library/Application Support/3CX Desktop App).
It then extracts values from the keys: "url" & "AccountName":
(I made a fake config.json file, so the malware would keep executing).
With the "url" & "AccountName" extracted from the config.json, the malware then calls a function named "read_config"
This opens/reads in the contents of the .main_storage file (recall that created by libffmpeg.dylib, and contains a UUID) and de-XORs it with the key 0x7a
Next it concats/encrypts the "url" & "AccountName" values via a function named "enc_text". Then combines this + the UUID (from .main_storage) w/ the following format:
On to the "send_post" function. This takes as its parameters the URI "https://sbmsa[.]wiki/blog/_insert" and the "3cx_auth_id=..." string:
First, it configures an url request with a hardcoded user-agent string ("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36...") and stores the "3cx_auth_id=..." string in the "Cookie" HTTP header.
Then, it makes the request to https://sbmsa[.]wiki/blog/_insert
...and associate it with the pid/process signing id of the malware:
Once UpdateAgent has made the request ...it simply exits ๐ง
Maybe this sample is incomplete or is a basic "placeholder" binary that could be updated/swapped out at any time for specific targets of interest. (Supply-chain attacks provide a lot of "non-relevant" targets). ๐ค
โข โข โข
Missing some Tweet in this thread? You can try to
force a refresh
First, (can't stress this enough), this variant though *compiled* for macOS is not specifically designed for macOS.
It's buggy (crashes), has an invalid signature, nor takes into account as of macOS's file-system security mechanisms.
So, impact to macOS users (for now): 0
Still as noted by others, the fact that a large ransomware gang (LockBit) has apparently set its sights on macOS, should give us all pause for concern.
So, wise to dig into this (test?) sample & gain a throughout understanding of its capabilities and approaches ๐พ๐ฌ๐ฉ๐ผโ๐ซ
Ever wondered what it's like writing security tools for macOS? ๐ค
As Apple provides no official way to detect what app is using the webcam/mic, OverSight simply monitored the system log.
This was (independently) reported to Apple, who decided to assign it a CVE/patch it ๐ฅฒ๐คฆ๐ปโโ๏ธ
Unfortunately this means OverSight is now broken on macOS 13.3
Apple still doesn't provide a method for security tools to determine what app is accessing the mic/camera, even after years of requesting (begging) for this capability ๐ญ
There are other log msgs that can still be used (even on macOS 13.3+) to determine what App is using the mic/camera
...but I'm reluctant to update OverSight if they will just be reported and given CVEs ๐
After creating a custom C&C server, we can uncover the malwareโs full capabilities - simply by asking (tasking) the right questions! ๐คญ
1๏ธโฃ First, we must understand how the malware figures out how to find its C&C server - so we can coerce it to talk to our C&C instead!
As this (encrypted) info is embedded within the malware, we can write a simple decryptor/encryptor to (re)configure the malware ๐พ๐โ๐ผ๐ โ ๐ฅโ
2๏ธโฃ Second, we need to understand its protocol, so we can task the malware to reveal its capabilities.
A brief triage of the malware's binary shows us it sets up a local server and registers various "routes" - taskable via requests from a remote C&C server.