FFRIエンジニアブログ

株式会社FFRIセキュリティのエンジニアが執筆する技術者向けブログです

Black Hat USA 2022 注目発表 2 ~ macOS のセキュリティの発表紹介

はじめに

基礎技術研究部の中川です。

2022/8/6 から 6 日間、ラスベガスで Black Hat USA が開催されました。

今回の記事では今年の Black Hat USA の中から macOS セキュリティに関係する発表 2 件を取り上げ簡単に内容について紹介していきます。

macOS はマルウェアとは無縁というのは今ではあまり当てはまりません。MalwareBytes のデータによれば、端末あたりのマルウェア検知数は Windows よりも多いというデータが出ています[1] *1。また、Apple 自身も、macOS のマルウェアは許容できないレベルに達しているとの発言をしています[2]。攻撃の高度化も進んでおり、昨年は macOS の 0-day 脆弱性を利用した XCSSET[3]や Shlayer[4]などのマルウェアが出ています。

一方、Apple は macOS に様々なセキュリティ機構を導入し、攻撃の成立を困難にしています。例えば Gatekeeper は Apple による審査をパスした、有効なコード署名を持ったアプリの実行のみを許可するためのセキュリティ機構です。Gatekeeper があるため、基本的に信頼されていないアプリの実行はブロックされます[5]。その他、Transparency Consent and Control (TCC) はユーザーの明示的な同意なしでの、機微なデータへのアクセスを制限するものです[6]。これにより、デスクトップや Documents のファイルへのアクセスは、明示的な同意がなければブロックされます。一部のアプリケーション (例えば Word などの Office 製品) は App Sandbox 環境で実行されるようになっています[7]。仮にユーザーがあやまって Office 製品のマクロを実行しても、攻撃者は App Sandbox をバイパスしなければ大部分のファイルにアクセスすらできません。

さて、このように macOS では何重にもセキュリティ機構が備わっているわけですが、果たしてこれらのセキュリティ機構はどの程度有効に機能しているものなのでしょうか。今年の Black Hat では macOS に標準で備わっているセキュリティ機構のほとんどをバイパスできてしまう深刻な脆弱性が報告されました。

Process Injection: Breaking All macOS Security Layers With a Single Vulnerability

この発表では macOS で利用可能な新しいプロセスインジェクション手法が紹介されています。発表で提案された手法を用いることで、macOS のセキュリティ機構である、App Sandbox, System Integrity Protection (SIP) などを 1 つの手法で全てバイパス可能であることが示されています。発表では特に言及がないですが、おそらく TCC のバイパスにおいても利用可能な手法と思われます。

たった 1 つのプロセスインジェクション手法で、なぜここまで多くのセキュリティ機構のバイパスが可能となるのでしょうか。これを理解するため、まず macOS のセキュリティモデルについて知る必要があります。

発表の背景: macOS のセキュリティモデル

macOS では従来、伝統的な UNIX のセキュリティモデルを採用していました。セキュリティの境界は一般ユーザーと root の間に存在し、一度 root 権限を取得してしまえば、基本的にはシステムのすべてのファイルにアクセスでき、どのプロセスにもアタッチが可能となります。

しかし、近年の macOS では事情が変わっています。SIP が導入されたことで、root 権限で実行可能な操作に制限が設けられるようになりました。例えば、システムファイルの変更 *2 は SIP の導入以降 root であっても制限され、書き換えができません。プロセスのアタッチについても、仮に root 権限を取得していたとしても、システムプロセスへのアタッチは SIP により制限されます。SIP は rootless とも呼ばれますが、その名の通り root に過度に集約された権限を制限する意図で導入されたものです。

一方で root でもシステムファイルの書き換えができない場合、まずいことがおきます。例えば、OS のアップデートを考えましょう。この時システムファイルの変更が必要になるわけですが、SIP により root による書き換えすら制限されると、OS の更新ができなくなってしまいます。そこで macOS ではコード署名とその中に含まれる entitlement によりこの問題を解決しています。entitlement は直訳すると"資格"ですが、そのバイナリで許可されている権限のリスト、と考えてもらえば大丈夫です。entitlement の中には SIP の制約を受けることなくシステムファイルの書き換えを許可するものがあり、これが付与されているバイナリであればシステムファイルの書き換えが可能となります。

試しに、システムバイナリに含まれる entitlement を見てみましょう。以下に示すのは system_installd と呼ばれるデーモンに含まれるコード署名と entitlement です。[Dict] という行以降に、 system_installd の entitlement が表示されていることがわかります。

$ codesign -dv --entitlements - /System/Library/PrivateFrameworks/PackageKit.framework/Resources/system_installd
Executable=/System/Library/PrivateFrameworks/PackageKit.framework/Versions/A/Resources/system_installd
Identifier=com.apple.system_installd
Format=Mach-O universal (x86_64 arm64e)
CodeDirectory v=20400 size=754 flags=0x0(none) hashes=13+7 location=embedded
Platform identifier=14
Signature size=4523
Signed Time=Sep 10, 2022 22:55:41
Info.plist=not bound
TeamIdentifier=not set
Sealed Resources=none
Internal requirements count=1 size=76
[Dict]
        [Key] com.apple.rootless.install.heritable
        [Value]
                [Bool] true
        [Key] com.apple.private.package_script_service.allow
        [Value]
                [Bool] true
        [Key] com.apple.private.responsibility.set-arbitrary
        [Value]
                [Bool] true
        [Key] com.apple.private.security.storage-exempt.heritable
        [Value]
                [Bool] true
        [Key] com.apple.private.responsibility.set-hosted-properties
        [Value]
                [Bool] true
        [Key] com.apple.private.storage.fusion.allow-pin-fastpromote
        [Value]
                [Bool] true
        [Key] com.apple.private.security.syspolicy.package-installation
        [Value]
                [Bool] true
        [Key] com.apple.private.security.syspolicy.package-verification
        [Value]
                [Bool] true
        [Key] com.apple.private.tcc.manager.access.delete
        [Value]
                [Array]
                        [String] kTCCServiceAll
        [Key] com.apple.private.launchservices.cansetapplicationstrusted
        [Value]
                [Bool] true

com.apple.* で始まる key とそれに対応する value が Bool 型の変数として定義されていることがわかります。中でも com.apple.rootless.install.heritable はシステムファイルを更新するインストーラーなどに含まれるもので、SIP で保護されているファイルの更新を可能とします。この entitlement は Apple のコード署名を持つバイナリにしか付与できません *3。そのため、基本的に Apple がビルドしたバイナリにのみ、SIP で保護されたバイナリの書き換えが許可されています。

しかし、仮にプロセスインジェクション可能な脆弱性が見つかった場合、この SIP による保護は破綻します。例えば com.apple.rootless.install.heritable の entitlement を持ったプロセスに対してコードインジェクションできるケースを考えます。この時、com.apple.rootless.install.heritable の entitlement を乗っ取りコード実行できるため、SIP で保護されているシステムファイルへの書き込みが全て許可されてしまいます。実際にこの手の脆弱性が報告されており、CVE-2021-30892 (a.k.a. Shrootless) として知られています[8]。

そのため、macOS ではプロセスインジェクションが非常に厳しく制限されています。Windows でいうところの Process Handle の取得すら、明示的に許可する entitlement が付与されていない限りは制限されます。また、Linux における LD_PRELOAD を介したライブラリのインジェクションも、hardened runtime 等で制限されています。ここでは SIP を例にとって説明しましたが、他のセキュリティ機構も基本的にはコード署名と entitlement に依存して機能します。

これまで、プロセスインジェクションは様々な macOS のセキュリティ機構のバイパスにおいて利用されてきました。ただ、それらの多くは debug 用のビルド設定をそのまま使っている、hardened runtime を有効にしていないなどと、どちらかといえばビルド設定の不備に起因する問題でした。このため、インジェクション対象は特定のバイナリに限定されていました。汎用的にどのプロセスに対してもインジェクション可能な手法はこれまで見つかっていませんでした。

発表の内容

この発表で取り上げられているプロセスインジェクション手法は、対象が AppKit ベースのアプリであれば、汎用的に利用できる点が特徴です。例えば、前節で紹介した com.apple.rootless.install.heritable という entitlement をもったアプリケーションに対してインジェクトすれば、SIP をバイパスできます。発表では root への権限昇格、App Sandbox のバイパスも可能であることが示されています。

このプロセスインジェクションは、macOS に実装されている saved state の機能を悪用することで実現されています。saved state は例えばシャットダウン直前のアプリケーションの状態を保存しておき、次にシステムを立ち上げた時に状態の復帰を可能とするために利用されています。この機能は現在のアプリケーションの状態を格納したオブジェクトをファイルとして保存し、復帰する際にこれをデシリアライズすることによって実装されています。アプリケーションの状態を格納したファイルは、~/Library/Saved Application State/<bundle id>.savedState というディレクトリに保存されています。

# ~/Library/Saved Application State/<bundle id>.savedState というディレクトリが存在
$ ls ~/Library/Saved\ Application\ State/*
com.apple.AppStore.savedState
com.google.Chrome.savedState
com.hnc.Discord.savedState
...
$ ls ~/Library/Saved\ Application\ State/com.apple.AppStore.savedState/
data.data windows.plist

発表者は、多くのアプリケーションにおいて、シリアライズが Secure Coding を有効にしない形で行われていることを発見しました*4。Secure Coding が有効になっていない場合、以下に示すように、オブジェクトを作成した後でその型を確認する形でのデシリアライズが許可されます。

id obj = [decoder decodeObjectForKey:@"myKey"];
if (![obj isKindOfClass:[MyClass class]]) { /* ...fail... */ }

このデシリアライズは Object Substitution 攻撃に対して脆弱であることが知られています。すなわち、攻撃者が用意したシリアライズオブジェクトをロードし、悪意のある任意のコードを実行することが可能となります。

一見すると問題には見えません。しかし、よく考えると 1 行目で obj を作成した時点で、いくつかのメソッドが呼び出されます (例えば、イニシャライザなど)。発表者はこの事実を利用し、アプリケーションの状態を格納したファイルに、インジェクションしたいコードを含むことにより、プロセスインジェクションを実現しています。

ちなみに Secure Coding が有効になっている場合、以下に示すようにデシリアライズは型検証と同時に行われます。そのため、Object Substitution 攻撃は困難となります。

id obj = [decoder decodeObjectOfClass:[MyClass class] forKey:@"myKey"];

本脆弱性の影響・対策

本脆弱性は saved state において Secure Coding が有効になっていない全てのアプリケーションに波及します。Apple は Xcode 13.2 からテンプレートを修正し、今後新規に作成されるアプリについては、Secure Coding が有効になるよう変更を加えています。

- (BOOL)applicationSupportsSecureRestorableState:(NSApplication *)app {
    return YES;
}

既存のアプリについては -applicationSupportsSecureRestorableState: の戻り値として YES を返すようにし、secure coding が有効になるように変更を加えるべきでしょう。

考察

本発表は macOS のセキュリティモデルがプロセスインジェクション可能な脆弱性 1 つで大きく破綻することを示す好例と言えます。

今後、こうした汎用的にインジェクション可能な脆弱性が見つかるかどうかは不明です。ただ、macOS は、最初からコード署名と entitlement に依存する形のセキュリティモデルを採用していたわけではなく、漸進的にセキュリティモデルを変化させてきました。そのため、追従しきれていない部分がまだ残っている可能性があります。こうした追従しきれていない部分に、コードインジェクション可能な脆弱性がまた見つかる可能性は十分に考えられます。

発表のスライドだけでなく、より詳細を説明したブログ記事も出ていますので、合わせてそちらも参照されると理解が深まります[9]。興味のある方はこちらもご参照ください。

Leveraging the Apple ESF for Behavioral Detections

2 つ目に取り上げる発表は Apple Endpoint Security Framework (ESF) を利用して振る舞い検知を実現する方法についての発表です。

発表の背景: Endpoint Security Framework について

Endpoint Security Framework (ESF) は macOS Catalina で導入された比較的新しいフレームワークです。このフレームワークを利用することで、システムイベントの取得・発生したシステムイベントの認可処理を実装することが可能となります。Windows における ProcMon 相当のシステムイベントの取得ツールの実装やアンチウイルスの実装において、本フレームワークは使われています。

macOS Catalina 以前は専用の Kernel Extension を作成し、その中で Kauth や MACF などのフレームワークを利用して同等のことを行っていました。しかし、以下のような問題がありました[10]。

  • 公開 API で取得できる情報が限定的であり、例えば、プロセス実行時のコマンドライン・環境変数が取得できない
    • そのために、検知に必要な情報を取得するに当たり、しばしば非公開 API を利用する必要があった
  • カーネルモードで動作するため、バグがあるとシステム全体が不安定になった

ESF は、公開 API で取得可能な情報が豊富で、かつユーザーモードで動作するため、これらの問題が改善されています[11]。

ESF では大きく分けて 2 種類のイベントを取得でき、それぞれ発生したシステムイベントにフックして callback 関数を呼び出すことができます。

  • Notification Event: 発生したシステムイベントの通知を受け取るのみ。Process Monitor などシステムイベントの監視ツールの実装においてはこちらが用いられる。
  • Authorization Event: 発生したシステムイベントを pending 状態にして、callback 関数内でそのイベントを実行を許可するかを設定する場合はこちらが用いられる。例えばアンチウイルスの実装においてはこちらのイベントを取得する。

ESF は様々なツールの実装で使われています。ProcessMonitorFileMonitor は macOS のマルウェア解析でシステムイベントを取得する上で標準的に使われている CLI ツールです[12,13]。これらのツールの実装は ESF の Notification Event を取得することによって行われています。また、macOS 上で発生したプロセスインジェクションを検知し、ブロックするために開発された Shield は Authorization Event を利用し、プロセスインジェクションを検知した時点でその実行をブロックします[14]。

発表の内容

発表では ESF を利用して、実際に攻撃で利用された挙動を検知するための様々なロジックが紹介されました。ここではそのロジックの中からいくつかピックアップして紹介していきます。

Plist Disguised as Apple

まずは "Plist Disguised as Apple" です。これは Apple 正規の launch items に偽装して persistence を実現するマルウェアを検知するためのロジックです。

ここで馴染みのない方向けに launch items についてここで補足説明します。launch items とはユーザーがログインした際に実行されるアプリケーションを設定する際に用いられるものです。これは ${HOME}/Library/LaunchAgents, /Library/LaunchAgents, /Library/LaunchDaemons 配下に plist ファイルを作成することにより設定できます*5

launch items の plist ファイルの名前では Reverse Domain Name Notation がよく用いられます。例えば com.apple.tccd.system.plist などです。マルウェアは Apple 正規のサービスに見せかけるため plist のファイル名として com.apple. をつける傾向にあります (OSX.CookieMiner など)[15]。

発表ではこの事実を利用した検知ロジックが紹介されていました。com.apple. の名前がついた plist ファイルを解析し launch items として登録された実行ファイルを抽出し、その実行ファイルのコード署名を確認する、というものです。Reverse Domain Name Notation で com.apple. がついたものであれば、実行ファイルに Apple によるコード署名がついているはずです。Malware はこのコード署名がついていないため、これにより異常な launch items が登録されたことを検知できます。

発表資料より "Plist Disguised as Apple" の該当スライドを転載

この他にも macOS マルウェアは plist を隠しファイルとして登録するケースもあります (例えば OSX.GMERA など)[16]。正規のプログラムで plist ファイルを隠しファイルとして登録するのは珍しいため、こうしたロジックも振る舞い検知の 1 つとして使えると考えられます。

CVE-2022-22616 Gatekeeper Bypass

CVE-2022-22616 は Gatekeeper Bypass の脆弱性です。詳細は Jamf のブログポストを参照して欲しいのですが[17]、Safari の Auto Unzip で展開された Application Bundle に com.apple.quarantine がついていないことによる、Gatekeeper Bypass の脆弱性です *6

発表では CVE-2022-22616 を含む類似の脆弱性の悪用を検知するロジックについて紹介されていました。具体的には以下の条件に合致したものを検知するというものです。

  • イベントが rename
  • プロセスが SandboxBroker
  • ファイルが app の拡張子を持っている
  • temp フォルダから Download に rename
  • 対象ファイルに com.apple.quarantine 拡張属性がついていない

発表資料より、Gatekeeper bypass を検知するロジックの説明の該当スライドを転載

SandboxBroker は Safari の Auto Unzip を行うプロセスです。これは一度 temp ディレクトリに解凍したディレクトリを展開し、展開したファイルを Download に rename します。この処理の実行後のディレクトリに com.apple.quarantine がついていない場合に、Gatekeeper Bypass として検知します。

このロジックは、CVE-2022-22616 を検知するのに特化しているように見えます。しかし、展開したファイルに com.apple.quarantine がついていないことに起因する Gatekeeper bypass の脆弱性は他にも知られており (例えば CVE-2021-1810[18]など)、将来的に見つかる可能性のある Safari の Auto Unzip に起因した Gatekeeper Bypass の脆弱性を検知する上で汎用的に使えるロジックと言えます。

最近の動向

この発表では触れられていませんが、ESF は WWDC22 で発表された macOS Ventura で大きくアップデートされることがアナウンスされました[19]。最後にその点についても触れていきます。

取得可能なイベントの増加

Authentication, Login/Logout, XProtect/Gatekeeper のイベントが追加で取得可能になりました。

Authentication のイベントはこれまで OpenBSM などの BSD 由来のコンポーネントを利用して取得する必要がありました。Ventura からこの必要がなくなり、OpenBSM 自体の利用が非推奨になりました。

また、XProtect/Gatekeeper のイベントを取れるようになった点も注目です。従来はドキュメント化されていないデータベースをパースし、関連するイベントを取り出す必要がありましたが、この必要がなくなり、安定した形で取得できるようになっています。

eslogger の導入

macOS Ventura からシステムイベントを取得するために、ESF で実装された専用ツール eslogger が提供されるようになりました。従来は、ESF を使って作られたサードパーティ製の ProcessMonitor や FileMonitor などが使われていたわけですが、今後は macOS 標準のツールで行えるようになります。

具体的にどういったイベントが取得できるのか見ていきましょう。取得可能なイベントは eslogger --list-events により一覧を表示できます。

sh-3.2# eslogger --list-events
access
authentication
btm_launch_item_add
btm_launch_item_remove
chdir
chroot
clone
close
copyfile
create
cs_invalidated
deleteextattr
dup
exchangedata
exec
exit
fcntl
...
unmount
utimes
write
xp_malware_detected
xp_malware_remediated

exec などのプロセスの実行のイベントや copyfile などのファイルに関係するイベントの他、 XProtect に関するイベント (xp_malware_detectedxp_malware_remediated など) も取得できることがわかります。

ここに表示されたイベント名を引数に指定し実行することで、選択したシステムイベントを取得できます。

# eslogger exec
{"schema_version":1,"mach_time":2991641323,"event_type":9,"thread":{"thread_id":3869},"version":6,"seq_num":0,"event":{"exec":{"script":null,"last_fd":2,"target":{"signing_id":"com.apple.xpc.proxy","parent_audit_token":{"asid":100001,"pidversion":7,"ruid":0,"euid":0,"rgid":0,"auid":4294967295,"egid":0,"pid":1},"codesigning_flags":570522385,"executable":{"path":"\/usr\/libexec\/xpcproxy","stat":{"st_blocks":96,"st_blksize":4096,"st_rdev":0,"st_dev":16777229,"st_uid":0,"st_gid":0,"st_ino":1152921500312427377,"st_birthtimespec":"2022-09-16T07:34:39.000000000Z","st_flags":524320,"st_nlink":1,"st_mtimespec":"2022-09-16T07:34:39.000000000Z","st_ctimespec":"2022-09-16T07:34:39.000000000Z" ...
...

おわりに

いかがでしたでしょうか。本記事をきっかけとして macOS セキュリティに興味を持ってもらえれば幸いです。最近では macOS セキュリティに特化した OBTS というセキュリティカンファレンスが毎年秋に開催されています。macOS セキュリティに興味を持たれた方はこちらのカンファレンスの発表もチェックしてみてください。

また、Black Hat では macOS 以外にも様々なセキュリティに関連する研究発表が取り上げられています。ぜひ他の研究発表もチェックしてみてください。

参考文献

[1] 2020 State of Malware Report, https://www.malwarebytes.com/resources/files/2020/02/2020_state-of-malware-report-1.pdf , 2022 年 9 月 21 日閲覧

[2] Apple exec Craig Federighi calls the state of Mac malware 'not acceptable', https://www.engadget.com/apple-craig-federighi-mac-os-220134152.html , 2022 年 9 月 21 日閲覧

[3] Deconstructing a Zero-Day: XCSSET Malware, https://www.jamf.com/resources/white-papers/deconstructing-a-zero-day-xcsset-malware/ , 2022 年 9 月 21 日閲覧

[4] All Your Macs Are Belong To Us bypassing macOS's file quarantine, gatekeeper, and notarization requirements, https://objective-see.org/blog/blog_0x64.html , 2022 年 9 月 21 日閲覧

[5] Mac で App を安全に開く, https://support.apple.com/ja-jp/HT202491 , 2022 年 9 月 21 日閲覧

[6] Wojciech Reguła and Csaba Fitzl, 20+ Ways to Bypass Your macOS Privacy Mechanisms, https://www.blackhat.com/us-21/briefings/schedule/#-ways-to-bypass-your-macos-privacy-mechanisms-23133

[7] Escaping the Sandbox – Microsoft Office on MacOS, https://www.mdsec.co.uk/2018/08/escaping-the-sandbox-microsoft-office-on-macos/ , 2022 年 9 月 22 日閲覧

[8] Microsoft finds new macOS vulnerability, Shrootless, that could bypass System Integrity Protection, https://www.microsoft.com/security/blog/2021/10/28/microsoft-finds-new-macos-vulnerability-shrootless-that-could-bypass-system-integrity-protection/ , 2022 年 9 月 15 日閲覧

[9] Process injection: breaking all macOS security layers with a single vulnerability, https://sector7.computest.nl/post/2022-08-process-injection-breaking-all-macos-security-layers-with-a-single-vulnerability/ , 2022 年 9 月 15 日閲覧

[10] Build an Endpoint Security app, https://developer.apple.com/videos/play/wwdc2020/10159/ , 2022 年 9 月 22 日閲覧

[11] macOS vs. Windows – What kernels tell you about security events: Part 1, https://www.elastic.co/jp/blog/macos-windows-what-kernels-tell-you-about-security-events-part-1 , 2022 年 9 月 22 日閲覧

[12] Writing a Process Monitor with Apple's Endpoint Security Framework, https://objective-see.org/blog/blog_0x47.html , 2022 年 9 月 22 日閲覧

[13] Writing a File Monitor with Apple's Endpoint Security Framework , 2022 年 9 月 22 日閲覧

[14] Shield - An app to protect against process injection on macOS, https://theevilbit.github.io/shield/ , 2022 年 9 月 22 日閲覧

[15] The Mac Malware of 2019, https://objective-see.org/blog/blog_0x53.html , 2022 年 9 月 22 日閲覧

[16] Detecting macOS.GMERA Malware Through Behavioral Inspection, https://www.sentinelone.com/labs/detecting-macos-gmera-malware-through-behavioral-inspection/ , 2022 年 9 月 22 日閲覧

[17] Jamf Threat Labs identifies macOS Archive Utility vulnerability allowing to bypass Gatekeeper, https://www.jamf.com/blog/jamf-threat-labs-macos-archive-utility-vulnerability/ , 2022 年 10 月 5 日閲覧

[18] The discovery of Gatekeeper bypass CVE-2021-1810, https://labs.withsecure.com/publications/the-discovery-of-cve-2021-1810 , 2022 年 9 月 22 日閲覧

[19] What’s new in Endpoint Security, https://developer.apple.com/videos/play/wwdc2022/110345/ , 2022 年 9 月 22 日閲覧

*1:ただし、このデータはアドウェアも含んだ結果である点に注意です

*2:例えば /usr/bin, /bin, /System 配下のファイル

*3:サードパーティのバイナリに対してこの entitlement を付与した場合、そもそも実行できなくなります。

*4:Secure Coding についてはApple の Documentationを参照してください。

*5:plist ファイルは macOS/iOS で設定情報を記述するのに用いられるファイル形式です。

*6:com.apple.quarantine は Windows の Mark of the Web に相当するものと考えてもらえれば良いです。com.apple.quarantine の拡張属性が付いたファイルはインターネットからダウンロードされたものとみなされます。Gatekeeper は com.apple.quarantine 拡張属性がついている場合、実行ファイルのコード署名と公証をパスしたものなのかを確認し、そうではない場合には実行をブロックするようになっています。