macOS and OS X use a common method to look for required dynamic libraries (dylib) to load into a program based on search paths. Adversaries can take advantage of ambiguous paths to plant dylibs to gain privilege escalation or persistence.
A common method is to see what dylibs an application uses, then plant a malicious version with the same name higher up in the search path. This typically results in the dylib being in the same folder as the application itself. (Citation: Writing Bad Malware for OSX) (Citation: Malware Persistence on OS X)
If the program is configured to run at a higher privilege level than the current user, then when the dylib is loaded into the application, the dylib will also run at that elevated level. This can be used by adversaries as a privilege escalation technique.
T1157は「Dylib Hijacking(Dylibハイジャック)」として定義されていた、macOS / OS X環境に特化した極めて強力なコード実行・潜伏手法です。
macOSのアプリケーションが起動する際、必要となる動的ライブラリ(.dylib)を読み込む検索経路の仕様(曖昧さ)を悪用し、正規のライブラリの代わりにマルウェアのコードを強制的に読み込ませる手法です。主に「永続化(Persistence)」と「特権昇格(Privilege Escalation)」、そして「防御回避(Defense Evasion)」を狙って使用されます。
Windowsにおける「DLL(Dynamic Link Library)」にあたるものが、macOSにおける dylib(Dynamic Library) です。
macOSのアプリは起動する際、プログラムに必要な共通機能を外部の .dylib ファイルからロードして使用します。この読み込み処理を管理するのがOSの動的リンクエディタである dyld です。
macOSのアプリは通常、内部に「どこにdylibを探しに行くか」という検索パス(@rpath や @executable_path など)を持っています。攻撃者はこのパスの指定方法にある弱みを突きます。
主に以下の2つのパターンでハイジャックが行われます。
アプリの設計上、ロードしようとするdylibの場所が絶対パスで固定されておらず、複数の候補フォルダ(検索パス)を順番に探しに行く設定(Runpath Dependent Dylibs)になっている場合があります。
攻撃の手順:
アプリが正規のフォルダ(例: システム領域)に探しに行く「より手前」の検索フォルダ(例: ユーザーが書き込み可能なアプリパッケージ内など)に、**同じ名前を騙った悪意ある .dylib** を先回りして配置します。
結果:
アプリは正規のファイルに到達する前に、攻撃者が置いた偽のdylibを先に読み込んで実行してしまいます。
開発者の設定ミスなどで、アプリの内部コードに「読み込むべきdylib」として登録されているにもかかわらず、実際にはシステム上に存在しない(または過去のバージョンアップで削除された)dylibが存在することがあります。
攻撃の手順:
アプリが「存在しないdylib」を探しに行くパスの場所に、攻撃者がその名前の通りにマルウェアdylibを設置します。
結果:
アプリはエラーで落ちることなく、設置されたマルウェアをそのままプロセス内にロードします。
この攻撃を仕掛けるため、攻撃者は事前にターゲットとなるフォルダ(アプリのパッケージ内やユーザーディレクトリなど)への書き込み権限を得ている必要があります。
標的アプリの選定:
攻撃者は脆弱な検索パスを持つ、または欠落したdylibを要求する正規のアプリケーション(例: Xcode、Adobe製品、Office for Macなど)を特定します。
悪意あるDylibの配置:
アプリが起動時に参照する予定のパスに、不正なコード(バックドアを仕込むなど)を埋め込んだカスタム .dylib を配置します。
ユーザーのアプリ起動(トリガー):
ユーザーが業務などでその正規アプリケーションをいつも通りダブルクリックして起動します。
コード実行:
アプリのプロセス(dyld)が攻撃者のdylibを自動的にロードします。マルウェアは「その正規アプリのプロセス内部」に溶け込んだ状態(インジェクション)で、バックグラウンドで隠密に実行されます。
macOSの標準的なセキュリティ機能の活用と、適切なコード署名が最大の防御になります。
修復(Forwarding)の実装確認:
安全なdylibハイジャック対策として、アプリ開発者は @rpath を使用する際、必ず絶対パスやOSが提供する安全なマクロ(@loader_path)のみを適切に使用し、検索経路に曖昧さを残さないようにコードをビルドする必要があります。
Gatekeeperとコード署名(Code Signing)の強制:
macOSの保護機能であるGatekeeperは、アプリやその構成コンポーネントのデジタル署名を検証します。改ざんされた、または署名のないdylibがアプリパッケージ内に混入した場合、OSレベルで起動をブロックするように設定します。
Hardened Runtimeの有効化:
macOSのモダンなセキュリティ機能である「Hardened Runtime(強化された実行環境)」を有効にしてアプリをビルド・実行することで、サードパーティや外部からの不審なライブラリの動的インジェクションをOSが自動的に拒否します。
ESF(Endpoint Security Framework)による監視:
ログ監視において、信頼された正規プロセス(例: Safari や Slack など)が、普段読み込まない不審なディレクトリ(~/Library/Caches/ や /tmp/ など)から .dylib ファイルをロードしていないかをEDR等で検知・遮断します。
「信頼されたプロセス」への寄生:
悪意あるコードは、Appleや大手ベンダーによって署名された「正規の信頼できるアプリ」の権限とプロセス名を使って動きます。そのため、パーソナルファイアウォールなどの「〇〇アプリの外部通信を許可する」といったルールをそのまま悪用して、外のC2サーバーと通信(防御回避)することができます。
技術レベルの高さ:
WindowsのDLL検索順序のハイジャック(DLL Search Order Hijacking - T1574.001)と概念は全く同じですが、macOS独自のマッハ・オー(Mach-O)バイナリ形式やライブラリロード機構を理解する必要があるため、標的型攻撃や高度なMac向けマルウェア(MacMaやOceanLotus等)で特に見られる手法です。
macOSのインシデント調査において、怪しい常駐バイナリ(.app やスタンドアロンの実行ファイル)がどこにも見当たらないのに、特定の正規ツールを立ち上げた時だけ不審なビーコニング(外部通信)が発生する場合は、この T1157 / T1574.004 を疑うべきです。
macOS のターミナルで otool -L [アプリのパス] や otool -l [アプリのパス] | grep LC_RPATH コマンドを実行することで、そのアプリがどのような検索パス(@rpath)を持っているかを解析し、仕込まれた偽のdylibを特定することが可能です。