macOS アプリ - 検査、デバッグ、ファジング
Tip
AWSハッキングを学び、実践する:
HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE)
Azureハッキングを学び、実践する:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricksをサポートする
- サブスクリプションプランを確認してください!
- **💬 Discordグループまたはテレグラムグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- HackTricksおよびHackTricks CloudのGitHubリポジトリにPRを提出してハッキングトリックを共有してください。
静的解析
otool & objdump & nm
otool -L /bin/ls #List dynamically linked libraries
otool -tv /bin/ps #Decompile application
objdump -m --dylibs-used /bin/ls #List dynamically linked libraries
objdump -m -h /bin/ls # Get headers information
objdump -m --syms /bin/ls # Check if the symbol table exists to get function names
objdump -m --full-contents /bin/ls # Dump every section
objdump -d /bin/ls # Dissasemble the binary
objdump --disassemble-symbols=_hello --x86-asm-syntax=intel toolsdemo #Disassemble a function using intel flavour
nm -m ./tccd # List of symbols
jtool2 & Disarm
You can download disarm from here.
ARCH=arm64e disarm -c -i -I --signature /path/bin # Get bin info and signature
ARCH=arm64e disarm -c -l /path/bin # Get binary sections
ARCH=arm64e disarm -c -L /path/bin # Get binary commands (dependencies included)
ARCH=arm64e disarm -c -S /path/bin # Get symbols (func names, strings...)
ARCH=arm64e disarm -c -d /path/bin # Get disasembled
jtool2 -d __DATA.__const myipc_server | grep MIG # Get MIG info
ここからjtool2をダウンロードするか、brewを使ってインストールできます。
# Install
brew install --cask jtool2
jtool2 -l /bin/ls # Get commands (headers)
jtool2 -L /bin/ls # Get libraries
jtool2 -S /bin/ls # Get symbol info
jtool2 -d /bin/ls # Dump binary
jtool2 -D /bin/ls # Decompile binary
# Get signature information
ARCH=x86_64 jtool2 --sig /System/Applications/Automator.app/Contents/MacOS/Automator
# Get MIG information
jtool2 -d __DATA.__const myipc_server | grep MIG
[!CAUTION] > jtoolはdisarmに取って代わられました
Codesign / ldid
[!TIP] >
CodesignはmacOSにあり、ldidはiOSにあります
# 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
# Get signature info
ldid -h <binary>
# Get entitlements
ldid -e <binary>
# Change entilements
## /tmp/entl.xml is a XML file with the new entitlements to add
ldid -S/tmp/entl.xml <binary>
SuspiciousPackage
SuspiciousPackage は、.pkg ファイル(インストーラー)を検査し、インストールする前にその内容を確認するのに役立つツールです。
これらのインストーラーには、マルウェア作成者が通常悪用する preinstall および postinstall bash スクリプトが含まれています。
hdiutil
このツールは、Apple のディスクイメージ(.dmg)ファイルをマウントして、何かを実行する前にそれらを検査することを可能にします:
hdiutil attach ~/Downloads/Firefox\ 58.0.2.dmg
It will be mounted in /Volumes
Packed binaries
- 高エントロピーをチェック
- 文字列をチェック(理解できる文字列がほとんどない場合、パックされている)
- MacOS用のUPXパッカーは、“__XHDR“というセクションを生成します。
Static Objective-C analysis
Metadata
Caution
Objective-Cで書かれたプログラムは、Mach-O binariesにコンパイルされるときにクラス宣言を保持します。そのようなクラス宣言には以下が含まれます:
- 定義されたインターフェース
- インターフェースメソッド
- インターフェースインスタンス変数
- 定義されたプロトコル
これらの名前は、バイナリのリバースエンジニアリングをより困難にするために難読化される可能性があります。
Function calling
Objective-Cを使用するバイナリで関数が呼び出されると、コンパイルされたコードはその関数を呼び出すのではなく、**objc_msgSend**を呼び出します。これが最終的な関数を呼び出します:
.png)
この関数が期待するパラメータは次のとおりです:
- 最初のパラメータ(self)は「メッセージを受け取るクラスのインスタンスを指すポインタ」です。簡単に言えば、メソッドが呼び出されるオブジェクトです。メソッドがクラスメソッドの場合、これはクラスオブジェクトのインスタンス(全体)になりますが、インスタンスメソッドの場合、selfはクラスのインスタンス化されたオブジェクトを指します。
- 2番目のパラメータ(op)は「メッセージを処理するメソッドのセレクタ」です。再度、簡単に言えば、これはメソッドの名前です。
- 残りのパラメータは、メソッド(op)によって必要とされる値です。
この情報をARM64でlldbを使って簡単に取得する方法をこのページで確認してください:
x64:
| Argument | Register | (for) objc_msgSend |
|---|---|---|
| 1st argument | rdi | self: object that the method is being invoked upon |
| 2nd argument | rsi | op: name of the method |
| 3rd argument | rdx | 1st argument to the method |
| 4th argument | rcx | 2nd argument to the method |
| 5th argument | r8 | 3rd argument to the method |
| 6th argument | r9 | 4th argument to the method |
| 7th+ argument |
rsp+ | 5th+ argument to the method |
Dump ObjectiveC metadata
Dynadump
Dynadumpは、Objective-Cバイナリをクラスダンプするためのツールです。GitHubではdylibsが指定されていますが、実行可能ファイルでも機能します。
./dynadump dump /path/to/bin
執筆時点では、これは現在最も効果的なものです。
一般的なツール
nm --dyldinfo-only /path/to/bin
otool -ov /path/to/bin
objdump --macho --objc-meta-data /path/to/bin
class-dump
class-dump は、ObjectiveC形式のコード内のクラス、カテゴリ、およびプロトコルの宣言を生成するための元のツールです。
古くてメンテナンスされていないため、正しく動作しない可能性があります。
ICDump
iCDump は、モダンでクロスプラットフォームのObjective-Cクラスダンプです。既存のツールと比較して、iCDumpはAppleエコシステムから独立して実行でき、Pythonバインディングを公開しています。
import icdump
metadata = icdump.objc.parse("/path/to/bin")
print(metadata.to_decl())
Static Swift analysis
Swiftバイナリでは、Objective-Cとの互換性があるため、時々class-dumpを使用して宣言を抽出できますが、常に可能というわけではありません。
**jtool -lまたはotool -lコマンドラインを使用すると、__swift5**プレフィックスで始まるいくつかのセクションを見つけることができます:
jtool2 -l /Applications/Stocks.app/Contents/MacOS/Stocks
LC 00: LC_SEGMENT_64 Mem: 0x000000000-0x100000000 __PAGEZERO
LC 01: LC_SEGMENT_64 Mem: 0x100000000-0x100028000 __TEXT
[...]
Mem: 0x100026630-0x100026d54 __TEXT.__swift5_typeref
Mem: 0x100026d60-0x100027061 __TEXT.__swift5_reflstr
Mem: 0x100027064-0x1000274cc __TEXT.__swift5_fieldmd
Mem: 0x1000274cc-0x100027608 __TEXT.__swift5_capture
[...]
これらのセクションに保存されている情報についての詳細は、このブログ投稿で見つけることができます。
さらに、Swiftバイナリにはシンボルが含まれている可能性があります(例えば、ライブラリはその関数を呼び出すためにシンボルを保存する必要があります)。シンボルには通常、関数名と属性に関する情報が含まれていますが、見栄えが悪いため非常に便利であり、元の名前を取得できる「デマンガラー」があります。
# Ghidra plugin
https://github.com/ghidraninja/ghidra_scripts/blob/master/swift_demangler.py
# Swift cli
swift demangle
ダイナミック分析
Warning
バイナリをデバッグするには、SIPを無効にする必要があります(
csrutil disableまたはcsrutil enable --without debug)またはバイナリを一時フォルダにコピーし、codesign --remove-signature <binary-path>で署名を削除するか、バイナリのデバッグを許可する必要があります(このスクリプトを使用できます)。
Warning
macOSでシステムバイナリ(例えば
cloudconfigurationd)をインスツルメントするには、SIPを無効にする必要があります(署名を削除するだけでは機能しません)。
APIs
macOSはプロセスに関する情報を提供するいくつかの興味深いAPIを公開しています:
proc_info: 各プロセスに関する多くの情報を提供する主要なAPIです。他のプロセスの情報を取得するにはroot権限が必要ですが、特別な権限やmachポートは必要ありません。libsysmon.dylib: XPCで公開された関数を介してプロセスに関する情報を取得することを可能にしますが、com.apple.sysmond.clientの権限が必要です。
Stackshot & microstackshots
Stackshottingは、プロセスの状態をキャプチャするために使用される技術で、すべての実行中のスレッドのコールスタックを含みます。これは、デバッグ、パフォーマンス分析、特定の時点でのシステムの動作を理解するために特に便利です。iOSおよびmacOSでは、**sampleやspindump**などのツールや方法を使用してstackshottingを実行できます。
Sysdiagnose
このツール(/usr/bini/ysdiagnose)は、ps、zprintなどの異なるコマンドを実行してコンピュータから多くの情報を収集します。
rootとして実行する必要があり、デーモン/usr/libexec/sysdiagnosedは、com.apple.system-task-portsやget-task-allowなどの非常に興味深い権限を持っています。
そのplistは/System/Library/LaunchDaemons/com.apple.sysdiagnose.plistにあり、3つのMachServicesを宣言しています:
com.apple.sysdiagnose.CacheDelete: /var/rmp内の古いアーカイブを削除しますcom.apple.sysdiagnose.kernel.ipc: 特殊ポート23(カーネル)com.apple.sysdiagnose.service.xpc:LibsysdiagnoseObj-Cクラスを介したユーザーモードインターフェース。辞書内に3つの引数(compress、display、run)を渡すことができます。
統合ログ
MacOSは、アプリケーションを実行して何をしているのかを理解する際に非常に役立つ多くのログを生成します。
さらに、いくつかのログには<private>タグが含まれ、ユーザーまたはコンピュータの識別可能な情報を隠すために使用されます。ただし、この情報を開示するための証明書をインストールすることが可能です。詳細はこちらを参照してください。
Hopper
左パネル
Hopperの左パネルでは、バイナリのシンボル(Labels)、手続きと関数のリスト(Proc)、および文字列(Str)を見ることができます。これらはすべての文字列ではなく、Mac-Oファイルのいくつかの部分(_cstringやobjc_methnameなど)で定義されたものです。
中央パネル
中央パネルでは、逆アセンブルされたコードを見ることができます。また、生の逆アセンブル、グラフ、デコンパイルされたもの、バイナリとしてそれぞれのアイコンをクリックすることで表示できます:
.png)
コードオブジェクトを右クリックすると、そのオブジェクトへの参照やそのオブジェクトからの参照を見ることができ、名前を変更することもできます(これはデコンパイルされた擬似コードでは機能しません):
.png)
さらに、中央下部ではPythonコマンドを入力することができます。
右パネル
右パネルでは、ナビゲーション履歴(現在の状況にどのように到達したかを知るため)、コールグラフ(この関数を呼び出すすべての関数と、この関数が呼び出すすべての関数を見ることができます)、およびローカル変数の情報など、興味深い情報を見ることができます。
dtrace
これは、ユーザーがアプリケーションに非常に低レベルでアクセスできるようにし、ユーザーがプログラムをトレースし、その実行フローを変更する方法を提供します。Dtraceは、カーネル全体に配置されたプローブを使用し、システムコールの開始と終了などの場所にあります。
DTraceは、各システムコールのプローブを作成するために**dtrace_probe_create関数を使用します。これらのプローブは、各システムコールのエントリポイントとエグジットポイント**で発火することができます。DTraceとのインタラクションは、/dev/dtraceを介して行われ、これはrootユーザーのみが利用可能です。
Tip
SIP保護を完全に無効にせずにDtraceを有効にするには、リカバリモードで次のコマンドを実行できます:
csrutil enable --without dtraceまた、
dtraceまたはdtrussのバイナリをコンパイルしたものを使用することもできます。
dtraceの利用可能なプローブは次のコマンドで取得できます:
dtrace -l | head
ID PROVIDER MODULE FUNCTION NAME
1 dtrace BEGIN
2 dtrace END
3 dtrace ERROR
43 profile profile-97
44 profile profile-199
プローブ名は、プロバイダー、モジュール、関数、および名前(fbt:mach_kernel:ptrace:entry)の4つの部分で構成されています。名前の一部を指定しない場合、Dtraceはその部分をワイルドカードとして適用します。
DTraceを構成してプローブをアクティブにし、発火したときに実行するアクションを指定するには、D言語を使用する必要があります。
より詳細な説明とさらに多くの例は、https://illumos.org/books/dtrace/chp-intro.htmlで見つけることができます。
例
man -k dtraceを実行して利用可能なDTraceスクリプトのリストを表示します。例: sudo dtruss -n binary
#Count the number of syscalls of each running process
sudo dtrace -n 'syscall:::entry {@[execname] = count()}'
- スクリプト
syscall:::entry
/pid == $1/
{
}
#Log every syscall of a PID
sudo dtrace -s script.d 1234
syscall::open:entry
{
printf("%s(%s)", probefunc, copyinstr(arg0));
}
syscall::close:entry
{
printf("%s(%d)\n", probefunc, arg0);
}
#Log files opened and closed by a process
sudo dtrace -s b.d -c "cat /etc/hosts"
syscall:::entry
{
;
}
syscall:::return
{
printf("=%d\n", arg1);
}
#Log sys calls with values
sudo dtrace -s syscalls_info.d -c "cat /etc/hosts"
dtruss
dtruss -c ls #Get syscalls of ls
dtruss -c -p 1000 #get syscalls of PID 1000
kdebug
これはカーネルトレース機能です。文書化されたコードは**/usr/share/misc/trace.codes**にあります。
latency、sc_usage、fs_usage、およびtraceのようなツールは内部でこれを使用します。
kdebugとインターフェースするには、kern.kdebug名前空間を介してsysctlが使用され、使用するMIBはsys/sysctl.hにあり、関数はbsd/kern/kdebug.cに実装されています。
カスタムクライアントでkdebugと対話するための一般的な手順は次のとおりです:
- KERN_KDSETREMOVEで既存の設定を削除
- KERN_KDSETBUFおよびKERN_KDSETUPでトレースを設定
- KERN_KDGETBUFを使用してバッファエントリの数を取得
- KERN_KDPINDEXでトレースから自分のクライアントを取得
- KERN_KDENABLEでトレースを有効化
- KERN_KDREADTRを呼び出してバッファを読み取る
- 各スレッドをそのプロセスにマッピングするにはKERN_KDTHRMAPを呼び出します。
この情報を取得するために、Appleのツール**trace**またはカスタムツールkDebugView (kdv)を使用することができます。
Kdebugは同時に1つの顧客にのみ利用可能であることに注意してください。 したがって、同時に実行できるk-debug対応ツールは1つだけです。
ktrace
ktrace_* APIはlibktrace.dylibから来ており、これがKdebugのラッパーです。クライアントはktrace_session_createとktrace_events_[single/class]を呼び出して特定のコードにコールバックを設定し、ktrace_startで開始できます。
SIPが有効になっていてもこれを使用できます。
クライアントとしてユーティリティktraceを使用できます:
ktrace trace -s -S -t c -c ls | grep "ls("
Or tailspin.
kperf
これはカーネルレベルのプロファイリングを行うために使用され、Kdebug コールアウトを使用して構築されています。
基本的に、グローバル変数 kernel_debug_active がチェックされ、設定されている場合は kperf_kdebug_handler を Kdebug コードとカーネルフレームのアドレスで呼び出します。Kdebug コードが選択されたものと一致する場合、ビットマップとして構成された「アクション」を取得します(オプションについては osfmk/kperf/action.h を確認してください)。
Kperf には sysctl MIB テーブルもあります:(root として)sysctl kperf。これらのコードは osfmk/kperf/kperfbsd.c にあります。
さらに、Kperf の機能のサブセットは kpc に存在し、マシンのパフォーマンスカウンタに関する情報を提供します。
ProcessMonitor
ProcessMonitor は、プロセスが実行しているプロセス関連のアクションを確認するための非常に便利なツールです(例えば、プロセスが作成している新しいプロセスを監視します)。
SpriteTree
SpriteTree は、プロセス間の関係を表示するツールです。sudo eslogger fork exec rename create > cap.json のようなコマンドで Mac を監視する必要があります(このターミナルを起動するには FDA が必要です)。その後、このツールに json を読み込んで、すべての関係を表示できます:
.png)
FileMonitor
FileMonitor は、ファイルイベント(作成、変更、削除など)を監視し、そのようなイベントに関する詳細情報を提供します。
Crescendo
Crescendo は、Windows ユーザーが Microsoft Sysinternal の Procmon から知っているかもしれないルックアンドフィールを持つ GUI ツールです。このツールは、さまざまなイベントタイプの記録を開始および停止でき、ファイル、プロセス、ネットワークなどのカテゴリによってこれらのイベントをフィルタリングでき、記録されたイベントを json 形式で保存する機能を提供します。
Apple Instruments
Apple Instruments は、アプリケーションのパフォーマンスを監視し、メモリリークを特定し、ファイルシステムのアクティビティを追跡するために使用される Xcode の開発者ツールの一部です。
.png)
fs_usage
プロセスによって実行されるアクションを追跡することができます:
fs_usage -w -f filesys ls #This tracks filesystem actions of proccess names containing ls
fs_usage -w -f network curl #This tracks network actions
TaskExplorer
Taskexplorer は、バイナリによって使用される ライブラリ、使用している ファイル、および ネットワーク 接続を確認するのに便利です。
また、バイナリプロセスを virustotal と照合し、バイナリに関する情報を表示します。
PT_DENY_ATTACH
このブログ記事 では、SIP が無効になっていてもデバッグを防ぐために PT_DENY_ATTACH を使用した 実行中のデーモンをデバッグする 方法の例を見つけることができます。
lldb
lldb は macOS バイナリ デバッグ のためのデファクトツールです。
lldb ./malware.bin
lldb -p 1122
lldb -n malware.bin
lldb -n malware.bin --waitfor
インテルフレーバーを設定するには、ホームフォルダーに**.lldbinit**というファイルを作成し、次の行を追加します:
settings set target.x86-disassembly-flavor intel
Warning
lldb内で、
process save-coreを使用してプロセスをダンプします。
| (lldb) コマンド | 説明 | ||||||||||||||||||||||
| run (r) | 実行を開始し、ブレークポイントがヒットするかプロセスが終了するまで継続します。 | ||||||||||||||||||||||
| process launch --stop-at-entry | エントリポイントで停止する実行を開始します。 | ||||||||||||||||||||||
| continue (c) | デバッグ中のプロセスの実行を続けます。 | ||||||||||||||||||||||
| nexti (n / ni) | 次の命令を実行します。このコマンドは関数呼び出しをスキップします。 | ||||||||||||||||||||||
| stepi (s / si) | 次の命令を実行します。nextiコマンドとは異なり、このコマンドは関数呼び出しに入ります。 | ||||||||||||||||||||||
| finish (f) | 現在の関数(“フレーム”)内の残りの命令を実行し、戻って停止します。 | ||||||||||||||||||||||
| control + c | 実行を一時停止します。プロセスが実行(r)または続行(c)されている場合、これによりプロセスは現在実行中の場所で停止します。 | ||||||||||||||||||||||
| breakpoint (b) |
breakpoint delete help breakpoint #ブレークポイントコマンドのヘルプを取得 help memory write #メモリへの書き込みのヘルプを取得 reg read reg read $rax reg read $rax --format <format> reg write $rip 0x100035cc0 これは、パラメータで参照されるオブジェクトを印刷します。 po $raw AppleのObjective-C APIやメソッドのほとんどはオブジェクトを返すため、"print object" (po) コマンドを使用して表示する必要があります。poが意味のある出力を生成しない場合は、 dis #現在の関数を逆アセンブル dis -n dis -n Tip コアダンプは次の場合に作成されます: これらの場合、コアダンプは ReportCrashはクラッシュしたプロセスを分析し、クラッシュレポートをディスクに保存します。クラッシュレポートには、開発者がクラッシュの原因を診断するのに役立つ情報が含まれています。 クラッシュレポートがAppleに送信されることを心配している場合は、それを無効にできます。そうでない場合、クラッシュレポートはサーバーがどのようにクラッシュしたかを把握するのに役立ちます。 MacOSでファジングを行う際は、Macがスリープしないようにすることが重要です: SSH接続を介してファジングを行う場合、セッションが切断されないようにすることが重要です。次のようにsshd_configファイルを変更してください: 次のページを確認してください どのアプリが 指定されたスキームまたはプロトコルを処理しているかを見つける方法を知るために: macOS File Extension & URL scheme app handlers これは、ネットワークデータを管理しているプロセスを見つけるのに興味深いです: または CLIツールに対応しています。 macOS GUIツールで「そのまま動作します」。いくつかのmacOSアプリには、ユニークなファイル名、正しい拡張子、サンドボックスからファイルを読み取る必要があるなど、特定の要件があります( いくつかの例: Tip AWSハッキングを学び、実践する: |
HackTricks


