谢谢大潘给我做的介绍,在演讲的问题上,在中国可能没有比大潘的能力更强了,大潘前阵子搞了极限演讲的挑战,就是站在台上整整讲了一天,挑战下来了。今天我给大家讲的内容是,之前讲过一次,听过的人举下手,很好,只有几个人,我又能拿这个混一下。“内存战争20年”,为什么用这个题目呢?我们看这个词,内存·战争·20年。
内存怎么打仗?大家听到这个名字的时候可能脑子里面浮现出来的是机箱里几个人的内存条跳出来造反了,互相掐,是不是这个意思呢?实际内存在这儿它并不是战争的主体,它是个战场,发生在内存当中的战争。为什么讲个20年呢?IT技术是个日新月异,每天都有变化的领域,我们为什么要看一个20年这样久远的历史?比如现在要提到ATP这个词,大家耳朵都听出茧子来,认为就像前几年发生的Starnecape(音)、火焰。当时1986年,苏联还没解体,克格勃的人,就是一个为克格勃服务的攻击者,从西德不莱梅大学,因为1986年互联网远远没有今天这么发达,没有那么便利,而且它也不太可能从苏联直接进入美国的网络,所以他们通过西德当时德意志联邦邮局,通过一条卫星链路接入到美国劳伦斯伯克利国家实验室,这个实验室是为军方和国防做一些研究的,进入之后利用UNIX主机上的漏洞,获得了系统root权限,在系统里试图寻找和核有关的资料。
这件事情,在今天看来是不不是一个ATP事件?应该说相当得符合,但它发生在什么时候呢?1986年,而且这个事情最后被发现也是非常具有戏剧性,那时候大型UNIX主机是按照给每个用户使用时间付费的,每个人是瘦终端,连接到大型主机上,用多长时间交多少钱。当时负责维护主机科学家,因为实验室里没有网管,网管也是科学家,是个天文学家,他们领导跟他说这个月的涨你看一下,有个0.75美元对不上,谁用的?没交钱,就差0.75美元把这个人抓出来了,他用了0.75美元计算时间在系统里搜寻核技术有关的资料。
虽然说技术日新月异,但很多东西,几十年来并没有太大的变化,还可以再把时间往前推,推到1972年,James P·Anderson为美国空军写了一份文档,有上下册,有两册的文档,名字叫《计算安全技术规划研究》,想象一下1972年那时候IT技术是怎样的背景,那份文档里已经非常非常详细地描述了我们今天已知的很多种漏洞类型,非常清晰地描述了关于木马和后门的概念,甚至不仅仅是概念,非常详细的技术细节,类似像我简单翻译的这么一小段,大家看这一段描述的是什么?缓冲器溢出,有些说法和今天的名词不太一样,但说的是这么一回事。也就是说在今天这件屋子里,很多人还没有出生以前,他已经把这个东西讲的很清晰了。
幸好这份文档当时是技术的经典,但在美国没有引起足够的重视,没有特别多的人把它当一回事,所以我说幸亏没有人把它当一回事,否则今天我们和美国的差距会更大。因为有那样一份文档,大家去意识到理论上存在的可能性和做出实用的例子之间是有距离的。我们看到文字描述和看到真实的攻击给人带来的感受也是完全不同的。在我们看到这种现实的比较严重的有目的的攻击例子之前,其实有非常多的人已经做出了预见,并且提出了警告。这些声音都被忽视了。如果今天我问你有哪些比较严重的攻击案例可能都能说出来,但哪些人注意提出过警告,可能没有人说出来,因为没有人进行主义。
1988年Morris蠕虫在数小时内感染了当时互联网所有服务器的10%,大家知道蠕虫很多,刚才那份安德森的文档大家听说很少,因为只有真正出了事情才会知道这个事情的重要性,这是这个行业的悲剧。1988年Morris蠕虫事件让人们意识到漏洞的威力,也导致美国SEZ(音)的成立。这是当时电视台播新闻的一位主持人,播新闻时截的图,当时人们对Virus的认识还停留在几个电阻和一个集成电路来表示,就是当时人们大脑里对这些东西是没有什么概念的。蠕虫利用了服务器上一个漏洞,对蠕虫也没有概念,所以它用Virus的词,因为普通人对安全唯一的概念就是Virus,所以电视台播这个新闻时不得不用大家熟知的概念介绍Morris蠕虫。即使在Morris蠕虫发生很长一段时间之后,很多程序员仍然认为缓冲区溢出类的用户只是导致一部分程序崩溃的Bug。相关技术只在非常小的圈子里被讨论。
1988年再往后,一直到1995年才出现了第一篇公开去讨论漏洞利用技术的文章,这才把一直是在台面之下的东西有人把它拖出来了,有人看一眼。我说的《内存战争20年》,这20年是从1995年开始算的。1995年到今天20年,因为战争要有交战双方。1995年这些东西都有了,但没有交战双方,因为没有防御者,只有攻击者,一方对另外一方无情殴打,根本不存在攻防双方的对抗,所以1995年之前是没有战争的,1995年之后才有战争。
安德森在23年前,就是1995年之前的23年所写下的那段话才真正被人们接受,攻防双方在内存中的较量才展开。第一个向人们介绍相关技术的同志。左边是他当程序员时的照片,右边是他2009年加入国防部的照片。是不是很难想象之前摇滚青年很朋克的形象一下就站到国旗下了。他本命叫Peter Zato(音),加入国防部之后加入了Google的实验室,昨天还是前天他又受到白宫的邀请,请他出来建立美国国家级信息产品的安全检测实验室。他应该是已经接受了这个工作邀请,从Google出来再走马上任干这件事情。
到了1997年,Sun公司在Solaris2.6中借助SPARC处理器的新特性,实现了禁止执行堆栈上的代码。大家在学校里学习安全编程相关课程时,有的教材会提到缓冲器溢出是由于冯·诺伊曼体系导致的。实际上Sun做的这些事情可以理解为在逻辑上让冯·诺伊曼体系成为某种程度上的哈佛式体系。同样,也在1997年,StackGuard技术诞生了,前面Sun技术是基于应尽做的,而StackGuard,非常有意思的是1997年基于软件和硬件的两套漏洞防御思路,也是我们今天沿用至今的两大防御思路都在1997年诞生了。
也在1997年,在这两种技术的对面,就是战争的另外一方,绕过这两种技术的对抗技术也诞生了,1997年8月和12月,分别有两个人提出了绕过硬件的内存不可执行位的对抗方法,以及绕过StackGuard的方法,尤其是第二个。前面大家写的都是一些Paper,我深知没办法告诉你Paper的名字,因为Newsham在邮件列表里回的时候简单提了一句话,简单提了一下他的思路。今天邮件列表大家有点陌生了,早期大家认为邮件列表就是今天的BBS,今天BBS也逐渐走向夕阳西下,或者今天的微信群。就是他提了这么一句,他提的这样一句话,在之后很多论文里,引用参考里会说某年某月某日在邮件列表里提了一下,甚至不是一篇正经的Paper,但有大量的Paper引用这个内容。
那段时间,整个安全研究界的气氛是非常好的,非常多的聪明人在这个领域里,而且毫无保留地发表自己各种想法。但从整体上闷热对漏洞的认识仍然前行的比较缓慢,包括一开始大家认为缓冲区溢出的问题只能在Unix系统上实现。1998年,1999年安全社区里出现了两篇文章,提出了成熟的Windows缓冲区溢出漏洞利用技术。1998年DilDog写的缓冲区溢出,这主要是栈溢出,1991年Shok写的Windows的堆溢出。因为Windows堆栈系统不稳定,而且高位经常是零,利用起来和Unix系统是很不一样的,这两个文章里把这个技术做得相对比较实用了。
第二篇文章的标题叫“W00W00”那个年代比较活跃的黑客组织,Shok是这个组织的成员之一,他写这篇文章时大概只有十几岁,左边穿蓝色衣服金发的是他,这是2001、2012年的照片,那时候看上去也非常年轻,可以想见他1998年该有多大,大概15、16岁。“W00W00”组织也是国外黑客组织历史上值得铭记的组织,Whatsapp创始人是W00W00这个组织的成员。ABO(音)这个厂商做抗拒绝服务的,ABO(音)厂商是W00W00的成员,这个成员还创建了很多其他的公司,它的CloudVolums被沃尔沃(音)收购了,成为沃尔沃(音)的一部分。该
Sun SPARPC的硬件体系中,存放位置由地址去确定的,也就是说计算机没有办法区分数据和代码。Sun的这个硬件防护技术可以把地址和指向代码的地址区分开,CPU可以拒绝职能那些指向数据区域的指针。这是内存不可执行技术的本质。继Sun SPARPC处理器出来之后,出现了DEC alpha、IBM的、AMD Athlon64一系列面向服务器的CPU,都增加了类似的特性,直到2003年这项技术才出现在电脑里。
在2003年,微软在新发布的Visual Studio中新增了类似StackGuard的软件保护机制,1997年软硬件防护措施和对抗措施同时出现,2003年又是很有趣的时间点,这些技术统统在个人电脑上出现了,一旦到了个人电脑上之后,这种对抗就就开始进入白热化阶段了,因为电脑影响面远远大于服务器的,各种各样的技术,我们叫神仙打仗,各种各样的技术在内存中混战。
2009年,战火从服务器烧到个人电脑,烧到了手机,Android系统在2009年引入了类似StackGuard的机制,2010年引入了内存不可执行(No-EXecute),2011年引入了地址随机化(ASLR),2013年把SEAndroid技术引进进去。中国国产手机并不能打开,Android官方这些都提供了,我们国家很多手机厂商开安全特性会影响跑分。跑分背景下有关安全就没有打开,总结一下漏洞相关的技术,可以粗略地去对照人类的文明发展,人类文明发展了上万年,内存发生了相似的阶段,如果我们把人类文明从原始、农业、工业这个过程,人们在原始文明进行狩猎采集,到了农业文明进行耕种养殖,到工业文明进行制造与合成。漏洞的挖掘、攻击和防御这三块领域其实也会有相关的关系,漏洞挖掘在早期都会有个人的能力,而且基本靠这个眼睛看,靠个人的经验。逐步发展开始有一些自动化和工程化,到了今天,把这个已经发展成个非常成熟的工业体系。包括攻击也是这样,最早我们可以把早期的漏洞攻击方法抽象成为利用内存中的数据,发展中期以黑伯斯布瑞(音译)为主的创造数据的技术。到今天发展为在内存中进行字节级的控制。
相应的防御领域也是这样,防御上,今天技术已经发展到什么程度呢?我们称之为“纵深防御”,最典型的厂商就是微软,以微软为代表的。今天的思路是减少可利用的漏洞。
1、以微软新推出的延迟释放和隔离堆等技术为代表;
2、降低漏洞利用成功率,漏洞再怎么减少它是不可能杜绝的。那么对于实在存在的这些漏洞,降低利用成功率,再怎么样降确实还有一些漏洞会被漏洞利用成功,怎么办?
3、增加漏洞代码编写成本,再怎么对抗最后也是成本对抗。
4、你要不惜一切代价来攻击,就假设你攻击成功了,降低漏洞利用带来的危害,以沙箱技术为代表。
从更大的视角来看,现在更大的漏洞防御已经从早期的单点发展到造的一个词“全时视野”,从设计时到开发时、到编译时、到运行时,每一时都有相应的技术体系和方法去保障。同时,通过业界合作,上游、下游,微软相当于在中间,上游是英特尔,下游以Adobe为代表的开展业界合作。我们知道与Adobe合作,微软把Adobe漏洞纳入到自己的安全公告体系里。社区建设,包括赞助活动、举办会议、悬赏奖励等等。
Intel近年为防御漏洞利用近期在他的Ivy Bridge处理器实现了SMEP或SMAP进行合作,这是在微软的Haswell处理器里实现的。
即将面世的Intel Skylake处理器新增了MPX指令集,英特尔为了安全性在处理器里加上指令集和特殊性,唯一目的是为安全,这些年他做了很多事情,这和微软的上游建设是分不开的,英特尔增加MPX指令集也不仅仅是这种因素,因为缓冲区溢出已经诞生几十年,而且已经有StackCookie等软件方案,为什么英特尔还要搞硬件方案呢?以前这些事儿靠微软就行了,但因为英特尔要做移动市场。刚才我提到的一些原因,Android碎片化很严重,安全又没有像微软这种强有力的手在上面推动,在这种背景之下,英特尔自己如果想把这个生态做好自己得开始出手了。微软为了推MPX在GCC社区里已经推了很长时间,把相关的指令集加到社群里面去了。
无论是攻击还是防御技术,都已经进入综合、融合、协同、多维度的发展阶段。在内存战争进行了20年后的今天,我们会议一下这20年中发生和发展的事情,再去想象一下未来这种战争,首先没有结束,其次会更加精彩!
谢谢大家!