エクスプロイト&脆弱性
macOSのセキュリティ機能SIPをバイパスする脆弱性「CVE-2019-8561」の解説
この記事では、ソフトウェアのインストーラパッケージ(PKGファイル)のインストール時に使用されるコンポーネントであるmacOSのPackageKitフレームワークに存在する脆弱性「CVE-2019-8561」の詳細について解説します。
この記事では、ソフトウェアのインストーラパッケージ(PKGファイル)のインストール時に使用されるコンポーネントであるmacOSのPackageKitフレームワークに存在する脆弱性「CVE-2019-8561」の詳細について解説します。具体的には、「Apple社がどのようにパッチを適用したか」、「この脆弱性が確認された後にどのようにエクスプロイトされたか」、そして「Apple社がどのようにパッチを再適用したか」について以下に解説します。
トレンドマイクロは、POC2022(パワー・オブ・コミュニティ2022)セキュリティ・コンファレンスにおいて、15件以上の重要なSIPバイパスの脆弱性をApple社に開示し、その一部について解説を行いました。本文は、SIP関連の脆弱性の発見について説明するブログエントリーの第1回目となります。
CVE-2019-8561の歴史
2019年3月25日、Apple社はroot権限の昇格、シグネチャバイパス、ひいてはApple社のSIP(System Integrity Protection)のバイパスにつながる可能性のあるバグ「CVE-2019-8561」にパッチを適用しました。
上記内容が公開されてから3カ月後、リサーチャーのJaron Bradley氏が第2回Objective by the Seaセキュリティ・コンファレンスにおいて、この脆弱性について解説しました。「Bad Things in Small Packages」と題された発表では、PackageKitフレームワークの分析を行った結果、Apple社の当時のデスクトップ・オペレーティングシステムの最新バージョンであるmacOS(Monterey)に対しCVE-2019-8561は依然として影響を及ぼしていることが確認されました。macOS 10.14(Mojave)に影響を与えたのと同様に、この脆弱性を悪用することにより権限昇格やSIP制限をバイパスすることが可能となります。
2022年10月24日、Apple社はmacOS 13(Ventura)の脆弱性として再度CVE-2022-32895を対処しました。
Apple社のSIP
SIPとは、OS X EI Capitanで導入されたセキュリティ機能であり、ファイルやフォルダーを改ざんする潜在的な不正ソフトウェアからMacのオペレーションシステムを保護するために設計されたものです。これは、「rootless」とも呼ばれ、rootユーザアカウントを制限し、rootユーザがオペレーティングシステム上の保護された領域に対し実行できるアクションを限定します
SIPが導入される以前は、rootユーザには権限の制限がなく、マシン上のあらゆるシステムフォルダやアプリにアクセスすることが可能でした。しかし、このセキュリティ機能の登場により、Apple-signed processes (Apple社が署名したプロセス)及び特別な権限を持つ者だけが保護されたシステムファイルを変更することができるようになりました。これらのプロセスには、Apple社のソフトウェアアップデートやインストーラが含まれます。
system_installdとは
MacOS は、「com.apple.rootless.install」や「com.apple.rootless.install.heritable」などの特別な権限を用いてシステムファイルを更新します。また、必要な目的のためにシステムファイルを変更する権限を付与します。
これらの特別な権限は Apple社のみが使用することができ、少数のシステムコマンドのみに署名がなされています。「system_installd」は、これらの権限を持つデーモンサービスの一つであり、Apple社の署名のあるパッケージのインストールを行います。そして、そのコアロジックはPackageKit フレームワークで実装されています。また、「com.apple.rootless.install.heritable」という特別な権限があるため、生成する子プロセスはSIPバイパス・コンテクストで実行されます。
CVE-2019-8561のテクニカル分析
CVE-2019-8561について
「CVE-2019-8561」 は、Apple 社の署名入りPKG ファイルをインストールすることで発生する典型的なTOCTTOU(time-of-check-to-time-of-use)のバグを悪用します。
- pre-install(プレインストール)またはpost-install(ポストインストール)スクリプトを含むApple社の署名入りPKGファイルがインストールされます。
- 「system_installd」デーモンサービスは、インストールリクエストを処理し、パッケージの署名を検証します。もし、パッケージがApple社により署名されていないとサービスが判断した場合、インストール処理を中断します。
- サービスが検証プロセスをパスさせた場合には、攻撃者はPKG ファイルを不正なものに置き換えることができます。
- サービスは、偽の PKG ファイル(署名なし)内にある不正なpre-install(プレインストール)またはpost-install(ポストインストール)スクリプトを抽出し実行します。
- 生成されたスクリプトは、SIPバイパス・コンテクストにより root 権限として実行されます。
このバグ自体は非常に単純であり、また不正利用も容易に行うことが可能です。
CVE-2019-8561の分析
トレンドマイクロが、当時の最新OSであったmacOS(Monterey)を用いて不正利用を試みたところ、「xar_open_digest_verify」関数においてエラーメッセージが表示されました。
ここでは、toc(Table of Content)のdigestが想定されたものと一致しないことが表示されました。
PackageKitフレームワーク内のコールスタックからcaller関数を解析した結果、installation clientからdigestが引き渡されていることが判明しました。また、戻されたXAR(extensible archive format)ポインタをメンバ変数としてキャッシュするため、次に PKG ファイルにアクセスする必要がある場合には、XAR アーカイブを再度開くのではなくメンバ変数としてキャッシュされた XAR ポインタを直接戻します。
この時点では、抽出前にdigestを検証できたためパッチは適用されたように見えましたが問題は解決していませんでした。
ダブル・トリプルフェッチ
PKGファイルは容量が大きくなる可能性があるため、シングルフェッチにより、その内容を全てメモリに読み込むのは得策ではありません。そのため、必要に応じてコンポーネントを読み込み抽出します。
以下の関数をリバースした結果、3種類のメソッドを用いて「BOM(bill of materials)ファイル」、「ペイロード」、そして「スクリプト」から抽出されていることが判明しました。
[PKExtractInstallOperation _extractAllSpecifiersOnceAndReturnFailingSpecifier:andError:]
最初のメソッドである以下の関数は、図2が示すようにBOM ファイルを抽出する前にdigestを検証します。
[PKExtractInstallOperation _extractBomForPackageSpecifier:error:]
2番目のメソッドである以下の関数は、
[PKExtractInstallOperation _extractScriptsForPackageSpecifier:error:]
次の関数を内部的に呼び出します。
[PKLeopardPackage scriptsExtractorWithDestination:error:]
また、以下の内部関数についても調査を行いました。
[PKPayloadCopier initWithArchivePath:offset:destination:]
この関数は20行目でPKGファイルを直接開き、戻されたファイル記述子を固定したoffsetにより検索しています。また、inputFDをキーインプットとしてBOMCopierにファイル記述子を読み込みます。
次に以下の関数の解析を行いました。
[PKPayloadCopier run]
この関数は、API 「BOMCopierCopyWithOptions」をinputFD(untrusted)から抽出することにより呼び出します。
API「xar_open_digest_verify」は、PKG ファイル(untrusted)を開く際に使用しても安全ですが、オープンAPIは安全ではありません。これは、典型的な「ダブルフェッチ」問題とされます。オープンAPIは、digestを再度検証することなくPKGファイル(untrusted)を直接開くため、PKGファイルが不正なものに置き換えられる可能性があり、これにより再び悪用される恐れがあります。
以下の3番目のメソッドは、、
[PKExtractInstallOperation _extractPayloadForPackageSpecifier:error:]
次の関数を内部的に呼び出します。
[PKLeopardPackage payloadExtractorWithDestination:externalRoot:error:]
28行目において、PKGファイル内のペイロードsubpathのoffset値が0に等しくない場合、以下の関数が
[PKLeopardPackage payloadExtractorWithDestination:externalRoot:error:]
次の関数を呼び出します。
[PKPayloadCopier initWithArchivePath:offset:destination:]
この場合には、上記2番目のメソッドと類似する「トリプルフェッチ」の問題が生じます。
もし、offset値が0に等しい場合、特殊な外部rootパスからペイロードを抽出します。このパスには制限がなく、攻撃者がコントロールすることが可能です。つまり、攻撃者が不正なペイロードを外部rootパスに配置する恐れがあります。しかし、現時点では、外部rootパスを持つApple社署名のPKGファイルは確認されていません。
エクスプロイト
トレンドマイクロは、後の検証のためにPKGファイルを抽出後、Apple社が署名したオリジナルのものに復元する必要がありました。また、新たに作成されたPKGファイル内のスクリプトまたはペイロードsubpathパスのコンポーネントにおけるoffset値を元のファイルのoffset値と一致させる必要もありました。
検証のために、まずペイロードを含むPKGファイルを作成しました。Apple社が署名したオリジナルのPKGファイルを展開した後、古いスクリプトをクリーンアップし、ペイロードをpost-install(ポストインストール)スクリプトに配置しました。
pkgutil --expand /Volumes/Pro\ Video\ Formats/ProVideoFormats.pkg /tmp/ProVideoFormats
rm -rf /tmp/ProVideoFormats/MXFPlugIns.pkg/Scripts/*
echo '#!/bin/bash' > /tmp/ProVideoFormats/MXFPlugIns.pkg/Scripts/postinstall
echo 'touch /Library/Apple/sip_bypass' >> /tmp/ProVideoFormats/MXFPlugIns.pkg/Scripts/postinstall
chmod +x /tmp/ProVideoFormats/MXFPlugIns.pkg/Scripts/postinstall
次に、スクリプトsubpathコンポーネントのoffset値に対応するため、offset値の要求が満たされるまで新しいPKGファイルを構築し続ける「Pythonスクリプト」を作成しました。
while True:
os.system('pkgutil --flatten /tmp/ProVideoFormats /tmp/ProVideoFormats.fake.pkg')
f=open('/tmp/ProVideoFormats.fake.pkg', 'rb')
f.seek(scriptsOffsetInPkg) # the offset value from the original PKG
if f.read(4)=='\x1f\x8b\x08\x00': break
f.close()
PKGファイルの準備が整った後、次の手順で脆弱性を検証しました。
- post-install(ポストインストール)スクリプトを含むApple社の署名入りPKGファイルをインストールします。
- 「system_installd」デーモンサービスがインストール要求を処理します。
- 以下の関数において、PKG ファイルは 8 行目から16 行目の間で新たに作成されたものに置き換わります。
[PKLeopardPackage scriptsExtractorWithDestination:error:]
- 作成されたPKGファイル内の不正なスクリプトを抽出するために、サービスはAPI「BOMCopierCopyWithOptions」を呼び出します。そして、PKGファイルはオリジナルなものに復元されます。
- 抽出された不正なスクリプトは、「system_installd」によりroot権限を用いてSIPバイパス・コンテキストで実行されます。
macOS (Ventura)におけるApple社の新しいパッチ
macOS(Ventura)においてApple社は以下の手順を用いて、この脆弱性に対応するパッチを再適用しました。
まず、新しいパッチコードはXAR ポインタを介してPKG ファイルのsubpathのchecksumプロパティを取得します。これは、API「xar_open_digest_verify」が戻されたものです。
次に、inputFDから直接読み込む代わりにObjC class「IASInputStream」のインスタンスを使用してinputStreamを読み込みます。抽出中は、同時に inputStream のdigestも更新します。
抽出後、inputStreamの実際のchecksumが期待値と等しいか確認します。もし等しい場合にはインストールを続行します。そうでない場合にはプロセスを中断します。
トレンドマイクロは、インストールする前に PKG ファイルを安全な場所にコピーすることが最善策であると考えます。Apple社署名のパッケージは、SIPにより保護された場所にコピーし、その他のパッケージはroot権限下においてコピーします。
被害に遭わないためには
Apple社は、この脆弱性に対するパッチを発行し2022年にmacOS (Ventura)における対応に成功しました。OSのアップデートを怠ったユーザは、root権限昇格、シグネチャバイパス、及びSIPバイパスの脆弱性による影響を受ける可能性があります。システムを安全に保つために、全てのアップデートをインストールすることが不可欠となります。
エンドユーザは、Trend Micro Apex One™ (Mac) などのセキュリティソリューションにより、エンドポイントに対する攻撃を検知・ブロックすることが可能となります。
参考記事
「CVE-2019-8561: A Hard-to-Banish PackageKit Framework Vulnerability in macOS」
By: Mickey Jin
翻訳:新井 智士(Core Technology Marketing, Trend Micro™ Research)