#渗透测试#漏洞挖掘#红蓝攻防#护网#sql注入介绍09基于布尔值的SQL注入(Boolean-Based SQL Injection)
免责声明 本教程仅为合法的教学目的而准备,严禁用于任何形式的违法犯罪活动及其他商业行为,在使用本教程前,您应确保该行为符合当地的法律法规,继续阅读即表示您需自行承担所有操作的后果,如有异议,请立即停止本文章阅读。
目录
一、基于布尔值的SQL注入概述
二、判断注入点
三、猜解数据库信息
四、常用函数
五、应用场景
六、防御措施
七、基于布尔值的SQL注入实际案例
案例背景
判断注入点
构建布尔查询
逐步推测信息
实际操作步骤
一、基于布尔值的SQL注入概述
基于布尔值的SQL注入是SQL注入的一种类型。在这种注入场景下,web页面不会返回错误信息,只能通过页面返回的正常与否(类似布尔值的True或False)来判断注入是否成功以及获取相关信息。比如在某些情况下,页面不会显示后端的报错和查询结果传来的结果,对前端任何输入都不返回不同内容(可能是后端不返回,也可能是返回了前端不显示),这时就需要基于布尔值的注入来获取数据库信息等内容。其适用于无回显的情况,通过判断所输入内容对应的页面状态(true或false及页面是否正常)来确定内容是否正确。
二、判断注入点
- 利用页面响应判断单引号闭合情况
- 例如在注入测试时添加单引号(如
id = 1'
),如果返回不正确页面,初步确定单引号存在注入。可以通过判断如TRUE
页面有特定标识(如'youarein.'
),FALSE
页面不存在该标识来确定。并且查看源代码中SQL语句构造情况(如$sql = SELECT * FROM users WHERE id = '$id' LIMIT 0,1;
),如果单引号闭合导致查询报错(如单引号在闭合后还存在一个单引号会引起查询报错),则可能存在注入点。例如在sqli - labs的题目中,sqli - labs lesson - 8
提示是单引号的错误,当使用?id = 1
和?id = 1'
判断时页面返回结果一样,无法直接判断是否错误,就需要考虑布尔盲注来确定是否存在注入点。- 利用逻辑判断语句测试
- 可以使用类似
and length(database()) == 10--+
这样的语句进行测试。如果输入的本应是正确的值,但却返回空操作,这可能表明是一个注入点。例如在判断数据库名长度时,如果数据库名的长度小于某个值是不正确的(如if(length(database()) < 3, sleep(3), 1)
),可以根据页面是否有延迟(如直接睡3秒)等来判断是否存在注入点。如果闭合了单引号,可能不需要等待(页面正常响应),没有闭合单引号可能加载时间会很长(如发生延迟),从而确定存在注入点,还可以通过类似if(length(database()) == 8, 1, sleep(3))
这样的语句,根据页面时间情况判断出数据库的字符长度是否为8。三、猜解数据库信息
- 猜解数据库名长度
- 使用
length(database())
函数结合布尔判断来猜解数据库名的长度。例如通过不断调整比较的值(如1and length(database()) = 4
来判断数据库名字的长度是否为4),根据页面返回的正常与否来确定数据库名的长度值。- 猜解数据库名字符
- 利用二分法猜解数据库名中的字符。例如猜当前数据库第一个字符时,可以使用
SELECT * FROM users WHERE id = '1' and ascii(substr(database(),1,1))>114#'
(后面单引号被#
注释掉)这样的语句,通过不断调整比较的ASCII码值(如115为fal
,114为TRUE
,如果数据库第一个字符ASCII为115,即s
)。同理修改substr(database(),2,1)
可猜第二个字符,以此类推来猜解数据库名中的各个字符。四、常用函数
在基于布尔值的SQL注入中,常用的函数包括:
substr()
:用于截取字符串。例如,substr(database(), 1, 1)
表示截取数据库名字的第一个字符。ascii()
:用于返回一个字符的ASCII码。例如,ascii(substr(database(), 1, 1))
表示返回数据库名字的第一个字符的ASCII码。length()
:用于返回字符串的长度。例如,length(database())
表示返回数据库名字的长度。五、应用场景
基于布尔值的SQL注入通常应用于以下场景:
- 无回显:应用程序不会直接显示查询结果,只会显示对错。
- 无报错:应用程序不会显示SQL错误信息,只会显示通用的错误消息或无响应。
- 限制输出:应用程序限制了输出的内容,无法直接获取数据库中的信息。
六、防御措施
为了防止基于布尔值的SQL注入,可以采取以下防御措施:
- 使用参数化查询:通过使用参数化查询或预编译语句,可以有效防止SQL注入。
- 输入验证:对用户输入的数据进行严格的验证和过滤,确保输入的数据符合预期格式。
- 错误处理:避免在应用程序中显示详细的错误信息,只显示通用的错误消息。
- 最小权限原则:为数据库用户分配最小的权限,限制其对数据库的操作。
七、基于布尔值的SQL注入实际案例
基于布尔值的SQL注入(Boolean-based SQL Injection)是一种常见的SQL注入技术,通过观察应用程序对不同SQL查询的响应来推测数据库中的信息。下面是一个实际案例,展示了如何利用基于布尔值的SQL注入来获取数据库信息。
案例背景
假设有一个在线留言系统,用户可以通过输入留言ID来查看对应的留言内容。系统使用的SQL查询语句如下:
SELECT * FROM messages WHERE id = [用户输入的ID];
判断注入点
首先,我们需要判断是否存在SQL注入点。可以通过向应用程序发送一些特殊的SQL语句来实现。例如,输入以下两个查询:
id=1' AND 1=1
id=1' AND 1=2
观察应用程序的响应:
- 如果第一个查询返回正常结果,而第二个查询返回错误或无响应,则说明存在SQL注入点。
- 如果两个查询都返回相同的结果,则说明不存在SQL注入点。
构建布尔查询
一旦确定了注入点,可以构建一些布尔查询来推测数据库中的信息。例如,输入以下查询:
id=1' AND ASCII(SUBSTR(DATABASE(), 1, 1)) > 100 -- a
观察页面是否正常显示。如果正常显示,则说明数据库名字的第一个字符的ASCII码大于100。依次调整ASCII码值,直到找到正确的字符。
逐步推测信息
通过不断调整查询语句,可以逐步推测出数据库中的各种信息,包括数据库名字、表名、字段名和数据内容。例如,输入以下查询:
id=1' AND SUBSTR(DATABASE(), 1, 1) = 's' -- a
观察页面是否正常显示。如果正常显示,则说明数据库名字的第一个字符是
s
。依次推测每个字符,直到猜出整个数据库名字。实际操作步骤
- 确定数据库名字:
- 输入
id=1' AND ASCII(SUBSTR(DATABASE(), 1, 1)) > 100 -- a
- 观察页面响应,调整ASCII码值,直到找到正确的字符。
- 依次推测每个字符,直到猜出整个数据库名字。
- 确定表名:
- 输入
id=1' AND ASCII(SUBSTR((SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=DATABASE() LIMIT 1), 1, 1)) > 100 -- a
- 观察页面响应,调整ASCII码值,直到找到正确的字符。
- 依次推测每个字符,直到猜出表名。
- 确定字段名:
- 输入
id=1' AND ASCII(SUBSTR((SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='messages' LIMIT 1), 1, 1)) > 100 -- a
- 观察页面响应,调整ASCII码值,直到找到正确的字符。
- 依次推测每个字符,直到猜出字段名。
- 获取数据内容:
- 输入
id=1' AND ASCII(SUBSTR((SELECT message_content FROM messages LIMIT 1), 1, 1)) > 100 -- a
- 观察页面响应,调整ASCII码值,直到找到正确的字符。
- 依次推测每个字符,直到猜出数据内容。