flawopen.com/Teardowns/cve-2024-32896-android-factory-reset-wipe-bypass
CVE-2024-32896 : la réinitialisation d'usine d'Android pouvait être interrompue avant la destruction des clés
CVE-2024-32896 (CVSS 7.8, exploitée dans des attaques limitées et ciblées) : la réinitialisation d'usine se contentait de redémarrer en mode recovery et laissait les clés de chiffrement en place jusqu'à l'effacement, si bien que quiconque tenait le téléphone pouvait interrompre le redémarrage et garder les données récupérables. Le correctif supprime toutes les clés du Keystore avant le redémarrage.
La règle d'une entreprise pour un ordinateur portable perdu est de lui envoyer l'ordre « broyer ». L'ordinateur se rend alors à la salle du broyeur, où tous les fichiers sont détruits. Mais celui qui tient l'ordinateur peut bloquer le couloir en chemin : les fichiers n'arrivent nulle part et restent intacts. Le correctif : avant de partir, l'ordinateur brûle les seules clés de son armoire verrouillée. Même si le trajet est interrompu, plus personne ne pourra jamais ouvrir l'armoire.
Concepts Clés et Termes
Réinitialisation d'usine (--wipe_data)- Effacement demandé par l'utilisateur, une app d'administration de l'appareil ou de MDM, ou un service d'effacement à distance.
RecoverySystemServiceécrit la commande.rebootRecoveryWithCommand()--wipe_datapour recovery puis redémarre. Bloc de contrôle du bootloader (BCB)- Petite partition (
misc) où Android laisse des instructions au bootloader et à recovery ; écrite parsetupOrClearBcb(). FBE et mot de passe synthétique- Chiffrement par fichier. Les clés des données utilisateur dérivent d'un mot de passe synthétique dont les blobs de protection sont liés à des clés KeyMint : détruire ces clés rend les données indéchiffrables.
KeyMint / Keystore- Service de clés adossé au matériel.
AndroidKeyStoreMaintenancedemande à chaque appareil KeyMint de supprimer toutes ses clés..deleteAllKeys()
Analyse de Cause Racine
rebootRecoveryWithCommand() dans RecoverySystemService.java traitait --wipe_data en écrivant la commande dans le bloc de contrôle du bootloader puis en redémarrant, en comptant sur recovery pour effacer /data ensuite. Tant que cet effacement n'était pas terminé, les clés KeyMint protégeant le mot de passe synthétique et les clés de chiffrement DE et de métadonnées restaient intactes. Interrompre le redémarrage, ou empêcher l'effacement de s'exécuter, laissait en place les données chiffrées et leurs clés : une erreur de logique dans l'ordre des opérations. Le correctif (AOSP 8b7b2c66, bug 324321147) appelle deleteSecrets(), qui exécute AndroidKeyStoreMaintenance, avant le redémarrage. C'est la moitié côté framework Android du correctif de firmware Pixel suivi sous .deleteAllKeys()CVE-2024-29748.
Déroulement de l'Attaque Étape par Étape
Un effacement est demandé
Le propriétaire, une app d'administration de l'appareil ou de MDM, ou un service d'effacement à distance demande la réinitialisation d'usine, qui aboutit à rebootRecoveryWithCommand("--wipe_data ...").
Redémarrage sans rien détruire
setupOrClearBcb() enregistre la commande et pm.reboot(REBOOT_RECOVERY) redémarre le téléphone. À ce stade, les clés de chiffrement sont intactes.
L'effacement est interrompu
Une personne ayant l'appareil en main arrête le redémarrage avant recovery, par exemple en maintenant Volume bas pour tomber dans le bootloader, et l'effacement ne s'exécute jamais.
Les données survivent à la réinitialisation
Les données utilisateur chiffrées et les clés qui les protègent restent sur l'appareil, qui peut encore être attaqué plus tard avec des outils forensiques au lieu d'être vierge.
Code Source : Vulnérable vs Sécurisé
// services/core/java/com/android/server/recoverysystem/RecoverySystemService.java
@Override // Binder call
public void rebootRecoveryWithCommand(String command) {
if (DEBUG) Slog.d(TAG, "rebootRecoveryWithCommand: [" + command + "]");
synchronized (sRequestLock) {
if (!setupOrClearBcb(true, command)) {
return;
}
// BUG: for "--wipe_data" nothing is destroyed yet. The keys that
// protect the user's encrypted data survive until recovery runs the
// wipe. If the reboot is interrupted or the wipe is skipped, the data
// is still recoverable.
PowerManager pm = mInjector.getPowerManager();
pm.reboot(PowerManager.REBOOT_RECOVERY);
}
}
// services/core/java/com/android/server/recoverysystem/RecoverySystemService.java
static final String RECOVERY_WIPE_DATA_COMMAND = "--wipe_data";
@Override // Binder call
public void rebootRecoveryWithCommand(String command) {
if (DEBUG) Slog.d(TAG, "rebootRecoveryWithCommand: [" + command + "]");
boolean isForcedWipe = command != null && command.contains(RECOVERY_WIPE_DATA_COMMAND);
synchronized (sRequestLock) {
if (!setupOrClearBcb(true, command)) {
return;
}
// FIX: destroy the keys first. Deleting every KeyMint key (including
// the synthetic-password protector keys and the keys protecting DE and
// metadata encryption keys) makes FBE data unrecoverable even if the
// wipe in recovery is interrupted or skipped.
if (isForcedWipe) {
deleteSecrets();
}
PowerManager pm = mInjector.getPowerManager();
pm.reboot(PowerManager.REBOOT_RECOVERY);
}
}
private static void deleteSecrets() {
Slogf.w(TAG, "deleteSecrets");
try {
AndroidKeyStoreMaintenance.deleteAllKeys();
} catch (android.security.KeyStoreException e) {
Log.wtf(TAG, "Failed to delete all keys from keystore.", e);
}
}
Liste de Contrôle de Sécurité pour l'Ingénierie
- ✓Maintenez les appareils au niveau de correctif de sécurité Android 2024-09-01 ou ultérieur (Pixel : mise à jour de juin 2024 ou ultérieure), qui incluent AOSP 8b7b2c66.
- ✓Pour tout effacement destructif, détruisez d'abord le matériel de clés (crypto-shredding) et lancez seulement ensuite l'effacement lent, pour qu'un effacement interrompu ne laisse rien d'exploitable.
- ✓Testez les parcours d'effacement en cas d'interruption — coupure de courant, entrée forcée dans le bootloader, étape recovery sautée — et vérifiez qu'ensuite les données ne peuvent plus être déchiffrées.
- ✓Dans les procédures de MDM, ne considérez un effacement terminé que lorsque l'appareil le confirme ou se réinscrit vierge, et alertez si un appareil effacé réapparaît avec son ancien état.
- ✓Sur les appareils contenant des données sensibles, exigez un identifiant d'écran de verrouillage robuste, pour que des données chiffrées ayant survécu à un effacement raté ne puissent pas être attaquées par force brute.