导语:这篇文章的主要内容是关于我发现的在应用程序中挖掘漏洞的几个方法(是软件安全的漏洞,而不是错误配置或补丁管理导致的安全问题)。
这篇文章的主要内容是关于我发现的在应用程序中挖掘漏洞的几个方法(是软件安全的漏洞,而不是错误配置或补丁管理导致的安全问题)。我之所以写这篇博文,是因为这是我一开始就所希望做的事情。虽然这篇文章是针对初学者的,而且并不是新的知识,但我认为更有经验的分析师可能会把我所讲述的这几个方法与他们自己的挖洞方法进行比较,比如像Brian Chess和Jacob West,Gynvael Coldwind,Malware Unicorn,LiveOverflow以及更多。
请记住,这是一个正在进行中的工作。所以这不应该是一个全面的或者权威的做法,相反,这些方法可能受到我在一些方面的知识和经验的限制。
我把它分成了几个部分。我将首先回顾一下我认为是高层次的挖洞过程,然后讨论在寻找安全漏洞时我需要了解和执行的内容。最后,我将讨论一些其他的想法和非技术性的经验教训,这些经验教训在前面的章节中可能不太合适。
漏洞发现的过程是什么样的?
在某些方面,漏洞发现的过程可以比喻为解决迷宫,拼图或逻辑网格等难题。一种抽象地思考的方法是把这个过程看作一种特殊的迷宫,其中:
1. 你不能马上看到它的样子。 2. 它的地图是通过探索逐渐形成的。 3. 你有多个起点和终点,但是不确定它们到底在哪里。 4. 最终的地图几乎不会100%的清晰展示,但足以弄清楚如何从A点走到B点。
如果我们不那么抽象地思考的话,这个过程则可以归结为三个步骤:
1. 枚举入口点(即与应用程序交互的方式)。 2. 考虑对手想要表现出的不安全状态(即脆弱性)。 3. 使用已识别的入口点操作应用程序以达到不安全的状态。
在这个过程中,迷宫就是你正在研究的应用程序,地图是你对它的理解,起点是你的入口点,终点是你想要造成的不安全状态。
要找到入口点,你可以从UI中明显可以看到的那些可修改的参数到对最终用户(例如IPC)更模糊或透明的交互这些范围中找到。一些攻击者或安全研究人员更感兴趣的入口点类型如下:
· 随着时间的推移,代码的范围越来越大,并且没有随着时间的变化而变化(例如,遗留的遗留问题)。
· 划分团队或个人(例如互操作性)的开发工作的交集。
· 调试或测试代码,这些代码从开发分支中被带到生产中。
· 客户端调用的api与服务器公开的api之间存在差距。
· 不直接影响最终用户的内部请求(例如IPC和表单字段)。
我认为可能会遇到的漏洞类型可以分为两类:通用型和上下文型。一般的漏洞(如RCE、SQLi、XSS等)可以在许多应用程序中寻找到,而不需要知道它们的业务逻辑,而上下文的漏洞(例如未经授权的资产暴露/篡改)则需要了解更多的业务逻辑、信任级别和信任边界。
我的经验是优先考虑哪些事情会产生最大的影响(比如对攻击者的最高奖励,以及对应用程序的利益相关者的最大损害)。像 STRIDE这样的轻量级威胁模型也有助于找出可能出错的地方。我们来看一个Web应用程序示例,然后再看一个桌面应用程序示例。
假设这个web应用程序是一个用于金融门户的单页面应用程序(SPA),我们对它进行了身份验证,但是我们没有服务器端源代码或二进制文件。当我们列举入口点时,我们可以探索站点的不同特性,以了解它们的用途,看看我们的HTTP代理中有哪些请求,并为我们提供一些清晰的思路。我们还可以查看客户端的JavaScript,以获得SPA所调用的RESTful api的列表。没有服务器端代码的话,我们不能看到SPA所调用的api和由服务器公开的api之间的不同。
然后,我们可以对所标识的入口点进行操作,以达到我们正在寻找的不安全状态。当我们考虑要面对哪些漏洞时,我们应该构建一个适合应用程序技术堆栈和业务逻辑的测试用例列表。如果没有,我们就会浪费时间去尝试那些永远不会工作的测试用例(例如,当后台使用Postgres时,尝试使用xpcmdshell),而不去尝试那些需要对应用程序有更深入了解的测试用例(例如,在外汇请求的货币参数中寻找验证的过程)。
在桌面应用程序中,通过识别的入口点来处理漏洞的基本过程仍然适用,但是存在一些差异。可以说,web应用程序最大的不同之处是它需要一套不同的知识和方法体系来执行。OWASP的Top 10不会提供太多的帮助,将应用连接到一个HTTP代理来检查网络流量可能不会达到同样的效果。这是因为入口点在包含本地向量时变得更加多样化。
与黑盒测试相比,当你能够访问源代码时,需要猜测的东西就更少了。在寻找易受攻击的代码路径和开发有效载荷时,寻找切入点和猜测的可能性要小一些。你可以从一个易受攻击的接收器开始,向后延伸直到找到一个入口点,而不是通过一个可能导致或可能不会导致不安全状态的入口点发送有效载荷。在一个白盒的场景中,你会因为你所知道的局限性而受到限制。
需要什么知识?
漏洞研究所需的知识是广泛的,会随着时间的推移而变化,并且可以根据应用程序的类型而变化。然而,知识领域往往保持不变,可分为四类:
1. 应用技术。这体现了开发人员应该知道构建目标应用程序的技术,包括编程语言、系统内部、设计范例/模式、协议、框架/库等等。一个有经验的技术人员,通常会比那些有着肤浅的理解的人更有生产力和创新。
2. 攻击和防御概念。这些范围从基本安全原则到不断变化的漏洞类别和缓解措施。攻击和防御概念的结合可以指导研究人员在面临漏洞攻击时避免漏洞。对应用技术和防御概念的深刻理解可以给出非通用和可操作的修复建议。
3. 工具和方法。这是关于如何有效和高效地将概念付诸实践的一部分。这是通过花费时间学习如何使用工具和配置它们,优化重复性任务以及建立自己的工作流的经验。学习相关工具的工作方式,如何开发这些工具,以及如何针对不同用例重新使用它们,与知道如何使用它们同样重要。
面向过程的方法比面向工具的方法更有价值。当他们使用的工具已经达到限制时,研究人员不应该停止追求领先。我的方法论发展的大部分来自于读书和写作,实践操作,并从许多错误中进行学习。通过课程学习通常是一个很好的途径,可以从有经验的专家那里得到很多知识,但通常不能代替从实际操作中获得的经验。
4. 目标应用。最后,能够比开发人员和维护人员更好地理解应用程序的安全性方面是很重要的。这不仅仅是查看应用程序具有哪些安全性特性。还包括了解其使用情况的背景,列举所有入口点,并能够假设适合其业务逻辑和技术堆栈的漏洞。在下一节我会详细介绍我在这方面执行建立知识的经验。
下面的表格举例说明了在Web应用程序和Windows桌面应用程序中研究漏洞所需的知识。请记住,每个类别中的条目仅用于说明目的,并不意味着这是全部的内容。
花费了数千个小时,修改了数百个错误,历经无数个不眠之夜,我终于建立了这些知识领域。这些领域的组合和增长有助于增加发现漏洞的可能性。如果上述部分内容的特点是你需要知道什么,那么下一部分内容的特点是你需要知道怎么做。请看 Part.2的内容吧。