For Red Team members who are already familiar with Linux, there may be some confusion when it comes to using a Mac. Many people believe that macOS and Linux are very similar operating systems, and in many ways, they are. Both are built on Unix, and both rely on the command line interface for much of their functionality.

However, there are some important differences between macOS and Linux that are important to understand. In this article, we’ll explore the differences between macOS’s Unix underpinnings and Linux, with a focus on how these differences affect Red Team members.

The History of macOS and Unix

To understand the differences between macOS and Linux, it’s important to understand the history of macOS and Unix. macOS is based on the Unix operating system, which was originally developed by AT&T Bell Labs in the 1970s.

In the 1980s, a group of developers at the University of California, Berkeley created an open-source version of Unix called BSD (Berkeley Software Distribution). BSD became very popular among universities and research institutions, and it eventually became the basis for many modern operating systems, including macOS.

The macOS operating system is built on a variant of the Unix operating system called Darwin. Darwin is an open-source operating system that was created by Apple in the late 1990s. It is based on the BSD operating system and includes many of the same components as Linux, such as the GNU Compiler Collection (GCC) and the Bash shell.

Differences between macOS and Linux

While macOS and Linux are both Unix-based operating systems, there are several important differences that Red Team members should be aware of.

Filesystem Structure

One of the most significant differences between macOS and Linux is their filesystem structure. macOS uses the HFS+ filesystem, while Linux uses the Ext4 filesystem. While both use hierarchical directory structures, there are some important differences in the way the structures are organized.

On macOS, the root directory is “/”, and there are several top-level directories that contain system files and folders. For example, the “/Applications” directory contains installed applications, while the “/Library” directory contains system libraries and resources. Additionally, the “/Users” directory contains home directories for all users on the system.

On Linux, the root directory is also “/”, but the filesystem is organized in a tree-like structure with multiple mount points. Each mount point represents a different partition or device, and can be mounted at different locations in the filesystem. For example, the “/boot” mount point contains boot loader files, while the “/home” mount point contains home directories for all users on the system.

Additionally, there are some other important differences to be aware of when working with the macOS filesystem. For example, macOS uses resource forks and extended attributes to store additional metadata about files and folders. This can affect how files are displayed and transferred between different systems.

Another difference to be aware of is that macOS uses the “Finder” application as the primary interface for working with files and folders. While the Finder can be navigated using the command line, it can be helpful to learn how to use the Finder for more complex file management tasks.

Command Line Tools

Another significant difference between macOS and Linux is the command line tools that are available. While many of the same tools are available on both systems, there are some important differences to be aware of.

Another difference to be aware of is that macOS uses BSD-based versions of many of the same tools that are available on Linux. For Red Team members who are familiar with Linux, it is important to note that some of the parameters for these BSD-based commands may be different than what is found on Linux. This can be especially important when writing scripts or automating tasks, as the differences in command syntax can result in unexpected results.

For example, the “ping” command, which is used to test network connectivity, works slightly differently on macOS than it does on Linux. On Linux, you can use “ping” with the “-c” option to specify the number of packets to send (e.g. “ping -c 5 google.com”), but on macOS, you need to use the “-t” option to specify the number of seconds to send packets for (e.g. “ping -t 5 google.com”).

Here are some examples of BSD-based commands that are commonly used on macOS and their differences compared to their GNU-based counterparts:

  • ps: The ps command on macOS is similar to the ps command on Linux, but the output format is different. On macOS, the output is in BSD format, which means that the columns are not named and the output may contain additional fields. For example, to display the process ID and name of all running processes on Linux, you can use the command ps -eo pid,comm. On macOS, the equivalent command would be ps -ax -o pid,command.
  • sed: The sed command on macOS is similar to the sed command on Linux, but it does not support the -i option to edit files in place. Instead, you need to use a temporary file and then rename it to the original filename. For example, to replace all occurrences of “foo” with “bar” in a file named test.txt on Linux, you can use the command sed -i 's/foo/bar/g' test.txt. On macOS, the equivalent command would be sed 's/foo/bar/g' test.txt > test.txt.tmp && mv test.txt.tmp test.txt.
  • netstat: The netstat command on macOS is similar to the netstat command on Linux, but it uses different options to display information about network connections. For example, to display all listening ports and their associated processes on Linux, you can use the command netstat -tlnp. On macOS, the equivalent command would be sudo lsof -iTCP -sTCP:LISTEN.
  • grep: The grep command on macOS is similar to the grep command on Linux, but it does not support the -P option for Perl-compatible regular expressions. Instead, you need to use the -E option to enable extended regular expressions. For example, to search for lines that contain the word “apple” and also end with a number on Linux, you can use the command grep -P 'apple.*\d$' file.txt. On macOS, the equivalent command would be grep -E 'apple.*[0-9]$' file.txt.
  • tar: The tar command on macOS is similar to the tar command on Linux, but it uses different options for creating and extracting archives. For example, to create a tar archive on Linux, you can use the command tar -czvf archive.tar.gz /path/to/files. On macOS, the equivalent command would be tar -czf archive.tar.gz /path/to/files. Additionally, to extract an archive on Linux, you can use the command tar -xvf archive.tar.gz. On macOS, the equivalent command would be tar -xf archive.tar.gz.

By understanding the differences between BSD-based and GNU-based command line tools, Red Team members can avoid unexpected behavior and ensure that their scripts and commands work as intended. While the differences in syntax can be frustrating at times, the stability and simplicity of BSD-based tools can make them a reliable choice for managing and automating tasks on macOS. Additionally, many of the BSD-based tools on macOS have additional options and features that are not available on their GNU-based counterparts, which can provide added functionality and flexibility.

User and Group Management

User and group management is another area where macOS and Linux differ. In Linux, users and groups are managed using the “useradd” and “groupadd” commands, respectively. On macOS, users and groups are managed using the “dscl” command, which interacts with the Directory Services system.

This difference can affect how Red Team members create and manage user accounts on macOS. For example, on Linux, you can create a new user account with the “useradd” command and specify the user’s home directory, password, and other settings. On macOS, you need to use the “dscl” command to create a new user account and then use additional commands to set the user’s home directory, password, and other settings.

Package Management

Package management is another area where macOS and Linux differ. On Linux, package management is typically handled by a package manager such as “apt” (used by Debian-based systems) or “yum” (used by Red Hat-based systems).

On macOS, package management is handled by the “Homebrew” package manager. Homebrew is a third-party package manager that can be used to install and manage software on macOS. While Homebrew is not built into macOS like “apt” or “yum” are built into Linux, it is widely used by developers and Red Team members who work on macOS.

Kernel and System Calls

The kernel and system calls are another area where macOS and Linux differ. The kernel is the core of the operating system, and it is responsible for managing system resources such as memory, processes, and files. System calls are the interface between user space (i.e. the applications running on the computer) and kernel space (i.e. the operating system).

While macOS and Linux both use Unix kernels, there are some differences in the way that they handle system calls. For example, on macOS, system calls are handled by the Mach microkernel, which provides a different set of system calls than the Linux kernel does.

This difference in system calls can affect how Red Team members write and execute code on macOS. For example, if you are writing a piece of code that relies on a particular system call, you may need to modify your code to work on both macOS and Linux.

Examples of macOS Commands

Now that we’ve explored some of the key differences between macOS and Linux, let’s take a look at some examples of macOS commands that Red Team members may find useful.

“sudo” Command

The “sudo” command is used to execute commands with administrative privileges. In macOS, the first user account created on the system is automatically added to the “sudoers” file, which allows that user to run commands with administrative privileges.

To run a command with administrative privileges, you can use the “sudo” command followed by the command you want to run. For example, if you want to install a package using Homebrew, you can use the following command:

sudo brew install package_name
“defaults” Command

The “defaults” command is used to read, write, and delete preferences for macOS applications. Preferences are stored as property lists (plist files), which are XML files that contain key-value pairs.

To read a preference, you can use the following command:

defaults read domain key

where “domain” is the domain name of the application (e.g. “com.apple.finder”), and “key” is the name of the preference.

To write a preference, you can use the following command:

defaults write domain key value

where “value” is the value you want to set for the preference.

To delete a preference, you can use the following command:

defaults delete domain key

For Red Team members, the defaults command can be useful for manipulating user defaults on a target system. Here are some examples of keys that might be of interest to a Red Team member:

  • com.apple.finder AppleShowAllFiles: This key controls whether hidden files are visible in the Finder. Setting this key to “true” can help reveal hidden files and directories that may contain sensitive data or configuration files.
  • com.apple.dock tilesize: This key controls the size of icons in the Dock. By setting the value to “0”, the Dock can be completely hidden from view, which can be useful for hiding running applications or backdoors.
  • com.apple.Safari IncludeDevelopMenu: This key controls whether the Develop menu is visible in Safari. The Develop menu provides access to a number of advanced features and can be useful for web application testing.
  • NSGlobalDomain AppleInterfaceStyle: This key controls the appearance of the user interface. By setting the value to “Dark”, the entire UI will be displayed in dark mode, which can be useful for reducing eye strain and making the interface less noticeable.
  • com.apple.screensaver askForPasswordDelay: This key controls the delay time before the screensaver password is required. By setting the value to “0”, the screensaver password will be required immediately, which can be useful for preventing unauthorized access to the system.
  • com.apple.Terminal SecureKeyboardEntry: This key controls whether or not keystrokes are displayed in the Terminal when entering passwords. Setting this key to “true” can help prevent others from seeing passwords or other sensitive information.

By using the defaults command to modify user defaults on a target system, Red Team members can customize the system settings and preferences to their advantage. It is important to note, however, that modifying user defaults without permission can be illegal and can have serious consequences. Red Team members should use the defaults command only for authorized security testing purposes.

“dscl” Command

The “dscl” command is used to manage users, groups, and computers on macOS. This command interacts with the Directory Services system, which is used to store user and group information on macOS.

To create a new user account, you can use the following command:

sudo dscl . -create /Users/newuser
sudo dscl . -create /Users/newuser UserShell /bin/bash
sudo dscl . -create /Users/newuser RealName "New User"
sudo dscl . -create /Users/newuser UniqueID 1001
sudo dscl . -create /Users/newuser PrimaryGroupID 20
sudo dscl . -create /Users/newuser NFSHomeDirectory /Users/newuser

This command creates a new user account named “newuser” with a home directory at “/Users/newuser” and a group ID of 20 (which corresponds to the “staff” group).

“tcpdump” Command

The “tcpdump” command is used to capture network traffic on macOS. This command can be useful for analyzing network traffic and identifying potential security issues.

To capture network traffic, you can use the following command:

sudo tcpdump -i en0 -s 0 -w /path/to/output/file.pcap

This command captures network traffic on the “en0” interface (which corresponds to the primary network interface on most Macs) and writes the output to a file at “/path/to/output/file.pcap”.

“launchctl” Command

launchctl is a command-line tool used to manage the launchd daemon on macOS. The launchd daemon is responsible for starting and stopping system services and user applications. It is the first process that runs when the system boots up, and it is responsible for launching all the other processes that are necessary for the system to function.

Here are some common commands used with launchctl:

  • sudo launchctl load /Library/LaunchDaemons/com.example.plist: Loads a daemon from a plist file located in the system-level LaunchDaemons directory. This will start the daemon immediately and also ensure that it starts up again whenever the system boots up.
  • sudo launchctl unload /Library/LaunchDaemons/com.example.plist: Unloads a daemon from a plist file located in the system-level LaunchDaemons directory. This will stop the daemon immediately and prevent it from starting up again when the system boots up.
  • sudo launchctl start com.example: Starts a service that has already been loaded into launchd. This command can be used to start a system-level or user-level service.
  • sudo launchctl stop com.example: Stops a service that has already been started. This command can be used to stop a system-level or user-level service.
  • sudo launchctl list: Lists all the services that are currently running in launchd. This command will show the name of the service, its process ID, and its status.
  • sudo launchctl list | grep com.example: Lists only the services that contain the specified search string. This command can be used to filter the output of the list command to show only the services that match a certain criteria.

Here’s an example of how to use launchctl to create and manage a simple daemon:

Create a plist file for the daemon. A plist file is an XML file that describes the properties and behavior of the daemon. Here’s an example of a simple plist file:

<?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>Label</key>
    <string>com.example.mydaemon</string>
    <key>ProgramArguments</key>
    <array>
      <string>/path/to/mydaemon</string>
    </array>
    <key>KeepAlive</key>
    <true/>
  </dict>
</plist>

This plist file specifies the name of the daemon (com.example.mydaemon), the command to run (/path/to/mydaemon), and the KeepAlive key, which tells launchd to automatically restart the daemon if it crashes.

Copy the plist file to the system-level LaunchDaemons directory:

sudo cp /path/to/com.example.mydaemon.plist /Library/LaunchDaemons/

Load the daemon into launchd:

sudo launchctl load /Library/LaunchDaemons/com.example.mydaemon.plist

This will start the daemon immediately and ensure that it starts up again whenever the system boots up.

Start or stop the daemon as needed:

sudo launchctl start com.example.mydaemon
sudo launchctl stop com.example.mydaemon

By using launchctl to manage daemons and services, Red Team members can ensure that critical system processes are started and stopped as needed, and that they are automatically restarted if they crash or fail. This can help ensure the stability and reliability of the macOS system, and make Red Team members’ jobs easier when managing multiple systems.

Additionally, launchctl can be used to manage user-level services as well. User-level services are launched when a user logs in and continue to run until the user logs out. User-level services can be useful for automating repetitive tasks or running background processes.

Here’s an example of how to use launchctl to create and manage a user-level service:

Create a plist file for the service. Here’s an example of a simple plist file that launches a script to display a random quote:

<?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>Label</key>
    <string>com.example.quote</string>
    <key>ProgramArguments</key>
    <array>
      <string>/usr/bin/python</string>
      <string>/path/to/quote.py</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
  </dict>
</plist>

This plist file specifies the name of the service (com.example.quote), the command to run (/usr/bin/python /path/to/quote.py), and the RunAtLoad key, which tells launchd to start the service immediately after the user logs in.

Copy the plist file to the user-level LaunchAgents directory:

cp /path/to/com.example.quote.plist ~/Library/LaunchAgents/

This will copy the plist file to the LaunchAgents directory for the current user.

Load the service into launchd:

launchctl load ~/Library/LaunchAgents/com.example.quote.plist

This will start the service immediately after the user logs in.

Start or stop the service as needed:

launchctl start com.example.quote
launchctl stop com.example.quote

In conclusion, launchctl is a powerful tool that can be used to manage daemons and services on macOS. One of the primary use cases for Red Team members is to use launchctl to persist a tool or backdoor on a target system. By understanding how to use launchctl to load and start services, Red Team members can ensure that their tools are started and running smoothly, and automatically restarted if they crash or are stopped. Additionally, launchctl can be used to manage user-level services, which can help automate tasks and make it more difficult to detect the presence of the backdoor or tool.

By using launchctl to persist a tool or backdoor, Red Team members can ensure that they maintain access to a target system even after a reboot or other system changes. Additionally, because launchctl is a built-in tool on macOS, it is less likely to be detected by antivirus software or other security tools. However, it is important to use launchctl responsibly and only for authorized security testing purposes, as misuse of this tool can result in serious consequences.

Conclusion

In conclusion, while macOS and Linux are both Unix-based operating systems, there are several key differences that Red Team members should be aware of. These differences include the filesystem structure, command line tools, user and group management, package management, and kernel and system calls.

While these differences can be challenging for Red Team members who are used to working on Linux, there are many tools and techniques available that can help make working on macOS more familiar and intuitive. By understanding the differences between macOS and Linux, Red Team members can become more effective and efficient in their work, regardless of which operating system they are using.