exploit Programmers are getting smarter → Stack overflows are getting extinct Stack is only the one side of the coin! What about other memory regions? We no longer live in the ‘90s Not sure if this is good or bad 4 argp & huku - FOSSCOMM 2011 Patras Heap Massacre
Heap data structures. Several authors began about 1975 to call the pool of available memory a “heap.” – Donald Knuth Unlike stacks, there’s no hardware (CPU) support for heaps. Heap managers have to organize memory by themselves Heap managers are 100% implemented in software (usually in C) …and, of course, they use their own housekeeping information (usually inline) …and this is where the problems begin :-) 5 argp & huku - FOSSCOMM 2011 Patras Heap Massacre
needs are known at compile time If they were, we would only need static memory Need to split a large memory area into small blocks in a dynamic fashion …and a userspace/kernel space API for doing so Preferably one that abstracts the internals. Advantages No/reduced fragmentation of the available memory Increased performance 6 argp & huku - FOSSCOMM 2011 Patras Heap Massacre
Layout Randomization Limited entropy – Usually only the first few bits of an address are randomized Example on Linux: $ cat /proc/self/maps 10 argp & huku - FOSSCOMM 2011 Patras Heap Massacre
Heap Massacre Organizes physical memory frames in caches Each cache holds slabs of objects of the same size General caches: kmalloc-64, kmalloc-96, etc Kernel structure specific caches: mm_struct, task_struct, dentry, etc The objects on a slab are contiguous A slab may have both allocated (used) and deallocated (free) objects
Heap Massacre Each slab is at least PAGE_SIZE bytes (default 4096) A slab may span many pages A kmalloc-32 slab has 128 objects (128 * 32 == 4096) A task_struct (1088 bytes) slab has 30 objects (30 * 1088 == 32640) A task_struct slab spans 8 pages (8 * 4096 == 32768) Each CPU core has its own slabs
Massacre No separate/dedicated metadata structures stored on the slabs Each free object stored on a slab has a next-free-object pointer Each slab has a page structure (struct page) that has a pointer (freelist) to the first free object of the slab
Heap Massacre Partial slabs, some free, some used objects New requests satisfied from partial slabs Least-recently-used (LRU) policy No partial slabs → new slab is allocated Allocations on a new slab are consecutive and objects are contiguous Generic slabs (e.g. kmalloc-32) are used to store objects of the same size But the type can differ (i.e. different kernel structures)
the slabs Corrupt adjacent objects on the slabs We need suitable kernel structures that we can allocate/deallocate at will from userland (e.g. syscall) Selection depends on content Selection also depends on size: we want it on the same slab as the object we can overflow from Bring target slab to a predictable state in order to have the victim structure after the overflown structure 32 argp & huku - FOSSCOMM 2011 Patras Heap Massacre
Patras Heap Massacre 1. Find free objects on target slab: /proc/slabinfo 2. Ensure allocations/deallocations happen on the slabs of the same CPU (sched_setaffinity(2)) 3. Consume a large number of objects that go on the target slab (reducing fragmentation) 4. Deallocate a small number of objects from the target slab 5. Allocate a smaller number of our selected victim objects 6. Trigger the overflow bug 7. Overwrite the structure/object we have selected Exploitation is specific to the selected structure
FOSSCOMM 2011 Patras Heap Massacre FreeBSD’s kernel memory allocator Funded by Nokia for a proprietary project The IPSO firewall/security appliance (thanks FX!) Donated to FreeBSD Functions like a traditional slab allocator Large areas, or slabs, of memory are initially allocated Items of specific type and size are pre-allocated on the slabs malloc(9) returns a pre-allocated item marked as free from a slab Size adjusted for alignment to find a slab
Heap Massacre Each zone (uma_zone) holds buckets (uma_bucket) of items The items are allocated on the zone’s slabs (uma_slab) Each zone is associated with a keg (uma_keg) The keg holds the corresponding zone’s slabs Each slab has a slab header (uma_slab_head) with metadata Slab header may or may not be inline
Patras Heap Massacre 1. Find free items on target zone 2. Consume all free items 3. Allocate enough items to fill a slab of the target zone Trigger the overflow on all of these One will be the last item on the slab 4. Overwrite the address of us_keg in uma_slab_head with a userland address 5. Construct a fake us_keg with the address of a fake uma_zone Point the uz_dtor function pointer to the shellcode 6. Deallocate all items that triggered the overflow 7. free(9) → uma_zfree_arg() → uz_dtor() → shellcode
Patras Heap Massacre The Windows kernel heap manager Exposed to drivers and kernel internal components Object = ExAllocatePool(Type, Bytes) → ExAllocatePoolWithTag(Type, Bytes, ‘enoN’) ExFreePool(Object) → ExFreePoolWithTag(Object, 0) Non-paged pool Must always be in memory Pages pool Can be paged out Managed by struct _POOL_DESCRIPTOR
Heap Massacre Specific exploitation techniques will become obsolete New software versions Exploitation mitigations Back in CS 101 we were told that the most important skill of a computer scientist is abstraction The same holds for exploit writers/security researchers/hackers Your ability to abstract will remain sharp (as long as you sharpen it) Develop exploitation methodologies Recognize/understand/reuse exploitation primitives
Massacre [SLAB] Jeff Bonwick The Slab Allocator: An Object-caching Kernel Memory Allocator http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.29.4759 [BLUE] Chris Valasek and Ryan Smith, Exploitation in the Modern Era (Blueprint) https://www.blackhat.com/html/bh-eu-11/bh-eu-11- briefings.html#Valasek [KERNHEAP] Larry Highsmith Linux Kernel Heap Tampering Detection http://www.phrack.org/issues.html?issue=66&id=15&mode=txt