腾讯马劲松:WannaCry病毒事件的反思

 

马劲松,腾讯安全反病毒实验室的负责人,实验室主要是做TAV杀毒引擎的研发和运维,加入腾讯之前在瑞星工作

本文是对于WannaCry事件的一些反思。

小病毒 大影响

WannaCry病毒爆发在一夜之间产生了非常大的社会影响,“勒索”“比特币”“暗网”等关键词在一夜之间耳熟能详。

我们先简单的回顾一下勒索软件的历史。最早可以追溯到1989年,真正的有一个历史标志性的事件实际上是在2013年,2013年的时候,真正的是勒索软件和比特币结合起来了。当勒索软件和比特币结合之后,真的形成了一个有大力可图的黑色产业。在2017年5月12日以前,勒索软件只是个小众的关键词,而此次的WannaCry事件是勒索软件被大众所熟知。

其实国内敲诈病毒也是在尝试阶段,比如这个上面提到的Windows的敲诈,这应该是在两年以前的一个病毒。这一页是一个手机敲诈,其实大家如果细看的话可以看到,里面都有一个QQ号,因为它里面有一个很大的问题不能解决,就是支付问题。就是你敲诈,把别人锁定了,怎么收复赎金呢?这是一个很麻烦的事情,他们把QQ号都写在上面了。所以这个东西,你说它是一个敲诈病毒也好,说是一个恶作剧其实更确切一些。因为写了QQ号,基本上定位你就是分分钟的事情,我们更认为它是一个恶作剧的东西。

具体到这次WannaCry事件,为什么影响这么大?基本上可以归结成两点。第一点就是这次的敲诈勒索病毒和漏洞结合起来了,这是一个质量非常好的漏洞,微软在3月14日已经发了补丁,但是打补丁的时候大家知道有一个空档期,这个被充分利用了。另外比较重要的原因就是利用方式公开了,把整个完整的利用的办法都公开了,你可以任意的替换里面的组件,想做任何的事情都可以,这个一公开之后,这些作恶者用起来就非常容易了。地区个其实也是比较重要的,就是这个漏洞是Windows的系统漏洞,基本上你只要用Windows,它就一定有这个漏洞,分布很广。不像某些应用漏洞,不装这个应用或者不开启这个应用就可以规避这个漏洞。这个不是,只要Windows启动了,就一定会暴露在这个漏洞之下。第二点影响比较大的就是这次针对的目标是我们PC上的数据文件,大家知道,一台PC也好,一台手机也好,真正有价值,有意义的可能是里面的数据,硬件的成本是固定的,而且随着摩尔定律,随着社会的发展是越来越降低的。真正重要的是你的数据,这次的发力点,破坏的也是你的数据,大家的感触非常深,非常疼。锁定被敲诈之后赎回之路非常漫长,我不知道在座的各位有没有人做过这方面的尝试,就是真正你点那个软件,按它的提示是非常麻烦的,就是国内因为一些特殊的网络,一些管理的因素,对于访问暗网都很成问题。就是你中招了,想赎回基本上都是没有办法的,很麻烦。如果我们用暴力破解,用技术手段几乎是不可解决的,这里打了“几乎”两个字,那就是说,在某些特殊的情况下,可能还是有一线希望,可能还原回来的。

具体到这个漏洞,Shadow Brokers公布这个漏洞方式是4月中旬,公布之后我们也紧急的利用它的一些信息做了一款漏洞的检测工具,可以直接输入IP或者输入一个IP列表进行检测。这个工具其实是有参考代码,还是很简单的。我想说的是,这个工具我们在5月12日之后,5月13日这个病毒真正爆发了,应该是在上班以后,周一或者是周二的样子,我们把这个工具给到了一个合作单位,不方便说这个单位的名称。让他们去检测一下内网的情况,大家可以看到,这是一个枚举,从.1开始一直到255,命中率其实还是很高的,随便就找到了一个没打补丁的。下面这一张我不知道后面的同事能不能看清,是他们单位里面把知道的IP写到一个配置文件里面,用这个工具去扫,基本上是把把中,大家可以看到。回到这一页大家也能看到,漏洞的利用方式是公开的,分布是很广的,这就是让敲打、勒索的这种危害的病毒,实际上是搭载了一个非常高效,非常好用的一个传播工具,可以快速的进行传播。

刚才分析了病毒为什么影响这么大,因为它的漏洞分布很广。下面我们来讨论一下关于破解的一些事情,被勒索以后真的就不能破解吗?其实也不完全是这样。这里面举了两个简单的Case,这是我们实验室曾经处理过的两个敲诈的病毒。第一个是作者实现的时候,算法没有问题,算法在理论层面上是不可逆的。但是在它的具体实现上,有了一个小小的瑕疵,找到了一个破解的办法,就是把它的破解强度一下子降低了很多。Tesla这个东西,因为一些原因,作者把Key放出去了。举这两个例子是说明什么呢?就是我们看起来一些不可解、不可破的危害或者是样本,只要追下去,可能就会有一丝的希望。

具体到这一次的敲诈,有没有可能找到曙光?我们也对整个加密流程做了一个详细的分析,简单的在这里进行了一下整理。这是一个加密流程,作者会把一个公钥放出来,在本机里面,在每一台中招的机器上面会生成一个RSA的公密钥,还有一个使AES,会把AES随机的密钥用生成的RSA的私钥加密起来。对应生成的这个RSA的公钥,用病毒做的公钥加密起来,这样形成的加密链导致是不可破解的。这张图如果大家熟悉SSL通讯的,可能也能看到,跟这个也是比较像的,你在建立一个SSL通讯的时候,基本上也是先通过证书拿到一个确认的公钥,然后进行后面的流程。

我们重点关注的是在这里,生成本地的RSA私钥的时候。大家看AES,这是一个对称加密的,这个密钥是一串随机的数,生成之后,这个数拿到下面去用了,再去碰这个数的机会实际上在算法里面是不多的,会把它拆解来使用,从产生到使用流程非常简短,所以在AES这个部分,找到漏洞的可能性是非常小的。但是在RSA这边不是,RSA要能够产生出来一个可用的公司钥,其实还是会经过几步的过程,我后面会提到。在这几步的过程当中,某一步如果在具体实现的时候有瑕疵和漏洞,还是会可能被利用到。

这里可能要简单的回顾一下RSA的算法。这个我就不详细的去读这个东西了,总之有几个关键点,就是首先要有两个大的素数P和Q做下面的运算。最关键的大家看这句话,当你产生了一对公钥和一对私钥之后,一定要把P和Q销毁掉,这是很关键的。如果有一个没有销毁,用N除以那个数,这两个质数就拿到了。拿到了两个质数,整个RSA的加密体系就能够破解掉。下面这张表格是我在网上找到的,我觉得这个可能是目前为止我看到的解释最清楚的一个RSA的加解密的算法。所以我们也是在想,在整个RSA使用的过程中,有没有可能有漏洞或者有缺陷能被我们利用呢?那几天我们的同事一直在做这一方面的逆向,这种研究工作,终于看到了转机。

我特别打了一个标题,向Adrien这个人表示敬意,他把他研究的成果及时的公开了,让我们很多人的工作速度和进程加快了很多。在他公开的文档里面,其实比较重要的是下面我打横线的这两句。简单来说,就是说Windows Crypt的API在具体实现的时候,在XP这个版本上没有把质数清除,在内存里面还是存在的,有一定的可能性,就是只要这个进程不做其他的事情了,通过枚举可能还是有办法的,这是很关键的一点。这里有一个很大的条件,就是在XP系统上,我们后来在Win7、Win10上都做了反复的验证,发现这个Key其实是被很好的清除掉了。这里其实也有一个比较有意思的事情,就是我们的同事在逆向WannaCry的时候,发现这个是非常高明的,很多人也有逆向的爱好和能力,非常建议大家能够去逆向一下这个Windows Crypt的API,那个实现还是非常严谨的。

破解流程。

会在整个加密进程的空间里面搜索所有的内存,每次读取128个字节,大家可以算一下,乘以8正好是1024。他每次会读128个字节,先假定它就是那个质数。最精彩的是在这里,怎么判断这128个字节是一个质数呢?他算了一下熵值,这是非常高明的。因为大家知道,算一段8分的熵值这个速度是非常快的,如果熵值大于0.8,也就是说这一段内存是比较混乱的,他认为就是质数了。如果它是质数了怎么办?后面就去看,再确认一下是不是真的是素数,然后对PE×Q那个大N做一下除法。我的同事后来发现,在新的版本里面已经把这个去掉了,Block是不是质数这个判断已经去掉了,因为前面靠熵值这个办法已经能够比较快的判定一个大数是不是质数了。如果能正除,那就找到了这个质数。刚才提到了,放到外面的公钥是E和N,私钥是D跟N,E是P×Q,都找到了,整个加密的东西就已经全部解开了。这是截屏的过程,非常精彩,大概试了3次,就找到了这个P。找到之后,后面的整个流程就非常的规范了。

在整个Adrien公开的代码过程当中,有两点是值得注意的,如果不认真的读代码,对于加解密这一块没有比较深厚的积累,可能也不太容易发现问题。在公开的代码里面,第一版把OpenSSL里面,有一套加密的算法库,大家可能都知道,刚才公开的代码第一版的时候,找到了那个素数,后面使用的过程当中,是按照OpenSSL规范使用的,而不是按照Windows Crypt使用的,就导致后面质数的使用过程当中不对,病毒清除的时候质数没法用。这是怎么回事?可能作者一边调试一边做,他发现找到这个质数了,可能就没有做进一步的事情了,代码就提交了,这是一个值得注意的点。

代码里面大量的使用Auto类型,这个其实也是新版本,或者C++这种新的规范,是比较推荐的。就会导致你的版本如果和他的版本不Match的话,就有可能导致不匹配。他定义的Auto的变量其实都是一个大整数。如果你的边系和作者的边系不匹配的时候,就会导致大整数被截断,后面所有的就被匹配掉了。这样小的瑕疵是无伤大雅的,并不能够掩盖作者的贡献和超凡的能力,还是要向作者表示敬意。

因为有了作者的贡献,所以我们的小伙伴在很短的时间之内找到了一个实现的方法,这个也是我们这个团队在那一天的时候,应该是5月19日那一天,在全网是首发了XP版的破解工具。那个时候还发生了一件非常精彩的事情,我们发了这一条微博之后,别的厂商也快速跟进,导致微博的操作都出现了一点迟钝,那天是非常精彩的一个场景。这是关于破解这一块。

如何减少安全的漏洞。这里有三点:

一是优化关键漏洞检查机制,刚才给大家看了,那个单位里面像筛子一样的整个漏洞情况。这里面有一个很大的问题,就是这种安全检查都是单向的,没有交叉检验,只是一个口径,比如某个软件上报,这是不好的。我们建议后面比如可以搞这种检测和模拟攻击结合,检测发现打或者是没打补丁,这个冲击力是非常有限的,但是如果用模拟攻击这种打进去了,或者说探测出来了,这个冲击力是非常强的。所以我们建议,后面能够有一些更优化的检测和攻击手段的结合。减小攻击面,其实大家也能看到,凡是中招的用户里面,一定是打开了445这个端口,而且在大多数情况下,其实445是不用的,大多数情况下是这样,当然某些局域网的情况下某些文件分享可能会用到,整体而言使用率是不高的,应该把不用的端口关闭掉,特别是高危的端口,减少攻击面。

二是作为开发者,就是老老实实的啃代码,认认真真的看文档。随着作者把代码公开出来了,如果不能一行行的阅读,理解里面的逻辑就不能发现问题,就是所谓的黑盒测试一样去验证,达不到一个很好的效果。包括在座的各位也是,很多年轻人,现在这种技术开发的成本实际上是非常低的,可能你用到的几乎所有的算法或者核心功能的代码在网络上都能找到。但是找到之后是不是一行行的去阅读?这个其实是一个很大的问题。通过认真严谨的阅读,会发现很多变量、实现细节这些逻辑。认认真真的看文档也是,刚才我截的那个截图,其实里面的很多信息是MSDN里面已经标清楚的,已经标明的。但是很多人阅读的时候,可能没有这么认真,或者是注意到这些细节,这可能也是技术从业人员应该具备的一个基本素质,就是读代码、写代码的能力和严谨的、海量文档的阅读能力。

三是一些方法论的东西,就是永不放弃。只要有一分希望,那就是百倍努力,你长期关注它,长期去研究它。当有一些别人或者同行有一点点进展的时候,你能第一时间感知到,你能第一时间把他们的成果和你的积累结合起来,这样也会让我们的工作能够取得更大的成效。

上一篇:ADLAB朱钱杭(大菠萝):其实它们近在咫尺

下一篇:腾讯徐少培:浏览器地址栏之困