SQL注入UNION攻击

发布时间 2023-05-05 23:29:47作者: 北蒙岛的cozyDay

1.SQL注入UNION攻击

当应用程序容易受到 SQL 注入的攻击并且查询结果在应用程序的响应中返回时,该UNION关键字可用于从数据库中的其他表中检索数据。这会导致 SQL 注入 UNION 攻击。

关键字UNION SELECT允许您执行一个或多个其他查询,并将结果追加到原始查询。例如:

SELECT a, b FROM table1 UNION SELECT c, d FROM table2

要使UNION查询正常工作,必须满足两个关键要求:

  • 各个查询必须返回相同数量的列。
  • 每列中的数据类型必须在各个查询之间兼容。

要执行 SQL 注入 UNION 攻击,您需要确保您的攻击满足这两个要求。这通常涉及弄清楚:

  • 从原始查询返回多少列?
  • 从原始查询返回的哪些列具有适合保存注入查询结果的数据类型?

2.确定 SQL 注入 UNION 攻击中所需的列数

执行 SQL 注入 UNION 攻击时,有两种有效的方法可以确定从原始查询返回的列数。

2.1 注入一系列子句并递增指定的列索引,直到发生错误。

例如:假设注入点是原始查询子句中的带引号的字符串,则应提交:ORDER BY WHERE

' order by 1--
' order by 2--
' order by 3--
etc

这一系列有效负载修改原始查询,以按结果集中的不同列对结果进行排序。子句中的列可以通过其索引指定,因此您无需知道任何列的名称。当指定的列索引超过结果集中的实际列数时,数据库将返回错误

应用程序实际上可能在其 HTTP 响应中返回数据库错误,或者它可能返回一般错误,或者只是不返回任何结果。如果可以检测到应用程序响应中的一些差异,则可以推断从查询返回的列数。

2.2 提交一系列有效负载,指定不同数量的空值
' union select null--
' union select null,null--
' union select null,null,null--
etc.

如果空值数与列数不匹配,数据库将返回错误

注意:

  • 在 Oracle 上,每个查询都必须使用该关键字并指定有效的表。Oracle 上有一个内置表,可用于此目的。因此,在 Oracle 上注入的查询需要如下所示:

    ' union select null from dual--
  • 所描述的有效负载使用双短划线注释序列在注入点之后注释掉原始查询的其余部分。在MySQL上,双破折号--序列后必须跟一个空格。或者,哈希字符#可用于标识注释。

3.在 SQL 注入 UNION 攻击中查找具有有用数据类型的列

执行 SQL 注入 UNION 攻击的原因是能够从注入的查询中检索结果。通常,要检索的有趣数据将采用字符串形式,因此需要在原始查询结果中找到数据类型为字符串数据或与字符串数据兼容的一个或多个列。

确定所需列数后,可以探测每列,通过提交一系列有效负载(依次将字符串值放入每列)来测试它是否可以保存字符串数据。

例如,如果查询返回四列,则应提交

' union select 'a',null,null,null--
' union select null,'a',null,null--
' union select null,null,'a',null--
' union select null,null,null,'a'--

如果列的数据类型与字符串数据不兼容,则注入的查询将导致数据库错误.

4.使用 SQL 注入 UNION 攻击检索相关数据

确定原始查询返回的列数并找到哪些列可以保存字符串数据后,就可以检索感兴趣的数据。

假设:

  • 原始查询返回两列,这两列都可以保存字符串数据。
  • 注入点是WHERE子句中的带引号的字符串。
  • 数据库包含一个调用的表users,其中包含列username和password 。

在这种情况下,您可以通过提交输入来检索表的内容:

' union select username,password from users--

当然,执行此攻击所需的关键信息是有一个users表,其中有两列名为 username和 password。如果没有此信息,您将只能尝试猜测表和列的名称。事实上,所有现代数据库都提供了检查数据库结构的方法,以确定它包含哪些表和列。

5.检索单个列中的多个值

在前面的示例中,假设查询仅返回单个列。

通过将值连接在一起,您可以轻松地在此单个列中检索多个值,理想情况下包括合适的分隔符以区分组合值。

Oracle 上,您可以提交输入:

' union select username || '~' || password from users--

这使用双管道序列||,该序列是 Oracle 上的字符串连接运算符。注入的查询将username 和 password字段的值连接在一起,用字符~分隔。

注意,不同的数据库使用不同的语法来执行字符串串联。有关更多详细信息,请参阅 SQL 注入备忘单