SQL Injection Attacks (SQLi)

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

2023 Mid-Year Threat Report

What is a SQL Injection Attack?

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

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

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

  • Bypassing authentication
  • Exfiltrating/stealing data
  • Modifying or corrupting data
  • Deleting data
  • Running arbitrary code
  • Gaining root access to the system itself

How Dangerous are SQL Injections?

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

数据库通常是通过应用程序(如网站)注入的目标, 它请求用户输入,然后根据输入在数据库中进行查找), but they can also be targeted directly. SQL injection attacks are listed on the OWASP Top 10 list of application security risks that companies wrestle with.

Types of SQL Injection Attacks

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

Unsanitized Input

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

For example, 用于在线支付账单的网站可能会在web表单中请求用户的账号,然后将其发送到数据库以提取相关的账户信息. 如果web应用程序正在使用用户提供的帐号动态构建SQL查询字符串, it might look something like this:

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

虽然这适用于正确输入帐户号码的用户, it leaves the door open for attackers. For example, 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 all customers being returned instead of just a single customer.

Blind SQL Injection

Also referred to as Inferential SQL Injection, 盲目SQL注入攻击不会直接从被攻击的数据库中泄露数据. Rather, the attacker closely examines indirect clues in behavior. Details within HTTP responses, blank web pages for certain user input, 根据攻击者的目标,数据库响应特定用户输入所需的时间都可能是线索. 它们还可以指向另一种SQLi攻击途径,供攻击者尝试.

Out-of-Band Injection

这种攻击有点复杂,当攻击者无法在一次攻击中实现目标时,可能会使用这种攻击, direct query-response attack. Typically, an attacker will craft SQL statements that, when presented to the database, 会触发数据库系统创建到攻击者控制的外部服务器的连接吗. 通过这种方式,攻击者可以获取数据或潜在地控制数据库的行为.

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

SQL Injection Example 

对于这个SQL注入示例,让我们使用两个数据库表:Users和Contacts. Users表可能非常简单,只有三个字段:ID、用户名和密码. The Contacts table has more information about the users, such as UserID, FirstName, LastName, Address1, Email, credit card number, and security code. 

The Users 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 Users where username=’jsmith’ and password=’P@$$w0rd’

SQL的工作方式是,它将对查询请求的每一行执行真或假比较. In our example, 查询要求检查Users表,并返回用户名为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 Users where username=’jsmith’ and password=’x’ or 1=1

This will work for us, 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? It does! 该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. In addition to our ‘ or 1=1, we can add on to that a second statement like UNION SELECT LastName, credit card number, security code from Contacts. 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) ” and this will do what it seems like. 它将告诉数据库服务器进行10秒的小睡,所有响应将被延迟.

How to Prevent SQL Injection Attacks

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

Don’t use dynamic SQL

Sanitize user-provided inputs

  • 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.
  • Salt the encrypted hashes.
  • 这还提供了另一层保护,以防攻击者成功地泄露敏感数据.

Limit database permissions and 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. 攻击者可以使用这些错误消息来获取有关数据库的信息.

Use a Web Application Firewall (WAF) for web applications that access databases

  • This provides protection to web-facing applications.
  • It can help identify SQL injection attempts.
  • Based on the setup, 它还可以帮助防止SQL注入尝试到达应用程序, therefore, the database).

Use web application security testing 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 data is encrypted, that you protect and test your web applications, and that you’re up to date with patches, you can take meaningful steps toward keeping your data secure.