Link to this headingDlmalloc
- The original Linux glibc implementation until 2006
- Leaking Pointers allow an attacker to de reference pointers to get pointers into glibc and the heap
Link to this headingFunctions
malloc - Allocates a chunk* at least size bytes and returns
- If size is less than or equal to a fast bin or a small bin use it.
- Move fast bins to unsorted bins
- Merge adjacent freed chunks together
- Sort bin
- Search through best fit bins
- Split the Top
free - De-allocates chunk* pointed by p
- If chunk is a fast chunk then put it in the fast bin
- Else
- Merge adjacent freed chunks together
- Then put it into the Unsorted bin
realloc - Increases the size of a chunk* while preserving it’s content
calloc - malloc but clears data
Link to this headingStructures
- Chunks must be at least 0x20 bytes
- Since Chunks are 8 byte aligned the 3 Least significant bits are used for Flags
- Bit 0: previous chunk in-use (
prev_inuse)- If the prev_inuse is not set then malloc will use prev_size
- Bit 1: Was the chunk allocates with mmap. (
is_mmapped) - Bit 2: is allocated from a spawned thread?
non_main_arena
- Bit 0: previous chunk in-use (
Allocated Chunk:
malloc returned address
||
\/
----------------------------
| size | user-data ....... |
----------------------------
Freed Malloc Chunk:
malloc returned address
||
\/
-------------------------------------------------------------------------------------------------------
| prev_size | size | next_chunk_pointer | prev_chunk_pointer | fd_nextsize | bk_nextsize | ... | size |
-------------------------------------------------------------------------------------------------------
Link to this headingBins
| Type | Size | List Type | Info |
|---|---|---|---|
| Fast | [0x20 - 0x80] | Single Linked | prev_inuse is set |
| Unsorted | All Sizes | Double Linked | chunks before sorted |
| Small | [0x20 - 0x400) | Double Linked | |
| Large | Ranges | Two Level Double Linked |
Link to this headingArena
Main Arena:
- Is a global variable in the program
- Contains the pointers to the bins
toppoints to “wilderness”
Arena/malloc_state:
--------------------------------------------------------------------------
| mutex | flags | fastbins[] | top | remainder | bins[] |...|
--------------------------------------------------------------------------
/ \
+------------------------+
|unsorted|small[]|large[]|
+------------------------+
Thread Arena:
Link to this headingUnsafe Unlink Arbitrary Write
- Works on Glibc version < 2.26
- Because the freed memory thinks that the previous block is also freed memory it combinds the data together to a bigger chunk.
- With this confusion of data this allows the unlink macro to be run.
- This results in arbitrary write
- Use a buffer to overwrite the heap meta data for an object that has a size greater than 0x70 bytes.
- We set up the prev_chunk_pointer to the pointer to the global buffer address - 0x10.
- This makes it so that when dereferenced the prev_chunk_pointer points to the global buffer address. (
(buffer->prev_chunk_pointer)->next_chunk_pointer == buffer)
- This makes it so that when dereferenced the prev_chunk_pointer points to the global buffer address. (
- We set up the next_chunk_pointer to the pointer to the global buffer address - 0x18.
- This makes it so that when dereferenced the next_chunk_pointer points to the global buffer address. (
(buffer->next_chunk_pointer)->prev_chunk_pointer == buffer)
- This makes it so that when dereferenced the next_chunk_pointer points to the global buffer address. (
- We set the prev_size (originally 0x90 because of metadata) to a smaller value that falls within the . Usually the size without the metadata (0x80).
- Using the buffer address we overwrite the previous_in_use flag to false
- We set up the prev_chunk_pointer to the pointer to the global buffer address - 0x10.
- Then call free on the object.
- This will set the
buffer + 0x18to a pointer that points to the start of the buffer.
- This will set the
- This can be exploited by changing the pointer in
buffer + 0x18and then writing to the buffer.- This will dereference the pointer in
buffer + 0x18and write data to that address
- This will dereference the pointer in
Link to this headingFixes
- Two new security checks include corrupted size vs. prev_size and corrupted double-linked list
Link to this headingExample
Link to this headingFastbin Consolidation Double Free
- Works on Glibc version < 2.30
- [Double Free](/Exploitation/Heap/Double Free.md) check is bypassed when a large chunk is allocated between the two frees.
- This makes the same address be in the fastbin and the unsorted bin.
- When making new allocations
Vulnerable Example:
int
Link to this headingHouse of Spirit
- Make a fake chunk and change the pointer to be freed.
- This allows the same control as the Unsafe Unlink.
- index 0 is the Pointer to write data to
- index 3 is the data that write to that address