AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |
Back to Blog
![]() ![]() ![]() Bits which are set to one represent disallowed blocks, and zero bits represent allowed blocks. Now that we understand how the validation functions operate, let's see how we can use the zero write primitive in order to disable their operation.įirst, as described above, the "is_disallowed_range" function uses a table of 32-bit entries, where each bit corresponds to a 1MB block of memory. Let's start by giving the memory validation function a name - from now on, we'll call it "tzbsp_validate_memory". These validations sound like a prime candidate for us to look into, since if we were able to disable their operation, we'd be able to leverage other SCM calls in order to create different kinds of primitives. The validation is done in order to make sure the physical address is within an "allowed" range, and isn't for example, within the TrustZone kernel's used memory ranges. We could try and edit any modifiable data (such as the heap, the stack or perhaps globals) within the TrustZone kernel, which might allow us to create a stepping stone for a better primitive.Īs we've mentioned in the previous blog post, normally, when an SCM command is called, any argument which is a pointer to memory, is So that said - how can we leverage a zero write primitive to enable full code execution? TrustZone memory mappings and permissions That once TrustZone's code is loaded into memory, it theoretically cannot (and should Permissions, and are verified during the secure boot process. Moreover, the TrustZone code segments are mapped with read-only access However, the internal data structures and state of the TrustZone kernel are largely unknown and subject to change due to the many different processes interacting with the TrustZone kernel (from external interrupts, to "Secure World" applications, etc.). Since the TrustZone kernel is loaded at a known physical address, this means that all of the addresses are already known in advance, and do not need to be discovered upon execution. ![]() In order to create a robust exploit using such a primitive, the first course of action would be to attempt to leverage this weak primitive into a stronger one. They are generally quite limited, and don't always lead to exploitable conditions. Zero write primitives are, drawing on personal experience, not very fun to work with. If you read the previous post, you already know that the vulnerability allows the attacker to cause the TrustZone kernel to write a zero DWORD to any address in the TrustZone kernel's virtual address space. With that out of the way, let's get right to it! In case anyone wants to recreate the exact research described below, or for any other reason, the exact version of my device at the time was: This means that all memory addresses and other specific information written below is taken from that device. While developing this exploit, I only had my trusty (personal) Nexus 5 device to work with. ![]() They've also gifted me a brand new (at the time) Moto X 2014, which will be the subject of many posts later on (going much more in depth into TrustZone's architecture and other security components on the device). I'd also like to take this opportunity to point out that Qualcomm did an amazing job in both responding to the disclosure amazingly fast and by being very keen to fix the issue as soon as possible. If you haven't read it already, please do!įirst of all, I'd like to point out that I've responsibly disclosed this vulnerability to Qualcomm, and the issue has already been fixed (see "Timeline" below). In this blog post, we'll cover the complete process of exploiting the TrustZone vulnerability described in the previous post. ![]()
0 Comments
Read More
Leave a Reply. |