SQL注入攻击(SQLi)

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

2023年中威胁报告

什么是SQL注入攻击?

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

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

Actions a successful attacker may take on a compromised target include:

  • 绕过身份验证
  • 漏出/窃取数据
  • 修改或破坏数据
  • 删除数据
  • 运行任意代码
  • Gaining root access to the system itself

SQL注入有多危险?

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

数据库通常是通过应用程序(如网站)注入的目标, 它请求用户输入,然后根据输入在数据库中进行查找), 但他们也可以直接成为目标. SQL injection attacks are listed on the OWASP Top 10 list of application security risks that companies wrestle with.

SQL注入攻击的类型

SQL injection attacks can be carried out in a number of ways. 攻击者在选择特定的攻击向量/方法之前可能会观察系统的行为.

Unsanitized输入

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

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

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

虽然这适用于正确输入帐户号码的用户, 这为攻击者敞开了大门. 例如, if someone decided to provide an account number of “‘ or ‘1’ = ‘1”, that would result in a query string of:

            “SELECT * FROM customers WHERE account = ‘’ or ‘1’ = ‘1’;”

Due to the ‘1’ = ‘1’ always evaluating to TRUE, sending this statement to the database will result in the data for 所有 customers being returned instead of just a single customer.

SQL盲注入

Also referred to as Inferential SQL Injection, 盲目SQL注入攻击不会直接从被攻击的数据库中泄露数据. Rather, the attacker closely examines indirect clues in behavior. HTTP响应中的详细信息, 某些用户输入的空白网页, 根据攻击者的目标,数据库响应特定用户输入所需的时间都可能是线索. 它们还可以指向另一种SQLi攻击途径,供攻击者尝试.

带外注入

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

A Second Order Injection is a type of 带外注入 attack. 在这种情况下, 攻击者将提供SQL注入,该SQL注入将由数据库系统的单独行为存储和执行. 当次要系统行为发生时(它可能是基于时间的作业或由数据库的其他典型管理员或用户使用触发的行为),并且执行攻击者的SQL注入, that’s when the “reach out” to a system the attacker controls happens.

SQL注入示例 

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

The 使用rs table has information used for logins like: 

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

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

当有人想登录时,他们会进入登录页面,输入他们的用户名和密码. This information is then sent to the webserver, 它将构造一个SQL查询并将该查询发送到数据库服务器. An example of what that query looks like might be:

Select ID from 使用rs where username=’jsmith’ 和 password=’P@$$w0rd’

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

But, what if we want to get malicious with this? Because the database server performs that true-or-false check, we can trick it into believing that we have successfully authenticated. We can do this by adding an OR to the password. 如果我们使用x '或1=1作为密码登录,将创建一个新的SQL查询,如下所示: 

Select ID from 使用rs where username=’jsmith’ 和 password=’x’ or 1=1

这对我们有用, because while x is not jsmith’s password, the database server will then check the second condition. If x isn’t jsmith’s password, then does 1 equal 1? 它! 该ID将被发送回应用程序,用户将成功地进行身份验证. 

This doesn’t have to be a 1=1 condition. Any two equal values will work, 2=2, 4726=4726 or even a=a. 

If a web page is capable of displaying data, it may also be possible to print additional data to the screen. To access the data, we can try to chain together two SQL requests. 除了'或1=1, we can add on to that a second statement like UNION SELECT 姓, 信用卡号, 来自联系人的安全码. Extra clauses like this may take some extra work, 但是访问数据是SQL注入攻击的最终目标.

Another technique we can use for blind SQL injection, 没有数据被发送回屏幕的是注入其他提示. Similar to our ‘ or 1=1 condition, we can tell the server to sleep. We could add: “ ‘ or sleep(10) ” 和 this will do what it seems like. 它将告诉数据库服务器进行10秒的小睡,所有响应将被延迟.

如何防止SQL注入攻击

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

不要使用动态SQL

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

  • Properly escape those characters which should be escaped.
  • Verify that the type of data submitted matches the type expected.

Don’t leave sensitive data in plaintext

  • Encrypt private/confidential data being stored in the database.
  • 对加密的哈希加盐.
  • 这还提供了另一层保护,以防攻击者成功地泄露敏感数据.

Limit database permissions 和 privileges

  • Set the capabilities of the database user to the bare minimum required.
  • This will limit what an attacker can do if they manage to gain access.

Avoid displaying database errors directly to the user. 攻击者可以使用这些错误消息来获取有关数据库的信息.

使用一个 Web应用防火墙(WAF) for web applications that access databases

  • This provides protection to web-facing applications.
  • It can help identify SQL injection attempts.
  • 基于设置, 它还可以帮助防止SQL注入尝试到达应用程序, 因此, 数据库).

使用 Web应用程序安全测试 to routinely test web apps that interact with databases. 这样做可以帮助捕获可能允许SQL注入的新错误或回归.

Keep databases updated to the latest available patches. 这可以防止攻击者利用旧版本中存在的已知弱点/错误.

SQL injection is a popular attack method for adversaries, but by taking the proper precautions such as ensuring 数据是加密的, that you protect 和 test your web applications, 和 that you’re up to date with patches, you can take meaningful steps toward keeping your data secure.