【专家专栏】Android中的防缓冲区溢出技术

转载 2012年10月07日 23:00:58

【51CTO专稿】本文将详细介绍Android中的防缓冲区溢出技术的来龙去脉。

1、什么是ASLR?

ASLR(Address space layout randomization)是一种针对缓冲区溢出的安全保护技术,通过对堆、栈、共享库映射等线性区布局的随机化,通过增加攻击者预测目的地址的难度,防止攻击者直接定位攻击代码位置,达到阻止溢出攻击的目的。通常情况下,黑客会利用某个特定函数或库驻存在特定内存位置的这一事实,通过在操纵堆或其他内存错误时调用该函数来发动攻击。ASLR则能够避免这种情况,因为它能确保系统和应用程序的代码每次被加载时不会出现在同一个存储位置。苹果的iOS系统自iOS 4.3以后就支持ASLR技术;虽然Comex在7月份发布的“iPhone越狱”软件就已攻克这一防御措施。而Android已经在4.0中应用了ASLR技术。

据研究表明ASLR可以有效的降低缓冲区溢出攻击的成功率,如今Linux、FreeBSD、Windows等主流操作系统都已采用了该技术。

2、缓冲区溢出攻击原理

缓冲区溢出是一种非常普遍、非常危险的漏洞,在各种操作系统、应用软件中广泛存在。利用缓冲区溢出攻击,可以导致程序运行失败、系统宕机、重新启动等后果。更为严重的是,可以利用它执行非授权指令,甚至可以取得系统特权,进而进行各种非法操作。

缓冲区溢出(图1)是指当计算机向缓冲区内填充数据位数时超过了缓冲区本身的容量溢出的数据覆盖在合法数据上,理想的情况是程序检查数据长度并不允许输入超过缓冲区长度的字符,但是绝大多数程序都会假设数据长度总是与所分配的储存空间相匹配,这就为缓冲区溢出埋下隐患.操作系统所使用的缓冲区 又被称为"堆栈". 在各个操作进程之间,指令会被临时储存在"堆栈"当中,"堆栈"也会出现缓冲区溢出。

在当前网络与分布式系统安全中,被广泛利用的50%以上都是缓冲区溢出,其中最著名的例子是1988年利用fingerd漏洞的蠕虫。而缓冲区溢出中,最为危险的是堆栈溢出,因为入侵者可以利用堆栈溢出,在函数返回时改变返回程序的地址,让其跳转到任意地址,带来的危害一种是程序崩溃导致拒绝服务,另外一种就是跳转并且执行一段恶意代码,比如得到shell,然后为所欲为。

历史上最著名的缓冲区溢出攻击可能要算是1988年11月2日的Morris Worm所携带的攻击代码了。这个因特网蠕虫利用了fingerd程序的缓冲区溢出漏洞,给用户带来了很大危害。此后,越来越多的缓冲区溢出漏洞被发现。从bind、wu-ftpd、telnetd、apache等常用服务程序,到Microsoft、Oracle等软件厂商提供的应用程序,都存在着似乎永远也弥补不完的缓冲区溢出漏洞。

缓冲区溢出攻击示意

图1  缓冲区溢出攻击示意

3、应用ASLR后的一个简单对比例子

下面使用一个比较典型的例子来显示使用ASLR前后的效果:

C源代码:

  1. #include <stdlib.h>  
  2. #include <unistd.h>  
  3. main()  
  4.  {  
  5.      char *i;  
  6.      char buff[20];  
  7.     i=malloc(20);  
  8.      sleep(1000);  
  9.      free(i);  
  10.  }  
  11. #ps -aux|grep test  
  12.  Warning: bad ps syntax, perhaps a bogus '-'? See http://procps.sf.net/faq.html  
  13.  aslr_test        8731  0.0  0.0   1632   332 pts/0    S+   18:49   0:00 ./test  
  14.  aslr_test        8766  0.0  0.0   2884   748 pts/1    R+   18:49   0:00 grep test  
  15.  aslr_test@aslr_test-laptop:~$ cat /proc/8731/maps  
  16.  08048000-08049000 r-xp 00000000 08:01 2256782    /home/aslr_test/Desktop/test  
  17.  08049000-0804a000 rw-p 00000000 08:01 2256782    /home/aslr_test/Desktop/test  
  18.  0804a000-0806b000 rw-p 0804a000 00:00 0          [heap]  
  19.  b7e60000-b7e61000 rw-p b7e60000 00:00 0  
  20.  b7e61000-b7f9c000 r-xp 00000000 08:01 12116      /lib/tls/i686/cmov/libc-2.5.so  
  21.  b7f9c000-b7f9d000 r--p 0013b000 08:01 12116      /lib/tls/i686/cmov/libc-2.5.so  
  22.  b7f9d000-b7f9f000 rw-p 0013c000 08:01 12116      /lib/tls/i686/cmov/libc-2.5.so  
  23.  b7f9f000-b7fa2000 rw-p b7f9f000 00:00 0  
  24.  b7fae000-b7fb0000 rw-p b7fae000 00:00 0  
  25.  b7fb0000-b7fc9000 r-xp 00000000 08:01 12195      /lib/ld-2.5.so  
  26.  b7fc9000-b7fcb000 rw-p 00019000 08:01 12195      /lib/ld-2.5.so  
  27.  bfe86000-bfe9c000 rw-p bfe86000 00:00 0          [stack]  
  28.  ffffe000-fffff000 r-xp 00000000 00:00 0          [vdso]  
  29. #ps -aux|grep test  
  30.  Warning: bad ps syntax, perhaps a bogus '-'? See http://procps.sf.net/faq.html  
  31.  aslr_test        8781  0.0  0.0   1632   332 pts/0    S+   18:49   0:00 ./test  
  32.  aslr_test        8785  0.0  0.0   2884   748 pts/1    R+   18:49   0:00 grep test  
  33.  aslr_test@aslr_test-laptop:~$ cat /proc/8781/maps  
  34.  08048000-08049000 r-xp 00000000 08:01 2256782    /home/aslr_test/Desktop/test  
  35.  08049000-0804a000 rw-p 00000000 08:01 2256782    /home/aslr_test/Desktop/test  
  36.  0804a000-0806b000 rw-p 0804a000 00:00 0          [heap]  
  37.  b7e1e000-b7e1f000 rw-p b7e1e000 00:00 0  
  38.  b7e1f000-b7f5a000 r-xp 00000000 08:01 12116      /lib/tls/i686/cmov/libc-2.5.so  
  39.  b7f5a000-b7f5b000 r--p 0013b000 08:01 12116      /lib/tls/i686/cmov/libc-2.5.so  
  40.  b7f5b000-b7f5d000 rw-p 0013c000 08:01 12116      /lib/tls/i686/cmov/libc-2.5.so  
  41.  b7f5d000-b7f60000 rw-p b7f5d000 00:00 0  
  42.  b7f6c000-b7f6e000 rw-p b7f6c000 00:00 0  
  43.  b7f6e000-b7f87000 r-xp 00000000 08:01 12195      /lib/ld-2.5.so  
  44.  b7f87000-b7f89000 rw-p 00019000 08:01 12195      /lib/ld-2.5.so  
  45.  bfe23000-bfe39000 rw-p bfe23000 00:00 0          [stack]  
  46.  ffffe000-fffff000 r-xp 00000000 00:00 0          [vdso]  

通过两次运行后对比/proc下的进程信息可以发现进程栈和共享库映射的地址空间都有了较大的变化,这使得以往通过esp值来猜测shellcode地址的成功率大大降低了。Phrack59期有一篇文章介绍过使用return-into-libc的方法突破ASLR保护,不过存在着较大的条件限制,milw0rm的一篇文章也介绍了通过搜索linux-gate.so.1中的jmp %esp指令从而转向执行shellcode的方法,不过由于现在的编译器将要恢复的esp值保存在栈中,因此也不能继续使用。总的来说,ASLR技术能够很好地保证Android代码及运行安全。

【责任编辑:立方 TEL:(010)68476606】

转载自:http://mobile.51cto.com/aprogram-358197.htm

Android专家级别的面试总结

1.. 自定义View流程 onMeasure, onLayout, onDraw, 采用深度优先,因为必须子view获得测量结果,父view才能确定大小; 2.. 事件分发机制 boolean...
  • qingtiantianqing
  • qingtiantianqing
  • 2017年02月15日 16:56
  • 876

如何成为技术专家

一万小时的专业技术积累和丰富的实战 丹尼尔在《一万小时天才理论》提出一万小时定律,即要成为某个领域的专家,需要积累一万小时,如果每天工作中花在学习和实践上的时间达到4小时,那么成为一个领域的...
  • jiazhen
  • jiazhen
  • 2015年07月29日 14:09
  • 1677

缓冲区溢出历史回顾

作者:fannywei在国外,早在80年代初就有人开始讨论溢出攻击,1989年,Spafford提交了一份关于运行在VAX机上的BSD版UNIX的fingerd的缓冲区溢出程序的技术细节的分析报告,这...
  • flycock
  • flycock
  • 2006年01月09日 12:03
  • 2196

《阿里感悟》如何在三年内成长为一名技术专家

工作前三年是职业生涯中成长最快的几年,在这段时间里你会充满激情,做事专注,也容易养成良好的习惯。在我们公司有些同学在前三年中就快速成为某一个领域的技术专家,有些同学也可能止步不前。本文和大家一起探讨下...
  • qq_28009065
  • qq_28009065
  • 2017年09月14日 20:16
  • 400

Java之旅--如何从草根成为技术专家

我个人觉得,不论什么领域,成为专家有3条是最重要的: 1、持续的努力,这是不可或缺的; 2、勤于思考,走了更少的弯路,这决定的是在路上的时间; 3、受到了高人的指导,或者自行模仿了高人,至少是仰望了一...
  • puma_dong
  • puma_dong
  • 2013年10月10日 01:17
  • 2690

掏心分享---年轻程序员如何快速发展成一名架构师或者技术专家?

做架构设计已经好多年了,前两天和一位年轻的同事聊天,这位同事从毕业到现在已经工作3年了,是我当前新公司里面最年轻的Team leader(在我现在新的公司,Team leader职位上的人工作7,8年...
  • chancein007
  • chancein007
  • 2016年12月18日 23:45
  • 6377

如何成为Java技术专家

首先声明,我不是专家。我还在路上,或许我永远也成为不了专家。不是我不够自信,而是对于知识应该保持敬畏之心。不知不觉工作快五年了,但仍然有很多困惑没有解开,写作此文,是为自己,也希望和与我类似的朋友探讨...
  • wuqinghai2012
  • wuqinghai2012
  • 2016年05月18日 16:13
  • 1321

怎样处理Android中的防缓冲区溢出技术

【51CTO专稿】本文将详细介绍Android中的防缓冲区溢出技术的来龙去脉。 1、什么是ASLR? ASLR(Address space layout randomization)是一种针对缓冲...
  • SoulsCarrier
  • SoulsCarrier
  • 2015年03月12日 14:59
  • 1018

Android 从小工到专家(必看)

欢迎Follow我的GitHub, 关注我的简书. 其余参考Android目录 通过微信公众号也可查看这篇博客文章.. Android 从小工到专家(必看) —— 由 吧主 分享推荐文章: ...
  • sunlion1993
  • sunlion1993
  • 2016年11月07日 10:07
  • 1986

谁是真正的程序语言专家

一直以来,程序语言的研究都是一个非常偏僻,却非常重要的专业。由于它令人却步的难度,很少有人说得清楚什么人是真正的“高手”。这是一个很简单的道理,当一个人仰望星空的时候,他不会知道哪颗星更加伟大。通常人...
  • wql19881207
  • wql19881207
  • 2012年07月03日 16:38
  • 2784
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:【专家专栏】Android中的防缓冲区溢出技术
举报原因:
原因补充:

(最多只允许输入30个字)