© The Author(s), under exclusive license to APress Media, LLC, part of Springer Nature 2023
C. Edge, R. TroutonApple Device Managementhttps://doi.org/10.1007/978-1-4842-9156-6_8

8. Securing Your Fleet

Charles Edge1   and Rich Trouton2
(1)
Minneapolis, MN, USA
(2)
Middletown, MD, USA
 

What’s really a threat on an Apple device? That’s often according to who you ask. But in order for Apple devices to be allowed on corporate networks, there’s a few criteria that must be met, and rarely have I seen an auditor who is willing to budge on these requirements. If you disagree that something is necessary, then you should absolutely speak up; however, a second or third effort is really just likely to make them dig into their position and trust you less. And sometimes, they’re right.

2018 was one of the roughest years for Mac security. You can find a rundown of the vulnerabilities and malware introduced at https://digitasecurity.com/blog/2019/01/01/malware2018/ which indicates OSX.MAMI, OSX.CrossRAT, and OSX.CreativeUpdate, among others. It hasn’t been smooth sailing since then either. Suffice it to say that given that security researchers are only beginning to scratch the surface of attacking the platform, there’s going to be more ahead of us than behind us. Given the closed nature of iOS, there’s just less to attack, and so expect fewer vulnerabilities there and maybe expect the Mac to trend in that direction as well. So more of this chapter is dedicated to the Mac than iOS, starting with securing the Mac.

Securing the Platform

Compliance is a thing. In this book, we have covered (and continue to cover) how to get devices into a compliant state. But compliance means different things for different teams and different platforms. While the Apple platforms are similar, what you can do on iOS is much more limited and so the security threats are as well. As an example, this means you don’t use antivirus on iOS but can on macOS. In general, mobile devices are treated differently in organizations: you don’t assume they’re always on your network, you don’t expect access to the filesystem on the device so you plan workflows that are app driven, and on Apple platforms, you leverage MDM to do much of the heavy lifting to secure devices.

The Mac is very different. You can do practically anything you want on the device. In many ways, the Mac is becoming more iOS-like, but you can still disable SIP (System Integration Protection), which has been covered throughout this book, and do anything you want on a device. Apple produces a great guide to macOS security at www.apple.com/business/resources/docs/macOS_Security_Overview.pdf, and this chapter is meant as a technical journey through the basic security measures required by most organizations. This starts with the operating system but quickly becomes as much about apps and content as hardened systems that follow guidelines, like those issued by the National Institute of Standards and Technology in the United States, or NIST. NIST has made their compliance work open source at https://github.com/usnistgov/macos_security with assistance from agencies like NASA and the Pentagon.

With both Mac and iOS, many assume any software that goes through the App Store is safe. This is because Apple scans software to indicate that it is indeed safe. Now with App Notarization, Apple is scanning apps for security flaws. This service is currently optional (except for kernel extensions, or kexts), and if an app has been certified by Apple and signing matches Apple’s database, then Gatekeeper (described further later in this chapter) provides a special icon that the software is clean. As we cover later in the chapter, this is good for many, but not all, organizations.

Security is a trade-off. In general, the more secure a fleet of devices becomes, the less features are available on devices and/or the slower the device will run. For example, removing the ability to use iCloud is interpreted as some environments as improving security; however, without iCloud, many services work suboptimally. Most classic Apple users and administrators think “Apple has me covered” when it comes to security. Most classic IT departments think “we must lock down everything that makes anything cool.” And according to the type of data being stored on a computer, they may be correct. The answer for how much security is required to protect a device is somewhere in the middle and is entirely based on the security posture of any given organization.

Many organizations have anywhere between three and eight LaunchAgents and/or LaunchDaemons that run on a Mac. Given the types and number of vulnerabilities on the Mac as well as what frameworks are allowed to touch on the Mac, it is unimaginable that a customer would actually need to deploy all of those agents given that each can have an expensive load on system resources, with some taking up 10–30% of the CPU or memory on a computer. One is usually too few, four is too many. None should touch the kernel (and therefore should not be kernel extensions) because doing so can lead to unbootable devices, and most existing products do not provide for zero-day support.

Mac Security

The Mac includes a number of built-in security features, on both the system level and the user level. Two major components of these security features are the signed system volume and System Integrity Protection (SIP).

Signed System Volume

As of macOS Big Sur and later, Apple has moved the parts of the OS it can make immutable by moving them to the system volume of the boot drive. This volume is mounted as read-only at boot by macOS, and all files stored in the volume on it now have a SHA-256 cryptographic hash which is stored in the filesystem. This allows macOS to check each file’s current hash against the stored hash at boot time, to verify that the file hasn’t been tampered with or damaged.

In addition, further hashing is used in the filesystem metadata itself. This additional hashing covers all directories from the deepest nested directories to the root level. This additional hashing is referred to as a cryptographic seal and covers the entire system volume, its directory structure, and all the data contained inside. This seal is verified every time the Mac starts up, though the behavior is slightly different between Apple Silicon Macs and Intel Macs equipped with T2 security chips:
  • Apple Silicon Macs: Bootloader verifies the seal before transferring control to macOS’s kernel.

  • Intel Macs with T2 security chips: Bootloader forwards seal measurement and signature to macOS’s kernel. The kernel verifies the seal before mounting the root filesystem.

If this seal verification fails, the macOS boot process halts at that point, and the user is prompted to reinstall macOS.

System Integrity Protection

Once the Mac is booted and running, System Integrity Protection (SIP) provides a security layer designed to limit the power of the root account on macOS.

The root account is the superuser for a Unix system, and the Unix permissions model is designed around the assumption that the root account has access to everything. To limit what the superuser can do and add another layer to the macOS security model, Apple developed System Integrity Protection (SIP) and first deployed it as part of OS X El Capitan. SIP is designed to limit the power of root and to protect the system, even from its own root user.

SIP is an overall security policy with the goal of preventing system files and processes from being modified by third parties. To achieve this, it has the following concepts:
  • Filesystem protection

  • Runtime protection

  • Kernel extension protection

SIP prevents parties other than Apple from adding, deleting, or modifying directories and files stored in certain directories, including the following:
  • /bin

  • /sbin

  • /usr

  • /System

The preceding directories are required for the computer to boot properly, and not allowing users to alter them keeps the operating system safe. Because the software you install needs to go somewhere on the system, Apple has indicated that the following directories are available for developers to access:
  • /usr/local

  • /Applications

  • /Library

  • ~/Library

All directories in /usr except for /usr/local are protected by SIP, and third-party developers should not write to protected locations. It is possible to add, remove, or change SIP-protected files and directories via an installer package which is signed by Apple’s own certificate authority. This allows Apple to make changes to SIP-protected parts of the OS without needing to change the existing SIP protections (Figure 8-1).

A screenshot of a pop-up. It has a lock icon at the top left. There is a checkbox with the text, always trust software updates. There is an image of a certificate with the text, software update, issued by, apple software update certification authority. There are options for hiding the certificate and ok at the bottom.

Figure 8-1

Suspicious package showing signing information for an Apple installer which uses Apple’s signing certificate

The certificate authority in question is reserved by Apple for their own use; Developer ID–signed installer packages are not able to alter SIP-protected files or directories. To define which directories are protected, Apple has currently defined a configuration file, which is /System/Library/Sandbox/rootless.conf. This file is controlled exclusively by Apple and lists all the applications and top-level directories which SIP is protecting (Figure 8-2).

A screenshot of the listed pathways. The names are on the left and the location is on the right.

Figure 8-2

Partial listing of SIP-protected paths in the /System/Library/Sandbox/rootless.conf file

SIP-Protected Directories

SIP is also protecting a number of directories and symlinks outside of /Applications. Many of those directories contain frameworks, binaries brought in from other projects, and binaries that have always been a part of the Mac, since the inception of Mac OS X.

Some of those directories contain files that administrators need to access. So Apple has also defined some exceptions to SIP’s protection in the rootless.conf file (Figure 8-3), with those exceptions marked with asterisks. These exemptions from SIP’s protection mean that it is possible to add, remove, or change files and directories within those locations.

A screenshot of listed exceptions to S I Ps protection. Four of them are highlighted. Each has an asterisk on the left side and a location on the right.

Figure 8-3

Exceptions to SIP’s protection listed in rootless.conf

Among those exceptions are the following, which many administrators or third-party software developers need access to:
  • /System/Library/User Template: Where macOS stores the files and directories it uses when creating home folders for new accounts.

  • /usr/libexec/cups: Where macOS stores printer configuration information.

  • /usr/share/man: A number of third-party software developers and open source projects will write a man file so you can have a manual of what the software does.

View SIP Protections Interactively

To see which files and directories have been protected by SIP, use the ls command with the capital O flag in Terminal:
ls -O
As you can see in Figure 8-4, the output will list SIP-protected files and directories as restricted. This is a common troubleshooting step you’ll get used to if you have a lot of scripts that touch these folders, and you need to resolve issues that come up with them due to not being able to write to objects in those directories or remove them.

A screenshot of listed directories with highlighted S I P protected root level directories. The highlighted directories have the labels, restricted and restricted, hidden. They contain date and time.

Figure 8-4

Using the ls command to display SIP-protected root-level directories

An important thing to note is that even if a symlink (a symbolic link acts as a shortcut of sorts) is protected by SIP, that does not necessarily mean that the directory it’s linking to is being protected by SIP. For example, the root level of a macOS boot drive contains several SIP-protected symlinks pointing to directories inside the root-level directory named private. Usually, this means that if one of those symlinks were removed, it would cause problems with the device.

However, when the contents of the private directory are examined (Figure 8-5), the directories to which those SIP-protected symlinks point are not themselves protected by SIP, meaning those directories and their included files can indeed be moved, edited, or changed by processes using root privileges.

A screenshot of listed directories inside the private directory. The listed directories have the date and time on the right.

Figure 8-5

Using the ls command to display directories inside the private directory

Runtime Protections

As mentioned, SIP’s protections are not limited to protecting the system from filesystem changes. There are also system calls which are now restricted in their functionality, including the following, which are more for developers and debugging:
  • task_for_pid()/processor_set_tasks() fail with EPERM.

  • Mach special ports are reset on exec(2).

  • dyld environment variables are ignored.

  • DTrace probes are unavailable.

Of the preceding list, DTrace is probably the most problematic for a Mac administrator. If you need DTrace to troubleshoot, then you will need to disable SIP while troubleshooting. If you are a developer rather than an administrator, SIP does not block inspection by the developer of their own applications while they’re being developed, so instrumentation tools are still available. Xcode’s tools will continue to allow apps to be inspected and debugged during the development process.

Kernel Extension Protections

The third type of protection that SIP proxies is for kernel extensions. While the use of kernel extensions has been reduced by the introduction of system extensions, SIP blocks the installation of unsigned kernel extensions as well as those that haven’t been notarized using Apple’s Notarization service. In order to install a kernel extension on macOS with SIP enabled, a kernel extension must
  • Install into /Library/Extensions.

  • Be signed with a Developer ID for Signing Kexts certificate.

  • Be notarized using the Apple Notarization service, which is described in more depth in Chapter 5.

For the purposes of this chapter, be aware of what kexts are running. A good tool for this is KextViewr available at https://objective-see.com/products/kextviewr.html.

If installing an unsigned kernel extension, SIP will need to be disabled first. However, SIP should only be disabled temporarily. Any time you start managing the settings for SIP by rebooting a machine into recovery mode, think long and hard about whether you should touch anything before you do so. You have plenty of time to do so, because the process is a bit slower than we might want.

Managing System Integrity Protection

To ensure that third parties will not be able to disable these protections, SIP’s configuration is stored in NVRAM (Non-volatile random-access memory) rather than in the filesystem itself and is only configurable if the Mac is booted into one of two environments:
  • The macOS Installer environment

  • The macOS Recovery environment

Note

The macOS Installer and macOS Recovery environments are in fact the same environment from macOS’s perspective. The main difference between the two is that the macOS Installer environment contains a copy of the installation files for macOS and the Recovery environment does not.

Because SIP’s configuration is stored in NVRAM, these settings will apply to the entire machine and will persist even if the OS is reinstalled. SIP can be managed to the extent of turning it on, turning it off, adding and removing IP addresses into a NetBoot whitelist, and reporting on whether SIP is enabled or disabled. All changes to SIP’s configuration settings also require a reboot before they take effect, and performing the changes without physically touching the computers will not be possible (and so you won’t be doing this en masse).

The tool used to manage SIP is /usr/bin/csrutil. csrutil is able to work with SIP because it has a unique application entitlement assigned to it by Apple. This entitlement is viewable using the codesign command shown in the following:
codesign -d --entitlements - /usr/bin/csrutil
The response to the command includes the com.apple.private.iokit.nvram-csr key as shown in Figure 8-6.

A screenshot of the listed csrutil's application entitlement. One of the entitlements has been highlighted. It is, com dot apple dot private dot i o kit dot n v r a m dash c s r.

Figure 8-6

Displaying csrutil’s application entitlement

When you run csrutil without any associated commands, Terminal will respond with the help page. Here, you’ll see any options get guidance on how to use the available commands, as you can see in Figure 8-7.

A screenshot of csrutil's help page. It has the commands, clear, disable, enable, and status.

Figure 8-7

Displaying csrutil’s help page

When booted from the Recovery environment, the command used to enable SIP is simply csrutil with the enable verb:
csrutil enable
When run, you’ll receive a message that SIP was enabled, as seen in Figure 8-8.

A screenshot of terminal bash, csrutil enable. It has the text, system integrity protection is on. Restart the machine for the changes to take effect.

Figure 8-8

Running csrutil enable from the Recovery environment

When booted from the Recovery environment, simply replace the enable with a disable in order to turn SIP off so you can perform some of the actions that would otherwise be unavailable to an administrator:
csrutil disable
The message is almost identical, but states disabled instead of enabled (Figure 8-9).

A screenshot for terminal bash, csrutil disable. It has the text, system integrity protection is off. Restart the machine for the changes to take effect.

Figure 8-9

Running csrutil disable from the Recovery environment

You can also reset the configuration for SIP by running the clear command. This simply returns the state to the factory-installed state:
csrutil clear
The resultant message doesn’t indicate that SIP is disabled or enabled, only that the state was cleared, as you can see in Figure 8-10.

A screenshot for terminal bash, csrutil clear. It has the text, successfully cleared system integrity configuration. Restart the machine for the changes to take effect.

Figure 8-10

Running csrutil clear from the Recovery environment

When csrutil clear is run, SIP goes back to its factory-default settings. That means SIP is enabled if it was disabled previously and any custom configuration is cleared out.

Signed System Volume and csrutil

As of macOS Big Sur and later, Apple has moved the parts of the OS it can make immutable by moving them to the system volume of the boot drive. As discussed earlier, this volume is cryptographically sealed, and the seal is verified against tampering every time the Mac starts up. The csrutil command can report whether this seal verification process is enabled or not and also turn this verification process on or off from the Recovery environment.

To enable the seal verification, run the following command as seen in Figure 8-11:
csrutil authenticated-root enable

A screenshot for terminal bash, csrutil authenticated-root enable. It has the text, successfully enabled authenticated root. Restart the machine for the changes to take effect.

Figure 8-11

Running csrutil authenticated-root enable from the Recovery environment

To disable the seal verification, run the following command as seen in Figure 8-12:
csrutil authenticated-root disable

A screenshot for terminal bash, csrutil authenticated-root disable. It has the text, successfully disabled authenticated root. Restart the machine for the changes to take effect.

Figure 8-12

Running csrutil authenticated-root disable from the Recovery environment

Running csrutil Outside of the Recovery Environment

If you run the csrutil enable and csrutil disable commands when you aren’t booted into the Recovery OS environment, you will receive a message that these commands need to be run from the Recovery OS. The current SIP configuration will remain unchanged, as you can see in Figure 8-13.

A screenshot of username, % csrutil enable. It has the text, this tool needs to be executed from Recovery O S.

Figure 8-13

Running csrutil enable outside the Recovery environment

Likewise, if you try to run the csrutil authenticated-root enable and csrutil authenticated-root disable commands while booted from a regular boot drive, you will receive a message that these commands need to be run from the Recovery OS (Figure 8-14).

A screenshot of username, % csrutil authenticated-root enable. It has the text, this tool needs to be executed from Recovery O S.

Figure 8-14

Running csrutil authenticated-root to enable outside the Recovery environment

What can be run while outside the Recovery environment are csrutil’s reporting functions. For example, to learn if SIP is enabled or disabled, run the following command:
csrutil status
This command can be run without root privileges and will display if SIP is enabled or disabled, as you’ll note in Figure 8-15.

A screenshot of username, % csrutil status. It has the text, System Integrity Protection status, enabled.

Figure 8-15

csrutil status displaying SIP is enabled

Similarly, csrutil authenticated-root status can be run to report on the status of the system volume seal’s verification check, as you can see in Figure 8-16.

A screenshot of username, % csrutil authenticated-root status. It has the text, Authenticated Root status, enabled.

Figure 8-16

Running csrutil authenticated-root status outside the Recovery environment

So you can programmatically derive information about SIP, but you can’t augment SIP when booted to the standard operating system. Now that we’ve covered getting SIP turned on and off, it’s worth noting that the enable options have more granular settings, usually invoked with a -- in the command.

Custom System Integrity Protection Configuration Options

It is possible to enable SIP protections and selectively disable aspects of it, by adding one or more flags to the csrutil enable command. All the following examples require being booted from Recovery in order to successfully configure.

To enable SIP and allow installation of unsigned kernel extensions, run the csrutil command with the enable verb, but then use the --without option and use the kext selection for what to disable:
csrutil enable --without kext
When this option is enabled, running csrutil status outside the Recovery environment should produce output similar to this, indicating that Kext Signing is disabled, as you can see in Figure 8-17. This isn’t to say that signed kexts can’t be run but instead that forcing signed kexts in order to run a kext has been disabled.

A screenshot of username, % csrutil status. It has the text, System Integrity Protection status, unknown. The configuration has apple internal and kext signing disabled with the rest enabled.

Figure 8-17

csrutil status displaying SIP is enabled with kext protections disabled

If you need to write to those protected directories we reviewed earlier in the chapter (whether you need to is very arguable), then you’ll need to disable Filesystem Protection. To enable SIP and disable Filesystem Protections, run the enable option for csrutil, with the --without option again, and then indicate fs instead of kext:
csrutil enable --without fs
When this option is enabled, running csrutil status should produce output similar to Figure 8-17 but with the Filesystem Protections set to disabled. You can also disable the debugging restrictions. To keep SIP enabled but disable debugging restrictions, run the same command as before but use debug as your option:
csrutil enable --without debug
When this option is enabled, running csrutil status will show Debugging Restrictions set to disabled. A common task is to disable DTrace restrictions so you can run dtrace commands and scripts. To leave SIP enabled but disable the DTrace enforcement, run the same command but use dtrace as the option to start SIP without, as follows:
csrutil enable --without dtrace
When this option is enabled, running csrutil status should produce a similar output but with the DTrace Restrictions listed as disabled. Many administrators will want to customize NVRAM options (e.g., to bless NetBoot servers). To enable SIP and disable restrictions on writing to NVRAM, run the same command but use the nvram option:
csrutil enable --without nvram
When this option is enabled, running csrutil status should produce output similar to the previous few iterations of the command, but with NVRAM Protections showing as Disabled. To enable SIP and disable basesystem verification, which will allow the use of a modified disk image to install macOS, run the command again but use basesystem as the exclusion:
csrutil enable --without basesystem

When this option is enabled, running csrutil status should produce a similar output but showing BaseSystem Verification set to disabled. These commands allow you to access specific options while still leaving SIP enabled. If you have to access those, try to do so granularly so the deployment still makes use of the added security features from running with SIP enabled on the fleet, and do so only for machines you have to. For example, try to only disable the nvram protections if you have a lab that you’d like to run with the option to boot into a NetBoot environment.

System Integrity Protection and Resetting NVRAM

As mentioned previously, SIP stores its active security configuration in NVRAM. This allows SIP’s configuration to persist across OS installs, but this design choice also means that resetting NVRAM will cause SIP’s configuration to reset as well. In my testing, a NVRAM reset will result in the following SIP configuration:
  • SIP will be enabled with all protections in place.

  • No entries will be set in the NetBoot whitelist.

Resetting the NVRAM, otherwise known as a PRAM reset or PRAM zap, has been a standard part of the Mac troubleshooting toolkit for a long time, but the process is different depending on if you’re using an Intel Mac or an Apple Silicon Mac.

For Intel Macs, a PRAM reset is performed by pressing and holding down the Option, Command (⌘), P, and R keyboard keys at startup (Figure 8-18). You can verify this worked because the startup tone will change.

An illustration of an Apple keyboard. The keys, R, P, Option, and Command have been highlighted.

Figure 8-18

Apple keyboard with PRAM reset keys indicated

For Apple Silicon Macs, you will need to boot to the Recovery environment. When booted from the Recovery environment, run the following command as shown in Figure 8-19.
nvram -c

A screenshot of terminal bash. It has n v r a m dash c command.

Figure 8-19

Running the nvram -c command from the Recovery environment

For environments that do not plan to change SIP’s default configuration, NVRAM resets should not affect normal operations. However, for those environments where custom SIP configurations need to be maintained, be advised how this change affects SIP configuration in your environment.

User-Level Protections

The final type of protection we’ll cover is user-level protections. Introduced as a part of the entitlement framework in macOS Mojave, these protections are managed by Apple’s expanded security framework, Transparency Consent and Control (TCC). These new protections are primarily focused on protecting data within a user’s home folder, but also affect access to the Mac’s built-in camera and microphone.

To summarize the protection, applications will now be required to request user approval before they’ll be able to access specific application data. If access is not granted, the application will not be able to access that data, and whatever function the application was trying to run may fail. Apple has not documented which files and directories inside an account’s home folder are affected by the user data protections, but in our research and testing, these are the affected areas we know of today:
  • ~/Library/Application Support/CallHistoryTransactions

  • ~/Library/Application Support/com.apple.TCC

  • ~/Library/Application Support/AddressBook

  • ~/Library/Application Support/CallHistoryDB

  • ~/Library/IdentityServices

  • ~/Library/Calendars

  • ~/Library/Preferences/com.apple.AddressBook.plist

  • ~/Library/Messages

  • ~/Library/Mail

  • ~/Library/Safari

  • ~/Library/Suggestions

  • ~/Library/Containers/com.apple.Safari

  • ~/Library/PersonalizationPortrait

  • ~/Library/Metadata/CoreSpotlight

  • ~/Library/Cookies

  • ~/Library/Caches/CloudKit/com.apple.Safari

  • /private/var/db/dslocal/nodes/

In order for applications to be able to access those protected areas, they must be approved either manually or by using a management profile. For more information on using a profile to manage privacy protections, please see Chapter 4. To show an example of an application which would legitimately need access to protected areas would be a backup solution. To manually approve a backup application to access all data stored in an account’s home folder, including protected data, the following procedure is used on macOS Mojave:
  1. 1.

    Open System Settings.

     
  2. 2.

    Select the Privacy & Security preferences.

     
  3. 3.

    Click the Full Disk Access settings.

     
  4. 4.

    Add the application to the Full Disk Access section as you can see in Figure 8-20.

     

A screenshot of a window. It has a search bar at the top left with several tabs below it. The tab for privacy and security has been selected. The right side has full disk access. It has the Terminal option with the toggle button turned on.

Figure 8-20

Allowing Terminal.app to have Full Disk Access

The Location Services, Contacts, Calendars, Photos, Camera, Microsoft, and other items that are covered by the privacy controls are configured in the same manner and represent the most likely places where a third-party developer will want to access information that an end user should be prompted to allow.

Privacy is an increasingly visible aspect of security, but there are a number of things that the industry has been doing for a long time. Many administrators are accustomed to scanning software on a computer for vulnerabilities. We’ll move on to doing so in the next section of this chapter.

Detect Common Vulnerabilities

The Mac comes with a number of tools for querying version numbers of things like apps and operating systems. First, let’s look at operating systems. The quickest way to derive the version of an operating system would be using the sw_vers command with the -productVersion option:
sw_vers -productVersion
The output is a simple point release version number. Older versions would have shown a 10 in front of the number, like 10.15.0. An example of a newer system like Ventura would report just the later part of the numbers:
13.0
It then becomes trivial to pipe that output into other languages, provided you can reach them from within a script. For example, if you import os into a python script, you can use the sw_vers command:
import os
os.system('sw_vers -productVersion')
Or to grab the version of the OS, you could import a function just for that:
version = platform.mac_ver()
So in the following example, this is in a python script that lists any available Common Vulnerabilities and Exposures, or CVEs, for a given macOS operating system, using cve.circl.lu, a public repository of CVEs copied from https://cve.mitre.org and with a REST API put in front of the database:
maccvecheck.py
#!/usr/bin/python import sys, urllib, json, platform
if len(sys.argv) > 1: url = 'https://cve.circl.lu/api/search/apple/mac_os_x:{}'.format(sys.argv[1])
print([j['id'] for j in json.loads(urllib.urlopen(url).read().decode('utf-8'))])
else:
version = platform.mac_ver() url = 'https://cve.circl.lu/api/search/apple/mac_os_x:{}'.format(version[0])
print([j['id'] for j in json.loads(urllib.urlopen(url).read().decode('utf-8'))])

Rather than typing all of that should you need this, copy it from https://github.com/krypted/maccvecheck.

The operating system isn’t all we might want to keep updated, the script can be used to check for other software on the computer as well. You can also read the index of an app using mdls, a command to query the Spotlight index on a Mac. To use the command, we’ll use the -name option and the kMDItemVersion attribute, as follows for Zoom:
mdls -name kMDItemVersion /Applications/zoom.us.app
And then you can look that up in the CVE database as well using a simple call to the same database:
curl https://cve.circl.lu/api/search/apple/itunes:12.5

Adding a bit more logic, you could then build a similar script that checks all items in /Applications. Ultimately, Apple has a number of products that are tracked in the cve database, and a library of each could easily be built and parsed to produce all cve hits encountered on a Mac. The number of products you would need to scan seems to go down every year. Obviously, you might not want to trust some random site from Luxembourg, and you can do this directly against the zip from Mitre or create your own microservice that responds similarly to this site. For the purposes of this book, we used the public-facing API, so we didn’t need to parse the json files distributed by Mitre. Now that we’ve looked into vulnerability scanning, another common practice (and therefore a checkbox in your security assessment forms) is managing the firewall.

Manage the macOS Firewall

macOS comes with an Application Layer Firewall (we’ll call it ALF for short), which is what is configured from the Security System Preference pane. You can enable the firewall simply enough by using the defaults command to augment the /Library/Preferences/com.apple.alf.plist file, setting the globalstate key to an integer of 1:
sudo defaults write /Library/Preferences/com.apple.alf globalstate -int 1
You can also configure the firewall from the command line. Stopping and starting ALF is easy enough, whether the global state has been set to zero or one, done using launchd. To stop:
launchctl unload /System/Library/LaunchAgents/com.apple.alf.useragent.plist launchctl unload /System/Library/LaunchDaemons/com.apple.alf.agent.plist
To start:
launchctl load /System/Library/LaunchDaemons/com.apple.alf.agent.plist launchctl load /System/Library/LaunchAgents/com.apple.alf.useragent.plist
These will start and stop the firewall daemon (aptly named firewall) located in the /usr/libexec/ApplicationFirewall directory. As you can imagine, the settings for ALF can be configured from the command line as well. The socketfilterfw command, in this same directory, is the command that actually allows you to manage ALF. ALF works not by the simple Boolean means of allowing or not allowing access to a port but instead by limiting access by specific applications, more along the lines of Mandatory Access Controls. When an application is allowed to open or accept a network socket, it’s known as a trusted application – and ALF keeps a list of all of the trusted applications. You can view trusted applications using socketfilterfw with the -l option, although the output can be difficult to read, and so you can constrain it using grep for TRUSTEDAPPS as follows:
sudo /usr/libexec/ApplicationFirewall/socketfilterfw -l | grep TRUSTEDAPPS
You can also use the command line to add a trusted application using the -t option for older versions of macOS or –blockapp or –unblockapp followed by a path to the binary of an app. For example, to unblock FileMaker Pro, we’d point to the FileMaker binary:
sudo /usr/libexec/ApplicationFirewall/socketfilterfw –blockapp "/Applications/FileMaker Pro 19/FileMaker Pro.app/Contents/MacOS/FileMaker Pro"

To see a list of apps the firewall has been configured to work with, use the –listapps option. You can also use the socketfilterfw command to sign applications, verify signatures, and enable debugging. Finally, there are a number of global preferences for the firewall that can be configured using the /usr/libexec/ApplicationFirewall/com.apple.alf.plist preferences file. You might be looking at the path to this file and think that it looks odd and it should really be in /Library/Preferences. And you might be right. Some keys in this file that might be of interest include globalstate (0 disables the firewall, 1 configs for specific services, and 2 is for essential services – as in the GUI), stealthenabled, and loggingenabled. All are integers and fairly self-explanatory vs. GUI settings from the System Preference pane.

Firewalls are one layer of security; the next we’ll cover is malware.

Combat Malware on macOS

One of the security requirements handed down by many an information security team that has seemed controversial since before macOS even is antivirus. In previous books, we tried to explore what the difference is between a virus, trojan, logic bomb, worm, backdoor, zombie, retrovirus, macrovirus, rootkits, etc. But here, we’ll just call it all malware. It’s something bad on the computer, and we need to scan for it routinely and correct it when found. Most malware that gets on an Apple device can’t actually hurt the device; instead, the device ends up sending infected files to other computers that the malware can actually affect. Or at least that was the perception in previous decades and is mostly still true for iOS.

Mac malware can be dangerous though. When it is, you’ll need a way to limit the impact and remediate. There are tons of great options to buy mature antivirus tools on the market. Apple has also provided a number of built-in tools, and for some, those will suffice to satisfy a CISO. We’ll start by covering XProtect.

XProtect and Gatekeeper

Gatekeeper is often used as a term to cover a number of different technologies. The first we’ll cover is XProtect, a tool built into macOS that is meant to protect the operating system by detecting various viral signatures and reacting to them by blacklisting that signature. Apple doesn’t add items to this list often, as there aren’t a lot of things that need to be added. If your organization requires the use of an antivirus tool, the first question you should answer is “will XProtect be sufficient?” The answer will often be no, but it’s worth understanding what XProtect is and how it works.

The signatures that are installed by default can be found in the /System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/Xprotect.plist property list, which includes a wonderful list of malware items that Apple has automatically decided you should not run on your computer. This allows other developers to extend signatures by adding more items into the XProtect.plist in Security Updates, or Apple may choose to deploy more items in subsequent software updates.

The great thing about XProtect is that it’s already running on the Mac and covers a number of different threats to the system by scanning files as they’re opened and then identifying those deemed dangerous. This means you’re not creating additional load on a computer during traditional antivirus scans, and you’re not going to hold up the deployment of new operating systems while testing if something works. XProtect is configured using Gatekeeper, a System Preference used to configure a few basic security options. To view and configure Gatekeeper settings, use the Privacy & Security System Settings pane, scroll down to the Security section, and choose whether your device will only allow App Store apps or whether to allow those from the “App Store and identified developers” as seen in Figure 8-21.

A screenshot of a window. It has a search bar at the top left. There are several tabs below it. The tab for privacy and security has been selected. The right side has the sub-tab for security. It has the selected option for app store and identified developers.

Figure 8-21

Gatekeeper settings in System Settings

Gatekeeper is enabled by default, and configuring Gatekeeper is as easy as selecting one of these options. There’s much more that can be done under the hood. The state of Gatekeeper is kept in /var/db/SystemPolicy-prefs.plist. There’s only one option there, though: enabled. You can run defaults to manage the status of Gatekeeper with the command line via the spctl binary. To enable:
sudo spctl –master-enable
Or to use --master-disable to disable Gatekeeper:
spctl --master-disable
Whether Gatekeeper (assessments) is enabled or disabled can be returned using the --status option:
spctl --status
The -a option is used to assess an application to see if it will open or not:
spctl -a /Applications/GitHub.app
If an application passes and has a rule available, then you’ll get no response. If there’s no rule for the application, you’ll get a response that
/Applications/GarageBuy.app: unknown error 99999=1869f
You don’t want users to just start clicking to accept screens, so, when possible, add the rules on behalf of users. To add rules about apps, use the --add option. Each app gets a label, defined with the –label option. For example, to add GitHub:
spctl --add --label "GitHub" /Applications/GitHub.app
To then enable access to GitHub:
spctl --enable --label "GitHub"
Or to disable an app:
spctl --disable --label "GitHub"

As with most things, there’s actually a rub: spctl doesn’t always work. There have been more than a few issues with getting the labels to apply properly. Sometimes, the -a will report back that an app is rejected and yet the app will still open, so build some sanity checking into any scripts when managing app labels. When you encounter problems with spctl, file a radar with Apple. Gatekeeper is more fully documented at https://support.apple.com/en-us/HT201940. To understand some of the underpinnings though, we’ll look at lsquarantine in the next section of this chapter.

lsquarantine

Gatekeeper works by scanning files that have been downloaded from the Internet, as we mentioned in the previous section. Deciding what files are allowed to be opened and what aren’t, as well as prompting users is handled using lsquarantine, Spotlight works very quickly because it maintains an index of metadata attributes. The lsquarantine tool works similarly. There is a set of attributes attached to any files downloaded from the Internet, and on opening a special screen appears, which can be seen in Figure 8-22.

A screenshot of a pop-up for quarantined apps. It has text, Google Chrome is an app downloaded from the Internet. Are you sure you want to open it? There are buttons for cancel and open at the bottom.

Figure 8-22

Prompt for quarantined apps

Any file downloaded from external sources (such as email attachments) attaches quarantine attributes, including Safari, Messages, HipChat, etc. These attributes include date, time, and a record of where the file was downloaded from. When you open a file received through a quarantine-aware application, macOS warns you where the file came from. You receive an alert asking, “Are you sure you want to open it?”

For more on how lsquarantine works under the hood, see https://developer.apple.com/documentation/foundation/urlresourcevalues/1792021-quarantineproperties. But let’s look at those attributes, given how important they are.

Xattr has a lot of different uses; you can programmatically manage Finder tags with it (Finder tags aren’t just used for security, so for more on Finder tags, see http://krypted.com/mac-os-x/command-line-finder-tags/). To see the full xattr dump on a given file, use the -l option as follows:
xattr -l com.apple.quarantine MyAppImage.dmg
The output is as follows:
xattr: No such file: com.apple.quarantine MyAppImage.dmg: com.apple.metadata:kMDItemDownloadedDate: 00000000 62 70 6C 69 73 74 30 30 A1 01 33 41 BE 31 0B A5 |bplist00..3A.1..| 00000010 70 D4 56 08 0A 00 00 00 00 00 00 01 01 00 00 00 |p.V.............| 00000020 00 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 |................| 00000030 00 00 00 00 13 |.....| 00000035 MyAppImage.dmg: com.apple.metadata:kMDItemWhereFroms: 00000000 62 70 6C 69 73 74 30 30 A1 01 5F 10 22 63 69 64 |bplist00.._."cid| 00000010 3A 69 6D 61 67 65 30 30 31 2E 70 6E 67 40 30 31 |:myappimage.dmg@01| 00000020 44 32 36 46 46 44 2E 35 37 31 30 37 30 46 30 08 |D26FFD.571070F0.| 00000030 0A 00 00 00 00 00 00 01 01 00 00 00 00 00 00 00 |................| 00000040 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000050 2F |/| 00000051
This could be helpful when troubleshooting and/or scripting. If you’re an application developer, check out the new API for App Translocation in the 10.12 SDK for <Security/SecTranslocate.h>. I guess one way to think of this is… Apple doesn’t want you running software this way anymore. And traditionally they lock things down further, not less, so probably best to find alternatives to running apps out of images, from a strategy standpoint. To remove the com.apple.quarantine bit, use xattr along with the -r option (given that Mac apps are bundles of files we need to do so recursively) and then the -d option for delete, followed by the bit being deleted and then the path to the app, as follows:
xattr -r -d com.apple.quarantine /Volumes/MyApp/MyAppImage.app

If you have multiple user accounts on your Mac, the user account that downloaded the file is the only user account that can remove the quarantine attribute on a file. All other user accounts can open a quarantined file, but they are still presented with an alert asking, “Are you sure you want to open it?” every time they open the file.

While a lot of focus is put on malware and privacy, the most substantial risk to most computers is a binary running persistently. Most malware will want to run in such a way. A lot of services run on a Mac and most are built by Apple, so can be identified as com.apple.something. We cover kexts, LaunchAgents, and LaunchDaemons in this book. But in the next section, we’ll look at manipulating the Launch Services database to find and isolate a foreign persistent service based on it being registered to open a given file type.

Using lsregister to Manipulate the Launch Services Database

The lsregister command is used to query and manage the Launch Services database, or the database that is used to determine the default application used to open files of various types. lsregister is part of Core Services and stored in /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support. To see the options available to lsregister, run the command with no operators:
/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister
You can dump the database to the screen using the -dump option:
/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister -dump
You can then grep the database or redirect the output into a text file for parsing:
/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister -dump > dump.txt
The dump of the database is really just meant to parse in other tools if you have security requirements to do so. Sometimes, applications don’t open with a given file type. When this happens, you can quickly and easily check if the problem has to do with the launchservices database. To do so, run the open command and define the application (using the -a option) followed by the app and then the file. For example, to open an XML file called krypted.xml in TextWrangler (assuming your working directory contains krypted.xml):
open -a TextWrangler.app krypted.xml
A full scan of apps can be run to repopulate the database with the --seed option:
/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister -seed
You can force an application to reregister file types for that application using the -f option followed by the application path. For example, to reregister Xcode:
/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister -R -f /Applications/TextPlus.app
You can also unregister a specific application using the -u option. To unregister Xcode, you would use the -u option:
/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister -u /Applications/Xcode.app

One of the most important aspects of lsregister is to look for changes that indicate an app has registered to handle a given file type. An example of a security threat would be an app that registers to open a file type and then each time that file type is run opens and then opens the legitimate app for the file type. This would allow malware to run without being detected.

The launchservices database can get unwieldy. There are applications registered in the local domain, system domain, and each user’s domain. These can be cleared with the following command, which also recursively rebuilds based on the output of a -lint option:
/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister -kill -r -domain local -domain system -domain user
To check the progress:
/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister -v

Changing File Handlers

To set a specific application to open a file type, use the Get Info dialog (Command-I when clicked on the file type). This dialog has a section for “Open with:” as seen in Figure 8-23.

A screenshot of dump dot t x t info window. It has a tab to add tags at the top with a tab for comments at the center. There is a table for name and privilege at the bottom.

Figure 8-23

Use Get Info to change how files are handled

Click the option list for opening the file and then use the Change All button to set the behavior from just that instance of the file type to all instances of the file type. You can also set the default application for a network protocol (e.g., smb://, rdp://, vnc://, http://, and https://). Because the options for lsregister leave one wanting in some ways (the commands to set file types to a specific application are a bit overly complicated one could argue), there is an awesome front-end app for older operating systems from Andrew Mortensen, aptly called duti, available at http://duti.sourceforge.net/index.php. With duti installed, the command to set the default browser for http would be
/usr/local/bin/duti -s com.apple.safari http

Finally, there’s a lot that Launch Services does and is involved in. For more information on Launch Services, check out the Apple developer library entry for Launch Services at https://developer.apple.com/library/archive/documentation/Carbon/Conceptual/LaunchServicesConcepts/LSCIntro/LSCIntro.html.

MRT

macOS also comes with a vulnerability scanner called mrt. The mrt binary is installed inside the MRT.app bundle in /System/Library/CoreServices/MRT.app/Contents/MacOS/, and while it doesn’t currently have a lot that it can do, it does protect against the various bad stuff that is actually available for the Mac. The mrt binary is based on Yara, an open source tool that searches for complex patterns, perfect for finding files that meet a known signature or other condition, such as malware.

To use mrt, simply run the binary with a -a flag for agent and then a -r flag along with the path to run it against. For example, let’s say you run a launchctl command to list LaunchDaemons and LaunchAgents running:
launchctl list
The list is a long listing of every LaunchAgent and LaunchDaemon running. Let’s say there’s something that starts with com.abc. Be assured that nothing should ever start with that. So it can easily be scanned with the following command:
/Library/Apple/System/Library/CoreServices/MRT.app/Contents/MacOS/MRT -a -r ~/Library/LaunchAgents/com.abc.123.c1e71c3d22039f57527c52d467e06612af4fdc9A.plist
The preceding command works for Big Sur and above, but previous versions might use
sudo /System/Library/CoreServices/MRT.app/Contents/MacOS/mrt -a -r ~/Library/LaunchAgents/com.abc.123.c1e71c3d22039f57527c52d467e06612af4fdc9A.plist
What happens next is that the potentially bad thing to scan will be checked to see if it matches a known hash from MRT or from /private/var/db/SystemPolicyConfiguration/XProtect.bundle/Contents/Resources/XProtect.yara, and the file will be removed if so. A clean output will look like the following:
2018.09-24 21:19:32.036 mrt[48924:4256323] Running as agent
2018.09-24 21:19:32.136 mrt[48924:4256323] Agent finished.
2018.09-24 21:19:32.136 mrt[48924:4256323] Finished MRT run

Yara rules are documented at https://yara.readthedocs.io/en/v3.8.0/. For a brief explanation of the json you see in those yara rules, see https://yara.readthedocs.io/en/v3.5.0/writingrules.html. Apple can update the yara rules silently.

A user would have had a username and password for most malware to run properly. XProtect with mrt protects against hundreds of file hashes that include over 100 variants of threats. Those are threats that Apple has effectively publicly acknowledged for the Mac based on their inclusion in Apple-supplied files. Most malware is a numbers game. The attacker needs to get enough people to click on a phishing email (e.g., one that looks very legitimate about their iTunes account), and the attacker can start sending things from their computers to further the cause provided they can make the message seem credible enough to accept.

The mrt binary runs somewhat resource intensive at the moment, and a common troubleshooting step is simply moving the binary out of the MRT.app directory, a heavy-handed way to disable mrt. All of this leads to Gatekeeper, XProtect, and mrt not covering the possible threats a third-party tool might cover. However, there are some tools that wrap mrt into graphical interfaces. One is DetectX from Phil Stokes of SentinelOne (Figure 8-24).

A screenshot of the detect X window. There is the logo of detect X swift at the top with a status bar below it. There are 3 boxes for the options, search, profile, and history.

Figure 8-24

DetectX

The XProtect and bundle information is stored in the CFBundleShortVersionString field in /Library/Apple/System/Library/CoreServices/XProtect.bundle/Contents/Info.plist and can be checked with the defaults command as follows:
defaults read /Library/Apple/System/Library/CoreServices/XProtect.bundle/Contents/Info.plist CFBundleShortVersionString
This can be used with an agent to make sure the XProtect information is up to date. MRT can also be checked with the same key but in the /Library/Apple/System/Library/CoreServices/MRT.app/Contents/Info.plist file as follows:
defaults read /Library/Apple/System/Library/CoreServices/MRT.app/Contents/Info.plist CFBundleShortVersionString

These tools are not sufficient for most compliance needs, and so third-party tools like Symantec, Sophos, SentinelOne, Jamf Protect, and others are often employed instead. Another default protection on the Mac that we’ve covered is the fact that all apps need to be signed (and many notarized).

Signing Applications

It’s not terribly difficult to sign an app, given that all you need is a signing certificate. All apps should be signed by Apple in the future, per Apple’s changing guidelines to keep end users secure. Simply use the codesign command-line tool.

To view the signature used on an app, use codesign:
codesign -dv MyAwesome.app
The same would be true for a package, which is equally as dangerous when provided with an administrative account:
productbuild --distribution mycoolpackage.dist --sign MYSUPERSECRETIDENTITY mycoolpackage.pkg
And some files are distributed in disk images (.dmg files). To sign a dmg:
codesign -s MYSUPERSECRETIDENTITY mycooldmg.dmg

So codesign is used to manage signatures and sign, but spctl only checks things with valid Developer IDs, and spctl checks items downloaded from the App Store. None of these allow for validating a file that has been brought into the computer otherwise (e.g., through a file share). These help to keep binaries from running on machines as persistent threats that might, for example, subvert a traditional malware defense infrastructure.

ClamAV

ClamAV is an antivirus application that is among the easiest to use. It is available at www.clamxav.com in a variety of languages. Although ClamAV lacks many of the features available in some of the commercial packages that are centrally manageable, it is a great and accessible tool that can be used as a first-line-of-defense warning system against malware. The underlying code is actually developed and distributed by the open source community as part of the ClamAV project. The GUI tools that ClamXAV brings to the table can then be distributed to large numbers of users to help administrators discover virus outbreaks and perform quarantine measures on infected files.

ClamXAV is a front end for ClamAV, which provides a nice graphical interface to ClamAV for a nominal cost. Other third-party antivirus solutions include Carbon Black, Cisco AMP, Malwarebytes, Panda Security, Sophos, Symantec, Trend Micro, Webroot, and now even Microsoft. For more, see Appendix A.

There are a number of ways to install ClamAV. For this example, just to get it done quickly, we’ll use homebrew which is simply brew with the install verb and clamav as the recipe to be brewed:
brew install clamav
This places the configuration files in /usr/local/etc/clamav, and these cannot be used as those supplied by default are simply sample configurations. Because the .sample files have a line that indicates they are an “Example,” they cannot be used. So we’ll copy the sample configuration files for freshclam.conf and clamd.conf (the demonized version) and then remove the Example line using the following two lines:
cp /usr/local/etc/clamav/freshclam.conf.sample /usr/local/etc/clamav/freshclam.conf; sed -ie 's/^Example/#Example/g'/usr/local/etc/clamav/freshclam.conf
cp /usr/local/etc/clamav/clamd.conf.sample /usr/local/etc/clamav/clamd.conf; sed -ie 's/^Example/#Example/g'/usr/local/etc/clamav/clamd.conf
Next, we’ll need to update the virus definitions for clamav. This can be run without the fully qualified file path, but we are going to go ahead and include it as some computers might have another version installed (e.g., via macOS Server):
freshclam -v
The initial scan should cover the full hard drive and can be run as clamscan:
sudo /usr/local/bin/clamscan -r — bell -i /
Your routinely run jobs should be set up to a quarantine location. Because all users should be able to see their data that was quarantined, we would write this to /Users/Shared/Quarantine. We can then use a standard clamscan to scan the system and then “move” quarantined items to that location and log those transactions to /Users/Shared/Quarantine/Quarantine.txt.
sudo mkdir /Users/Shared/Quarantine
sudo clamscan -r — scan-pdf=yes -l /Users/Shared/Quarantine/Quarantine.txt — move=/Users/Shared/Quarantine//
You can then use an Extension Attribute to read the Quarantine.txt file (the following is an example of using a Jamf Extension Attribute to do so):
#!/bin/bash
#Read Quarantine
result = `cat /Users/Shared/Quarantine/Quarantine.txt`
#Echo Quarantine into EA
echo"<result>$result</result>"

The clamdscan binary is multithreaded and hence runs a lot faster than a clamscan call. You can easily daemonize ClamAV by using this repo, which has a plist that automatically runs on-demand clamdscan on a schedule: https://github.com/essandess/macOS-clamAV.

Every environment is different. When combined with standard mrt scans using the built-in malware removal tool for macOS, ClamAV can provide a routine added protection to isolate and help you remediate infections. You can easily run this nightly and parse the quarantine.txt file prior to picking it up with the Extension Attribute routinely in order to provide an additional layer of defense against potential threats to the Mac. Putting all of this into a software package would be rudimentary and could benefit many organizations without putting our coworkers through the performance hit that many a commercial antivirus (or more importantly full malware prevention or threat hunting) solution brings with it.

Threat Management on iOS

There are plenty of threats of any kind of device; however, iOS is more secure than most. As with securing a Mac, start with the Apple security guide at www.apple.com/business/resources/docs/iOS_Security_Overview.pdf and determine what gaps your organization might have. For the most part, keeping devices running the latest operating system, make sure to have a passcode on devices (or Touch ID or Face ID) and make sure your servers encrypt communication to and from devices. Some organizations will also look to containerization technologies and restricting features of devices. Make sure to go through each restriction available with an information security team and check which correspond to an organization’s security posture. This will keep you from starting to think that iOS is immune from any external threats.

YiSpecter was the first iOS malware to infect jailbroken and nonjailbroken phones by abusing private APIs in the iOS system. The malware spread via hijacked traffic from nationwide ISPs within China and Taiwan, an SNS worm on Windows, and an offline app installation and community promotion. YiSpecter contains four components signed with enterprise certificates. Abusing the APIs allows these components to download from a server and install on a targeted iOS device. Three of these components hide their icons, preventing the user from finding and deleting them. After infection occurs, iOS apps can be downloaded, installed, and launched; existing apps can be replaced with other apps; apps can be hijacked to display advertisements; Safari’s default search engine can be changed; and device information can be sent to the C2 server. YiSpecter is capable of maintaining persistence on the device and can defeat attempts to delete it. Abusing private APIs allows even iOS users who only download apps from the official App Store to be infected with YiSpecter.

The landscape is very different on iOS than most any other platform – yet another reason macOS continues to move in the direction of iOS. Most security solutions available to mobile devices such as an iOS device try to protect against the following types of attacks:
  • Rogue AP: A wireless access point that is made to look like a legitimate network in order to perform man-in-the-middle attacks.

  • Man-in-the-middle: Intercepts insecure communication between a server and a client by pretending to be the intended server.

  • SSL strip: Replaces encrypted HTTPS version of a web page with an HTTP version so the unencrypted traffic can be captured.

  • Femtocell: A fake antenna is used to intercept traffic on a cellular network.

All of these are basically about intercepting communication and not attacking an actual device. There have been small attacks that involved brute forcing the device when plugged into a computer, but nothing very successful. Many organizations will not need a tool for their iOS deployments. If you do, start the hunt for a vendor that does real things at Zimperium and Cylance and do a thorough review of what protections each provider offers as compared to those your organizational security posture requires. Things to look for might be a demo of them blocking a real-world example of an exploit.

Additionally, phishing is one of the top threats for the iOS and iPadOS devices. This is where ZTNA and other zero-trust solutions become important for most environments. These are often provided by companies like Palo Alto, the Citrix Zscalar, and Cisco. There are some that are fairly Apple-centric, like Jamf Private Access and Jamf Threat Defense, which was built based on Jamf’s acquisition of Wandera. All of these tools require routing data from a device to a server like how proxies and VPNs work. These protect network access but don’t typically help with binaries that can run on devices, which is more an issue with the Mac.

macOS Binary Whitelisting

By default, only binaries loaded through the App Store or installed via an ipsw can be opened on an iOS device and Apple TV. The Mac is much more open, even though it has been closing down more and more in the past few years. Of the binaries that can be opened on a Mac, you can limit them using what is known as binary whitelisting or binary blacklisting.

There are a few techniques for managing which binaries can be opened on Apple devices. The original technique to manage binaries, which still mostly works, but is actively being deprecated, was using MCX, or Managed Client Extensions. The easiest way to describe how this worked was with the now defunct Workgroup Manager, seen in Figure 8-25. More modern techniques include
  • Gatekeeper, which was covered earlier in this chapter, which can be managed through the command line, through a Privacy & Security configuration profile manually, or via MDM

  • Editing the permissions to remove access to an app either manually through the Finder or using a script

  • Using a Restrictions profile through MDM or installed manually (only covers certain Apple apps)

  • Using a third-party LaunchDaemon or agent that can terminate apps which have been blacklisted

  • Blocking the installation of a given application, as is done with Munki (https://github.com/munki/munki/wiki/Blocking-Applications)

A screenshot of the workgroup manager local window. The left section has a search bar with the group name below it. The section to the right has the selected applications option. It contains a list of applications with the text, always allow these applications, at the top.

Figure 8-25

MCX in Workgroup Manager

As seen in the preceding screen, it’s possible to whitelist only the Applications a given user should be able to launch. If this is something you need to do and you want to do so sanely, then consider Google Santa. Available at https://github.com/google/santa, Santa is a project that uses a kernel extension to monitor for the execution of a blocked binary and then terminates it.

A screenshot of Google Santa. It has the name of the application, path, publisher, identifier, parent, and user. There are buttons for the next steps and dismiss at the bottom.

Figure 8-26

Google Santa

This is one of those rare places where a kernel extension is necessary to shut down a binary before it could potentially do harm to a system or the network environment a system is in. As can be seen in Figure 8-26, Santa reacts so quickly that a notice can be displayed indicating that access to an application has been blocked.

The reason we said “sanely” is because a large user base is likely to run a lot of software you don’t know about. So prior to deploying a tool like Santa, you’ll likely define all of the software allowed to be run on your fleet only to end up having to pull back your spiffy new whitelisting solution because users are angry about it. Upvote is another Google tool available at https://github.com/google/upvote that allows users to submit apps to be whitelisted, and then when an app has had enough votes, the app is whitelisted. This allows users to self-manage what software is allowed en masse.

Compliance

Sometimes, it seems like every organization has a different interpretation of what compliance is. Not only are there dozens of compliances (from SOC2 to CIS to FedRAMP), but there is an interpretation to each of their components that is left to the attorneys at a given organization. And then as engineers, we often tighten various areas where we feel confident and smile and nod in areas we don’t.

There is remedial compliance checking in a number of device management solutions. Workspace ONE and Jamf both have the ability to check devices for compliance. These are configuration management solutions. Additionally, there are a number of third-party solutions dedicated to scanning a device for compliance against known frameworks, such as Qualis or Lynis, which can be found at https://cisofy.com/lynis/.

One of the most common guidelines for compliance today is the CIS Benchmarks, put out by the Center for Internet Security and available freely at www.cisecurity.org/cis-benchmarks/. An example of scanning to check if a computer meets those guidelines would be using the extension attributes and remediation scripts available at https://github.com/jamf/CIS-for-macOS-High-Sierra-CP, which is written to work with Jamf Pro but can be conformed to other tools if need be as was done with the NIST macOS Security Compliance project (https://github.com/usnistgov/macos_security). Beyond checking to see if a device is in compliance, a number of organizations also need to review logs to check for unapproved or anomalous security events. In the next section, we’ll review the logging API in macOS.

Note

Logs are not available in the graphical interface of an iOS device but can be viewed using the Console app on a Mac.

Centralized Log Capture and Analysis

Apple has a number of different logging APIs. For the past few releases, Apple has tried to capture everything possible in logs, creating what many administrators and developers might consider to be a lot of chatter. As such, an entirely new interface needed to be developed to categorize and filter messages sent into system logs.

Writing Logs

The logger command is used to create entries in system logs. However, if you are then using tail to view /var/log/system.log, then you will notice that you no longer see your entry being written. This is because as the logs being created in macOS have gotten more complex, the tools to read and write those logs have gotten more complicated as well. Let’s take a simple log entry. In the following example, we’ll write the string “Hello Logs” into the system log.

To do so, use the –i option to put the process ID of the logger process and –s to write to the system log, as well as to stderr. To make the entry easier, we’ll tag it with –t followed by the string of the tag. And finally, we’ll quote the entry we want written into the log. This is basically the simplest form of an entry:
logger -is -t krypted "Hello Logs"

Once written, use the log command to read new entries. If you are developing scripting tools, you will need to note that all of the legacy APIs you might be using, which include asl_log_message, NSLog, and syslog, have been redirected to the new Unified Logging system, provided you build software for 10.12 (you can still build as before for 10.11, iOS 9, tvOS 10, and watchOS 3 and below). These are replaced with the os_log, os_log_info, os_log_debug, os_log_error, os_log_fault, and os_log_create APIs (which correspond to various levels of logs that are written).

Reading Logs

Logs are now stored in the tracev3 formatted files in /var/db/diagnostics, which is a compressed binary format. As with all binary files, you’ll need new tools to read the files. Console has been updated with a new hierarchical capability and the ability to watch activities, subsystems, etc.

The log command provides another means of reading those spiffy new logs. To get started, first check out the man page: (using the man log command). The log command can be used to easily view logs using the “log show” command. In the following example, we’ll just run a scan of the last three minutes, using the –last option, and then provide a –predicate. We’ll explain those a bit later, but think of it as query parameters – here, we’ll specify to look for “Hello Logs” in eventMessage:
log show --predicate 'eventMessage contains "Hello Logs"' --last 3m
Filtering the log data using "eventMessage CONTAINS "Hello Logs"" shows us that our entry appears as follows:
Timestamp                       Thread     Type
Activity             PID 2022.08-23 23:51:05.236542-0500 0x4b83bb   Default     0x0                  88294  logger: Hello Logs ——————————————————————————————————————– Log –
Default:          1, Info:                0, Debug:
0, Error:          0, Fault:          0 Activity – Create:           0, Transition:          0, Actions:           0
How do you find out what to use where? Here’s an example where I’m going to try to find all invalid login attempts. First, I’m just going to watch the logs. Many will prefer the “log stream” command. I’m actually going to just use show again, because I like the way it looks more. I’m also going to use log with the syslog –style so it’s easier to read (for me at least), and then here I’m just looking at everything by specifying a space instead of an actual search term:
log show --style syslog --predicate 'eventMessage contains " "' --info --last 24h
Looking at the output, you can see an entry similar to the following:
2022.08-23 14:01:43.953929-0500  localhost authorizationhost[82865]: Failed to authenticate user <admin> (error: 9).
Just search for “Failed to authenticate user,” and I’ll be able to count invalid login attempts. To then take this and place it into a command that, for example, I could build an extension attribute using, I can then just find each entry in eventMessage that contains the string, as follows:
log show --style syslog --predicate 'eventMessage contains "Failed to authenticate user"' --info --last 1d
As with many tools, once you have a couple of basic incantations, they become infinitely simpler to understand. These few commands basically get you back to where you were with tailing logs. If you want to get that –f functionality from tail, to watch the logs live, just swap show with stream. The most basic incantation of this would just be "log stream" without bothering to constrain the output:log stream. Running this is going to spew so much data into your terminal session. So to narrow down what you’re looking for, let’s look at events for Twitter: log stream --predicate ‘eventMessage contains “Twitter”’. You can also view other logs and archives by calling a filename:
log show system_logs.logarchive

Now that you can browse logs, in the next section, we’ll cover how they’re organized and classified starting with Subsystems.

Organization and Classification

The logging format also comes with Subsystems. If you’re a developer, you’ll be able to file your messages into, for example, a com.yourname.whatevers domain space, so you can easily find your log messages. You can also build categories and of course, as we noted previously, tag. So there are about as many ways to find log entries as you can possibly ask for. Apple has a number of subsystems built into macOS. We put together a list of Apple subsystems into a class that you should be able to throw into your python projects at https://gist.github.com/krypted/495e48a995b2c08d25dc4f67358d1983.

You also have different logging levels. These include the basic levels of Default, Info, and Debug. You also have two special levels available: Fault and Error. All of this is to add hierarchical logs (which makes tracing events a much more lovely experience) and protect privacy of end users (think sandbox for logs). I’d recommend watching the WWDC session where Unified Logging was introduced at https://developer.apple.com/videos/play/wwdc2016/721 if interested in learning more about these types of things, especially if you’ll be building software that makes use of these new logging features.

The one thing that’s worth mentioning for the Mac Techs out there is how you would go about switching between logging levels for each subsystem. This is done with the “log config” command. Here, I’ll use the –mode option to set the level to debug and then define the subsystem to do so with the –subsystem option: log config --mode “level:debug” --subsystem com.krypted. If you have a particularly dastardly app, this might just help you troubleshoot a bit. As mentioned earlier, we also have these predicates, which you can think of as metadata in the searching context. These include the following:
  • category: Category of a log entry.

  • eventMessage: Searches the activity or message.

  • eventType: Type of events that created the entry (e.g., logEvent, traceEvent).

  • messageType: Type or level of a log entry.

  • processImagePath: Name of the process that logged the event.

  • senderImagePath: Not all entries are created by processes, so this also includes libraries and executables.

  • subsystem: The name of the subsystem that logged an event.

Comparisons and Searches

Let’s make things just a tad bit more complicated. We’ll do this by stringing together search parameters. Here, we have a number of operators available to us, similar to what you see in SQL. These include the following:
  • && or AND indicates two matches.

  • || or OR indicates one of the patterns matches.

  • ! or NOT searches for items that the patterns don’t match for, which is useful for filtering out false positives in scripts.

  • = indicates that one search matches a pattern or is equal to.

  • != indicates that the search is not equal to.

  • > is greater than.

  • < is less than.

  • => means greater than or equal to.

  • =< means less than or equal to.

  • CONTAINS indicates a string matches a given pattern with case sensitivity.

  • CONTAINS[c] indicates a string matches a given pattern without case sensitivity.

  • BEGINSWITH indicates a string begins with a given pattern.

  • ENDSWITH indicates that a string ends with a given pattern.

  • LIKE indicates a pattern is similar to what you’re searching for.

  • MATCHES indicates that two text strings match.

  • ANY, SOME, NONE, IN are used for pattern matching in arrays.

  • NULL indicates a NULL response (e.g., you see “with error (NULL)” in logs a lot).

To put these into context, let’s use one in an example. Thus far, my most common use case has been a compound search, so in this example we’ll be matching both patterns. Here, we’ll look at the WirelessProximity subsystem for Bluetooth, and we’ll look at how often it’s scanning for new devices, keeping both patterns to match inside their own parentheses, with all patterns stored inside single quotes, as follows: log show --style syslog --predicate ‘(subsystem == “com.apple.bluetooth.WirelessProximity”) && (eventMessage CONTAINS[c] “scanning”)’ --info --last 1h. Developers and systems administrators will find the Apple guide on predicate programming, available at https://developer.apple.com/library/prerelease/content/documentation/Cocoa/Conceptual/Predicates/AdditionalChapters/Introduction.html, to be pretty useful if you’re doing lots of this kind of work.

Simply run the log command with the show verb. I’m including –last to only look at the last couple of minutes and then using –predicate to define that the processImagePath contains the word Slack, the app I’m searching for:
log show --last 120s --predicate 'processImagePath CONTAINS[c] "Slack"'
Note

sysdiagnose, a tool long used for capture diagnostics information to include in bug reports, is still functional and now includes Unified Logging information, so Apple developers can get a complete picture of what’s going on in systems.

Ultimately, the new Unified Logging is a bit more complicated than the previous options for both creating and reading logs. But once you get used to it, you’ll log it – I mean, love it.

The built-in logging facilities in macOS provide logging for a number of tasks, mostly those app developers choose to log events for. But you can get deeper with Apple’s implementation of Sun’s Basic Security Module, or OpenBSM.

OpenBSM

OpenBSM is a subsystem that has been installed on the Mac for some time. While deprecated as of macOS Big Sur and replaced with the Endpoint Security API for system extensions, OpenBSM provides the ability to create and read audit logs based on the Common Criteria standards. By default, OpenBSM is not enabled, so we’ll go through checking what is being audited, enabling, and reviewing those logs.

Audit Logs

OpenBSM stores information about security events in audit logs. The quick and easy way to see what OpenBSM is auditing is to cat the /etc/security/audit_control file, as follows:
cat /etc/security/audit_control
The output displays the directory of audit logs, as well as what is currently being audited. By default, the configuration is as follows:
#
# $P4: //depot/projects/trustedbsd/openbsm/etc/audit_control#8 $
#
dir:/var/audit
flags:lo,aa
minfree:5
naflags:lo,aa
policy:cnt,argv
filesz:2M
expire-after:10M
superuser-set-sflags-mask:has_authenticated,has_console_access
superuser-clear-sflags-mask:has_authenticated,has_console_access
member-set-sflags-mask:
member-clear-sflags-mask:has_authenticated
You can then see all of the files in your audit log, using a standard ls of those:
ls /var/audit
As you can see, the files are then stored with a date/timestamp naming convention:
2220119012009.crash_recovery 20220407065646.20180407065716 20220407073931.20220407074018
20220119022233.crash_recovery 20220407065716.20180407065747 20220407074018.20220407074050
20220119043338.crash_recovery 20220407065748.20180407065822 20220407074050.20220511030725
20220119134354.crash_recovery
20220407065822.20180407065853

The files are binary and so cannot be read properly without the use of a tool to interpret the output. In the next section, we will review how to read the logs.

Using praudit

Binary files aren’t easy to read. Using the praudit binary, you can dump audit logs into XML using the -x flag followed by the path of the log. For example, the following command would read a given log in the preceding /var/audit example directory:
praudit -x 20180407065748.20180407065822
One record of the output would begin as follows:
record version="11" event="session start" modifier="0" time="Sat Aug  7 01:58:22 2022" msec=" + 28 msec" >
<argument arg-num="1" value="0x0" desc="sflags" />
<argument arg-num="2" value="0x0" desc="am_success" />
<argument arg-num="3" value="0x0" desc="am_failure" />
<subject audit-uid="-1" uid="root" gid="wheel" ruid="root" rgid="wheel" pid="0" sid="100645" tid="0 0.0.0.0" />
<return errval="success" retval="0" />
</record>

In the preceding output, find the time that an event was logged, as well as the type of event. This could be parsed for specific events and, as an example, just dump the time and event in a simple json or xml for tracking in another tool, for example, if you’re doing statistical analysis for how many times privileges were escalated as a means of detecting a bad actor on a system.

You can also use the auditreduce command to filter records. Once filtered, results are still in binary and must be converted using praudit. You can also stream OpenBSM output over a tool formerly called cmdReporter and now a part of Jamf. A tool like this is helpful to get logging data to what’s known commonly as a SIEM, or Security Information and Even Management system, such as Splunk. Of course, the ability to have an event that violates an organization’s policies assumes users actually have permissions to perform some of those tasks (although logging failures is common as well). We’re not going to go in depth on editing the Authorization Database on a Mac, a journey that begins at /System/Library/Security/authorization.plist. The database is a SQLite database stored at /var/db/auth.db which can easily be viewed using the
security authorizationdb read admin

The default values change, but for older operating systems, these can be seen at http://krypted.com/utilities/authorizationdb-defaults-macos-10-14 or historically at www.dssw.co.uk/reference/authorization-rights/. For more on scripting changes to the database to provide more granular access, see https://scriptingosx.com/2018/05/demystifying-root-on-macos-part-4-the-authorization-database/.

Given that many organizations will not have the time, skills, or inclination for such granular permissions management, tools like Avecto Defendpoint alter the database on behalf of administrators using a least privilege model. This is important as in high-security environments, Mac users can work without needing admin rights yet remain on task and not calling the service desk every time they need to reset a printer queue.

How do you know what privileges they need or what to look for in logs, or what a system is actually doing? This is one of the hardest parts of information security and, once you get started, the most fun: reverse engineering.

Reverse Engineering

The documentation provided by any vendor about their software only goes so far. Apple has some pretty solid documentation, but when it comes to security research, the ability to decompile, disassemble, and trace signals sent by software is important. There are entire books on these topics – and most of the techniques are similar enough between Windows, Linux, and macOS. And therefore, some of the tools are easily used, or ported, between the platforms, especially the open source tools.

As an example of these low-level similarities, most computers use a 64-bit version of x86 architecture, and most mobile devices use a variation of ARMv8. Different implementations of ARM and x86 have their own modes and formats, but in general reverse engineering is done using similar tools (if not the same tools). macOS seems more and more built for software developers with every passing year.

There are a number of these tools that are well documented, including the following:
  • Class-dump is a tool used to view Objective-C runtime information stored in Mach-O files. Seeing class declarations and headers provides you with a lot of information about what a file is doing. Class-dump can be found at http://stevenygard.com/projects/class-dump/ and represents one of the better tools to locate private APIs in macOS.

  • codesign: Command-line tool built into macOS that outputs extremely granular information about signatures used to sign code and installation packages.

  • dtrace: Short for dynamic tracing, dtrace (built into macOS) can show anything you can build a program to access using the D programming language. For example, you can get as finely grained as a script that outputs the arguments used calling a function. You can only do this with SIP disabled, but then, you can only do reverse engineering on an iOS device if you’ve jailbroken the device.

  • Hopper Disassembler (Figure 8-27) is a solid tool for translating machine language into assembly. Hopper isn’t going to show you the raw code for compiled files, but can help you find files and information that points you in the right direction during research.

  • IDA is short for Interactive Disassembler and should be reserved for highly complex research tasks. IDA is available at www.hex-rays.com/products/ida/.

  • lldb: Built-in macOS lldb debugger library interface (if you call one of these tools a debugger or a reverse engineering tool is really determined based on your profession).

  • Lulu (https://objective-see.com/products/lulu.html) and Little Snitch (www.obdev.at/products/littlesnitch) both prompt and provide information about egress and ingress network connections.

  • MachOView provides a view into Mach-O files using a GUI but hasn’t been updated for some time so suffers from stability issues. To download the latest version, see https://github.com/gdbinit/MachOView.

  • nm: Built-in tool for viewing names and symbols in Mach-O executables.

  • otool: Command-line tool built into macOS that shows dependencies (based on what frameworks were included in a piece of software which can be seen using the -L option) and allows you to view raw Mach-O executables. To find all apps dependent on a given binary, see https://github.com/krypted/looto.

  • Task Explorer: Free tool to receive really detailed information about processes running on a Mac, https://objective-see.com/products/taskexplorer.html.

A screenshot of Firefox dot h o p window. The left section has a search bar with address, type, and name below it. The right section has the file information, address information, navigation information, navigation history, instruction encoding, graphic views, format, and comment.

Figure 8-27

Hopper Disassembler

Perhaps we’ll write a book about reverse engineering someday because we used so many more tools and products to write this book, but the best way to get started would be to download some of these tools and start playing around or try to answer a specific question, like installing some malware (you can find plenty of samples to play with at https://objective-see.com/malware.html) on a virtual machine and start trying to figure out what it’s trying to do, by reading source code, taking it apart, and watching signals.

Beyond reverse engineering, there’s an emerging discipline for iOS known as threat hunting. This is the act of looking for malware or other threats on the Mac. MonitorKit, from Digita Security (https://digitasecurity.com) is an event-driven macOS monitoring framework, written in Swift (compatible with Objective-C), that gives developers easy-to-use access to a wide array of native macOS monitoring capabilities.

MonitorKit minimizes the complexity of using the native macOS APIs while maximizing event details with its comprehensive data model. Underlying the MonitorKit framework are OpenBSM, FSEvents, Spotlight Notifications, Event Taps, IOKit, and CoreMedia. It builds upon code samples and proven techniques for accessing system event streams from experts such as Jonathan Levin (http://technologeeks.com/course.jl?course=OSXRE) and Patrick Wardle (https://Objective-See.com). As you can see in Figure 8-28, MonitorKit has a number of options for events it can track out of the box.

A screenshot of the Monitor Kit. The bar at the top has the icons for process, file, download, screen capture, webcam, mic, keylogging, login, U S B, and synthetic clicks.

Figure 8-28

MonitorKit

Jamf Protect is Endpoint Detection and Response (EDR) tailor-made for macOS, built on top of MonitorKit, among other tools. Through on-device analysis of macOS system events, Jamf Protect (originally called GamePlan) creates unprecedented telemetry and provides enterprise security teams with the insights they require for behavioral detections and threat hunting. With its streaming insights and KEXT-less design, Protect extends Apple’s security and privacy model to an enterprise while upholding the Apple user experience and never delaying an OS upgrade.

There are a number of other tools, many of which are provided by large technology companies that are happy to sell software that works on the Mac, but often don’t work as well as we’d like. This isn’t to say there isn’t merit in them, and there are tools out there evolving at a rapid pace. And, of course, there are environments that see no need for any security solutions whatsoever, relying entirely on their own automations using built-in frameworks in macOS.

Administrator Rights on macOS

An important topic from both an operational and security standpoint is how to manage administrator rights for the user accounts used on the fleet. Before delving into that, first some backstory on how administrator rights came to exist on macOS.

Apple currently has five platforms available:
  • iOS

  • iPadOS

  • macOS

  • tvOS

  • watchOS

Most of these Apple platforms do not have the concept of multiple users. There's just one user state in play by default. iOS and iPadOS do include authentication, but there is still usually only one user context which is in scope.

iPadOS does have the concept of multiple user accounts via supporting user sessions for multiple Managed Apple IDs, but that's a special configuration option for when sharing an iPad between multiple people is necessary. All of the Managed Apple ID user accounts are equal in terms of what they can do on the iPad, so the idea of standard user vs. admin user doesn't come into play. Instead, the user paradigm is equal user rights with separation of documents and data for each user.

It's only on macOS that the paradigm of multiple user accounts and those accounts having different permissions for access and actions exists. The Macs haven’t always had it though. If you look at the various versions of the original Mac OS between System One’s introduction and Mac OS 9, you see a similar user paradigm to what you see on Apple’s other platforms. By default, there was only one user context, and the operating system would boot into it automatically.

So if the paradigm we use today didn’t come from the original Mac OS, where did it come from?

It comes from NeXT Computers and more specifically the Unix-based NeXTSTEP operating system developed by NeXT. When Apple bought NeXT in 1996, it began using NeXTSTEP’s foundations to build what would eventually become Mac OS X. This included building a Unix-based operating system, which included multiple user accounts. More importantly for this topic, NeXTSTEP included the paradigm of an account named root which is a superuser account. On NeXTSTEP, root can do anything. It has read/write access to the entire local filesystem and can run any command.

Apple had previously built Unix-based operating systems with superuser accounts for specialized purposes, but with this change, Apple began mainstreaming the paradigm for its main operating system of both multiple user accounts and a superuser account which has more access and privileges than other user accounts.

However, there’s only one root user in Unix and only one password to that account. Sharing passwords is a security issue. Apple’s solution was to introduce a new set of superuser privileges for Mac OS X, which they designated an admin account. These privileges could then be applied to multiple accounts.

Management of which accounts have admin rights is handled by membership in a local group on the Mac named admin, shown in Figure 8-29. However, membership in this group only handles admin rights for the Mac OS X graphical user interface.

A screenshot of the directory utility window. It has icons for services, search policy, and directory editor. The option directory editor has been selected. The left section has a search bar with selected administrators. The right section has the name and value.

Figure 8-29

Accessing the admin group in Directory Utility.app

To provide administrative rights on the command line, Apple uses the sudo command-line tool. This tool enables authorized user accounts to run commands as root or another user. As part of the OS installation process, Apple installs a configuration file for sudo that grants members of the admin group all the privileges that the sudo tool can grant. In turn, this means that members of the admin group have the same ability as the root account to run all commands and functions with the root account’s privileges (Figure 8-30).

A screenshot of username pico sudo window. It highlights the default sudo configuration. It is % admin, A L L equals open parenthesis A L L close parenthesis A L L.

Figure 8-30

Default sudo configuration for macOS with admin group’s permissions highlighted

With regard to the actual root user, Apple put some controls in place to limit the root user account's abilities and permissions. These controls include disabling the root account by default, discouraging its use, and providing ways to access elevated or root privileges using other means.

This paradigm of multiple user accounts, a superuser account whose use is discouraged, special accounts (referred to as administrator accounts) which have more access and privileges than other user accounts, and nonspecial accounts (referred to as standard accounts) has been used in all versions of the Mac operating system from Mac OS X 10.0 Cheetah through to today's version of macOS.

Administrator and standard accounts have different access and privileges, as described as follows:

Administrator Account

Standard Account

Install software

Install software*

Change their own account’s settings and system settings

Change their own account’s settings

Add or manage user accounts

 

* Standard accounts can install software into areas of the filesystem where the standard account has read and write permissions, like the standard account’s home folder. It is also possible for standard accounts to install software in situations where Apple makes it possible, like installing software from the App Store on macOS or running software updates using Software Update in System Settings.

Note

Why does it matter if an account has admin rights or not? Because anything the root account on macOS can do, an account with administrator rights can do.

Giving admin rights to a user account on the current version of macOS means they now have all the powers that the root account has. That said, as discussed earlier in this chapter, the power of the root account is constrained by the following security measures built into macOS:
  • Signed system volume

  • System Integrity Protection

  • User-level privacy protections

With these protections in place to contain the power of the root account, where large sections of the filesystem can’t be written to or altered and user data requires permission to access, let’s reexamine the statement about root as it relates to administrator rights. It remains true that anything root can do, an account with admin rights can do, but what root can do on macOS is significantly contained compared to other Unix-based OSs. With the lowered capability also comes lowered risk.

Now that we’ve examined how admin rights work and their capabilities, let’s look at managing them. As discussed earlier, Apple has enabled an account to have admin rights in two locations:
  • Admin rights in the graphical user interface: Adding the user account to the admin group

  • Admin rights for the command line: Apple installing a configuration file for the sudo tool which grants all available privileges to the admin group

With these rights being managed in two locations, this leaves open the possibility that admin rights in the macOS graphical user interface and the command line can be managed separately. If desired, you could assign admin rights in the GUI but not to the command line or vice versa by editing the sudo configuration file to change it from Apple’s default settings.

Note

sudo configuration options are available via the sudo documentation: www.sudo.ws/docs/man/1.8.17/sudoers.man/.

Assuming that you choose to manage admin rights, there’s three states of management to consider for your accounts:
  • Permanent admin rights

  • No admin rights

  • Admin rights allowed on a nonpermanent basis

Permanent admin rights can be granted to an account by adding the account in question to the admin group and not removing it. With Apple’s default configuration for sudo, this should grant the account administrator rights for both the graphical user interface and the command line.

Not granting administrator rights to an account means making sure that the account is not a member of the admin group. Assuming Apple’s default configuration for sudo, keeping the account out of the admin group should ensure it only has the rights granted to a standard user account.

Granting administrator rights on a nonpermanent basis to an account usually means that there is a mechanism in place to enable the account to be added and removed from the admin group as needed.

Is there a one best way for deciding how to manage admin rights? Unfortunately, not. There are a number of factors which affect this decision, which may include legal requirements, complying with the requirements of an external standard that your business has committed to complying with, internally created policy requirements of your company, school, or institution, or operational requirements in your environment.

No matter what other factors exist, the key question which must be answered is going to be if you can trust your users with admin rights while also remaining in compliance with your other requirements. If you can, then (in this author's opinion) they should have them. If you can’t, then they shouldn’t.

If you make the choice to grant admin rights on a nonpermanent basis, as mentioned earlier, you will likely need a mechanism in place which can enable accounts to be added and removed from the admin group as needed. A tool for enabling this is the Privileges app (Figure 8-31), an application developed and open sourced by SAP, which allows a user account which is logged in to macOS’s graphical user interface to grant and remove administrator rights.

A screenshot of Privileges window. There is a pop-up window on the screen with the text, you are currently a standard user. Would you like to request administrator privileges? There are buttons for options, request privileges and cancel at the bottom.

Figure 8-31

Privileges app granting administrator rights to an account

Note

The Privileges app and configuration documentation are both available on GitHub: https://github.com/SAP/macOS-enterprise-privileges.

Summary

The Mac is still very much treated as a computer by most corporate IT departments. Therefore, they will expect the same full complement of tools to be used on the Mac so it is an equal citizen to Windows. You may disagree that you need a tool to perform various tasks, but that doesn’t mean that you always have the option to choose whether to run these tools or not. iOS is very different. You can’t run an agent on iOS. But you can check that the device meets certain criteria and look for threats on the device.

You have to implement these tools, settings, or procedures so the device is compliant with the policies required to be able to get on the network of most organizations. Doing so may require two to three agents. But the alternative is likely that you can’t let devices access the network.

Ultimately, the Mac team at most organizations will start off by integrating solutions the larger Windows population of devices already leverage. For example, if you’re using Symantec products for other platforms, you probably already have licensing and so will just use those same tools to secure the Mac. However, as your deployment matures and grows, you will end up with the political capital to go to your CISO and argue for the tools that work best for the platform (see Appendix A) or to explain why those tools are irrelevant for the platform your team manages.

Some of the more talented administrators might read this chapter and be surprised that something wasn’t covered. We included the links to Apple’s security documents and didn’t want to duplicate any of the content covered there. Some aspects of securing devices simply couldn’t be covered as they’re moving targets, though. Security might be the fastest changing landscape in technology.

Now that you’re starting to get a number of different tools running on devices throughout your enterprise, let’s shift our attention toward testing, so you can make sure everything works when Apple accelerates the rate of change in their systems even faster in the years to come.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.16.130.201