Fastbin duplication

黎 浩然/ 23 5 月, 2022/ PWN, 安全/SECURITY, 计算机/COMPUTER/ 0 comments

glibc-2.23

Fastbin的每一个bin是一个LIFO的单项链表

Fastbin dup attack的目的是两次(malloc)分到同一个fastbin块,可以构造如下fast bin链表:

注意:如果连续两次free同一个块进入fastbin会出错,中间必须隔开一个不同的chunk

Source code:

int *a = malloc(8);
int *b = malloc(8);
int *c = malloc(8);

free(a);
free(b);
free(a);

a = malloc(8);
b = malloc(8);
c = malloc(8);

assert(a == c);

glibc-2.27

Fastbin的每一个bin是一个LIFO的单项链表

Fastbin dup attack的目的是两次(malloc)分到同一个fastbin块。如果连续两次free同一个块进入fastbin会出错,中间必须隔开一个不同的chunk。

记得calloc是不会从tcache中分配chunk的,所以2.27的fastbin duplication如下:

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

int main()
{
	setbuf(stdout, NULL);

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

	printf("Fill up tcache first.\\n");
	void *ptrs[8];
	for (int i=0; i<8; i++) {
		ptrs[i] = malloc(8);
	}
	for (int i=0; i<7; i++) {
		free(ptrs[i]);
	}

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

	printf("1st calloc(1, 8): %p\\n", a);
	printf("2nd calloc(1, 8): %p\\n", b);
	printf("3rd calloc(1, 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);
	a = calloc(1, 8);
	b = calloc(1, 8);
	c = calloc(1, 8);
	printf("1st calloc(1, 8): %p\\n", a);
	printf("2nd calloc(1, 8): %p\\n", b);
	printf("3rd calloc(1, 8): %p\\n", c);

	assert(a == c);
}

记得第八块chunk是为了防止合并到top chunk的。虽然tcache和fastbin的内部不会合并,但是如果free的过程中撞到top chunk仍然是会与top chunk合并到。

Share this Post

Leave a Comment

您的邮箱地址不会被公开。 必填项已用 * 标注

*
*