在 Nmap 中执行 SQL 注入实验

Beginner

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

简介

SQL 注入(SQL Injection)是一种常见的攻击技术,攻击者通过构造恶意输入,在后端数据库中执行任意 SQL 语句,从而利用 Web 应用程序的漏洞。在本实验中,我们将使用 Docker 搭建一个基于 sqli-labs 的 SQL 注入环境,并通过动手实验来理解 SQL 注入漏洞的原理和利用方法。


Skills Graph

识别注入点

欢迎来到我们的 Web 安全测试入门课程,本课程将重点介绍如何识别潜在的 SQL 注入漏洞。SQL 注入是 Web 应用程序中常见且可能造成严重后果的安全漏洞,但通过正确的知识,你可以学会如何识别并预防它。

什么是 SQL 注入?

SQL 注入是一种攻击技术,攻击者将恶意的 SQL 代码插入到 Web 应用程序的数据库查询中。如果 Web 应用程序未对用户输入进行适当的清理,这可能导致数据泄露、数据丢失或其他严重问题。

识别潜在的 SQL 注入点

与数据库交互的 Web 应用程序通常会在 URL 中包含参数。如果这些参数未经过适当的清理,它们可能会被利用。例如,你可能会看到如下 URL:

http://some-website.com/page.php?id=XX

在这个 URL 中,id 是一个与数据库交互的参数。任何使用此类参数的网页,如果输入未经过适当的清理,都可能存在 SQL 注入漏洞。

测试 SQL 注入:单引号技术

测试 SQL 注入漏洞的一种简单方法是使用单引号技术。以下是具体步骤:

  1. 在 URL 的参数值后附加一个单引号(')。例如,你可以将 URL 修改为:http://some-website.com/page.php?id=1'
  2. 如果网页在按下回车后返回错误信息,这可能意味着该网站存在 SQL 注入漏洞。

这种方法之所以有效,是因为在 SQL 中,无论是数值还是字符串数据类型,当引入不平衡的单引号时都会生成语法错误。这种错误可以揭示 SQL 注入漏洞的存在。

重要提示

如果你附加单引号后没有显示错误,这并不一定意味着不存在 SQL 注入漏洞。可能是应用程序过滤了单引号,这时你需要使用其他技术来测试漏洞。别担心,我们将在后续课程中介绍这些更高级的技术。

请记住,道德黑客的目的是提高安全性。在你的测试过程中,始终尊重隐私和合法性。祝你学习愉快!

确定 SQL 注入类型

干得漂亮!你已经成功识别了潜在的 SQL 注入点。现在,让我们进入下一步:确定 SQL 注入漏洞的类型。我们将重点关注两种主要类型:数值型 SQL 注入和字符串型 SQL 注入。

数值型 SQL 注入

当输入参数(我们称之为 x)被 Web 应用程序视为整数时,SQL 查询可能如下所示:

select * from <table_name> where id = x

为了识别数值型 SQL 注入,我们使用两个简单的逻辑条件:and 1=1and 1=2。具体步骤如下:

  1. 在浏览器中输入 http://some-website.com/page.php?id=x and 1=1。如果页面正常加载,继续下一步。
  2. 现在,尝试输入 http://some-website.com/page.php?id=x and 1=2。如果页面返回错误或行为异常,这可能表明存在数值型 SQL 注入漏洞。

为什么这种方法有效?

当你输入 and 1=1 时,生成的 SQL 查询如下:

select * from <table_name> where id = x and 1=1

条件 1=1 始终为真,因此如果页面正常加载,这表明输入被直接插入到 SQL 查询中。

当你输入 and 1=2 时,生成的 SQL 查询如下:

select * from <table_name> where id = x and 1=2

条件 1=2 始终为假,因此如果页面行为异常(例如返回错误),这表明我们的输入影响了 SQL 查询,暗示可能存在 SQL 注入漏洞。

字符串型 SQL 注入

在某些情况下,输入参数 x 被 Web 应用程序视为字符串。SQL 查询可能如下所示:

select * from <table_name> where id = 'x'

为了识别字符串型注入,我们使用与数值型注入类似的方法,但使用字符串条件:and '1'='1'and '1'='2'。具体步骤如下:

  1. 在浏览器中输入 http://some-website.com/page.php?id=x' and '1'='1。如果页面正常加载,继续下一步。
  2. 现在,尝试输入 http://some-website.com/page.php?id=x' and '1'='2。如果页面返回错误或行为异常,这可能表明存在字符串型 SQL 注入漏洞。

为什么这种方法有效?

当你输入 and '1'='1' 时,生成的 SQL 查询如下:

select * from <table_name> where id = 'x' and '1'='1'

条件 '1'='1' 始终为真,因此如果页面正常加载,这表明输入被直接插入到 SQL 查询中。

当你输入 and '1'='2' 时,生成的 SQL 查询如下:

select * from <table_name> where id = 'x' and '1'='2'

条件 '1'='2' 始终为假,因此如果页面行为异常(例如返回错误),这表明我们的输入影响了 SQL 查询,暗示可能存在 SQL 注入漏洞。

在这两种情况下,请记住,Web 应用程序的异常响应可能提示你找到了 SQL 注入点。然而,始终确保你有权限执行这些测试,并负责任地使用你的技能。祝你学习愉快!

利用 SQL 注入绕过身份验证

在本实验中,我们将深入探讨 SQL 注入漏洞。我们的重点是如何利用这些漏洞绕过登录身份验证,这种技术通常被称为“万能密码”攻击。

准备实验环境

首先,我们需要准备实验环境。我们将使用 Damn Vulnerable Web Application (DVWA) —— 一个故意设计为不安全的 PHP/MySQL Web 应用程序,是理解 Web 应用程序安全的理想学习工具。

  1. 下载 sqli-labs Docker 镜像: sqli-labs Docker 镜像可在 Docker Hub 上下载。在终端中使用以下命令拉取镜像:

    docker pull acgpiano/sqli-labs
  2. 启动 sqli-labs Docker 容器: 下载镜像后,使用以下命令运行容器:

    docker run -it -d --name sqli-labs -p 80:80 -p 13306:3306 acgpiano/sqli-labs

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

通过以上步骤,你已经成功设置了必要的实验环境。

设置完成后,打开 Firefox 并在地址栏中输入 http://localhost

如果你是第一次访问 http://localhost,请点击 Setup/reset Database for lab 以准备实验,然后刷新网页。

识别 SQL 注入

点击 Less-11 后,你应该会看到一个简单的登录页面。尝试输入任意用户名 123 和密码 123

错误页面会提示你“无效的用户名或密码”。

解析后端代码

让我们看一下负责身份验证过程的后端代码:

// 获取变量
if(isset($_POST['uname']) && isset($_POST['passwd']))
{
	$uname=$_POST['uname'];
	$passwd=$_POST['passwd'];

	// 将连接参数记录到文件中以便分析
	$fp=fopen('result.txt','a');
	fwrite($fp,'User Name:'.$uname);
	fwrite($fp,'Password:'.$passwd."\n");
	fclose($fp);

	// 连接数据库
	@$sql="SELECT username, password FROM users WHERE username='$uname' and password='$passwd' LIMIT 0,1";
	$result=mysql_query($sql);
	$row = mysql_fetch_array($result);
....
}

实际执行的 SQL 查询如下:

SELECT * FROM users WHERE username='123' AND password='123' LIMIT 0,1

这个查询很容易理解:如果返回一行,其中 usernamepassword 都匹配,则登录成功。

利用漏洞

基于上一个实验的知识,让我们尝试输入以下 payload:

用户名:123' or 1=1 #
密码:123' or 1=1 #

有趣的是,这让我们成功登录了!原因是实际执行的 SQL 查询如下:

SELECT * FROM users WHERE username='123' or 1=1 #' AND password='123' or 1=1 #'

在 MySQL 中,# 符号用于注释掉行的其余部分,因此查询实际上变为:

SELECT * FROM users WHERE username='123' or 1=1

由于条件 or 1=1 始终为真,查询将始终返回结果,从而导致成功登录。

我们还可以尝试不使用注释符号的变体:

用户名:123' or '1'='1
密码:123' or '1'='1

实际执行的 SQL 查询如下:

SELECT * FROM users WHERE username='123' or '1'='1' AND password='123' or '1'='1'

在这种情况下,两个 or 条件确保它们之间的 and 条件始终为真,从而导致成功登录。

结论

如上所示,有许多技术可用于利用 SQL 注入漏洞并绕过身份验证。你可以自由探索和尝试不同的 payload。我们的目标是理解这些漏洞,以便更好地保护自己的应用程序免受其害。祝你道德黑客学习愉快!

总结

在本实验中,我们学习了如何使用单引号技术识别 SQL 注入漏洞,以及如何通过特定的 payload 确定 SQL 注入的类型(数值型或字符串型)。我们还探讨了如何利用 SQL 注入漏洞绕过登录身份验证,这是一种常见的场景,被称为“万能密码”攻击。通过动手实验,我们获得了理解和利用 SQL 注入漏洞的实践经验,这些漏洞在 Web 应用程序中非常普遍,尤其是在输入清理未正确实施的情况下。