设为主页 | 加入收藏 | 繁體中文

UNIX下的缓冲区溢出深度防御体系

  文/ayazerowww.ph4nt0m.org
  Contact:zhaoyan@nsfocus.com
  Version:2004/10/05 draft
  谈及防备之前
  首先简要回首一下缓冲区溢出的打击大系:
  l栈溢出(stack smashing)
  未检查输出缓冲区长度,导致数组越界,覆盖栈中局部变量空间之上的栈桢指针%ebp以及函数返回地址retaddr,当函数返回执行ret指令时,retaddr从栈中弹出,作为下一条指令的地址赋给%eip寄存器,继而改变原步伐的执行流程指向我们的shellcode.
  l堆溢出(malloc/free heap corruption)
  一种是和传统的栈溢出一样,当输出凌驾malloc()预先分配的空间巨细,就会覆盖掉这段空间之后的一段存储区域,如果该存储区域有一个紧张的变量比如euid,那么我就可以用它来打击。另一种是典范的double-free堆糜烂,在内存回出操纵中,合并相邻闲暇块重新拔出双向链表时会有一个写4字节内存的操纵,如果缺点步伐由于编程错误free()一个不存在的块,我们就可以经心伪造这个块,从而覆盖任何我们想要的值:函数的返回地址、库函数的.plt地址等
  l格式化字符窜毛病(format string vulnerability)
  如果格式窜由用户定制,打击者就可以任意伪造格式窜,利用*printf()系列函数的特性就可以窥伺堆栈空间的内容,超常输出可以引发传统的缓冲区溢出,或是用”%n”覆盖指针、返回地址等。
  l整形变量溢出(integer variable overflow)
  利用整数的范畴、标记等题目触发宁静毛病,大少数整形溢出不克不及直接利用,但如果该整形变量决议内存分配等操纵,我们就有大概直接利用该毛病。
  l其他的打击手法(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官方链接:
  http://immunix.org/
  Stackshield
  StackShield使用了另外一种不同的技能。它的做法是创建一个特别的堆栈用来贮存函数返回地址的一份拷贝。它在受掩护的函数的扫尾和末端分别增加一段代码,扫尾处的代码用来将函数返回地址拷贝到一个特殊的表中,而末端处的代码用来将返回地址从表中拷贝回堆栈。因而函数执行流程不会改变,将总是精确返回到主调函数中。在新的版本中曾经增加了一些新的掩护步伐,当调用一个地址在非文本段内的函数指针时,将终止函数的执行。
  Stackshield无法防备只覆盖%ebp的单字节溢出,异样,我们也可以经过覆盖其他的ELF结构来绕过限定。
  www.angelfire.com/sk/stackshield/download.html
  二、库函数链接掩护
  Formatguard
  Formatguard是个Glibc的补丁,遵照GPL,它使用特殊的CPP(gcc预编译步伐)宏取代原有的*printf()的参数统计方法,它会比较通报给*printf的参数的个数和格式窜的个数,如果格式窜的个数大于现实参数的个数,就鉴定为打击行为,像syslogd发送消息并终止历程。
  如果缺点步伐调用Glibc以外的库,formatguard就无法掩护。
  www.immunix.org
  Libsafe
  Libsafe是一个静态链接库,在标准的C库之前被加载,主要加固了gets(),strcpy(),strcat(),sprintf()……等容易发生宁静题目的C函数,它设计为只针对stack smashing && format string范例的打击。Alert7很早也写过怎样绕过libsafe掩护的文章。
  http://www.research.avayalabs.com/project/libsafe/
  三、栈不可执行
  Solar designer’s nonexec kernel patch
  从名字可以看出这是一个Linux上的内核补丁,该补丁最主要的特性是:用户区堆栈不可执行(Non-executable User Stack),由于x86 CPU上并没有提供页(page)执行的bit位,所以该补丁经过减小代码段的虚拟地址来区分数据段和代码段,步伐执行流返回 0xC0000000以下一段用户堆栈空间的操纵都被认为是缓冲区溢出打击行为,随即孕育发生一个通用掩护异常而终止历程。这样把shellcode布置在buffer或环境变量(都位于堆栈段)的exploit都市生效。当然其宁静也不是绝对的,利用PLT返回库函数的文章里详细形貌了突破该补丁的打击方法。
  该补还有一些其他的特性:静态链接库映射到地址低端(0x00开端)、限定标记链接打击、/tmp目录限定、/proc目录限定、execve体系调用加固等。
  www.openwall.com
  Solaris/SPARC nonexec-stack protection
  在Solaris/SPARC下可以通已往掉堆栈的执行权限来禁止堆栈段执行,方法如下,在/etc/system中参加两条语句:
  Set noexec_user_stack = 1
  Set noexec_user_stack_log = 1
  第一条禁止堆栈执行,第二条记载全部实验在堆栈段运转代码的活动。Reboot之后才会见效。
  全部只让栈不可执行的掩护是无限的。Return-to-libc、fake frame之类的技能都可以突破限定,不外栈不可执行的掩护曾经极大了提拔了打击难度。
  四、数据段不可执行
  kNoX
  Linux内核补丁,功能:数据段的页不可执行,撤销共享内存,加强对execve体系调用的限定,对文件形貌符0、1、2的特殊处理,/proc目录的限定,FIFO限定,标记链接限定,该补丁只支2.2内核。
  http://isec.pl/projects/knox/knox.html
  RSX
  Linux内核模块,数据段(stack、heap)不可执行。
  http://www.starzetz.com/software/rsx/
  Exec shield
  Exec-shield从内核态显示的跟踪一个使用步伐所包罗的可执行映像的最大虚拟地址,静态的维护这个“可执行虚拟地址的最大值”称为“可执行限界”,每次发生历程切换的时候调度历程就会用这个值更新代码段形貌符写入GDT,exec-shield静态的跟踪每个使用步伐,所以每个步伐运转时都有不同的“可执行限界”,由于可执行限界通常是个很低的虚拟地址,所以除了stack以外mmap()映射的区域以及malloc()分配的空间都处在可执行限界之上,因而都是不可执行的。
  当然Exec-shield无法防备跳转到低16M地址空间和return-to-libc的打击,不外还是能阻止绝大少数把shellcode布置在数据段的打击。
  http://redhat.com/~mingo/exec-shield/
  五、增强的缓冲区溢出掩护及内核MAC
  OpenBSD security feature
  OpenBSD和Hardened Gentoo、Adamantix、SELinux都是属于默许宁静品级十分高的操纵体系。OpenBSD经过代码审计,毛病十分少。异样他具有许多宁静特性:
  l使用strlcpy()和strlcat()函数更换原有的危险函数
  l内存掩护:W^X、只读数据段、页掩护、mmap()随机映射、malloc()随机映射、atexit()及stdio掩护、
  l特权分离
  l特权回收
  lBSD chroot jail
  l其他的许多特性
  此中W^X有不少内容:stack、mmap随机映射,只读GOT/PLT/.ctor/.dtor等。虽然实际上OpenBSD无法阻止全部范例的打击,但曾经阻断了不少打击手法。
  PaX
  PaX是个十分BT的东西,好像天生就是缓冲区溢出的死仇家,他严厉的审视每一种打击方法,予以阻断。
  l基于x86段式内存办理的数据段不可执行
  l基于页式内存办理的数据段的页不可执行
  l内核页只读
  2Const结构只读
  2体系调用表只读
  2局部段形貌符表(IDT)只读
  2全局段形貌符表(GDT)只读
  2数据页只读
  2该特性不克不及与正常的LKM功能共存
  l完全的地址空间随机映射
  2每个体系调用的内核栈随机映射
  2用户栈随机映射
  2ELF可执行映像随机映射
  2Brk()分配的heap随机映射
  2Mmap()办理的heap随机映射
  2静态链接库随机映射
  l还有诸如把静态链接库映射到0x00开端的低地址的其他特性
  这里顺便提一下Phrack58上Nergal写过的<>,这篇大作里提到用伪造栈桢(Fake frame)和dl-resolve()技能突破PaX多少掩护的方法,这极有大概*nix使用层exploit技能中最初级的技能,Nergal办理了几个题目:Stack/Heap/BSS不可执行、mmap随机映射,显然这种初级的技能仍旧无法无条件的突破PaX,所以在一个运转完全版PaX的Linux上,你想发动缓冲区溢出大概是没无机会的!!!
  PaX Team
  http://pax.grsecurity.net
  Grsecurity
  Grsec内含PaX(这个更BT??汗~),和Lids一样grsec支持内核MAC(Madatory Access Control,逼迫拜访控制),拥有十分多的特性,详见http://grsecurity.net/features.php
  www.grsecurity.net
  六、硬件级别的掩护
  X86 CPU上采用4GB平坦形式,数据段和代码段的线性地址是堆叠的,页面只需可读就可以执行,所以下面提到的诸多内核补丁才会久有存心设计了种种方法来使数据段不可执行。现在Alpha、PPC、PA-RISC、SPARC、SPARC64、AMD64、IA64都提供了页执行bit位。Intel及AMD新增加的页执行比特位称为NX宁静技能,Windows XP SP2及Linux Kernel 2.6都支持NX,虽然这种硬件级的页掩护不如PaX那样强,但硬件级别的支持无疑大大增加了软件和操纵体系的兼容性,可以或许使缓冲区溢出的防护得到遍及。
  总结
  宁静和易用性总是站在统一面上,以上提及的掩护技能都市惹起少量的性能损耗,设计者们曾经从性能的角度优化了他们的作品。然而人们更关心的题目是兼容性,也许你会发明在那些运营级的BOX上根本看不到这些东西,是的,人们盼望的另一种宁静是不发生错误,即稳固的运转,使用这些分外的掩护会给人形成心理不安,我相信随着NX的流行以及掩护技能自己的发展这些题目都市得到办理。
  也许你经常会看到这样或那样的文章报告怎样突破缓冲区溢出掩护的初级exploit技能,实在许多内容只适合作为教学、或者技能自己还处在研究阶段,在现实的打击中,使用初级的bypass技能通常需要餍足一些条件,并不是单纯多花点力气增长了exploit代码的长度就能到达目的,在使用缓冲区溢出掩护的体系上,打击将变得十分困难,有些时候实在就是不大概,尤其是在远程无法准确得到必需的ELF标记地址的时候,许多技能都将变成纸上谈兵。
  使用雷同PaX的补丁,+iptables规则,再联合内核MAC,想入侵得到shell险些是不大概的,可惜偶没钱,不然拿个Linux box放到Internet上公测,让牛人们纵情的玩玩,哈~
  在缓冲区溢出尚未成为历史的本日,临时惦记一下吧,这当然也不是什么灰心的论调,旧技能的消亡一定陪同着新技能的降生,如果没有了Evil Hacking我们还坐在电脑前干什么呢?如果那样的话,我就和傻Billy去开个小超市,顺便报告Adam,Why他们也别干了。。让那些做宁静啥也不懂就会吹牛的人去干吧~~
  PST,
  Ph4nt0m Security Team
  http://www.ph4nt0m.org
  一群自由自在的年老人,虽然大多从事网络宁静工作,却由于崇尚Black Hat而聚到一同。
  Reference:
  Various paper & source free from Internet, most of them were listed above.
 


    文章作者: 福州军威计算机技术有限公司
    军威网络是福州最专业的电脑维修公司,专业承接福州电脑维修、上门维修、IT外包、企业电脑包年维护、局域网网络布线、网吧承包等相关维修服务。
    版权声明:原创作品,允许转载,转载时请务必以超链接形式标明文章原始出处 、作者信息和声明。否则将追究法律责任。

TAG:
评论加载中...
内容:
评论者: 验证码: