How to make your org more resilient to common Mac OS attacks

· 6 MIN READ · ANDREW PRITCHETT · JUL 23, 2019 · TAGS: EDR / Get technical / How to / Threat hunting / Vulnerability

I remember when I got my first MacBook. My first “malware-less” computer, I thought to myself.

Fast forward a few years to when I started working in the information security world and my feelings of invincibility depreciated pretty rapidly.

Although Mac OS attacks occur less often than Windows OS attacks, the implications of an attack happening on either OS can be lethal.

If you work in cybersecurity, you know that attack trends are a thing. There’s always some new hotness in attacker Tactics, Techniques, and Procedures (TTPs), which often parallels the TTPs of security red teamers. Why? Well, when you see something that works, why reinvent the wheel?

At Expel, we’re seeing more and more orgs utilizing Mac OS, yet there’s still little discussion about practical enterprise security for Mac OS. But because plenty of our customers run Mac OS systems, we’re calling attention to a few recent attack trends we’re seeing and how you can make your org (and devices) more resilient.

Recent Mac OS activity and detections

There are two TTPs I’ve seen recently that target Mac OS.

The first involves the use of persistent interactive scripting interpreters to evade command line auditing. The second involves the use of launchd persistence to download encoded text and compile the encoded text into binary in order to evade perimeter content-based filtering and host-based AV. Using encoded commands from PowerShell is an effective technique that’s been used by Windows attackers for a long time … Macs are no longer immune.

Technique 1: Execution of persistent interactive scripting interpreters:

What is it?

Like PowerShell and CMD with Windows, what’s a Mac without Bash and Python? Plenty of people love Python because you can use it as both a scripting interpreter and an interactive console.

The only downside? Some of the features we love about Python also make it a security threat. For instance, I love how I can quickly write a Python script to conduct common Bash-like functions like making new files and directories. However, if you want to use the Bash syntax we all know and love, you can invoke Bash directly from Python and execute a command within an interactive Bash console. Using Bash, the ability to execute commands are nearly limitless on a Mac.

Immediately following successful lateral movement to a Mac OS host, I’ve seen attackers use “/bin/bash” to execute “/usr/bin/nohup” with parameters for an interactive Python console. If you’re not familiar with the native BSD utility, the “nohup” utility invokes another utility — in this case it’s Python — with its arguments and tells your system to ignore the “SIGHUP” signal. This is a problem because “nohup” allows the utility to remain active and hidden in the background even after a user signs out.

Using Python, attackers then execute another interactive Bash terminal. He or she uses that interactive Bash terminal to execute Curl — which lets him or her download malicious shellcode from an online code repository like GitHub or Paste Code. Once the attacker gets his or her hands on the data they’re looking for, that data is then executed locally. The acquired data is either exploit payloads like keyloggers and Keychain dumpers, or utilities to further the attacker’s mission like media streamers for data exfiltration.

The process looks something like this:

Though this technique doesn’t make it impossible to detect malicious activity, it definitely helps obscure the attacker’s activity. For example:

1. Following the compromise of a user account with sudo permissions, an attacker executes a Python console which spawns another Bash under root context.

2. The attacker uses a utility such as Curl to download raw text, using it as shell code or converting it to binary.

3. The shell code or binary code is executed under root context.

4. Now the Bash history for the Curl activity mentioned above isn’t in the user’s “.bash_history” file or “/var/root/.sh_history.” And it’s not mentioned in the Mac OS unified logs. So the crafty attacker goes undetected.

How do you detect this type of attack?

To detect this type of activity on your network, your best bet is to look at your Endpoint Detection and Response (EDR) tech recording process activity from the kernel level.

Using your EDR, look for common code syntax to spawn a TTY shell from another shell. Try any of the following queries:

  • python -c ‘import pty; pty.spawn(“/bin/sh”)’
  • python -c ‘import pty; pty.spawn(“/bin/bash”)’
  • bash -i
  • /bin/sh -i
  • perl —e ‘exec “/bin/sh”;’
  • ruby: exec “/bin/sh”

You can also look for any of these processes as parent of a TTY shell:

  • vi (or) vim
  • nmap
  • python
  • perl
  • ruby
  • Java

The next step in the process is to look for instances where the child process is a parent of “curl” or “wget,” and where the process arguments point to an online code repository. Here are some examples of code repository domains that — in this context — should raise a red flag:

  • paste[.]ofcode[.]org
  • pastecode[.]xyz
  • pastiebin[.]com
  • paste[.]org
  • raw[.]githubusercontent[.]com
  • wstools[.]io
  • gist[.]github[.]com
  • pasted[.]co
  • etherpad[.]org
  • Snipplr[.]com

By running the activities above using Carbon Black Response (one of the EDR techs that some of our customers use), I produced this recorded process tree:

Looking at the curl process arguments resulting from the child bash shell, there’s a command line argument noting a download from “raw[.]githubusercontent[.]com”:

How do I protect my org from this kind of attack in the future?

1. Determine if your engineering team has a business and/or production justification for granting any employees access to any of the online code repositories referenced above. If not, black list the domains using your network permeter tech.

2. Use your EDR tech to set up a recurring hunt or custom detection to monitor for the activity discussed above.

3. Consider restricting standard user accounts from using “sudo” or “root,” or implement a privilege control service like “Make Me Admin” or “Privileges.app” so that user accounts can only be elevated to administrator level on a temporary basis.

4. If you don’t have an EDR, go get one. Relying on local host-based detection is risky at best — without an EDR, it’s easy to miss this type of activity.

Technique 2: Launchd persistence to download encoded text

What is it?

I first saw this technique used by a sophisticated commodity malware masquerading as a legit media update. When an unsuspecting user tries to update the tech, the malware establishes persistence via “launchd” and creates and executes a randomly named sub-process from “/private/tmp.” Launchd allows an attacker to continually execute the malicious app every time a user logs on. Even if the user kills and deletes the processes running from “/private/tmp” the malicious process recreates the “/private/tmp” process again following a successful logon.

The sub-process running from “/private/tmp” then executes “/bin/bash” and is followed by a series of strategic bash commands to assemble a malicious binary from raw text. A sub-process uses “/bin/bash” to pass a block of encoded text in an anonymous pipe which is then decoded by executing “/usr/bin/base64.” The decoded value is passed back through the anonymous pipe to “xxd” and formatted into hex. Once in hex, it’s then reverted from hex to binary. The resulting malicious binary is then executed on the local host while leaving no evidence of a binary download at the perimeter of the network. The process looks like this:

How do you detect this type of attack?

Just like the first attack I described, your EDR tech is your best friend for detecting this one. However, identifying the specific commands executed by the attacker is a multi-step (aka not quick) process. Why? Because of the way that the kernel assigns the “file system value” in place of the actual value being passed in the anonymous pipe.

The screenshot below shows an actual process tree of an attacker attempting this technique as recorded by Crowdstrike Falcon. The command line for base64 specifies to decode (“–decode”) the encoded value (“/dev/fd/63”). The encoded value is actually a base64 string, but you can’t see the true value the attacker is attempting to decode.

This creates an extra step for analysts in the investigation process.

How can you discover that an attacker is storing data in an anonymous pipe? Use your EDR tech to look for processes with “/dev/fd/63” in command line arguments, especially if the process has the ability to encode, decode, archive or compile binaries. The occurrence of “/dev/fd/63” is not that common; however, you’ll run into false positives. Once you find a couple suspicious processes with “/dev/fd/63,” make note of the process names, command lines, hosts and users associated with them.

Now use your EDR technology to either “tail” or “grep” the user’s Bash history file for the process name and command line which included “/dev/fd/63” in its command line arguments.
Here’s how to do it using Carbon Black Response:

1. Use your EDR tech to get a copy of the user’s bash history file:

2. Download the Bash history file and use a combination of “tail” and “grep” to identify the process — in this case “base64” — command which generated the recorded activity by your EDR tech:

3. The long base64 string follows the “–decode” argument. You can use any number of tools or utilities, including “base64”, to safely decode the string and find out what the attacker was trying to do.

How do I protect my org from this kind of attack in the future?

To make your org more resilient to this type of technique in the future, use your EDR tech to set up a recurring hunt or custom detection to monitor for processes with “/dev/fd/63” in command line arguments, especially if the process has the ability to encode, decode, archive or compile binaries. Then follow the suggested triage steps above.

Need some help setting up a new hunt? Read our post on getting started with threat hunting.

Bonus tip: all of these resilience actions will benefit your company’s security posture if you’ve got Linux hosts in your environment, too.


Whether its commodity malware or obfuscated command execution on Mac OS that keeps you up at night, there are some easy steps to take for detecting and triaging the problems … and keeping them from happening again.

Have questions about detecting attacks on Mac OS, or want to know more about hunting for these types of threats? Send us a note.