Part 1: Heap Exploit Development on iOS
In my previous posts, I talked about the general strategy used in an iOS exploit to turn a heap overflow vulnerability into a use after free vulnerability. The reason the exploit developer did this was because the attacker had little control over the heap overflow itself; the data that spilled past the end of the allocation would corrupt a neighboring object by overwriting the beginning of it with a kernel heap pointer that the exploit developer can’t control with any precision. The exploit developer therefore needed to find a good victim object that could be corrupted with this kernel pointer. They could then free the underlying data belonging to that pointer, and any further use of the victim object’s pointer would immediately be a use-after-free.
While it is a great strategy to use vulnerability conversion to turn hard-to-exploit vulnerabilities into easier-to-exploit vulnerabilities, exploiting this bug still requires a bit of work to get the victim object to sit just after the overflow object. Only then will the overflow definitely corrupt the victim object and not some other random object on the heap. The theory may be great, but getting it to actually happen in practice requires a “heap groom”.
The need for heap grooms is one of the big differences between heap exploitation and stack exploitation, and a reason why heap overflows tend to be much more complex to exploit. Let’s take a look in more detail at how it works.