zyNo.18
布尔盲注问题
知识点
1.SQL注入的类型,按回显方式划分:
有回显:联合查询->构造联合查询语句,直接查看查询结果,
报错注入->构造报错语句,在报错中查看结果,
堆查询->多行语句执行,进而实现想要达到的目的
无回显:盲注->布尔型/时间型 通过某种手段“爆破”结果
2.盲注分类
布尔盲注-回显不同
布尔状态例如:
1.回显不同(内容、长度)
2.HTTP响应状态码不同(200、500)(eg成功301,失败200具体数据不定)
3.HTTP响应头变化(无条件重定向(location)、设置cookie)
4.基于错误的布尔注入(MySQL是否报错)
时间盲注-响应时间不同
3.盲注初识
select * from users where id = '1' and substr((select database()),1,1) = 'a' #'数据库的首字母是不是等于a
select * from users where id = '1' and substr((select database()),1,1) = 'c' #'
substr((select database()),1,1)从第一个字符开始截取数据库中的一位即首字母,类似于爆破一个一个去试,a-z,A-Z,0-9一共62种可能,然后将1,1改成2,1再然后改成3,1逐个爆破就可以解出数据库内容
4.盲注的两大基本问题
a.字符串的截取 b.比较
5.字符串截取方法总结
1.substr()/ substring()
SUBSTR (str, pos)
截取从pos位置开始到最后的所有str字符串
SUBSTR (str, pos, len)(做盲注基本用这个写法,因为三个参数从某一位开始截取一个字符)
注意pos是从1开始数的
注:
如果过滤了逗号可以用from for代替
SELECT SUBSTR('2018-08-17',6,5);与SELECT SUBSTR('2018-08-17'FROM 6 FOR 5);意思
相同
2.mid()
SQL MID()函数用于得到一个字符串的一部分。这个函数被MySQL支持,但不被MS SQL Server和Oracle支持。
在SQL Server,Oracle数据库中,我们可以使用SQL SUBSTRING函数或者SQL SUBSTR函数作为替代。
在mysql里和substr()基本一样 ~~
mid和substr的区别在于:
1.substr中长度是可选的但mid必须是3个参数
2.substr支持这样的语法:
SUBSTRING(str FROM pos FOR len)
SUBSTRING(str FROM pos)
3.right()
技巧是结合ascii()
ascii('str')返回字符串的第一个字符的ascii码
能用ascii时尽量用ascii!因为字符的比较可能因为字符比较特殊(比如是单引号)而出现很多问题,但是ascii
直接转成数字,就解决了这个问题!
ascii的同名函数是ord用于过滤ascii的过滤
ascii(right('abcdef',4)) 99 可以精确地截取指定的一位了
还有一个优点结合ascii()可以进行二分查找(如上图所示)
question:
substr里面也有符号之类的,为啥它不用,还有既然如此先用substr还是right结合ascii
anwser:搜嘎,搜了一下可以直接等于@等符号,不必忧心
4.left()
left不方便直接用ascii,因为反出结果始终是第一位,所以要再和reverse(倒叙)结合select ord(reverse(left('abc',3)));但是有right也就没有大费周章用lett的必要了
5.trim(不常见)
SQL trim()函数 过滤指定的字符串,最常见的用途是移除字首或字尾的空白。
MySQL: TRIM(), RTRIM(), LTRIM()
TRIM()#删除前后空格
RTRIM()#删除字符串结尾空格
LTRIM()#删除字符串起始空格
trim(leading I from 'abcd')=trim(leading I+1 from 'abcd')不相等,说明正确结果是I或者I+1
trim(leading I+2 from 'abcd')= trim(leading I+1 from 'abcd')相等则正确为I;不相等则I+1正确
6.比较方法总结
1.等于
substr(database(),1,1) = 'a'
2.大于 小于
How about 'b' > 'azzzzzzz' (比较从每个字符串的第一个字符开始)
3.like
数据库和excel一样都是要进行筛查的
我们知道在MySQL 中使用SQL SELECT命令来读取数据,同时我们可以在SELECT语句中使用WHERE子句来获取指定的记录。
WHERE子句中可以使用等号=来设定获取数据的条件,如“runoob_author = 'RUNOOB.COM'".
但是有时候我们需要获取runoob_author 字段含有“COM"字符的所有记录,这时我们就需要在WHERE子句中使用SQL LIKE子句。(举个例子要筛查所有2019年的学生则在2019字段后面加上%)select database() like "ctfga%";
SQL LIKE 子句中使用百分号%字符来表示任意字符,类似于UNIX或正则表达式中的星号*。
如果没有使用百分号%,LIKE子句与等号=的效果是一样的。select 1 like '1';
4.正则表达式 regexp rlike
regexp是不区分大小写的,需要大小写敏感需要加上binary关键字
5.Between
expr [NOT] BETWEEN begin_expr AND end_expr;
between筛选的是expr>=begin_expr并且expr <= end_expr的数据,如果不存
在则返回的是0;not between筛选的是expr<begin_expr或者expr>end_expr的数据,如果不
存在则返回的是0;如果expr返回的是NULL,则between也返回的是null
注意:between是闭区间所以between 1and 3不能确定是3因为有三个数select 2 between 1 and 3;
select 2 between 2 and 2;
6.In
依然是大小写不敏感的 需要加上binary关键字字符数字都可用,也有not in
7.And 逻辑与运算符
1和任何字符都是0,1和非0数字都是1
8.或 or
||等价于 or,|是按位或
按位或(|)
- 定义与操作:按位或是对两个整数的二进制表示进行逐位运算。对于两个二进制位,如果其中至少有一个为
1
,则结果位为1
;只有当两个位都为0
时,结果位才为0
。 - 示例:假设要对十进制数
5
(二进制101
)和3
(二进制011
)进行按位或运算。101
011
111(结果)
- 结果
111
转换为十进制是7
。
- 结果
9.异或
Xor逻辑异或,^ 按位异或
- 逻辑异或(XOR)
- 定义:逻辑异或(XOR)是一种逻辑运算,通常用符号 “⊕” 表示(在某些编程语言中用 “^” 表示逻辑异或)。对于两个逻辑值(通常为真或假,用 1 和 0 表示),当且仅当两个值不同时,结果为真(1),否则为假(0)。
- 真值表:
A B A ⊕ B 0 0 0 0 1 1 1 0 1 1 1 0 - 示例:在布尔代数或逻辑判断场景中,如果 A 表示 “今天是晴天”,B 表示 “今天是工作日”,那么 “A ⊕ B” 表示 “今天要么是晴天且不是工作日,要么不是晴天且是工作日”。
- 按位异或(^)
- 定义:按位异或是一种位运算,操作数是二进制数。它对两个操作数的对应位进行逻辑异或运算。也就是说,对于两个二进制数的每一位,当且仅当这两位的值不同时,结果位为 1,否则为 0。
- 示例:
- 假设有两个十进制数 5 和 3,5 的二进制表示是 101,3 的二进制表示是 011。
- 对它们进行按位异或运算:
- 101
- 011
- 110(结果)
- 结果 110 转换为十进制就是 6。5 ^ 3= 6。
使用场景
题目不让使用注释符的时候where id = '1' and 1=1 #(或者-- 来构造闭合)'不让使用#和-- 的时候连异或where id = '1'^(substr()='a')^'1'
延时盲注(考的比较少)
不管查询什么都显示查询成功只有一种回显
(时间盲注:
没有回显,只能依据sleep时间来判断正确与否
当然有回显当然也能用,甚至union select直接查出数据时都也能用,就是没必要
常用条件+sleep())
条件表达式
1.Case
case exp1 when exp2 then exp3 else exp4 end;
1=2返回3否则返回4
2.if
If( exp1, exp2 exp3)
含义:
If exp1: return exp2
Else: return exp3
基本姿势Sleep(x)睡眠x秒
以下还有考的少
过滤了sleep()又没有回显 只能延时注入 怎么办?
Ps:mysql中只有sleep()这一个延时函数
1.benchmark
MySQL有一个内置的BENCHMARK()函数,可以测试某些特定操作的执行速度。参数可以是需要执行的次数和表达式。表达式可以是任何的标量表达式,比如返回值是标量的子查询或者函数。该函数可以很方便地测试某些特定操作的性能,比如通过测试可以发现,MD5()函数比SHAI()函数要快
2.笛卡儿积
这种方法又叫做heavy query,可以通过选定一个大表来做笛卡儿积,但这种方式执行时间会几何倍数的提升,在站比较大的情况下会造成几何倍数的效果,实际利用起来非常不好用。
1.count()函数是用来统计表中记录的一个函数,返回匹配条件的行数。
2.count()语法:
(1)count(+) --- 包括所有列,返回表中的记录数,相当于统计表的行数,在统计结果的时候,不会忽略列值为NULL的记录。
(2)count(1) --- 忽略所有列,1表示一个固定值,也可以用count(2)、count(3)代替,在统计结果的时候,不会忽略列值为NULL的记录。
(3)count(列名) --- 只包括列名指定列,返回指定列的记录数,在统计结果的时候,会忽略列值为NULL的记录(不包括空字符串和0),即列值为NULL的记录不统计在内。
(4)count(distinct列名) --- 只包括列名指定列,返回指定列的不同值的记录数,在统计结果的时候,在统计结果的时候,会忽略列值为NULL的记录(不包括空字符串和0),即列值为
NULL记录不统计在内。
3.count(*)&count(1)&count(列名)执行效率比较:
(1)如果列为主键,count(列名)效率优于count(1)
(2)如果列不为主键,count(1)效率优于count(列名)
(3)如果表中存在主键,count(主键列名)效率最优
(4)如果表中只有一列,则count(*)效率最优
(5)如果表有多列,且不存在主键,则count(1)效率优于count(*)
3. get_lock
这是一种比较神奇的利用技巧,延时是精确可控的,但问题在于并不是所有站都能实现。
4.正则表达式
正则匹配在匹配较长字符串但自由度比较高的字符串时,
会造成比较大的计算量,我们通过rpad或repeat构造长字符
串,加以计算量大的pattern,通过控制字符串长度我们可
以控制延时。
select rpad('a',4999999,'a') RLIKE concat(repeat('(a .* )+',30),'b');,
报错盲注
If error, return ERR
Else return OK!
只能选择延时盲注但是可能被过滤掉了,只会告诉你正确否不告诉你原因,构造表达式让报错有选择性的报错
if ( (substr='a'), sleep(5), 0)
if((substr='a'),执行某个函数执行过程中会报错,0)