»In April, I ran across a nice bug in iTunes URL parsing which is accessible automatically from Safari.
It turns out that URL components following a colon are copied from the heap buffer containing the URL to a stack buffer. This copy is unbounded which leaves iTunes exposed to a classic stack buffer overflow. However, it comes with a number of constraints:
- the payload must be URL-safe (otherwise it is automatically encoded to %XX) - the stack is set non-executable
Given these constraints, I had expected a long slog when it came to exploiting the vulnerability. However, it's possible to bypass both of those limitations quite easily.
== Bypassing a non-executable stack
iTunes makes this quite trivial. If we look at the register state when we clobber the stack, we see that the ECX register is a pointer to the heap buffer containing the remaining URL. In particular, we can get it to point to the section just after the '/':
With that in place, we just need to find a way to jump the that register...
== Dealing with a URL-safe-only attack payload
The URL-safe attack payload highly restricts the contents that can be sent across. Thankfully, there are ASCII-encoders for x86. So if we can assume we can get working shell code, we still have to figure out how to get to it. Turns out, it's also pretty easy.
Any text preceding the '/' in the URL is truncated with NULs. This means that if we supply alphanumeric characters that address in to the text segment, we can mask the higher order bits using truncation. For instance, ATe/ would become 0x00655441:
00655441 jmp *%ecx
Well, now we can jump to our ASCII-encoded payload. The last wrinkle is that the ECX pointer varies depending on the content. That is easily sorted by placing another ':' after the '/' and setting the offset of the ASCII decoder to the length of the additional characters.