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
If you're running a network tool such as DNSMonitor (objective-see.org/products/utili…) you'll be able to see capture/view this request.
...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
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.