知道创宇周景平:非主流fuzzing

周景平:大家好,今天我给大家分享的主题是非主流的Fuzzing。这个主要是在我以往的一些漏洞挖掘领域的积累,有好多可能是好几年前做的一些实践,有一些是最近做过的一些实践,主要是跟大家分享一下。

4--周景平(Heige黑哥)

首先自我介绍一下,我的本名是周景平,目前在知道创宇当CSO,首席安全官。后面列举了一些黑客组织,下面有我的电子邮箱,我比较喜欢分享一些观点到微博上面,到Twitter,有知乎上面的一些分享,大家有兴趣的话可以关注一下。

首先我要介绍一下什么叫Fuzzing,Fuzzing的中文就是模糊测试。在这里列举了一本书,有两版,但是我不是说这个书有多牛,我觉得这个书一般。但是为什么会贴出来?我觉得它的标题写得好,表达了Fuzzing的一些比较深刻的认识,是《模糊测试强制发掘安全漏洞的利器》,我觉得这个标题取得好。里面有一些介绍模糊测试的历史、分类,我觉得可以参考,至于里面的一些内容,大家仁者见仁。里面什么叫Fuzzing,在这本书的序言里面,就是MSF的创始人举了一个例子,他有一个朋友,有一个小孩拿到一个苹果电脑被锁屏了,小孩一顿乱敲,结果把那个锁屏解了,这个就是模糊测试。

在里面有一个定义,在我们安全界里面我常说的一句话就是,安全圈都是语文没学好的,很多问题就纠结在中文的博大精深,你可以这样解释,也可以那样解释。比如我们安全界经常争论的,这个是漏洞吗?什么是漏洞,什么是Bug,一提到这个问题大家就吵个不停。这个东西有时候很难下一个定义,我觉得这本书里面也可以借鉴一下。它就给这个模糊测试下了一个定义,他是说通过向应用程序提供非预期的输入,并监控输出过程中发生的异常,发现这么一个软件缺陷的方法。另外也提到了一句话,在里面代表了一些主流的思想,就是模糊测试数是利用自动化和半自动化的一个方法重复的向程序输入。就像开始我举例子这个小孩一样,他不停的在键盘上输入,恰好有某一个命令就解锁了。

在这里我也类比了一下漏洞挖掘的过程和测试的结构和流程。这个其实很简单,就是按照定义来的,你首先输入你的原始数据,向你的目标程序解析执行,你去监控这个异常的输出就行了。在那本书里面,他的结构分得比较细。有一个识别目标,识别输入,这是什么意思呢?这个就是好像你拿了一个软件过来分析的话,你首先要更多的时候去了解它的协议,它是怎么样输入输出的一个数据格式。对于文件格式类的,你可能要去分析一下这个文件格式是怎么一个构造。然后你对于一个程序来说,哪些变量是你需要去控制的,这是一点。还有一点那个分类后面又解释了说,这个监测的异常不一定是漏洞,很可能是Bug。在这个Bug里面抽出来以后,再识别哪些是你要的漏洞。

我们第一步就是构造这种非预期的输入,我把它理解为这种生成模糊测试的样本数据,这个我认为是一个关键点。因为你所有的触发这个漏洞的东西,就取决于这个数据的量或者变化有多大。你的变化越多,或者说你的变化越大,可能你发现的漏洞,发现的异常可能就更多。但是这个里面的数据结构一般包括几个,这个是按我个人的理解来分的,包括基本的数据结构和模板及对应值。基本的数据模块,比如就是一个文件格式,你要放一个crash,首先要有这么一个模板。要发Word文档,本身自己有一个文件格式,但是文件格式里面还包括一些网络协议,包括一个语言语法概念。对应的值一般就是在某个属性的基础上,你要给予复制。比如一般常见的,我们比较常见的注入里面来一个逗号,或者在某些内层的漏洞里面给一个空的值,或者给一个超大的值,或者是给一个超长的字符串,告诉他内存的溢出。所以这个其实就是告诉我们非预期的一个输入。

这是一个例子,是一个浏览器的识别,其实你可以把基本的这些属性定义化搜集,首先要搜集这些东西,把这些搜集到,然后里面第一部分提到了有很多值,包括常见的字符串格式化的漏洞,或者是给他来一个复值,或者来一个超大的支点,其实就是一个很典型的非预期输入,首先要搜集一些前期的工作准备。

这个应用程序的解析其实就很简单了,注意两点就行了,对于Fuzzing来说,因为Fuzzing是要求自动化或者半自动化的东西。但是在这个阶段,对于一个Fuzzing来说,一般要求是全自动化要不停的把你的数据提交到应用程序,不停的去测试解析。整个东西里面有一些注意点在设计的时候,比如说在跑的过程当中异常了,推出了,崩溃了,你怎么样继续跑下去?要怎么样去处理这个异常?这是要注意的。然后就是框架稳定性的这一步,当你大规模集群部署的时候,你这个Fuzzing不能中断,一旦中断了,后面样本的测试就走不下去了。

这个里面要主要的主要是分类,就是说你这个Crash点是不是同一个,是属于同一类的问题。假如说你海量的数据,导致的异常太多了,你不去自动把它分类处理的话,有可能你这个样本简化半天,发现这个漏洞分析来分析去是同一个问题,极大的浪费了时间和成本。还有一种就是不能够稳定出现,因为这种有一次性的Crash,就是只能跑一次它就崩溃了,你不能复现,这种对于我们来说是没有太大的意义的,你没有办法复现我怎么去调试呢?根本没办法。

这里面主要是讲了一下主流Fuzzing的历史和现状。这本书里面有一个图,其实当时也总结得还算OK,是总结到了2007年。最开始提出的应该是在1989年,有一个教授在学术圈测试稳健性的时候就提出了这么一个方法,然后逐步发展。可以看到在这里面列举了几列,前期可以看出来,很多都是在文件格式里面,比如Word、Office系列的那些,后面又出现了基于浏览器的。到现在,我接着在后面总结了三个比较有名的,跟大家说一下。2010年Lcamtuf发布了一个Fuzzing的程序。为什么提他呢?因为他当时提出来,那个程序他刚刚发布的时候我就测试过,对于用的量比较少的那一类浏览器,提上去立马卡死。为什么要提它?它的影响在哪里呢?现在还有好多人基于这个代码进行修改,包括我前面贴图的那个,也是参考了这个代码进行修改。第二个是一个框架的代表,这个也是基于浏览器的。目前的主流Fuzz在浏览器这一块应用得很广,很多都在用浏览器。为什么要提这个框架?因为有很多公司或者说很多个人研究者在选用框架的时候去参考了这个框架,我也去尝试过套用这个框架做测试,但是它的缺陷确实还是很明显的。所以很多人做了自己的开发修改,好在它是开源的,可以去修改。第三个又是这个人,他现在是非常火的一个Fuzzing的工具,他跑出了很多的漏洞。这个人的理念相对来说是比较领先一点的,是跑内存,各种方法,这个效果你可以去参考一下,确实是很惊人的,目前还在不断的有人加入这个计划去跑。

这个现状,目前内存型的漏洞主要的挖掘手段就是模糊测试,这个竞争是非常激烈的。你可以从浏览器IE,或者说Chrome、Firefox每一个去看,你会发现这个竞争是相当激烈的。而且另一个就是高度的定制化、私有化、复杂化,很多安全人员都开始有自己的开源工具,比如著名的我们557的一位博士,他自己写了一个很牛的框架,他光ID就报了100来个CVE。而且我问了他一下大概用了多少机器,当时就是200个VM,这个产出是很惊人的。然后就是集群化和大规模化,前面谷歌有位安全人员在某个安全大会上分享了他们的一个云的Fuzzing,他就是已经云端化了,把这个Fuzzing的机器集群已经扩大到那种规模了,大概有4千台机器,他没提VMware。所以4千台机器上面还部署了多少VMware不知道,所以这个量是很庞大的。现在包括百度、腾讯和360的,有大量的机器在做这一块。这个截图就是火狐上面的,可以看到Bug List上面有多少应用Fuzzing这个程序报告的。这个是谷歌的Fuzzing,这个是我用的一个。就因为这10几台的VMware,在去年我跻身于微软漏洞挖掘100强里面,也就是10个。

前面讲了那么多主流的东西,其实我今天要讲的是非主流的,那种问题就来了,这种非预期输入一定非得随机化吗?异常输出就一定是Crash吗?因为前面所有的框架异常处理都是找这个Crash崩溃的信息,这个是内存的一种漏洞。或者我换一种提法,这个只适合于这种内存型漏洞的测试码?只有大规模的计算资源才能Fuzzing吗?这个可以和第一个问题可以配合来,当你手上没有多少资源的时候,你觉得走不下去了。我觉得不一定,我觉得有一点,不一定很复杂,这一点其实也是跟前面两点可以一起说的,你必须有大量的机器,大量的计算力,必须开发很牛的框架来做这个Fuzzing的测试,这个Fuzzing的测试只适合找一些内存型的漏洞。

我今天讲这个非主要的就是想告诉大家,Fuzzing虽然是一种漏洞挖掘Bug的方法,我更加认为它是一种思想,它可以适合于各种各样的场景,不一定非得你做一个内存型的漏洞挖掘。我要强调的就是你要有这种意识,当你在漏洞完全的时候,你要有这样一种方法,可能快速的定位找到漏洞。

我们从漏洞挖掘的方法论到到Fuzzing,我们经常用的一个方法论里面,首先我们一般对于一个漏洞挖掘者的学习经历来看一般都是这样的,首先是分析别人的漏洞,或者分析漏洞以后,我会总结这个漏洞有什么样的一个模型,我们能形成一个模型。然后我用这个模型去匹配和发现一些新的问题漏洞,在这个模型下面去找这个。其实这个东西你用的Fuzzing也是一样的,我把最后一步做到自动化,首先通过我自己的分析,这个漏洞是这个样的,原理是这个样子的,是不是在技术的点还会有这样的问题?我写一个程序,自动化的变了一遍,或者我去尝试,可能又发现是一样的问题。

这里面还是要纠结到那三步,就是输入数据的架构,其实这个东西有的时候就要根据不同的类型去做了。举一个很简单的例子,比如SQL注入的,有的时候你提交一个单引号或者是一个双引号,它就出错了,这就是异常信息。比如说XSS,提交一个能够弹框的,按一个1,弹一个1出来,说明这也是一种异常,已经执行了。所以我们要抓住这两点,就很好做一些事情。

这里面举了几个例子,第一个就是XSS的Fuzzing,在攻防里面有几个方向,第一个方向就是找新的策略,就是人家的那个防护策略他根本没考虑到这种方式能够执行,我要找的就是这个。还有一种方向就是说,我不跟你对抗,我绕过,利用你这个机制我提交两次,一次以后我还原了原来的,这是一种对抗。所以这里面有一个原型,当时做测试就是这一句,就是一个反斜杠的利用。当时有人提出来,有一个XS的点,它的空格被过滤了,可能是其他机制过滤了,他没办法插入这个,后来就发现这个反斜杠可以。我们就顺势思考,这就是一个漏洞模型了,我总结出来了,就是一个漏洞模型,这是反斜杠。我们就很自然而然的想,会不会有其他的字符串可以做到这个效果?写一个脚本很简单,整个下面是PHP,就是这么一个代码。

这个设计就是你怎么捕获异常,我的意思就是说,假如浏览器成功执行了1.PHP的话,解析了HPH的话,他会去访问,所以我记录了一个异常就行了,我当时测试有这么一些结果。我在测试的时候,做这个测试没多久就有一个老外也做了相同的工作,他做的比我全,前面那两个字符串我测过,没有什么效果。他做得更广,范围更大,把宽字节什么都考虑到了。这个报告可以看一下,他的设计和我的方法其实也相当于差不多。这个里面的点模型还有很多,比如我这个空格,因为里面那句话的模型有很多,只是一个空格。这个空格定了,还有另外一个空格,假如两者或者三者,或者各种各样组合起来,其实你Fuzzing的数据量还是很庞大的。后来有另外一个老外,他干脆就写了这么一个框架,你只要去在里面填充这个模板就行了,而且这个数据也是共享的,大家有兴趣的可以去学习参考一下。

下面我讲一个SQL注入的尝试。在这个里面其实异常很简单,前面反复提到了,提交一个逗号,或者说一个双引号就可以了。Oracle有一个存储过程的Fuzzing,这是我很早的一个研究。这个存储过程其实有非常大的意义,假如玩过Oracle的话,会经常利用它的漏洞,利用集成去注入,这就是一个典型的注入的代码程序。这个里面的关键点,异常数据很简单就是一个引号就行了,异常输出也很简单,就是他提示你的语法错误了,你抓到这个就行了。剩下你要做的,要想的是什么呢?你在里想思考的事,这个存储过程有,这个参数有,那么其他参数有没有?其他存储过程有没有?我们怎么想办法把所有的东西都变了一遍,答案是可以的。所以通过一些研究,第一步就通过Object ID,就得到一些可扩展的参数。得到这个参数以后,这些得到的函数名和过程名是一样的。这三步的目的都是为了得到存储过程的名字、过程ID和变量的名字,剩下的就是你调用它,就可以判断了。当时有一个朋友跟我写过一个程序,我们配合的,效果还是有的,后面没有去跑,而且自己后来方向变了,就没有专注那一块,慢慢放弃了,但是这个方式是OK的。

另外可以提一下比较有意思的一个案例,就是iis6下面有一个文件名解析的漏洞,虽然微软一直不承认这是一个漏洞,他认为是一个特性,但是这个确实给很多网站带来了困扰。就因为上传这么一个文件,导致被解析了,所以绕过了很多的程序过滤。当时这个问题的发现应该是乌云他们那个团队。他们当时给了一个公告,也没给我细节,我问过他们,他们还不告诉我。那么怎么办呢?我只好自己去想办法跑一下。其实这个设计很简单,也是按之前的我变了一下所有的字符。这里面的异常判断,直接CURL去访问一下,如果能够访问到那个被解析的代码说明是OK的。

我前面说的是一种思想,就是Fuzzing可以应用于很多的场景,这是在渗透测试中,其实我们也要很多用到的场景。比如说猪猪侠在某一年的乌云大会上讲到的一个议题,就是自动化攻击的这么一个现在和将来的议题,里面就提到了各种各样的组合方法,比如生日和排列组合,各种年月日、名字,加到这个字典里面去模糊测试。其实这就是一个很典型的Fuzzing,我还可以跟我另外一个朋友分享一下,是在他的渗透测试中,这个有点想法,就像我开篇讲的那个小孩一样的。他就是通过在某次渗透测试中,他发现他搞定了一个权限,但是是一个低权限的,他通过很多的提权工具都没有办法。他唯一做的是什么事呢?这个时候他就坐在电脑面前盲目的敲,就用SU的那个盲目的敲密码。他已经敲了大概有几个小时,他有点晕了,突然一抬头看,是一个井号了。问题是这个时候他不知道哪个密码是对的,这是一个真实的案例,是我朋友的一个案例。我举这个例子的意思就是说,你不要太局限于你的思维,你的思维要发散,向前看。

这里讲一个我提的比较多的,就是相似性的漏洞挖掘。相似性的漏洞挖掘有几条,其中有一条就是相似的业务必然带来相似的漏洞,这个大家可以去理解。还有一条也可以顺带说一下,同一个人开发的代码肯定有同一个问题。所以他开发的这个程序有漏洞了,他开发的另外一个程序肯定有同样的问题,放心,绝对有。所以你怎么去发现呢?大家知道我一直是漏洞之王,刷榜的,有一个技巧。我在2012年就报告了这么一个XSS给腾讯,当时他们很积极的修复了。当时因为漏洞足够多,我们要去想这个方法测试。2014年有一天实在无聊,我写这个程序有一个新的想法,我能不能实践一下?我就去做了。我要做的是什么呢?首先看一下效果,就报了这么多Bug。这个是怎么来的呢?其实很简单,我第一步就把qq.com的子域名全部爬一遍,暴力也好,越多的得到子域名就越OK。我把这些子域名变了一遍,这个里面涉及到异常判断,可能涉及到开发,比如你假如手工要贴到UI的话,这个就不能自动化,不能说是Fuzzing。我当时就想到一个解析的方法,这是一个命令行的版本,我能够解析这个确实执行了,相当于一个命令行的浏览器,判断这个值就行了。这个代码也很简单,就是把所有的子域名变了一遍就行了。这是我其中刷的一个漏洞,其实还有好多漏洞可以刷。所以有时候你总结一下,把所有你在乌云上看到的那些漏洞,把这些变量都保存一下,这个处罚的保存一下,把所有的子域都爬一遍,说不定你能够刷爆好几个SRC。

这里面主要说一下秘籍,这个Fuzzing首先要有这个意思,不止是一个漏洞挖掘的工具方法,它是一种思想,可能应用于各种各样的场景。你要看到这个漏洞原型的时候,或者你要想到这个东西。你看到这个漏洞的时候,你会想到是不是有相当多的问题我要跑一下?就是跑很重要。所以第二个秘籍,就是你要跑,Just do it。就是你有这个想法了,必须要去做。这一句话基本上是流传很广的,那个小伙问我怎么才能牛?我说你整就牛,你只要去做了,就会牛。下面还有一个真实的例子,我就可以告诉你为什么你只要做了,就真的有漏洞出来。

跨维思维,有的时候不要把你的思维太局限了,你要想的东西,这里主要是提了不要局限在你提取的那个漏洞模型里面,有可能这个漏洞模型里面还有其他的一些东西,我下面这个例子就可以说明这个问题。

首先看一下Bypass,这是乌云上有一个报了360的一个漏洞,当时他的漏洞其实很简单,其实绕过了白名单。因为当时细节没有出来,我当时看到这个点,我看到这个因为出在解析方法上面,取得的getHost跟原来的不一致,绕过了这个检测。后来我就想办法找到这个东西,其实这个细节已经给出来了,他就是提交这么一个URL,他通过这个getHost的取得,是取得了360.cn。他通过浏览器去访问这个URL的时候,其实他访问的是乌云。所以这个漏洞模型就来了,我把这个反斜杠作为我的Fuzzing点,我去跑一下,看看还有没有其他的出现。我当时设计了这么一个模型,其实这个异常捕获很简单,就是有没有访问到这个80服务器就行了。把完整的模型跑起来,没有任何发现,有可能就是局限了。

但是我们做深一层次的思考,不能够局限于目前这个漏洞模型,这是一个典型的标准不一致带来的安全问题,就是两个方法,两个东西在做判断的时候,在做对比的时候,它的标准是不同的。最基本的标准不同,你根本判断出来的结果是不靠谱的。这个例子里面其实是getHost取得的那个值,没有考虑反斜杠的问题。我们反过来想一想,在其他的场合是不是也有这样的东西呢?比如GS里面的域,当取得这个域值的时候,是不是也会出现同样的问题?剩下来就是重新做了。其实这个做起来很简单,这个当然是我最后从事的版本,前面我还做好几款设置,写一个APK,自动化的打开这个浏览器,那个时候是想多了,后来发现这是很简单的一个方法。这里面只是一部分,还有一个部分,这个其实很简单,就是用这个框架去调用访问这么一些网址,自动访问。然后我要捕获异常是一样的,我的同事写的,他就写了里面有一个判断,不管你请求什么,我都会执行这个命令,打印出当时的这个域。很简单,只要你访问成功了,这是第一步,我要看当前的域是不是这个结果,有没有绕过。这个我跑下来的结果,第一个在Android平台上面的QQ浏览器、微信,包括QQ,这些都存在UXSS,都跨域了。很简单,其实原理就是因为有两点,他在处理IP和域名组合的时候,一般默认的用这个点去分割了,到这儿直接分割了,他看到执行的效果就是这样,这个域其实是在QQ下面的。就相当于你可以控制qq.com一个不存在的子域,你可以通过跨子域的一些方法,实现你的攻击目的。这里攻击的方法不在今天议题的范畴之内,就不介绍了,这个是截图qq。

另外发现了Firefox平台下面的UXSS,很简单,这个值就是两个,一个是11,还有一个12,也是一样的效果。但是这个问题,其实当时我发现这个问题大概在好几个约制前就发现了,但是很可悲。我发现了就丢在那里没管了,有一天我再去测试没有了,怎么回事呢?我发现在论坛上面,我还找这个老外聊了一下,确实就是补的这个漏洞。我在这个例子里面就是说,第一个你要有跨域的想法,不要局限于现在这个漏洞模型,要发散思维,有没有其他点。然后你一定要去跑,一定要去做。你只要去做了,就可以发现新的问题。

今天我就讲到这儿,谢谢大家!

 

潘柱廷:大家有没有问题问一下黑哥?

 

提问:你现在通过这些方法,在实际的应用于SQL方面挖掘的漏洞,还有在二进制方面会有一些什么样的心得和体会?

 

周景平:其实很多关注我的人知道,黑哥以前是做Web安全的,突然之间来了一个微软的一百强里面的名单,报了很多浏览器的漏洞,这个里面其实主要是我身边大牛比较多,朋友比较多,他们对我进行了指导,确实给了我很大的帮助,包括百度的一些交流,让我受益匪浅。

另外一个我的优势在哪里呢?因为我就12个VM。我的优势在哪里呢?我的想法可能比别人多一点。就是很多时候我看到人家的样板,人家可能想到这个点测试就过了,我有可能就是在你的样本基础上,就类似于今天我提到这么一些方法。我发现有一些他们自己都没有意识到的点,我可能就做到了。后来我回顾了自己的整个职业技术生涯,我喜欢回顾一下自己。后来发现我的很多研究其实都是站在别人的基础上去完成的,这个可能是我的一个弱势,或者说也是我的一个强势。

 

潘柱廷:如果给你1200个VM,会不会和现在不一样?

 

周景平:我不太喜欢有压力。当有人给你投资源的时候,他是有要求的。当你没有资源的时候,你就觉得很牛。你看我就这么点条件,我都能做得这么好,是不是给你很多条件你就会做得更好了?那不一定,真不一定,有可能更失望,所以我宁愿保持现在这种状态。

 

潘柱廷:说到底还是计算密集型,黑哥更喜欢计算不密集型,他喜欢创意密集型。

 

周景平:我喜欢玩创意,比较猥琐一点,人也长得比较猥琐。

上一篇:盘古刘涛:使用Janus大规模挖掘滥用授权凭证的移动应用

下一篇:对话腾讯马斌 解读互联网+安全战略