Backup Android /data partition without any permissions
Posted on: Aug 22, 2020 9:19 AM UTC
Contents
Around two years ago my Nexus 5 died and I bought a Redmi Note 5 Pro (whyred) for around $200.
Of course it couldn't compete but I liked the big screen and its weight among others.
Of course it couldn't compete but I liked the big screen and its weight among others.
The first disappointment came when I learnt that Xiaomi wanted to control the unlocking of their devices.
I didn't have the time to fully grasp the implications, including the data deletion when I will unlock.
That never really bothered me because I had no problem with the phone.
I didn't have the time to fully grasp the implications, including the data deletion when I will unlock.
That never really bothered me because I had no problem with the phone.
The second disappointment was Xiaomi's aggressive background app managing: MiUI kills all background apps, whatever their purpose.
That meant no VPN app, no Automate.
I already had much data and that still wasn't enough to motivate me to root the phone and to get rid of the crazy situation.
That meant no VPN app, no Automate.
I already had much data and that still wasn't enough to motivate me to root the phone and to get rid of the crazy situation.
Since then, Xiaomi introduced ads in many places (settings, app installations, etc.) in the Chinese ROM but they promised that would never happen in global versions.
And finally as you can guess, they thought it was a good idea to lie and put them in the global ROM.
And finally as you can guess, they thought it was a good idea to lie and put them in the global ROM.
Well, this was the final straw. And I won't even talk about auto update installation (now fixed?) and the inability to shut off their calendar app among others.
Let's now focus on the goal here: backup all my data, including app data, and never touch a Xiaomi device again.
As mentionned earlier, the official process is:
As mentionned earlier, the official process is:
- you ask Xiaomi for an unlock code using a proprietary binary on Windows
- you wait for up to 360 hours, i.e. 15 days
- if the request is approved, their proprietary binary erases all your data and unlocks the phone
So to access my data, I need to erase it all.
Read my data -----> delete my data
Let's introduce two intermediate steps to find where the chain can be attacked:
Read app data --(2)--> be root in OS --(3)--> unlock bootloader --(1)--> delete app data
So in order to access my data without having to delete it, I need to perform any one of the three following things:
- find how to read the app data without being root (2)
- find how to be root without unlocking the bootloader (3)
- find how to unlock the bootloader without erasing the data (1)
I will explore the three cases in this article.
Don't mind the numbering pattern, it's only the chronological way I will discuss them.
Don't mind the numbering pattern, it's only the chronological way I will discuss them.
Unlock the bootloader without erasing the data
The dirty and unsafe way
A termination of the Mi Unlock tool and some recovery flashings are reported to allow you to unlock the bootloader without having to suffer the data deletion.
People have reported doing this method with success.
While this simple solution is rather appealing, some people have reported failing to do so.
I can't accept any chance of losing data though so I didn't test this.
People have reported doing this method with success.
While this simple solution is rather appealing, some people have reported failing to do so.
I can't accept any chance of losing data though so I didn't test this.
The surgical way
Xiaomi's phones can be unlocked but also re-locked.
That means that so the bootloader state isn't permanently written in fuses and there is a place where the value is stored.
This place seems to be in the
Some indexes you can supposedly write to in order to unlock the bootloader come from the
It may have been used for older devices but the code deletion and my inability to reproduce (I put
There are two ways to determine the place to edit:
That means that so the bootloader state isn't permanently written in fuses and there is a place where the value is stored.
This place seems to be in the
devinfo
partition. I found mentions of this for LG, ZTE and Xiaomi phones.Some indexes you can supposedly write to in order to unlock the bootloader come from the
device_info
structure in the lk
bootloader.It may have been used for older devices but the code deletion and my inability to reproduce (I put
0x01
in many places of devinfo
) seem to indicate it is not used anymore and the info is stored else where.There are two ways to determine the place to edit:
- compare the whole flash before and after an official unlock (+ hope only a bit has changed)
- find the SBL and ABL to find where they look for these flags
Although these two things are promising, the former needs to have access to the same flash both before and after the unlocking, and the latter would too time consuming for me right now.
Read the app data without being root
Backup the encrypted /userdata
Path (1) being out of the way, let's talk about reading the data without gaining special privileges.
We know the data is here so maybe there is a way to dump it.
After digging through lots of forum pages I indeed found one: Qualcomm's emergency mode, known as QDL, QDLoader, EDL or 9008 mode.
When you boot into this mode, you have direct access to the SoC and can send it commands.
This mode is designed for OEMs but often stays available on shipped products.
We know the data is here so maybe there is a way to dump it.
After digging through lots of forum pages I indeed found one: Qualcomm's emergency mode, known as QDL, QDLoader, EDL or 9008 mode.
When you boot into this mode, you have direct access to the SoC and can send it commands.
This mode is designed for OEMs but often stays available on shipped products.
There are different way to boot in this mode, sometimes it's accessible with
For the some phones, including the Note 5 Pro, you can connect two pads on the motherboard before booting up and this mode will be enabled.
The screen will stay black so the only way to be sure it works is using
adb reboot edl
or fastboot reboot-edl
but it seems these commands have been deleted from the tools.For the some phones, including the Note 5 Pro, you can connect two pads on the motherboard before booting up and this mode will be enabled.
The screen will stay black so the only way to be sure it works is using
lsusb
:Bus 001 Device 009: ID 05c6:9008 Qualcomm, Inc. Gobi Wireless Modem (QDL mode)
Continuing still needs some work: the SoC is waiting but it doesn't have any capabilities yet.
For this you need to provide a device-specific program that will actually do the work.
Fortunately many have leaked on the web so if you search with the right terms, chances are you'll find the one you're looking for.
They are found in two formats, MBN and ELF, and contain the codename of the Qualcomm chip of your device.
In my case, I found the file named
For this you need to provide a device-specific program that will actually do the work.
Fortunately many have leaked on the web so if you search with the right terms, chances are you'll find the one you're looking for.
They are found in two formats, MBN and ELF, and contain the codename of the Qualcomm chip of your device.
In my case, I found the file named
prog_emmc_firehose_sdm660_ddr.mbn
.Once this is done you can start to talk to the SoC using publicly available tools.
The most used one is QPST (
I never found any real evidence of that so I don't know how much you can trust the shady binaries on shady websites that have these names.
I nevertheless tried using several versions of it on a Windows 10 virtual machine but it never worked. It could have been bad rules on the Linux side, bad Virtual Box configuration or anything else.
The most used one is QPST (
Qualcomm Product Support Tools
), which is a supposedly leaked Qualcomm software.I never found any real evidence of that so I don't know how much you can trust the shady binaries on shady websites that have these names.
I nevertheless tried using several versions of it on a Windows 10 virtual machine but it never worked. It could have been bad rules on the Linux side, bad Virtual Box configuration or anything else.
Anyway I finally chose to use an open-source program on my Linux setting, it worked like a charm.
It allows you to do tons of things but the only one I wanted is
Just don't forget the loader and you're good to go.
After waiting a bit, I finally had my 58.2GiB
It allows you to do tons of things but the only one I wanted is
"./edl.py rf flash.bin" -> to dump whole flash for device with emmc
.Just don't forget the loader and you're good to go.
After waiting a bit, I finally had my 58.2GiB
all.img
Three interesting things to note here:
- using
edl.py
you can read but also write partitions - you have the whole partition table (
gdisk -l filename
) - the
/userdata
partition is encrypted, as expected
I knew this wasn't the end of the road but it is the step 1: I can theoretically flash the image again and have my data back on the phone.
A kind a poor man's backup.
A kind a poor man's backup.
Number Start (sector) End (sector) Size Code Name
1 40 55 8.0 KiB 8300 switch
2 56 71 8.0 KiB FFFF dpo
3 72 87 8.0 KiB FFFF fsc
4 88 151 32.0 KiB FFFF limits
5 152 215 32.0 KiB FFFF ssd
6 216 255 20.0 KiB FFFF sec
7 256 383 64.0 KiB FFFF vbmeta
8 384 511 64.0 KiB 0700 vbmetabak
9 512 767 128.0 KiB FFFF storsec
10 768 1023 128.0 KiB 0700 storsecbak
11 1024 1535 256.0 KiB FFFF apdp
12 1536 2047 256.0 KiB FFFF msadp
13 2048 3071 512.0 KiB FFFF keystore
14 3072 4095 512.0 KiB FFFF frp
15 4096 5119 512.0 KiB FFFF rpm
16 5120 6143 512.0 KiB 0700 rpmbak
17 6144 7167 512.0 KiB FFFF hyp
18 7168 8191 512.0 KiB 0700 hypbak
19 8192 9215 512.0 KiB FFFF pmic
20 9216 10239 512.0 KiB 0700 pmicbak
21 10240 12287 1024.0 KiB FFFF cmnlib
22 12288 14335 1024.0 KiB 0700 cmnlibbak
23 14336 16383 1024.0 KiB FFFF cmnlib64
24 16384 18431 1024.0 KiB 0700 cmnlib64bak
25 18432 20479 1024.0 KiB FFFF abl
26 20480 22527 1024.0 KiB 0700 ablbak
27 22528 24575 1024.0 KiB FFFF dip
28 24576 26623 1024.0 KiB FFFF ddr
29 26624 28671 1024.0 KiB FFFF toolsfv
30 28672 30719 1024.0 KiB 0700 devcfgbak
31 30720 32767 1024.0 KiB FFFF devcfg
32 32768 40959 4.0 MiB FFFF tz
33 40960 49151 4.0 MiB 0700 tzbak
34 49152 57343 4.0 MiB FFFF mdtpsecapp
35 57344 65535 4.0 MiB 0700 mdtpsecappbak
36 65536 67583 1024.0 KiB FFFF keymaster
37 67584 69631 1024.0 KiB 0700 keymasterbak
38 69632 71679 1024.0 KiB FFFF bluetooth
39 71680 75775 2.0 MiB FFFF sti
40 75776 82943 3.5 MiB FFFF xbl
41 82944 90111 3.5 MiB 0700 xblbak
42 90112 98303 4.0 MiB FFFF misc
43 98304 114687 8.0 MiB FFFF devinfo
44 114688 131071 8.0 MiB FFFF logfs
45 131072 147455 8.0 MiB FFFF fsg
46 147456 163839 8.0 MiB FFFF modemst1
47 163840 180223 8.0 MiB FFFF modemst2
48 180224 212991 16.0 MiB FFFF dsp
49 212992 262143 24.0 MiB 8300 bk1
50 262144 327679 32.0 MiB FFFF mdtp
51 327680 393215 32.0 MiB 8300 bk2
52 393216 524287 64.0 MiB FFFF splash
53 524288 589823 32.0 MiB FFFF persist
54 589824 655359 32.0 MiB 0700 persistbak
55 655360 786431 64.0 MiB FFFF logdump
56 786432 1179647 192.0 MiB 0700 modem
57 1179648 1441791 128.0 MiB FFFF rawdump
58 1441792 1572863 64.0 MiB FFFF boot
59 1572864 1703935 64.0 MiB FFFF recovery
60 1703936 2228223 256.0 MiB FFFF cache
61 2228224 8519679 3.0 GiB FFFF system
62 8519680 12713983 2.0 GiB FFFF vendor
63 12713984 14417919 832.0 MiB FFFF cust
64 14417920 122142686 51.4 GiB FFFF userdata
What can I do now to have access to my raw decrypted data?
Easy: read the code and decrypt it.
Easy: read the code and decrypt it.
Decrypting: the legit way
So now I have a
The Android encryption scheme is known (as being open-source) so it shouldn't be too difficult to decrypt my data.
Looking at
userdata.img
1 that contains my data in an encrypted state.The Android encryption scheme is known (as being open-source) so it shouldn't be too difficult to decrypt my data.
Looking at
cryptfs.c
sure looks promising.Before Android 7, the scheme was the following:
- generate a random DEK (data encrypting key)
- encrypt /userdata with DEK
- user passphrase used to create the KEK (key encrypting key)
- KEK is used to encrypt the DEK
This way when you change your password only the KEK and the encrypted DEK are re-written.
This was good news because knowing the algorithm and the key you can decrypt your data.
This is why starting with Android 7, Google introduced a new algorithm involving hardware chips.
Dealing with this is much less fun and possibly proprietary code comes in the process.
Following the function calls has been too much of a hurdle and I'd need to actually talk to the hardware in the end anyway, so I would have to execute unauthorized code to do this.
Note that running unauthorized code is already something that would make me achieve my goal (path 3: how to be root without unlocking the bootloader) so no need to continue this.
Dealing with this is much less fun and possibly proprietary code comes in the process.
Following the function calls has been too much of a hurdle and I'd need to actually talk to the hardware in the end anyway, so I would have to execute unauthorized code to do this.
Note that running unauthorized code is already something that would make me achieve my goal (path 3: how to be root without unlocking the bootloader) so no need to continue this.
Decrypting: the tricky way
There is another thing worth mentioning though.
Instead of decrypting using the hardware keys, we may be able to trick the system to downgrade the encryption scheme to an older version where they are not used.
Instead of decrypting using the hardware keys, we may be able to trick the system to downgrade the encryption scheme to an older version where they are not used.
In crypt.c you can see these blobs of code:
c// Upgrade if we're not using the latest KDF. use_keymaster = keymaster_check_compatibility(); if (crypt_ftr->kdf_type == KDF_SCRYPT_KEYMASTER) { // Don't allow downgrade } else if (use_keymaster == 1 && crypt_ftr->kdf_type != KDF_SCRYPT_KEYMASTER) { crypt_ftr->kdf_type = KDF_SCRYPT_KEYMASTER; upgrade = 1; } else if (use_keymaster == 0 && crypt_ftr->kdf_type != KDF_SCRYPT) { crypt_ftr->kdf_type = KDF_SCRYPT; upgrade = 1; } if (upgrade) { rc = encrypt_master_key(passwd, crypt_ftr->salt, saved_master_key, crypt_ftr->master_key, crypt_ftr); if (!rc) { rc = put_crypt_ftr_and_key(crypt_ftr); } ...
cint cryptfs_changepw(int crypt_type, const char *newpw){ ... #ifdef CONFIG_HW_DISK_ENCRYPTION if (!strcmp((char *)crypt_ftr.crypto_type_name, "aes-xts")) { if (crypt_type == CRYPT_TYPE_DEFAULT) { int rc = update_hw_device_encryption_key(DEFAULT_PASSWORD, (char*) crypt_ftr.crypto_type_name); SLOGD("Update hardware encryption key to default for crypt_type: %d. rc = %d", crypt_type, rc); if (!rc) return -1; } else { int rc = update_hw_device_encryption_key(newpw, (char*) crypt_ftr.crypto_type_name); SLOGD("Update hardware encryption key for crypt_type: %d. rc = %d", crypt_type, rc); if (!rc) return -1; } } #endif ... }
As you can see, it wouldn't be too difficult to either perform a scheme downgrade or even to retrieve the master key itself.
But again we have a problem because there are two choices:
But again we have a problem because there are two choices:
- modify
system.img
orboot.img
to change the code, but to do this you need to unlock the bootloader so we are back to path (1) - or patch the kernel once booted and then change the password to trigger a new encryption, but that would mean running unauthorized code, which is path (3)
It's again a dead end, path (2) doesn't seem possible.
Be root without unlocking the bootloader
This chapter will be short because there is another article on this subject with many explanations that didn't fit in this one.
There are two ways to have root access without unlocking the bootloader: either you modify a partition to have the
su
binary in your booted system or you exploit a vulnerability to gain root access.Partition editing
Modifying partitions is widely known in the Android world as it is what is done by issuing commands like
Depending on the expected result it targets a specific partition.
In the boot chain I previously mentioned, it is clear you can't do what you want: if your bootloader is locked, the SBL and the ABL will have to trust the next link and will check it is signed with a key they know.
fastboot flash boot boot.img
or by flashing from inside a custom recovery.Depending on the expected result it targets a specific partition.
In the boot chain I previously mentioned, it is clear you can't do what you want: if your bootloader is locked, the SBL and the ABL will have to trust the next link and will check it is signed with a key they know.
'Destroyed' actually means 'tampered with'
Flashing the original partitions back 'undestroys' the system
Flashing the original partitions back 'undestroys' the system
You don't have the Xiaomi signing key so you can't produce a valid signature if you change
You don't have the Xiaomi signing key so you can't produce a valid signature if you change the ABL, so the SBL/XBL will reject it and show you an error.
You don't have the Xiaomi signing key so you can't produce a valid signature if you change the SBL/XBL, so the PBL will reject it and show you an error.
boot.img
, system.img
or vendor.img
, so the ABL will reject them and show you an error.You don't have the Xiaomi signing key so you can't produce a valid signature if you change the ABL, so the SBL/XBL will reject it and show you an error.
You don't have the Xiaomi signing key so you can't produce a valid signature if you change the SBL/XBL, so the PBL will reject it and show you an error.
Final answer is: if you want to edit the partitions, you have to attack the PBL.
I didn't have the time to play with this but I'll try to make a full article on this later.
I didn't have the time to play with this but I'll try to make a full article on this later.
Exploit a vulnerability to gain root access
During my research I stumbled upon a vulnerability used to root Pixel 2 XL's.
I didn't think much of it at first because all the previous paths were more or less simultaneously being tried.
Finally this became the most promising way to claim my data back.
I didn't think much of it at first because all the previous paths were more or less simultaneously being tried.
Finally this became the most promising way to claim my data back.
This is what I finally used and this is what I finally got.
More on this in this article: Exploiting CVE-2019-2215 to gain root access on the Redmi Note 5 Pro (whyred)
More on this in this article: Exploiting CVE-2019-2215 to gain root access on the Redmi Note 5 Pro (whyred)
This vulnerability has been patched in the Android security patch of october 2019 that is included in MIUI 11.
Fortunately even though I didn't take the time to root my phone, I always thought it would be better to stay on the lowest possible version if one day I attempt the rooting.
Fortunately even though I didn't take the time to root my phone, I always thought it would be better to stay on the lowest possible version if one day I attempt the rooting.
Conclusion
Sadly the easiest way to do that is using an Android vulnerability.
Also I will never buy a Xiaomi product ever again.
Also I will never buy a Xiaomi product ever again.
Notes
1:
dd if=all.img of=userdata.img skip=14417920 count=$((122142686-14417920+1))
No comments yet