hacktricks/macos-hardening/macos-security-and-privilege-escalation/macos-apps-inspecting-debugging-and-fuzzing
2023-07-07 23:42:27 +00:00
..
arm64-basic-assembly.md Translated to Japanese 2023-07-07 23:42:27 +00:00
README.md Translated to Japanese 2023-07-07 23:42:27 +00:00

macOSアプリ - 検査、デバッグ、およびFuzzing

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥

静的解析

otool

otool -L /bin/ls #List dynamically linked libraries
otool -tv /bin/ps #Decompile application

objdump

objdumpは、バイナリファイルの解析とデバッグに使用されるユーティリティです。このツールは、オブジェクトファイルや実行可能ファイルのセクション、シンボル、リロケーションエントリなどの情報を表示します。

使用法

objdump [オプション] <ファイル>

オプション

  • -d:逆アセンブルされたコードを表示します。
  • -t:シンボルテーブルを表示します。
  • -r:リロケーションエントリを表示します。
  • -s:セクションの内容を表示します。
  • -x:ヘッダ情報を表示します。

objdump -d binary

このコマンドは、binaryという名前のバイナリファイルの逆アセンブルされたコードを表示します。

注意事項

objdumpは、バイナリファイルの解析に使用されるため、慎重に使用する必要があります。不正な目的で使用しないようにしてください。

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

jtool2

このツールは、codesignotool、およびobjdump代替として使用することができ、いくつかの追加機能も提供します。

# 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

Codesign

Codesignコードサインは、macOSにおいてアプリケーションの信頼性とセキュリティを確保するための重要な手法です。Codesignは、アプリケーションが信頼できるソースから提供され、改ざんされていないことを確認するために使用されます。

Codesignによって、アプリケーションにはデジタル署名が付与されます。この署名には、アプリケーションの開発者や配布元の情報が含まれています。また、アプリケーションが改ざんされていないことを確認するためのチェックサムも含まれています。

Codesignによってアプリケーションが署名されると、macOSはそのアプリケーションを実行する際に署名を検証します。もし署名が有効でない場合、macOSはアプリケーションの実行をブロックします。

Codesignは、アプリケーションの信頼性を確保するだけでなく、プライバシーとセキュリティの向上にも役立ちます。署名されたアプリケーションは、システムの特権を要求することができますが、その際にはユーザーに対して警告が表示されます。

アプリケーションのCodesignを確認するには、ターミナルで以下のコマンドを実行します。

codesign -dv /path/to/application.app

このコマンドによって、アプリケーションの署名情報やチェックサムが表示されます。また、署名が有効であるかどうかも確認できます。

Codesignは、macOSアプリケーションのセキュリティを向上させるための重要な手法です。アプリケーションの署名を確認することで、信頼性のあるアプリケーションのみを実行することができます。

# Get signer
codesign -vv -d /bin/ls 2>&1 | grep -E "Authority|TeamIdentifier"

# Check if the apps 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

SuspiciousPackage

SuspiciousPackageは、インストールする前に**.pkg**ファイル(インストーラ)を検査し、中身を確認するのに役立つツールです。
これらのインストーラには、マルウェアの作者が通常悪用するpreinstallpostinstallのBashスクリプトが含まれています。

hdiutil

このツールは、Appleディスクイメージ.dmg)ファイルを実行する前に検査するためにマウントすることができます。

hdiutil attach ~/Downloads/Firefox\ 58.0.2.dmg

Objective-C

メタデータ

{% hint style="danger" %} Objective-Cで書かれたプログラムは、Mach-Oバイナリにコンパイルされるときに、クラスの宣言を保持します。このクラスの宣言には、以下の情報が含まれます: {% endhint %}

  • クラス
  • クラスメソッド
  • クラスのインスタンス変数

これらの情報は、class-dumpを使用して取得できます。

class-dump Kindle.app

関数の呼び出し

Objective-Cを使用するバイナリで関数が呼び出されると、コンパイルされたコードはその関数を呼び出す代わりに**objc_msgSend**を呼び出します。これにより、最終的な関数が呼び出されます。

この関数が期待するパラメータは次のとおりです:

  • 最初のパラメータ(selfは、「メッセージを受け取るクラスのインスタンスを指すポインタ」です。簡単に言えば、メソッドが呼び出されるオブジェクトです。メソッドがクラスメソッドの場合、これはクラスオブジェクト全体としてのインスタンスになります。一方、インスタンスメソッドの場合、selfはクラスのインスタンスとしてインスタンス化されたオブジェクトを指します。
  • 2番目のパラメータop)は、「メッセージを処理するメソッドのセレクタ」です。簡単に言えば、これは単にメソッドの名前です。
  • 残りのパラメータは、メソッドで必要なですop
引数 レジスタ (for) objc_msgSend
1番目の引数 rdi self: メソッドが呼び出されるオブジェクト
2番目の引数 rsi op: メソッドの名前
3番目の引数 rdx メソッドへの第1引数
4番目の引数 rcx メソッドへの第2引数
5番目の引数 r8 メソッドへの第3引数
6番目の引数 r9 メソッドへの第4引数
7番目以降の引数

rsp+
(スタック上)

メソッドへの第5引数以降

Swift

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
[...]

詳細な情報は、このブログ記事で、これらのセクションに格納された情報について説明されています。

パックされたバイナリ

  • 高いエントロピーをチェックする
  • 文字列をチェックする(理解できる文字列がほとんどない場合は、パックされている可能性がある)
  • MacOS用のUPXパッカーは、"__XHDR"というセクションを生成します

動的解析

{% hint style="warning" %} バイナリをデバッグするには、SIPを無効にする必要がありますcsrutil disableまたはcsrutil enable --without debug)またはバイナリを一時フォルダにコピーしてcodesign --remove-signature <binary-path>で署名を削除するか、バイナリのデバッグを許可します(このスクリプトを使用できます) {% endhint %}

{% hint style="warning" %} MacOS上でcloudconfigurationdなどのシステムバイナリインストゥルメントするには、SIPを無効にする必要があります(署名を削除するだけでは機能しません)。 {% endhint %}

統合ログ

MacOSは、アプリケーションを実行する際に非常に役立つログを生成します。これにより、アプリケーションが何をしているかを理解することができます。

さらに、一部のログには、一部のユーザーコンピューター識別可能な情報非表示にするためのタグ<private>が含まれています。ただし、この情報を開示するための証明書をインストールすることも可能です。こちらの説明に従ってください。

Hopper

左パネル

Hopperの左パネルでは、バイナリのシンボルラベル)、手続きと関数のリスト(Proc)、および文字列(Strを表示することができます。これらはすべての文字列ではありませんが、Mac-Oファイルのいくつかの部分_cstringやobjc_methnameなど)で定義されています。

中央パネル

中央パネルでは、逆アセンブルされたコードを表示することができます。また、生の逆アセンブル、グラフ逆コンパイルバイナリのいずれかをクリックして表示することもできます。

コードオブジェクトを右クリックすると、そのオブジェクトへの参照や名前の変更などを確認することができます(逆コンパイルされた擬似コードでは機能しません)。

さらに、中央下部にはPythonコマンドを記述することもできます。

右パネル

右パネルでは、ナビゲーション履歴(現在の状況に到達するまでの経緯を知るため)、この関数を呼び出すすべての関数と、この関数が呼び出すすべての関数を表示する呼び出しグラフ、およびローカル変数の情報など、興味深い情報を確認することができます。

dtruss

dtruss -c ls #Get syscalls of ls
dtruss -c -p 1000 #get syscalls of PID 1000

ktrace

これは、SIPが有効化されていても使用することができます。

ktrace trace -s -S -t c -c ls | grep "ls("

dtrace

これにより、ユーザーは非常に低レベルでアプリケーションにアクセスでき、プログラムをトレースし、実行フローを変更する方法を提供します。Dtraceは、カーネル全体に配置されたプローブを使用し、システムコールの開始と終了などの場所にあります。

DTraceは、各システムコールごとにプローブを作成するために**dtrace_probe_create関数を使用します。これらのプローブは、各システムコールのエントリーポイントと終了ポイント**で発火することができます。DTraceとのやり取りは、ルートユーザーにのみ利用可能な/dev/dtraceを介して行われます。

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はその部分をワイルドカードとして適用します。

プローブをアクティブにし、それらが発生したときに実行するアクションを指定するには、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()}'

MacOSアプリの検査、デバッグ、およびファジング

このセクションでは、MacOSアプリの検査、デバッグ、およびファジングについて説明します。これらのテクニックは、アプリケーションのセキュリティと特権エスカレーションのテストに役立ちます。

アプリの検査

アプリの検査は、アプリのセキュリティホールや脆弱性を特定するために行われます。以下の手法が使用されます。

静的解析

静的解析は、アプリのバイナリコードを分析してセキュリティ上の問題を特定する手法です。以下のツールが使用されます。

動的解析

動的解析は、アプリを実行して実行時の挙動を分析する手法です。以下のツールが使用されます。

デバッグ

デバッグは、アプリの実行中に問題を特定し、修正するために行われます。以下の手法が使用されます。

ブレークポイントの設定

ブレークポイントは、特定のコード行でプログラムの実行を一時停止するために使用されます。以下の手法が使用されます。

  • lldbを使用したブレークポイントの設定
  • fridaを使用したブレークポイントの設定

メモリの解析

メモリの解析は、アプリのメモリ内の情報を調査する手法です。以下の手法が使用されます。

  • lldbを使用したメモリの解析
  • fridaを使用したメモリの解析

ファジング

ファジングは、アプリにランダムなデータを入力して、予期しない動作やセキュリティ上の問題を特定する手法です。以下の手法が使用されます。

ファジングツールの使用

ファジングツールは、自動的にランダムなデータを生成してアプリに入力するツールです。以下のツールが使用されます。

クラッシュの解析

ファジング中に発生したクラッシュを解析することで、セキュリティ上の問題を特定することができます。以下の手法が使用されます。

  • lldbを使用したクラッシュの解析
  • fridaを使用したクラッシュの解析

以上がMacOSアプリの検査、デバッグ、およびファジングに関する情報です。これらのテクニックを使用して、アプリのセキュリティを向上させることができます。

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"

ProcessMonitor

ProcessMonitorは、プロセスが実行しているプロセス関連のアクション(例えば、プロセスが作成している新しいプロセスを監視する)をチェックするための非常に便利なツールです。

FileMonitor

FileMonitorは、ファイルのイベント(作成、変更、削除など)を監視し、そのようなイベントに関する詳細な情報を提供します。

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
(lldb) コマンド 説明
run (r) 実行を開始し、ブレークポイントがヒットするかプロセスが終了するまで続行します。
continue (c) デバッグ対象のプロセスの実行を続行します。
nexti (n / ni) 次の命令を実行します。このコマンドは関数呼び出しをスキップします。
stepi (s / si) 次の命令を実行します。nextiコマンドとは異なり、このコマンドは関数呼び出しに入ります。
finish (f) 現在の関数("フレーム")の残りの命令を実行し、停止します。
control + c 実行を一時停止します。プロセスが実行されている場合rまたはc、プロセスは現在の実行位置で停止します。
breakpoint (b)

b main

b -[NSDictionary objectForKey:]

b 0x0000000100004bd9

br l #ブレークポイントリスト

br e/dis <num> #ブレークポイントの有効化/無効化

breakpoint delete <num>
b set -n main --shlib <lib_name>

help

help breakpoint #ブレークポイントコマンドのヘルプを取得

help memory write #メモリへの書き込みのヘルプを取得

reg

reg read

reg read $rax

reg write $rip 0x100035cc0

x/s <reg/memory address> メモリをヌル終端文字列として表示します。
x/i <reg/memory address> メモリをアセンブリ命令として表示します。
x/b <reg/memory address> メモリをバイトとして表示します。
print object (po)

これにより、パラメータで参照されるオブジェクトが表示されます

po $raw

{

dnsChanger = {

"affiliate" = "";

"blacklist_dns" = ();

AppleのObjective-CのほとんどのAPIやメソッドはオブジェクトを返すため、「print object」poコマンドを使用して表示する必要があります。 poが有意義な出力を生成しない場合は、x/bを使用します

memory

memory read 0x000....
memory read $x0+0xf2a
memory write 0x100600000 -s 4 0x41414141 #そのアドレスにAAAAを書き込む
memory write -f s $rip+0x11f+7 "AAAA" #そのアドレスにAAAAを書き込む

disassembly

dis #現在の関数を逆アセンブルする
dis -c 6 #6行を逆アセンブルする
dis -c 0x100003764 -e 0x100003768 #一つのアドレスから他のアドレスまで逆アセンブルする
dis -p -c 4 #現在のアドレスから逆アセンブルを開始する

parray parray 3 (char **)$x1 # x1レジスタの3つのコンポーネントの配列をチェックします

{% hint style="info" %} objc_sendMsg関数を呼び出す際、rsiレジスタにはヌル終端("C")文字列としてのメソッド名が格納されます。lldbを使用して名前を表示するには、次のようにします

(lldb) x/s $rsi: 0x1000f1576: "startMiningWithPort:password:coreCount:slowMemory:currency:"

(lldb) print (char*)$rsi:
(char *) $1 = 0x00000001000f1576 "startMiningWithPort:password:coreCount:slowMemory:currency:"

(lldb) reg read $rsi: rsi = 0x00000001000f1576 "startMiningWithPort:password:coreCount:slowMemory:currency:" {% endhint %}

アンチダイナミック解析

VMの検出

  • **sysctl hw.model**コマンドは、ホストがMacOSである場合は「Mac」を返しますが、VMの場合は異なる値を返します。
  • **hw.logicalcpuおよびhw.physicalcpu**の値を操作することで、一部のマルウェアはVMであるかどうかを検出しようとします。
  • 一部のマルウェアは、MACアドレス00:50:56に基づいてマシンがVMwareであるかどうかも検出できます。
  • 次のような単純なコードで、プロセスがデバッグされているかどうかを検出することもできます:
  • if(P_TRACED == (info.kp_proc.p_flag & P_TRACED)){ //process being debugged }
  • **ptraceシステムコールをPT_DENY_ATTACH**フラグとともに呼び出すこともできます。これにより、デバッガがアタッチおよびトレースを行うことができなくなります。
  • sysctlまたはptrace関数がインポートされているかどうかを確認できます(ただし、マルウェアは動的にインポートする可能性があります)
  • この記事によれば、"Defeating Anti-Debug Techniques: macOS ptrace variants"
    "メッセージ「Process # exited with status = 45 (0x0000002d)」は、デバッグ対象がPT_DENY_ATTACHを使用していることを示す兆候です"

ファジング

ReportCrash

ReportCrashは、クラッシュしたプロセスを分析し、クラッシュレポートをディスクに保存します。クラッシュレポートには、クラッシュの原因を診断するのに役立つ情報が含まれています。
ユーザーごとのlaunchdコンテキストで実行されるアプリケーションや他のプロセスの場合、ReportCrashはLaunchAgentとして実行され、クラッシュレポートをユーザーの~/Library/Logs/DiagnosticReports/に保存します。
デーモン、システムlaunchdコンテキストで実行される他のプロセス、および他の特権プロセスの場合、ReportCrashはLaunchDaemonとして実行され、クラッシュレポートをシステムの/Library/Logs/DiagnosticReportsに保存します。

クラッシュレポートがAppleに送信されることを心配している場合は、それらを無効にすることができます。そうでない場合、クラッシュレポートはサーバーのクラッシュの原因を特定するのに役立ちます。

#To disable crash reporting:
launchctl unload -w /System/Library/LaunchAgents/com.apple.ReportCrash.plist
sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.ReportCrash.Root.plist

#To re-enable crash reporting:
launchctl load -w /System/Library/LaunchAgents/com.apple.ReportCrash.plist
sudo launchctl load -w /System/Library/LaunchDaemons/com.apple.ReportCrash.Root.plist

スリープ

MacOSでのフジング中にMacがスリープしないようにすることが重要です。

  • systemsetup -setsleep Never
  • pmset、システム環境設定
  • KeepingYouAwake

SSHの切断

SSH接続を介してフジングを行っている場合、セッションが切断されないようにすることが重要です。したがって、sshd_configファイルを以下のように変更します。

  • TCPKeepAlive Yes
  • ClientAliveInterval 0
  • ClientAliveCountMax 0
sudo launchctl unload /System/Library/LaunchDaemons/ssh.plist
sudo launchctl load -w /System/Library/LaunchDaemons/ssh.plist

内部ハンドラ

次のページをチェックして、指定されたスキームやプロトコルを処理するアプリを見つける方法を見つけてください:

{% content-ref url="../macos-file-extension-apps.md" %} macos-file-extension-apps.md {% endcontent-ref %}

ネットワークプロセスの列挙

ネットワークデータを管理しているプロセスを見つけるために興味深いです:

dtrace -n 'syscall::recv*:entry { printf("-> %s (pid=%d)", execname, pid); }' >> recv.log
#wait some time
sort -u recv.log > procs.txt
cat procs.txt

または、netstatまたはlsofを使用します。

Libgmalloc

{% code overflow="wrap" %}

lldb -o "target create `which some-binary`" -o "settings set target.env-vars DYLD_INSERT_LIBRARIES=/usr/lib/libgmalloc.dylib" -o "run arg1 arg2" -o "bt" -o "reg read" -o "dis -s \$pc-32 -c 24 -m -F intel" -o "quit"

{% endcode %}

Fuzzers

AFL++

CLIツールに対して動作します。

Litefuzz

macOSのGUIツールと "just works" します。ただし、一部のmacOSアプリは、ユニークなファイル名、正しい拡張子、サンドボックスからのファイルの読み取りが必要など、特定の要件を持っています~/Library/Containers/com.apple.Safari/Dataからのファイルなど)。

いくつかの例:

{% code overflow="wrap" %}

# iBooks
litefuzz -l -c "/System/Applications/Books.app/Contents/MacOS/Books FUZZ" -i files/epub -o crashes/ibooks -t /Users/test/Library/Containers/com.apple.iBooksX/Data/tmp -x 10 -n 100000 -ez

# -l : Local
# -c : cmdline with FUZZ word (if not stdin is used)
# -i : input directory or file
# -o : Dir to output crashes
# -t : Dir to output runtime fuzzing artifacts
# -x : Tmeout for the run (default is 1)
# -n : Num of fuzzing iterations (default is 1)
# -e : enable second round fuzzing where any crashes found are reused as inputs
# -z : enable malloc debug helpers

# Font Book
litefuzz -l -c "/System/Applications/Font Book.app/Contents/MacOS/Font Book FUZZ" -i input/fonts -o crashes/font-book -x 2 -n 500000 -ez

# smbutil (using pcap capture)
litefuzz -lk -c "smbutil view smb://localhost:4455" -a tcp://localhost:4455 -i input/mac-smb-resp -p -n 100000 -z

# screensharingd (using pcap capture)
litefuzz -s -a tcp://localhost:5900 -i input/screenshared-session --reportcrash screensharingd -p -n 100000

{% endcode %}

より多くのMacOSの情報をフジングする

参考文献

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥