使用 Nmap 挖掘 SQL 注入漏洞

Beginner

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

介绍

欢迎来到这个互动实验!我们的重点是 SQL 注入漏洞——这是对 Web 应用程序普遍存在且严重的威胁。简单来说,当应用程序接收到未经适当检查或编码的数据,并将这些数据包含在 SQL 查询中时,就会发生 SQL 注入攻击。这个漏洞可能使网络攻击者能够运行有害的 SQL 命令,从而导致未经授权访问机密数据,或使他们能够执行其他有害操作。

本实验的目标有两个。首先,我们旨在揭开 SQL 注入漏洞的核心概念,将其分解为易于理解的部分。其次,我们提供动手实践,帮助你学习如何利用这些漏洞,不是为了恶意目的,而是为了更好地理解和预防它们。这种实践方法将使你具备保护应用程序免受此类威胁的知识和技能。


Skills Graph

设置实验环境

在本节中,我们将指导你完成设置实验环境的过程,以便你可以在其中练习 SQL 注入攻击。

  1. 拉取 DVWA Docker 镜像:
    DVWA Docker 镜像可在 Docker Hub 上获取。你可以使用以下命令拉取它:

    docker pull vulnerables/web-dvwa
  2. 运行 DVWA Docker 容器:
    拉取镜像后,你可以使用以下命令运行它:

    docker run -d -p 80:80 --name dvwa vulnerables/web-dvwa

    该命令将启动一个新容器,并将容器中的 80 端口映射到主机上的 80 端口。

以上步骤为实验准备了必要的环境。设置完成后,在桌面上启动 Firefox 浏览器并输入以下 URL:http://localhost

稍等片刻后,你将进入登录页面。默认的凭据如下:用户名 - "admin",密码 - "password"。

你将看到 DVWA(Damn Vulnerable Web Application)网页。点击“Create/Reset Database”按钮为应用程序生成一个新的数据库。

重要提示: 为了本实验的目的,我们将安全级别设置为“low”。此调整使 SQL 注入漏洞更加明显。为此,从“Security Level”下拉菜单中选择“low”,然后点击“Submit”按钮。

识别 SQL 注入点

在本模块中,我们将揭示应用程序中存在的 SQL 注入漏洞。

步骤 1:导航到 SQL 注入页面

在应用程序的左侧菜单中,你会找到一个标记为“SQL Injection”的链接。点击此链接以导航到 SQL 注入页面。在这里,你会看到一个要求输入用户 ID 的表单。

步骤 2:输入示例用户 ID

让我们尝试输入一个用户 ID,看看会发生什么。

示例输入:

1

在表单中输入“1”并点击“Submit”按钮。输出应显示 ID 为 1 的用户详细信息。

步骤 3:检查源代码

通过点击“View Source”按钮,你可以检查页面的源代码。你应该会看到类似于以下 PHP 代码的内容:

$id = $_GET['id'];
$sql = "SELECT first_name, last_name FROM users WHERE user_id = '$id';";
$result = mysqli_query($conn, $sql);

这段代码揭示了应用程序通过将用户输入直接与 SQL 语句拼接来构建 SQL 查询。这是一个常见的错误,可能会造成 SQL 注入漏洞。

步骤 4:确认 SQL 注入漏洞

为了验证 SQL 注入漏洞的存在,让我们尝试在值“1”后注入一个单引号(')。在表单中输入以下内容:

1'

如果你看到数据库错误消息,这表明应用程序确实存在 SQL 注入漏洞。这是识别并随后解决此类漏洞的关键步骤。

确定 SQL 注入类型和数据库类型

在本节中,我们将指导你完成识别 SQL 注入漏洞类型以及应用程序使用的数据库类型的过程。

我们的首要目标是确定原始 SQL 查询返回的列数。为此,我们将使用ORDER BY子句。

示例代码:

1' ORDER BY 1#
1' ORDER BY 2#
1' ORDER BY 3#

请将上述 SQL 语句逐一输入到表单中。如果应用程序行为正常,前两个查询将成功执行,而第三个查询将失败。此失败表明原始 SQL 查询返回了两列。

接下来,我们可以使用UNION操作符从数据库中提取更多数据。

示例代码:

1' UNION SELECT version(), @@version_compile_os#

此 SQL 语句将获取数据库的版本以及运行数据库的操作系统版本。

执行此查询后,输出应显示有关数据库版本和操作系统的信息。

获取数据库名称

在本课程中,我们将指导你完成获取应用程序使用的数据库名称的过程。这是一项关键技能,尤其是在你试图了解数据库的结构和组织时。

示例代码:

1' UNION SELECT database(), user()#

上述 SQL 查询是一种称为“SQL 注入”的技术示例。这是一种代码注入技术,攻击者利用它来利用应用程序数据库层中存在的安全漏洞。此特定查询用于获取当前数据库名称以及执行查询的用户。

以下是代码的解析:

  • 1' UNION:这是 SQL 注入的第一部分。1'部分用于完成应用程序可能正在运行的查询。UNION关键字用于组合两个或多个 SELECT 语句的结果,而不返回任何重复行。
  • SELECT database(), user()#:这是你注入的查询部分。database()函数用于获取当前数据库的名称,user()函数用于获取执行查询的用户名称。

提交查询后,你应该会在输出中看到数据库名称和用户信息。这些信息对于进一步了解数据库结构以及用户在应用程序上下文中的权限至关重要。

请记住,理解这些技术不仅有助于利用漏洞,还能通过了解需要防御的内容来创建安全的应用程序。

获取表名

在本课程中,我们将进一步探索数据库的结构,通过获取其中的表名来深入了解。理解表结构对于尝试提取或操作数据库中的数据至关重要。

示例代码:

1' UNION SELECT table_name, table_schema FROM information_schema.tables WHERE table_schema = 'dvwa'#

上述 SQL 查询继续利用 SQL 注入技术。这一次,它用于获取数据库中表的名称及其对应的数据库模式。

以下是代码的解析:

  • 1' UNION:如前所述,这部分用于完成应用程序可能的查询,并将其与我们注入的负载结合。
  • SELECT table_name, table_schema FROM information_schema.tables WHERE table_schema = 'dvwa':这是查询中我们注入的负载部分。它从information_schema.tables系统表中获取表名及其对应的数据库模式,特别是针对'dvwa'模式。

information_schema.tables是一个系统表,其中包含数据库中所有表的信息。table_schema指的是表所属的数据库名称,而table_name是表的名称。

提交查询后,你应该会在输出中看到表名及其对应的数据库模式。这些信息可以为进一步探索或利用数据库提供路线图。

一如既往,请记住,理解这些技术不仅对于利用漏洞至关重要,还能通过了解需要防御的内容来创建安全的应用程序。

获取列名和数据

在本课程中,我们将通过获取特定表的列名来更深入地探索数据库结构。有了这些知识,我们就可以从表中提取潜在的敏感数据。

示例代码:

1' UNION SELECT 1, group_concat(column_name) FROM information_schema.columns WHERE table_name = 'users'#

上述 SQL 查询利用 SQL 注入技术来获取'users'表的列名。它将这些列名连接成一个字符串,以便于查看。

以下是代码的解析:

  • 1' UNION:如前所述,这部分用于完成应用程序可能的查询,并将其与我们注入的负载结合。
  • SELECT 1, group_concat(column_name) FROM information_schema.columns WHERE table_name = 'users':这是查询中我们注入的负载部分。它从'users'表中获取列名,并使用group_concat函数将它们连接成一个字符串。

提交查询后,你应该会在输出中看到列名。

现在我们已经有了列名,就可以从'users'表中提取敏感数据。

示例代码:

1' UNION SELECT user, password FROM users#

此 SQL 查询利用 SQL 注入技术从'users'表中获取'user'和'password'列。

提交查询后,你应该会在输出中看到用户名和哈希密码。这些信息可能非常敏感,了解如何提取这些信息对于利用漏洞和防御此类攻击至关重要。

请记住,理解这些技术的目标有两个:识别潜在的漏洞并构建更安全的应用程序。

总结

在本实验中,你学习了 SQL 注入漏洞,并通过动手实践掌握了如何利用这些漏洞。你搭建了一个存在漏洞的 Web 应用程序,识别了 SQL 注入点,确定了 SQL 注入类型和数据库类型,并通过利用 SQL 注入漏洞从数据库中提取了敏感信息。

通过完成本实验,你获得了理解和利用 SQL 注入漏洞的实践经验,这些漏洞是最常见且危险的 Web 应用程序漏洞之一。这些知识将帮助你在实际场景中识别和缓解此类漏洞,从而提升你的 Web 应用程序安全技能。