0%

chunk_overlapping

chunk_overlapping是堆中常见的漏洞

低版本下其打法主要有两种 2.27之后会新增pre_size和size一致性的校验

针对size位置的打法(此种打法是向后合并

直接修改一个正在使用的堆块的size位

然后free掉

实现overlap

1
2
3
4
5
6
7
8
9
10
11
12
1 //gcc -g test1.c -o test
2 #include<stdio.h>
3 int main(void)
4 {
5 void *hollk, *hollkr1;
6 hollk = malloc(0x10);//分配第一个0x10的chunk
7 malloc(0x10);//分配第二个0x10的chunk
8 *(long long *)((long long)hollk - 0x8) = 0x41;// 修改第一个块的size域
9 free(hollk);
10 hollk1 = malloc(0x30);// 实现extend,控制了第二个块的内容
11 return 0;
12 }
1
2
3
4
5
6
7
8
9
10
11
12
1 //gcc -g test2.c -o test2
2 #include<stdio.h>
3 int main()
4 {
5 void *hollk, *hollk1;
6 hollk = malloc(0x80);//分配第一个 0x80 的chunk1
7 malloc(0x10); //分配第二个 0x10 的chunk2
8 malloc(0x10); //防止与top chunk合并
9 *(long *)((long)hollk-0x8) = 0xb1;
10 free(hollk);
11 hollk1 = malloc(0xa0);
12}

或者对一个已经free掉的堆块修改size位,也能实现overlap

先free

修改size位

申请出来即可

1
2
3
4
5
6
7
8
9
10
11
1 //gcc -g test3 -o test3
2 #include<stdio.h>
3 int main()
4 {
5 void *hollk, *hollk1;
6 hollk = malloc(0x80);//分配第一个0x80的chunk1
7 malloc(0x10);//分配第二个0x10的chunk2
8 free(hollk);//首先进行释放,使得chunk1进入unsorted bin
9 *(long *)((long)hollk - 0x8) = 0xb1;
10 hollk1 = malloc(0xa0);
11}

同时对pre_size和pre_inuse的利用(此种打法是向前合并

利用的是smallbin的unlink机制

记得得free两个堆块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//gcc -g test5.c -o test
#include<stdio.h>
int main(void)
{
void *hollk1, *hollk2, *hollk3, *hollk4;
hollk1 = malloc(128);//smallbin1
hollk2 = malloc(0x10);//fastbin1
hollk3 = malloc(0x10);//fastbin2
hollk4 = malloc(128);//smallbin2
malloc(0x10);//防止与top合并
free(hollk1);
*(int *)((long long)hollk4 - 0x8) = 0x90;//修改pre_inuse域
*(int *)((long long)hollk4 - 0x10) = 0xd0;//修改pre_size域
free(hollk4);//unlink进行前向extend
malloc(0x150);//占位块
}

参考文章:

好好说话之Chunk Extend/Overlapping_好好说话 堆_hollk的博客-CSDN博客

ssp攻击

canary的各种利用方式中,有一种是通过 __stack_chk_fail函数打印报错信息来实现。

__stack_chk_fail源码:

1
2
3
4
5
6
7
8
9
10
11
void __attribute__ ((noreturn)) __stack_chk_fail (void)
{
__fortify_fail ("stack smashing detected");
}
void __attribute__ ((noreturn)) internal_function __fortify_fail (const char *msg)
{
/* The loop is added only to keep gcc happy. */
while (1)
__libc_message (2, "*** %s ***: %s terminatedn",
msg, __libc_argv[0] ?: "<unknown>");
}

据源码可见,报错信息中会打印出libc_argv[0]的值,而libc_argv[0]指向的则是程序名。

若我们能够栈溢出足够的长度,覆盖到__libc_argv[0]的位置,那我们就能让程序打印出任意地址的数据,造成任意地址数据泄露。这就是ssp攻击。