first_fit

堆的系统学习

first_fit

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
fprintf(stderr, "This file doesn't demonstrate an attack, but shows the nature of glibc's allocator.\n");
fprintf(stderr, "glibc uses a first-fit algorithm to select a free chunk.\n");
fprintf(stderr, "If a chunk is free and large enough, malloc will select this chunk.\n");
fprintf(stderr, "This can be exploited in a use-after-free situation.\n");

fprintf(stderr, "Allocating 2 buffers. They can be large, don't have to be fastbin.\n");
char* a = malloc(512);
char* b = malloc(256);
char* c;

fprintf(stderr, "1st malloc(512): %p\n", a);
fprintf(stderr, "2nd malloc(256): %p\n", b);
fprintf(stderr, "we could continue mallocing here...\n");
fprintf(stderr, "now let's put a string at a that we can read later \"this is A!\"\n");
strcpy(a, "this is A!");
fprintf(stderr, "first allocation %p points to %s\n", a, a);

fprintf(stderr, "Freeing the first one...\n");
free(a);

fprintf(stderr, "We don't need to free anything again. As long as we allocate less than 512, it will end up at %p\n", a);

fprintf(stderr, "So, let's allocate 500 bytes\n");
c = malloc(500);
fprintf(stderr, "3rd malloc(500): %p\n", c);
fprintf(stderr, "And put a different string here, \"this is C!\"\n");
strcpy(c, "this is C!");
fprintf(stderr, "3rd allocation %p points to %s\n", c, c);
fprintf(stderr, "first allocation %p points to %s\n", a, a);
fprintf(stderr, "If we reuse the first allocation, it now holds the data from the third allocation.\n");
}

执行程序后的输出
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
This file doesn't demonstrate an attack, but shows the nature of glibc's allocator.
glibc uses a first-fit algorithm to select a free chunk.
If a chunk is free and large enough, malloc will select this chunk.
This can be exploited in a use-after-free situation.
Allocating buffers. They can be large, don't have to be fastbin.
1st ): 0x245b420
2nd ): 0x245b630
we could continue mallocing here...
now let's put a string at a that we can read later "this is A!"
first allocation 0x245b420 points to this is A!
Freeing the first one...
We don't need to free anything again. As long as we allocate less than 512, it will end up at 0x245b420
So, let's allocate 500 bytes
3rd ): 0x245b420
And put a different string here, "this is C!"
3rd allocation 0x245b420 points to this is C!
first allocation 0x245b420 points to this is C!
If we reuse the first allocation, it now holds the data from the third allocation.

这个案例只是讲了glibc分配chunk时的first fit原则,可以用于use after free漏洞,比较简单,对照看看源码和输出即可,

我的理解是 free(a)之后a的指针空闲了出来 除非字节大于512 不然还是输出a的值 0x245b420,c字节为500,所以还是输出0x245b420

总结

1
2
3
4
5
6
7
8
9
10
当一个较大的 chunk 被分割成两半后,如果剩下的部分大于 MINSIZE,就会被放到 unsorted bin 中。
释放一个不属于 fast bin 的 chunk,并且该 chunk 不和 top chunk 紧邻时,该 chunk 会被首先放到 unsorted bin 中。关于top chunk的解释,请参考下面的介绍。
当进行 malloc_consolidate 时,可能会把合并后的 chunk 放到 unsorted bin 中,如果不是和 top chunk 近邻的话。

Unsorted Bin 在使用的过程中,采用的遍历顺序是 FIFO,即插入的时候插入到 unsorted bin 的头部,取出的时候从链表尾获取。
在程序 malloc 时,如果在 fastbin,small bin 中找不到对应大小的 chunk,就会尝试从 Unsorted Bin 中寻找 chunk。如果取出来的 chunk 大小刚好满足,就会直接返回给用户,否则就会把这些 chunk 分别插入到对应的 bin 中。

uaf 造成原因:

​ 指针free 掉后并没有置0
0%