
مختبر عشوائي موجَّه بالتغطية داخل العملية لخفي بلوتوث iOS (bluetoothd) باستخدام FRIDA، مع اختبار عشوائي عبر الأثير لبروتوكول MagicPairing وإمكانيات إعادة تشغيل الأعطال.

ToothPicker هو مبرمج اختبار تطبيقات (fuzzer) موجه بالتغطية يعمل داخل العملية (in-process) لنظام iOS. تم تطويره خصيصًا لاستهداف خفيضة Bluetooth الخاصة بنظام iOS bluetoothd وتحليل بروتوكولات Bluetooth المختلفة على iOS. نظرًا لأنه مبني باستخدام FRIDA، يمكن تكييفه لاستهداف أي منصة تدير FRIDA.
يتضمن هذا المستودع أيضًا مبرمج اختبار عبر الهواء (over-the-air fuzzer) مع تنفيذ نموذجي لاختبار بروتوكول MagicPairing من Apple باستخدام InternalBlue. بالإضافة إلى ذلك، يحتوي على السكربت ReplayCrashFile.py الذي يمكن استخدامه للتحقق من الأعطال التي عثر عليها المبرمج داخل العملية.
هذا مبرمج اختبار بسيط جدًا يقلب البتات والبايتات فقط في الاتصالات النشطة. لا توجيه بالتغطية، ولا حقن، لكنه جيد كعرض توضيحي وحالة (stateful). يعمل فقط مع Python و Frida، لا حاجة لوحدات أو تثبيت. تم اختباره على iOS 13.5-14.3. انظر inplace-fuzzer.
يعمل مبرمج الاختبار داخل العملية بشكل فوري على إصدارات iOS المختلفة (تم اختبار 13.3-13.7)، ولكن يجب تحديد الرموز. تتطلب إصدارات iOS الأخرى تعديلات على عناوين الدوال. بالإضافة إلى ذلك، يبدو أن متعقب FRIDA (stalker) يعاني من بعض المشاكل مع iPhone 8. على أجهزة iPhone الأحدث التي تدعم PAC، يتأثر الأداء بشكل كبير بسبب توقيع المؤشرات. لذلك، يُوصى بتشغيله على iPhone 7.
ToothPicker مبني على قاعدة كود frizzer. ومع ذلك، فقد تم تكييفه لهذا التطبيق المحدد وبالتالي لم يعد متوافقًا مع الإصدار الأصلي. توجد خطط لاستبداله بمكون أكثر تخصصًا في المستقبل.
على iPhone:
على Linux:
لتوزيعات Arch المستندة إلى Linux:
# usbmuxd عادةً ما يأتي مع libimobiledevice
# لكن للتأكد، نقوم بتثبيته يدويًا أيضًا
sudo pacman -S usbmuxd libimobiledevice python-virtualenv radamsa
# قم بتوصيل iPhone بالكمبيوتر
# افتح قفله.
# إذا ظهرت رسالة اقتران، اضغط على "Trust"
# إذا لم تظهر رسالة اقتران:
idevicepair pair
# الآن يجب أن تظهر النافذة المنبثقة، اقبل ثم أعد:
idevicepair pair
# في حالة أخطاء الاتصال:
sudo systemctl restart usbmuxd
# أو أعد اقتران الهاتف والكمبيوتر
# أوامر مفيدة أخرى
# للاتصال بـ iPhone عبر SSH:
# Checkra1n يأتي مع خادم SSH يستمع على المنفذ 44
# قم بتمرير منفذ SSH الخاص بالهاتف إلى المنفذ المحلي 4444:
iproxy 4444 44
# اتصل:
ssh root@localhost -p 4444
# كلمة المرور الافتراضية: alpine
# لجلب بعض معلومات الجهاز عن الهاتف:
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، PacketLogger، وهو جزء من Additional Tools for Xcode، يمكن فك تشفير العديد من الحزم بمجرد تثبيت Bluetooth Debug Profile. علاوة على ذلك، إذا قمت بفتح سجلات الأعطال في iOS باستخدام Xcode، فسيضيف بعض الرموز.
الإعداد:
frizzer.frizzer.projects على مشروع مثال لاختبار بروتوكول MagicPairing.MagicPairing المتخصصة في ملف واحد.harness وقم بتثبيت 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 من جديد.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 في Settings -> Privacy -> Analytics & Improvements -> Analytics Data.
إذا كانت تحتوي على أعطال bluetoothd من النمط bluetoothd.cpu_resource-*.ips، فهذا يشير إلى أن العطل ناتج عن تجاوز الموارد. يمكن زيادتها على النحو التالي.
على 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 عن حفظ سجلات الأعطال لبرنامج واحد بعد الوصول إلى الحد الأقصى وهو 25. إذا قمت بتحميل سجل عطل باستخدام Xcode (عبر Simulators&Devices)، تتم إضافة بعض الرموز إلى تتبع المكدس. بمجرد الوصول إلى الحد الأقصى، يمكن إزالة السجلات إما عبر Xcode أو مباشرة على جهاز iOS عن طريق حذفها في المجلد /var/mobile/Library/Logs/CrashReporter/.
A12+:
بدءًا من iPhone XR/Xs، تم تقديم PAC. يتطلب ذلك استدعاء sign() على NativeFunction في FRIDA. على الرغم من أن هذا لا يفعل شيئًا على وحدات المعالجة المركزية الأقدم، إلا أنه يقلل السرعة بشكل هائل على الأجهزة الأحدث، ولكنه مطلوب لجعلها تعمل على الإطلاق. لاحظنا أن ToothPicker يعمل بنصف السرعة عند استخدام iPhone SE2 بدلاً من iPhone 7.
يتطلب تنفيذ MagicPairing لمبرمج الاختبار عبر الهواء تثبيت InternalBlue ويمكن تنفيذه عن طريق تشغيل python MagicPairingFuzzer.py TARGET_BD_ADDR.
إذا كنت ترغب في إعادة إنتاج الأعطال، استخدم السكربت ReplayCrashFile.py، والذي يمكنه أخذ ملف عطل وبدء اتصال عبر الهواء بحمولة مستندة إلى العطل.