- CVE-2021-40020 OOB Access in CmdInitObjectWithKeys
The SignTool TA conforms to the GlobalPlatform TEE Internal Core API. As such, it receives commands from a client application located in the normal world. These commands are handled by the TA_InvokeCommandEntryPoint
function. This TA implements 16 commands, including CmdInitObjectWithKeys
which contains a vulnerability.
OOB Access in CmdInitObjectWithKeys
¶
CmdInitObjectWithKeys
is used to allocate a transient object populated with a user-provided set of attributes. For example, the object could be a RSA keypair, and its attributes the modulus, public exponent and private exponent. retrieveUint32FromBuffer
simply dereferences its argument, byte-swaps it and returns it.
int CmdInitObjectWithKeys(void *session, unsigned int paramTypes, TEE_Param *params) {
// [...]
attrInfo = (uint32_t *)params[1].memref.buffer;
attrData = (uint8_t *)params[2].memref.buffer;
// [...]
i = 0;
do {
attributeID = retrieveUint32FromBuffer(attrInfo);
offset = retrieveUint32FromBuffer(attrInfo + 1);
length = retrieveUint32FromBuffer(attrInfo + 2);
attrInfo += 3;
TEE_InitRefAttribute(&attrs[3 * i++], attributeID, attrData + offset, length);
}
while (i < attrCount);
// [...]
object = *(TEE_ObjectHandle *)session;
TEE_PopulateTransientObject(object, attrs, attrCount);
// [...]
}
For each attribute, the user needs to provide 3 dwords in the first buffer attrInfo
:
- the
attributeID
; - the
offset
of the attribute data in the second bufferattrData
; - the
length
of the attribute data.
The issue is that the offset
is unbounded, so attrData + offset
can be made to point to an arbitrary location. During the later call to TEE_PopulateTransientObject
, the attribute data will be copied into an object handle that is saved in the session.
Exploitation¶
Our Device Setup¶
The device we have developed an exploit for is a P40 Pro running the firmware update ELS-LGRP4-OVS_11.0.0.196
. The trustlet binary MD5 checksum is as follows:
HWELS:/ # md5sum /vendor/bin/9b17660b-8968-4eed-917e-dd32379bd548.sec
f47939bd8d271f0cc8bedbd02042bb28 /vendor/bin/9b17660b-8968-4eed-917e-dd32379bd548.sec
Huawei's TEE OS iTrustee implements a whitelist mechanism that only allows specific client applications (native binaries or APKs) to talk to a trusted application.
In our case, the HuaweiNfcActiveCard TA can only be called by 4 native binaries and 2 APKs:
/vendor/bin/atcmdserver
(uid 0);system_server
(uid 1000);com.huawei.systemserver
APK;com.huawei.cryptosms.service
APK;/vendor/bin/hw/vendor.huawei.hardware.huaweisigntool@1.0-service
(uid 1000);/vendor/bin/hw/vendor.huawei.hardware.hwsecurity-service
(uid 1000).
The authentication mechanism is implemented in 3 parts:
- the teecd
daemon, that implements the TEE Client API, checks which native binary/APK is talking to it and sends that information to the kernel driver;
- the kernel driver ensures that it is talking to teecd
, and forwards the information it received to the TEE OS;
- the TEE OS verifies that the client application is in the TA's whitelist.
Since we did not want to bother with injecting code in one of these binaries, we chose to circumvent the authentication by patching the kernel driver to add the ability to impersonate any native binary/APK.
Arbitrary Read¶
To achieve an arbitrary read, we first send a CmdInitObjectWithKeys
command to initialize an RSA keypair object with 3 attributes: a modulus, public exponent and private exponent. By specifying an offset of addr
- attrData
for the modulus, it will be initialized with the data located at addr
. We obtained the address of the second input buffer attrData
empirically and using knowledge from past exploits, and verified that this address always stays the same.
Next we send a CmdGetPublicKey
command that returns the modulus and public exponent from the object we just created. The modulus attribute data will be the data that was read from addr
.
In the exploit, we demonstrate our read primitive by dumping the trustlet memory:
adb wait-for-device shell su root sh -c 0 "/data/local/tmp/ta_signtool"
ta_base_addr = 380d000
0x0380d000: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 .ELF............
0x0380d010: 03 00 28 00 01 00 00 00 cc 10 00 00 34 00 00 00 ..(.........4...
0x0380d020: 88 69 00 00 00 02 00 05 34 00 20 00 05 00 28 00 .i......4. ...(.
0x0380d030: 11 00 10 00 01 00 00 00 00 00 00 00 00 00 00 00 ................
Affected Devices¶
We have verified that the vulnerability impacted the following device(s):
- Kirin 990: P40 Pro (ELS)
Please note that other models might have been affected.
Patch¶
Name | Severity | CVE | Patch |
---|---|---|---|
OOB Access in CmdInitObjectWithKeys |
Critical | CVE-2021-40020 | January 2022 |
Timeline¶
- Oct. 08, 2021 - A vulnerability report is sent to Huawei PSIRT.
- Nov. 16, 2021 - Huawei PSIRT acknowledges the vulnerability report.
- Jan. 01, 2022 - Huawei PSIRT states that these issues were fixed in the January 2022 update.
- From Nov. 30, 2022 to Jul, 19 2023 - We exchange regularly about the release of our advisories.
Copyright © Impalabs 2021-2023