Kindles are a device that people use for reading ebooks. Kindles can download books and have other features as well. The author discovered a chain of three bugs that lead to RCE on the kindle.
Kindles have a feature called Send To Kindle that allows users to send an email to special Amazon Kindle email which will load the book onto the device automatically. However, there is an allowlist on the email for who can send these.
Email servers are commonly unauthenticated and do not validate the authenticity of the sender of the email. So, an attacker can spoof the sender email address and send a device to ANY Kindle.
With the ebook on the device, is there anything that can be done? This is the question that the author asked themselves. Books have a lot of functionality, such as image rendering, font rendering and many other things.
After getting off all of the binaries on device (jailbroken kindle) a particular library stood out: libjpegXR. This is an obscure image format, which looked like a good attack surface.
While looking at the official reference implementation of the parsing format, the author came up with some ideas for potential things that a developer would miss. One of these identified checks was indeed missing, which made for an excellent exploit. This buffer overflow in the image parsing format was easily repeatable and allowed for a nice arbitrary write primitive by overflowing a nearby object.
To make matters worse, the binary is loaded at a constant address and does not have the Nx flag; this means that some memory can be writable, readable and executable! To exploit this, the author used the arbitrary-write to overwrite a GOT address to jump to the authors shellcode.
At this point though, the user has NO privileges. There was a script (running with higher privileges) that allowed debugging of the binary using GDB. However, one of the passed in parameters to GDB was NOT escaped (shell metacharacters). Using this, an attacker could inject a shellscript into the GDB startup!
This trick was a known issue to the developers, which they attempted to prevent by validating with a call to atoi. However, atoi will only validate the number if it is used at the beginning. This means that something like 1 hello would parse as the number 1.
Additionally, the developers attempted to use the regex ^[0–9]*$, which says only numbers. However, this will match per line! Adding a newline into the could match for the first line, not the second, and still pass the check. According to the people at DayZeroSec, this is a fairly common issue.
The fixes are as follows:
- In cases where Amazon cannot authenticate the sending email address, they now send a verification link to the approved address.
- The buffer overflow just added a sanity check on a size parameter.
- The GDB script now validates that ONLY numbers are in the string.
An additional thing to note is that a user would have to click on an ebook then a link within the ebook in order to exploit this. Although this is NOT zero-click, it is still a really good collection of findings.