Transmission is a popular BitTorrent client for Mac, over the weekend it emerged that a version of their app available from the projects website had been swapped with another version.
Below is more information, as well as a script that should alert or clean up affected Macs.
- 1 What Happened?
- 2 Some Things To Mention
- 3 The Method
- 4 Gimme some main
- 5 The Script
- 6 Acknowledgements
- 7 Next Steps
- 8 Transmission.app
- 9 Removal From Smart Group
The story of what happened is written up here, (amongst numerous other sources).
I’ll not recap that here, but please read that post as i’ll reference it throughout this one.
Once I digested the above, I was on the hunt for an affected copy of the app to run on a VM to see if how I could detect & maybe remove the malware.
Luckily, I had a VM that had been powered off for a while & as such did not have the most up to date XProtect data to block the app.
Before we proceed, another post you should read is Tim Sutton’s post here.
TL:DR, If you’re disabling SoftwareUpdate’s schedule, you might be putting your Macs at risk of things such as KeRanger etc.
Some Things To Mention
Below are several points that I feel are worth mentioning as they help explain the method to the madness that is the script in the following section.
At this point you might just think detection via the JSS is simply a matter of a Smart Group looking for Transmission.app 2.90, RONG.
By default the JSS gathers inventory for apps in the below locations:
So if the app your looking for is anywhere else, you JSS will not pick it up unless you have added additional paths under the above.
The above can be located at the following in the JSS: Computer Management > Computer Inventory Collection > Software.
GateKeeper & XProtect will protect us!
If a copy of the infected app was ran before XProtect was updated, the app will still be able to run as it’s quarantine flags have been removed & so it will not come under their scrutiny again.
But, Apple pulled the dev cert!
The below is the output of spctl on the VM, which the assessment failed the app would still run due to the quarantine flags having been removed:
Closing The Stable Door After The Horse Has Bolted
It’s worth a note about AutoPKG recipes & this situation.
If a recipe is for a signed app, then CodeSignatureVerifier should be added to the recipe.
With those fields set, AutoPKG will then verify the code signature of the app against what’s in the recipe & fail if it finds a difference.
So, if downloading Transmission via an AutoPKG recipe please verify that it uses CodeSignatureVerifier & if it doesn’t log an issue with the author.
One last thing we could do as JSS Admins is to add the kernel_service under “Restricted Software” as this seems to be the service that KeRanger runs under, but this will still not cure the patient & so I’ve not gone down that route.
Well, none of my Users are admins.. So we’re OK.
The below is taken from the Palo Alto article, linked at the top of this post:
After connecting to the C2 server and retrieving an encryption key, the executable will traverse the “/Users” and “/Volumes” directories, encrypt all files under “/Users”, and encrypt all files under “/Volumes” which have certain file extensions. There are 300 different extensions specified by the malware, including: Documents: .doc, .docx, .docm, .dot, .dotm, .ppt, .pptx, .pptm, .pot, .potx, .potm, .pps, .ppsm, .ppsx, .xls, .xlsx, .xlsm, .xlt, .xltm, .xltx, .txt, .csv, .rtf, .tex</li><li>Images: .jpg, .jpeg Audio and video: .mp3, .mp4, .avi, .mpg, .wav, .flac</li><li>Archives: .zip, .rar., .tar, .gzip</li><li>Source code: .cpp, .asp, .csh, .class, .java, .lua</li><li>Database: .db, .sql Email: .eml Certificate: .pem
NOTE: "the executable will traverse the “/Users” and “/Volumes” directories, encrypt all files under “/Users”, and encrypt all files under “/Volumes” which have certain file extensions."
Typically the encryption starts after 3 days of being infected, but there may be more aggressive variants out there.
Due to the above, detecting the app in only /Applications/ is not enough.
Won’t FileVault2 help?
FileVault2 is full volume encryption & the volumes are unlocked when a user logs in, which means that the files are still vulnerable to this.
FileVault2 is not an anti-malware tool.
So the below is a breakdown of the script I wrote to try & detect & remove KeRanger.
This is a script to be run as an EA, it’s an ‘Active-EA’ & will have a value when something has been found or done.
I took this approach to then be able to setup a Smart Group with the JSS notifying of any changes to group & keeping things self contained.
Below is an example of the Smart Group’s scope:
The script logs it’s actions to /Library/Logs/KeRanger-Remove.log, these are timestamped with the logs contents being read into the EA as per:
Gimme some main
I’ll now run through the scripts main block, step by step to advise what it’s doing & why.
This returns the time that the EA was run, this is used for some date comparisons later on.
The path of the log file mentioned above.
This configures the logging for the EA.
os.system(‘killall -9 kernel_service’)
The script kills the ‘kernel_service’ process, no fancy checks to see if it’s running.
This function checks to see if the log file for the EA exists, if it does not it enables Automatic Checking in SoftwareUpdate.plist & then tries to update XProtect via:
The log file check is so that the EA only enables the automatic check once in case it’s wanted to be removed later, but you really shouldn’t disable it.
Enabling this does bring the software update nags though but is the only way to update XProtect:
This will check each account in for /Users/*/Library/.kernel_time, if found gets encryption time from within the file & calculates 3 days from that.
The compare the date in 3 days from the time in the file against the value of RUN_TIME & will log if the EA thinks that the User might have had some files encrypted.
This is a bit of guess work though.
Lastly, it deletes the /Users/*/Library/.kernel_time files.
Check for /Users/*/Library/.kernel_pid, if found gets the pid & kills the process & deletes the file.
The above is a Composer snapshot taken after infecting my VM.
Checks for all Transmission apps, gets version & if 2.90 checks for General.rtf file within the app bundle. If found deletes app bundle.
Only some copies of 2.90 were affected & there are some perfectly safe copies of 2.90 out there so no need to delete them.
Checks for DMGs named ‘Transmission*.dmg’ & re-quarantines, this coupled with this means that previously opened versions of the app that are infected will be blocked by XProtect (as long as clients can get the needed config-data).
The above is what you’ll see when trying to launch an affected app from a DMG that has been re-quarantined.
Yep the dates a bit back to the future past, but it works.
This is the date that the log file was modified.
if date.today() == MOD_DATE.date()
If the log file was modified today, it’s contents are read into the EA.
The script should display below, but can be found here.
If you deploy Transmission to your Macs, update them to 2.92 ASAP, being mindful of the AutoPKG recipe you may use.
Removal From Smart Group
To remove a client from the Smart Group, remove from the Mac any Transmission DMG’s & then empty the contents of the log file, then run recon.
They will only be re-added to the smart group if something triggers one of the above actions which are then logged.