网络安全技术峰会上讲演实录:
褚诚云:大家好!我叫褚诚云,来自微软公司。我这个讲座可能跟其他人的讲座都有一点不一样,我是从产品开发的角度和大家分析安全漏洞。我希望利用这个机会可以和大家分享一些在软件开发过程中如何避免安全漏洞的经验。我先自我简单介绍一下,SWI称为Secure Windows Initiative,我们这个组处理微软产品的安全问题。我们这个组严格意义上隶属于MSRC的一部分。 ChrisW是我们一个资深的架构师。
现在我们转到正题。很多人说微软是不是真正了解安全,为什么这么说呢?微软的安全漏洞问题层出不穷。如果真正懂得安全,为什么产品还有这么多安全漏洞呢?
今天讲的核心问题:{dy},什么是安全漏洞。第二,为什么代码中存在安全漏洞。第三,我们想探讨一下对每一个安全漏洞,我们做了什么。微软发现安全漏洞后,怎么处理它?我们是怎么在开发实践中去提高我们实践开发的指导过程,这样可以避免同样错误不要犯两次。
为什么你需要了解这些东西?现在安全漏洞不是微软一个的问题,就像腾讯总裁所说现在软件安全是整个产业的问题。比如微软收到很多不安全的反映。实际上攻击本身不是针对微软系统本身,而是上面运行的应用。我们希望通过和所有厂商共同努力,提高整个产业环境安全水准。例如,百度工具条就有安全漏洞、暴风有控件安全漏洞、迅雷也发现有很多安全漏洞、google输入法的安全漏洞,还有QQ。
下面我跟大家讨论一下五个我们组经过非常艰苦的努力,可以和大家分享的5个06、05年的安全漏洞。可以给大家公开讨论导致安全漏洞的源代码,在后面我要跟大家谈谈微软开发周期,怎么指导开发行为,这样可以降低安全漏洞的数目。{zh1}提一下微软关于安全响应流程的部分。
什么是安全漏洞?我们定义是代码或设计缺陷,导致系统可以被恶意攻击。我想特别强调一点,实际上很多安全漏洞是一个设计上的问题。设计上没有考虑这个功能在安全上给大家带来什么样的影响,这与设计人员本身素质有关系。我们看看安全漏洞主要类型:远程代码攻击最受大家关注。但是权限提升、拒绝访问、信息泄露的比例也是非常高的。
{dy}个,MS03-026漏洞。这个安全漏洞大家非常熟悉了。它的问题就在于一个字母串越界的问题,就是这一行代码错误,损失非常巨大。我们得到的经验:GS编译选项,静态代码检查工具。例如在VS2005,有一个选项是可以做代码的静态分析,尤其是溢出错误,可以帮助你检查。
缓冲溢出已经谈了很久了,为什么微软还有这么多安全漏洞?问题就是说安全漏洞本身和缓存溢出不相等。很多安全漏洞其实xx不是由缓存溢出构成的。这两个是不等价的。下面说的五个安全漏洞只有一个是缓存溢出。即使这一个缓存溢出也不是那么容易看出来的。
{dy}个安全漏洞,06-001 WMF。这个安全漏洞很严重。当时在圣诞节,我记得我是在赴宴途中被传呼。一个圣诞节,几百人都没有过好。WMF大家都已经很熟悉,他是Windows支持的一种图像文件。简单说就是大家访问这个文件,收到这个电子邮件,只需要预览就会被感染。可能直接导致大规模蠕虫爆发,所以当时大家非常紧张。这是源代码(图),你觉得这个代码需要特别注意什么地方?我其实首先看到是win.3.1这段注释,写这段代码的时候没有考虑到安全问题,当我们读到类似这种注释的时候,我们脑子里开始紧张。我们看看它具体出了什么问题,这个是一个函数指针,这是函数指针的调用,这是执行(图),关键是在这里,当我开始处理WMF文件的时候,当收到特殊字符的时候就对它进行解析处理,把Abort方式设置好,{zh1}开始执行。整个过程没有缓存溢出漏洞。你需要一个函数可以终止打印操作,这在Windows3.1是很正常的操作,而现在造成这么严重的安全漏洞,这就是设计上的缺陷。有时候设计的缺陷比代码缺陷更难发现。一个设计上的问题导致安全漏洞非常严重。在构造这个文件的时候,提供一个老的无用功能,结果导致一个严重的漏洞。我们把NetDDE、IPX/SPX、NETWare这些全从VISTA中删除了。我们尽可能把那些不需要用的以前的老代码统统删除,因为老代码编写过程中往往没有考虑到安全需求。即使删除不了的,我们在缺省情况也要禁用,只有用户特别有这个需求,需要他自己主动把禁用这个功能开通。而且必须加以辅助测试和fuzzing,仅仅依赖人眼查看代码是不够的。
第二个安全漏洞,06-013 IE create textrange,问题就是我访问一个网页,机器就中招了。这个安全漏洞和缓存溢出xx没有关系。有没有人能发现问题?它的错误就在goto Cleanup这个地方。hr初始赋值S-OK。为什么这是安全漏洞?首先调用pvarresult就是一个函数指针,下面检查hr=s-ok,这是一个标准的com调用。我会调用到未初始化内存。4、5年前微软如果收到这个安全漏洞,他可能认为这不是一个安全漏洞,而只是一个程序崩溃。结果现在有了heap spray攻击,可能10次有9次能达到成功攻击。静态工具专门要提高对未初始化内存访问,使用SAL确保函数返回时的错误检查。
第三个安全漏洞,05-047 plug-n-play。首先他是直接读到一个注册表key,然后拷贝到堆栈上的变量,大家初看这是非常危险的。但是我们仔细一看,发现从本地注册表读这个key,内容是攻击者无法控制的。这个key本身最多只有255字节,而且内容只有admin才能控制。堆栈的变量大小是360字节,怎么会导致字符串溢出?我们当时也一下看不出有缓存溢出问题。它的攻击就是通过这样去攻击,虽然Key在注册表也是有效,但是后来加了这样一堆东西,会自动被过滤掉,结果拷贝就会溢出的。这是一个非常有意思的缓存溢出漏洞。得到经验是禁用危险的APIs,以前有这样的反对意见,只要我知道我在做什么,即使用危险的API也没有什么问题。这个例子就看出,在有些情况下即使你以为你知道你在干什么,但是还会发生你并没有想到的后果。所以我们彻底把危险的API从VISTAxx取消掉。
第四个漏洞,06-013 IE。当你访问一个文件类型属于不安全类型,我们通知你下载而不是直接执行。这就是代码(图),看上去xx没有什么问题。到底它出了什么问题?我们仔细看这个变量,它可以被多个线程同时访问,可能会导致跳过安全对话框。这个漏洞也和缓存溢出没有关系。我们得到一个经验:多线程环境下测试、代码复查时的安全意识。例子:微软对安全方面的标准,包括攻击界面分析、常见安全漏洞类型、针对威胁的缓解手段、针对安全缺陷来复查代码。我们这个组本身不可能去复查所有微软代码,要依靠各个产品组自身复查代码,但是你复查代码,你需要知道你去找什么样的错误。如果不知道要去找什么的话,即使你看半天也发现不出来什么。
第五个漏洞,06-018 MSDTC。这个实际上是自定义的内存分配。这里有一个宏,我看到这个代码是比较头疼的。微软针对这个安全漏洞补丁,发现了两次公告,{dy}次公告没有发布对,只好发第二次安全补丁。微软得到经验:对内存分配器加注SAL。在Windows VISTA删除大多数的定制在内存分配器,除非有特别考虑,一般是不允许的。另外,在汇编代码一级经验证补丁,这样可以避免补丁发布的错误。
安全漏洞分析小结:分析安全漏洞产生的根本原因,在已经实施现有的流程后,为什么还有安全漏洞?我已经规定你产品组需要做的安全流程,结果还有安全漏洞,这可能有两个原因,{dy},我说要做的事你没有做,这是管理上的问题。第二,你确实做了我要做的东西,但是还是避免不了安全漏洞。那就是流程或工具的问题。提供建议来完善现有工具和开发新的工具,同安全软件开发集成,并提供反馈。减少以后的安全漏洞。
于是我们提出SDL开发概念,安全软件开发专门针对产品安全性,它有几个原则:安全的设计、安全的开发、安全的部署。也就是在产品真正部署配置上怎么来处理。在设计阶段和需求阶段中,需求阶段引入安全功能上的需求,设计上提高安全设计风险分析,对程序攻击界面一个评估,编码就是安全编码实践和提供很多安全开发工具,测试提供是专门要进行安全测试,每个组都要提供尤其是安全方面的测试报告,{zh1}发布,你这个组响应过程,如果出现漏洞,你是怎么响应,有没有专人处理漏洞。{zh1}就是一个维护。这是具体流程(图),这里不跟大家仔细说了。如果产品暴露出严重的安全问题,即使下个月要发布这个产品,我们就有这个权力让你不能发布。微软认为安全这个问题不能忽视。
这是SDL效果(图),通过SDL可以在很大程度上降低安全漏洞。这是XP避免安全漏洞。VISTA安全漏洞的数目下降了,像这种统计数据可以证明SDL在实践中可以降低安全漏洞爆发的数目。
特别我想跟大家说一下微软安全漏洞响应流程,我们有一个邮箱地址,如果你有安全漏洞可以发邮件。我们相关团队对问题进行分析评估。相关团队包括两部分,{dy}部分就是我们组。第二组就是产品组。产品组根据我们意见看他们所有组有没有这样的问题。我们收到报告,我们验证这个地方确实是否有安全漏洞。产品组就要负责对所有版本都要检查,然后给我们汇报过来。因为我们组熟悉安全,产品组熟悉产品,两个组一起对这个问题进行评估。另一方面,是寻找安全漏洞变种和攻击方式。看到一个安全漏洞,但有可能发现5个、10个、20个漏洞的变种。然后就是一个修补计划。Windows SE组专门负责修补计划发布,代码的修改要经过我们组和产品组复查。还有一个就是缓解和变动。不管你怎么努力,你的产品中的代码是会有问题的,或者你的设计会有问题的,导致产品的安全漏洞是不可避免的。比如我有一个功能存在安全漏洞,但是这个功能在缺省安装上并没有被打开,比如这个安全漏洞是一个服务程序的安全漏洞,在缺省配置情况下这个服务没有被打开,这中情况下会会有效降低安全漏洞危害级别。这个是我们称为缓解概念。还有一个变通概念,用户并不想打补丁,可不可以通过命令行或者可不可以通过只是限制文件访问权限,或修改注册表,导致这个安全漏洞可以不能被利用,这个也是很关键的概念。我们把缓解和变通反馈给用户。给大家举一个例子,OFFICE的例子,大家知道OFFICE2003以前的版本安全漏洞,用户如果出现问题,他只有两个办法,{dy},必须赶紧打安全补丁。第二,如果不打安全补丁,你就不能打开doc文件。我们没有一个很好的缓解和变通说法。你要么打安全补丁、要么不要使用OFFICE产品。OFFICE2003现在有MOICE这个功能,就可以很大程度减低安全漏洞的危害。{zh1}一个是补丁发布。补丁发布很大的问题是兼容性的问题,一个补丁要过若干测试,看许多应用程序是否兼容。就是这样我们还是发现补丁发布后的兼容性问题。
我就讲到这里。如果你感兴趣的话,可以访问我们组的blog。我们一直认为安全问题不能通过信息隐藏达到。黑客总是有办法得信息,我们希望通过这个blog把我们能够公布的信息给大家。我主要就说到这里。
以下是现场问答部分:
问:你们有没有碰到针对发布方面的攻击?他们采取一些方式防止你们打补丁,碰到这种问题有没有什么好的解决方式。攻击人员分析漏洞一边是汇编级,你怎么定位成是什么地方代码,因为Windows代码也比较多。直接用汇集定位到代码问题。另外,每次程序崩溃后,可能会产生一些错误信息,提供当前什么地方出错。从我们现在来看,凡是碰到这个东西的时候,从这个地方看不出什么地方出问题,是更上一层导致的,这个东西对你们用处比较大吗?
褚诚云:{dy}个问题,我们有没有碰到补丁没法被用户下载或者直接利用的情况。这个问题是碰到过的,当你从Windows更新下载的时候,有一个反馈的过程。多少人执行完这个补丁是成功执行,多少人没有成功利用这个补丁,这个数据是有的。对每个数据我们都会分析。我现在记不清具体门槛是多少,假如一个补丁下载100万次,有5%即使下载了,但是不能成功打上。我们就有专人负责研究为什么不能打上补丁,而且这个数据是可以通过Windows更新拿到。
第二个问题,怎么从汇编代码确定源代码问题,首先源代码不是公开的,我们收到所有报告都是根据汇编代码累计的,或者有人直接POC,这是我们一般收到的漏洞报告。通过Symbol文件,就可以从汇编代码来确定对应的源代码。假设你自己的程序,当你收到外面一个反馈,你也可以确定哪一行程序的崩溃。
第三个问题,Crash Dump是非常有用的。通过Crash Dump,你可以确定知道哪里出错。可以说我们很多情况都是依照错误信息来研究的。
问:刚才你说到某一些部门不愿意推行安全SDL,你怎么处理?第二,我们经常会收到一些不是关于安全的问题,你们如何区分和排除?
褚诚云:{dy}个问题,当然是有。作为产品开发组,总有自己的要求、自己的客户、自己的开发计划。SDL对他们来说,一开始是额外的东西。所以要SDL的实施,你必须要有权力。如果你没有权力的话,你只能建议。当然我们不希望在很多情况下发生强制,我们不希望我们变成经常要说不。第二,在很多情况你不需要这种权力,可以通过培训方式改变观念。所有开发人员必须接受安全培训,例如为什么要注重安全漏洞。经过这么多年,微软观念已经被扭转了。SDL的观念已经被产品开发组接受。第二个问题,有没有垃圾信息,有。有没有办法,没有特别的办法。邮件过滤{zd0}的问题就是怕过滤掉有效信息。如果一个有用信息被当做垃圾邮件过滤掉,这是我们无法承受的。所以我们是专门有人看的。
问:我这边有两个问题:{dy},我们知道很多补丁发布的时候,黑客会通过补丁对比技术,到底产品问题在哪里。这样就存在一个问题,很多用户来不及打补丁,但是补丁发布后造成一些黑客通过补丁对比技术知道漏洞在哪里,然后写出一些办法。微软对补丁发布这块这种现象有没有一种保护措施?第二,刚才提到VS2005有一些工具对代码检查,后期测试也有一些工具,我想问一下这些工具我们从外部能够拿到吗?大概有哪些工具可以推荐给我们院?
褚诚云:{dy}个问题,这个我们都知道,如果对一个比较简单的补丁做对比,{yt}、半天就可以做到。我们有没有想过这个问题?想过,但是我们决定不这样做。你可以把补丁搞得比较麻烦。更大的问题是这个没有效果。不管你用什么样的技术,实际上是没有用处的。这是我们的观点。安全永远是不可能通过信息隐藏来得到,这是我们一直认为的观点。第二,根据现在趋势,一旦补丁发布的话,几天之微软可以分析有多少用户打了补丁。至于没有打补丁的用户,我们只好加强安全教育。而且每个补丁,我们尽可能提供workaround。即使你在补丁上加加密技术,也是阻止不了黑客。而且你看到微软所有程序也没有采用加壳技术,这也是微软一贯的风格。
第二,有关工具的问题。微软有很多内部工具,一个工具作为内部使用到一个工具可以公开发行,这是有一段距离。我们有很多内部工具,并没有公开发布。Visual Studio Team Edition里面提供了代码的静态分析程序。
问:我现在面临一个问题,我们在补丁发放时都培训过,问题是重启机器会带来很多问题,因为我们的应用不能说停就停,这样就存在出现时间差的机率非常大。微软有没有对这些方案解决的?
褚诚云:我想老的操作系统就没有办法xx解决这个问题。比如我要对核心dll修改,你就必须重新启动。你可以考虑workaround,可以保证你的系统暂时不受影响,当你什么时候维护的时候可以再重新启动。另外,可以考虑负载均衡,load balance。例如假设一个功能是由八个服务器共同服务的。这次两个服务器打上补丁,再打下面两个,这样不影响整个系统运行。
问:我多次听你说到VISTA有比较多安全改进,VISTA SP1相对2003、SP有什么安全漏洞方面的改进?
褚诚云:我先说2003、XP。2003是server,和XP针对的用户不一样。例如IE用在2003上,你会发现IE功能限制的很厉害。按理说你不应该在你的服务器上去访问随意的网站。否则你需要的话,这是一个很大的问题。至于Windows Vista,提供了许多安全的改进。例如DEP,ASLR等等。在Windows Vista下的缓存溢出的安全漏洞的利用,要困难很多。
问:我更关心DEP防溢出有没有改进?
褚诚云:要利用缓存溢出漏洞。在VISTA不是很容易实现。DEP只是其中的一个安全功能。Windows Vista中有若干个功能合在一起,例如GS,SEH,ALSR,DEP。