Exploiting directory permissions on macOS Csaba Fitzl Twitter: @theevilbit
whoami • content developer at Offensive Security • ex red/blue teamer • recent macOS research • husband, father • hiking • yoga
agenda • macOS filesystem permissions • finding bugs • bugs • preventing attacks
macOS filesystem permissions
POSIX model • every file and directory • owner (user) permissions • group permissions • everyone (world) permissions • each of them • read • write • execute
POSIX model • files • r/w/x permissions are straightforward • directories • read - you can enumerate the directory entries • write - you can delete/write files to the directory • execute - you are allowed to traverse the directory - if you don't have this right, you can't access any files inside it, or in any subdirectories.
POSIX model - scenarios • directory: r - - (only read) • can’t access any files (no execute permissions) • directory: - - x (only execute) • can’t list files (no read permissions) • can access files if name is known
experiment
POSIX model - scenarios • in case you don’t have `x` permissions on a directory but have permissions on the file -> maybe find a way to leak • have `rwx` on a directory - can delete / create files regardless of file’s permissions • e.g.: file is owned by root -> you can still delete it (!!!)
flag modifiers • there are many flag modifiers • from exploitation point of view, the important ones: • uchg, uchange, uimmutable (same, different names) - no one can change the file until the flag is removed • restricted - protected by SIP (= not even root can modify it, special entitlement is needed)
experiment
sticky bit > When a directory's sticky bit is set, the filesystem treats the files in such directories in a special way so only the file's owner, the directory's owner, or root user can rename or delete the file* >Typically this is set on the /tmp directory to prevent ordinary users from deleting or moving other users' files* * Wikipedia
Access Control Lists • more granular then the POSIX model • Access Control Entries • can be applied for multiple users, groups • directory rights: list, search, add_file, add_subdirectory, delete_child • file rights: read, write, append, execute
sandbox • SIP is also enforced by the sandbox • can further restrict file access - typically through sandbox profiles • profiles are in: • `/usr/share/sandbox/` • `/System/Library/Sandbox/Profiles/
sandbox example (mds)
finding bugs
static method • file owner is root, but the directory owner is different • file owner is not root, but directory owner is root • file owner is root, and one of the user's group has write access to the directory • file owner is not root, but the group is wheel, and the parent folder also not root owned • python script is available the blog post
dynamic method • monitor for similar relationships • tools: fs_usage, Objective-See's FileMonitor • benefit: find cases where root process changes file owner in a controllable location
BUGs
general idea • goal: redirect file operation to a location we want • process: delete file, place a symlink or hardlink, wait and see
problems 1. the process might run as root, however because of sandboxing it might not be able to write to any interesting location 2. the process might not follow symlinks / hardlinks, but instead it will overwrite our link, and create a new file 3. if we can successfully redirect the file operation, the file will still be owned by root, and we can't modify it after. We need to find a way to affect the file contents for our benefits. • 1 || 2 = no bug
controlling content • need to find a way to inject data into files owned by root • or if given file is controlling access, we can just make a new file
InstallHistory.plist file - Arbitrary file overwrite vulnerability (CVE-2020-3830)
InstallHistory.plist file - Arbitrary file overwrite vulnerability (CVE-2020-3830) • whenever someone installs an app on macOS, the system will log it to a file called `InstallHistory.plist`, which is located at `/Library/Receipts` • admins have write access to this location ==> delete file ==> place symlink ==> overwrite arbitrary files
InstallHistory.plist file - Arbitrary file overwrite vulnerability (CVE-2020-3830) • can't really control contents - only limited, the metadata of the application • trigger: install something
Adobe Reader macOS installer - arbitrary file overwrite vulnerability (CVE-2020-3763)
Adobe Reader macOS installer - arbitrary file overwrite vulnerability (CVE-2020-3763) • at the end of installing Adobe Acrobat Reader for macOS a file is placed in the `/tmp/` directory, named `com.adobe.reader.pdfviewer.tmp.plist` • prior the installation we can create a symlink, which will be followed • content is fixed ==> only arbitrary overwrite
Grant group write access to plist files via DiagnosticMessagesHistory.plist (CVE-2020-3835)
Grant group write access to plist files via DiagnosticMessagesHistory.plist (CVE-2020-3835) • someone can add `rw-rw-r` permissions to any `plist` file by abusing the file `DiagnosticMessagesHistory.plist` in the `/Library/Application Support/CrashReporter/` directory • the directory `/Library/Application Support/CrashReporter/` allows write access to users in the admin group. • the permissions for the file: • -rw-rw-r-- 1 root admin 258 Oct 12 20:28 DiagnosticMessagesHistory.plist
Grant group write access to plist files via DiagnosticMessagesHistory.plist (CVE-2020-3835) • we can create a symlink as normal • no file overwrite will happen • but! if the target is a PLIST file, permissions will set to -rw-rw-r-- • we can grant world read access to any PLIST file • we can grant group write access to any PLIST file
Grant group write access to plist files via DiagnosticMessagesHistory.plist (CVE-2020-3835) • trigger: Analytics & Improvements settings • find interesting files
macOS fontmover - file disclosure vulnerability (CVE-2019-8837)
macOS fontmover - file disclosure vulnerability (CVE-2019-8837) • `/Library/Fonts` has group write permissions set • as admin users are in the `admin` group, someone can drop here any file • this is the folder containing the system wide fonts, and I think this privilege unnecessary and I will come back to this why
exploitation • download a font, and double click
exploitation • set the install location to `Computer` • user location (default): `~/Library/Fonts` • computer location: `/Library/Fonts`
exploitation • press `Install Font` • press `Install Ticked` • authentication prompt to root • file is being copied
exploitation • symlinks or hardlinks don't work • will be removed • can't win race condition • even if worked, fontmover is sandboxed
exploitation • the file disclosure vulnerability happens with regards of the source file • between the steps `Install Font` and `Install Ticked` the file is not locked by the application • replace original file with symlink • what do we gain? • root process moves a file with its original permissions to a place where we already have write access • not interesting at first sight, but remember POSIX permissions!
exploitation • remember: in case you don’t have `x` permissions on a directory but have permissions on the file -> maybe find a way to leak • example: -rw-r--r-- 1 root wheel 1043 Aug 30 16:10 /private/var/run/ mds/uuid-tokenID.plist
exploitation
fix • file replacement will be verified, link is not followed
macOS DiagnosticMessages arbitrary file overwrite vulnerability (CVE-2020-3855)
macOS DiagnosticMessages arbitrary file overwrite vulnerability (CVE-2020-3855) • usual story • `/private/var/log/DiagnosticMessages` is writeable for the `admin` group • bunch of *.asl log files owned by root • exploit via hardlinks (might need to reboot)
content • this is a log file - can we control content? - partially • ASL logs - old API, few documentation • multiple destination file, how do I end up in `/private/var/log/ DiagnosticMessages`? • Most logs looked like, pre-defined fields
• Hope: found custom text from CalendarAgent • from: /System/Library/PrivateFrameworks/CalendarPersistence.framework/ Versions/Current/CalendarPersistence content
content • CalMessageTracer leads to `/System/Library/PrivateFrameworks// CalendarFoundation.framework/Versions/Current/CalendarFoundation`
content • CalMessageTracer • we see the ASL API
content • custom messages lead to further functions • I stopped • we can use this function to create a log entry for us
content • we need to create a header file • load the private framework • call the function • we can insert custom string
content • not enough for code execution :( • but can be useful trick :)
Adobe Reader macOS installer - local privilege escalation (CVE-2020-3762)
Adobe Reader macOS installer - LPE (CVE-2020-3762) • installer's `Acrobat Update Helper.app` component • `com.adobe.AcrobatRefreshManager` dir is created in /tmp/ during install • 2 PLIST files that will be copied into `/Library/LaunchDaemons/` • fixed location • installer deletes existing `com.adobe.AcrobatRefreshManager`
Adobe Reader macOS installer - LPE (CVE-2020-3762) • `/tmp/com.adobe.AcrobatRefreshManager/Adobe Acrobat Updater.app/ Contents/Library/LaunchServices` - where the plist files are stored • race condition - we recreate the dir structure after deletion, before creation • installers places the original PLIST • we delete (we own the dir), and put our own • installer puts our PLIST into LaunchDameons
macOS periodic scripts - 320.whatis script privilege escalation to root (CVE-2019-8802)
macOS periodic scripts - 320.whatis script LPE (CVE-2019-8802) • macOS's periodic maintenance scripts • weekly: /etc/periodic/weekly/320.whatis • rebuilds the man database • runs as root • will get the man paths • /usr/local/share/man • owned by the user, typically via brew install
makewhatis • makewhatis • creates `whatis.tmp` • we can redirect it via symlink • target: LaunchDaemons • PLIST file has to be proper XML
whatis database • database format: • 1st column: derived from the filename • 2nd column: the name from the NAME section of the man file • How do we get a proper XML?
exploit • STEP 1 • we put our PLIST file into the NAME section • need to end it with `<!--` to comment out any following text
exploit • STEP 2 • our man page has to be the first • if any other starts with a number (e.g.: 7zip) -> rename
exploit • STEP 3 • the filename has to make sense in XML • be it: <!--7z.1 This is a valid filename!!!
exploit • STEP 4 • need to close the XML comment that comes from the filename • The new NAME section:
exploit • STEP 5 • create symlink, run weekly scripts (or wait a week ;)) • the file we got: filename NAME section
demo - makewhatis exploit
Avoiding the attack
Installers • Use random directory name in /tmp/ • if not random: • create the directory, set permissions: owned by root, no one else has rights • cleanup the directory • can start using it
move operation • move (mv) operation doesn't follow symlinks/hardlinks for files • both will be overwritten
Objective-C • `writeToFile` doesn't follow links, overwrites them
?
Icons • Icons made by Darius Dan • Icons made by Eucalyp • Icons made by phatplus • Icons made by Freepik • Icons made by Flat Icons • Icons made by Kiranshastry • https://www.flaticon.com/

Exploiting Directory Permissions on macOS

  • 1.
    Exploiting directory permissions onmacOS Csaba Fitzl Twitter: @theevilbit
  • 2.
    whoami • content developerat Offensive Security • ex red/blue teamer • recent macOS research • husband, father • hiking • yoga
  • 3.
    agenda • macOS filesystempermissions • finding bugs • bugs • preventing attacks
  • 4.
  • 5.
    POSIX model • everyfile and directory • owner (user) permissions • group permissions • everyone (world) permissions • each of them • read • write • execute
  • 6.
    POSIX model • files •r/w/x permissions are straightforward • directories • read - you can enumerate the directory entries • write - you can delete/write files to the directory • execute - you are allowed to traverse the directory - if you don't have this right, you can't access any files inside it, or in any subdirectories.
  • 7.
    POSIX model -scenarios • directory: r - - (only read) • can’t access any files (no execute permissions) • directory: - - x (only execute) • can’t list files (no read permissions) • can access files if name is known
  • 8.
  • 9.
    POSIX model -scenarios • in case you don’t have `x` permissions on a directory but have permissions on the file -> maybe find a way to leak • have `rwx` on a directory - can delete / create files regardless of file’s permissions • e.g.: file is owned by root -> you can still delete it (!!!)
  • 10.
    flag modifiers • thereare many flag modifiers • from exploitation point of view, the important ones: • uchg, uchange, uimmutable (same, different names) - no one can change the file until the flag is removed • restricted - protected by SIP (= not even root can modify it, special entitlement is needed)
  • 11.
  • 12.
    sticky bit > Whena directory's sticky bit is set, the filesystem treats the files in such directories in a special way so only the file's owner, the directory's owner, or root user can rename or delete the file* >Typically this is set on the /tmp directory to prevent ordinary users from deleting or moving other users' files* * Wikipedia
  • 13.
    Access Control Lists •more granular then the POSIX model • Access Control Entries • can be applied for multiple users, groups • directory rights: list, search, add_file, add_subdirectory, delete_child • file rights: read, write, append, execute
  • 14.
    sandbox • SIP isalso enforced by the sandbox • can further restrict file access - typically through sandbox profiles • profiles are in: • `/usr/share/sandbox/` • `/System/Library/Sandbox/Profiles/
  • 15.
  • 16.
  • 17.
    static method • fileowner is root, but the directory owner is different • file owner is not root, but directory owner is root • file owner is root, and one of the user's group has write access to the directory • file owner is not root, but the group is wheel, and the parent folder also not root owned • python script is available the blog post
  • 18.
    dynamic method • monitorfor similar relationships • tools: fs_usage, Objective-See's FileMonitor • benefit: find cases where root process changes file owner in a controllable location
  • 19.
  • 20.
    general idea • goal:redirect file operation to a location we want • process: delete file, place a symlink or hardlink, wait and see
  • 21.
    problems 1. the processmight run as root, however because of sandboxing it might not be able to write to any interesting location 2. the process might not follow symlinks / hardlinks, but instead it will overwrite our link, and create a new file 3. if we can successfully redirect the file operation, the file will still be owned by root, and we can't modify it after. We need to find a way to affect the file contents for our benefits. • 1 || 2 = no bug
  • 22.
    controlling content • needto find a way to inject data into files owned by root • or if given file is controlling access, we can just make a new file
  • 23.
    InstallHistory.plist file -Arbitrary file overwrite vulnerability (CVE-2020-3830)
  • 24.
    InstallHistory.plist file -Arbitrary file overwrite vulnerability (CVE-2020-3830) • whenever someone installs an app on macOS, the system will log it to a file called `InstallHistory.plist`, which is located at `/Library/Receipts` • admins have write access to this location ==> delete file ==> place symlink ==> overwrite arbitrary files
  • 25.
    InstallHistory.plist file -Arbitrary file overwrite vulnerability (CVE-2020-3830) • can't really control contents - only limited, the metadata of the application • trigger: install something
  • 26.
    Adobe Reader macOSinstaller - arbitrary file overwrite vulnerability (CVE-2020-3763)
  • 27.
    Adobe Reader macOSinstaller - arbitrary file overwrite vulnerability (CVE-2020-3763) • at the end of installing Adobe Acrobat Reader for macOS a file is placed in the `/tmp/` directory, named `com.adobe.reader.pdfviewer.tmp.plist` • prior the installation we can create a symlink, which will be followed • content is fixed ==> only arbitrary overwrite
  • 28.
    Grant group writeaccess to plist files via DiagnosticMessagesHistory.plist (CVE-2020-3835)
  • 29.
    Grant group writeaccess to plist files via DiagnosticMessagesHistory.plist (CVE-2020-3835) • someone can add `rw-rw-r` permissions to any `plist` file by abusing the file `DiagnosticMessagesHistory.plist` in the `/Library/Application Support/CrashReporter/` directory • the directory `/Library/Application Support/CrashReporter/` allows write access to users in the admin group. • the permissions for the file: • -rw-rw-r-- 1 root admin 258 Oct 12 20:28 DiagnosticMessagesHistory.plist
  • 30.
    Grant group writeaccess to plist files via DiagnosticMessagesHistory.plist (CVE-2020-3835) • we can create a symlink as normal • no file overwrite will happen • but! if the target is a PLIST file, permissions will set to -rw-rw-r-- • we can grant world read access to any PLIST file • we can grant group write access to any PLIST file
  • 31.
    Grant group writeaccess to plist files via DiagnosticMessagesHistory.plist (CVE-2020-3835) • trigger: Analytics & Improvements settings • find interesting files
  • 32.
    macOS fontmover -file disclosure vulnerability (CVE-2019-8837)
  • 33.
    macOS fontmover -file disclosure vulnerability (CVE-2019-8837) • `/Library/Fonts` has group write permissions set • as admin users are in the `admin` group, someone can drop here any file • this is the folder containing the system wide fonts, and I think this privilege unnecessary and I will come back to this why
  • 34.
    exploitation • download afont, and double click
  • 35.
    exploitation • set theinstall location to `Computer` • user location (default): `~/Library/Fonts` • computer location: `/Library/Fonts`
  • 36.
    exploitation • press `InstallFont` • press `Install Ticked` • authentication prompt to root • file is being copied
  • 37.
    exploitation • symlinks orhardlinks don't work • will be removed • can't win race condition • even if worked, fontmover is sandboxed
  • 38.
    exploitation • the filedisclosure vulnerability happens with regards of the source file • between the steps `Install Font` and `Install Ticked` the file is not locked by the application • replace original file with symlink • what do we gain? • root process moves a file with its original permissions to a place where we already have write access • not interesting at first sight, but remember POSIX permissions!
  • 39.
    exploitation • remember: incase you don’t have `x` permissions on a directory but have permissions on the file -> maybe find a way to leak • example: -rw-r--r-- 1 root wheel 1043 Aug 30 16:10 /private/var/run/ mds/uuid-tokenID.plist
  • 40.
  • 41.
    fix • file replacementwill be verified, link is not followed
  • 42.
    macOS DiagnosticMessages arbitrary fileoverwrite vulnerability (CVE-2020-3855)
  • 43.
    macOS DiagnosticMessages arbitraryfile overwrite vulnerability (CVE-2020-3855) • usual story • `/private/var/log/DiagnosticMessages` is writeable for the `admin` group • bunch of *.asl log files owned by root • exploit via hardlinks (might need to reboot)
  • 44.
    content • this isa log file - can we control content? - partially • ASL logs - old API, few documentation • multiple destination file, how do I end up in `/private/var/log/ DiagnosticMessages`? • Most logs looked like, pre-defined fields
  • 45.
    • Hope: foundcustom text from CalendarAgent • from: /System/Library/PrivateFrameworks/CalendarPersistence.framework/ Versions/Current/CalendarPersistence content
  • 46.
    content • CalMessageTracer leadsto `/System/Library/PrivateFrameworks// CalendarFoundation.framework/Versions/Current/CalendarFoundation`
  • 47.
  • 48.
    content • custom messageslead to further functions • I stopped • we can use this function to create a log entry for us
  • 49.
    content • we needto create a header file • load the private framework • call the function • we can insert custom string
  • 50.
    content • not enoughfor code execution :( • but can be useful trick :)
  • 51.
    Adobe Reader macOSinstaller - local privilege escalation (CVE-2020-3762)
  • 52.
    Adobe Reader macOSinstaller - LPE (CVE-2020-3762) • installer's `Acrobat Update Helper.app` component • `com.adobe.AcrobatRefreshManager` dir is created in /tmp/ during install • 2 PLIST files that will be copied into `/Library/LaunchDaemons/` • fixed location • installer deletes existing `com.adobe.AcrobatRefreshManager`
  • 53.
    Adobe Reader macOSinstaller - LPE (CVE-2020-3762) • `/tmp/com.adobe.AcrobatRefreshManager/Adobe Acrobat Updater.app/ Contents/Library/LaunchServices` - where the plist files are stored • race condition - we recreate the dir structure after deletion, before creation • installers places the original PLIST • we delete (we own the dir), and put our own • installer puts our PLIST into LaunchDameons
  • 54.
    macOS periodic scripts- 320.whatis script privilege escalation to root (CVE-2019-8802)
  • 55.
    macOS periodic scripts- 320.whatis script LPE (CVE-2019-8802) • macOS's periodic maintenance scripts • weekly: /etc/periodic/weekly/320.whatis • rebuilds the man database • runs as root • will get the man paths • /usr/local/share/man • owned by the user, typically via brew install
  • 56.
    makewhatis • makewhatis • creates`whatis.tmp` • we can redirect it via symlink • target: LaunchDaemons • PLIST file has to be proper XML
  • 57.
    whatis database • databaseformat: • 1st column: derived from the filename • 2nd column: the name from the NAME section of the man file • How do we get a proper XML?
  • 58.
    exploit • STEP 1 •we put our PLIST file into the NAME section • need to end it with `<!--` to comment out any following text
  • 59.
    exploit • STEP 2 •our man page has to be the first • if any other starts with a number (e.g.: 7zip) -> rename
  • 60.
    exploit • STEP 3 •the filename has to make sense in XML • be it: <!--7z.1 This is a valid filename!!!
  • 61.
    exploit • STEP 4 •need to close the XML comment that comes from the filename • The new NAME section:
  • 62.
    exploit • STEP 5 •create symlink, run weekly scripts (or wait a week ;)) • the file we got: filename NAME section
  • 63.
  • 64.
  • 65.
    Installers • Use randomdirectory name in /tmp/ • if not random: • create the directory, set permissions: owned by root, no one else has rights • cleanup the directory • can start using it
  • 66.
    move operation • move(mv) operation doesn't follow symlinks/hardlinks for files • both will be overwritten
  • 67.
    Objective-C • `writeToFile` doesn'tfollow links, overwrites them
  • 68.
  • 69.
    Icons • Icons madeby Darius Dan • Icons made by Eucalyp • Icons made by phatplus • Icons made by Freepik • Icons made by Flat Icons • Icons made by Kiranshastry • https://www.flaticon.com/