c - 双重自由攻击的理解

标签 c linux heap-memory glibc

我从这里得到一小段代码 https://github.com/shellphish/how2heap/blob/master/fastbin_dup.c

#include <stdio.h>
#include <stdlib.h>

int main()
{
    printf("This file demonstrates a simple double-free attack with fastbins.\n");

    printf("Allocating 3 buffers.\n");
    int *a = malloc(8);
    int *b = malloc(8);
    int *c = malloc(8);

    printf("1st malloc(8): %p\n", a);
    printf("2nd malloc(8): %p\n", b);
    printf("3rd malloc(8): %p\n", c);

    printf("Freeing the first one...\n");
    free(a);

    printf("If we free %p again, things will crash because %p is at the top of the free list.\n", a, a);
    // free(a);

    printf("So, instead, we'll free %p.\n", b);
    free(b);

    printf("Now, we can free %p again, since it's not the head of the free list.\n", a);
    free(a);

    printf("Now the free list has [ %p, %p, %p ]. If we malloc 3 times, we'll get %p twice!\n", a, b, a, a);
    printf("1st malloc(8): %p\n", malloc(8));
    printf("2nd malloc(8): %p\n", malloc(8));
    printf("3rd malloc(8): %p\n", malloc(8));
}
  1. 为什么我不能连续释放 A 两次?
  2. 为什么我可以在释放 B 之后再次释放 A?
  3. 如果我再次进行 malloc,为什么要两次返回同一个 block ?

谢谢!

最佳答案

这是编译器特定的“漏洞利用”。首先,让我们叫出房间里的大象:

  1. 您是故意使用未定义行为 (UB),因此从那时起,所有赌注都将落空。
  2. 您没有使用任何静态代码分析工具,例如 cppcheck或 lint,也不是任何调试工具,如 valgrind捕获这个。在生产系统中,您将使用此类工具至少 try catch 这些错误。
  3. 您可以随时拉取最新的glibc source并亲自发现它:)

现在,进入正题。首先,此漏洞利用仅在启用“fastbins”的 GCC 上有效。如果您只是将以下内容添加到您的代码中:

#include <malloc.h>
// ...
mallopt(M_MXFAST, 0);

然后它会更快崩溃:

This file demonstrates a simple double-free attack with fastbins.
Allocating 3 buffers.
1st malloc(8): 0x556f373b1010
2nd malloc(8): 0x556f373b1030
3rd malloc(8): 0x556f373b1050
Freeing the first one...
If we free 0x556f373b1010 again, things will crash because 0x556f373b1010 is at the top of the free list.
So, instead, we'll free 0x556f373b1030.
Now, we can free 0x556f373b1010 again, since it's not the head of the free list.
*** Error in `./a.out': double free or corruption (!prev): 0x0000556f373b1010 ***
Aborted (core dumped)

这是由于“fastbins”的工作方式:

M_MXFAST (since glibc 2.3) Set the upper limit for memory allocation requests that are satisfied using "fastbins". (The measurement unit for this parameter is bytes.) Fastbins are storage areas that hold deallocated blocks of memory of the same size without merging adjacent free blocks. Subsequent reallocation of blocks of the same size can be handled very quickly by allocating from the fastbin, although memory fragmentation and the overall memory footprint of the program can increase. The default value for this parameter is 64*sizeof(size_t)/4 (i.e., 64 on 32-bit architectures). The range for this parameter is 0 to 80*sizeof(size_t)/4. Setting M_MXFAST to 0 disables the use of fastbins.

free 调用不会立即释放内存,只是将其标记为可用于将来的 malloc() 调用。如果您立即尝试连续两次对同一 block 内存发出 free() 调用,内部指针检查将捕获它,但损坏已经完成(调用 UB),但同样的检查不会处理您提供的示例案例。

至于最后的 3 个 malloc() 调用两次生成相同的地址:UB 已被调用,并且损坏了空闲列表。

关于c - 双重自由攻击的理解,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36406041/

相关文章:

java - Vaadin 8 - 应用程序范围的缓存

objective-c - 在 Objective-C 中使用静态内存分配的最佳实践是什么?

linux - 在单节点集群 Elasticsearch v 7.11.1 中未发现 Elasticsearch 主机

java - 虚拟内存每秒增加 - 内存不足错误

c++ - libstdc++ - 由于 tr1/regex 导致编译失败

c - ptrace 在 Linux 中如何工作?

java - 在java中编写大型文本文件最有效的方法是什么?

c - 如何打印 uint8_t 字节数组?

c - 在 C 中, printf ("Hello") 如何在任何情况下输出 "Cello"?

c - 为什么我不能用两个具有相同内容的结构互换分配?