首先要问:sql注入是什么?
sql注入就是利用错误的sql语句(错误的sql语句,就是跟网站开放人员设定的代码不一样)进行获取数据库里面的内容(我们一般都学过了mysql,mysql里要建库、建表、建字段、建值,这是mysql的四大板块 库、表、列、值),
像我们经常进入的网站、用户账号、密码、头像,还有管理员的账号、密码什么的都保存在数据库里,(通过设置数据库与网站的设置,使得网站有建立自己的数据库,)
如何判别是否可以进行sql注入
(这里我借用一下掌控安全的封神台靶场,
链接:[封神台 - 掌控安全在线演练靶场,是一个在线黑客攻防演练平台。 (zkaq.cn)](https://hack.zkaq.cn/battle/target?id=c0c45746e7d351bc )
我们一开始进入一个网站页面,是正常页面,然后我们在id=1后面输入了一个'(单引号)发现页面不一样了,这时候我们就可以判断这里存在sql注入
将id改为2,这时我们就可以得到id=2的用户的信息
and 进行判断
?id=1 and 1=1 (mysql也是有and语句的 就是前面和后面都正确则输出,id=1正确,1=1也正确)
?id=1 and 1=2(?id=1正确,1=2错误 不正确)
1=1 和1=2 两个页面不一样则可以判断存在sql注入(图片上的%20是网页自动将空格转换为%20了,无影响)
单引号进行判断
同样也是没有单引号的页面 和添加了单引号的页面不一样,则说明存在sql注入
以下图片是添加了单引号后的界面,这说明他将'(单引号)也在sql语句中执行了
至此,我们已经知道了该网页存在sql注入漏洞,那么我们就可以进行第二步了
找到该表中是有几列
order by (order by 本身是一个排序函数,但我们可以通关order by 来猜出该表中有多少列
如:select * from users order by 5
我们在使用sql语句的时候,必须要与该表中所设定的列数相等,不相等的话,sql语句则不能执行
已知 该 users表中 列为5列 分别为 Id、username、mobile、password、crate_time,我们可以使用union select (联合查询)来继续输出后面的
这次我们输出一下数据库名
但是如果我们union select 1,2,3,4的话,与原本的列数不照应,那么就不能运行sql语句,所以我们才需要先使用order by 语句来进行判别该表有几列
在回到我们这个靶场,使用order by 3页面是正常的,说明至少有3列,然后order by 4发现页面不正常了,说明没有第4列,这样我们就知道了该表有3列
我们已经知道该表有3列,那么我们就可以进入第三步,使用union select 1,2,3来找到显示位
那么有人疑惑了,什么叫做显示位?
显示位就是 该表中有3列,但是,在该网页他只输出了几列,并没有把每一列的数据都输出在页面上,我们将输出到页面上对应的列的内容叫做显示位
?id=1 and 1=2 union select 1,2.3
为什么不是直接 ?id=1 union select 1,2,3呢,为什么要 and 1=2?
因为一个网页在这个输出的位置,他只有一个,他只会输出test和mima(id=1的用户名和密码)我们想要他输出的2,3被覆盖掉了(可以查询到,但是该页面只能输出一个,所以2,3可以被查到,但是不能被输出),and 1=2 利用了and 语句 1=2 是错误的,所以 id=1 and 1=2 不会被执行,这样就只会执行 union select 1,2,3.这样就可以知道显示位是在哪里
COLLATION_CHARACTER_SET_APPLICABILITY
知道了显示位,那么我们就可以进入第四步。进行爆库、爆表、爆列名、爆数据
我们已经知道第2列和第3列是显示位,那么我们就可以使用这两者任意一列,这里我选择了第3列,也就是密码处
爆库(得出:error)
?id=1 and 1=2 union select 1,2,database()
爆表(error_flag,user)
?id=1 and 1=2 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database()
?id=1 and 1=2 union select 1,2,table_name from information_schema.tables where table_schema=database()
现在大多mysql(版本在5.几的一般都包含information_shema)若没有这个information_schema就会难搞,现在的基本上都有
information_schema包含了所有的数据库
information_schema.tables包含了所有的数据表
information_schema.columns包含了所有的字段名
所有我们就可以使用from infromation什么的进行,在这个大范围里面进行查找使用
group_concat()
没有使用group_concat(),只获取了一个值,而使用了group_concat()可以获取所有的值
(原理:一个空只能输出一个,而group_concat()将不同的值用,’逗号‘隔开,组成了一个新的值,这个值包含了所有,所有满足一个空输出所有的值)
爆字段名(Id,flag)
很明显,erroe_flag,这明眼人基本就知道了flag在这个里面,那么我们就开始爆字段名(爆列名),若不明显的话,就需要我们一个一个实验
id=1 and 1=2 union select 1,2,group_concat(column_name) from information_schema.columns where table_name='error_flag'
爆值(zKaQ-Nf,zKaQ-BJY,zKaQ-XiaoFang,zKaq-98K)
id=1 and 1=2 union select 1,2,group_concat(flag) from error_flag
就这样flag的值就出来了
这么多值,我们就需要一个一个去提交试试
如flag{zKaQ-Nf}
总结:
第一步,找注入点,判断是否存在sql注入
第二步,判断该网页中的表是由几列
第三步,找显示位
第四步,进行爆库、爆表、爆列名、爆值
最后在提示一点,上面的代码,爆库爆表什么的代码,都是套路,学会复制粘贴,修改关键值就可以使用
若 列不同,就就在增添一个
若表名不同 就修改表名就行
就可以运行sql语句
就可以先收集这,等使用的时候就可以直接粘贴修改