Resources

People often ask me "How did you learn how to hack?" The answer: by reading. This page is a collection of the blog posts and other articles that I have accumulated over the years of my journey. Enjoy!

Attacking the Android kernel using the Qualcomm TrustZone- 1258

Tamir ZhaviPosted 2 Years Ago
  • Arm TrustZone is a Trusted Execution Environment (TEE) which runs two operating systems: a secure world and a non-secure world. For instance, a cryptographic service could be on the secure world. Then, a user could make a request to sign the data, without directly having access to the key. The Qualcomm secure world is called Qualcomm Secure Execution Environment (QSEE) but has not seen much use.
  • Android runs the non-secure code and the QSEE contains user mode programs called trustlets. An Android user program sends a special ioctl that the kernel will handle and send to the secure world. This process is performed using shared memory. Write to some place, send the ioctl and then the secure world will do the processing and write back to the specified location.
  • The simple protocol is not always enough. In these cases, some truslets need read/write access to memory, requiring the use of pointers. There's potential for abuse though: writing of arbitrary addresses to physical memory is bad and giving the trustlet access to the buffers directly is scary.
  • To prevent these attacks, Qualcomm adds ION file descriptors, each represents an offset into the input buffer. Upon receiving the write request, the ION buffer is translated back to its original form. There is an allowlist for what descriptor can access what memory with a given offset.
  • This offset causes major problems. By using the offset into the middle of these tables, we can get it to pull addresses part way in between. Although we can't write to arbitrary addresses, we can write to these corrupted addresses. The images in the article explain this super well.
  • The difference between physical and virtual memory is important here. The virtual memory may be contiguous but not the physical. As a result, the buffer must contain information about both the address and the size of it. So, this allows us to control both the address and the size of the data being copied in.
  • By using the primitive, the author was able to corrupt the allowlist table itself. Now, the buffers physical memory is mapped to the entire Android kernel. The author needed a primitive where they could write to arbitrary locations using the allowlist bypass they found. The widevine DRM has a bunch of complicated pointer functionality that was perfect for this. Using the encrypt/decrypt functionality made this easy to get a R/W primitive.
  • Overall, an interesting post on using TrustZone to attack the Android kernel. The fundamental design flaw of the system was surprising. I didn't fully understand the entire exploit mechanism but enjoyed it regardless.