
FRIDAを使用したiOS Bluetoothデーモン(bluetoothd)向けカバレッジガイド型インプロセスファザー。MagicPairingプロトコルに対する無線(OTA)ファジングとクラッシュリプレイ機能を備えています。

ToothPickerは、iOS用のインプロセス・カバレッジガイド型ファザーです。iOSのBluetoothデーモンbluetoothdを特に対象とし、iOS上のさまざまなBluetoothプロトコルを解析するために開発されました。FRIDAをベースに構築されているため、FRIDAが動作する任意のプラットフォームをターゲットに適応できます。
このリポジトリには、InternalBlueを使用してAppleのMagicPairingプロトコルをファジングするための模範的な実装を備えたオーバー・ザ・エア・ファザーも含まれています。さらに、インプロセスファザーが見つけたクラッシュを検証するために使用できるReplayCrashFile.pyスクリプトも含まれています。
これは、アクティブな接続でビットとバイトを反転するだけの非常にシンプルなファザーです。カバレッジガイダンスやインジェクションはありませんが、デモやステートフルな動作に適しています。Python+Fridaだけで動作し、モジュールやインストールは不要です。iOS 13.5-14.3でテスト済みです。inplace-fuzzerを参照してください。
インプロセスファザーは、さまざまなiOSバージョン(13.3-13.7でテスト済み)でそのまま動作しますが、シンボルを指定する必要があります。他のiOSバージョンでは、関数アドレスの適応が必要です。さらに、FRIDAのストーカーはiPhone 8でいくつか問題があるようです。PACをサポートする新しいiPhoneでは、ポインタの署名によりパフォーマンスが大幅に低下します。したがって、iPhone 7で実行することを推奨します。
ToothPickerは、frizzerのコードベース上に構築されています。ただし、この特定のアプリケーション向けに適応されているため、元のバージョンとは互換性がありません。将来的には、これをより専用のコンポーネントに置き換える計画があります。
iPhone上:
Linux上:
ArchベースのLinuxの場合:
# usbmuxd typically comes with libimobiledevice
# but just to be sure, we manually install it as well
sudo pacman -S usbmuxd libimobiledevice python-virtualenv radamsa
# Connect the iPhone to the computer
# Unlock it.
# If a pairing message pops up, click "Trust"
# If no pairing message pops up:
idevicepair pair
# Now there should be the pop up, accept and then again:
idevicepair pair
# In case of connection errors:
sudo systemctl restart usbmuxd
# or pair phone and computer again
# Other useful commands
# To ssh into the iPhone:
# Checkra1n comes with an SSH server listening on Port 44
# Proxy the phone's SSH port to 4444 localport:
iproxy 4444 44
# Connect:
ssh root@localhost -p 4444
# Default password: alpine
# To fetch some device information of the phone:
ideviceinfo
Debian Linuxの場合:
上とほぼ同じです。例外:
radamsa はパッケージ化されていないため、gitリポジトリからインストールする必要があります。iproxyは追加パッケージlibusbmuxd-toolsを必要とします。macOSの場合:
Arch Linuxのセットアップとは少し異なるコマンド...
brew install libimobiledevice usbmuxd radamsa npm
idevicepair pair
npm install frida-compile
pip3 install frida-tools
macOSでは、Bluetooth Debug Profileがインストールされていれば、Additional Tools for Xcodeの一部であるPacketLoggerがさまざまなパケットをデコードできます。 さらに、XcodeでiOSのクラッシュログを開くと、いくつかのシンボルが追加されます。
セットアップ:
frizzer用の仮想Python環境をセットアップすることを推奨します。frizzerディレクトリ内で必要なパッケージをインストールします。projectsディレクトリには、MagicPairingプロトコルをファジングするためのサンプルプロジェクトが含まれています。MagicPairingハーネスを1つのファイルにコンパイルします。harnessディレクトリにcdし、frida-compileをインストールします。これはそのフォルダ内で実行する必要があり、npm install frida-compileを実行してユーザーとして直接インストールできることに注意してください。frida-compile ../projects/YOUR_PROJECT/YOUR_SPECIALIZED_HARNESS.JS -o ../projects/YOUR_PROJECT/harness.jsを実行します。これはnpmコンテキストでインストールされているため、代わりにnpx frida-compileを実行する必要があるかもしれません。ハーネスが変更されるたびに、frida-compileを再実行する必要があります。ファジング:
killall -9 bluetoothdを実行して、bluetoothdを新たに起動します。cdして戻り、クラッシュログディレクトリを作成し(mkdir crashes)、../../frizzer/fuzzer.py fuzz -p .を実行します。手短に、新しいプロジェクトを開始するには、以下を実行します:
cd harness
npx frida-compile ../projects/YOUR_PROJECT/YOUR_SPECIALIZED_HARNESS.JS -o ../projects/YOUR_PROJECT/harness.js
cd ../projects/YOUR_PROJECT/
mkdir crashes
../../frizzer/fuzzer.py fuzz -p .
frizzer/fuzzer.py fuzz --seed 1234 -p .を使用して、異なるシードで開始することもできます。
新しいiOSバージョンの追加:
現在、iOSの異なるバージョンはbluetoothd.jsで定義されています。必要なすべてのシンボルを持つ初期バージョンが与えられれば、Ghidraバージョニングツールでこれらを見つけることができます。それらの一部は元のiOSバイナリでは名前が付けられていないため、理想的には以前に注釈が付けられたものから始めてください。bluetoothd.jsが変更されるたびに、frida-compileを再実行する必要があります。
bluetoothdの容量増加:
iOSのクラッシュログは設定 -> プライバシー -> 解析と改善 -> 解析データに保存されます。パターンbluetoothd.cpu_resource-*.ipsのbluetoothdクラッシュが含まれている場合、これはリソース超過によるクラッシュを示しています。以下のようにして増やすことができます。
iPhone 7の場合:
cd /System/Library/LaunchDaemons/
plistutil -i com.apple.jetsamproperties.D10.plist -o com.apple.jetsamproperties.D10.plist.txt
plistutil -i com.apple.jetsamproperties.D101.plist -o com.apple.jetsamproperties.D101.plist.txt
iPhone SE2では、これらはcom.apple.jetsamproperties.D79.plistにあります。:
cd /System/Library/LaunchDaemons/
plistutil -i com.apple.jetsamproperties.D79.plist -o com.apple.jetsamproperties.D79.plist.txt
bluetoothdを検索し、優先度を19(有効な最高優先度)に更新し、メモリ制限を非常に高く設定します。両方のファイルに同じ変更を適用します。
<dict>
<key>ActiveSoftMemoryLimit</key>
<integer>24000</integer>
<key>InactiveHardMemoryLimit</key>
<integer>24000</integer>
<key>EnablePressuredExit</key>
<false/>
<key>JetsamPriority</key>
<integer>19</integer>
</dict>
変更を書き戻し、bluetoothdを再起動します。
plistutil -i com.apple.jetsamproperties.D10.plist.txt -o com.apple.jetsamproperties.D10.plist
plistutil -i com.apple.jetsamproperties.D101.plist.txt -o com.apple.jetsamproperties.D101.plist
killall -9 bluetoothd
同様にiPhone SE2では:
plistutil -i com.apple.jetsamproperties.D79.plist.txt -o com.apple.jetsamproperties.D79.plist
killall -9 bluetoothd
古いログの削除:
iOSは、1つのプログラムに対して25の制限に達すると、クラッシュログの保存を停止します。Xcode(シミュレータとデバイス経由)でクラッシュログを読み込むと、スタックトレースにいくつかのシンボルが追加されます。制限に達すると、ログはXcodeを介して、またはiOSデバイス上のフォルダ/var/mobile/Library/Logs/CrashReporter/で直接削除することができます。
A12以上:
iPhone XR/Xs以降、PACが導入されました。これにより、FRIDAでNativeFunctionにsign()を呼び出す必要があります。これは以前のCPUでは何もしませんが、新しいデバイスでは速度が大幅に低下しますが、動作させるために必要です。ToothPickerは、iPhone 7の代わりにiPhone SE2を使用すると、半分の速度で動作することが観察されました。
オーバー・ザ・エア・ファザーのMagicPairing実装は、InternalBlueがインストールされている必要があり、python MagicPairingFuzzer.py TARGET_BD_ADDRを実行して実行できます。
クラッシュを再現したい場合は、ReplayCrashFile.pyスクリプトを使用します。このスクリプトはクラッシュファイルを受け取り、クラッシュに基づいたペイロードでオーバー・ザ・エア接続を開始します。