The toddler’s introduction to Heap Exploitation, House of Lore(Part 4.5)

Similarly to other heap exploitation attacks that we saw so far, the idea behind the House of Lore (HoL) is to trick malloc to return a pointer to a memory location which is controlled by the attacker. HoL (ab)uses the way that ptmalloc handles the small bin entries although the initial post included the large bin entries too. Besides the fact that the conditions surrounding the House of Lore are quite unique[1], changes in malloc implementation (the introduction of fd_nextsize and bk_nextsize) [2] rendered this attack impractical for large bin abuse, while after the tcache introduction and the additional hardening at the latest glibc versions, even more conditions need to be in place for this attack to be successful.

Beyond its (un)practicality, understanding how this attack works, will help us comprehend how malloc works, and after all… this what really matters.

Before we start, here is the story so far:

The House of Lore

Sticking with the main idea of the attack, we will force malloc to return a pointer to a stack memory area that we control. This will help us to overwrite the return address of the function where the vulnerability takes place and bypass the stack smash detection by jumping over the canary value. We will investigate the HoL in the context of glibc version 2.23 to avoid the tcache and gradually, we will add the missing conditions in order to implement this attack for the latest glibc version.

Before we start, here is what you need to know:

  • When a chunk is passed to free(), it is first added to the unsorted bin.
  • On the next call to malloc, if the memory requirement cannot be satisfied by a smallbin or an unsorted chunk, then the unsorted chunks are put to the appropriate list.
  • When a chunk is inserted into the (doubly linked) small bin the fd and bk pointers are updated in order to point to the appropriate nodes.
  • As the allocator follows a FIFO rule for this bin, a call to free will send the new chunk to the head of the list and a call to malloc will unlink and remove a chunk from the tail:
Inserting and removing a chunk from the smallbin
The chunk struct

The attack

Assume that you have an overflow that allows you to overwrite the bk entry of a N-size chunk so it points to an arbitrary memory location:

Overwriting bk to point to the fake chunk

Then in order for the attack to take place the allocator needs to perform n calls to a N-sized malloc so the overwritten bk will be reached. Lets see an example from the shellphish’s how2heap repo:

The stack_buffer_1 and stack_buffer_2 at lines 6 and 7 represent two fake chunks which will be allocated in the stack. In line 9 we allocate the victim chunk which we suppose to control its header data via an overflow. At line 11 the victim_chunk will point to the header of the victim chunk. The lines 14 to 19 craft the stack_buffer_1 and stack_buffer_2 to look like valid chunks which are linked with the victim chunk. More specifically, line 16 will bypass the malloc’s check at line 3388:

and the code at lines 17,19 will link the fake chunks in a double linked list, thus we’ll have the following:

Line 21 is added to avoid consolidation of the victim chunk with the top chunk. The call to free at line 23 will first move the victim chunk to the unsorted bin thus the next malloc which can’t be satisfied by the unsorted bin will move the victim chunk to the smallbin. The line 28 symbolises the vulnerability which will have as a result the following arrangement:

Since the victim_chunk is the only node in the smallbin, the first call to malloc at line 31 will return its address to satisfy the allocation, so the subsequent call to malloc at line 33 will return a pointer to the (fake) data part of stack_buffer_1. As we control the memory location where p4 points to, we can overwrite the return address of the main function (line 37) to point to the entry of the jackpot() function, thus by running the program we will get a Nice jump d00d in the output and then the program will exit.

#if USE_TCACHE

The tcache introduction added a couple of additional branches to the smallbin handling flow that have to be bypassed for the attack to be successful. More specifically, malloc will try to stash the rest of the same sized smallbin chunks to the tcache

To overcome these checks the code at shellphish’s repo creates a fake free list and links each node via a fake bk pointer:

void* fake_freelist[7][4];

for(int i=0; i<6; i++) { fake_freelist[i][3] = fake_freelist[i+1]; }

This will create the following setup:

which will fill the tcache list and exit the loop at line 3927. Finally, the code exhausts the tcache list via a dummy requirement, listed below:

void *dummies[7]; for(int i=0; i<7; i++) dummies[i] = malloc(0x100);

for(int i=0; i<7; i++) free(dummies[i]);

The whole code is as follows:

[1] https://dl.packetstormsecurity.net/papers/attack/MallocMaleficarum.txt

[2] https://heap-exploitation.dhavalkapil.com/attacks/house_of_lore

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store