SQL注入攻击(SQLi)

了解什么是SQLi攻击,它们的目标是谁,它们与其他类型的网络攻击有何不同.

2023年中威胁报告

什么是SQL注入攻击?

结构化查询语言(SQL)是一种设计用于操作和管理数据库中的数据的语言. 从一开始,SQL就稳步地进入了许多商业和开源数据库. SQL注入(SQLi)是一种 网络安全攻击类型 它使用精心设计的SQL语句来针对这些数据库,以欺骗系统做意想不到的和不希望的事情.

如果你有不到五分钟的时间,可以在这个视频中了解SQL注入攻击: 

成功的攻击者可能对受攻击的目标采取的行动包括:

  • 绕过身份验证
  • 漏出/窃取数据
  • 修改或破坏数据
  • 删除数据
  • 运行任意代码
  • 获得对系统本身的root访问权限

SQL注入有多危险?

如果完成成功, SQL注入有可能对任何企业或个人造成难以置信的危害. 一旦敏感数据在攻击中被泄露,就很难完全恢复. 

数据库通常是通过应用程序(如网站)注入的目标, 它请求用户输入,然后根据输入在数据库中进行查找), 但他们也可以直接成为目标. SQL注入攻击列在 OWASP 公司需要应对的十大应用程序安全风险.

SQL注入攻击的类型

SQL注入攻击可以通过多种方式实现. 攻击者在选择特定的攻击向量/方法之前可能会观察系统的行为.

Unsanitized输入

未经清理的输入是一种常见的SQLi攻击类型,攻击者提供的用户输入没有对应该转义的字符进行正确清理, 并且/或者输入没有被验证为正确/期望的类型. 

例如, 用于在线支付账单的网站可能会在web表单中请求用户的账号,然后将其发送到数据库以提取相关的账户信息. 如果web应用程序正在使用用户提供的帐号动态构建SQL查询字符串, 它可能看起来像这样:

            “SELECT * FROM customers WHERE account = ' ' + userProvidedAccountNumber + ' '; "

虽然这适用于正确输入帐户号码的用户, 这为攻击者敞开了大门. 例如, 如果有人决定提供一个账号“'或' 1 ' = ' 1”, 这将导致查询字符串为:

            “SELECT * FROM customers WHERE account = " or ' 1 ' = ' 1 '; "

由于' 1 ' = ' 1 '总是求值为TRUE, 将此语句发送到数据库将导致数据为 所有 顾客被退回,而不是单个顾客.

SQL盲注入

也称为推理SQL注入, 盲目SQL注入攻击不会直接从被攻击的数据库中泄露数据. 相反,攻击者会仔细检查行为中的间接线索. HTTP响应中的详细信息, 某些用户输入的空白网页, 根据攻击者的目标,数据库响应特定用户输入所需的时间都可能是线索. 它们还可以指向另一种SQLi攻击途径,供攻击者尝试.

带外注入

这种攻击有点复杂,当攻击者无法在一次攻击中实现目标时,可能会使用这种攻击, 直接查询-响应攻击. 通常, 攻击者将编写SQL语句, 当呈现给数据库时, 会触发数据库系统创建到攻击者控制的外部服务器的连接吗. 通过这种方式,攻击者可以获取数据或潜在地控制数据库的行为.

二阶注入是一种带外注入攻击. 在这种情况下, 攻击者将提供SQL注入,该SQL注入将由数据库系统的单独行为存储和执行. 当次要系统行为发生时(它可能是基于时间的作业或由数据库的其他典型管理员或用户使用触发的行为),并且执行攻击者的SQL注入, 这就是攻击者“伸出”控制系统的时候.

SQL注入示例 

对于这个SQL注入示例,让我们使用两个数据库表:使用rs和联系s. 使用rs表可能非常简单,只有三个字段:ID、用户名和密码. 联系s表中有关于用户的更多信息, 例如使用rID, FirstName, 姓, Address1, 电子邮件, 信用卡号, 还有安全码. 

使用rs表包含如下登录信息: 

  1. jsmith, P@ w0rd美元美元
  2. sbrown, WinterIsComing!
  3. kcharles, Sup3rSecur3Password $

注意:当密码存储在数据库中时,应该始终对其进行散列和加盐处理,而不是以明文形式存储.

当有人想登录时,他们会进入登录页面,输入他们的用户名和密码. 然后将此信息发送到web服务器, 它将构造一个SQL查询并将该查询发送到数据库服务器. 这个查询的一个例子可能是:

从用户名= ' jsmith '和密码= ' P@$$w0rd '的用户中选择ID

SQL的工作方式是,它将对查询请求的每一行执行真或假比较. 在我们的例子中, 查询要求检查使用rs表,并返回用户名为jsmith、密码为P@$$w0rd的每一行的ID值. 通常,web服务器会看到数据库服务器返回的是什么,以及它是否是一个数字. 在我们的示例中,web服务器将收到返回的1并允许用户通过登录页面. 

但是,如果我们想恶意地使用它呢? 因为数据库服务器执行真假检查, 我们可以欺骗它,让它相信我们已经成功认证了. 我们可以通过在密码中添加OR来实现这一点. 如果我们使用x '或1=1作为密码登录,将创建一个新的SQL查询,如下所示: 

从用户名= ' jsmith ',密码= ' x '或1=1的用户中选择ID

这对我们有用, 因为x不是jsmith的密码, 然后,数据库服务器将检查第二个条件. 如果x不是jsmith的密码,那么1是否等于1? 它! 该ID将被发送回应用程序,用户将成功地进行身份验证. 

这并不一定是1=1的条件. 任意两个相等的值都可以,2=2,4726=4726,甚至a=a. 

如果一个网页能够显示数据, 也可以在屏幕上打印额外的数据. 为了访问数据,我们可以尝试将两个SQL请求链接在一起. 除了'或1=1, 我们可以在此基础上添加第二个语句,如UNION SELECT 姓, 信用卡号, 来自联系人的安全码. 像这样的附加条款可能需要额外的工作, 但是访问数据是SQL注入攻击的最终目标.

另一种可以用于SQL盲注入的技术, 没有数据被发送回屏幕的是注入其他提示. 与' or 1=1条件类似,我们可以告诉服务器休眠. 我们可以加上:“' or sleep(10)”,这看起来就像这样. 它将告诉数据库服务器进行10秒的小睡,所有响应将被延迟.

如何防止SQL注入攻击

以下建议可以帮助防止SQL注入攻击成功:

不要使用动态SQL

对用户提供的输入进行消毒

  • 适当转义那些应该转义的字符.
  • 验证提交的数据类型是否与预期的类型匹配.

不要以明文形式留下敏感数据

  • 加密存储在数据库中的私有/机密数据.
  • 对加密的哈希加盐.
  • 这还提供了另一层保护,以防攻击者成功地泄露敏感数据.

限制数据库权限和特权

  • 将数据库用户的能力设置为所需的最低限度.
  • 这将限制攻击者在设法获得访问权限时所能做的事情.

避免直接向用户显示数据库错误. 攻击者可以使用这些错误消息来获取有关数据库的信息.

使用一个 Web应用防火墙(WAF) 用于访问数据库的web应用程序

  • 这为面向web的应用程序提供了保护.
  • 它可以帮助识别SQL注入尝试.
  • 基于设置, 它还可以帮助防止SQL注入尝试到达应用程序, 因此, 数据库).

使用 Web应用程序安全测试 常规测试与数据库交互的web应用程序. 这样做可以帮助捕获可能允许SQL注入的新错误或回归.

保持数据库更新到最新的可用补丁. 这可以防止攻击者利用旧版本中存在的已知弱点/错误.

SQL注入是攻击者常用的攻击方法, 但是通过采取适当的预防措施,比如确保数据加密, 保护和测试您的web应用程序, 并且你的补丁是最新的, 您可以采取有意义的步骤来保证数据安全.