Subject: w00w00 on Heap Overflows This is a PRELIMINARY BETA VERSION of our final article! We apologize for any mistakes. We still need to add a few more things. [ Note: You may also get this article off of ] [ http://www.w00w00.org/articles.html. ] w00w00 on Heap Overflows By: Matt Conover (a.k.a. Shok) & w00w00 Security Team —————————————————————————— Copyright (C) January 1999, Matt Conover & w00w00 Security Development You may freely redistribute or republish this article, provided the following conditions are met: 1. This article is left intact (no changes made, the full article published, etc.) 2. Proper credit is given to its authors; Matt Conover (Shok) and the w00w00 Security Development (WSD). You are free to rewrite your own articles based on this material (assuming the above conditions are met). It’d also be appreciated if an e-mail is sent to either mattc@repsec.com or shok@dataforce.net to let us know you are going to be republishing this article or writing an article based upon one of our ideas. —————————————————————————— Prelude: Heap/BSS-based overflows are fairly common in applications today; yet, they are rarely reported. Therefore, we felt it was appropriate to present a “heap overflow” tutorial. The biggest critics of this article will probably be those who argue heap overflows have been around for a while. Of course they have, but that doesn’t negate the need for such material. In this article, we will refer to “overflows involving the stack” as “stack-based overflows” (”stack overflow” is misleading) and “overflows involving the heap” as “heap-based overflows”. This article should provide the following: a better understanding of heap-based overflows along with several methods of exploitation, demonstrations, and some possible solutions/fixes. Prerequisites to this article: a general understanding of computer architecture, assembly, C, and stack overflows. This is a collection of the insights we have gained through our research with heap-based overflows and the like. We have written all the examples and exploits included in this article; therefore, the copyright applies to them as well. Why Heap/BSS Overflows are Significant ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ As more system vendors add non-executable stack patches, or individuals apply their own patches (e.g., Solar Designer’s non-executable stack patch), a different method of penetration is needed by security consultants (or else, we won’t have jobs!). Let me give you a few examples: 1. Searching for the word “heap” on BugTraq (for the archive, see www.geek-girl.com/bugtraq), yields only 40+ matches, whereas “stack” yields 2300+ matches (though several are irrelevant). Also, “stack overflow” gives twice as many matches as “heap” does. 2. Solaris (an OS developed by Sun Microsystems), as of Solaris 2.6, sparc Solaris includes a “protect_stack” option, but not an equivalent “protect_heap” option. Fortunately, the bss is not executable (and need not be). 3. There is a “StackGuard” (developed by Crispin Cowan et. al.), but no equivalent “HeapGuard”. 4. Using a heap/bss-based overflow was one of the “potential” methods of getting around StackGuard. The following was posted to BugTraq by Tim Newsham several months ago: > Finally the precomputed canary values may be a target > themselves. If there is an overflow in the data or bss segments > preceding the precomputed canary vector, an attacker can simply > overwrite all the canary values with a single value of his > choosing, effectively turning off stack protection. 5. Some people have actually suggested making a “local” buffer a “static” buffer, as a fix! This not very wise; yet, it is a fairly common misconception of how the heap or bss work. Although heap-based overflows are not new, they don’t seem to be well understood. Note: One argument is that the presentation of a “heap-based overflow” is equivalent to a “stack-based overflow” presentation. However, only a small proportion of this article has the same presentation (if you will) that is equivalent to that of a “stack-based overflow”. People go out of their way to prevent stack-based overflows, but leave their heaps/bss’ completely open! On most systems, both heap and bss are both executable and writeable (an excellent combination). This makes heap/bss overflows very possible. But, I don’t see any reason for the bss to be executable! What is going to be executed in zero-filled memory?! For the security consultant (the ones doing the penetration assessment), most heap-based overflows are system and architecture independent, including those with non-executable heaps. This will all be demonstrated in the “Exploiting Heap/BSS Overflows” section. Terminology ~~~~~~~~~~~ An executable file, such as ELF (Executable and Linking Format) executable, has several “sections” in the executable file, such as: the PLT (Procedure Linking Table), GOT (Global Offset Table), init (instructions executed on initialization), fini (instructions to be executed upon termination), and ctors and dtors (contains global constructors/destructors). “Memory that is dynamically allocated by the application is known as the heap.” The words “by the application” are important here, as on good systems most areas are in fact dynamically allocated at the kernel level, while for the heap, the allocation is requested by the application. Heap and Data/BSS Sections ~~~~~~~~~~~~~~~~~~~~~~~~~~ The heap is an area in memory that is dynamically allocated by the application. The data section initialized at compile-time. The bss section contains uninitialized data, and is allocated at run-time. Until it is written to, it remains zeroed (or at least from the application’s point-of-view). Note: When we refer to a “heap-based overflow” in the sections below, we are most likely referring to buffer overflows of both the heap and data/bss sections. On most systems, the heap grows up (towards higher addresses). Hence, when we say “X is below Y,” it means X is lower in memory than Y. Exploiting Heap/BSS Overflows ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In this section, we’ll cover several different methods to put heap/bss overflows to use. Most of examples for Unix-dervied x86 systems, will also work in DOS and Windows (with a few changes). We’ve also included a few DOS/Windows specific exploitation methods. An advanced warning: this will be the longest section, and should be studied the most. Note: In this article, I use the “exact offset” approach. The offset must be closely approximated to its actual value. The alternative is “stack-based overflow approach” (if you will), where one repeats the addresses to increase the likelihood of a successful exploit. While this example may seem unnecessary, we’re including it for those who are unfamiliar with heap-based overflows. Therefore, we’ll include this quick demonstration: —————————————————————————– /* demonstrates dynamic overflow in heap (initialized data) */ #include#include #include #include #define BUFSIZE 16 #define OVERSIZE 8 /* overflow buf2 by OVERSIZE bytes */ int main() { u_long diff; char *buf1 = (char *)malloc(BUFSIZE), *buf2 = (char *)malloc(BUFSIZE); diff = (u_long)buf2 - (u_long)buf1; printf(”buf1 = %p, buf2 = %p, diff = 0x%x bytesn”, buf1, buf2, diff); memset(buf2, ‘A’, BUFSIZE-1), buf2[BUFSIZE-1] = ‘
