macOS TCC Bypasses
Last updated
Last updated
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
This is not a bypass, it's just how TCC works: It doesn't protect from writing. If Terminal doesn't have access to read the Desktop of a user it can still write into it:
The extended attribute com.apple.macl
is added to the new file to give the creators app access to read it.
It's possible to put a window over the TCC prompt to make the user accept it without noticing. You can find a PoC in TCC-ClickJacking.
Attacker can create apps with any name (e.g. Finder, Google Chrome...) in the Info.plist
and make it request access to some TCC protected location. The user will think that the legit application is the one requesting this access.
Moreover, it's possible to remove the legit app from the Dock and put the fake one on it, so when the user clicks on the fake one (which can use the same icon) it could call the legit one, ask for TCC permissions and execute a malware, making the user believe the legit app requested the access.
More info and PoC in:
macOS Privilege EscalationBy default an access via SSH used to 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:
Note that now, in order to be able to enable SSH you need Full Disk Access
The attribute com.apple.macl
is given to files to give a certain application permissions to read it. This attribute is set when drag&drop a file over an app, or when a user double-clicks a file to open it with the default application.
Therefore, a user could register a malicious app to handle all the extensions and call Launch Services to open any file (so the malicious file will be granted access to read it).
The entitlement com.apple.private.icloud-account-access
it's possible to communicate with com.apple.iCloudHelper
XPC service which will provide iCloud tokens.
iMovie and Garageband had this entitlement and others that allowed.
For more information about the exploit to get icloud tokens from that entitlement check the talk: #OBTS v5.0: "What Happens on your Mac, Stays on Apple's iCloud?!" - Wojciech Regula
An app with the kTCCServiceAppleEvents
permission will be able to control other Apps. This means that it could be able to abuse the permissions granted to the other Apps.
For more info about Apple Scripts check:
macOS Apple ScriptsFor example, if an App has Automation permission over iTerm
, for example in this example Terminal
has access over iTerm:
Terminal, who doesn't have FDA, can call iTerm, which has it, and use it to perform actions:
Or if an App has access over Finder, it could a script such as this one:
The userland tccd daemon what using the HOME
env variable to access the TCC users database from: $HOME/Library/Application Support/com.apple.TCC/TCC.db
According to this Stack Exchange post and because the TCC daemon is running via launchd
within the current user’s domain, it's possible to control all environment variables passed to it.
Thus, an attacker could set $HOME
environment variable in launchctl
to point to a controlled directory, restart the TCC daemon, and then directly modify the TCC database to give itself every TCC entitlement available without ever prompting the end user.
PoC:
Notes had access to TCC protected locations but when a note is created this is created in a non-protected location. So, you could ask notes to copy a protected file in a noe (so in a non-protected location) and then access the file:
The binary /usr/libexec/lsd
with the library libsecurity_translocate
had the entitlement com.apple.private.nullfs_allow
which allowed it to crate nullfs mount and had the entitlement com.apple.private.tcc.allow
with kTCCServiceSystemPolicyAllFiles
to access every file.
It was possible to add the quarantine attribute to "Library", call the com.apple.security.translocation
XPC service and then it would map Library to $TMPDIR/AppTranslocation/d/d/Library
where all the documents inside Library could be accessed.
Music
has an interesting feature: When it's running, it will import the files dropped to ~/Music/Music/Media.localized/Automatically Add to Music.localized
into the user's "media library". Moreover, it calls something like: rename(a, b);
where a
and b
are:
a = "~/Music/Music/Media.localized/Automatically Add to Music.localized/myfile.mp3"
b = "~/Music/Music/Media.localized/Automatically Add to Music.localized/Not Added.localized/2023-09-25 11.06.28/myfile.mp3
This rename(a, b);
bevabiour is vulnerable to a Race Condition, as it's possible to put inside the Automatically Add to Music.localized
folder a fake TCC.db file and then when the new forder(b) is created to copy the file, delete it, and point it to ~/Library/Application Support/com.apple.TCC
/.
If SQLITE_SQLLOG_DIR="path/folder"
basically means that any open db is copied to that path. In this CVE this control was abused to write inside a SQLite database that is going to be open by a process with FDA the TCC database, and then abuse SQLITE_SQLLOG_DIR
with a symlink in the filename so when that database is open, the user TCC.db is overwritten with the opened one.
More info in the writeup and in the talk.
If the environment variable SQLITE_AUTO_TRACE
is set, the library libsqlite3.dylib
will start logging all the SQL queries. Many applications used this library, so it was possible to log all their SQLite queries.
Several Apple applications used this library to access TCC protected information.
This env variable is used by the Metal
framework which is a dependency to various programs, most notably Music
, which has FDA.
Setting the following: MTL_DUMP_PIPELINES_TO_JSON_FILE="path/name"
. If path
is a valid directory, the bug will trigger and we can use fs_usage
to see what is going on in the program:
a file will be open()
ed, called path/.dat.nosyncXXXX.XXXXXX
(X is random)
one or more write()
s will write the contents to the file (we do not control this)
path/.dat.nosyncXXXX.XXXXXX
will be renamed()
d to path/name
It's a temporary file write, followed by a rename(old, new)
which is not secure.
It's not secure because it has to resolve the old and new paths separately, which can take some time and can be vulenrable to a Race Condition. For more information you can check out the xnu
function renameat_internal()
.
So, basically, if a privileged process is renaming from a folder you control, you could win a RCE and make it access a different file or, like in this CVE, open the file the privileged app created and store a FD.
If the rename access a folder you control, while you have modified the source file or has a FD to it, you change the destination file (or folder) to point a symlink, so you can write whenever you want.
This was the attack in the CVE: For example, to overwrite the user's TCC.db
, we can:
create /Users/hacker/ourlink
to point to /Users/hacker/Library/Application Support/com.apple.TCC/
create the directory /Users/hacker/tmp/
set MTL_DUMP_PIPELINES_TO_JSON_FILE=/Users/hacker/tmp/TCC.db
trigger the bug by running Music
with this env var
catch the open()
of /Users/hacker/tmp/.dat.nosyncXXXX.XXXXXX
(X is random)
here we also open()
this file for writing, and hold on to the file descriptor
atomically switch /Users/hacker/tmp
with /Users/hacker/ourlink
in a loop
we do this to maximize our chances of succeeding as the race window is pretty slim, but losing the race has negligible downside
wait a bit
test if we got lucky
if not, run again from the top
More info in https://gergelykalman.com/lateralus-CVE-2023-32407-a-macos-tcc-bypass.html
Now, if you try to use the env variable MTL_DUMP_PIPELINES_TO_JSON_FILE
apps won't launch
As root you could enable this service and the ARD agent will have full disk access which could then be abused by a user to make it copy a new TCC user database.
TCC uses a database in the user's HOME folder to control access to resources specific to the user at $HOME/Library/Application Support/com.apple.TCC/TCC.db. Therefore, if the user manages to restart TCC with a $HOME env variable pointing to a different folder, the user could create a new TCC database in /Library/Application Support/com.apple.TCC/TCC.db and trick TCC to grant any TCC permission to any app.
Note that Apple uses the setting stored within the user's profile in the NFSHomeDirectory
attribute for the value of $HOME
, so if you compromise an application with permissions to modify this value (kTCCServiceSystemPolicySysAdminFiles
), you can weaponize this option with a TCC bypass.
The first POC uses dsexport and dsimport to modify the HOME folder of the user.
Get a csreq blob for the target app.
Plant a fake TCC.db file with required access and the csreq blob.
Export the user’s Directory Services entry with dsexport.
Modify the Directory Services entry to change the user’s home directory.
Import the modified Directory Services entry with dsimport.
Stop the user’s tccd and reboot the process.
The second POC used /usr/libexec/configd
which had com.apple.private.tcc.allow
with the value kTCCServiceSystemPolicySysAdminFiles
.
It was possible to run configd
with the -t
option, an attacker could specify a custom Bundle to load. Therefore, the exploit replaces the dsexport
and dsimport
method of changing the user’s home directory with a configd
code injection.
For more info check the original report.
There are different techniques to inject code inside a process and abuse its TCC privileges:
macOS Process AbuseMoreover, the most common process injection to bypass TCC found is via plugins (load library). Plugins are extra code usually in the form of libraries or plist, that will be loaded by the main application and will execute under its context. Therefore, if the main application had access to TCC restricted files (via granted permissions or entitlements), the custom code will also have it.
The application /System/Library/CoreServices/Applications/Directory Utility.app
had the entitlement kTCCServiceSystemPolicySysAdminFiles
, loaded plugins with .daplug
extension and didn't have the hardened runtime.
In order to weaponize this CVE, the NFSHomeDirectory
is changed (abusing the previous entitlement) in order to be able to take over the users TCC database to bypass TCC.
For more info check the original report.
The binary /usr/sbin/coreaudiod
had the entitlements com.apple.security.cs.disable-library-validation
and com.apple.private.tcc.manager
. The first allowing code injection and second one giving it access to manage TCC.
This binary allowed to load third party plug-ins from the folder /Library/Audio/Plug-Ins/HAL
. Therefore, it was possible to load a plugin and abuse the TCC permissions with this PoC:
For more info check the original report.
System applications that open camera stream via Core Media I/O (apps with kTCCServiceCamera
) load in the process these plugins located in /Library/CoreMediaIO/Plug-Ins/DAL
(not SIP restricted).
Just storing in there a library with the common constructor will work to inject code.
Several Apple applications were vulnerable to this.
The Firefox application had the com.apple.security.cs.disable-library-validation
and com.apple.security.cs.allow-dyld-environment-variables
entitlements:
Fore more info about how to easily exploit this check the original report.
The binary /system/Library/Filesystems/acfs.fs/Contents/bin/xsanctl
had the entitlements com.apple.private.tcc.allow
and com.apple.security.get-task-allow
, which allowed to inject code inside the process and use the TCC privileges.
Telegram had the entitlements com.apple.security.cs.allow-dyld-environment-variables
and com.apple.security.cs.disable-library-validation
, so it was possible to abuse it to get access to its permissions such recording with the camera. You can find the payload in the writeup.
Note how to use the env variable to load a library a custom plist was created to inject this library and launchctl
was used to launch it:
It's possible to invoke open
even while sandboxed
It's quiet common to give terminal Full Disk Access (FDA), at least in computers used by tech people. And it's possible to invoke .terminal
scripts using with it.
.terminal
scripts are plist files such as this one with the command to execute in the CommandString
key:
An application could write a terminal script in a location such as /tmp and launch it with a come such as:
Any user (even unprivileged ones) can create and mount a time machine snapshot an access ALL the files of that snapshot.
The only privileged needed is for the application used (like Terminal
) to have Full Disk Access (FDA) access (kTCCServiceSystemPolicyAllfiles
) which need to be granted by an admin.
A more detailed explanation can be found in the original report.
Even if TCC DB file is protected, It was possible to mount over the directory a new TCC.db file:
Check the full exploit in the original writeup.
The tool /usr/sbin/asr
allowed to copy the whole disk and mount it in another place bypassing TCC protections.
There is a third TCC database in /var/db/locationd/clients.plist
to indicate clients allowed to access location services.
The folder /var/db/locationd/
wasn't protected from DMG mounting so it was possible to mount our own plist.
In several occasions files will store sensitive information like emails, phone numbers, messages... in non protected locations (which count as a vulnerability in Apple).
This doesn't work anymore, but it did in the past:
Another way using CoreGraphics events:
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)