HackTricks
Search…
Pentesting
Powered By GitBook
MacOS Security & Privilege Escalation
First of all, please note that most of the tricks about privilege escalation affecting Linux/Unix will affect also MacOS machines. So see:

Basic MacOS

OS X Specific Extensions

    .dmg: Apple Disk Image files are very frequent for installers.
    .kext: It must follow a specific structure and it's the OS X version of a driver.
    .plist: Also known as property list stores information in XML or binary format.
      Can be XML or binary. Binary ones can be read with:
        defaults read config.plist
        /usr/libexec/PlistBuddy -c print config.plsit
        plutil -p config.plist
    .app: Apple applications that follows directory structure.
    .dylib: Dynamic libraries (like Windows DLL files)
    .pkg: Are the same as xar (eXtensible Archive format). The installer command can be use to install the contents of these files.

File hierarchy layout

    /Applications: The installed apps should be here. All the users will be able to access them.
    /bin: Command line binaries
    /cores: If exists, it's used to store core dumps
    /dev: Everything is treated as a file so you may see hardware devices stored here.
    /etc: Configuration files
    /Library: A lot of subdirectories and files related to preferences, caches and logs can be found here. A Library folder exists in root and on each user's directory.
    /private: Undocumented but a lot of the mentioned folders are symbolic links to the private directory.
    /sbin: Essential system binaries (related to administration)
    /System: File fo making OS X run. You should find mostly only Apple specific files here (not third party).
    /tmp: Files are deleted after 3 days (it's a soft link to /private/tmp)
    /Users: Home directory for users.
    /usr: Config and system binaries
    /var: Log files
    /Volumes: The mounted drives will apear here.
    /.vol: Running stat a.txt you obtain something like 16777223 7545753 -rw-r--r-- 1 username wheel ... where the first number is the id number of the volume where the file exists and the second one is the inode number. You can access the content of this file through /.vol/ with that information running cat /.vol/16777223/7545753

Special MacOS files and folders

    .DS_Store: This file is on each directory, it saves the attributes and customisations of the directory.
    .Spotlight-V100: This folder appears on the root directory of every volume on the system.
    .metadata_never_index: If this file is at the root of a volume Spotlight won't index that volume.
    <name>.noindex: Files and folder with this extension won't be indexed by Spotlight.
    $HOME/Library/Preferences/com.apple.LaunchServices.QuarantineEventsV2: Contains information about downloaded files, like the URL from where they were downloaded.
    /var/log/system.log: Main log of OSX systems. com.apple.syslogd.plist is responsible for the execution of syslogging (you can check if it's disabled looking for "com.apple.syslogd" in launchctl list.
    /private/var/log/asl/*.asl: These are the Apple System Logs which may contain interesting information.
    $HOME/Library/Preferences/com.apple.recentitems.plist: Stores recently accessed files and applications through "Finder".
    $HOME/Library/Preferences/com.apple.loginitems.plsit: Stores items to launch upon system startup
    $HOME/Library/Logs/DiskUtility.log: Log file for thee DiskUtility App (info about drives, including USBs)
    /Library/Preferences/SystemConfiguration/com.apple.airport.preferences.plist: Data about wireless access points.
    /private/var/db/launchd.db/com.apple.launchd/overrides.plist: List of daemons deactivated.
    /private/etc/kcpassword: If autologin is enabled this file will contain the users login password XORed with a key.

Common users

    Daemon: User reserved for system daemons. The default daemon account names usually start with a "_":
    1
    _amavisd, _analyticsd, _appinstalld, _appleevents, _applepay, _appowner, _appserver, _appstore, _ard, _assetcache, _astris, _atsserver, _avbdeviced, _calendar, _captiveagent, _ces, _clamav, _cmiodalassistants, _coreaudiod, _coremediaiod, _coreml, _ctkd, _cvmsroot, _cvs, _cyrus, _datadetectors, _demod, _devdocs, _devicemgr, _diskimagesiod, _displaypolicyd, _distnote, _dovecot, _dovenull, _dpaudio, _driverkit, _eppc, _findmydevice, _fpsd, _ftp, _fud, _gamecontrollerd, _geod, _hidd, _iconservices, _installassistant, _installcoordinationd, _installer, _jabber, _kadmin_admin, _kadmin_changepw, _knowledgegraphd, _krb_anonymous, _krb_changepw, _krb_kadmin, _krb_kerberos, _krb_krbtgt, _krbfast, _krbtgt, _launchservicesd, _lda, _locationd, _logd, _lp, _mailman, _mbsetupuser, _mcxalr, _mdnsresponder, _mobileasset, _mysql, _nearbyd, _netbios, _netstatistics, _networkd, _nsurlsessiond, _nsurlstoraged, _oahd, _ondemand, _postfix, _postgres, _qtss, _reportmemoryexception, _rmd, _sandbox, _screensaver, _scsd, _securityagent, _softwareupdate, _spotlight, _sshd, _svn, _taskgated, _teamsserver, _timed, _timezone, _tokend, _trustd, _trustevaluationagent, _unknown, _update_sharing, _usbmuxd, _uucp, _warmd, _webauthserver, _windowserver, _www, _wwwproxy, _xserverdocs
    Copied!
    Guest: Account for guests with very strict permissions
      state=("automaticTime" "afpGuestAccess" "filesystem" "guestAccount" "smbGuestAccess"); for i in "${state[@]}"; do sysadminctl -"${i}" status; done;
    Nobody: Processes are executed with this user when minimal permissions are required
    Root

User Privileges

    Standard User: The most basic of users. This user needs permissions granted from an admin user when attempting to install software or perform other advanced tasks. They are not able to do it on their own.
    Admin User: A user who operates most of the time as a standard user but is also allowed to perform root actions such as install software and other administrative tasks. All users belonging to the admin group are given access to root via the sudoers file.
    Root: Root is a user allowed to perform almost any action (there are limitations imposed by protections like System Integrity Protection).
      For example root won't be able to place a file inside /System

File ACLs

When the file contains ACLs you will find a "+" when listing the permissions like in:
1
ls -ld Movies
2
drwx------+ 7 username staff 224 15 Apr 19:42 Movies
Copied!
You can read the ACLs of the file with:
1
ls -lde Movies
2
drwx------+ 7 username staff 224 15 Apr 19:42 Movies
3
0: group:everyone deny delete
Copied!
You can find all the files with ACLs with (this is veeery slow):
1
ls -RAle / 2>/dev/null | grep -E -B1 "\d: "
Copied!

Resource Forks or MacOS ADS

This is a way to obtain Alternate Data Streams in MacOS machines. You can save content inside an extended attribute called com.apple.ResourceFork inside a file by saving it in file/..namedfork/rsrc.
1
echo "Hello" > a.txt
2
echo "Hello Mac ADS" > a.txt/..namedfork/rsrc
3
4
xattr -l a.txt #Read extended attributes
5
com.apple.ResourceFork: Hello Mac ADS
6
7
ls -l a.txt #The file length is still q
8
[email protected] 1 username wheel 6 17 Jul 01:15 a.txt
Copied!
You can find all the files containing this extended attribute with:
1
find / -type f -exec ls -ld {} \; 2>/dev/null | grep -E "[x\-]@ " | awk '{printf $9; printf "\n"}' | xargs -I {} xattr -lv {} | grep "com.apple.ResourceFork"
Copied!

Risk Files Mac OS

The files /System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/System contains the risk associated to files depending on the file extension.
The possible categories include the following:
    LSRiskCategorySafe: Totally safe; Safari will auto-open after download
    LSRiskCategoryNeutral: No warning, but not auto-opened
    LSRiskCategoryUnsafeExecutable: Triggers a warning “This file is an application...”
    LSRiskCategoryMayContainUnsafeExecutable: This is for things like archives that contain an executable. It triggers a warning unless Safari can determine all the contents are safe or neutral.

Remote Access Services

You can enable/disable these services in "System Preferences" --> Sharing
    VNC, known as “Screen Sharing”
    SSH, called “Remote Login”
    Apple Remote Desktop (ARD), or “Remote Management”
    AppleEvent, known as “Remote Apple Event”
Check if any is enabled running:
1
rmMgmt=$(netstat -na | grep LISTEN | grep tcp46 | grep "*.3283" | wc -l);
2
scrShrng=$(netstat -na | grep LISTEN | egrep 'tcp4|tcp6' | grep "*.5900" | wc -l);
3
flShrng=$(netstat -na | grep LISTEN | egrep 'tcp4|tcp6' | egrep "\*.88|\*.445|\*.548" | wc -l);
4
rLgn=$(netstat -na | grep LISTEN | egrep 'tcp4|tcp6' | grep "*.22" | wc -l);
5
rAE=$(netstat -na | grep LISTEN | egrep 'tcp4|tcp6' | grep "*.3031" | wc -l);
6
bmM=$(netstat -na | grep LISTEN | egrep 'tcp4|tcp6' | grep "*.4488" | wc -l);
7
printf "\nThe following services are OFF if '0', or ON otherwise:\nScreen Sharing: %s\nFile Sharing: %s\nRemote Login: %s\nRemote Mgmt: %s\nRemote Apple Events: %s\nBack to My Mac: %s\n\n" "$scrShrng" "$flShrng" "$rLgn" "$rmMgmt" "$rAE" "$bmM";
Copied!

MacOS Architecture

MacOS Serial Number

MacOS MDM

MacOS Protocols

MacOS - Inspecting, Debugging and Fuzzing

MacOS Security Mechanisms

Gatekeeper

In this talk Jeremy Brown talks about this protections and a bug that allowed to bypass them.
Gatekeeper is designed to ensure that, by default, only trusted software runs on a user’s Mac. Gatekeeper is used when a user downloads and opens an app, a plug-in or an installer package from outside the App Store. Gatekeeper verifies that the software is signed by an identified developer, is notarised by Apple to be free of known malicious content, and hasn’t been altered. Gatekeeper also requests user approval before opening downloaded software for the first time to make sure the user hasn’t been tricked into running executable code they believed to simply be a data file.

Notarizing

In order for an app to be notarised by Apple, the developer needs to send the app for review. Notarization is not App Review. The Apple notary service is an automated system that scans your software for malicious content, checks for code-signing issues, and returns the results to you quickly. If there are no issues, the notary service generates a ticket for you to staple to your software; the notary service also publishes that ticket online where Gatekeeper can find it.
When the user first installs or runs your software, the presence of a ticket (either online or attached to the executable) tells Gatekeeper that Apple notarized the software. Gatekeeper then places descriptive information in the initial launch dialog indicating that Apple has already checked for malicious content.

File Quarantine

Gatekeeper builds upon File Quarantine. Upon download of an application, a particular extended file attribute ("quarantine flag") can be added to the downloaded file. This attribute is added by the application that downloads the file, such as a web browser or email client, but is not usually added by others like common BitTorrent client software. When a user executes a "quarantined" file, Gatekeeper is the one that performs the mentioned actions to allow the execution of the file.
Checking the validity of code signatures is a resource-intensive process that includes generating cryptographic hashes of the code and all its bundled resources. Furthermore, checking certificate validity involves doing an online check to Apple's servers to see if it has been revoked after it was issued. For these reasons, a full code signature and notarization check is impractical to run every time an app is launched.
Therefore, these checks are only run when executing apps with the quarantined attribute.
Safari and other web browsers and applications are the ones that
It's possible to check it's status and enable/disable (root required) with:
1
spctl --status
2
assessments enabled
3
4
spctl --enable
5
spctl --disable
6
#You can also allow nee identifies to execute code using the binary "spctl"
Copied!
You can also find if a file has the quarantine extended attribute with:
1
xattr portada.png
2
com.apple.macl
3
com.apple.quarantine
Copied!
Check the value of the extended attributes with:
1
xattr -l portada.png
2
com.apple.macl:
3
00000000 03 00 53 DA 55 1B AE 4C 4E 88 9D CA B7 5C 50 F3 |..S.U..LN.....P.|
4
00000010 16 94 03 00 27 63 64 97 98 FB 4F 02 84 F3 D0 DB |....'cd...O.....|
5
00000020 89 53 C3 FC 03 00 27 63 64 97 98 FB 4F 02 84 F3 |.S....'cd...O...|
6
00000030 D0 DB 89 53 C3 FC 00 00 00 00 00 00 00 00 00 00 |...S............|
7
00000040 00 00 00 00 00 00 00 00 |........|
8
00000048
9
com.apple.quarantine: 0081;607842eb;Brave;F643CD5F-6071-46AB-83AB-390BA944DEC5
Copied!
And remove that attribute with:
1
xattr -d com.apple.quarantine portada.png
2
#You can also remove this attribute from every file with
3
find . -iname '*' -print0 | xargs -0 xattr -d com.apple.quarantine
Copied!
And find all the quarantined files with:
1
find / -exec ls -ld {} \; 2>/dev/null | grep -E "[x\-]@ " | awk '{printf $9; printf "\n"}' | xargs -I {} xattr -lv {} | grep "com.apple.quarantine"
Copied!

XProtect

X-Protect is also part of Gatekeeper. It's Apple’s built in malware scanner. It keeps track of known malware hashes and patterns. You can get information about the latest XProtect update running:
1
system_profiler SPInstallHistoryDataType 2>/dev/null | grep -A 4 "XProtectPlistConfigData" | tail -n 5
Copied!

MRT: Malware Removal Tool

Should malware make its way onto a Mac, macOS also includes technology to remediate infections. The Malware Removal Tool (MRT) is an engine in macOS that remediates infections based on updates automatically delivered from Apple (as part of automatic updates of system data files and security updates). MRT removes malware upon receiving updated information and it continues to check for infections on restart and login. MRT doesn’t automatically reboot the Mac. (From here)

Automatic Security Updates

Apple issues the updates for XProtect and MRT automatically based on the latest threat intelligence available. By default, macOS checks for these updates daily. Notarisation updates are distributed using CloudKit sync and are much more frequent.

TCC

TCC (Transparency, Consent, and Control) is a mechanism in macOS to limit and control application access to certain features, usually from a privacy perspective. This can include things such as location services, contacts, photos, microphone, camera, accessibility, full disk access, and a bunch more.
From a user’s perspective, they see TCC in action when an application wants access to one of the features protected by TCC. When this happens the user is prompted with a dialog asking them whether they want to allow access or not. This response is then stored in the TCC database.
An example of a TCC prompt
Check some of the already given permissions to apps in System Preferences --> Security & Privacy --> Privacy --> Files and Folders.
The TCC database is just a sqlite3 database, which makes the task of investigating it much simpler. There are two different databases, a global one in /Library/Application Support/com.apple.TCC/TCC.db and a per-user one located in /Users/<username>/Library/Application Support/com.apple.TCC/TCC.db. The first database is protected from editing with SIP(System Integrity Protection), but you can read them by granting terminal(or your editor) full disk access.
This information was taken from here (read the original source for more information).
Some protected directories:
    $HOME/Desktop
    $HOME/Documents
    $HOME/Downloads
    iCloud Drive
    ...
Unprotected directories:
    $HOME (itself)
    $HOME/.ssh, $HOME/.aws, etc
    /tmp

Bypasses

By default an access via SSH will have "Full Disk Access". In order to disable this you need to have it listed but disabled (removing it from the list won't remove those privileges):
Here you can find examples of how some malwares have been able to bypass this protection:

Seatbelt Sandbox

MacOS Sandbox works with the kernel extension Seatbelt. It makes applications run inside the sandbox need to request access to resources outside of the limited sandbox. This helps to ensure that the application will be accessing only expected resources and if it wants to access anything else it will need to ask for permissions to the user.
Important system services also run inside their own custom sandbox such as the mdnsresponder service. You can view these custom sandbox profiles inside the /usr/share/sandbox directory. Other sandbox profiles can be checked in https://github.com/s7ephen/OSX-Sandbox--Seatbelt--Profiles.
To start an application with a sandbox config you can use:
1
sandbox-exec -f example.sb /Path/To/The/Application
Copied!
Note that the Apple-authored software that runs on Windows doesn’t have additional security precautions, such as application sandboxing.
Bypasses examples:

SIP - System Integrity Protection

This protection was enabled to help keep root level malware from taking over certain parts of the operating system. Although this means applying limitations to the root user many find it to be worthwhile trade off. The most notable of these limitations are that users can no longer create, modify, or delete files inside of the following four directories in general:
    /System
    /bin
    /sbin
    /usr
Note that there are exceptions specified by Apple: The file /System/Library/Sandbox/rootless.conf holds a list of files and directories that cannot be modified. But if the line starts with an asterisk it means that it can be modified as exception. For example, the config lines:
1
/usr
2
* /usr/libexec/cups
3
* /usr/local
4
* /usr/share/man
Copied!
Means that /usr cannot be modified except for the 3 allowed folders allowed.
The final exception to these rules is that any installer package signed with the Apple’s certificate can bypass SIP protection, but only Apple’s certificate. Packages signed by standard developers will still be rejected when trying to modify SIP protected directories.
Note that if a file is specified in the previous config file but it doesn't exist, it can be created. This might be used by malware to obtain stealth persistence. For example, imagine that a .plist in /System/Library/LaunchDaemons appears listed but it doesn't exist. A malware may create one and use it as persistence mechanism.
Also, note how files and directories specified in rootless.conf have a rootless extended attribute:
1
xattr /System/Library/LaunchDaemons/com.apple.UpdateSettings.plist
2
com.apple.rootless
3
4
ls -lO /System/Library/LaunchDaemons/com.apple.UpdateSettings.plist
5
[email protected] 1 root wheel restricted,compressed 412 1 Jan 2020 /System/Library/LaunchDaemons/com.apple.UpdateSettings.plist
Copied!
SIP handles a number of other limitations as well. Like it doesn't allows for the loading of unsigned kexts. SIP is also responsible for ensuring that no OS X system processes are debugged. This also means that Apple put a stop to dtrace inspecting system processes.
Check if SIP is enabled with:
1
csrutil status
2
System Integrity Protection status: enabled.
Copied!
If you want to disable it, you need to put the computer in recovery mode (start it pressing command+R) and execute: csrutil disable You can also maintain it enable but without debugging protections doing:
1
csrutil enable --without debug
Copied!

Apple Binary Signatures

When checking some malware sample you should always check the signature of the binary as the developer that signed it may be already related with malware.
1
#Get signer
2
codesign -vv -d /bin/ls 2>&1 | grep -E "Authority|TeamIdentifier"
3
4
#Check if the app’s contents have been modified
5
codesign --verify --verbose /Applications/Safari.app
6
7
#Check if the signature is valid
8
spctl --assess --verbose /Applications/Safari.app
Copied!

Installed Software & Services

Check for suspicious applications installed and privileges over the.installed resources:
1
system_profiler SPApplicationsDataType #Installed Apps
2
system_profiler SPFrameworksDataType #Instaled framework
3
lsappinfo list #Installed Apps
4
launchtl list #Services
Copied!

User Processes

1
# will print all the running services under that particular user domain.
2
launchctl print gui/<users UID>
3
4
# will print all the running services under root
5
launchctl print system
6
7
# will print detailed information about the specific launch agent. And if it’s not running or you’ve mistyped, you will get some output with a non-zero exit code: Could not find service “com.company.launchagent.label” in domain for login
8
launchctl print gui/<user's UID>/com.company.launchagent.label
Copied!

Auto Start Extensibility Point (ASEP)

An ASEP is a location on the system that could lead to the execution of a binary without user interaction. The main ones used in OS X take the form of plists.

Launchd

launchd is the first process executed by OX S kernel at startup and the last one to finish at shut down. It should always have the PID 1. This process will read and execute the configurations indicated in the ASEP plists in:
    /Library/LaunchAgents: Per-user agents installed by the admin
    /Library/LaunchDaemons: System-wide daemons installed by the admin
    /System/Library/LaunchAgents: Per-user agents provided by Apple.
    /System/Library/LaunchDaemons: System-wide daemons provided by Apple.
When a user logs in the plists located in /Users/$USER/Library/LaunchAgents and /Users/$USER/Library/LaunchDemons are started with the logged users permissions.
The main difference between agents and daemons is that agents are loaded when the user logs in and the daemons are loaded at system startup (as there are services like ssh that needs to be executed before any user access the system). Also agents may use GUI while daemons need to run in the background.
1
<?xml version="1.0" encoding="UTF-8"?>
2
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN">
3
<plist version="1.0">
4
<dict>
5
<key>Label</key>
6
<string>com.apple.someidentifier</string>
7
<key>ProgramArguments</key>
8
<array>
9
<string>/Users/username/malware</string>
10
</array>
11
<key>RunAtLoad</key><true/> <!--Execute at system startup-->
12
<key>StartInterval</key>
13
<integer>800</integer> <!--Execute each 800s-->
14
<key>KeepAlive</key>
15
<dict>
16
<key>SuccessfulExit</key></false> <!--Re-execute if exit unsuccessful-->
17
<!--If previous is true, then re-execute in successful exit-->
18
</dict>
19
</dict>
20
</plist>
Copied!
There are cases where an agent needs to be executed before the user logins, these are called PreLoginAgents. For example, this is useful to provide assistive technology at login. They can be found also in /Library/LaunchAgents(see here an example).
New Daemons or Agents config files will be loaded after next reboot or using launchctl load <target.plist> It's also possible to load .plist files without that extension with launchctl -F <file> (however those plist files won't be automatically loaded after reboot). It's also possible to unload with launchctl unload <target.plist> (the process pointed by it will be terminated),
To ensure that there isn't anything (like an override) preventing an Agent or Daemon from running run: sudo launchctl load -w /System/Library/LaunchDaemos/com.apple.smdb.plist
List all the agents and daemons loaded by the current user:
1
launchctl list
Copied!

Cron

List the cron jobs of the current user with:
1
crontab -l
Copied!
You can also see all the cron jobs of the users in /usr/lib/cron/tabs/ and /var/at/tabs/ (needs root).
In MacOS several folders executing scripts with certain frequency can be found in:
1
ls -lR /usr/lib/cron/tabs/ /private/var/at/jobs /etc/periodic/
Copied!
There you can find the regular cron jobs, the at jobs (not very used) and the periodic jobs (mainly used for cleaning temporary files). The daily periodic jobs can be executed for example with: periodic daily.

kext

In order to install a KEXT as a startup item, it needs to be installed in one of the following locations:
    /System/Library/Extensions
      KEXT files built into the OS X operating system.
    /Library/Extensions
      KEXT files installed by 3rd party software
You can list currently loaded kext files with:
1
kextstat #List loaded kext
2
kextload /path/to/kext.kext #Load a new one based on path
3
kextload -b com.apple.driver.ExampleBundle #Load a new one based on path
4
kextunload /path/to/kext.kext
5
kextunload -b com.apple.driver.ExampleBundle
Copied!
For more information about kernel extensions check this section.

Login Items

In System Preferences -> Users & Groups -> Login Items you can find items to be executed when the user logs in. It it's possible to list them, add and remove from the command line:
1
#List all items:
2
osascript -e 'tell application "System Events" to get the name of every login item'
3
4
#Add an item:
5
osascript -e 'tell application "System Events" to make login item at end with properties {path:"/path/to/itemname", hidden:false}'
6
7
#Remove an item:
8
osascript -e 'tell application "System Events" to delete login item "itemname"'
Copied!
These items are stored in the file /Users/<username>/Library/Application Support/com.apple.backgroundtaskmanagementagent

At

“At tasks” are used to schedule tasks at specific times. These tasks differ from cron in that they are one time tasks that get removed after executing. However, they will survive a system restart so they can’t be ruled out as a potential threat.
By default they are disabled but the root user can enable them with:
1
sudo launchctl load -F /System/Library/LaunchDaemons/com.apple.atrun.plist
Copied!
This will create a file at 13:37:
1
echo hello > /tmp/hello | at 1337
Copied!
If AT tasks aren't enabled the created tasks won't be executed.

Login/Logout Hooks

They are deprecated but can be used to execute commands when a user logs in.
1
cat > $HOME/hook.sh << EOF
2
#!/bin/bash
3
echo 'My is: \`id\`' > /tmp/login_id.txt
4
EOF
5
chmod +x $HOME/hook.sh
6
defaults write com.apple.loginwindow LoginHook /Users/$USER/hook.sh
Copied!
This setting is stored in /Users/$USER/Library/Preferences/com.apple.loginwindow.plist
1
defaults read /Users/$USER/Library/Preferences/com.apple.loginwindow.plist
2
{
3
LoginHook = "/Users/username/hook.sh";
4
MiniBuddyLaunch = 0;
5
TALLogoutReason = "Shut Down";
6
TALLogoutSavesState = 0;
7
oneTimeSSMigrationComplete = 1;
8
}
Copied!
To delete it:
1
defaults delete com.apple.loginwindow LoginHook
Copied!
In the previous example we have created and deleted a LoginHook, it's also possible to create a LogoutHook.
The root user one is stored in /private/var/root/Library/Preferences/com.apple.loginwindow.plist

Emond

Apple introduced a logging mechanism called emond. It appears it was never fully developed, and development may have been abandoned by Apple for other mechanisms, but it remains available.
This little-known service may not be much use to a Mac admin, but to a threat actor one very good reason would be to use it as a persistence mechanism that most macOS admins probably wouldn't know to look for. Detecting malicious use of emond shouldn't be difficult, as the System LaunchDaemon for the service looks for scripts to run in only one place:
1
ls -l /private/var/db/emondClients
Copied!
As this isn't used much, anything in that folder should be suspicious

Startup Items

This is deprecated, so nothing should be found in the following directories.
A StartupItem is a directory that gets placed in one of these two folders. /Library/StartupItems/ or /System/Library/StartupItems/
After placing a new directory in one of these two locations, two more items need to be placed inside that directory. These two items are a rc script and a plist that holds a few settings. This plist must be called “StartupParameters.plist”.
StartupParameters.plist
1
<?xml version="1.0" encoding="UTF-8"?>
2
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
<plist version="1.0">
4
<dict>
5
<key>Description</key>
6
<string>This is a description of this service</string>
7
<key>OrderPreference</key>
8
<string>None</string> <!--Other req services to execute before this -->
9
<key>Provides</key>
10
<array>
11
<string>superservicename</string> <!--Name of the services provided by this file -->
12
</array>
13
</dict>
14
</plist>
Copied!
superservicename
1
#!/bin/sh
2
. /etc/rc.common
3
4
StartService(){
5
touch /tmp/superservicestarted
6
}
7
8
StopService(){
9
rm /tmp/superservicestarted
10
}
11
12
RestartService(){
13
echo "Restarting"
14
}
15
16
RunService "$1"
Copied!

/etc/rc.common

This isn't working in modern MacOS versions
It's also possible to place here commands that will be executed at startup. Example os regular rc.common script:
1
##
2
# Common setup for startup scripts.
3
##
4
# Copyright 1998-2002 Apple Computer, Inc.
5
##
6
7
#######################
8
# Configure the shell #
9
#######################
10
11
##
12
# Be strict
13
##
14
#set -e
15
set -u
16
17
##
18
# Set command search path
19
##
20
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/libexec:/System/Library/CoreServices; export PATH
21
22
##
23
# Set the terminal mode
24
##
25
#if [ -x /usr/bin/tset ] && [ -f /usr/share/misc/termcap ]; then
26
# TERM=$(tset - -Q); export TERM
27
#fi
28
29
####################
30
# Useful functions #
31
####################
32
33
##
34
# Determine if the network is up by looking for any non-loopback
35
# internet network interfaces.
36
##
37
CheckForNetwork()
38
{
39
local test
40
41
if [ -z "${NETWORKUP:=}" ]; then
42
test=$(ifconfig -a inet 2>/dev/null | sed -n -e '/127.0.0.1/d' -e '/0.0.0.0/d' -e '/inet/p' | wc -l)
43
if [ "${test}" -gt 0 ]; then
44
NETWORKUP="-YES-"
45
else
46
NETWORKUP="-NO-"
47
fi
48
fi
49
}
50
51
alias ConsoleMessage=echo
52
53
##
54
# Process management
55
##
56
GetPID ()
57
{
58
local program="$1"
59
local pidfile="${PIDFILE:=/var/run/${program}.pid}"
60
local pid=""
61
62
if [ -f "${pidfile}" ]; then
63
pid=$(head -1 "${pidfile}")
64
if ! kill -0 "${pid}" 2> /dev/null; then
65
echo "Bad pid file $pidfile; deleting."
66
pid=""
67
rm -f "${pidfile}"
68
fi
69
fi
70
71
if [ -n "${pid}" ]; then
72
echo "${pid}"
73
return 0
74
else
75
return 1
76
fi
77
}
78
79
##
80
# Generic action handler
81
##
82
RunService ()
83
{
84
case $1 in
85
start ) StartService ;;
86
stop ) StopService ;;
87
restart) RestartService ;;
88
* ) echo "$0: unknown argument: $1";;
89
esac
90
}
Copied!

Profiles

Configuration profiles can force a user to use certain browser settings, DNS proxy settings, or VPN settings. Many other payloads are possible which make them ripe for abuse.
You can enumerate them running:
1
ls -Rl /Library/Managed\ Preferences/
Copied!

Other persistence techniques and tools

Memory Artifacts

Swap Files

    /private/var/vm/swapfile0: This file is used as a cache when physical memory fills up. Data in physical memory will be pushed to the swapfile and then swapped back into physical memory if it’s needed again. More than one file can exist in here. For example, you might see swapfile0, swapfile1, and so on.
    /private/var/vm/sleepimage: When OS X goes into hibernation, data stored in memory is put into the sleepimage file. When the user comes back and wakes the computer, memory is restored from the sleepimage and the user can pick up where they left off.
    By default in modern MacOS systems this file will be encrypted, so it might be not recuperable.
      However, the encryption of this file might be disabled. Check the out of sysctl vm.swapusage.

Dumping memory with osxpmem

In order to dump the memory in a MacOS machine you can use osxpmem.
1
#Dump raw format
2
sudo osxpmem.app/osxpmem --format raw -o /tmp/dump_mem
3
4
#Dump aff4 format