<- Back to documentation

Verified boot / remote attestation limitations

Goal: make (privileged) persistence more difficult after an attacker exploits a device and gains root access. Not necessarily a very realistic goal for general purpose builds of CopperheadOS with lots of freedom, but at the very least specialized builds with some crippling of the feature set can do a significantly better job. There are still hard problems to solve even on a specialized build able to make big sacrifices. Some firmware limitations will need to be addressed by Google. Hopefully they start taking more active / direct control of those areas and end up being responsive to suggestions and vulnerability / security feature regression reports.

Everything here assumes an attacker that already used exploits to gain real root access.

Key attestation including verified boot / the OS version is very new and we haven’t adopted it yet but that’s planned. It provides a form of trust even for first use via Google’s root of trust and with pairing it can do better (via the per-device-batch attestation key - sadly not yet per-device like some of the other hardware keys apparently, although the Qualcomm CE hardware-bound key for the TEE could be used for pairing and should be unique).

attacks on OS

  • attacker cannot make changes to boot, system, vendor or firmware partitions without detection unless they can exploit the verified boot process
  • firmware support for downgrade protection on current devices is weak, which can only be fixed by Google and is very difficult on devices meant to be very usable as: 1) development devices (testing old releases) 2) bootloaders that can be unlocked via persistent state accessible to the admin account in the OS combined with physical access to interact with firmware (aboot) via fastboot
    • ideally, Google will decide to ship downgrade protection regardless of the impact it has on development needs via being unable to downgrade low-level firmware partitions or perhaps even the OS while locked
  • attacker can downgrade to a valid past version of CopperheadOS
    • future mitigation: show version, patch level and build date in early boot of the OS so the user can notice a downgrade occurred and investigate it or report it to us
    • attacker can change the system clock, so pausing boot until user input with a strong warning if very out-of-date wouldn’t really work, have to make do with the user noticing it
  • attacker can likely do partial downgrades, even with firmware level write protection of the active set of partitions, because there isn’t enforcement of versions matching
    • future mitigation: check for consistency of firmware / OS partition versions in early boot of the OS and report problems, potentially to the point of hard enforcement that everything properly matches
  • attacker can downgrade firmware
    • radio and bootloader version are shown in the fastboot menu, but there’s no way to see it at boot, beyond noticing rare changes over time like “powered by android” being missing which is not ever going to happen in practice
    • not clear where the bootloader version comes from in the fastboot menu since there are multiple images and versions can be mismatched once something goes wrong
    • can check for a mismatch in early boot of the OS (boot.img), but the attacker may have replaced boot.img to exploit a past vulnerability in the bootloader
  • if an attacker downgrades part of the verified boot chain, they can exploit a vulnerability that was fixed in the past via the next step in the chain, like exploiting a downgraded late stage bootloader via a malicious boot.img, exploiting a downgraded kernel (boot.img) via the system and vendor partitions
  • could also exploit TEE to fake attestation results
  • boot partition code doesn’t enforce that system / vendor partition fingerprints match
  • OS detects mismatch of fingerprint versions in late boot after using boot, system and vendor code and warns the user
    • this check would likely need to happen earlier to have any value, but doing it from boot probably would be significantly better

without userdata

  • user can boot to bootloader / recovery via key combination and do a factory reset
    • can an attacker persistently break booting recovery via bootloader control block (BCB / misc) via broken reboot reason, etc? needs testing

with userdata

  • attacker can modify any persistent state: files, POSIX permissions SELinux labels, raw disk structure
  • can exploit the OS via persistent state, which combined with a downgrade attack from above could be particularly powerful
  • /data/dalvik-cache holds code / trusted data for the base system
    • solved to a large extent by CopperheadOS already, but more work is required for completion
  • various ways to block the automatic updater from working
  • could do things like partially corrupting the userdata filesystem to prevent the OS from trying to repair or validate a portion of it
  • can target the file system implementation for exploitation via the disk format
  • install non-system apps
  • grant apps runtime permissions
  • mess with package manager metadata and other information that may be trusted to a large extent
    • may be able to get system / signature gated permissions, etc. if this isn’t done well, so this needs to be audited
    • should also make sure it’s not possible to do a ‘fake’ system app update, which should already be impossible due to apk signatures and verification on every boot but this really needs auditing from a verified boot perspective
  • accessibility service
  • device manager
  • direct boot to start apps before the first unlock
    • the updater uses this, so it’s notable that without direct boot being available to non-system apps, the updater gets to run before any other app could run
  • direct boot + accessibility service quite soundly rules out any kind of reporting to the user in late boot unless it’s something that can actually be verified (i.e. the attestation support now provided by TEE)
  • developer options, adb key whitelist