macOS Process Abuse
Last updated
Last updated
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
プロセスは実行中の実行可能ファイルのインスタンスですが、プロセスはコードを実行しません。これらはスレッドです。したがって、プロセスは実行中のスレッドのためのコンテナに過ぎません。メモリ、ディスクリプタ、ポート、権限を提供します...
従来、プロセスは**fork
を呼び出すことによって他のプロセス内で開始されました(PID 1を除く)。これにより、現在のプロセスの正確なコピーが作成され、その後子プロセスは一般的にexecve
を呼び出して新しい実行可能ファイルをロードして実行します。その後、vfork
が導入され、このプロセスをメモリコピーなしで高速化しました。
次に、posix_spawn
が導入され、vfork
とexecve
**を1回の呼び出しで組み合わせ、フラグを受け入れます:
POSIX_SPAWN_RESETIDS
: 有効なIDを実際のIDにリセット
POSIX_SPAWN_SETPGROUP
: プロセスグループの所属を設定
POSUX_SPAWN_SETSIGDEF
: シグナルのデフォルト動作を設定
POSIX_SPAWN_SETSIGMASK
: シグナルマスクを設定
POSIX_SPAWN_SETEXEC
: 同じプロセスでexec(execve
のように、より多くのオプションを持つ)
POSIX_SPAWN_START_SUSPENDED
: サスペンド状態で開始
_POSIX_SPAWN_DISABLE_ASLR
: ASLRなしで開始
_POSIX_SPAWN_NANO_ALLOCATOR:
libmallocのナノアロケータを使用
_POSIX_SPAWN_ALLOW_DATA_EXEC:
データセグメントでrwx
を許可
POSIX_SPAWN_CLOEXEC_DEFAULT
: exec(2)でデフォルトで全てのファイル記述子を閉じる
_POSIX_SPAWN_HIGH_BITS_ASLR:
ASLRスライドの高位ビットをランダム化
さらに、posix_spawn
は、生成されたプロセスのいくつかの側面を制御する**posix_spawnattr
の配列を指定することを許可し、ディスクリプタの状態を変更するためのposix_spawn_file_actions
**を提供します。
プロセスが終了すると、親プロセスに戻りコードを送信します(親が終了した場合、新しい親はPID 1です)し、シグナルSIGCHLD
を送信します。親はこの値を取得する必要があり、wait4()
またはwaitid()
を呼び出し、その間、子プロセスはゾンビ状態に留まり、リストに表示されますが、リソースを消費しません。
PIDはプロセス識別子で、ユニークなプロセスを識別します。XNUでは、PIDは64ビットで、単調に増加し、決してラップしません(悪用を避けるため)。
プロセスはグループに挿入され、管理を容易にします。たとえば、シェルスクリプト内のコマンドは同じプロセスグループにあり、killを使用して一緒にシグナルを送信することが可能です。
プロセスをセッションにグループ化することも可能です。プロセスがセッションを開始すると(setsid(2)
)、子プロセスはセッション内に設定されますが、独自のセッションを開始しない限り、そうなります。
コアリションは、Darwinでプロセスをグループ化する別の方法です。コアリションに参加するプロセスは、プールリソースにアクセスでき、台帳を共有したり、Jetsamに直面したりします。コアリションには異なる役割があります:リーダー、XPCサービス、拡張。
各プロセスは、システム内の権限を識別するための資格情報を保持します。各プロセスには1つの主要なuid
と1つの主要なgid
があります(ただし、複数のグループに属する可能性があります)。
バイナリがsetuid/setgid
ビットを持っている場合、ユーザーIDとグループIDを変更することも可能です。
新しいuid/gidを設定するための関数がいくつかあります。
システムコール**persona
は、代替の資格情報のセットを提供します。ペルソナを採用すると、そのuid、gid、およびグループメンバーシップを一度に**引き受けます。ソースコードには、次の構造体が見つかります:
POSIXスレッド(pthreads): macOSはPOSIXスレッド(pthreads
)をサポートしており、これはC/C++の標準スレッドAPIの一部です。macOSにおけるpthreadsの実装は/usr/lib/system/libsystem_pthread.dylib
にあり、これは公開されているlibpthread
プロジェクトから来ています。このライブラリはスレッドを作成し管理するために必要な関数を提供します。
スレッドの作成: pthread_create()
関数は新しいスレッドを作成するために使用されます。内部的に、この関数はXNUカーネル(macOSが基づいているカーネル)特有の低レベルのシステムコールであるbsdthread_create()
を呼び出します。このシステムコールは、スレッドの動作を指定するpthread_attr
(属性)から派生したさまざまなフラグを受け取ります。これにはスケジューリングポリシーやスタックサイズが含まれます。
デフォルトスタックサイズ: 新しいスレッドのデフォルトスタックサイズは512 KBで、通常の操作には十分ですが、必要に応じてスレッド属性を介して調整できます。
スレッドの初期化: __pthread_init()
関数はスレッドのセットアップ中に重要で、env[]
引数を利用してスタックの位置やサイズに関する詳細を含む環境変数を解析します。
スレッドの終了: スレッドは通常、pthread_exit()
を呼び出すことで終了します。この関数はスレッドがクリーンに終了し、必要なクリーンアップを行い、スレッドが参加者に戻り値を送信できるようにします。
スレッドのクリーンアップ: pthread_exit()
を呼び出すと、pthread_terminate()
関数が呼び出され、すべての関連スレッド構造の削除を処理します。これによりMachスレッドポートが解放され(MachはXNUカーネルの通信サブシステム)、スレッドに関連するカーネルレベルの構造を削除するシステムコールbsdthread_terminate
が呼び出されます。
共有リソースへのアクセスを管理し、競合状態を避けるために、macOSはいくつかの同期プリミティブを提供します。これらはマルチスレッド環境においてデータの整合性とシステムの安定性を確保するために重要です:
ミューテックス:
通常のミューテックス(シグネチャ:0x4D555458): メモリフットプリントが60バイト(ミューテックス56バイト、シグネチャ4バイト)の標準ミューテックス。
ファストミューテックス(シグネチャ:0x4d55545A): 通常のミューテックスに似ていますが、より高速な操作のために最適化されており、サイズは60バイトです。
条件変数:
特定の条件が発生するのを待つために使用され、サイズは44バイト(40バイトプラス4バイトのシグネチャ)。
条件変数属性(シグネチャ:0x434e4441): 条件変数の設定属性で、サイズは12バイトです。
ワンス変数(シグネチャ:0x4f4e4345):
初期化コードが一度だけ実行されることを保証します。サイズは12バイトです。
読み書きロック:
同時に複数のリーダーまたは1つのライターを許可し、共有データへの効率的なアクセスを促進します。
読み書きロック(シグネチャ:0x52574c4b): サイズは196バイトです。
読み書きロック属性(シグネチャ:0x52574c41): 読み書きロックの属性で、サイズは20バイトです。
これらのオブジェクトの最後の4バイトはオーバーフローを検出するために使用されます。
スレッドローカル変数(TLV)は、Mach-Oファイル(macOSの実行可能ファイルの形式)の文脈で、マルチスレッドアプリケーション内の各スレッドに特有の変数を宣言するために使用されます。これにより、各スレッドが変数の独自のインスタンスを持ち、ミューテックスのような明示的な同期メカニズムを必要とせずに競合を回避し、データの整合性を維持する方法が提供されます。
Cおよび関連言語では、**__thread
**キーワードを使用してスレッドローカル変数を宣言できます。以下は、あなたの例での動作方法です:
このスニペットは tlv_var
をスレッドローカル変数として定義します。このコードを実行している各スレッドは独自の tlv_var
を持ち、あるスレッドが tlv_var
に加えた変更は他のスレッドの tlv_var
に影響を与えません。
Mach-O バイナリでは、スレッドローカル変数に関連するデータは特定のセクションに整理されています:
__DATA.__thread_vars
: このセクションには、スレッドローカル変数に関するメタデータが含まれており、変数の型や初期化状態などが記載されています。
__DATA.__thread_bss
: このセクションは、明示的に初期化されていないスレッドローカル変数に使用されます。ゼロ初期化データのために確保されたメモリの一部です。
Mach-O は、スレッドが終了する際にスレッドローカル変数を管理するための特定の API tlv_atexit
も提供しています。この API を使用すると、スレッドが終了する際にスレッドローカルデータをクリーンアップする特別な関数である デストラクタを登録 できます。
スレッドの優先順位を理解するには、オペレーティングシステムがどのスレッドをいつ実行するかを決定する方法を見ていく必要があります。この決定は、各スレッドに割り当てられた優先度レベルによって影響を受けます。macOS および Unix 系システムでは、これを nice
、renice
、および Quality of Service (QoS) クラスのような概念を使用して処理します。
Nice:
プロセスの nice
値は、その優先度に影響を与える数値です。すべてのプロセスには -20(最高優先度)から 19(最低優先度)までの範囲の nice 値があります。プロセスが作成されるときのデフォルトの nice 値は通常 0 です。
より低い nice 値(-20 に近い)は、プロセスをより「自己中心的」にし、他のプロセスよりも多くの CPU 時間を与えます。
Renice:
renice
は、すでに実行中のプロセスの nice 値を変更するために使用されるコマンドです。これを使用して、プロセスの優先度を動的に調整し、新しい nice 値に基づいて CPU 時間の割り当てを増減させることができます。
たとえば、プロセスが一時的により多くの CPU リソースを必要とする場合、renice
を使用してその nice 値を下げることができます。
QoS クラスは、特に Grand Central Dispatch (GCD) をサポートする macOS のようなシステムでスレッドの優先順位を処理するためのより現代的なアプローチです。QoS クラスを使用すると、開発者は作業をその重要性や緊急性に基づいて異なるレベルに 分類 できます。macOS はこれらの QoS クラスに基づいてスレッドの優先順位を自動的に管理します:
ユーザーインタラクティブ:
このクラスは、現在ユーザーと対話しているタスクや、良好なユーザーエクスペリエンスを提供するために即時の結果を必要とするタスクに使用されます。これらのタスクは、インターフェースを応答性のあるものに保つために最高の優先度が与えられます(例:アニメーションやイベント処理)。
ユーザー開始:
ユーザーが開始し、即時の結果を期待するタスク(例:ドキュメントを開く、計算を必要とするボタンをクリックするなど)。これらは高優先度ですが、ユーザーインタラクティブよりは低いです。
ユーティリティ:
これらのタスクは長時間実行され、通常は進行状況インジケーターを表示します(例:ファイルのダウンロード、データのインポート)。これらはユーザー開始タスクよりも優先度が低く、即座に終了する必要はありません。
バックグラウンド:
このクラスは、バックグラウンドで動作し、ユーザーには見えないタスクに使用されます。これには、インデックス作成、同期、バックアップなどのタスクが含まれます。これらは最低の優先度を持ち、システムパフォーマンスに与える影響は最小限です。
QoS クラスを使用することで、開発者は正確な優先度番号を管理する必要がなく、タスクの性質に焦点を当てることができ、システムはそれに応じて CPU リソースを最適化します。
さらに、スレッドスケジューリングポリシーが異なり、スケジューラが考慮するスケジューリングパラメータのセットを指定することができます。これは thread_policy_[set/get]
を使用して行うことができます。これはレースコンディション攻撃に役立つかもしれません。
MacOS は、他のオペレーティングシステムと同様に、プロセスが相互作用し、通信し、データを共有するためのさまざまな方法とメカニズムを提供します。これらの技術は効率的なシステム機能に不可欠ですが、脅威アクターによって 悪意のある活動を行うために悪用される可能性もあります。
ライブラリインジェクションは、攻撃者が プロセスに悪意のあるライブラリをロードさせる 技術です。一度注入されると、ライブラリはターゲットプロセスのコンテキストで実行され、攻撃者にプロセスと同じ権限とアクセスを提供します。
macOS Library Injection関数フッキングは、ソフトウェアコード内の 関数呼び出し やメッセージを 傍受する ことを含みます。関数をフックすることで、攻撃者はプロセスの 動作を変更 したり、機密データを観察したり、実行フローを制御したりすることができます。
macOS Function Hookingプロセス間通信 (IPC) は、別々のプロセスが データを共有し、交換する 方法を指します。IPC は多くの正当なアプリケーションにとって基本的ですが、プロセスの分離を覆したり、機密情報を漏洩させたり、無許可のアクションを実行するために悪用される可能性もあります。
macOS IPC - Inter Process Communication特定の環境変数で実行される Electron アプリケーションは、プロセスインジェクションに対して脆弱である可能性があります:
macOS Electron Applications Injection--load-extension
および --use-fake-ui-for-media-stream
フラグを使用して ブラウザ内の攻撃 を実行し、キー入力、トラフィック、クッキーを盗んだり、ページにスクリプトを注入したりすることが可能です:
NIB ファイルは ユーザーインターフェース (UI) 要素 とその相互作用をアプリケーション内で定義します。しかし、これらは 任意のコマンドを実行することができ、NIB ファイルが変更されても すでに実行されたアプリケーションの実行を Gatekeeper は停止しません。したがって、任意のプログラムが任意のコマンドを実行するために使用される可能性があります:
macOS Dirty NIB特定の Java 機能(_JAVA_OPTS
環境変数など)を悪用して、Java アプリケーションが 任意のコード/コマンドを実行する ことが可能です。
.Net デバッグ機能を悪用することによって コードを .Net アプリケーションに注入することが可能です(macOS の保護(ランタイムハードニングなど)によって保護されていません)。
macOS .Net Applications Injection任意のコードを実行するための Perl スクリプトを実行するさまざまなオプションを確認してください:
macOS Perl Applications InjectionRuby 環境変数を悪用して、任意のスクリプトが任意のコードを実行することも可能です:
macOS Ruby Applications Injection環境変数 PYTHONINSPECT
が設定されている場合、Python プロセスは終了後に Python CLI にドロップします。また、PYTHONSTARTUP
を使用して、インタラクティブセッションの開始時に実行する Python スクリプトを指定することも可能です。
ただし、PYTHONINSPECT
がインタラクティブセッションを作成する際には PYTHONSTARTUP
スクリプトは実行されません。
他の環境変数(PYTHONPATH
や PYTHONHOME
など)も、Python コマンドが任意のコードを実行するのに役立つ可能性があります。
pyinstaller
でコンパイルされた実行可能ファイルは、埋め込まれた Python を使用して実行されていても、これらの環境変数を使用しないことに注意してください。
全体として、環境変数を悪用して Python が任意のコードを実行する方法を見つけることができませんでした。 ただし、ほとんどの人は Hombrew を使用して Python をインストールし、デフォルトの管理者ユーザーのために 書き込み可能な場所 に Python をインストールします。これを次のようにハイジャックできます:
Even root will run this code when running python.
Shield (Github) は、プロセスインジェクションアクションを検出しブロックできるオープンソースアプリケーションです:
環境変数を使用:次の環境変数のいずれかの存在を監視します:DYLD_INSERT_LIBRARIES
、CFNETWORK_LIBRARY_PATH
、RAWCAMERA_BUNDLE_PATH
、および ELECTRON_RUN_AS_NODE
task_for_pid
呼び出しを使用:あるプロセスが別のプロセスのタスクポートを取得しようとする際を見つけるため。
Electronアプリのパラメータ:誰かが**--inspect
、--inspect-brk
**、および --remote-debugging-port
コマンドライン引数を使用して、デバッグモードでElectronアプリを起動し、コードを注入することができます。
シンボリックリンクまたはハードリンクを使用:一般的な悪用は、ユーザー権限でリンクを作成し、より高い権限の場所を指すことです。リンクを作成するプロセスがターゲットファイルとは異なる権限レベルを持っている場合、アラートを作成します。残念ながら、シンボリックリンクの場合は、作成前にリンクの宛先に関する情報がないため、ブロックは不可能です。これはAppleのEndpointSecurityフレームワークの制限です。
このブログ記事では、task_name_for_pid
関数を使用して、他のプロセスがプロセスにコードを注入している情報を取得し、その他のプロセスに関する情報を取得する方法を見つけることができます。
その関数を呼び出すには、プロセスを実行しているのと同じuidであるか、rootである必要があります(そして、プロセスに関する情報を返しますが、コードを注入する方法ではありません)。
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)