【二进制安全】堆漏洞:Double Free原理
参考:https://www.anquanke.com/post/id/241598
 次要参考:https://xz.aliyun.com/t/6342
malloc_chunk 的源码如下:
struct malloc_chunk {
INTERNAL_SIZE_T prev_size;  /*前一个chunk的大小*/
INTERNAL_SIZE_T size;       /*当前chunk的大小*/
struct malloc_chunk * fd;   /*指向前一个释放的chunk*/
struct malloc_chunk * bk;   /*指向后一个释放的chunk*/
}
 
释放的chunk 会以单向链表的形式回收到fastbin 里面。
 fastbin 是 LIFO 的数据结构,使用单向链表实现。
示例代码:
// https://www.anquanke.com/post/id/241598#include <stdio.h>
#include <string.h>
#include <stdlib.h>int main(void)
{puts("The goal of this is to show how we can edit a freed chunk using a Double Free bug.");puts("Editing freed chunks will allow us to overwrite heap metadata, which is crucial to a lot of heap attacks.");puts("However a bug to edit the heap metadata is often just one piece of the exploitation process.\n");printf("So we start off by allocating three chunks of memory. Let's also write some data to them.\n\n");char *ptr0, *ptr1, *ptr2;ptr0 = malloc(0x30);ptr1 = malloc(0x30);ptr2 = malloc(0x30);char *data0 = "00000000";char *data1 = "11111111";char *data2 = "22222222";memcpy(ptr0, data0, 0x8);memcpy(ptr1, data1, 0x8);   memcpy(ptr2, data2, 0x8);printf("Chunk0: @ %p\t contains: %s\n", ptr0, ptr0);printf("Chunk1: @ %p\t contains: %s\n", ptr1, ptr1);printf("Chunk2: @ %p\t contains: %s\n\n", ptr2, ptr2);printf("Now is where the bug comes in. We will free the same pointer twice (the first chunk pointed to by ptr0).\n");printf("In between the two frees, we will free a different pointer. This is because in several different versions of malloc, there is a double free check \n(however in libc-2.27 it will hit the tcache and this will be fine).\n");printf("It will check if the pointer being free is the same as the last chunk freed, and if it is the program will cease execution.\n");printf("To bypass this, we can just free something in between the two frees to the same pointer.\n\n");free(ptr0); //-----------------------> b1free(ptr1);free(ptr0); //-----------------------> b2printf("Next up we will allocate three new chunks of the same size that we freed, and write some data to them. This will give us the three chunks we freed.\n\n");char *ptr3, *ptr4, *ptr5;ptr3 = malloc(0x30); //--------------> b3ptr4 = malloc(0x30);ptr5 = malloc(0x30);memcpy(ptr3, data0, 0x8);memcpy(ptr4, data1, 0x8);   memcpy(ptr5, data2, 0x8);printf("Chunk3: @ %p\t contains: %s\n", ptr3, ptr3);  //-------------> b4printf("Chunk4: @ %p\t contains: %s\n", ptr4, ptr4);printf("Chunk5: @ %p\t contains: %s\n\n", ptr5, ptr5);printf("So you can see that we allocated the same pointer twice, as a result of freeing the same pointer twice (since malloc will reuse freed chunks of similar sizes for performance boosts).\n");printf("Now we can free one of the pointers to either Chunk 3 or 5 (ptr3 or ptr5), and clear out the pointer. We will still have a pointer remaining to the same memory chunk, which will now be freed.\n");printf("As a result we can use the double free to edit a freed chunk. Let's see it in action by freeing Chunk3 and setting the pointer equal to 0x0 (which is what's supposed to happen to prevent UAFs).\n\n");free(ptr3);ptr3 = 0x0;printf("Chunk3: @ %p\n", ptr3);printf("Chunk5: @ %p\n\n", ptr5);printf("So you can see that we have freed ptr3 (Chunk 3) and discarded it's pointer. However we still have a pointer to it. Using that we can edit the freed chunk.\n\n");char *data3 = "15935728";memcpy(ptr5, data3, 0x8);printf("Chunk5: @ %p\t contains: %s\n\n", ptr5, ptr5);printf("Just like that, we were able to use a double free to edit a free chunk!\n");}
 
需要使用glibc 2.27编译。
 Linux下更换glibc版本的方法:https://blog.csdn.net/weixin_44864859/article/details/107237134
 使用glibc-all-in-one和patchelf对编译好的二进制文件直接替换其ld和libc的链接库地址,指向2.27版本的再次进行调试。
下面进行解释。
首先是申请三段内存,并填入数据:
ptr0 = malloc(0x30);
ptr1 = malloc(0x30);
ptr2 = malloc(0x30);char *data0 = "00000000";
char *data1 = "11111111";
char *data2 = "22222222";memcpy(ptr0, data0, 0x8);
memcpy(ptr1, data1, 0x8);   
memcpy(ptr2, data2, 0x8);
 
然后依次释放ptr0、ptr1、ptr0
 释放ptr0和ptr1之后的Tcachebin:
 
再释放ptr0之后的Tcachebin:
 
 可以看到addr=0x555555758670这个chunk被放到了tcache 0x40 大小的链表上两次
之后再申请ptr3、ptr4、ptr5(同样大小)
    char *ptr3, *ptr4, *ptr5;ptr3 = malloc(0x30); //--------------> b3ptr4 = malloc(0x30);ptr5 = malloc(0x30);memcpy(ptr3, data0, 0x8);memcpy(ptr4, data1, 0x8);   memcpy(ptr5, data2, 0x8);printf("Chunk3: @ %p\t contains: %s\n", ptr3, ptr3);  //-------------> b4printf("Chunk4: @ %p\t contains: %s\n", ptr4, ptr4);printf("Chunk5: @ %p\t contains: %s\n\n", ptr5, ptr5);
 

 可以看出来,ptr3和ptr5实际上是返回的同一块地址。
 因此,在之后,即便我们释放ptr3,并且把ptr3的值指向0x0,我们还是可以操作这个已经被释放的chunk。
free(ptr3);
ptr3 = 0x0;printf("Chunk3: @ %p\n", ptr3);
printf("Chunk5: @ %p\n\n", ptr5);char *data3 = "15935728";
memcpy(ptr5, data3, 0x8);
printf("Chunk5: @ %p\t contains: %s\n\n", ptr5, ptr5);
 

 总结就是2次free,2次malloc,一次free,最终得到可用的空闲块指针。
我们先不用管 修改已被释放的空闲块中的内容到底有什么用,
 我们现在只需要知道Double free可以实现这个目标 就可以了
相关文章:
【二进制安全】堆漏洞:Double Free原理
参考:https://www.anquanke.com/post/id/241598 次要参考:https://xz.aliyun.com/t/6342 malloc_chunk 的源码如下: struct malloc_chunk { INTERNAL_SIZE_T prev_size; /*前一个chunk的大小*/ INTERNAL_SIZE_T size; /*当前chunk的…...
python之open,打开文件时,遇到解码错误处理方式
在Python中,当我们打开一个文件时,我们可以指定文件的编码方式。如果文件的编码方式与我们指定的编码方式不同,那么就会出现解码错误。为了避免这种情况,我们可以使用errors参数来指定如何处理解码错误。 errors参数用于指定解码…...
STM32 CAN通信-CubeMX环境下CAN通信程序的编程与调试经验
文章目录 STM32 CAN通信-CubeMX环境下CAN通信程序的编程 STM32 CAN通信-CubeMX环境下CAN通信程序的编程 STM32F103ZE芯片 CAN通信测试代码: #include "main.h" #include "can.h"CAN_HandleTypeDef hcan1;void SystemClock_Config(void);int ma…...
windows创建不同大小的文件命令
打开命令窗口(windowsR输入cmd打开) 输入:fsutil file createnew C:\Users\Desktop\fileTran\10M.txt 10240000,创建10M大小的文件。 文件若存在需要先删除。...
Attention Is All You Need
Attention Is All You Need 摘要1. 简介2. Background3. 模型架构3.1 编码器和解码器堆栈3.2 Attention3.2.1 缩放的点积注意力(Scaled Dot-Product Attention)3.2.2 Multi-Head Attention3.2.3 Attention 在我们模型中的应用 3.3 Position-wise前馈网络…...
手写线程池 - C++版 - 笔记总结
1.线程池原理 创建一个线程,实现很方便。 缺点:若并发的线程数量很多,并且每个线程都是执行一个时间较短的任务就结束了。 由于频繁的创建线程和销毁线程需要时间,这样的频繁创建线程会大大降低 系统的效率。 2.思考 …...
PHP 容器化引发线上 502 错误状态码的修复
最后更新时间 2023-01-24. 背景 笔者所在公司技术栈为 Golang PHP,目前部分项目已经逐步转 Go 语言重构,部分 PHP 业务短时间无法用 Go 重写。 相比 Go 语言,互联网公司常见的 Nginx PHP-FPM 模式,经常会出现性能问题—— 特…...
QT中UDP之UDPsocket通讯
目录 UDP: 举例: 服务器端: 客户端: 使用示例: 错误例子并且改正: UDP: (User Datagram Protocol即用户数据报协议)是一个轻量级的,不可靠的࿰…...
【C语言】10-三大结构之循环结构-1
1. 引言 在日常生活中经常会遇到需要重复处理的问题,例如 统计全班 50 个同学平均成绩的程序求 30 个整数之和检查一个班级的同学程序是否及格要处理以上问题,最原始的方法是分别编写若干个相同或相似的语句或者程序段进行处理 例如:处理 50 个同学的平均成绩可以先计算一个…...
Windows下RocketMQ的启动
下载地址:下载 | RocketMQ 解压后 一、修改runbroker.cmd 修改 bin目录下的runbroker.cmd set "JAVA_OPT%JAVA_OPT% -server -Xms2g -Xmx2g" set "JAVA_OPT%JAVA_OPT% -XX:MaxDirectMemorySize15g" set "JAVA_OPT%JAVA_OPT% -cp %CLASSP…...
linux内核升级 docker+k8s更新显卡驱动
官方驱动 | NVIDIA在此链接下载对应的显卡驱动 # 卸载可能存在的旧版本nvidia驱动(如果没有安装过可跳过,建议执行) sudo apt-get remove --purge nvidia* # 安装驱动需要的依赖 sudo apt-get install dkms build-essential linux-headers-generic sudo vim /etc/mo…...
express学习笔记2 - 三大件概念
中间件 中间件是一个函数,在请求和响应周期中被顺序调用(WARNING:提示:中间件需要在响应结束前被调用) 路由 应用如何响应请求的一种规则 响应 / 路径的 get 请求: app.get(/, function(req, res) {res…...
Steam搬砖蓝海项目
这个项目早在很久之前就已经存在,并且一直非常稳定。如果你玩过一些游戏,你一定知道Steam是什么平台。Steam平台是全球最大的综合性数字发行平台之一,玩家可以在该平台购买、下载、讨论、上传和分享游戏和软件。 今天我给大家解释一下什么是…...
就业并想要长期发展选数字后端还是ic验证?
“就业并想要长期发展选数字后端还是ic验证?” 这是知乎上的一个热点问题,浏览量达到了13,183。看来有不少同学对这个问题感到疑惑。之前更新了数字后端&数字验证的诸多文章,从学习到职业发展,都写过,唯一没有做过…...
当服务器域名出现解析错误的问题该怎么办?
 域名解析是互联网用户接收他们正在寻找的域的地址的过程。更准确地说,域名解析是人们在浏览器中输入时使用的域名与网站IP地址之间的转换过程。您需要站点的 IP 地址才能知道它所在的位置并加载它。但,在这个过程中,可能会出现多种因素…...
面试必考精华版Leetcode2095. 删除链表的中间节点
题目: 代码(首刷看解析 day22): class Solution { public:ListNode* deleteMiddle(ListNode* head) {if(head->nextnullptr) return nullptr;ListNode *righthead;ListNode *lefthead;ListNode *NodeBeforeLeft;while(right!n…...
对 Redis 实现分布式事务的探索与实现
对 Redis 实现分布式事务的探索与实现 一、简介简介优势 二、Redis 的事务机制事务WATCH 命令MULTI 命令EXEC 命令UNWATCH 命令 三、Redis 的分布式事务集群架构分布式事务分布式事务实现方式1. 两阶段提交(2PC)方式Paxos 算法实现方式Raft 算法实现方式…...
Matlab实现Spectral Clustering算法
Spectral Clustering算法是一种基于图论的聚类算法,它可以将数据点按照图结构进行划分,发现复杂和非线性可分的结构。在这篇博客中,我将介绍Spectral Clustering算法的原理和步骤,并给出一个用Matlab实现的代码示例。 目录 一、…...
Android 测试
工程目录图 1- Espresso 2- uiautomator Espresso 文档UI Automator文档ui-automator 英文文档 请点击下面工程名称,跳转到代码的仓库页面,将工程 下载下来 Demo Code 里有详细的注释 代码:testespresso 参考文献 Android 利用 espre…...
全面解析大语言模型的工作原理
当ChatGPT在去年秋天推出时,在科技行业乃至世界范围内引起了轰动。当时,机器学习研究人员尝试研发了多年的语言大模型(LLM),但普通大众并未十分关注,也没有意识到它们变得多强大。 如今,几乎每个…...
shell脚本--常见案例
1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件: 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...
智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql
智慧工地管理云平台系统,智慧工地全套源码,java版智慧工地源码,支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求,提供“平台网络终端”的整体解决方案,提供劳务管理、视频管理、智能监测、绿色施工、安全管…...
centos 7 部署awstats 网站访问检测
一、基础环境准备(两种安装方式都要做) bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats࿰…...
Docker 运行 Kafka 带 SASL 认证教程
Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明:server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...
连锁超市冷库节能解决方案:如何实现超市降本增效
在连锁超市冷库运营中,高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术,实现年省电费15%-60%,且不改动原有装备、安装快捷、…...
MVC 数据库
MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...
linux 错误码总结
1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...
React19源码系列之 事件插件系统
事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...
IT供电系统绝缘监测及故障定位解决方案
随着新能源的快速发展,光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域,IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选,但在长期运行中,例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...
【论文阅读28】-CNN-BiLSTM-Attention-(2024)
本文把滑坡位移序列拆开、筛优质因子,再用 CNN-BiLSTM-Attention 来动态预测每个子序列,最后重构出总位移,预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵(S…...
