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

【二进制安全】堆漏洞: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原理

参考&#xff1a;https://www.anquanke.com/post/id/241598 次要参考&#xff1a;https://xz.aliyun.com/t/6342 malloc_chunk 的源码如下&#xff1a; struct malloc_chunk { INTERNAL_SIZE_T prev_size; /*前一个chunk的大小*/ INTERNAL_SIZE_T size; /*当前chunk的…...

python之open,打开文件时,遇到解码错误处理方式

在Python中&#xff0c;当我们打开一个文件时&#xff0c;我们可以指定文件的编码方式。如果文件的编码方式与我们指定的编码方式不同&#xff0c;那么就会出现解码错误。为了避免这种情况&#xff0c;我们可以使用errors参数来指定如何处理解码错误。 errors参数用于指定解码…...

STM32 CAN通信-CubeMX环境下CAN通信程序的编程与调试经验

文章目录 STM32 CAN通信-CubeMX环境下CAN通信程序的编程 STM32 CAN通信-CubeMX环境下CAN通信程序的编程 STM32F103ZE芯片 CAN通信测试代码&#xff1a; #include "main.h" #include "can.h"CAN_HandleTypeDef hcan1;void SystemClock_Config(void);int ma…...

windows创建不同大小的文件命令

打开命令窗口&#xff08;windowsR输入cmd打开&#xff09; 输入&#xff1a;fsutil file createnew C:\Users\Desktop\fileTran\10M.txt 10240000&#xff0c;创建10M大小的文件。 文件若存在需要先删除。...

Attention Is All You Need

Attention Is All You Need 摘要1. 简介2. Background3. 模型架构3.1 编码器和解码器堆栈3.2 Attention3.2.1 缩放的点积注意力&#xff08;Scaled Dot-Product Attention&#xff09;3.2.2 Multi-Head Attention3.2.3 Attention 在我们模型中的应用 3.3 Position-wise前馈网络…...

手写线程池 - C++版 - 笔记总结

1.线程池原理 创建一个线程&#xff0c;实现很方便。 缺点&#xff1a;若并发的线程数量很多&#xff0c;并且每个线程都是执行一个时间较短的任务就结束了。 由于频繁的创建线程和销毁线程需要时间&#xff0c;这样的频繁创建线程会大大降低 系统的效率。 2.思考 …...

PHP 容器化引发线上 502 错误状态码的修复

最后更新时间 2023-01-24. 背景 笔者所在公司技术栈为 Golang PHP&#xff0c;目前部分项目已经逐步转 Go 语言重构&#xff0c;部分 PHP 业务短时间无法用 Go 重写。 相比 Go 语言&#xff0c;互联网公司常见的 Nginx PHP-FPM 模式&#xff0c;经常会出现性能问题—— 特…...

QT中UDP之UDPsocket通讯

目录 UDP&#xff1a; 举例&#xff1a; 服务器端&#xff1a; 客户端&#xff1a; 使用示例&#xff1a; 错误例子并且改正&#xff1a; UDP&#xff1a; &#xff08;User Datagram Protocol即用户数据报协议&#xff09;是一个轻量级的&#xff0c;不可靠的&#xff0…...

【C语言】10-三大结构之循环结构-1

1. 引言 在日常生活中经常会遇到需要重复处理的问题,例如 统计全班 50 个同学平均成绩的程序求 30 个整数之和检查一个班级的同学程序是否及格要处理以上问题,最原始的方法是分别编写若干个相同或相似的语句或者程序段进行处理 例如:处理 50 个同学的平均成绩可以先计算一个…...

Windows下RocketMQ的启动

下载地址&#xff1a;下载 | 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驱动(如果没有安装过可跳过&#xff0c;建议执行) sudo apt-get remove --purge nvidia* # 安装驱动需要的依赖 sudo apt-get install dkms build-essential linux-headers-generic sudo vim /etc/mo…...

express学习笔记2 - 三大件概念

中间件 中间件是一个函数&#xff0c;在请求和响应周期中被顺序调用&#xff08;WARNING&#xff1a;提示&#xff1a;中间件需要在响应结束前被调用&#xff09; 路由 应用如何响应请求的一种规则 响应 / 路径的 get 请求&#xff1a; app.get(/, function(req, res) {res…...

Steam搬砖蓝海项目

这个项目早在很久之前就已经存在&#xff0c;并且一直非常稳定。如果你玩过一些游戏&#xff0c;你一定知道Steam是什么平台。Steam平台是全球最大的综合性数字发行平台之一&#xff0c;玩家可以在该平台购买、下载、讨论、上传和分享游戏和软件。 今天我给大家解释一下什么是…...

就业并想要长期发展选数字后端还是ic验证?

“就业并想要长期发展选数字后端还是ic验证&#xff1f;” 这是知乎上的一个热点问题&#xff0c;浏览量达到了13,183。看来有不少同学对这个问题感到疑惑。之前更新了数字后端&数字验证的诸多文章&#xff0c;从学习到职业发展&#xff0c;都写过&#xff0c;唯一没有做过…...

当服务器域名出现解析错误的问题该怎么办?

​  域名解析是互联网用户接收他们正在寻找的域的地址的过程。更准确地说&#xff0c;域名解析是人们在浏览器中输入时使用的域名与网站IP地址之间的转换过程。您需要站点的 IP 地址才能知道它所在的位置并加载它。但&#xff0c;在这个过程中&#xff0c;可能会出现多种因素…...

面试必考精华版Leetcode2095. 删除链表的中间节点

题目&#xff1a; 代码&#xff08;首刷看解析 day22&#xff09;&#xff1a; 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. 两阶段提交&#xff08;2PC&#xff09;方式Paxos 算法实现方式Raft 算法实现方式…...

Matlab实现Spectral Clustering算法

Spectral Clustering算法是一种基于图论的聚类算法&#xff0c;它可以将数据点按照图结构进行划分&#xff0c;发现复杂和非线性可分的结构。在这篇博客中&#xff0c;我将介绍Spectral Clustering算法的原理和步骤&#xff0c;并给出一个用Matlab实现的代码示例。 目录 一、…...

Android 测试

工程目录图 1- Espresso 2- uiautomator Espresso 文档UI Automator文档ui-automator 英文文档 请点击下面工程名称&#xff0c;跳转到代码的仓库页面&#xff0c;将工程 下载下来 Demo Code 里有详细的注释 代码&#xff1a;testespresso 参考文献 Android 利用 espre…...

全面解析大语言模型的工作原理

当ChatGPT在去年秋天推出时&#xff0c;在科技行业乃至世界范围内引起了轰动。当时&#xff0c;机器学习研究人员尝试研发了多年的语言大模型&#xff08;LLM&#xff09;&#xff0c;但普通大众并未十分关注&#xff0c;也没有意识到它们变得多强大。 如今&#xff0c;几乎每个…...

挑战杯推荐项目

“人工智能”创意赛 - 智能艺术创作助手&#xff1a;借助大模型技术&#xff0c;开发能根据用户输入的主题、风格等要求&#xff0c;生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用&#xff0c;帮助艺术家和创意爱好者激发创意、提高创作效率。 ​ - 个性化梦境…...

JavaSec-RCE

简介 RCE(Remote Code Execution)&#xff0c;可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景&#xff1a;Groovy代码注入 Groovy是一种基于JVM的动态语言&#xff0c;语法简洁&#xff0c;支持闭包、动态类型和Java互操作性&#xff0c…...

C++初阶-list的底层

目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...

Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务

通过akshare库&#xff0c;获取股票数据&#xff0c;并生成TabPFN这个模型 可以识别、处理的格式&#xff0c;写一个完整的预处理示例&#xff0c;并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务&#xff0c;进行预测并输…...

Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具

文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...

leetcodeSQL解题:3564. 季节性销售分析

leetcodeSQL解题&#xff1a;3564. 季节性销售分析 题目&#xff1a; 表&#xff1a;sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...

Golang——6、指针和结构体

指针和结构体 1、指针1.1、指针地址和指针类型1.2、指针取值1.3、new和make 2、结构体2.1、type关键字的使用2.2、结构体的定义和初始化2.3、结构体方法和接收者2.4、给任意类型添加方法2.5、结构体的匿名字段2.6、嵌套结构体2.7、嵌套匿名结构体2.8、结构体的继承 3、结构体与…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现企业微信功能

1. 开发环境准备 ​​安装DevEco Studio 3.1​​&#xff1a; 从华为开发者官网下载最新版DevEco Studio安装HarmonyOS 5.0 SDK ​​项目配置​​&#xff1a; // module.json5 {"module": {"requestPermissions": [{"name": "ohos.permis…...

Web后端基础(基础知识)

BS架构&#xff1a;Browser/Server&#xff0c;浏览器/服务器架构模式。客户端只需要浏览器&#xff0c;应用程序的逻辑和数据都存储在服务端。 优点&#xff1a;维护方便缺点&#xff1a;体验一般 CS架构&#xff1a;Client/Server&#xff0c;客户端/服务器架构模式。需要单独…...

【Linux】自动化构建-Make/Makefile

前言 上文我们讲到了Linux中的编译器gcc/g 【Linux】编译器gcc/g及其库的详细介绍-CSDN博客 本来我们将一个对于编译来说很重要的工具&#xff1a;make/makfile 1.背景 在一个工程中源文件不计其数&#xff0c;其按类型、功能、模块分别放在若干个目录中&#xff0c;mak…...