一、概述
创新互联建站是一家专业提供邢台县企业网站建设,专注与成都网站建设、做网站、H5技术、小程序制作等业务。10年已为邢台县众多企业、政府机构等服务。创新互联专业网站制作公司优惠进行中。
栈溢出保护是一种缓冲区溢出攻击缓解手段,当函数存在缓冲区溢出攻击漏洞时,攻击者可以覆盖栈上的返回地址来让shellcode能够得到执行。当启用栈保护后,函数开始执行的时候会先往栈里插入cookie信息,当函数真正返回的时候会验证cookie信息是否合法,如果不合法就停止程序运行。攻击者在覆盖返回地址的时候往往也会将cookie信息给覆盖掉,导致栈保护检查失败而阻止shellcode的执行。在Linux中我们将cookie信息称为canary(以下统一使用canary)。
gcc在4.2版本中添加了-fstack-protector和-fstack-protector-all编译参数以支持栈保护功能,4.9新增了-fstack-protector-strong编译参数让保护的范围更广。以下是-fstack-protector和-fstack-protector-strong的区别:
Linux系统中存在着三种类型的栈:
二、 应用程序栈保护
1. 栈保护工作原理
下面是一个包含栈溢出的例子:
- /* test.c */
- #include
- #include
- int main(int argc, char **argv)
- {
- char buf[16];
- scanf("%s", buf);
- printf("%s\n", buf);
- return 0;
- }
我们先禁用栈保护功能看看执行的结果
- [root@localhost stackp]# gcc -o test test.c -fno-stack-protector
- [root@localhost stackp]# python -c "print 'A'*24" | ./test
- AAAAAAAAAAAAAAAAAAAAAAAA
- Segmentation fault <- RIP腐败,导致异常
当返回地址被覆盖后产生了一个段错误,因为现在的返回地址已经无效了,所以现在执行的是CPU的异常处理流程。我们打开栈保护后再看看结果:
- [root@localhost stackp]# gcc -o test test.c -fstack-protector
- [root@localhost stackp]# python -c "print 'A'*25" | ./test
- AAAAAAAAAAAAAAAAAAAAAAAAA
- *** stack smashing detected ***: ./test terminated
这时触发的就不是段错误了,而是栈保护的处理流程,我们反汇编看看做了哪些事情:
- 0000000000400610
: - 400610: 55 push %rbp
- 400611: 48 89 e5 mov %rsp,%rbp
- 400614: 48 83 ec 30 sub $0x30,%rsp
- 400618: 89 7d dc mov %edi,-0x24(%rbp)
- 40061b: 48 89 75 d0 mov %rsi,-0x30(%rbp)
- 40061f: 64 48 8b 04 25 28 00 mov %fs:0x28,%rax <- 插入canary值
- 400626: 00 00
- 400628: 48 89 45 f8 mov %rax,-0x8(%rbp)
- 40062c: 31 c0 xor %eax,%eax
- 40062e: 48 8d 45 e0 lea -0x20(%rbp),%rax
- 400632: 48 89 c6 mov %rax,%rsi
- 400635: bf 00 07 40 00 mov $0x400700,%edi
- 40063a: b8 00 00 00 00 mov $0x0,%eax
- 40063f: e8 cc fe ff ff callq 400510 <__isoc99_scanf@plt>
- 400644: 48 8d 45 e0 lea -0x20(%rbp),%rax
- 400648: 48 89 c7 mov %rax,%rdi
- 40064b: e8 80 fe ff ff callq 4004d0
- 400650: b8 00 00 00 00 mov $0x0,%eax
- 400655: 48 8b 55 f8 mov -0x8(%rbp),%rdx <- 检查canary值
- 400659: 64 48 33 14 25 28 00 xor %fs:0x28,%rdx
- 400660: 00 00
- 400662: 74 05 je 400669
# 0x400669 - 400664: e8 77 fe ff ff callq 4004e0 <__stack_chk_fail@plt>
- 400669: c9 leaveq
- 40066a: c3 retq
我们看到函数开头(地址:0x40061f)处gcc编译时在栈帧的返回地址和临时变量之间插入了一个canary值,该值是从%fs:0x28里取的,栈帧的布局如下:
- stack:
- | ...... |
- | orig_return |
- | orig_rbp | <- %rbp
- | canary | <- -0x8(%rpb), 既 %fs:0x28
- | local variables |
- | | <- %rsp
在函数即将返回时(地址:0x400655)检查栈中的值是否和原来的相等,如果不相等就调用glibc的_stackchk_fail函数,并终止进程。
2. canary值的产生
这里以x64平台为例,canary是从%fs:0x28偏移位置获取的,%fs寄存器被glibc定义为存放tls信息的,我们需要查看glibc的源代码:
- typedef struct
- {
- void *tcb; /* Pointer to the TCB. Not necessarily the
- thread descriptor used by libpthread. */
- dtv_t *dtv;
- void *self; /* Pointer to the thread descriptor. */
- int multiple_threads;
- int gscope_flag;
- uintptr_t sysinfo;
- uintptr_t stack_guard; <- canary值,偏移位置0x28处
- uintptr_t pointer_guard;
- ......
- } tcbhead_t;
结构体tcbheadt就是用来描述tls的也就是%fs寄存器指向的位置,其中+0x28偏移位置的成员变量stackguard就是canary值。另外通过strace ./test看到在进程加载的过程中会调用arch_prctl系统调用来设置%fs的值,
- root@localhost stackp]# strace ./test
- execve("./test", ["./test"], [/* 24 vars */]) = 0
- ......
- arch_prctl(ARCH_SET_FS, 0x7f985a041740) = 0
- ......
产生canary值的代码在glibc的dlmain和_libcstart_main函数中:
- /* Set up the stack checker's canary. */
- uintptr_t stack_chk_guard = _dl_setup_stack_chk_guard (_dl_random);
- # ifdef THREAD_SET_STACK_GUARD
- THREAD_SET_STACK_GUARD (stack_chk_guard);
- # else
- __stack_chk_guard = stack_chk_guard;
- # endif
dlrandom是一个随机数,它由dlsysdepstart函数从内核获取的。dlsetupstackchkguard函数负责生成canary值,THREADSETSTACK_GUARD宏将canary设置到%fs:0x28位置。
在应用程序栈保护中,进程的%fs寄存器是由glibc来管理的,并不涉及到内核提供的功能。
3. x32应用程序栈保护
解读完了x64的实现,我们来看看x32下面的情况,我们还是使用上面例子的代码在x32的机器上编译,得到下面的代码:
- 08048464
: - ......
- 8048474: 65 a1 14 00 00 00 mov %gs:0x14,%eax # 插入canary值
- 804847a: 89 44 24 3c mov %eax,0x3c(%esp)
- ......
- 80484aa: 65 33 15 14 00 00 00 xor %gs:0x14,%edx # 检查canary值
- 80484b1: 74 05 je 80484b8
# 0x80484b8 - 80484b3: e8 c0 fe ff ff call 8048378 <__stack_chk_fail@plt>
- 80484b8: c9 leave
- 80484b9: c3 ret
网站题目:解读Linux安全机制之栈溢出保护
当前网址:http://www.csdahua.cn/qtweb/news29/267379.html
网站建设、网络推广公司-快上网,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 快上网