【二进制安全】堆漏洞: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的大小*/
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); //-----------------------> b1
    free(ptr1);
    free(ptr0); //-----------------------> b2

    printf("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); //--------------> b3
    ptr4 = 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);  //-------------> b4
    printf("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
(这里之所以要把ptr1插入进来,是因为直接连续两次释放ptr0的话,会被检测出来异常)

free(ptr0); //-----------------------> b1
free(ptr1);
free(ptr0); //-----------------------> b2

释放ptr0和ptr1之后的Tcachebin:
【二进制安全】堆漏洞:Double Free原理,Pwn,android,安全

再释放ptr0之后的Tcachebin:
【二进制安全】堆漏洞:Double Free原理,Pwn,android,安全
可以看到addr=0x555555758670这个chunk被放到了tcache 0x40 大小的链表上两次

之后再申请ptr3、ptr4、ptr5(同样大小)

    char *ptr3, *ptr4, *ptr5;

    ptr3 = malloc(0x30); //--------------> b3
    ptr4 = 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);  //-------------> b4
    printf("Chunk4: @ %p\t contains: %s\n", ptr4, ptr4);
    printf("Chunk5: @ %p\t contains: %s\n\n", ptr5, ptr5);

【二进制安全】堆漏洞:Double Free原理,Pwn,android,安全
可以看出来,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);

【二进制安全】堆漏洞:Double Free原理,Pwn,android,安全
总结就是2次free,2次malloc,一次free,最终得到可用的空闲块指针。

我们先不用管 修改已被释放的空闲块中的内容到底有什么用,
我们现在只需要知道Double free可以实现这个目标 就可以了文章来源地址https://www.toymoban.com/news/detail-622681.html

Java中是否存在Double Free

  • C/C++ 提供了 malloc 和 free两个函数,允许程序员自主管理内存,因此可能出现Double Free漏洞;
  • Java、Python等语言处于内存安全的考虑,不允许用户自己管理内存,因此不存在Double Free漏洞。
    (Java有自己的垃圾回收机制)
    参考:https://cloud.tencent.com/developer/article/2246094

到了这里,关于【二进制安全】堆漏洞:Double Free原理的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 二进制与十进制数互相转换的方法及原理

    有人问我一道十进制数转化为二进制数的题:13.625转化为二进制应该如何表示。让我回忆起十多年前学编程时就搞不懂二进制,不找“不必求甚解”的借口,我搜索了一些平台,但很失望,这么多年过去了,能找到的资源依然和以前一样,只讲怎样操作,不提为什么这样操作

    2024年02月04日
    浏览(73)
  • 多重背包问题(详解二进制优化原理)

    这道题同样是背包问题,那么它也同样满足三个性质:重叠子问题、最优子结构以及无后效性。那么这样的话,我们依然可以使用动态规划的思路去分析这道题目。那么动态规划的分析主要分为两步:状态转移方程的书写以及循环的设计。 (1)状态表示: 我们在前面的两篇

    2024年02月14日
    浏览(39)
  • 二进制安全找实习记录

    就二进制安全岗而言,这里笔者主要面试了腾讯的科恩实验室内核安全和浏览器安全组,然后还面试了一些乙方(其它的就面了一下前后端开发,基本秒挂,这就不说了,笔者也没打算搞开发)。其实后面还面了个华子,但是一直没推流程,笔者也不太想等了,最后成功拿到

    2024年04月16日
    浏览(33)
  • 二进制安全学习 第一天

    (仅用作自己学习)XMCVE 2020 CTF Pwn入门课程_哔哩哔哩_bilibili   屏幕剪辑的捕获时间: 2024/3/15 17:13     Terminal:终端 shell:区别于GUI的提供给系统的用户接口   为什么c和c++的市场占额会下不去? 很多编译型语言都存在,Gc:垃圾收集器,例如 go语言,虽然也能编译成二进制程

    2024年04月17日
    浏览(37)
  • 新书速览|二进制安全基础

    详解C 语言反汇编技术、二进制漏洞挖掘和软件逆向分析方法。配套示例源码、PPT课件、教学大纲、教案、习题答案、作者QQ群答疑。 本书内容 《二进制安全基础》为 二进制安全技术知识普及与技术基础教程 ,不仅能为初学二进制安全技术的读者提供全面、实用的 C语言反汇

    2024年01月21日
    浏览(38)
  • 二进制加密PHP Webshell原理及简单实现

    今天继续给大家介绍渗透测试相关知识,本文主要内容是二进制加密PHP Webshell原理及简单实现。 免责声明: 本文所介绍的内容仅做学习交流使用,严禁利用文中技术进行非法行为,否则造成一切严重后果自负! 再次强调:严禁对未授权设备进行渗透测试! 为了躲避WAF、杀软

    2023年04月09日
    浏览(45)
  • 你了解Redis 的二进制安全吗

    最近面试的时候被问到Redis 的二进制安全相关八股文面试题。Redis二进制安全内容比较多,以下是简单的总结大致的过程,需要深入学习的建议跳过 Redis是基于C语言进行开发的,而C语言中的字符串是二进制不安全的,所以Redis就没有直接使用C语言的字符串,而是自己编写了一

    2024年02月04日
    浏览(35)
  • 安全研究 # 二进制代码相似性检测综述

    本文参考: [1]方磊,武泽慧,魏强.二进制代码相似性检测技术综述[J].计算机科学,2021,48(05):1-8. (信息工程大学数学工程与先进计算国家重点实验室, 国家重点研发课题,北大核心) 代码相似性检测常用于 代码预测 、 知识产权保护 和 漏洞搜索 等领域,可分为 源代码相似性检测

    2024年02月02日
    浏览(39)
  • 安全研究 # 课题:二进制成分分析(Binary SCA)

    本文参考多篇文章写作而成,出处在文末注明(本文在课题开展过程中长期保持更新)。 SCA(Software Composition Analysis)软件成分分析,通俗的理解就是通过分析软件包含的一些信息和特征来实现对该软件的识别、管理、追踪的技术。通常用来对软件源码、二进制软件包等进行静

    2024年02月16日
    浏览(38)
  • [ARM汇编]计算机原理与数制基础—1.1.2 二进制与十进制数制转换

    在计算机中,我们通常使用二进制数制来表示数据,因为计算机的基本电平只有两种状态:高电平(通常表示为 1)和低电平(通常表示为 0)。而在我们的日常生活中,我们习惯使用十进制数制。为了方便理解,我们需要掌握二进制与十进制之间的转换方法。 二进制转十进

    2024年02月08日
    浏览(52)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包