写在前面的话
在此之前,很多朋友都曾通过电子邮件在我直播的时候问过我有关漏洞挖掘方面的问题,而且很多时候不同的人问的都是相同的问题。因此,我决定写一篇文章来回答一下朋友们问得最多的问题,即如何去发现一个安全漏洞。不过我要声明的是,问题的答案也许并不具有权威性,因为这些都是我根据自己的经验、知识、以及我对事物的看法来回答的。如果你有任何新的观点或者看法的话,欢迎大家在文章下方积极留言,很多聪明的人对相同的问题也会有不同的见解。
问题:怎样发现漏洞?
首先,你可能已经发现了这个问题其实是一个“高度抽象的”的问题。因为漏洞挖掘不仅涉及到很多有趣的技术,而且更重要的是,你所讨论的漏洞指的是一般人在网络渗透测试过程中所要寻找的一个系统漏洞,还是说在一个应用程序、服务、驱动程序、内核模块、操作系统或固件中发现一个之前从未被人发现过的漏洞?对于我个人而言,与渗透测试相比我对漏洞研究更加的感兴趣,所以我在本文中将主要讨论后面这种情况。
就我个人的理论体系而言,主要有以下三种类型的漏洞挖掘方法:
1. 代码审查(有可能涉及到代码的逆向工程分析);
2. 黑盒测试(包括使用扫描器和模糊测试工具等软件);
3. 文档研究;
上面这三种方法都有其各自的前提条件以及相应的限制,并且还有各自的适用场景,因为没有什么方法是通用的,我们需要根据自己的目标来选择相应的测试方法。一般来说,我在对一个目标进行安全测试的时候都会同时使用上面这三种方法。
1. 代码审查
要求:
-熟悉常见的漏洞类型;
-熟悉逆向工程技术;
用处:
-能够找到十分复杂的安全漏洞;
限制:
-需要花费很多的时间和精力;
概述:
漏洞类型指的是一种安全漏洞所属的大类,它们都是安全从业人员耳熟能详的一些基本漏洞类型,例如基于栈的缓冲区溢出漏洞、反射型XSS漏洞或SQL注入漏洞。对于这些漏洞类型,目前不仅有已知的缓解方案,而且网上也有很多能够检测相应漏洞的模式、方法和工具。
某些情况下,一个安全漏洞是由多个问题共同产生的,例如整形溢出漏洞将有可能导致缓冲区溢出漏洞等等。不过也有很多漏洞并没有被归类,比如说你可能会在某些特定应用或技术中发现Bug,但这些Bug并没有被归为常见漏洞类别中。如果你想了解更多的漏洞类型,请参考下面这三份资料:
(a) Common Weakness Enumeration (MITRE)
(b) AdversarialTactics, Techniques & Common Knowledge (MITRE)
(c) OWASPPeriodic Table of Vulnerabilities
在这种方法中,我们需要对代码进行分析,然后尝试识别出代码中存在的逻辑错误并对漏洞进行分类。但是这种方法对研究人员的基本素质要求非常高,因为如果你无法了解代码的具体功能(代码审查只是一带而过),或者说你对常见的安全漏洞都不够了解的话,那么你就无法发现其中的漏洞了。
除此之外,这种方法并不适用于大规模的项目。因为项目越小,我们就越容易对目标进行完整的代码审查。但是项目非常大的话,我们就只能对其中的关键部分或者比较有意思的部分进行代码审查了。
2. 黑盒测试
要求:
-熟悉常见的漏洞类型;
-【自动化黑盒测试】了解黑盒测试工具的运行机制以及使用和配置方法;
用处:
-【自动化黑盒测试】测试规模和范围非常大;
-【手动黑盒测试】如果你触发了一个漏洞,那么你就找到了一个漏洞,这种场景下的假阳性会比较低;
限制:
-【自动化黑盒测试】扫描器/模糊测试器都是非常好的工具,而且也有很多现成的工具可以使用,但是很多复杂的漏洞它们是发现不了的;
-【手动黑盒测试】这种方法比代码审计要节省时间,但是测试规模和范围会受到限制。除此之外,测试效果还会受到研究人员的经验以及想象力的限制;
概述:
这是一种在不考虑代码本身的情况下寻找程序漏洞的方法,它最主要是侧重于跟应用程序的交互方面。在这种方法中,我们需要从程序的用户接口/界面发动攻击,并观察该程序的响应情况,而无需分析应用程序的内部结构或代码。而手动黑盒测试一般是我在拿到一个待测Web应用时最先采用的测试方法,因为这种方法可以帮助我迅速对测试目标的整体情况有一个大概的认识。
自动化黑盒测试的测试规模和范围一般来说都比较合适。一般来说,我们在进行其他测试方法(例如手动测试)的过程中,我们可以设置一个模糊测试器/扫描器并让它们在后台自动进行漏洞扫描。不过在漏洞报告生成之后,别忘了对扫描结果进行检查和分析以避免假阳性或漏洞重复率过高,不过具体情况还得取决于你所使用的技术和工具。
3. 文档研究
要求:
-熟悉常见的漏洞类型;
-曾经当过程序员,或者了解程序员得思维方式;
用处:
-有可能在同一个目标中发现多个相同的安全漏洞;
限制:
-测试效果会受到研究人员的经验以及想象力的限制;
-往往针对的是系统中的单个协议、格式或某个部分;
概述:
在这种方法中,我们需要通过浏览待测目标的文档、规范或引用手册来定位某些编程实现方面的错误。与代码审计和黑盒测试不同的是,这种方法一开始并不需要与待测目标进行交互。
在某些情况下,我们甚至还可以通过自动化的方式完成文档的浏览,具体详见【参考资料1】【参考资料2】
总结
对于新手而言,我建议大家先从你最感兴趣的漏洞下手,了解与这个漏洞类型相关的技术以及工具,然后通过本文介绍的方法来尝试寻找一下这种漏洞。一开始你可能会花很多时间却收获甚少,不过别担心,哪怕是最顶尖的安全研究专家也有可能努力了好几个月也一无所获,你可别指望只花几个小时就找到一个惊世骇俗的安全漏洞。