Blog: Vulnerability Disclosure
Moto E20 Readback Vulnerability
09/11/2022 Update: CVE ID CVE-2022-3917 has been reserved, with Lenovo to publish the Advisory Summary.
- The Motorola E20 is an entry-level smartphone that uses a Unisoc system-on-chip.
- Motorola holds around 10% of the US smartphone market, though the sales of the E20 as a subset of that are unclear.
- The E20 featured a bootloader vulnerability that enabled reading of RAM or stored partitions through a cold boot attack.
- This allowed anyone with physical access to a locked phone to extract personal data from running apps.
- Data we extracted included Wi-Fi keys, contacts, photos, WhatsApp messages and more.
- Motorola took 5 weeks to replicate the vulnerability.
- The issue was fixed in the September firmware release, version Moto E20 RETGB RON31.267-38-8.
- We strongly recommend that all E20 owners ensure their phone software is at this version or later.
RAM / Partition readback allowed on Moto E20 phone
CVSS 4.6 (Medium severity)
Lenovo to issue a CVE
Firmware version: Moto E20 RETGB RON31.266-41
Fixed in version: Moto E20 RETGB RON31.267-38-8
The Moto E20 from Lenovo phone uses a Unisoc T606 SoC. In common with all Unisoc SoCs, this uses a customised U-boot bootloader as a secondary bootloader which then loads Android. The bootloader can be communicated with using the Android fastboot protocol.
Analysis of the bootloader showed that there was an undocumented fastboot oem subcommand, pull, that could read data from the phone (i.e. could upload data from the phone to the fastboot client).
The pull command has three different modes:
- oem pull partition – would return the partition table
- oem pull partition_name – would return the contents of partition_name (g. oem pull uboot_log)
- oem pull address++size – would return the contents of the memory address, returning size bytes. (g. oem pull 0x80000000++0x1000)
As the userdata partition is encrypted, PII cannot be stolen through method 2 by default. It is useful to extract the contents of the bootloader or Android to reverse engineer potential vulnerabilities. The uboot_log and miscdata partitions can contain information useful for potential future attacks.
Method 3 can allow cold boot attacks – where the device is booted into the bootloader and the RAM is then examined to look for confidential information from the Android operating system.
As a proof of concept, some canary values were set in the Android Settings and Contacts app. The device was booted into bootloader mode. 2 GB of memory was extracted from address 0x80000000 (which usually maps to RAM on ARM cores) and examined. All canaries were found within the memory, including a wireless PSK. Showing it could be possible to compromise user data.
Although this was discovered on the version of the firmware described above, the same command has been identified on other versions and software channels for the Moto E20.
- 2022-07-04 – Vulnerability identified
- 2022-07-05 – Lenovo advised through [email protected]
- 2022-07-06 – Lenovo acknowledges receipt of vulnerability
- 2022-08-11 – Lenovo confirms the vulnerability is reproducible
- 2022-08-31 – Lenovo confirm that vulnerability is fixed in RONS31.267-38-8
- 2022-10-19 – Disclosure date
The Unisoc firmware is commonly provided in the form of a special container file, known as a .pac file. This is used by support tools to talk to the Unisoc’s primary bootloader. The pac file consists of a selection of filesystem images, some raw binaries and a file stager.
The firmware for the Motorola E20 was downloaded and unpacked using a custom internally written unpacker. After unpacking it the u-boot-sign.bin binary, which represents the secondary bootloader, was loaded into the Ghidra disassembler to look for potential vulnerabilities.
The secondary bootloader consists of a heavily customised version of the U-boot bootloader, with a simple implementation of the fastboot protocol compiled in, to allow access to it from other systems.
To import into Ghidra, the bootloader was loaded as an AARCH64 binary with a base offset of 0x9EFFFE00 to account for the header.
Fastboot commands were added in the function at address 0x9f022440, as shown below. Function names are my annotations and will not be the original function names:
The oem command is handled by a function at 0x9f28280, which was renamed to HandleOem for convenience. This is a large function which follows the format of multiple if statements, handling most subcommand individually.
The pull command is checked for at the start of the function, although the code for that block is quite distance from the check:
The executed code for the pull command checks for a number (which performs a memory read):
This forms method 3 described above, allowing memory to be read. Investigation into this returned mostly blank data, with some data around addresses 0x60000000 and with the device’s RAM from 0x80000000.
It then checks for the parameter partition:
Finally, it checks for the name of a partition, with an optional size parameter:
If it matches these cases, it will return a DATA packet, and then stream data back to the fastboot client.
The standard fastboot client has a restricted number of commands that it will allow. To work around this, I wrote a simple fastboot client which will allow me to issue any command and will return any valid response. It can be found here on GitHub.
As part of the testing data was entered into the default Contacts application for some simple strings that could be searched for. After this the device was rebooted into the bootloader mode and the RAM extracted. The strings could be found.
The bootloader is accessible from the phone, with no access to the underlying operating system, by doing a force power off (holding down power) and then holding down power and volume up whilst the device powers on.
If you have a Moto E20 update it to the September firmware update as soon as possible.
For vendors, ensure that no debugging or undocumented commands exist in your customised bootloaders.