解析应用程序

攻击应用程序的第一步是收集和分析与其有关的一些关键信息,以清楚了解攻击目标。解析过程首先是枚举应用程序的内容与功能,从而了解应用程序的实际功能与运行机制。我们可轻松确定应用程序的大部分功能,但其中一些功能并不明显,需要进行猜测和凭借一定的运气才能查明。

列出应用程序的功能后,接下来的首要任务就是仔细分析应用程序运行机制的每一个方面、核心安全机制及其(在客户端和服务器上)使用的技术。这样就可以确定应用程序暴露的主要受攻击面并因此确定随后探查过程的主要目标,进而发现可供利用的漏洞。我们在本章后面部分将讲到,通常在分析过程中就可以发现相关漏洞。

随着应用程序变得越来越复杂,功能越来越强大,有效的解析将成为一种重要技能。经验丰富的专家能够迅速对所有功能区域进行分类,参照各种实例查找不同类型的漏洞,同时花费大量时间测试其他特定区域,以确定高风险的问题。

本章将描述应用程序解析过程的主要步骤、各种可用来提高效率的技巧与窍门,以及一些帮助进行解析的工具。

枚举内容与功能

通常,手动浏览即可确定应用程序的绝大部分内容与功能。浏览应用程序的基本方法是从主初始页面开始,然后是每一个链接和所有多阶段功能(如用户注册或密码重设置)。如果应用程序有一个“站点地图”,可以从它开始枚举内容。

但是,为了仔细检查枚举的内容,全面记录每一项确定的功能,我们有必要使用一些更加先进的技术,而不仅仅是简单浏览。

Web抓取

我们可使用各种工具自动抓取Web站点的内容。这些工具首先请求一个Web页面,对其进行分析,查找连接到其他内容的链接,然后请求这些内容,再继续进行这个循环,直到找不到新的内容为止。

基于这一基本功能,Web应用程序爬虫(spider)以同样的方式分析HTML表单,并使用各种预先设定值或随机值将这些表单返回给应用程序,以扩大搜索范围、浏览多阶段功能、进行基于表单的导航(如什么地方使用下拉列表作为内容菜单)。一些工具还对客户端JavaScript进行某种形式的分析,以提取指向其他内容的URL。有各种免费工具可以详细枚举应用程序的内容与功能,它们包括Burp Suite、WebScarab、Zed Attack Proxy和CAT(请参阅第20章了解详情)。

 提示 许多Web服务器的Web根目录下有一个名为robots.txt的文件,其中列出了站点不希望Web爬虫访问或搜索引擎列入索引的URL。有时,这个文件中还包含敏感功能的参考信息,渗透测试员肯定会对抓取这些信息感兴趣。一些攻击Web应用程序的抓取工具会搜索robots.txt文件,并根据其中列出的URL开始抓取过程。在这种情况下,robots.txt文件可能会危及Web应用程序的安全。

在本章中,我们将以一个虚构的应用程序Extreme Internet Shopping(EIS)为例,说明常见的应用程序解析操作。使用Burp Spider解析EIS的过程如图4-1所示。不需要登录,即可以解析出/shop目录及/media目录中的两件新商品。还要注意的是,图中显示的robots.txt文件引用了/mdsecportal和/site-old目录。这两个目录没有链接到应用程序中的任何位置,Web爬虫仅仅通过访问公开内容中的链接不可能发现这些目录。

图4-1 使用BurpSpider解析应用程序的部分内容

 提示 采用REST风格的URL的应用程序使用部分URL文件路径来唯一标识应用程序所使用的数据和其他资源(请参阅第3章了解详情)。在这些情况下,传统Web爬虫的基于URL的应用程序视图非常有用。在EIS应用程序中,/shop和/pub路径采用了REST风格的URL,抓取这些区域即可轻松获取这些路径中的商品的唯一链接。

尽管通常能够进行有效的抓取,但这种完全自动化的方法在内容枚举方面还存在一些重要的限制。

这些工具一般无法正确处理不常用的导航机制(如使用复杂的JavaScript代码动态建立和处理的菜单),因此可能会遗漏应用程序某个方面的功能。

爬虫可能无法抓取到隐藏在编译客户端对象(如Flash和Java applet)中的链接。

多阶段功能往往会严格地执行输入确认检查,因而可能不会接受由自动工具提交的值。例如,用户注册表单中可能包含姓名、电子邮件地址、电话号码和邮政编码字段。自动应用程序爬虫通常会向每一个可编辑的表单字段提交一个单独的测试字符串,而应用程序将返回一条错误消息,称其提交的一个或几个数据无效。由于爬虫并没有能力理解这种错误消息并采取相应行动,所以也就无法成功通过注册,因此无法发现这以后的任何其他内容或功能。

自动化爬虫通常使用URL作为内容标识符。为避免进行连续不确定的抓取,如果爬虫认识到链接内容已被请求,它们会识别出来并且不会再向其发出请求。但是,许多应用程序使用基于表单的导航机制,其中相同的URL可能返回截然不同的内容和功能。例如,一个银行应用程序可能通过一个指向/account.jsp的POST请求执行每一项用户操作,并使用参数传达执行的操作。如果爬虫拒绝向这个URL提交多次请求,它就会遗漏应用程序的大部分功能。一些应用程序爬虫试图解决这一问题(例如,可对Brup Spider进行配置,使其根据参数名称和参数值对提交的表单进行“个性化”处理)。但是,在许多情况下,这种完全自动化的方法并非绝对有效。本章后面我们会讨论解析这一功能的方法。

与前面的情形恰恰相反,一些应用程序在URL中插入实际上并不用于确定资源或功能的可变数据(例如,包含定时器或随机数种子的参数)。应用程序的每个页面中都可能包含一组似乎是爬虫必须请求的新URL,导致它不断进行不确定的抓取。

如果应用程序使用身份验证机制,应用程序爬虫要实现有效抓取,必须能够处理这种机制才能访问它所保护的功能。如果为其手动配置一个通过验证的会话令牌或提交给登录功能的证书,前面提到的爬虫就能实现有效抓取。然而,即使获得令牌或证书,由于各种原因,爬虫执行的一些操作也会让通过验证的会话中断。

由于访问所有URL,爬虫会在某个时候请求退出功能,致使会话中断。

如果爬虫向某个敏感功能提交无效输入,应用程序可能会进行自我防御,终止会话。

如果应用程序在每个页面都使用令牌,爬虫肯定无法按正确的顺序请求页面,这可能引起应用程序结束整个会话。

 警告 在一些应用程序中,即使运行一个解析并请求链接的简单Web爬虫也可能极其危险。例如,应用程序可能具有删除用户、关闭数据库、重启服务器等管理功能。如果使用应用程序感知的爬虫,该爬虫发现并使用敏感功能,就可能造成巨大损失。我们曾经遇到一个应用程序具有某种内容管理系统(CMS)功能,它可编辑主应用程序的实际内容。这项功能可通过站点地图发现,并且没有受到任何访问控制的保护。如果针对这个站点运行自动化爬虫,它就会发现编辑功能并开始发送任意数据,致使主Web站点的内容在爬虫运行时就被扭曲。

用户指定的抓取

这是一种更加复杂且可控制的技巧,它比自动化抓取更加先进。用户使用它通过标准浏览器以常规方式浏览应用程序,试图枚举应用程序的所有功能。之后,生成的流量穿过一个组合拦截代理服务器与爬虫的工具,监控所有请求和响应。该工具绘制应用程序地图、集中由浏览器访问的所有URL,并且像一个正常的应用程序感知爬虫那样分析应用程序的响应,同时用它发现的内容与功能更新站点地图。Burp Suite和WebScarab中的爬虫即可用于这种用途(请参阅第20章了解详细信息)。

相比于基本的抓取方法,该技巧具有诸多优点。

如果应用程序使用不常用或复杂的导航机制,用户能够以常规方式使用浏览器来遵循这些机制。用户访问的任何功能和内容将由代理服务器/爬虫工具处理。

用户控制提交到应用程序的所有数据,这样可确保满足数据确认要求。

用户能够以常规方式登录应用程序,确保通过验证的会话在整个解析过程中保持活动状态。如果所执行的任何操作导致会话终止,用户可重新登录并继续浏览。

由于该技巧可从应用程序的响应中解析出链接,因而它能够完整枚举任何危险功能(如deleteUser.jsp),并能将其合并到站点地图中。但是用户可以根据自己的判断决定请求或执行哪些功能。

在Extreme Internet Shopping站点中,以前爬虫无法为/home中的任何内容建立索引,因为这些内容已通过验证。针对/home的请求将导致以下响应:

通过用户指导的抓取,用户可以直接使用浏览器登录应用程序,随后代理服务器/爬虫工具将提取生成的会话,并确定现在对用户可用的所有其他内容。用户成功通过应用程序受保护区域的验证时的EIS站点地图如图4-2所示。

图4-2 执行用户指导的抓取后Burp显示的站点地图

这揭示了主菜单系统中的其他一些资源。该图显示了一个对私有用户资料的引用,此用户资料通过onClick事件处理程序启动的JavaScript函数访问:

由于传统的Web爬虫仅仅抓取HTML中的链接,因此可能会遗漏这种类型的链接。即使是最先进的自动化应用程序爬虫,仍然无法抓取当前应用程序和浏览器扩展所采用的各种导航机制。但是,通过用户指导的抓取,用户只需使用浏览器访问屏幕上可见的链接,代理服务器/爬虫工具就会将生成的内容添加到站点地图中。

相反,值得注意的是,爬虫已成功确定HTML注释中包含的指向/core/sitestats的链接,即使该链接并未在屏幕上向用户显示。

 提示 除上面描述的代理服务器/爬虫工具外,在应用程序解析过程中,我们还经常使用一些其他工具,如可从浏览器界面执行HTTP和HTML分析的各种浏览器扩展工具。例如,图4-3所示的IEWatch工具可在Microsoft Internet Explorer中运行,对所有请求和响应(包括消息头、请求参数与cookie)进行监控,并分析每一个应用程序页面,以显示链接、脚本、表单和厚客户端组件。虽然可以在拦截代理服务器中查看所有这些信息,但是,拥有另一份解析数据有助于更好地了解应用程序,并枚举它的所有功能。请参阅第20章了解有关这种工具的详细信息。

图4-3 IEWatch在浏览器中进行HTTP和HTML分析

渗透测试步骤

(1)配置浏览器,使用Burp或WebScarab作为本地代理服务器(如果不确定,请参阅第20章了解相关信息)。

(2)以常规方式浏览整个应用程序,访问发现的每一个链接/URL,提交每一个表单并执行全部多阶段功能。尝试在JavaScript激活与禁用、cookie激活与禁用的情况下进行浏览。许多应用程序能够处理各种浏览器配置,可以获取应用程序内的不同内容和代码路径。

(3)检查由代理服务器/爬虫工具生成的站点地图,确定手动浏览时没有发现的所有应用程序内容或功能。确定爬虫如何枚举每一项内容,例如,在Burp Spider中,检查“链接自”(Linked From)的详细内容。通过浏览器访问这些内容,以使代理服务器/爬虫工具检查服务器响应,从而确定其他所有内容。继续递归执行上述步骤,直到无法再确定其他内容或功能。

(4)另外,还可以要求工具以已经枚举的所有内容为基础,主动抓取站点内容。首先,请确定任何危险的或可能会中断应用程序会话的URL,并配置爬虫,将它们排除在抓取范围之外。运行爬虫并检查它发现的结果以查找其他所有内容。

在代理服务器/爬虫工具生成的站点地图中包含大量关于目标应用程序的信息,稍后可以利用它们确定应用程序暴露的各种受攻击面。

发现隐藏的内容

应用程序常常包含没有直接链接或无法通过可见的主要内容访问的内容和功能。在使用后没有删除测试或调试功能就是一个常见的示例。

另一个例子是,应用程序为不同类型的用户(如匿名用户、通过验证的常规用户和管理员)提供不同的功能。在某种权限下对应用程序进行彻底抓取的用户会遗漏拥有另一种权限的用户可使用的功能。发现相关功能的攻击者可利用这些功能提升其在应用程序中的权限。

还存在许多前面描述的解析技巧无法确定的重要内容和功能,如下所示。

备份文件。如果使用动态页面,它们的文件扩展名可能已变成不可执行文件扩展名,可通过审查页面源代码查找可在主页中加以利用的漏洞。

包含Web根目录下(或根目录外)完整文件快照的备份档案,可以使用它迅速确定应用程序的所有内容与功能。

部署在服务器上、用于测试目的但尚未在主应用程序中建立链接的新功能。

定制应用程序中的默认应用程序功能对用户不可见,但在服务器端仍然可见。

尚未从服务器中删除的旧版本文件。如果使用动态页面,这些文件中可能包含当前版本已经修复、但仍然可以在旧版本中加以利用的漏洞。

配置和包含敏感数据(如数据库证书)的文件。

编译现有应用程序功能的源文件。

极端情况下,源代码中可能包含用户名和密码等信息,但更可能提供有关应用程序状态的信息。如果某个位置出现“测试此功能”(test this function)或类似的关键短语,应立即从此处开始探查漏洞。

包含有效用户名、会话令牌、被访问的URL以及所执行操作等敏感信息的日志文件。

发现隐藏的内容需要组合使用自动和手动技巧,而且往往需要一定的运气。

蛮力技巧

第14章将介绍攻击者如何利用自动技巧提高攻击应用程序的效率。现在可以利用自动技巧向Web服务器提出大量请求,尝试猜测隐藏功能的名称或标识符。

例如,假设用户指定的抓取已经确定有以下应用程序内容:

首先,试图确定隐藏内容的自动化工具将提出下列请求,以定位其他目录:

Burp Intruder可用于循环访问一组常见的目录名称并收集服务器的响应信息,可通过检查这些信息来确定有效的目录。图4-4表示正在配置Burp Intruder探查Web根目录中的常见目录。

图4-4 配置Burp Intruder探查常见目录

执行攻击后,单击status和length等标题栏会对其中的结果进行相应分类,有助于迅速发现异常,如图4-5所示。

图4-5 Burp Intruder显示目录蛮力攻击结果

对目录和子目录进行蛮力攻击后,就可以查找应用程序中的其他页面。这时,/auth目录特别有用,其中包含在抓取过程中确定的登录资源,对未通过验证的攻击者而言,这可能是一个不错的起点。同样,攻击者可以请求该目录中的一系列文件:

此攻击的结果如图4-6所示,它确定了/auth目录中的一些资源:

图4-6 Burp Intruder显示文件蛮力攻击结果

值得注意的是,针对Profile的请求返回了HTTP状态码302。这表示如果未经验证访问此链接,用户将被重定向到登录页面。此外,虽然Login页面已在抓取过程中被发现,但Register页面尚未被发现。这可能说明此功能可以运行,攻击者能够在该站点上注册一个用户账户。

 注解 不要想当然地认为:如果被请求的资源存在,应用程序将返回200 OK响应,否则将返回404 Not Found响应。许多应用程序以自定义的方式处理访问不存在资源的请求,通常返回一个带200响应码的预定义错误消息。而且,一些访问现存资源的请求可能会收到非200响应。下面简要说明在使用蛮力技巧查找隐藏内容时可能遇到的响应码的含义。

302 Found。如果重定向指向一个登录页面,那么只有通过验证的用户才能够访问该资源;如果指向一个错误消息,就可能披露其他不同的原因;如果指向另一个位置,重定向可能属于应用程序特定逻辑的一部分,应深入分析。

400 Bad Request。应用程序可能对URL中的目录和文件名使用定制的命名方案,但特殊的请求并不遵循该方案。然而,出现这种情况很可能是因为使用的词汇中包含一些空白符或其他无效的语法。

401 Unauthorized或403 Forbidden。该响应通常表示被请求的资源存在,但不管用户的验证状态或权限等级如何,禁止任何用户访问该资源。请求目录时往往会返回此响应,可以据此推断所请求的目录确实存在。

500 Internal Server Error。在查找内容的过程中,该响应通常表示应用程序希望在请求资源时提交某些参数。

由于各种可能的响应都可表示存在某些重要内容,因而很难编写出一段完全自动化的脚本来输出一组有效资源。最佳方法是在使用蛮力技巧时尽可能多地收集与应用程序有关的信息,并对其进行手动检查。

渗透测试步骤

(1)手动提出一些访问有效与无效资源的请求,并确定服务器如何处理无效资源。

(2)使用用户指定的抓取生成的站点地图作为自动查找隐藏内容的基础。

(3)自动提出访问应用程序内已知存在的每个目录或路径中常用文件名和目录的请求。使用Burp Intruder或一段定制脚本,结合常用文件名和目录词汇表,迅速生成大量请求。如果已经确定应用程序处理访问无效资源请求的特定方式(如自定义的file not found页面),应配置Intruder或脚本突出显示这些结果,以便将其忽略。

(4)收集从服务器收到的响应,并手动检查这些响应以确定有效的资源。

(5)反复执行这个过程,直到发现新内容。

通过公布的内容进行推测

许多应用程序对其内容与功能使用某种命名方案。通过应用程序中已经存在的资源进行推断,可以调整自动枚举操作,提高发现其他隐藏内容的可能性。

请注意,在EIS应用程序中,/auth中的所有资源均以大写字母开头,这就是上一节的文件蛮力攻击中使用的单词表有意大写的原因。而且,既然我们已在/auth目录中确定了一个名为ForgotPassword的页面,我们就可以在其中搜索其他名称类似的项目,例如:

http://eis/auth/ResetPassword

此外,在用户指导的抓取过程中创建的站点地图确定了以下资源:

http://eis/pub/media/100

http://eis/pub/media/117

http://eis/pub/user/11

其他类似范围的数值可用于确定其他资源和信息。

 提示 Burp Intruder高度可定制化,并且可用于针对HTTP请求的任何部分。图4-7显示了如何使用Burp Intruder对前半部分文件名实施蛮力攻击,以提出下列请求:

图4-7 使用Burp Intruder对部分文件名实施定制蛮力攻击

渗透测试步骤

(1)检查用户指定的浏览与基本蛮力测试获得的结果。编译枚举出的所有子目录名称、文件词干和文件扩展名列表。

(2)检查这些列表,确定应用程序使用的所有命名方案。例如,如果有些页面的名称为AddDocument.jsp和ViewDocument.jsp,那么可能还有叫做EditDocument.jsp和RemoveDocument.jsp的页面。通常,只需要查看几个示例,就能推测出开发者的命名习惯。根据其个人风格,开发者可能采用各种命名方法,如冗长式(AddANewUser.asp)、简洁式(AddUser.asp)、使用缩写式(AddUsr.asp)或更加模糊的命名方式(AddU.asp)。了解开发者使用的命名方式有助于猜测出尚未确定的内容的准确名称。

(3)有时候,不同内容的命名方案使用数字和日期作为标识符,通过它们可轻易推测出隐藏的内容。静态内容(而非动态脚本)常常采用这种命名方式。例如,如果一家公司的Web站点含有AnnualReport2009.pdf和AnnualReport2010.pdf这两个文件的链接,应该可以立即确定接下来的报告名称。令人难以置信的是,一些公司在公布金融结果之前,常常会将包含金融信息的文件放在Web服务器上,有些精明的新闻记者往往能够根据其在前些年使用的命名方案,发现这些文件。

(4)检查所有客户端代码,如HTTP和JavaScript,确定任何与隐藏服务器端内容有关的线索。这些代码包括与受保护或没有建立链接功能有关的HTML注释以及包含禁用SUBMIT元素的HTML表单等。通常,注释由生成Web内容的软件自动生成,或者由应用程序运行的平台生成。参考服务器端包含文件之类的内容也特别有用。这些文件可被公众下载,并且可能包含高度敏感的信息(如数据库连接字符串和密码)。另外,开发者的注释中可能包含各种有用的信息,如数据库名称、后端组件引用、SQL查询字符串等。厚客户端组件(如Java applet和ActiveX控件)也可能包含可供利用的敏感数据。请参阅第15章了解应用程序揭示自身信息的其他方式。

(5)把已经枚举出的内容添加到其他根据这些列表项推测出来的名称中,并将文件扩展名列表添加到txt、bak、src、inc和old这些常用扩展名中,它们也许能够披露现有页面备份版本的来源以及与所使用的开发语言有关的扩展名,如.Java和.cs;这些扩展名可能揭示已经被编译到现有页面的来源文件(请参阅本章后面的提示,了解如何确定所使用的技术)。

(6)搜索开发者工具和文件编辑器不经意建立的临时文件。例如.DS_Store文件,其中包含一个OS X目录索引,或者file.php~1,它是编辑file.php时临时创建的文件,或者大量软件工具使用的.tmp文件。

(7)进一步执行自动操作,结合目录、文件词干和文件扩展名列表请求大量潜在的资源。例如,在特定的目录中,请求每个文件词干和每个文件扩展名;或者请求每个目录名作为已知目录的子目录。

(8)如果确定应用程序使用一种统一的命名方案,考虑在此基础上执行更有针对性的蛮力测试。例如,如果已知AddDocument.jsp和ViewDocument.jsp存在,就可以建立一个操作列表(编辑、删除、新建等)并请求XxxDocument.jsp。此外,还可以建立项目类型(用户、账户、文件等)并请求AddXxx.jsp。

(9)以新枚举的内容和模式作为深入用户指定抓取操作的基础,反复执行上述每一个步骤,继续执行自动内容查找。所采取的操作只受到想象力、可用时间以及在所针对的应用程序中发现隐藏内容的重要性的限制。

 注解 使用Burp Intruder Pro的“内容查找”(Content Discovery)功能可以自动完成我们迄今为止介绍的大多数任务。在使用浏览器手动解析应用程序的可见内容后,可以选择Burp站点地图的一个或多个分支,并对这些分支启动内容查找会话。在尝试查找新内容时,Burp使用以下技巧:

使用内置的常用文件名和目录名列表实施蛮力攻击;

基于在目标应用程序中观察到的资源名称动态生成单词表;

推断包含数字和日期的资源名称;

基于已确定的资源测试其他文件扩展名;

从查找到的内容中进行抓取;

自动识别有效或无效响应,以减少错误警报。

所有操作均以递归方式执行,在发现新的应用程序内容后,将安排新的查找任务。图4-8显示了一个正在进行的针对EIS应用程序的内容查找会话。

图4-8 一个正在进行的针对EIS应用程序的内容查找会话

 提示 在执行自动内容查找任务时,OWASP发起的DirBuster项目也是一个有用的资源,其中包含大量以出现频率排序的、在现实世界的应用程序中发现的目录名列表。

利用公共信息

应用程序的一些内容与功能现在可能并没有与主要内容建立链接,但过去曾经存在链接。在这种情况下,各种历史记录中可能仍然保存隐藏内容的引用。我们可以利用两类主要的公共资源查找隐藏的内容。

搜索引擎,如Google。这些搜索引擎中保存有其使用的强大爬虫所发现的所有内容的详细目录,并且将这些内容保存在缓存中,即使原始内容已被删除,缓存中的内容仍然不变。

Web档案,如www.archive.org上的WayBack Machine。这些档案保存大量Web站点的历史记录。许多时候允许用户浏览某个站点从几年前到现在于不同时期彻底复制的站点快照。

除过去已经链接的内容外,这些资源中还可能包含第三方站点,而非目标应用程序本身链接内容的引用。例如,一些应用程序中包含仅可由其商业合作伙伴使用的限制性功能。这些合作伙伴可能会以应用程序无法预料的方式披露上述功能。

渗透测试步骤

(1)使用几种不同的搜索引擎和Web档案查找它们编入索引或保存的关于所攻击的应用程序的内容。

(2)查询搜索引擎时,可以使用各种高级技巧提高搜索效率。以下建议适用于Google(可以在其他引擎中选择“高级搜索”找到对应的查询)。

site:www.wahh-target.com。它将返回Google引用的每一个目标站点资源。

site:www.wahh-target.com login。它将返回所有包含login表达式的页面。在大型而复杂的应用程序中,这个技巧可用于迅速定位感兴趣的资源,如站点地图、密码重设功能、管理菜单等。

link:www.wahh-target.com。它将返回其他Web站点和应用程序中所有包含目标站点链接的页面。其中包括过去内容的链接或仅第三方可用的功能,如合作伙伴链接。

related:www.wahh-target.com。它将返回与目标站点“相似”的页面,因此可能包含大量无关的资料。但是,其中也可能包含在其他站点与目标有关的讨论,它们可能会有帮助。

(3)每次搜索时,不仅在Google的默认Web部分进行搜索,还要搜索“群组”和“新闻”部分,它们可能会提供不同的结果。

(4)浏览到某个查询搜索结果的最后一个页面,并选择“将省略的结果纳入搜索范围后再重新搜索”。默认情况下,Google会删除结果中它认为与其他页面非常相似的页面,过滤冗长的结果。撤销这一行为能够发现稍有不同的页面,它们也许有助于攻击目标应用程序。

(5)查看感兴趣页面的缓存版本,包括任何不再在应用程序中出现的内容。某些情况下,搜索引擎缓存中可能包含如果未通过身份验证或付费就无法直接访问的资源。

(6)在属于相同组织的其他域名上执行相同的查询,这些域名中可能包含与所攻击的应用程序有关的有用信息。

如果搜索结果发现主应用程序中不再存有链接的陈旧内容和功能,它们可能仍然有用。陈旧功能中可能包含应用程序其他地方并不存在的漏洞。

即使陈旧内容已经从现有应用程序中删除,但是从搜索引擎缓存或Web档案中发现的相关信息仍然可能包含与应用程序现有功能有关的引用或线索,它们可能有助于攻击者向其实施攻击。

开发人员和其他人在因特网论坛上发表的帖子是提供目标应用程序有用信息的另一个公共来源。因特网上有大量软件设计人员和程序员在其中询问和回答技术问题的论坛。发表在这些论坛上的帖子通常包含与应用程序有关的信息,攻击者可直接对其加以利用。这些信息包括应用程序使用的技术、执行的功能、在开发过程中遇到的问题、已知的安全缺陷、向其提交以帮助解决疑难的配置与日志文件,甚至是源代码摘录。

渗透测试步骤

(1)列出所发现的与目标应用程序及其开发有关的每一个姓名和电子邮件地址,其中应包括所有已知的开发者、在HTML源代码中发现的姓名、在公司主要Web站点联系信息部分发现的姓名以及应用程序本身披露的所有姓名(如管理职员)。

(2)使用上文描述的搜索技巧,搜索发现的每一个姓名,查找他们在因特网论坛上发表的所有问题和答案。分析发现的所有信息,了解与目标应用程序功能或漏洞有关的线索。

利用Web服务器

Web服务器层面存在的漏洞有助于攻击者发现Web应用程序中并未建立链接的内容与功能。例如,Web服务器软件中存在大量的程序缺陷,允许攻击者枚举目录的内容,或者获取服务器可执行的动态页面的原始来源(请参阅第18章了解这些漏洞的一些实例以及确定漏洞的方法)。如果应用程序中存在上述程序缺陷,攻击者就可以利用它直接获得应用程序的所有页面和其他资源。

许多Web服务器上默认包含有助于攻击者对其实施攻击的内容。例如,样本和诊断性脚本中可能包含已知的漏洞,或者可被用于某些恶意用途的功能。而且,许多Web应用程序整合了常用的第三方组件,执行各种常规功能,如购物车、论坛或内容管理系统(CMS)功能。这些功能通常安装在与Web根目录或应用程序的起始目录相关的固定位置。

本质上,自动化工具非常适用于执行上述任务,许多自动化工具可向一系列已知的默认Web服务器内容、第三方应用程序组件和常用目录名称发布请求。虽然这些工具无法准确查明任何隐藏的预定义功能,但使用它们往往有助于查找其他应用程序没有建立链接以及有利于实施攻击的资源。

Wikto就是许多能够执行上述扫描的免费工具中的一个,其中还包含一个可配置的蛮力攻击内容列表。如图4-9所示,针对Extreme Internet Shopping站点进行扫描时,它可以使用自己的内部单词表确定一些目录。由于其中包含一个常用Web应用程序软件和脚本的大型数据库,因此,它还能确定以下目录,而攻击者通过自动或用户驱动的抓取却找不到这些目录:

图4-9 将Wikto用于查找内容和某些已知的漏洞

http://eis/phpmyadmin/

此外,虽然/gb目录已通过抓取得以确定,但Wikto确定了以下URL:

/gb/index.php?login=true

Wikto检查该URL,是因为gbook PHP应用程序使用该URL,而前者包含一个广为人知的漏洞。

 警告 和许多商业Web扫描器一样,Nikto和Wikto之类的工具包含大量默认文件和目录列表,因此似乎能够很好地完成大量检查任务。但是,这些检查大部分都是多余的,错误警报也经常发生。更糟糕的是,如果将服务器配置为隐藏旗标、将脚本或脚本集合移至其他目录、或以自定义的方式处理HTTP状态码,还经常会出现漏报。为此,通常最好是使用Burp Intruder等工具,因为这类工具可以解译原始的响应信息,并且不会误报或漏报问题。

渗透测试步骤

运行Nikto时可以参考以下几点。

(1)如果认为服务器将Nikto检查的内容保存在一个非标准位置(如/cgi/cgi-bin而非/cgi-bin),可以使用-root/cgi/选项指定这个位置。在使用CGI目录的特殊情况下,还可通过-Cgidirs选项指定保存位置。

(2)如果站点使用不返回HTTP404状态码的file not found定制页面,可以指定一个特殊字符串,使用-404选项标识这个页面。

(3)注意,Nikto并不对潜在的问题执行任何智能核实。因此,它往往会做出错误诊断。请手动核实由Nikto返回的任何结果。

需要注意,在使用Nikto之类的工具时,可以使用域名或IP地址来指定目标应用程序。如果某工具使用IP地址来访问一个页面,则此工具会将该页面上使用域名的链接视为属于不同的域,因而不会访问这些链接。这样做是有道理的,因为一些应用程序属于虚拟托管应用程序,有多个域名共享同一个IP地址。因此,在配置相关工具时,请记住上述事实。

应用程序页面与功能路径

迄今为止,我们讨论的枚举技巧实际上由如何概念化和分类Web应用程序内容这种特殊的动机暗中推动。这种动机源自于Web应用程序出现之前的万维网时代,当时的Web服务器是静态信息仓库,人们使用实际为文件名的URL获取这类信息。要公布Web内容,只需简单生成一批HTML文件并将其复制到Web服务器上的相应目录即可。当用户单击超链接时,他们浏览由公布者创建的文件,通过服务器上目录树中的文件名请求每个文件。

虽然Web应用程序的急速演变从根本上改变了用户与Web交互的体验,但上述动机仍然适用于绝大多数的Web应用程序内容和功能。各种功能一般通过不同的URL访问,后者通常是执行该项功能的服务器端脚本的名称。请求参数(位于URL查询字符串或POST请求主体中)并不告知应用程序执行何种功能,而是告知应用程序在执行功能时使用哪些信息。有鉴于此,建立基于URL的解析方法可对应用程序的功能进行有效分类。

在使用REST风格的URL的应用程序中,URL文件路径的某些部分包含实际上用做参数值的字符串。在这种情况下,通过解析URL,爬虫能够解析应用程序功能和这些功能的已知参数值列表。

但是,在某些应用程序中,基于应用程序“页面”的动机并不适用。尽管从理论上说,我们可以将任何应用程序结构强制插入这种形式的表述中。但是,在许多情况下,另外一种基于功能路径的动机可以更加有效地分类其内容与功能。以仅使用以下请求访问的应用程序为例:

这里的每个请求对应唯一一个URL。请求参数指定Java servlet和需要调用的方法,告诉应用程序执行何种功能。其他参数提供执行该项功能所需的信息。在基于应用程序页面的动机中,应用程序明显只有一种功能,且基于URL的解析不会解释它的功能。但是,如果我们根据功能路径解析应用程序,就能更加清楚地了解应用程序的有用功能。图4-10是应用程序功能路径图的一部分。

图4-10 Web应用程序功能路径图

即使在应用基于应用程序页面的常规图不存在任何问题的情况下,以这种方式描述应用程序的功能通常更加有用。在URL使用的目录结构中,不同功能之间的逻辑与依赖关系无法一一对应起来。但是,无论是对于了解应用程序的核心功能,还是制订可能的攻击方案,这些逻辑关系对攻击者而言都非常有用。确定这些逻辑关系后,攻击者就能够全面了解应用程序开发人员在执行功能时的期待和假设,并设法找到违背这些假设、在应用程序中造成无法预料的行为的方法。

在使用请求参数而非URL确定功能的应用程序中,这种方法对于枚举应用程序的功能会有所帮助。在前面的示例中,使用前面讨论的内容查找技巧目前还不可能发现任何隐藏的内容。那些技巧需要根据应用程序访问功能时实际使用的机制修改。

渗透测试步骤

(1)确定所有通过在参数中提交某一功能的名称(如/admin.jsp?action=editUser)而非通过请求代表那个功能的一个特殊页面(如/admin/editUser.jsp)访问应用程序功能的情况。

(2)修改上述用于查找URL相关内容的自动化技巧,利用它处理应用程序使用的内容–访问机制。例如,如果应用程序使用参数指定servlet和方法名称,首先确定它在请求一个无效servlet或方法以及请求一个有效方法与其他无效参数时的行为。设法确定表示“触点”(即有效servlet和方法)的服务器响应的特点。如果可能,想出办法分两个阶段攻击这个问题,首先枚举servlet,然后枚举其中的方法。对用于查找URL相关内容的技巧使用相似的方法,列出常见项目,通过从实际观察到的名称进行推断,增加这些项目,并根据项目生成大量请求。

(3)如果可能,根据功能路径绘制一幅应用程序内容图,说明所有被枚举的功能和逻辑路径以及它们之间的依赖关系。

发现隐藏的参数

如果应用程序使用其他参数以别的方式控制其逻辑,那么它使用请求参数说明应执行何种功能的情况就会出现变化。例如,如果在URL的查询字符串中加入debug=true参数,应用程序的运作方式就会发生改变:它可能会关闭某些输入确认检查,允许用户避开某些访问控制或者在响应中显示详细的调试信息。许多时候,我们无法从应用程序的任何内容直接推断它如何处理这个参数(例如,它并不在超链接的URL中插入debug=false)。只有通过猜测许多值,才能在提交正确的值之后了解这个参数产生的效果。

渗透测试步骤

(1)使用常用调试参数名称(调试、测试、隐藏、来源等)和常用值(真、是、开通和1等)列表,向一个已知的应用程序页面和功能提出大量请求。重复执行这一操作,直到浏览完所有名/值对组合。在POST请求的URL查询字符串和消息主体中插入增加的参数。

可以使用多组有效载荷和“集束炸弹”(cluster bomb)攻击类型(请参阅第14章了解详细信息),通过Burp Intruder执行这一测试。

(2)监控收到的全部响应,确定任何表明增加的参数给应用程序处理过程造成影响的异常。

(3)根据可用时间,在许多不同的页面或功能中查找隐藏的参数。选择开发人员最有可能在其中执行调试逻辑的功能,如登录、搜索、文件上传和下载等。

分析应用程序

枚举尽可能多的应用程序内容只是解析过程的一个方面。分析应用程序的功能、行为及使用的技术,确定它暴露的关键受攻击面,并开始想出办法探查其中可供利用的漏洞,这项任务也同样重要。

值得研究的一些重要方面如下。

应用程序的核心功能:用于特定目的时可利用它执行的操作。

其他较为外围的应用程序行为,包括站外链接、错误消息、管理与日志功能、重定向使用等。

核心安全机制及其运作方式,特别是会话状态、访问控制以及验证机制与支持逻辑(用户注册、密码修改、账户恢复等)。

应用程序处理用户提交的输入的所有不同位置:每个URL、查询字符串参数、POST数据、cookie以及类似内容。

客户端使用的技术,包括表单、客户端脚本、厚客户端组件(Java applet、ActiveX控件和Flash)和cookie。

服务器端使用的技术,包括静态与动态页面、使用的请求参数类型、SSL使用、Web服务器软件、数据库交互、电子邮件系统和其他后端组件。

任何可收集到的、关于服务器端应用程序内部结构与功能的其他信息(客户端可见的功能和行为的后台传输机制)。

确定用户输入入口点

在检查枚举应用程序功能时生成的HTTP请求的过程中,可以确定应用程序获取用户输入(由服务器处理)的绝大部分位置。需要注意的关键位置包括以下几项。

每个URL字符串,包括查询字符串标记。

URL查询字符串中提交的每个参数。

POST请求主体中提交的每个参数。

每个cookie。

极少情况下可能包括由应用程序处理的其他所有HTTP消息头,特别是User-Agent、Referer、Accept、Accept-Language和Host消息头。

URL文件路径

通常,查询字符串之前的URL部分并不被视为是进入点,因为人们认为它们只是服务器文件系统上的目录和文件的名称。但是,在使用REST风格的URL的应用程序中,查询字符串之前的URL部分实际上可以作为数据参数,并且和进入点一样重要,因为用户输入就是查询字符串本身。

典型的REST风格的URL可以采用以下格式:

http://eis/shop/browse/electronics/iPhone3G/

在这个示例中,字符串electronics和iPhone3G应被视为存储搜索功能的参数。

同样,在下面这个URL中:

http://eis/updates/2010/12/25/my-new-iphone/

updates之后的每个URL组件都可以以REST方式进行处理。

根据URL结构和应用程序上下文,我们可以轻松确定使用REST风格的URL的应用程序。但是,在解析应用程序时,并不存在必须遵循的固有标准,因为用户与应用程序的交互方式通常由应用程序的开发者决定。

请求参数

多数情况下,在URL查询字符串、消息主体和HTTP cookie中提交的参数都是明显的用户输入进入点。但是,一些应用程序并不对这些参数使用标准的name=value格式,而是使用定制的方案。定制方案采用非标准查询字符串标记和字段分隔符,甚至可能在参数数据中嵌入其他数据方案(如XML)。

以下是笔者在现实世界中遇到的一些非标准参数格式实例:

/dir/file;foo=bar&foo2=bar2;

/dir/file?foo=bar$foo2=bar2;

/dir/file/foo%3dbar%26foo2%3dbar2;

dir/foo.bar/file;

/dir/foo=bar/file;

/dir/file?param=foo:bar;

/dir/file?data=%3cfoo%3ebar%3c%2ffoo%3e%3cfoo2%3ebar2%3c%2ffoo2%3e。

如果应用程序使用非标准的查询字符串格式,那么在探查其中是否存在各种常见的漏洞时必须考虑到这种情况。例如,测试上面最后一个URL时,如果忽略定制格式,认为其仅包含一个名为data的参数,因而提交各种攻击有效载荷作为这个参数的值,对其进行简单处理,那么可能会遗漏处理查询字符串过程中存在的许多漏洞。相反,如果详细分析它使用的定制格式并将有效载荷提交到嵌入的XML数据字段中,立即就会发现严重缺陷,如SQL注入或路径遍历。

HTTP消息头

许多应用程序执行定制的日志功能,并可能会记录HTTP消息头(如Referer和User-Agent)的内容。应始终将这些消息头视为基于输入的攻击的可能进入点。

一些应用程序还对Referer消息头进行其他处理。例如,应用程序可能检测到用户已通过搜索引擎到达,并提供针对用户的搜索查询的定制响应。一些应用程序可能会回应搜索术语,或者尝试突出显示响应中的匹配表达式。一些应用程序则通过动态添加HTML关键字等内容,并包含搜索引擎中最近的访问者搜索的字符串,以提高它们在搜索引擎中的排名。这时,通过提出大量包含经过适当设计的Referer URL的请求,就可以不断在应用程序的响应中注入内容。

近年来出现了一个重要的趋势,即应用程序向通过不同设备(如笔记本电脑、移动电话、平板电脑)进行访问的用户呈现不同的内容。应用程序通过检查User-Agent消息头实现这一目的。除了能为直接在User-Agent消息头本身中实施的基于输入的攻击提供“便利”外,这种行为还可以揭示应用程序中的其他受攻击面。通过伪造流行移动设备的User-Agent消息头,攻击者可以访问其行为与主要界面不同的简化用户界面。由于这种界面通过服务器端应用程序中的不同代码路径生成,并且可能并未经过严格的安全测试,因此,攻击者就可以确定主要应用程序界面中并不存在的漏洞(如跨站点脚本)。

 提示 Burp Intruder提供了一个内置的有效载荷列表,其中包含大量针对不同类型设备的用户代理字符串。攻击者可以执行一次简单的攻击,即向提供不同用户代理字符串的应用程序主页面提出一个GET请求,然后检查Burp Intruder返回的结果,从中确定表明使用了不同用户界面的反常现象。

除了针对浏览器默认发送或应用程序组件添加的HTTP请求消息头实施攻击外,有些时候,攻击者还可以通过添加应用程序可能会处理的其他消息头来实施成功的攻击。例如,许多应用程序会对客户的IP地址进行某种处理,以执行日志、访问控制或用户地理位置定位等功能。通常,应用程序通过平台API可以访问客户的网络连接IP地址。但是,如果应用程序位于负载均衡器或代理服务器之后,应用程序可能会使用X-Forwarded-For请求消息头(如果存在)中指定的IP地址。然后,开发者可能误认为该IP地址是安全的,并以危险的方式处理该地址。在这种情况下,通过添加适当设计的X-Forwarded-For消息头,攻击者就可以实施SQL注入或持续的跨站点脚本等攻击。

带外通道

最后一类用户输入进入点是带外通道,应用程序通过它接收攻击者能够控制的数据。如果只是检查应用程序生成的HTTP流量,攻击者可能根本无法检测到其中一些进入点,发现它们往往需要全面了解应用程序所执行的各种功能。通过带外通道接收用户可控制的数据的Web应用程序包括:

处理并显示通过SMTP接收到的电子邮件消息的Web邮件应用程序;

具有通过HTTP从其他服务器获取内容功能的发布应用程序;

使用网络嗅探器收集数据并通过Web应用程序界面显示这些数据的入侵检测应用程序;

任何提供由非浏览器用户代理使用的API接口(如果通过此接口处理的数据与主Web应用程序共享)的应用程序,如移动电话应用程序。

确定服务器端技术

通常,我们可以通过各种线索和指标确定服务器所采用的技术。

提取版本信息

许多Web服务器公开与Web服务器软件本身和所安装组件有关的详细版本信息。例如,HTTP Server消息头揭示大量与安装软件有关的信息:

除Server消息头外,下列位置也可能揭露有关软件类型和版本的信息:

建立HTML页面的模板;

定制的HTTP消息头;

URL查询字符串参数。

HTTP指纹识别

从理论上说,服务器返回的任何信息都可加以定制或进行有意伪造,Server消息头等内容也不例外。大多数应用程序服务器软件允许管理员配置在Server HTTP消息头中返回的旗标。尽管采取了这些防御措施,但通常而言,蓄意破坏的攻击者仍然可以利用Web服务器的其他行为确定其所使用的软件,或者至少缩小搜索范围。HTTP规范中包含许多可选或由执行者自行决定是否使用的内容。另外,许多Web服务器还以各种不同的方式违背或扩展该规范。因此,除通过Server消息头判断外,还可以使用大量迂回的方法来识别Web服务器。在图4-11中,Httprecon工具正对EIS应用程序进行扫描,并以不同的可信度报告各种可能的Web服务器。

图4-11 Httprecon正在识别EIS应用程序

文件扩展名

URL中使用的文件扩展名往往能够揭示应用程序执行相关功能所使用的平台或编程语言。例如:

 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19
asp——Microsoft Active Server Pages; aspx——Microsoft ASP.NET; jsp——Java Server Pages; cfm——Cold Fusion; php——PHP语言; d2w——WebSphere; pl——Perl语言; py——Python语言; dll——通常为编译型本地代码(C或C++); nsf或ntf——Lotus Domino。

即使应用程序在它公布的内容中并不使用特定的文件扩展名,但我们一般还是能够确定服务器是否执行支持该扩展名的技术。例如,如果应用程序上安装有ASP.NET,请求一个不存在的.aspx文件将返回一个由ASP.NET框架生成的错误页面,如图4-12所示。但是,请求一个扩展名不同的不存在的文件将返回一个由Web服务器生成的常规错误消息,如图4-13所示。

图4-12 一个指出服务器上安装有ASP.NET平台的定制错误页面

图4-13 请求一个无法识别的文件扩展名时生成的常规错误消息

使用前面描述的自动化内容查找技巧,我们能够请求大量常见的文件扩展名,并迅速确定服务器是否执行了任何相关技术。

之所以出现上述不同的行为,是因为许多Web服务器将特殊的文件扩展名映射到特定的服务器端组件中。不同的组件处理错误的方式(包括请求不存在的内容)也各不相同。图4-14说明了默认安装IIS 5.0时将各种扩展名映射到不同处理程序DLL的情况。

图4-14 IIS5.0中的文件扩展名映射

分析请求文件扩展名时生成的各种错误消息可以确定该文件扩展名映射是否存在。在某些情况下,发现一个特殊的映射可能表示存在一个Web服务器漏洞。例如,过去,IIS中的.printer和.ida/.idq处理程序易于遭受缓冲区溢出攻击。

类似于下面的URL是另外一种值得注意的常用识别方法:

https://wahh-app/news/0,,2-421206,00.html

URL末尾用逗号分隔的数字通常由Vignette内容管理平台生成。

目录名称

一些子目录名称常常表示应用程序使用了相关技术。例如:

servlet ——Java servlet;

pls ——Oracle Application Server PL/SQL网关;

cfdocs或cfide —— Cold Fusion;

SilverStream —— SilverStream Web服务器;

WebObjects或{function}.woa—— Apple WebObjects;

rails—— Ruby on Rails。

会话令牌

许多Web服务器和Web应用程序平台默认生成的会话令牌名称也揭示其所使用技术的信息,例如:

JSESSIONID ——Java平台;

ASPSESSIONID ——Microsoft IIS服务器;

ASP.NET_SessionId —— Microsoft ASP.NET;

CFID/CFTOKEN ——Cold Fusion;

PHPSESSID —— PHP。

第三方代码组件

许多Web应用程序整合第三方代码组件执行常见的功能,如购物车、登录机制和公告牌。这些组件可能为开源代码,或者从外部软件开发者购买而来。如果是这样,那么相同的组件会出现在因特网上的大量其他Web应用程序中,可以根据这些组件了解应用程序的功能。通常,其他应用程序会利用相同组件的不同特性,确保攻击者能够确定目标应用程序的其他隐藏行为和功能。而且,软件中可能包含其他地方已经揭示的某些已知漏洞,攻击者也可以下载并安装该组件,对它的源代码进行分析或以受控的方式探查其中存在的缺陷。

渗透测试步骤

(1)确定全部用户输入入口点,包括URL、查询字符串参数、POST数据、cookie和其他由应用程序处理的HTTP消息头。

(2)分析应用程序使用的查询字符串格式。如果应用程序并未使用第3章描述的标准格式,设法了解它如何通过URL提交参数。几乎所有定制方案仍然使用名/值模型的某种变化形式,因此要设法了解名/值对如何被封装到已经确定的非标准URL中。

(3)确定任何向应用程序处理过程引入用户可控制或其他第三方数据的带外通道。

(4)查看应用程序返回的HTTP服务器旗标。注意,在某些情况下,应用程序的不同区域由不同的后端组件处理,因此可能会收到不同的Server消息头。

(5)检查所有定制HTTP消息头或HTML源代码注释中包含的任何其他软件标识符。

(6)运行Httprecon工具识别Web服务器。

(7)如果获得关于Web服务器和其他组件的详细信息,搜索其使用的软件版本,确定在发动攻击时可供利用的所有漏洞(请参阅第18章了解相关内容)。

(8)分析应用程序URL列表,确定任何看似重要的文件扩展名、目录或其他提供服务器使用技术相关线索的内容。

(9)分析应用程序发布的全部会话令牌的名称,确定其使用的技术。

(10)使用常用技术列表或Google推测服务器所使用的技术,或者查找其他明显使用相同技术的Web站点和应用程序。

(11)在Google上搜索可能属于第三方软件组件的任何不常见的cookie、脚本、HTTP消息头名称。如果发现使用相同组件的应用程序,对其进行分析,确定该组件支持的任何其他功能和参数,并确定目标应用程序是否具有这些功能、使用这些参数。注意,由于品牌定制,相同第三方组件在每个应用程序中的外观可能截然不同,但其核心功能(包括脚本和参数名称)往往并无变化。如有可能,下载并安装组件,对其进行分析以充分了解它的功能、查找其中存在的所有漏洞。同时,查询已知漏洞库,确定相关组件中存在的所有已知漏洞。

确定服务器端功能

通过留意应用程序向客户端披露的线索,通常可推断与服务器端功能和结构有关的大量信息,或者至少可做出有根据的猜测。

仔细分析请求

以下面用于访问搜索功能的URL为例:

https://wahh-app.com/calendar.jsp?name=new%20applicants&isExpired=0&startDate=22%2F09%2F2010&endDate=22%2F03%2F2011&OrderBy=name

可见,.jsp文件扩展名表示它使用Java Server Pages。据此可以推断:搜索功能从索引系统或数据库获取信息;OrderBy参数暗示它使用后端数据库,提交的值将被SQL查询的ORDER BY子句使用。和数据库查询使用的其他参数一样,这个参数也非常容易受到SQL注入攻击(请参阅第9章了解相关内容)。

在这些参数中,isExpired字段同样值得我们注意。很明显,这是一个指定搜索查询是否应包含已到期内容的布尔型标志。如果应用程序的设计者并不希望用户访问任何到期的内容,将这个参数由0改为1就能够确定一个访问控制漏洞(请参阅第8章了解相关内容)。

下面的URL允许用户访问内容管理系统,其中包含另外一些线索:

https://wahh-app.com/workbench.aspx?template=NewBranch.tpl&loc=/default&ver=2.31&edit=false

这里的.aspx文件扩展名表示这是一个ASP.NET应用程序。而且,很可能template参数用于指定一个文件名,loc参数用于指定一个目录。很明显,文件扩展名.tpl证明了上述推论,而位置/default很有可能是一个目录名称。应用程序可能获得指定的模板文件,并将其内容包含在响应中。这些参数非常容易受到路径遍历攻击,允许攻击者读取服务器上的任何文件(请参阅第10章了解相关内容)。

同样值得注意的是edit参数,它被设置为假。将这个值更改为真会修改注册功能,可能允许攻击者编辑应用程序开发者不希望用户编辑的数据。由ver参数并不能推断出任何有用的线索,但修改这个参数可能会使应用程序执行一组可被攻击者利用的不同功能。

最后,我们来分析以下请求,它用于向应用程序管理员提出问题:

和其他示例一样,.php文件扩展名表示它使用PHP语言执行功能。而且,应用程序极有可能正通过接口与一个外部电子邮件系统连接;同时,它显示使用电子邮件的相关字段向那个系统提交用户可控制的输入。攻击者可利用这项功能向任何接收者发送任意邮件,并且,其中所有字段都易于遭受电子邮件消息头的注入攻击(请参阅第10章了解相关内容)。

 提示 在猜测请求不同部分的功能时,通常有必要从整个URL和应用程序的角度进行考虑。同样以Extreme Internet Shopping应用程序中的以下URL为例:

http://eis/pub/media/117/view

在功能上,此URL相当于以下URL:

http://eis/manager?schema=pub&type=media&id=117&action=view

虽然并不肯定,但media资源集中很可能包含资源117,并且应用程序正对该资源执行相当于view的操作。检查其他URL将有助于确认这一点。

首先需要考虑将view操作更改为其他可能的操作,如edit或add。但是,如果将其更改为add并且猜测是正确的,则该操作可能相当于添加一个ID为117的资源。这一操作将会失败,因为已经存在一个ID为117的资源。最佳方案是,寻找ID值大于观察到的最大ID值的add操作,或选择任意较大的值。例如,可以请求以下URL:

http://eis/pub/media/7337/add

此外,还有必要通过修改media(同时保留类似的URL结构)来寻找其他数据集合:

http://eis/pub/pages/1/view

http://eis/pub/users/1/view

渗透测试步骤

(1)检查提交到应用程序的全部参数的名称和参数值,了解它们支持的功能。

(2)从程序员的角度考虑问题,想象应用程序可能使用了哪些服务器端机制和技术来执行能够观察到的行为。

推测应用程序的行为

通常,应用程序以统一的方式执行其全部功能。这可能是因为不同的功能由同一位开发者编写,或者可遵循相同的设计规范,或者共享相同的代码组件。在这种情况下,我们可轻松推断出服务器端某个领域的功能,并据此类推其他领域的功能。

例如,应用程序可能会执行某种全局输入确认检查,如在处理前净化各种潜在的恶意输入。确定一个SQL盲注漏洞后,会遇到如何利用它的问题,因为专门设计的请求正被输入确认逻辑以不可见的方式修改。然而,应用程序中可能还有其他功能为正在执行的净化提供良好的反馈,例如,将用户提交的数据“反射”给浏览器的功能。可以使用这项功能测试不同编码及SQL注入有效载荷的各种变化形式的有效性,判定在应用输入确认逻辑后,必须提交哪些原始输入才能获得想要的攻击字符串。如果幸运,会发现整个应用程序使用相同的确认机制,让攻击者可以利用注入漏洞。

当在客户端保存敏感数据时,一些应用程序可使用定制的模糊处理方案,防止用户随意查阅和修改这些数据(请参阅第5章了解相关内容)。由于只能访问一个经过模糊处理的数据样本,这类模糊处理方案可能非常难以解译。然而,应用程序中可能具有某些功能,用户向其提交模糊字符串即可获得原始字符串。例如,错误消息中可能包含导致错误的反模糊处理数据。如果整个应用程序使用相同的模糊处理方案,就可以从某个位置(如cookie中)提取一个模糊字符串,将其提交给其他功能,解译出它的意义。而且,我们还可以对模糊处理方案执行逆向工程,系统地向该功能提交各种数据并监控反模糊处理后得到的结果。

最后,应用程序处理各种错误的方式并不一致,一些区域合理防御并处理错误,而另外一些区域则简单放弃错误,向用户返回冗长的调试信息(请参阅第15章了解相关内容)。在这种情况下,我们可以从某个区域返回的错误消息中收集相关信息,并将其应用于合理处理错误的其他区域。例如,通过系统化地操纵请求参数并监控得到的错误消息,可以判定相关应用程序组件的内部结构和逻辑;幸运的话会发现这个结构的某些方面还被沿用到其他区域。

渗透测试步骤

(1)确定应用程序中任何可能包含与其他区域内部结构和功能有关的线索的位置。

(2)即使暂时无法获得任何肯定的结论,但是,在后期试图利用任何潜在的漏洞时,确定的情况可能会有用。

3.隔离独特的应用程序行为

有时,情况可能恰恰相反。许多可靠或成熟的应用程序采用一致的框架来防止各种类型的攻击,如跨站点脚本、SQL注入和未授权访问。在这类情况下,最可能发现漏洞的区域,是应用程序中后续添加或“拼接”而其常规安全框架不会处理的部分。此外,这些部分可能没有通过验证、会话管理和访问控制与应用程序进行正确连接。一般情况下,通过GUI外观、参数命名约定方面的差异,或者直接通过源代码中的注释即可确定这些区域。

渗透测试步骤

(1)记录其使用的标准GUI外观、参数命名或导航机制与应用程序的其他部分不同的任何功能。

(2)同时记录可能在后续添加的功能,包括调试功能、CAPTCHA控件、使用情况跟踪和第三方代码。

(3)对这些区域进行全面检查,不要假定在应用程序的其他区域实施的标准防御在这些区域也同样适用。

解析受攻击面

解析过程的最后一个步骤是确定应用程序暴露的各种受攻击面,以及与每个受攻击面有关的潜在漏洞。下面简要说明渗透测试员能够确定的一些主要行为和功能,以及其中最可能发现的漏洞。本书的其他内容将详细讨论渗透测试员如何在实际操作过程中探测并利用这些漏洞。

客户端确认——服务器没有采用确认检查。

数据库交互——SQL注入。

文件上传与下载——路径遍历漏洞、保存型跨站点脚本。

显示用户提交的数据——跨站点脚本。

动态重定向——重定向与消息头注入攻击。

社交网络功能——用户名枚举、保存型跨站点脚本。

登录——用户名枚举、脆弱密码、能使用蛮力。

多阶段登录——登录缺陷。

会话状态——可推测出的令牌、令牌处理不安全。

访问控制——水平权限和垂直权限提升。

用户伪装功能——权限提升。

使用明文通信——会话劫持、收集证书和其他敏感数据。

站外链接——Referer消息头中查询字符串参数泄漏。

外部系统接口——处理会话与/或访问控制的快捷方式。

错误消息——信息泄漏。

电子邮件交互——电子邮件与命令注入。

本地代码组件或交互——缓冲区溢出。

使用第三方应用程序组件——已知漏洞。

已确定的Web服务器软件——常见配置薄弱环节、已知软件程序缺陷。

解析Extreme Internet Shopping应用程序

解析EIS应用程序的内容和功能后,攻击者可以通过各种路径对该应用程序实施攻击,如图4-15所示。

图4-15 EIS应用程序暴露的受攻击面

/auth目录包含验证功能。为此,有必要仔细检查所有验证功能、会话处理和访问控制,包括其他内容搜索攻击。

在/core路径内,站点状态页面似乎接受由管道符(|)分隔的参数构成的数组。除传统的基于输入的攻击外,还可以对source、location和IP这些值实施蛮力攻击,以揭示有关其他用户或在pageID中指定的页面的详细信息。另外,还可以搜索有关无法访问的资源的信息,或者在pageID中尝试使用通配符,如pageID=all或pageID=*。最后,由于显示的pageID值中包含斜杠,这表示应用程序可能正从文件系统检索资源,因而可以对其实施路径遍历攻击。

/gb路径包含该站点的留言板。访问此页面后发现,这是一个由管理员主持的讨论论坛。虽然其中的消息由管理员进行管理,但却采用了登录避开机制login=true,这说明攻击者可以尝试批准恶意消息(以实施跨站点脚本攻击),以及阅读其他用户发送给管理员的私有消息。

/home路径似乎保存的是经过验证的用户内容。基于这一点,攻击者可以尝试实施水平权限提升攻击,以访问其他用户的个人信息,并确保在每个页面实施了访问控制。

快速检查后发现,/icons和/images路径保存的是静态内容。这说明可以尝试对属于第三方软件的图标名称实施蛮力攻击,并检查这些目录的目录索引,但不必做过多尝试。

/pub路径的/pub/media和/pub/user目录下包含的是REST风格的资源。这说明可以针对/pub/user/11中的数字值实施蛮力攻击,以查找其他应用程序用户的个人资料页面。与此功能类似的社交网络功能可以揭示用户信息、用户名和其他用户的登录状态。

/shop路径中包含网上购物站点和大量URL。但是,这些URL的结构大致相同。仅查看一或两个URL,攻击者就可以确定所有相关的受攻击面。购物过程中可能包含有趣的逻辑缺陷,攻击者可以利用这些缺陷获得未授权折扣或逃避支付。

渗透测试步骤

(1)了解应用程序执行的核心功能和使用的主要安全机制。

(2)确定通常与常见漏洞有关的应用程序功能和行为特点。

(3)在公共漏洞数据库(如www.osvdb.org)中检查任何第三方代码,以确定任何已知问题。

(4)制订攻击计划,优先考虑最可能包含漏洞的功能,以及最严重的漏洞。

小结

解析应用程序是向其发动攻击的重要前提。虽然直接发动攻击并开始探查实际漏洞的做法十分具有吸引力,但详细了解应用程序的功能、技术与受攻击面更利于后面的攻击。

在几乎所有的Web应用程序攻击中,在采用手动技巧的同时,适当采用受控的自动化技巧是最有效的攻击手段。几乎不存在任何完全自动化的工具,能够对应用程序进行安全、彻底的解析。要解析应用程序,渗透测试员需要自己动手并利用相关经验。本章讨论的核心技术包括以下几项。

手动浏览和用户指定的抓取,枚举应用程序的可见内容与主要功能。

使用蛮力结合人为干预和直觉发现尽可能多的隐藏内容。

对应用程序进行智能分析,确定其关键功能、行为、安全机制与技术。

评估应用程序的受攻击面,确定最易受到攻击的功能和行为,对其执行更有针对性的探查,以发现可供利用的漏洞。

问题

欲知问题答案,请访问http://mdsec.net/wahh。

(1)当解析一个应用程序时,会遇到以下URL:

https://wahh-app.com/CookieAuth.dll?GetLogon?curl=Z2Fdefault.aspx

据此可以推论出服务器使用何种技术?该技术的运作方式可能是怎样的?

(2)如果所针对的应用程序是一个Web论坛,并且只发现了一个URL:

http://wahh-app.com/forums/ucp.php?mode=register

如何通过它获得论坛成员列表?

(3)当解析一个应用程序时,遇到以下URL:

https://wahh-app.com/public/profile/Address.asp?action=view&location=default

据此推断服务器端应使用何种技术。可能还存在哪些其他内容和功能?

(4)Web服务器的一个响应包含以下消息头:

Server: Apache-Coyote/1.1

这表示服务器使用何种技术?

(5)假设正在解析两个不同的Web应用程序,在每个应用程序中请求URL/admin.cpf。每个请求返回的响应消息头如下所示。仅由这些消息头能否确定每个应用程序中存在所请求的资源?

浙ICP备11005866号-12