Introduction

测试应用程序漏洞的众多方法之一是获取正在运行的实例并像外部攻击者一样对其进行攻击。此过程称为动态应用程序安全测试 (DAST),将成为当前房间的重点。

房间目标

  • 了解如何应用 DAST 来查找实际应用程序中的弱点。
  • 了解使用 DAST 而不是其他技术的利弊。
  • 熟悉用于 DAST 的一些工具。

房间先决条件

在尝试这个房间之前,您应该了解 Web 应用程序和 HTTP 协议的工作原理。了解常见的 Web 漏洞也是可取的。如果您需要复习上述任何主题,请务必查看以下房间:

Dynamic Application Security Testing (DAST)

什么是 DAST?

动态应用程序安全测试 (DAST) 是测试正在运行的 Web 应用程序实例是否存在弱点和漏洞的过程。它侧重于黑盒测试方法,在这种方法中,漏洞的发现方式与普通攻击者发现漏洞的方式一样。简而言之,DAST 通过尝试利用漏洞来识别漏洞,无论是手动还是通过自动化工具。

通过从外部角度测试应用程序,我们可以从其内部工作中抽象出来,专注于识别攻击者可能发现的漏洞。这意味着从 DAST 获得的结果通常会指向需要优先关注的漏洞,因为预计这些漏洞会在不了解应用程序的情况下被发现。

需要注意的是,DAST 不会取代其他方法来查找应用程序中的漏洞,而是对它们进行补充。安全开发生命周期通常会混合使用多种技术,以提供足够好的漏洞覆盖率。

手动与自动 DAST

DAST 有两种执行方式:

  • 手动 DAST:安全工程师将手动对应用程序执行测试以检查漏洞。
  • 自动 DAST:自动化工具将扫描 Web 应用程序以查找漏洞。

这两个过程是互补的,可以在软件开发生命周期 (SDLC) 的不同阶段使用。结合使用手动和自动化工具通常会产生最佳效果,而不是单独依赖其中任何一种。

手动 DAST 将帮助我们发现自动化工具无法轻易发现的弱点,因为它们无法从功能角度理解应用程序。

手动完成所有操作的问题在于,在开发阶段对代码中的每次提交或小更改运行手动测试将花费太多时间。这就是自动化 DAST 的优势所在,因为它提供了一种快速的方法,可以针对目标应用程序运行许多测试,而无需人工交互。

SDLC 中的 DAST

DAST in the SSDLC

虽然每种情况都不同,但在测试阶段使用自动化 DAST 是很常见的。自动化 DAST 工具通常会针对速度进行优化,以便开发人员能够快速获得反馈,而传统的 Web 应用程序漏洞扫描程序可能需要几个小时才能运行。这里的想法不是对应用程序进行广泛的扫描,而是尽早发现容易发现的问题。

另一方面,手动 DAST 通常会定期运行,以避免减慢整个开发过程的速度。在开发应用程序时,通常每周运行一次手动扫描,但这在很大程度上取决于每个项目。在这些手动扫描中可以使用更密集的扫描配置文件来识别更多漏洞。

当应用程序准备好投入生产时,运行全面的 Web 应用程序渗透测试始终是很好的做法,可以发现最终产品实施中的任何缺陷。

注意:大多数文献通常将自动化 DAST 简称为 DAST,并经常将手动 DAST 视为 Web 应用程序渗透测试的一部分。手动 DAST 也可能被称为“传统 DAST”。

DAST 的优缺点

与用于查找应用程序中的漏洞的任何其他流程一样,DAST 也有其优点和缺点:

优点:在运行时发现漏洞。这将包括特定于部署过程的漏洞,这些漏洞无法通过仅分析代码来发现。DAST 将发现使用 SAST 无法发现的漏洞,例如 HTTP 请求走私、缓存中毒和参数污染。DAST 工具不关心应用程序使用的编程语言。由于 DAST 是黑盒测试,因此所有应用程序都以与语言无关的方式处理。与 SAST 相比,误报数量减少。DAST 工具可能能够发现一些业务逻辑缺陷。有效性取决于工具,不应将其视为手动测试的替代品。 缺点:代码覆盖率不是最好的。DAST 可能无法覆盖仅由应用程序中的特定用例触发的特定情况。与静态代码分析技术相比,使用 DAST 可能更难发现某些漏洞。某些应用程序难以抓取。现代应用程序严重依赖客户端的 javascript 处理。这使得 DAST 工具更难遍历它们。DAST 扫描器无法告诉您如何详细修复某些漏洞,因为它们不知道底层代码。某些类型的扫描可能需要大量时间才能完成。您需要一个正在运行的应用程序来进行测试。

准备好使用 DAST 了吗?

大多数情况下,您会发现 DAST 被当做一系列自动化测试。但是,我们将探索手动过程的工作原理,以便更好地了解大多数工具的基本功能。一般来说,DAST 工具将针对目标网站执行至少以下两项任务:

  • 蜘蛛/爬取:该工具将浏览 Web 应用程序,尝试映射应用程序并识别可能受到攻击的页面和参数列表。
  • 漏洞扫描:该工具将尝试针对已识别的页面和参数启动攻击负载。用户通常可以自定义攻击类型,以仅包含与目标应用程序相关的攻击。

我们将在此房间中使用 ZAP 代理作为我们的 DAST 工具进行演示。但是,请考虑企业设置中使用的许多 DAST 工具都是付费的,而且价格相当昂贵,但将使用与任何其他 Web 应用程序漏洞扫描程序相同的基本原理。工具之间的主要区别在于它们的漏洞检测能力以及它们在产品中添加了多少对企业有用的附加功能,例如仪表板、票务系统集成等等。

Spiders and Crawlers

使用 ZAP 爬取应用程序

我们采取的第一步是获取目标 Web 应用程序中所有资源的地图,以确定分析范围。ZAP 提供了一个爬取模块,我们可以使用它来实现此目的。Spider 将导航到您提供的起始页,并通过跟踪它可以检测到的所有链接从根本上探索网站。

Spidering

要抓取某个网站,我们可以转到工具 -> 蜘蛛。这将显示蜘蛛对话框,我们只需在其中指定一个网站作为起点。现在,我们将上下文和用户框留空。如果需要,您可以检查以下附加选项:

  • 递归:递归抓取网站上的链接。
  • 仅抓取子树:将抓取限制在起点 URL 的子文件夹中。
  • 显示高级选项:启用高级选项卡,您可以在其中指定其他参数来调整抓取。

Spider Window

指向 http://10.10.36.45:8082/ 并按“开始扫描”。片刻之后,您应该会在“站点”选项卡上看到蜘蛛找到的所有 URL:

Sites Tab

现在您应该会看到站点列表,其中包含在爬取过程中找到的所有 URL。起始页 URL 之外的任何项目都被视为超出范围,不会添加到列表中。

您可能会注意到,如果您手动导航到 http://10.10.36.45:8082/,您应该会在菜单中看到指向 /nospiders-gallery.php 的链接,但是如果您在 ZAP 上展开站点列表,您将看不到此 URL。

Spider Limitations

发生这种情况的原因是,此特定链接并非直接嵌入到页面的 HTML 代码中,而是使用浏览器上的 JavaScript 即时生成的(许多现代应用程序都是这样)。由于 ZAP 中的常规蜘蛛没有 JavaScript 引擎,因此无法找到该链接。

更多蜘蛛

为了克服 ZAP 常规蜘蛛的局限性,ZAP 可以利用 Firefox 或 Chrome 等真实浏览器来处理附加到网站的任何脚本并检索生成的 HTML 代码。它不是直接从 HTTP 响应解析链接,而是从浏览器处理网站的结果中解析链接。这可以通过使用 AJAX 蜘蛛 来实现。

利用真正的浏览器非常有利,因为 ZAP 不必处理当前 javascript 引擎的所有复杂问题,而是将此任务委托给浏览器,从而保证结果与用户使用相同浏览器时看到的结果相匹配。

使用 AJAX 蜘蛛的过程与常规蜘蛛类似。只需转到 工具 -> AJAX 蜘蛛,配置 URL 作为起点并检查您认为合适的选项。您唯一的新选项是浏览器选择,这次我们将选择 Firefox。浏览器列表还有无头选项,它将运行所选浏览器而不显示其图形界面,但现在,让我们坚持使用常规 Firefox,因为它可以更轻松地理解 AJAX 蜘蛛的工作原理。您的配置应如下所示:

AJAX Spider

让我们点击“开始扫描”来让它工作。您应该会看到 Firefox 弹出并浏览网站一小会儿。当 AJAX 蜘蛛完成后,它将像常规蜘蛛一样填充 ZAP 中的站点。由于 AJAX 蜘蛛利用 Firefox 的强大功能来获得更好的结果,您现在应该会在 ZAP 中的站点列表中看到“/nospiders-gallery.php”。

Scanning for Vulnerabilities

在 ZAP 中配置扫描策略

运行 DAST 工具时,自定义针对应用程序运行的测试类型至关重要。扫描配置文件越适合 Web 应用程序,扫描器发送与特定场景无关的有效负载所花费的时间就越少。由于 DAST 工具主要在白盒设置中使用,因此用于支持应用程序的底层技术的所有细节都是已知的。以下是我们将在整个房间中使用的应用程序的详细信息:

  • 操作系统:Linux
  • Web 服务器:Apache 2.4
  • 编程语言:PHP(未使用框架)
  • 数据库:无

例如,我们的应用程序不使用数据库。如果您运行默认扫描配置文件,扫描器将尝试在这种情况下毫无意义的 SQL 注入等操作。这会让您的扫描花费更长时间,对于像这个房间中的应用程序这样的小型应用程序来说,这可能没问题,但在扫描更复杂的应用程序时,时间的增加会变得明显。

要在 ZAP 中创建或修改扫描策略,请转到 分析 -> 扫描策略管理器。在那里,让我们单击添加按钮来创建一个新的:

Creating a Scan Policy

从这里,您可以控制作为策略的一部分要运行的测试类型。对于每个类别,您将有两个参数需要配置:

  • 阈值:此参数控制每个类别的详细程度。较低的阈值意味着 ZAP 更有可能根据少量信息报告漏洞。这样,您就会获得更多发现,但 ZAP 可能会报告可能不存在的漏洞(误报)。较高的阈值将指示 ZAP 仅报告具有高度确定性的发现。这样,您就会得到较少的结果,但这些结果更有可能得到证实。使用较高阈值的风险是 ZAP 可能不会报告可能实际存在的某些漏洞(误报)。您还可以将阈值设置为 OFF 以禁用类别。
  • 强度:此参数控制每个类别运行的测试次数。较高的强度级别可能会报告更多发现,但代价是显著增加扫描时间。

由于每个应用程序都不同,因此必须相应地调整这些参数。将其视为一个需要随着时间的推移而改进的反复试验过程。

在我们的应用程序中,由于没有使用数据库,也没有进行任何 XML 处理,我们可以安全地禁用所有相关测试,如下图所示:

Injection Policy

确保这次禁用跨站点脚本(基于 DOM)测试,因为它们会占用大量资源并且可能会减慢您对这个房间的扫描速度:

Disabling Client Browser Checks

运行我们的第一次扫描

现在我们有了自定义的扫描策略,让我们通过菜单中的 工具 -> 主动扫描 来运行漏洞扫描。在这里,我们可以从之前爬取的资源和我们新创建的扫描策略中选择一个起点。让我们使用 http://10.10.36.45:8082/ 作为起点,并选中“递归”框以确保扫描除起点以外的任何页面。让我们暂时忽略其余选项,然后单击 开始扫描

Running a Scan

过了一会儿,我们应该会在警报部分看到一些结果。您可以获得每个发现的描述,这些描述应该可以概括地表明发现了什么。您还可以检查 ZAP 用于检测漏洞的特定请求和相应的响应。

Checking Alerts

这样您就可以检查结果以确保它们都是正确的。如果您认为其中任何一个是误报,您可以通过右键单击结果并选择标记为误报来将其标记为误报。

Authenticated Scans

处理登录

到目前为止,我们已经成功运行了扫描,并在目标应用程序中发现了一些漏洞。但是,我们的应用程序仍有漏洞需要发现。如果我们手动导航到我们的应用程序,我们将看到一个只能使用正确凭据访问的管理控制台。由于 ZAP 不知道这些凭据,因此它将无法检查任何需要身份验证的内容。

我们必须教 ZAP 如何进行身份验证并确保其会话处于活动状态才能解决此问题。为此,我们将身份验证过程记录到 ZEST 脚本中,以便 ZAP 可以在扫描期间复制该过程。现在,将 ZEST 脚本视为一种保存和重现一系列请求的方法。

注意:对于此任务,请确保从工具栏禁用 ZAP HUD。如果启用它,某些功能将无法按预期工作。您可以在工具栏末尾找到执行此操作的按钮:

Disabling ZAP HUD

记录身份验证

要记录身份验证,我们将点击工具栏上的记录新的 ZEST 脚本按钮:

Recording ZEST Scripts

让我们为脚本设置一个标题并选择类型身份验证。我们还想将前缀设置为应用程序的基本 URL,因为这将过滤掉对其他网站的任何请求

Record ZEST Script

一旦我们点击开始录制按钮,通过 ZAP 代理的每个 HTTP 请求都将被记录为脚本的一部分。让我们这样做,并通过单击工具栏上的打开浏览器按钮打开浏览器:

Open Firefox From ZAP

在新打开的浏览器中导航到 http://10.10.36.45:8082/login.php。我们将手动登录网站,以便 ZAP 可以记录该过程。

Website login

您可以使用以下凭据从菜单中的登录页面访问 Web 应用程序:

Username nospiders
Password nospiders

一旦我们正确登录到应用程序,我们将再次单击记录新的 ZEST 脚本按钮来停止录制。也可以随时关闭 ZAP 的浏览器。一些捕获的请求可能对于身份验证过程不是必需的,可以删除。在这种情况下,这些是唯一重要的请求:

Recorded Authentication Script

对于每个请求,ZAP 将检查状态代码和响应长度以查看它们是否匹配。如果匹配,ZAP 将假定登录成功。现在,您可以通过按下 脚本控制台 上的 运行 按钮来测试录制的脚本:

Replaying the Recorded Authentication

通过检查对请求的响应,您可以测试是否正确记录了该过程。我们的应用程序应该响应对 login.php 的 POST 请求,并重定向到 cowsay.php

Checking the Authentication Result

创建上下文

现在我们的身份验证过程已记录,我们需要告诉 ZAP 在哪里使用它。这可以通过创建 上下文 来完成,它只是定义一组 URL 的一种方式。

由于这是一个简单的应用程序,因此记录的身份验证将应用于整个应用程序。因此,我们必须定义一个包含应用程序中的每个 URL 的上下文,以便我们可以将我们的 ZEST 脚本链接到它。

注意:根据您的目标应用程序,记录的身份验证可能仅授予对应用程序部分内容的访问权限。例如,想象一下有老师和学生的教育平台。根据他们的角色,教师和学生可以访问应用程序的不同部分。为了让 ZAP 覆盖应用程序的两侧,我们需要记录两个身份验证 ZEST 脚本(一个用于学生帐户,一个用于教师),并将它们附加到具有相应 URL 的两个不同上下文中。

要创建新上下文,请转到 站点 选项卡,右键单击 站点 选项卡上目标应用程序的基本 URL,然后选择 包含在上下文中 -> 新建上下文

Creating a Context

这将自动创建一个与 Web 应用程序上的任何页面匹配的正则表达式。您可以在上下文中配置许多选项。现在,单击身份验证,然后使用基于脚本的身份验证链接您的 zest 脚本:

Authentication Configuration

请务必单击脚本名称右侧的 Load 按钮。您还可以在此选项卡中配置身份验证验证,以便 ZAP 可以检查其是否具有有效会话或是否需要在扫描期间重新进行身份验证,但我们稍后会以更简单的方式执行此操作。

要进行经过身份验证的扫描,ZAP 还需要您在 Users 部分中定义至少一个用户。在我们的例子中根本不会使用它,因为我们的 ZEST 脚本嵌入了我们将使用的用户和密码。但是,ZAP 需要定义一个用户,否则它将完全跳过身份验证。

Users Configuration

完成后,按“确定”,您应该会看到网站的所有资源现在都标有目标图标,这意味着它们现在是已定义上下文的一部分。

重新抓取应用程序

现在我们已经使用身份验证脚本设置了上下文,让我们重新运行抓取程序,但设置正确的上下文和我们创建的用户:

Authenticated Spidering

这次,ZAP 应该能够找到任何需要身份验证且之前未检测到的资源。让我们点击开始扫描按钮,看看我们得到了什么。如果您想查看在蜘蛛扫描会话期间是否发现了任何新资源,您可以随时检查添加的节点选项卡:

Authenticated Spider Results

ZAP 发现了几个额外的 PHP 脚本。其中一个脚本负责注销用户,可能会造成问题。如果 ZAP 尝试访问它,它将注销其会话。

避免注销

为了防止 ZAP 自行注销,我们将右键单击“站点”选项卡中的 logout.php 脚本,并从我们的上下文中排除该脚本:

Excluding Logout From Context

现在,ZAP 将避免在抓取或扫描期间与注销脚本交互。请注意,根据应用程序的不同,可能还需要排除其他一些脚本。了解应用程序的工作原理对于充分利用扫描过程至关重要。

除了防止直接注销之外,我们还可以指定 ZAP 的指标来识别其会话是否仍处于活动状态,并在必要时重复登录脚本。这可以通过选择仅在您登录或注销时出现的响应部分轻松完成。

例如,我们知道只有在您成功登录后才能访问 cowsay.php,因此它可能具有我们可以用于 ZAP 的良好指标。让我们从“站点”选项卡中选择 cowsay.php,然后选择与注销链接相对应的文本。右键单击所选文本并选择标记为上下文 -> (您的上下文名称):身份验证登录指示器:

Defining a Logged-in Indicator

从现在开始,ZAP 将在每个响应中搜索注销链接。如果不存在,它将假定其会话需要更新,并使用我们记录的 ZEST 脚本重新登录应用程序。

您也可以执行相同操作来选择已注销指示器。由于我们知道登录链接只有在您注销后才可见,因此我们可以按照类似的程序将其用于此目的。让我们从“站点”选项卡中的“aboutme.php”脚本中获取链接的 HTML:

Defining a Logged-out Indicator

我们将右键单击选定的文本并选择标记为上下文 ->(您的上下文名称):身份验证已注册此时。

注意:ZAP 可能已缓存 aboutme.php 的验证响应。在这种情况下,您需要通过内置浏览器向该 URL 重新发送请求以获取正确的模式。

现在ZAP有模式来识别它是否已登录正确,我们需要选择验证策略来告诉它如何正确使用配置其模式。根据您正在检查的网站,您将需要使用不同的策略并进行调整以适应目标应用程序。在这种情况下,我们将使用轮询指定的URL策略并告诉它每60个请求轮询一次/aboutme.php资源以检查登录/注销模式。因此,上面并更改身份验证下的以下设置:

Verification Strategy

最后一次重新扫描应用程序

我们终于准备好对应用程序运行新的扫描,知道它现在将覆盖需要身份验证的应用程序区域。让我们转到工具 -> 主动扫描,然后选择我们创建的上下文用户

Authenticated Scan

如果您正确遵循了这些步骤,ZAP 现在将发现一个新的高风险漏洞。请务必记下它以回答任务结束时的问题。

Checking APIs with ZAP

如今,Web 应用程序依赖 API 来执行部分或全部任务。到目前为止,我们展示的 DAST 过程涉及能够抓取传统的 Web 应用程序,但 API 并不是可以轻松抓取的东西。API 的端点通常不会公开有关其他端点的信息,这使得发现过程更加困难。此外,即使我们获得了端点的名称,我们仍然需要知道可以传递给它的参数。

我们不会抓取 API,而是依靠开发团队为我们提供 API 中可用端点的精确规范以及我们可以发送给它们的所有参数。这样,我们就不需要花时间在发现过程上,而可以直接专注于测试其安全性。

API 描述

存在几个用于记录 API 的标准,这些标准通常包括开发人员构建正确请求所需的所有信息,并了解每个可用端点的响应内容。这也是我们开始测试安全漏洞所需的全部内容。

ZAP 可以导入由 OpenAPI(以前称为 Swagger)、SOAPGraphQL 定义的 API。根据您正在测试的 API,您可能会从开发团队那里获得其中一种格式。

为了让您更好地了解这些文件包含的内容,让我们看一下在 http://10.10.36.45:8081/swagger.json 上发布的文件,它遵循 OpenAPI 2.0 标准。在文件中,您将找到一个名为“paths”的部分,其中列出了 API 的每个端点。对于每个端点,都会显示可用参数的完整列表。例如,这里有关于如何与“/asciiart/{art_id}”交互的规范部分:

"/asciiart/{art_id}": {
"get": {
"parameters": [
{
"description": "art id",
"in": "path",
"name": "art_id",
"required": true,
"type": "string"
}
],
"responses": {
"default": {
"description": "",
"schema": {
"$ref": "#/definitions/ASCIIArt"
}
}
}
}
}

该文件表明,您可以通过在 URL 中发送字符串形式的 art_id 参数,使用 GET 方法调用 /asciiart/{art_id}。您可以找到其他路径的类似定义,如 /asciiart/generate/asciiart/add

API 定义文件预计由机器处理,因此其格式可能难以阅读。为了让我们更容易理解它们,一些 API 还将提供更友好的 UI,我们可以使用它来运行快速测试并探索可用的端点。您可以访问 http://10.10.36.45:8081/swagger-ui/ 进行检查。

注意:生产应用程序可能会隐藏 API 定义,以防止外部攻击者知道如何与它们交互。请记住,如果需要(如果存在),您可以随时向开发团队索取它们。

在 ZAP 中导入 OpenAPI 定义

ZAP 支持两种导入 API 定义的方法:您可以提供离线文件或下载它们的 URL。由于我们的 API 在 http://10.10.36.45:8081/swagger.json 中公开了其定义文件,因此我们使用 URL 选项。转到 导入 -> 从 URL 导入 OpenAPI 定义。指定相应的 URL 并点击 导入 按钮。

Importing OpenAPI Definition

现在您应该看到“站点”选项卡中加载的所有可用端点和参数。

Sites Tab with API Endpoints

ZAP 还将自动对端点进行被动扫描并报告一些警报。导入 API 定义后,ZAP 将把 API 视为任何其他普通网页。

扫描 API

将 API 定义加载到 ZAP 后,您可以像对待任何其他网站一样使用可用的工具。要对 API 运行扫描,请右键单击其 URL 并选择 攻击 -> 主动扫描

Scanning the API

运行扫描后,ZAP 应该发现 API 中的一些漏洞。使用扫描结果来回答任务结束时的问题。

Integrating DAST into the development pipeline

通常,在讨论 DAST 时,人们会提到在开发流程中实施自动漏洞扫描,而不是我们介绍过的手动流程。因此,该术语与您通常所说的应用程序渗透测试不同。

将 DAST 添加到开发流程中可能听起来很简单,但也有一些注意事项:

  • 我们必须决定在开发流程的哪个阶段运行扫描。
  • 我们必须决定什么会触发扫描。我们可以在每次提交代码时或按计划运行扫描。
  • 我们必须确定每次扫描的强度。对中型应用程序进行完整的漏洞扫描需要大量时间,我们不想拖慢开发团队的速度。

由于没有适合所有场景的解决方案,因此必须在开发团队的帮助下确定所有这些,以便满足安全要求而不会对其既定流程造成重大干扰。

在此任务中,我们将研究如何快速将 DAST 直接实施到开发流程中,以提供漏洞的早期可见性。扫描将在每次提交时自动运行,并且仅测试一部分漏洞,以避免在管道中引入长时间延迟。

审查我们的 CI/CD 管道

我们当前的机器为您之前扫描的 Web 应用程序和 API 实现了整个开发管道。以下两个组件负责执行此操作:

每次在 Gitea 中进行提交时,Jenkins 都会从存储库中获取代码并将其编译为 Docker 实例。这些 Docker 实例就是您迄今为止扫描的内容。

CI/CD Pipeline in Action

要访问 Gitea 或 Jenkins,您可以使用以下凭据:

Username thm
Password thm

使用 zap2docker 运行自动扫描

为了将 ZAP 集成到我们的管道中,我们将使用 zap2docker,这是 ZAP 代理的 docker 化版本,主要目的是实现自动化。zap2docker 的完整文档可在 此处 找到。

注意:本节中的命令仅供参考。您无需手动运行它们,因为我们稍后会让 Jenkins 为我们执行此操作。

要安装 zap2docker,您可以使用以下命令从 Docker Hub 中拉取它:

docker pull owasp/zap2docker-stable

您可以使用其中一个打包的扫描脚本从 docker 实例运行 ZAP,这将允许您运行以下扫描配置文件之一:

基线扫描:ZAP 将对目标网站进行最长 1 分钟的蜘蛛扫描。不会执行任何主动扫描。如果需要,您可以选择运行 AJAX 蜘蛛扫描。

docker run -t owasp/zap2docker-stable zap-baseline.py -t https://www.example.com

全面扫描:ZAP 将运行不受时间限制的蜘蛛程序,然后进行主动扫描。

docker run -t owasp/zap2docker-stable zap-full-scan.py -t https://www.example.com

API 扫描:ZAP 将对 API 执行主动扫描。您需要提供 API 描述文件 (OpenAPI、GraphQL 或 SOAP) 的 URL。

docker run -t owasp/zap2docker-stable zap-api-scan.py -t https://www.example.com/swagger.json -f openapi

在任何扫描中,被动扫描的结果将限制为 10 条警报。除了基本命令之外,您还可以添加 -j 开关以对基线和完整扫描执行 AJAX 扫描。

将 ZAP 集成到管道中

您有权访问的环境已经有一个可供使用的 zap2docker 实例。我们需要做的就是告诉 Jenkins 使用我们需要的选项运行 zap2docker,就这样。

在开始之前,让我们先探索一下 Jenkins 中的内容。登录 Jenkins 时,您会发现一个名为 thm 的 组织,其中包含用于 Web 应用程序和 API 的两个 存储库。对于每个存储库,您都可以看到可用的 分支

Organization, Repositories and Branches

两个项目中都会有一个名为“main”的分支。如果单击该分支,您将能够看到它的构建。例如,“simple-webapp”项目已经构建了两次:

Jenkins Builds

对于每个构建,我们可以看到配置了两个阶段:

  • 构建 Docker 镜像:此阶段将根据每个项目上的 Dockerfile 构建 Docker 容器。
  • 部署 Docker 镜像:此阶段将部署 Docker 容器。

这两个阶段都在每个存储库中的 Jenkinsfile 中定义。如果我们转到 Gitea 并打开 simple-webapp 存储库上的 Jenkinsfile,我们可以看到在每个阶段上运行的具体命令:

Jenkinsfile Example

例如,在第二阶段,您可以看到手动扫描的 Web 应用程序如何部署到端口 8082。

如果我们想将 zap2docker 纳入我们的管道,我们可以添加第三阶段,在构建容器后为我们运行扫描。为方便起见,该阶段已在 Jenkinsfile 末尾定义,您可以取消注释以使其运行。如果您觉得更方便,请随意使用“git”向存储库发送提交,或者使用 Gitea 的内置编辑器:

Editing Jenkinsfile from Gitea

请注意,我们仅运行基线扫描,因为此扫描将针对对存储库的每次提交运行,因此用可能需要数小时才能完成的完整扫描来延迟管道是不明智的。此扫描仅用于查找容易实现的目标。这意味着您不会看到任何 SQL 注入、跨站点脚本或任何其他需要主动扫描的内容。

由于 Jenkins 会捕获存储库中的任何更改,因此它会在您编辑文件后立即启动构建过程。您可以切换回 Jenkins 中的 simple-webapp 项目以实时查看进度:

Build with ZAP Stage

您可以看到当前构建现在添加了“使用 OWASP ZAP 扫描”阶段。扫描大约需要 5 分钟。完成后,构建将失败,因为 ZAP 会在应用程序中发现一些漏洞。要检查报告,请打开构建并转到菜单上的 工作区 部分:

Build Failed with Vulnerabilities

您可以在此处浏览项目文件,ZAP 会将其报告放在 zap-reports 文件夹中。下载并检查报告以回答任务结束时的问题。

注意:您应该在打开报告之前右键单击并保存它。直接从 Jenkins 打开它会破坏格式。

重复相同的过程以在 simple-api 存储库上启用 ZAP 并获取相应的报告。使用该报告回答此任务结束时的问题。

Conclusion

在本会议室中,我们介绍了 DAST 的工作原理,并介绍了 ZAP 代理,这是一种可以手动和自动执行 DAST 的工具。DAST 只是检查应用程序漏洞的众多方法之一,应与其他类型的测试(如 SAST、SCA、渗透测试等)结合使用,以确保我们的应用程序具有合理的安全级别。与任何其他技术一样,DAST 不是万能的解决方案,但将有助于提高应用程序在整个软件开发生命周期中的整体安全性。