|
Double Free Vulnerabilities - Part 2
Double Free Vulnerabilities - Part 2
<p>Continued from <a href="http://www.symantec.com/enterprise/security_response/weblog/2007/01/double_free_vulnerabilities_pa.html">Part 1</a>... </p>
<p><strong>Exploiting double free vulnerabilities: Case 1</strong></p>
<p>The first way that a double free vulnerability can be exploited is when the first free puts the chunk on the <span class="MD_monospace">Lookaside</span> (which the Windows heap implementation tries to use before the <span class="MD_monospace">FreeList</span> since it's more efficient). When a chunk is freed to the <span class="MD_monospace">Lookaside</span>, the Chunk is still marked as busy (that is, <span class="MD_monospace">Chunk.Flags & BUSY_FLAG</span> is set) to prevent the chunk from being coalesced with the previous/next chunk. That's because entries on the <span class="MD_monospace">Lookaside</span> list are meant to be a fast allocate/deallocate (akin to "fast bins" in the GLIBC and related Unix heap implementations). By contrast, entries on the <span class="MD_monospace">FreeList</span> are frequently coalesced when a chunk is being freed and the chunk before/after it is also free (to make larger contiguous chunks of memory available and avoid heap fragmentation).</p>
<p>So after the first free (in the double free vulnerability) the chunk is put onto the <span class="MD_monospace">Lookaside</span> and left marked as busy. The <span class="MD_monospace">Lookaside</span> will only fit four entries per chunk size (initially)—in other words, only allow four chunks of size X before putting the remainder on the <span class="MD_monospace">FreeList</span>. If an attacker can manipulate how many allocations/frees occur (as is possible with some vulnerabilities, such as the Exchange XEXCH heap vulnerability from a year or two ago), the attacker can cause the first free to fill up the <span class="MD_monospace">Lookaside</span>. The second free (the double free that produces the vulnerability), therefore, will <em>also</em> put the chunk onto the <span class="MD_monospace">FreeLists</span>. That is, there are two different locations—the <span class="MD_monospace">Lookaside[SizeX]</span> and also the <span class="MD_monospace">FreeLists[SizeX]</span>—that point to this chunk. That means we can allocate the chunk off the <span class="MD_monospace">Lookaside</span> first (since the <span class="MD_monospace">Lookaside</span> is checked first) and then overwrite the <span class="MD_monospace">Flink/Blink</span> still contained in the chunk's data (since it's still on the <span class="MD_monospace">FreeList</span>). So when the <em>SizeX</em> chunk on the <span class="MD_monospace">FreeLists</span> is eventually allocated, it will unlink that chunk (which is simultaneously allocated via the <span class="MD_monospace">Lookaside</span>) and a four-byte overwrite will occur since the attacker has already modified that chunk.</p>
<p><strong>Exploiting double free vulnerabilities: Case 2</strong></p>
<p>Another interesting case of double frees is when both times the chunk is put on the <span class="MD_monospace">Lookaside</span> list (that is, there are at least two available slots on <span class="MD_monospace">Lookaside[SizeX]</span>). Since the entry is still marked as busy after the first free (since chunks on the <span class="MD_monospace">Lookaside</span> are left as busy) it will be freed again, and the same chunk will be on the <span class="MD_monospace">Lookaside</span> twice:<br />
<br />
<span class="MD_monospace">Lookaside[SizeX] -> AttackerChunk -> AttackerChunk</span></p>
<p>This means that after the first allocation, <span class="MD_monospace">AttackerChunk</span> will be returned (the first entry) but <span class="MD_monospace">Lookaside[SizeX]</span> will still point to <span class="MD_monospace">AttackerChunk</span>. Because <span class="MD_monospace">AttackerChunk</span> has already been allocated once, the attacker can modify the Flink pointer (offset 0 of a free chunk on the <span class="MD_monospace">Lookaside</span>) and then allocate a <em>SizeX </em>chunk again. The <span class="MD_monospace">Lookaside</span> will now point to arbitrary address. With one final allocation of <em>SizeX</em>, the attacker will receive a pointer to whatever address he overwrites the <span class="MD_monospace">Flink</span> with and will be able to modify up to <em>SizeX</em> bytes at an arbitrary address in memory.</p>
<p><strong>Windows Vista heap mitigations</strong></p>
<p>Heap overflows on Windows Vista have several mitigations that will make double free vulnerabilities more difficult to exploit: </p>
<p>1. Randomized heap base. You need to know the <span class="MD_monospace">FreeLists[]</span> address in order to defeat safe unlinking.<br />
2. The <span class="MD_monospace">Flink/Blink</span> are now encoded pointers (they are XOR’d with a random value initialized once when the process starts). So even if you know the <span class="MD_monospace">FreeLists[]</span> address, you also have to know the random value that the <span class="MD_monospace">Flink/Blink</span> are XOR’d with. If you guess the incorrect random value, you will read from random memory locations.<br />
3. Exit on heap corruption rather than silently ignored. This is opt-in functionality, as far as I know, but most of the Windows core components (I assume CSRSS also) will have this enabled.<br />
4. The <span class="MD_monospace">Lookaside</span> list has been replaced with the Low Fragmentation Heap (LFH). I’ve briefly touched on the LFH implementation in the SyScan 2004 presentation. It has not been well ****yzed yet, but initial indications are that LFH is significantly harder to abuse than the <span class="MD_monospace">Lookaside</span> list was.<br />
</p>
http://www.symantec.com/enterprise/security_response/weblog/2007/01/double_free_vulnerabilities_pa_1.html
http://www.symantec.com/enterprise/security_response/weblog/2007/01/double_free_vulnerabilities_pa_1.html
Mon, 22 Jan 2007 06:30:00 -0800
|