For Red Team members who are already familiar with Linux, there may be some confusion about 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 rely on the command line interface for much of their functionality.
However, some essential differences between macOS and Linux are significant to understand. In this article, we’ll explore the differences between macOS’s Unix underpinnings and Linux, focusing on how these differences affect Red Team members.
The History of macOS and Unix
To understand the differences between macOS and Linux, it’s essential to understand the history of macOS and Unix. macOS is based on the Unix operating system, which AT&T Bell Labs initially developed 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 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 Apple created 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 significant 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 how the structures are organized.
On macOS, the root directory is “/,” and several top-level directories 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 system users.
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 various 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 other significant 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 it for more complex file management tasks.
Command Line Tools
Another significant difference between macOS and Linux is the command-line tools available. While many of the same tools are available on both systems, there are some essential differences.
Another difference is that macOS uses BSD-based versions of many of the same tools available on Linux. For Red Team members familiar with Linux, it is essential to note that some of the parameters for these BSD-based commands may differ from 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, used to test network connectivity, works slightly differently on macOS than 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 that on Linux, but the output format differs. The output is in BSD format on macOS, meaning 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 commandps -eo pid,comm
. On macOS, the equivalent command would be the 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 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 commandsed -i 's/foo/bar/g' test.txt
. On macOS, the equivalent command would besed '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, you can use the command netstat -tlnp to display all listening ports and associated processes on Linux. On macOS, the equivalent command would besudo lsof -iTCP -sTCP:LISTEN
.grep
: The grep command on macOS is similar to the grep command on Linux but does not support the -P option for Perl-compatible regular expressions. Instead, you must use the -E option to enable extended regular expressions. For example, to search for lines containing the word “apple” and end with a number on Linux, you can use the commandgrep -P 'apple.*\d$' file.txt
. On macOS, the equivalent command would begrep -E 'apple.*[0-9]$' file.txt
.tar
: The tar command on macOS is similar to that 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 commandtar -czvf archive.tar.gz /path/to/files
. On macOS, the equivalent command would betar -czf archive.tar.gz /path/to/files
. Additionally, to extract an archive on Linux, you can use the commandtar -xvf archive.tar.gz
. On macOS, the equivalent command would betar -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. 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 must 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,” which are built into Linux, it is widely used by developers and Red Team members who work on macOS.
Kernel and System Calls
Another area where MacOS and Linux differ is the kernel and system calls. 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, they handle system calls differently. For example, on macOS, system calls are handled by the Mach microkernel, which provides a different set of system calls than the Linux kernel.
This difference in system calls can affect how Red Team members write and execute code on macOS. For example, if you write 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 examine some examples of macOS commands that Red Team members may find useful.
“sudo” Command
The “sudo” command executes commands with administrative privileges. In macOS, the first user account created on the system is automatically added to the “sudoers” file, allowing users 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’re going to install a package using Homebrew, you can use the following command:
sudo brew install package_name
“defaults” Command
The “defaults” command reads, writes, and deletes 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 helpful 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 helpful 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 helpful in 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.
Red Team members can customize the system settings and preferences to their advantage by using the defaults command to modify user defaults on a target system. However, modifying user defaults without permission can be illegal and have serious consequences. Red Team members should use the defaults command only for authorized security testing purposes.
“dscl” Command
The “dscl” command manages users, groups, and computers on macOS. It interacts with the Directory Services system, which stores 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 captures network traffic on macOS. It 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 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 in the system-level LaunchDaemons directory. This will start the daemon immediately and ensure it starts again whenever the system boots up.sudo launchctl unload /Library/LaunchDaemons/com.example.plist
: Unloads a daemon from a plist file in the system-level LaunchDaemons directory. This will immediately stop the daemon and prevent it from reoccurring 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
: This command lists all the services currently running in launched. It will show the service’s name, process ID, and status.sudo launchctl list | grep com.example
: Lists only the services that contain the specified search string. This command can filter the output of the list command to show only the services that match 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 describing the daemon’s properties and behavior. 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 restart the daemon if it crashes automatically.
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 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 helpful in 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 essential to use launchctl responsibly and only for authorized security testing purposes, as misuse of this tool can result in severe 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, many tools and techniques are 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 their operating system.