flawopen.com/Teardowns/cve-2024-32896-android-factory-reset-wipe-bypass

● CVE-2024-32896 · CVSS 7.8 · Tinggi
Riset Keamanan · FlawOpen

CVE-2024-32896: Reset Pabrik Android Bisa Dihentikan Sebelum Kunci Dihancurkan

CVE-2024-32896 (CVSS 7.8, dieksploitasi dalam serangan terbatas dan tertarget): reset pabrik hanya me-reboot ke recovery dan membiarkan kunci enkripsi utuh sampai penghapusan berjalan, sehingga orang yang memegang ponsel dapat menghentikan reboot dan membuat data tetap bisa dipulihkan. Perbaikannya menghapus semua kunci Keystore sebelum reboot.

💡 Penjelasan Sederhana (ELI5)

Aturan sebuah perusahaan untuk laptop yang hilang adalah mengirim perintah "hancurkan". Laptop lalu berjalan ke ruang penghancur kertas, tempat semua file dimusnahkan. Tetapi orang yang memegang laptop bisa menghalangi lorong di tengah jalan, sehingga file tidak sampai ke mana pun dan tetap utuh. Perbaikannya: sebelum berangkat, laptop membakar satu-satunya kunci lemari arsipnya yang terkunci. Meski perjalanannya dihentikan, tidak ada yang bisa membuka lemari itu lagi.

Konsep Kunci & Istilah

Reset pabrik (--wipe_data)
Penghapusan yang diminta pengguna, aplikasi device-admin atau MDM, atau layanan hapus jarak jauh. RecoverySystemService.rebootRecoveryWithCommand() menulis perintah --wipe_data untuk recovery lalu me-reboot.
Blok kontrol bootloader (BCB)
Partisi kecil (misc) tempat Android meninggalkan instruksi untuk bootloader dan recovery; ditulis oleh setupOrClearBcb().
FBE dan kata sandi sintetis
Enkripsi berbasis file. Kunci data pengguna diturunkan dari kata sandi sintetis yang blob pelindungnya terikat pada kunci KeyMint, sehingga menghancurkan kunci itu membuat data tak bisa didekripsi.
KeyMint / Keystore
Layanan kunci berbasis perangkat keras. AndroidKeyStoreMaintenance.deleteAllKeys() meminta setiap perangkat KeyMint menghapus semua kuncinya.

Analisis Akar Masalah (Root Cause)

rebootRecoveryWithCommand() di RecoverySystemService.java menangani --wipe_data dengan menulis perintah ke blok kontrol bootloader lalu me-reboot, dengan asumsi recovery akan menghapus /data sesudahnya. Sampai penghapusan itu selesai, kunci KeyMint yang melindungi kata sandi sintetis serta kunci enkripsi DE dan metadata tetap utuh. Menghentikan reboot, atau mencegah penghapusan berjalan, membuat data terenkripsi beserta kuncinya tetap di tempat: kesalahan logika dalam urutan operasi. Perbaikannya (AOSP 8b7b2c66, bug 324321147) memanggil deleteSecrets(), yang menjalankan AndroidKeyStoreMaintenance.deleteAllKeys(), sebelum reboot. Ini adalah separuh bagian framework Android dari perbaikan firmware Pixel yang dilacak sebagai CVE-2024-29748.

Alur Serangan Langkah demi Langkah

Langkah 1

Penghapusan diminta

Pemilik, aplikasi device-admin atau MDM, atau layanan hapus jarak jauh meminta reset pabrik, yang berakhir di rebootRecoveryWithCommand("--wipe_data ...").

Langkah 2

Reboot tanpa menghancurkan apa pun

setupOrClearBcb() menyimpan perintah dan pm.reboot(REBOOT_RECOVERY) me-restart ponsel. Pada titik ini kunci enkripsi belum disentuh.

Langkah 3

Penghapusan terhenti

Orang yang memegang perangkat secara fisik menghentikan reboot sebelum masuk recovery, misalnya dengan menahan tombol Volume Turun agar masuk bootloader, sehingga penghapusan tak pernah berjalan.

Langkah 4

Data selamat dari reset

Data pengguna terenkripsi dan kunci yang melindunginya tetap ada di perangkat, sehingga masih bisa diserang dengan alat forensik di kemudian hari alih-alih sudah bersih.

Kode Sumber: Rentan vs Aman

IMPLEMENTASI RENTAN
// 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);
    }
}
PERBAIKAN AMAN & KUAT
// 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);
    }
}

Daftar Periksa Penguatan Sistem Rekayasa

Sumber