UNIX下的缓冲区溢出防御体系分析
敬业的IT人
互联网
佚名
2008-4-22 20:59:31
------------
谈及防御之前
------------
首先简要回顾一下缓冲区溢出的攻击大系:
◆栈溢出(stack smashing)
未检查输入缓冲区长度,导致数组越界,覆盖栈中局部变量空间之上的栈桢指针%ebp以及函数返回地址retaddr,当函数返回执行ret指令时,retaddr从栈中弹出,作为下一条指令的地址赋给%eip寄存器,继而改变原程序的执行流程指向我们的shellcode.
◆堆溢出(malloc/free heap corruption)
一种是和传统的栈溢出一样,当输入超出malloc()预先分配的空间大小,就会覆盖掉这段空间之后的一段存储区域,如果该存储区域有一个重要的变量比如euid,那么我就可以用它来攻击。另一种是典型的double-free堆腐败,在内存回收操作中,合并相邻空闲块重新插入双向链表时会有一个写4字节内存的操作,如果弱点程序由于编程错误free()一个不存在的块,我们就可以精心伪造这个块,从而覆盖任何我们想要的值:函数的返回地址、库函数的。plt地址等
◆格式化字符窜漏洞(format string vulnerability)
如果格式窜由用户定制,攻击者就可以任意伪造格式窜,利用*printf()系列函数的特性就可以窥探堆栈空间的内容,超常输入可以引发传统的缓冲区溢出,或是用“%n”覆盖指针、返回地址等。
◆整形变量溢出(integer variable overflow)
利用整数的范围、符号等问题触发安全漏洞,大多数整形溢出不能直接利用,但如果该整形变量决定内存分配等操作,我们就有可能间接利用该漏洞。
◆其他的攻击手法(others)
只能算是手法,不能算是一种单独的类别。利用ELF文件格式的特性如:覆盖。plt(过程连接表)、。dtor(析构函数指针)、。got(全局偏移表)、return-to-libc(返回库函数)等的方式进行攻击。
----------------
一、编译保护技术
----------------
◆Stackguard
因为缓冲区溢出的通常都会改写函数返回地址,stackguard是个编译器补丁,它产生一个"canary"值(一个单字)放到返回地址的前面,如果当函数返回时,发现这个canary的值被改变了,就证明可能有人正在试图进行缓冲区溢出攻击,程序会立刻响应,发送一条入侵警告消息给syslogd,然后终止进程。"canary"包含:NULL(0x00), CR(0x0d), LF (0x0a) 和 EOF (0xff)四个字 符,它们应该可以阻止大部分的字符串操作,使溢出攻击无效。一个随机数canary在程序执行的时候被产生。所以攻击者不能通过搜索程序的二进制文件得到"canary"值。如果/dev/urandom存在,随机数就从那里取得。否则,就从通过对当前时间进行编码得到。其随机性足以阻止绝大部分的预测攻击。Immunix系统为采用stackguard编译的Red Hat Linux,但stackguard所提供的保护并非绝对安全,满足一些条件就可以突破限制:如覆盖一个函数指针、可能存在的exit()或_exit()系统调用地址、GOT等。Stackguard官方链接:
------------------
二、库函数链接保护
------------------
◆Formatguard
Formatguard是个Glibc的补丁,遵循GPL,它使用特殊的CPP(gcc预编译程序)宏取代原有的*printf()的参数统计方式,它会比较传递给*printf的参数的个数和格式窜的个数,如果格式窜的个数大于实际参数的个数,就判定为攻击行为,向syslogd发送消息并终止进程。如果弱点程序调用Glibc以外的库,formatguard就无法保护。
◆Libsafe
Libsafe是一个动态链接库,在标准的C库之前被加载,主要加固了gets(),strcpy(),strcat(),sprintf()……等容易发生安全问题的C函数,它设计为只针对stack smashing && format string类型的攻击。
--------------
三、栈不可执行
--------------
◆Solar designer’s nonexec kernel patch
从名字可以看出这是一个Linux上的内核补丁,该补丁最主要的特性是:用户区堆栈不可执行[Non-executable User Stack]由于x86 CPU上并没有提供页(page)执行的bit位,所以该补丁通过减小代码段的虚拟地址来区分数据段和代码段,程序执行流返回 0xC0000000以下一段用户堆栈空间的操作都被认为是缓冲区溢出攻击行为,随即产生一个通用保护异常而终止进程。这样把shellcode安置在buffer或环境变量(都位于堆栈段)的exploit都会失效。当然其安全也不是绝对的,利用PLT返回库函数的文章里详细描述了突破该补丁的攻击方法。该补还有一些其他的特性:动态链接库映射到地址低端(0x00开始)、限制符号链接攻击、/tmp目录限制、/proc目录限制、execve系统调用加固等。
◆Solaris/SPARC nonexec-stack protection
在Solaris/SPARC下可以通过去掉堆栈的执行权限来禁止堆栈段执行,方法如下,在/etc/system中加入两条语句:Set noexec_user_stack = 1Set noexec_user_stack_log = 1第一条禁止堆栈执行,第二条记录所有尝试在堆栈段运行代码的活动。Reboot之后才会生效。所有只让栈不可执行的保护是有限的。Return-to-libc、fake frame之类的技术都可以突破限制,不过栈不可执行的保护已经极大了提升了攻击难度。
------------------
四、数据段不可执行
------------------
◆kNoX
Linux内核补丁,功能:数据段的页不可执行,撤销共享内存,加强对execve系统调用的限制,对文件描述符0、1、2的特殊处理,/proc目录的限制,FIFO限制,符号链接限制,该补丁只支2.2内核。
◆RSX
Linux内核模块,数据段(stack、heap)不可执行。
- 最新文章
- 如何用ROOT远程登陆UNIX系统和防御办法[04-22]
- 检测Unix操作系统是否被入侵最简单快捷方法[04-22]
- SCO UNIX环境下多级域名的配置[04-22]
- 有效而合理的策略,UNIX网络安全性之我见[04-22]
- 学好unix:Linux系统疑难解答之98式(五)[04-22]
- Unix编程/应用问答中文版 ---17.文件查看问题 18..[04-22]
- 相关文章
- 如何用ROOT远程登陆UNIX系统和防御办法[04-22]
- 检测Unix操作系统是否被入侵最简单快捷方法[04-22]
- SCO UNIX环境下多级域名的配置[04-22]
- 有效而合理的策略,UNIX网络安全性之我见[04-22]
- 学好unix:Linux系统疑难解答之98式(五)[04-22]
- Unix编程/应用问答中文版 ---17.文件查看问题 18..[04-22]
