The notes functionality is basically a HTML browser included in the iPod. Some documentation about it can be found here.
Basic rules are:
- 64kB files are loaded just after the boot of the iPod, however they are not kept in RAM
- each file is limited to 4kB
- the links point to other files, notes, or media files.
- the link is limited to 256 chars. Apple documents this limit, but they don't say it can cause a buffer overflow ;)
There are many buffers scattered throughout the RAM:
- Some are perfect copies of the disc file, including BOM, etc... These are the ideal buffers to jump to.
- Some have UTF16 processing. These are a burden but can be worked around.
- Some have UTF8 processing. These are virtually unusable.
The main disadvantage to this vulnerability is that small buffers must be located in megabytes of RAM. The Pwnage 2.0 vulnerability is now preferred since it does not have this disadvantage.
Dealing with UTF-16
If jumping to a UTF16-processed buffer, the possible character sequences are limited. The best thing to have the most charset possibilities is to encode the exploit directly to UTF16.
The forbidden values in UTF16 are:
- FE FF: UTF16 BOM
- D8 00 up to DF FF: not checked what happens if inserting them
- 00 00: would stop string processing
The payload is placed in the body of the .htm file.
After loading the file, the links are then checked against the file system. Many modified copies of this string are present on the stack. We could identify the most important steps of this process, until the string overflow in the stack (order could be a little different):
- Fist, the link is extracted from the file, and copied to some heap or fixed buffers
- The link is converted to UTF8. Every char >7F is encoded in many bytes
- Then it is passed through an uppercase function
- The URL encoding is decoded : %xx values are converted to their equivalent (limited to valid UTF8 or the like)
- Finally, this link is copied in a limited buffer which is located on the stack. By putting a return adress repetitively in the link, the processor will jump to this adress.
For conveninece, the return adress is always encoded using %xx URL encodings. This avoids problems with some special chars and with lowercase chars. Possible values are 00 < xx <= 7F. (the unescaped chars seem to be transcoded from ISO-8859-1 to UTF8 again)
Exploiting, getting execution
(Credit for the exploit goes to Sto)
To exploit, we used JTAG to determine the correct paddings and return adresses of the buffers.
In my case, I had to place a second file to influence the buffer's location in order to have a return adress which conforms to UTF8 (no byte of the return address can be >7F).
An example of a working overflow file set is here. The file "Brokenlink.htm" begins with a UTF16 BOM, then "AA" as padding, then the overflowing link (the return address is 0x08640D60), then a NOP (opcode E1A01001) landing zone, and finally a "while(1);"
This "while(1);" does not freeze or reset the iPod, but instead just crashes the background task since interrupts are still enabled. You can still scroll the menus, but the ipod will freeze as soon as you press "play" or if you enter the notes menu, etc...
The processor arrives at the notes payload in supervisor state, with interrupts activated (menu scrolling) and so on. Caches are also activated. Disabling them is recommended if you are performing complex IO & DMA stuff because they can interfere.
For dumping the iPod's memories, first the cache was used (JTAG dumps), but it turned out that the UART is more flexible. The dumps can't be published here, due to copyright issues.
The UART is exactly the same as described in the datasheet (if one did indeed exist).
See this guide for building a UART cable for the iPod dock connector.
My complete setup is a little bit more complex:
- left board: DLC5 JTAG interface, modified for reset and USB switching
- right board: some programmer board, only the ST232 is used
- upper board: this was the JTAG scanner, now only the power supply and 5V regulator are used
- middle board: all the switching stuff
To automatically enter DFU mode, I wired transistors to the USB 5V line, and to the "play" and "enter" buttons of the clickwheel.
USB was eventually figured out so we no longer needed the UART cables.